/* Sector.c*/
 
 
/*Include For "Sector.h"*/
#include "ACP_Base.h"
#include "MTH.h"
#include "GEO.h"	
#include "GLI.h"
#include "COL.h"
#include "SPO.h"
#include "LST.h"
 
/*For the sound*/
#include "SND.h"
 
#include "SCT.h"
 
/*Include for Physical objects*/
#include"PCS.h"
#include "PO.h"
/*XB980821*/
#ifndef D_THROW_IPO
#include "IPO.h"
#endif /* D_THROW_IPO */
/*End XB*/
 
/*prototypes*/
MTH3D_tdstVector fn_xComputeNormalOfPoint(ACP_tdxIndex xI, ACP_tdxHandleOfObject hPhysical);
void fn_vCoherenceOfSmoothing(HIE_tdxHandleToSuperObject   hSprObjSector);
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vGetNextSector(HIE_tdxHandleToSuperObject *_p_hSectorSOWhereIWas,
                       ACP_tdxHandleOfObject _hObjectGeometric,
                       GLI_tdstDataOfElement *_p_stDataPickedObject);
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
extern FILE *dump;
extern float fScale; 

#endif //U64CONVERTLOG
// } fin N64-format
/*End of prototypes*/
 
 
/*Global variables*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
HIE_tdxHandleToSuperObject SCT_a10_hSectorChangeHistory[10];
ACP_tdxIndex SCT_xNbChange;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*End of global variables*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by Oliv' - 07/09/1998 */ /* the values are corrected at binarization stage */
/* Function*/
/* Oliv' Modification - 16/06/1998 - Added 4th parameter to have real position of parent SuperObject*/
/*void SECT_fn_vComputeMinMaxPoint (ACP_tdxHandleOfObject _hGeometricObject, MTH3D_tdstVector *_p_stMin, MTH3D_tdstVector *_p_stMax)*/
void SECT_fn_vComputeMinMaxPoint (ACP_tdxHandleOfObject _hGeometricObject, MTH3D_tdstVector *_p_stMin, MTH3D_tdstVector *_p_stMax, POS_tdstCompletePosition *_p_stPosition )
{
	MTH3D_tdstVector	stPoint;
	ACP_tdxIndex		xNbPoints, xNumPoint;
 
	/* get number of points in the object*/
	xNbPoints = GEO_xGetGeometricObjectNumberOfPoints(_hGeometricObject);
	/* check coordinates of each point */
	for (xNumPoint = 0; xNumPoint < xNbPoints; xNumPoint++)
	{
		/* get point*/
		GEO_vGetPointOfObject(_hGeometricObject, &stPoint, xNumPoint);
/* Oliv' - 16/06/1998 - get absolute position of this point*/
		POS_fn_vMulMatrixVertex( &stPoint, _p_stPosition, &stPoint );
/* EndOfOliv'*/
 
		/* check x coordinate*/
		if (stPoint.xX < _p_stMin->xX) _p_stMin->xX = stPoint.xX;
		if (stPoint.xX > _p_stMax->xX) _p_stMax->xX = stPoint.xX;
		/* check y coordinate*/
		if (stPoint.xY < _p_stMin->xY) _p_stMin->xY = stPoint.xY;
		if (stPoint.xY > _p_stMax->xY) _p_stMax->xY = stPoint.xY;
		/* check z coordinate*/
		if (stPoint.xZ < _p_stMin->xZ) _p_stMin->xZ = stPoint.xZ;
		if (stPoint.xZ > _p_stMax->xZ) _p_stMax->xZ = stPoint.xZ;
	}
}
/*End of Function*/
 
/* Function*/
void SECT_fn_vComputeBorder (HIE_tdxHandleToSuperObject hSector)
{
	SECT_tdxHandleOfSectorObject	hSectorObject;
	HIE_tdxHandleToSuperObject		hElementPhysicalSector;
	ACP_tdxHandleOfObject			hPhysicalObject;
	MTH3D_tdstVector				stMin, stMax;
/* SHAITAN -> REQUEST FROM DESIGNERS : SECTORS CAN HAVE SOME PART OUTSIDE THE BORDER...*/
	MTH3D_tdstVector				stRealMin, stRealMax;
/* END SHAITAN*/
	ACP_tdxIndex					xInd;
	MTH_tdxReal						xTemp, xZmax;
 
	/* compute border of sector object*/
	hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hSector);
	/* save loaded Zmax*/
	SECT_fn_vGetMaxPointInBorder(hSectorObject, &stMax);
	SECT_fn_vGetMinPointInBorder(hSectorObject, &stMin);
	xZmax = stMax.xZ;
 
/* SHAITAN -> REQUEST FROM DESIGNERS : SECTORS CAN HAVE SOME PART OUTSIDE THE BORDER...*/
	SECT_fn_vGetMaxPointInBorder(hSectorObject, &stRealMax);
	SECT_fn_vGetMinPointInBorder(hSectorObject, &stRealMin);
/* END SHAITAN*/
 
	HIE_M_ForEachChildOf(hSector, hElementPhysicalSector, xInd)
	{
		switch (HIE_fn_ulGetSuperObjectType(hElementPhysicalSector))
		{
			/* geometric object*/
			case HIE_C_ulEDT_Geometric:
				/*Take the physical object*/
				hPhysicalObject = (ACP_tdxHandleOfObject) HIE_fn_hGetSuperObjectObject(hElementPhysicalSector);
				break;
 
			/* instanciated physical object*/
/*XB980821*/
#ifndef D_THROW_IPO
			case HIE_C_ulIPO:
			case HIE_C_ulIPO_Mirror:
				/*Take the physical object*/
				GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(hElementPhysicalSector))),
					0L,
					&xTemp,
					&hPhysicalObject);
				break;
#endif /* D_THROW_IPO */
/*End XB*/
 
			/* physical object*/
			case HIE_C_ulPO:
#ifndef D_THROW_VISUAL_SET
				/*Take the physical object*/
				GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hElementPhysicalSector)),
					0L,
					&xTemp,
					&hPhysicalObject);
#else
				/*Take the physical object*/
				hPhysicalObject=PO_fn_hGetGeometricObject((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hElementPhysicalSector));
#endif /* D_THROW_VISUAL_SET */
 
/* ANNECY AV {*/
                break;
 
            default:
                hPhysicalObject = NULL;
                break;
		}
		
		/* update min&max*/
/* Oliv' - 16/06/1998 - Added 4th parameter to get absolute position of object*/
        if (hPhysicalObject) 
		 SECT_fn_vComputeMinMaxPoint(hPhysicalObject, &stMin, &stMax, HIE_fn_hGetSuperObjectGlobalMatrix(hElementPhysicalSector) );
/* EndOfOliv'*/
/* END ANNECY AV }*/
	}
 
#ifdef ACTIVE_EDITOR
	SECT_fn_vSetRealZmax(hSectorObject, stMax.xZ);
#endif /*ACTIVE_EDITOR*/
 
	/* update Zmax*/
	if ((xZmax > MTH_C_InfinitMinus) && (xZmax > stMax.xZ))
		stMax.xZ = xZmax;
 
/* SHAITAN -> REQUEST FROM DESIGNERS : SECTORS CAN HAVE SOME PART OUTSIDE THE BORDER...*/
/*	
	// set box parameters
	SECT_fn_vSetMinPointInBorder(hSectorObject, &stMin);
	SECT_fn_vSetMaxPointInBorder(hSectorObject, &stMax);
*/
	/* set box parameters*/
	if ((stRealMax.xX == MTH_C_InfinitMinus) || (stRealMax.xY == MTH_C_InfinitMinus) || (stRealMax.xZ == MTH_C_InfinitMinus))
		SECT_fn_vSetMaxPointInBorder(hSectorObject, &stMax);
	if ((stRealMin.xX == MTH_C_InfinitPlus) || (stRealMin.xY == MTH_C_InfinitPlus) || (stRealMin.xZ == MTH_C_InfinitPlus))
		SECT_fn_vSetMinPointInBorder(hSectorObject, &stMin);
/* END SHAITAN*/

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	fprintf(dump,"--------- Border sector : %s\n",hSectorObject->szSectorName);

	SECT_fn_vGetMinPointInBorder(hSectorObject,&stMin);
	stMin.xX = (float) (( (long)( (stMin.xX*fScale) + 0.5) ) / fScale);		
	stMin.xY = (float) (( (long)( (stMin.xY*fScale) + 0.5) ) / fScale);		
	stMin.xZ = (float) (( (long)(stMin.xZ*fScale + 0.5) - (long)(0.20f * fScale + 0.5) ) / fScale);
	SECT_fn_vSetMinPointInBorder(hSectorObject, &stMin);
	fprintf(dump,"min point : %f,%f,%f\n",stMin.xX,stMin.xY,stMin.xZ);
	fflush(dump);

	SECT_fn_vGetMaxPointInBorder(hSectorObject,&stMin);
	stMin.xX = (float) (( (long)( (stMin.xX*fScale) + 0.5) ) / fScale);		
	stMin.xY = (float) (( (long)( (stMin.xY*fScale) + 0.5) ) / fScale);		
	stMin.xZ = (float) (( (long)( (stMin.xZ*fScale) + 0.5) ) / fScale);		
	SECT_fn_vSetMaxPointInBorder(hSectorObject, &stMin);
	fprintf(dump,"max point : %f,%f,%f\n",stMin.xX,stMin.xY,stMin.xZ);
	fflush(dump);

#endif //U64CONVERTLOG
// } fin N64-format


}
/*End of Function*/
 
/* Function*/
void SECT_fn_vInitAllBorders (HIE_tdxHandleToSuperObject hSectorRoot)
{
	HIE_tdxHandleToSuperObject		hCurrentSector;
	ACP_tdxIndex					xInd;
 
	/* must init all sectors*/
	HIE_M_ForEachChildOf(hSectorRoot, hCurrentSector, xInd)
	{
		/* compute border of sector object*/
		SECT_fn_vComputeBorder(hCurrentSector);
	}
}
/*End of Function*/
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by Oliv' */
 
//XB 16/06/99
void SECT_fn_vGetMinPointInBorder (SECT_tdxHandleOfSectorObject  _hSector,
								   MTH3D_tdstVector				*_p_stMinPoint)
{
	MTH3D_M_vCopyVector(_p_stMinPoint, &_hSector->stMinMaxPoints[0]);
}

void SECT_fn_vGetMaxPointInBorder (SECT_tdxHandleOfSectorObject	 _hSector,
								   MTH3D_tdstVector				*_p_stMaxPoint)
{
	MTH3D_M_vCopyVector(_p_stMaxPoint, &_hSector->stMinMaxPoints[1]);
}

void SECT_fn_vGetCenterOfBorder (SECT_tdxHandleOfSectorObject _hSector,
								 MTH3D_tdstVector			 *_p_stCenter)
{
	MTH3D_M_vAddVector(_p_stCenter, &_hSector->stMinMaxPoints[0], &_hSector->stMinMaxPoints[1]);
	MTH3D_M_vDivScalarVector(_p_stCenter, _p_stCenter, 2);
}

SECT_tdxHandleOfElementLstCharacter SECT_fn_hCreateElementLstCharacter(void)
{
  SECT_tdxHandleOfElementLstCharacter hCharacterElement;
  
  //hCharacterElement=(SECT_tdstListOfSOCharacters*)malloc( sizeof(SECT_tdstListOfSOCharacters));
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeSector , MMG_C_lSubTypeCharacterElement , 0 );
  GEO_M_CPAMalloc( hCharacterElement, SECT_tdstListOfSOCharacters*, sizeof(SECT_tdstListOfSOCharacters), E_uwGEONotEnoughtMemory);
  
  LST2_M_DynamicInitElement(hCharacterElement);
  return hCharacterElement;
}

void SECT_fn_vSetCharacterPointerInCharacterList(
                                                 SECT_tdxHandleOfElementLstCharacter hCharacterElement,
                                                 HIE_tdxHandleToSuperObject hSectorSuperObject
                                                 )
{
  hCharacterElement->hPointerOfCharacter= hSectorSuperObject;
}

SECT_tdxHandleOfElementLstDNMLights SECT_fn_hCreateElementLstDNMLights(void)
{
  SECT_tdxHandleOfElementLstDNMLights hDNMLightsElement;
  
  /*hDNMLightsElement=(SECT_tdxHandleOfElementLstDNMLights)malloc( sizeof(struct SECT_tdstListOfDNMLights_));*/
  MMG_fn_vAddMemoryInfo( MMG_C_lTypeSector , MMG_C_lSubTypeDNMLightElement , 0 );
  GEO_M_CPAMalloc( hDNMLightsElement, SECT_tdxHandleOfElementLstDNMLights, sizeof(struct SECT_tdstListOfDNMLights_), E_uwGEONotEnoughtMemory);
  
  LST2_M_DynamicInitElement(hDNMLightsElement);
  return hDNMLightsElement;
}

void SECT_fn_vSetHandleOfLightsInDNMLightsList(
                                               SECT_tdxHandleOfElementLstDNMLights hDNMLightsElement,
                                               GLI_tdxHandleToLight hDNMLights
                                               )
{
  hDNMLightsElement->hDNMLights= hDNMLights;
}
//End XB 16/06/99
 
/* Function*/
BOOL SECT_fn_bIsInBorderBox (MTH3D_tdstVector *_p_stPosition, SECT_tdxHandleOfSectorObject _hSector)
{
	MTH3D_tdstVector	stMin, stMax;
 
	/* get the border box of the sector*/
	SECT_fn_vGetMinPointInBorder(_hSector, &stMin);
	SECT_fn_vGetMaxPointInBorder(_hSector, &stMax);
 
	/* check X coordinates*/
	if ((_p_stPosition->xX < stMin.xX) || (_p_stPosition->xX > stMax.xX))
		return FALSE;
	/* check Y coordinates*/
	if ((_p_stPosition->xY < stMin.xY) || (_p_stPosition->xY > stMax.xY))
		return FALSE;
	/* check Z coordinates*/
	if ((_p_stPosition->xZ < stMin.xZ) || (_p_stPosition->xZ > stMax.xZ))
		return FALSE;
 
	/* point is in the box*/
	return TRUE;
}
/*End of Function*/
 
/*ENDANNECY Shaitan Add }*/
 
/*Function*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
ACP_tdxIndex SCT_fn_xGetSectorChangeHistory(HIE_tdxHandleToSuperObject **_p_hHistory)
{
  *_p_hHistory=SCT_a10_hSectorChangeHistory;
 
  return SCT_xNbChange;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*End of Function*/
 
 
 
/*Function*/
HIE_tdxHandleToSuperObject SECT_fn_hResearchInWhatSectorIAm ( HIE_tdxHandleToSuperObject SECT_hFatherSector,
                                                              MTH3D_tdstVector			 *p_stAbsolutePosition)
{
	SECT_tdxHandleOfSectorObject	hSectorObject;
	HIE_tdxHandleToSuperObject		hSectorWhereIAm;
	HIE_tdxHandleToSuperObject		hVirtualSectorWhereIAm;
	HIE_tdxHandleToSuperObject		hCurrentSector;
	HIE_tdxHandleToSuperObject		hLastSector=NULL;
	MTH3D_tdstVector				stDistance;
	ACP_tdxIndex					xInd;
	MTH_tdxReal						xNearDistance;
	MTH_tdxReal						xCurrentDistance;
	MTH_tdxReal						xVirtualDistance;
	char							cCurrentPriority;
	char							cVirtualPriority;
	
	/*Initialize to infinite*/
	cCurrentPriority		= C_SectorMinPriority;
	cVirtualPriority		= C_SectorMinPriority;
	xCurrentDistance		= MTH_C_InfinitPlus;
	xVirtualDistance		= MTH_C_InfinitPlus;
	xNearDistance			= MTH_C_InfinitPlus;
	hSectorWhereIAm			= NULL;
	hVirtualSectorWhereIAm	= NULL;
	
	HIE_M_ForEachChildOf(SECT_hFatherSector,hCurrentSector,xInd)
	{
		/*Take the sector object*/
		hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCurrentSector);
		
		hLastSector = hCurrentSector;
		
		if (SECT_fn_bIsInBorderBox(p_stAbsolutePosition, hSectorObject))
		{
			SECT_fn_vGetCenterOfBorder(hSectorObject, &stDistance);
			MTH3D_M_vSubVector(&stDistance, &stDistance, p_stAbsolutePosition);
			xNearDistance = MTH3D_M_xNormVector(&stDistance);
			if (!hSectorObject->xVirtual)
			{
				if (hSectorObject->cPriority > cCurrentPriority)
				{
					hSectorWhereIAm = hCurrentSector;
					xCurrentDistance = xNearDistance;
					cCurrentPriority = hSectorObject->cPriority;
				}
				else if ((hSectorObject->cPriority == cCurrentPriority) && (xNearDistance < xCurrentDistance))
				{
					hSectorWhereIAm = hCurrentSector;
					xCurrentDistance = xNearDistance;
				}
			}
			else
			{
				if (hSectorObject->cPriority > cVirtualPriority)
				{
					hVirtualSectorWhereIAm = hCurrentSector;
					xVirtualDistance = xNearDistance;
					cVirtualPriority = hSectorObject->cPriority;
				}
				else if ((hSectorObject->cPriority == cVirtualPriority) && (xNearDistance < xVirtualDistance))
				{
					hVirtualSectorWhereIAm = hCurrentSector;
					xVirtualDistance = xNearDistance;
				}
			}
		}
	}
	
	/* if there is no current sector, try with virtual*/
	if (hSectorWhereIAm == NULL)
		hSectorWhereIAm = hVirtualSectorWhereIAm;
	
	/* if there is no current sector, return UNIVERS sector*/
	if (hSectorWhereIAm == NULL)
		hSectorWhereIAm = hLastSector;
	
	return hSectorWhereIAm;
}
/*End of*/
 
 
/* Function*/
void SCT_fn_vTestChangeSectorWithHistory (MTH3D_tdstVector			 *_p_stBeforeAbsolutePosition,
                                          MTH3D_tdstVector			 *_p_stAfterAbsolutePosition,
                                          HIE_tdxHandleToSuperObject *_p_hSectorSOWhereIWas)
{
	SECT_tdxHandleOfElementLstCollisionInteraction	hCollisionNode;
	SECT_tdxHandleOfSectorObject					hSectorObject;
	SECT_tdxHandleOfSectorObject					hCurrentSectorObject;
	HIE_tdxHandleToSuperObject						hCurrentSector, hCollideSector;
	long											iInd;
 
	/* get current sector*/
    hCurrentSector = *_p_hSectorSOWhereIWas;
	hCurrentSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCurrentSector);
	/* if the sector has not changed, nothing to do*/
	if (SECT_fn_bIsInBorderBox(_p_stAfterAbsolutePosition, hCurrentSectorObject) && !hCurrentSectorObject->xVirtual)
	{
		/* check if we can change to a higher priority sector*/
		SECT_M_ForEachCollisionNodeInCollisionInteractionList(hCurrentSector, hCollisionNode, iInd)
		{
			/* get collide sector*/
			hCollideSector = SECT_GetSectorInCollisionList(hCollisionNode);
			hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCollideSector);
			/* if the priority is not higher, current sector must not change -> return*/
			if (hSectorObject->cPriority <= hCurrentSectorObject->cPriority)
				return;
			/* if the priority is higher and we are in the border, update the sector and return*/
/* Oliv' - 18/11/1998 - speedup process*/
			else if( !hSectorObject->xVirtual && SECT_fn_bIsInBorderBox(_p_stAfterAbsolutePosition,hSectorObject) )
/* EndOfOliv'*/
			{
				*_p_hSectorSOWhereIWas = hCollideSector;
				return;
			}
		}
		/* if no sector was found stay in this sector*/
		return;
	}
 
	/* check each sector in collision list*/
	SECT_M_ForEachCollisionNodeInCollisionInteractionList(hCurrentSector, hCollisionNode, iInd)
	{
		/* get collide sector*/
		hCollideSector = SECT_GetSectorInCollisionList(hCollisionNode);
		hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCollideSector);
		/* if this is the new current sector, update and return*/
/* Oliv' - 18/11/1998 - speedup process*/
		if( !hSectorObject->xVirtual && SECT_fn_bIsInBorderBox(_p_stAfterAbsolutePosition,hSectorObject) )
/* EndOfOliv'*/
		{
			*_p_hSectorSOWhereIWas = hCollideSector;
			return;
		}
	}
	/* sector was not found => try with picking*/
	*_p_hSectorSOWhereIWas = SECT_fn_hResearchInWhatSectorIAm(HIE_fn_hGetSuperObjectFather(hCurrentSector), _p_stAfterAbsolutePosition);
 
}
/*End of function*/
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void SECT_fn_vTestChangeSector (MTH3D_tdstVector			*p_stBeforeAbsolutePosition,
                                MTH3D_tdstVector			*p_stAfterAbsolutePosition,
                                HIE_tdxHandleToSuperObject	*_p_hSectorSOWhereIWas)
{
	SECT_tdxHandleOfElementLstCollisionInteraction	hCollisionNode;
	SECT_tdxHandleOfSectorObject					hSectorObject;
	SECT_tdxHandleOfSectorObject					hCurrentSectorObject;
	HIE_tdxHandleToSuperObject						hCurrentSector, hCollideSector;
	long											iInd;
 
	/* get current sector*/
    hCurrentSector = *_p_hSectorSOWhereIWas;
	hCurrentSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCurrentSector);
	/* if the sector has not changed, nothing to do*/
	if (SECT_fn_bIsInBorderBox(p_stAfterAbsolutePosition, hCurrentSectorObject) && !hCurrentSectorObject->xVirtual)
	{
		/* check if we can change to a higher priority sector*/
		SECT_M_ForEachCollisionNodeInCollisionInteractionList(hCurrentSector, hCollisionNode, iInd)
		{
			/* get collide sector*/
			hCollideSector = SECT_GetSectorInCollisionList(hCollisionNode);
			hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCollideSector);
			/* if the priority is not higher, current sector must not change -> return*/
			if (hSectorObject->cPriority <= hCurrentSectorObject->cPriority)
				return;
			/* if the priority is higher and we are in the border, update the sector and return*/
			else if (SECT_fn_bIsInBorderBox(p_stAfterAbsolutePosition, hSectorObject) && !hSectorObject->xVirtual)
			{
				*_p_hSectorSOWhereIWas = hCollideSector;
				return;
			}
		}
		/* if no sector was found stay in this sector*/
		return;
	}
 
	/* check each sector in collision list*/
	SECT_M_ForEachCollisionNodeInCollisionInteractionList(hCurrentSector, hCollisionNode, iInd)
	{
		/* get collide sector*/
		hCollideSector = SECT_GetSectorInCollisionList(hCollisionNode);
		hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hCollideSector);
		/* if this is the new current sector, update and return*/
		if (SECT_fn_bIsInBorderBox(p_stAfterAbsolutePosition, hSectorObject) && !hSectorObject->xVirtual)
		{
			*_p_hSectorSOWhereIWas = hCollideSector;
			return;
		}
	}
	/* sector was not found => try with picking*/
	*_p_hSectorSOWhereIWas = SECT_fn_hResearchInWhatSectorIAm(HIE_fn_hGetSuperObjectFather(hCurrentSector), p_stAfterAbsolutePosition);
 
}
 
/*Function*/
void fn_vGetNextSector(HIE_tdxHandleToSuperObject *_p_hSectorSOWhereIWas,
                       ACP_tdxHandleOfObject _hObjectGeometric,
                       GLI_tdstDataOfElement *_p_stDataPickedObject)
{
		switch ( _hObjectGeometric->d_xListOfElementsTypes [_p_stDataPickedObject->xElements] )
    {
				case GEO_C_xElementIndexedTriangles :
          *_p_hSectorSOWhereIWas=(HIE_tdxHandleToSuperObject)
            ((struct GEO_tdstElementIndexedTriangles_ **)
            (_hObjectGeometric->d_stListOfElements))[_p_stDataPickedObject->xElements]->hMaterial;
          break;
        case GEO_C_xElementFaceMapDescriptors :
          *_p_hSectorSOWhereIWas=(HIE_tdxHandleToSuperObject)
            ((struct GEO_tdstElementFaceMapDescriptors_**)
            (_hObjectGeometric->d_stListOfElements))[_p_stDataPickedObject->xElements]->d_stListOfFacesQuadrupled[_p_stDataPickedObject->xIndexOfFace].hFaceMapDescriptor->hMaterial;
          break;
    }
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*End of*/
 
 
/*/////////////////////////////*/
void SECT_fn_vIsolateCharListNode(
                                  SECT_tdxHandleOfElementLstCharacter hNode)
{
  LST2_M_DynamicIsolate( hNode);
}
void SECT_fn_vAddTailCharListNode(
                                  HIE_tdxHandleToSuperObject hSector,
                                  SECT_tdxHandleOfElementLstCharacter hNode)
{
  LST2_M_DynamicAddTail( &((SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSector))->stListOfCharacters,hNode);
}
void SECT_fn_vAddHeadCharListNode(
                                  HIE_tdxHandleToSuperObject hSector,
                                  SECT_tdxHandleOfElementLstCharacter hNode)
{
  LST2_M_DynamicAddHead( &((SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSector))->stListOfCharacters,hNode);
}
 
/*//////////////////////*/
void SECT_fn_vIsolateDNMLightsListNode(
                                       SECT_tdxHandleOfElementLstDNMLights hNode)
{
  LST2_M_DynamicIsolate( hNode);
}
void SECT_fn_vAddTailDNMLightsListNode(
                                       HIE_tdxHandleToSuperObject hSector,
                                       SECT_tdxHandleOfElementLstDNMLights hNode)
{
  LST2_M_DynamicAddTail( &((SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSector))->stListOfDNMLights, hNode);
}
 
 
/*//////////////////////*/
#ifdef ACTIVE_EDITOR
 
void SECT_fn_vIsolateStaticLightsListNode(
                                          SECT_tdxHandleOfElementLstStaticLights _hNode)
{
  LST2_M_StaticIsolate( _hNode);
}
 
void SECT_fn_vDestructStaticLightsListNode(SECT_tdxHandleOfElementLstStaticLights _hNode)
{
  SECT_fn_vIsolateStaticLightsListNode(_hNode);
  
  _hNode->hStaticLights=NULL;
  
  GEO_M_CPAFree(_hNode);
}
 
void SECT_fn_vAddTailStaticLightsListNode(
                                          HIE_tdxHandleToSuperObject hSector,
                                          SECT_tdxHandleOfElementLstStaticLights hNode)
{
  LST2_M_StaticAddTail( &((SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSector))->stListOfStaticLights,hNode);
}
 
#endif /* ACTIVE_EDITOR */
 
/****** DEMO FIN*/
 
/*Function*/
void fn_vGeneralCoherenceOfSmoothing(HIE_tdxHandleToSuperObject   hSprObjSector)
{
  ACP_tdxIndex xI;
  HIE_tdxHandleToSuperObject hElement;
  
  
  HIE_M_ForEachChildOf( hSprObjSector,hElement,xI)
  {
    fn_vCoherenceOfSmoothing(hElement);
  }
}
/*End of*/
 
 
 
/*Function*/
void fn_vCoherenceOfSmoothing(HIE_tdxHandleToSuperObject   hSprObjSector)
{
  SECT_tdxHandleOfElementLstGraphicInteraction hGraphicInteractionChild;
  SECT_tdxHandleOfSectorObject hSectorObject;
  HIE_tdxHandleToSuperObject hExploredChild;
  HIE_tdxHandleToSuperObject hNeighbourChild;
  ACP_tdxHandleOfObject hPhysicalExploredObject;
  ACP_tdxHandleOfObject hPhysicalNeighbourObject;
  MTH3D_tdstVector xNormal1;
  MTH3D_tdstVector xNormal2;
  ACP_tdxIndex xI;
  ACP_tdxIndex xIndex1;
  ACP_tdxIndex xIndex2;
  ACP_tdxIndex xJ;
  ACP_tdxIndex xK;
#ifndef U64
  ACP_tdxIndex xL;
  ACP_tdxIndex xCommonVertexIndex;
  SCT_tdstCommonVertices a30_stArrayOfCommonVertices[30];
#endif
#ifndef D_THROW_VISUAL_SET
  MTH_tdxReal xTemp;
#endif
  
  /*take the object*/
  hSectorObject=(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSprObjSector);
  
  /*For the Children*/
  HIE_M_ForEachChildOf(hSprObjSector, hExploredChild, xI)
  {
    /*If it is a good Element*/
    if(HIE_fn_ulGetSuperObjectType(hExploredChild)==HIE_C_ulEDT_Geometric)
    {
      hPhysicalExploredObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(hExploredChild);
      
      /* For each point*/
      for(xJ=0;xJ<hPhysicalExploredObject->xNbPoints;xJ++)
      {
        /* For each sector in graphic interaction*/
        LST2_M_StaticForEachElementOf(  &(hSectorObject->stListOfSectorsInGraphicInteraction), hGraphicInteractionChild, xIndex1)
        {
          /*For each Child*/
          HIE_M_ForEachChildOf(hGraphicInteractionChild->hPointerOfSectorSO, hNeighbourChild, xIndex2)
          {
            /*if it is good Child*/
            if(HIE_fn_ulGetSuperObjectType(hNeighbourChild)==HIE_C_ulEDT_Geometric)
            {
              hPhysicalNeighbourObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(hNeighbourChild);
              /*Search the point in a other object*/
              for(xK=0;xK<hPhysicalNeighbourObject->xNbPoints;xK++)
              {
                if(
                  MTH3D_M_bEqualVector( &(hPhysicalExploredObject->d_stListOfPoints[xJ]),
                  &(hPhysicalNeighbourObject->d_stListOfPoints[xK]))
                  
                  )
                {
                  /*if the normals are different*/
                  if(
                    !(MTH3D_M_bEqualVector( &(hPhysicalExploredObject->d_stListOfPointsNormals[xJ]),
                    &(hPhysicalNeighbourObject->d_stListOfPointsNormals[xK])))
                    )
                  {
                    /*compute the new normal*/
                    xNormal1=fn_xComputeNormalOfPoint(xJ,hPhysicalExploredObject);
                    xNormal2=fn_xComputeNormalOfPoint(xK,hPhysicalNeighbourObject);
                    MTH3D_M_vAddVector(&xNormal1,&xNormal1,&xNormal2 );
                    if(!MTH3D_M_bIsNullVector(&xNormal1))
                      MTH3D_M_vNormalizeVector(&xNormal1,&xNormal1);
                    
                    MTH3D_M_vCopyVector(&(hPhysicalExploredObject->d_stListOfPointsNormals[xJ]),&xNormal1);
                    MTH3D_M_vCopyVector(&(hPhysicalNeighbourObject->d_stListOfPointsNormals[xK]),&xNormal1);
                  }
                }
              }
            }
          }
        }
      }
    }
    
    /*If it is a good Element*/
/*XB980821*/
#ifndef D_THROW_IPO
    if(HIE_fn_ulGetSuperObjectType(hExploredChild) & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
    {
      GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(hExploredChild))),
        0L,
        &xTemp,
        &hPhysicalExploredObject);
      
      /* For each point*/
      for(xJ=0;xJ<hPhysicalExploredObject->xNbPoints;xJ++)
      {
        /*Initialyse array of common vertices*/
        xCommonVertexIndex=0;
 
        /* For each sector in graphic interaction*/
        LST2_M_StaticForEachElementOf(  &(hSectorObject->stListOfSectorsInGraphicInteraction), hGraphicInteractionChild, xIndex1)
        {
          /*For each Child*/
          HIE_M_ForEachChildOf(hGraphicInteractionChild->hPointerOfSectorSO, hNeighbourChild, xIndex2)
          {
            /*if it is good Child*/
            if(HIE_fn_ulGetSuperObjectType(hNeighbourChild) & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
            {
              GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(hNeighbourChild))),
                0L,
                &xTemp,
                &hPhysicalNeighbourObject);
              /*Search the point in a other object*/
              for(xK=0;xK<hPhysicalNeighbourObject->xNbPoints;xK++)
              {
                if(
                    /*Warning no use of MTH*/
                    (hPhysicalExploredObject->d_stListOfPoints[xJ].xX-hPhysicalNeighbourObject->d_stListOfPoints[xK].xX)
                    *(hPhysicalExploredObject->d_stListOfPoints[xJ].xX-hPhysicalNeighbourObject->d_stListOfPoints[xK].xX)
                    +
                    (hPhysicalExploredObject->d_stListOfPoints[xJ].xY-hPhysicalNeighbourObject->d_stListOfPoints[xK].xY)
                    *(hPhysicalExploredObject->d_stListOfPoints[xJ].xY-hPhysicalNeighbourObject->d_stListOfPoints[xK].xY)
                    +
                    (hPhysicalExploredObject->d_stListOfPoints[xJ].xZ-hPhysicalNeighbourObject->d_stListOfPoints[xK].xZ)
                    *(hPhysicalExploredObject->d_stListOfPoints[xJ].xZ-hPhysicalNeighbourObject->d_stListOfPoints[xK].xZ)
                    <0.0001f
 
 
 
                  )
                {
                  /*Upgrade Array of Common Vertices*/
                  a30_stArrayOfCommonVertices[xCommonVertexIndex].xVertexIndex=xK;
                  a30_stArrayOfCommonVertices[xCommonVertexIndex].hPhysicalObject=hPhysicalNeighbourObject;
                  xCommonVertexIndex++;
 
                  MTH3D_M_vCopyVector(&(hPhysicalExploredObject->d_stListOfPoints[xJ]),&(hPhysicalNeighbourObject->d_stListOfPoints[xK]));
                }
              }
            }
          }
        }
        /*Compute the normal*/
        if(xCommonVertexIndex)
        {
          xNormal1=fn_xComputeNormalOfPoint(xJ,hPhysicalExploredObject);
          
          /*compute the sum of normals*/
          for(xL=0;xL<xCommonVertexIndex;xL++)
          {
            xNormal2=fn_xComputeNormalOfPoint(a30_stArrayOfCommonVertices[xL].xVertexIndex,
                                              a30_stArrayOfCommonVertices[xL].hPhysicalObject);
            MTH3D_M_vAddVector(&xNormal1,&xNormal1,&xNormal2 );
          }
 
          /*Normalise normal*/
          if(!MTH3D_M_bIsNullVector(&xNormal1))
          {
            MTH3D_M_vNormalizeVector(&xNormal1,&xNormal1);
          }
          
          MTH3D_M_vCopyVector(&(hPhysicalExploredObject->d_stListOfPointsNormals[xJ]),&xNormal1);
          
          for(xL=0;xL<xCommonVertexIndex;xL++)
          {
            MTH3D_M_vCopyVector(&(a30_stArrayOfCommonVertices[xL].hPhysicalObject->d_stListOfPointsNormals[a30_stArrayOfCommonVertices[xL].xVertexIndex]),&xNormal1);
          }
        }
      }
    }
#endif /* D_THROW_IPO */
/*End XB*/
 
    /*If it is a good Element*/
    if(HIE_fn_ulGetSuperObjectType(hExploredChild)==HIE_C_ulPO)
    {
      /*To Modify Visual*/
#ifndef D_THROW_VISUAL_SET
      GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hExploredChild)),
        0L,
        &xTemp,
        &hPhysicalExploredObject);
#else
			hPhysicalExploredObject=PO_fn_hGetGeometricObject((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hExploredChild));
#endif /* D_THROW_VISUAL_SET */
      
      /* For each point*/
      for(xJ=0;xJ<hPhysicalExploredObject->xNbPoints;xJ++)
      {
        /* For each sector in graphic interaction*/
        LST2_M_StaticForEachElementOf(  &(hSectorObject->stListOfSectorsInGraphicInteraction), hGraphicInteractionChild, xIndex1)
        {
          /*For each Child*/
          HIE_M_ForEachChildOf(hGraphicInteractionChild->hPointerOfSectorSO, hNeighbourChild, xIndex2)
          {
            /*if it is good Child*/
            if(HIE_fn_ulGetSuperObjectType(hNeighbourChild)==HIE_C_ulPO)
            {
              /*To Modify Visual*/
#ifndef D_THROW_VISUAL_SET
              GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hNeighbourChild)),
                0L,
                &xTemp,
                &hPhysicalNeighbourObject);
#else
							hPhysicalNeighbourObject=PO_fn_hGetGeometricObject((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hNeighbourChild));
#endif /* D_THROW_VISUAL_SET */
              /*Search the point in a other object*/
              for(xK=0;xK<hPhysicalNeighbourObject->xNbPoints;xK++)
              {
                if(
                  MTH3D_M_bEqualVector( &(hPhysicalExploredObject->d_stListOfPoints[xJ]),
                  &(hPhysicalNeighbourObject->d_stListOfPoints[xK]))
                  
                  )
                {
                  /*if the normals are different*/
                  if(
                    !(MTH3D_M_bEqualVector( &(hPhysicalExploredObject->d_stListOfPointsNormals[xJ]),
                    &(hPhysicalNeighbourObject->d_stListOfPointsNormals[xK])))
                    )
                  {
                    /*compute the new normal*/
                    xNormal1=fn_xComputeNormalOfPoint(xJ,hPhysicalExploredObject);
                    xNormal2=fn_xComputeNormalOfPoint(xK,hPhysicalNeighbourObject);
                    MTH3D_M_vAddVector(&xNormal1,&xNormal1,&xNormal2 );
                    if(!MTH3D_M_bIsNullVector(&xNormal1))
                      MTH3D_M_vNormalizeVector(&xNormal1,&xNormal1);
                    
                    MTH3D_M_vCopyVector(&(hPhysicalExploredObject->d_stListOfPointsNormals[xJ]),&xNormal1);
                    MTH3D_M_vCopyVector(&(hPhysicalNeighbourObject->d_stListOfPointsNormals[xK]),&xNormal1);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
/*End function*/
 
 
 
 
/*Function*/
MTH3D_tdstVector fn_xComputeNormalOfPoint(ACP_tdxIndex xI, ACP_tdxHandleOfObject hPhysical)
{
  ACP_tdxIndex xElement;
  ACP_tdxIndex xFaces;
  struct GEO_tdstElementIndexedTriangles_ *stIndexedTriangles;
/* XB 05/05/99 */
#ifndef U64
   struct GEO_tdstElementFaceMapDescriptors_ *stFaceMapDescriptors; 
#endif
/* End XB 05/05/99 */
  MTH3D_tdstVector xNormalReturn;
  MTH3D_tdstVector xTempNormal;
  
  /*Initialize xNormalReturn*/
  MTH3D_M_vSetVectorElements( &xNormalReturn,MTH_C_ZERO,MTH_C_ZERO,MTH_C_ZERO);
  
  /*for each element*/
  for(xElement=0;xElement<hPhysical->xNbElements;xElement++)
  {
    switch ( hPhysical->d_xListOfElementsTypes[xElement] )
    {
    case GEO_C_xElementIndexedTriangles :
      stIndexedTriangles=	((struct GEO_tdstElementIndexedTriangles_ **)
        (hPhysical->d_stListOfElements))[xElement];
      for(xFaces=0;xFaces<stIndexedTriangles->xNbFaces;xFaces++)
      {
        if(
          (stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[0]==xI)
          ||
          (stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[1]==xI)
          ||
          (stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[2]==xI)
          )
        {
          GEO_xComputeNormalWeightedBySurf(
            &xTempNormal,
            &(hPhysical->d_stListOfPoints[stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[0]]),
            &(hPhysical->d_stListOfPoints[stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[1]]),
            &(hPhysical->d_stListOfPoints[stIndexedTriangles->d_stListOfFacesTripled[xFaces].a3_xIndex[2]])
            );
          MTH3D_M_vAddVector(&xNormalReturn,&xNormalReturn,&xTempNormal);
        }
        
      }
      break;
//XB99/04/27
#ifndef U64
    case GEO_C_xElementFaceMapDescriptors :
      stFaceMapDescriptors=((struct GEO_tdstElementFaceMapDescriptors_**)
        (hPhysical->d_stListOfElements))[xElement];
      /*->d_stListOfFacesQuadrupled[].hFaceMapDescriptor->;*/
      break;
#endif U64
//End XB99/04/27
    }
  }
  return xNormalReturn;
}
/*End function*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void SCT_fn_vClearCharacterSectorLink(SECT_tdxHandleOfElementLstCharacter hLstChar)
{
 LST2_M_DynamicSetNextElement(hLstChar,NULL);
 LST2_M_DynamicSetPrevElement(hLstChar,NULL);
 LST2_M_DynamicSetFather(hLstChar,NULL);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void SCT_fn_vClearLightSectorLink(SECT_tdxHandleOfElementLstDNMLights hLstLight)
{
 LST2_M_DynamicSetNextElement(hLstLight,NULL);
 LST2_M_DynamicSetPrevElement(hLstLight,NULL);
 LST2_M_DynamicSetFather(hLstLight,NULL);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*	Quick'n dirty Fix for binarisation (Ronan Bel)*/
 
 
 
/* JO 09/12/97*/
#if (defined(_DEBUG) || defined(USE_PROFILER))
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
char * fn_szGetSectorName(HIE_tdxHandleToSuperObject _hSector)
{
   SECT_tdxHandleOfSectorObject hSectorObject;
	
   if(HIE_fn_ulGetSuperObjectType(_hSector)==HIE_C_ulSector)
   {
      /*take the object*/
      hSectorObject = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSector);
		return( hSectorObject->szSectorName );
	}      
   else
	   return NULL;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
#endif /* _DEBUG || USE_PROFILER */
 
/* ANNECY AV {*/
ACP_tdxBool SECT_fn_bIsThisSectorVirtual (HIE_tdxHandleToSuperObject _hSprObjSector)
{
    return ((SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject (_hSprObjSector)) -> xVirtual;
}
/* END ANNECY AV }*/
 
/* ANNECY MT - 09/09/98 {*/
ACP_tdxBool SECT_fn_bIsThisSectorUniverse (HIE_tdxHandleToSuperObject _hSprObjSector)
{
    return (HIE_fn_hForceGetSuperObjectNextBrother(_hSprObjSector) == NULL);
}
/* END ANNECY MT }*/
 
char fn_cGetSectorCameraType(HIE_tdxHandleToSuperObject _hSprObjSector)
{
    return ((SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject (_hSprObjSector)) -> cCameraType;
}
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vSetSectorCameraType(HIE_tdxHandleToSuperObject _hSprObjSector, char cType)
{
    ((SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject (_hSprObjSector)) -> cCameraType = cType;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/*
 =======================================================================================
	Access function for ZFar sector member 
 =======================================================================================
 */
MTH_tdxReal fn_xGetSectorZFar(HIE_tdxHandleToSuperObject _hSprObjSector)
{
    return ((SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject (_hSprObjSector))->xZFar;
}
 
/*Function*/
MTH3D_tdstVector *SECT_fn_p_stGetMinPointInBorder(SECT_tdxHandleOfSectorObject  _hSector)
{
	return &_hSector->stMinMaxPoints[0];
}
/*End of*/
 
/*Function*/
MTH3D_tdstVector *SECT_fn_p_stGetMaxPointInBorder(SECT_tdxHandleOfSectorObject  _hSector)
{
	return &_hSector->stMinMaxPoints[1];
}
/*End of*/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vSetSectorZFar(HIE_tdxHandleToSuperObject _hSprObjSector, MTH_tdxReal _xZFar)
{
    ((SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject (_hSprObjSector))->xZFar = _xZFar;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
