/* (c) Ubi Studios 1997 */
/* See Vincent Greco  or Frederic Philippe for any comment or question */
 
#include "ACP_base.h"
 
#include "GEO.h"
#include "GLI.h"
#include "COL.h"
 
#include "PCS.h"
#include "PO.h"
#include "IPO.h"
#include "SCT.h"
#undef extern /*for PO (and AI)*/
 
#include "SPO/HieConst.h"
 
#include "LST.h"
#include "SPO/HieSpObj.h"
#include "SPO/HieHand.h"
#include "SPO/HieDef.h"
#include "SPO/HieMacro.h"
#include "SPO/HieMtStk.h"
#include "SPO/HieExt.h"
#include "SPO\HieBdVol.h"
 

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

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

MTH_tdxReal VoidReal;
ACP_tdxHandleOfObject GeoHandle;
/*-----------------------------------------------------------------------------*/
#define M_hGetRepositionZoneFromPo(Po)	\
(GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle)
/*-----------------------------------------------------------------------------*/
ACP_tdxBool HIE_fn_bIsChildInsideHisFather( ACP_tdxBool bFatherBox, void * hFatherBdV,
										    ACP_tdxBool bChildBox, void *hChildBdV,
											MTH3D_tdstVector	* _p_stTranslation)
{
	GEO_tdxHandleToParallelBox		hFatherBox;
	GEO_tdxHandleToParallelBox		hChildBox;
	MTH3D_tdstVector				stMaxChildPoint;	
	MTH3D_tdstVector				stMinChildPoint;	
	MTH3D_tdstVector				stChildCenter;	
	MTH_tdxReal						xChildRadius;	
 
	MTH3D_tdstVector		*		p_stFatherMax;	
	MTH3D_tdstVector		*		p_stFatherMin;	
	MTH3D_tdstVector				stFatherCenter;	
	MTH_tdxReal						xFatherRadius;	
 
	if(bFatherBox)
	{
		hFatherBox = (GEO_tdxHandleToParallelBox)hFatherBdV;
		p_stFatherMax = GEO_fn_pGetMaxPointOfParallelBox(hFatherBox);
		p_stFatherMin = GEO_fn_pGetMinPointOfParallelBox(hFatherBox);
		if(bChildBox)
		/* Father ---> Box*/
		/* Child  ---> Box*/
		{
			MTH3D_tdstVector	*p_stMinPoint;
			MTH3D_tdstVector	*p_stMaxPoint;
 
			hChildBox = (GEO_tdxHandleToParallelBox)hChildBdV;
			
			p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hChildBox);
			p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hChildBox);
			
			MTH3D_M_vAddVector(&stMinChildPoint, p_stMinPoint , _p_stTranslation);
			MTH3D_M_vAddVector(&stMaxChildPoint, p_stMaxPoint , _p_stTranslation);					 
 
 
			return( MTH_M_bLessEqual (MTH3D_M_xGetXofVector(&stMaxChildPoint), MTH3D_M_xGetXofVector(p_stFatherMax)) &&
				MTH_M_bLessEqual (MTH3D_M_xGetXofVector(p_stFatherMin), MTH3D_M_xGetXofVector(&stMinChildPoint)) &&
				MTH_M_bLessEqual (MTH3D_M_xGetYofVector(&stMaxChildPoint), MTH3D_M_xGetYofVector(p_stFatherMax)) &&
				MTH_M_bLessEqual (MTH3D_M_xGetYofVector(p_stFatherMin), MTH3D_M_xGetYofVector(&stMinChildPoint)) &&
				MTH_M_bLessEqual (MTH3D_M_xGetZofVector(&stMaxChildPoint), MTH3D_M_xGetZofVector(p_stFatherMax)) &&
				MTH_M_bLessEqual (MTH3D_M_xGetZofVector(p_stFatherMin), MTH3D_M_xGetZofVector(&stMinChildPoint)));
		}
		else
		/* Father ---> Box*/
		/* Child  ---> Sphere*/
		{
			xChildRadius = GEO_fn_xGetRadiusOfBoundingSphere(hChildBdV);
			MTH3D_M_vAddVector(&stChildCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hChildBdV), _p_stTranslation);
 
			return( MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetXofVector(p_stFatherMax), MTH3D_M_xGetXofVector(&stChildCenter))) &&
				MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetXofVector(&stChildCenter), MTH3D_M_xGetXofVector(p_stFatherMin))) &&
				MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetYofVector(p_stFatherMax), MTH3D_M_xGetYofVector(&stChildCenter))) &&
				MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetYofVector(&stChildCenter), MTH3D_M_xGetYofVector(p_stFatherMin))) &&
				MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetZofVector(p_stFatherMax), MTH3D_M_xGetZofVector(&stChildCenter))) &&
				MTH_M_bLessEqual (xChildRadius, MTH_M_xSub( MTH3D_M_xGetZofVector(&stChildCenter), MTH3D_M_xGetZofVector(p_stFatherMin))));
		}
	}
	else
	{
		MTH3D_M_vCopyVector( &stChildCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hFatherBdV));
		xFatherRadius = GEO_fn_xGetRadiusOfBoundingSphere(hFatherBdV);
		MTH3D_M_vAddVector(&stFatherCenter, &stFatherCenter, _p_stTranslation);
		if(bChildBox)
		/* Father ---> Sphere*/
		/* Child  ---> Box*/
		{
			MTH3D_tdstVector	*p_stMinPoint;
			MTH3D_tdstVector	*p_stMaxPoint;
 
			hChildBox = (GEO_tdxHandleToParallelBox)hChildBdV;
			
			p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hChildBox);
			p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hChildBox);
			
			MTH3D_M_vAddVector(&stMinChildPoint, p_stMinPoint , _p_stTranslation);
			MTH3D_M_vAddVector(&stMaxChildPoint, p_stMaxPoint , _p_stTranslation);					 
			
 
			return( MTH_M_bLessEqual( MTH3D_M_xGetXofVector(&stMaxChildPoint), MTH_M_xAdd(MTH3D_M_xGetXofVector(&stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub(MTH3D_M_xGetXofVector(&stFatherCenter), xFatherRadius),  MTH3D_M_xGetXofVector(&stMinChildPoint)) &&
				MTH_M_bLessEqual( MTH3D_M_xGetYofVector(&stMaxChildPoint), MTH_M_xAdd(MTH3D_M_xGetYofVector(&stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub(MTH3D_M_xGetYofVector(&stFatherCenter), xFatherRadius),  MTH3D_M_xGetYofVector(&stMinChildPoint)) &&
				MTH_M_bLessEqual( MTH3D_M_xGetZofVector(&stMaxChildPoint), MTH_M_xAdd(MTH3D_M_xGetZofVector(&stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub(MTH3D_M_xGetZofVector(&stFatherCenter), xFatherRadius),  MTH3D_M_xGetZofVector(&stMinChildPoint)));
		}
		else
		/* Father ---> Sphere*/
		/* Child  ---> Sphere*/
		{
			MTH3D_M_vCopyVector( &stChildCenter, GEO_fn_pGetCenterPointOfBoundingSphere(hChildBdV));
			MTH3D_M_vAddVector(&stChildCenter, &stChildCenter, _p_stTranslation);
			xChildRadius = GEO_fn_xGetRadiusOfBoundingSphere(hChildBdV);
 
			return( MTH_M_bLessEqual( MTH_M_xAdd (MTH3D_M_xGetXofVector( &stChildCenter), xChildRadius), MTH_M_xAdd (MTH3D_M_xGetXofVector( &stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub (MTH3D_M_xGetXofVector( &stFatherCenter), xFatherRadius), MTH_M_xSub (MTH3D_M_xGetXofVector( &stChildCenter), xChildRadius)) &&
				MTH_M_bLessEqual( MTH_M_xAdd (MTH3D_M_xGetYofVector( &stChildCenter), xChildRadius), MTH_M_xAdd (MTH3D_M_xGetYofVector( &stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub (MTH3D_M_xGetYofVector( &stFatherCenter), xFatherRadius), MTH_M_xSub (MTH3D_M_xGetYofVector( &stChildCenter), xChildRadius)) &&
				MTH_M_bLessEqual( MTH_M_xAdd (MTH3D_M_xGetZofVector( &stChildCenter), xChildRadius), MTH_M_xAdd (MTH3D_M_xGetZofVector( &stFatherCenter), xFatherRadius)) &&
				MTH_M_bLessEqual( MTH_M_xSub (MTH3D_M_xGetZofVector( &stFatherCenter), xFatherRadius), MTH_M_xSub (MTH3D_M_xGetZofVector( &stChildCenter), xChildRadius)));
		}
	}
}

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
int level = 0;
int ddd;
char	tab[512];
char	*tab2;

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

/*-----------------------------------------------------------------------------*/
void HIE_fn_vComputeAllBoundingVolumes(HIE_tdxHandleToSuperObject _hSprObj)
 
{
	ACP_tdxIndex						xIndex;
	long								lType;
	MTH3D_tdstVector					stGlobalMaxBoxPoint;
	MTH3D_tdstVector					stGlobalMinBoxPoint;
	MTH3D_tdstVector					stLocalMaxBoxPoint;
	MTH3D_tdstVector					stLocalMinBoxPoint;
	MTH3D_tdstVector					stFatherCenter;
	MTH_tdxReal							xFatherRadius;
	HIE_tdxHandleToSuperObject			hChild;
	ACP_tdxHandleOfObject				hGeometricObject;
	ACP_tdxHandleOfObject				hCollideGeometricObject;
	PO_tdxHandleToPhysicalObject		hTempPo;
	GEO_tdxHandleToMatrix				hGlobalMatrix;
	GEO_tdxHandleToMatrix				hLocalMatrix;
	GEO_tdxHandleToParallelBox			hFatherBox;
	GEO_tdxHandleToBoundingSphere		hFatherSphere;
	ACP_tdxBool							bFatherBoundingBox;
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	char txt[20];

#endif //U64CONVERTLOG
// } fin N64-format
	
	hFatherBox = NULL;
	
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	level++;
	tab[0] = 0;

	sprintf (txt,"\t");
	for (ddd=0;ddd<level;ddd++)
	{
		strcat(tab,txt);
	}

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

	
	bFatherBoundingBox = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj);
	hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj);
	lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
	
	if(bFatherBoundingBox)
	{
		if(lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
		{
			assert(0);
			hFatherBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
			if(!hFatherBox)
				GEO_fn_vCreateParallelBox(&hFatherBox);
			
			hTempPo=(PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
			hGeometricObject=M_hGetRepositionZoneFromPo(hTempPo);
			hCollideGeometricObject = (PO_fn_hGetCollideSet(hTempPo)) ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet(PO_fn_hGetCollideSet(hTempPo)) : NULL;
#ifdef USE_ALTIMAPS
			if( hGeometricObject->d_xListOfElementsTypes[0] == GEO_C_xElementAltimap )
			{
				MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
				MTH3D_M_vCopyVector(&stLocalMinBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
			}
			else
#endif /*USE_ALTIMAPS*/
			/* Oliv' - 19/05/1998*/
			if( hGeometricObject->d_stListOfPoints )
			{
				MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, hGeometricObject->d_stListOfPoints);
				MTH3D_M_vCopyVector(&stLocalMinBoxPoint, hGeometricObject->d_stListOfPoints);
			}
			else
			{
#if defined(U64)
				MTH_tdxReal xTemp;
				xTemp = MTH_M_xFloatToReal( (float)sqrt(2.0f) * hGeometricObject->fRadius );
				MTH3D_M_vSetVectorElements( &stLocalMaxBoxPoint, xTemp, xTemp, xTemp );
				MTH3D_M_vNegVector( &stLocalMinBoxPoint, &stLocalMaxBoxPoint );
#else
				MTH3D_M_vNullVector(&stLocalMaxBoxPoint);
				MTH3D_M_vNullVector(&stLocalMinBoxPoint);
#endif /* U64 */
			}
			
			MTH3D_M_vMulMatrixVector ( &stGlobalMaxBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
			MTH3D_M_vMulMatrixVector ( &stGlobalMinBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
			GEO_fn_vAddObjectToBox(hGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);	
			if(hCollideGeometricObject)
				GEO_fn_vAddObjectToBox(hCollideGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);	
 
		}
		/*The linked object is an IPO*/
		if(lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
		{
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
			SCR_tdst_Link_Value   *test;

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

			hFatherBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
			if(!hFatherBox)			
				GEO_fn_vCreateParallelBox(&hFatherBox);
			hTempPo=IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
			test = SCR_fnp_st_Link_SearchValue(&PO_g_stLinkTable, (unsigned long)hTempPo);
			if (test != NULL)
			{
				tab2 = SCR_M_p_sz_Link_GetKey(test);
			}
			else
			{
				tab2 = NULL;
			}

#endif //U64CONVERTLOG
// } fin N64-format
			hGeometricObject=M_hGetRepositionZoneFromPo(hTempPo);
			hCollideGeometricObject = (PO_fn_hGetCollideSet(hTempPo)) ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet(PO_fn_hGetCollideSet(hTempPo)) : NULL;
#ifdef USE_ALTIMAPS
			if( hGeometricObject->d_xListOfElementsTypes[0] == GEO_C_xElementAltimap )
			{
				MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
				MTH3D_M_vCopyVector(&stLocalMinBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
			}
			else
#endif /*USE_ALTIMAPS*/
			/* Oliv' - 19/05/1998*/
				if( hGeometricObject->d_stListOfPoints )
					
				{
					MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, hGeometricObject->d_stListOfPoints);
					MTH3D_M_vCopyVector(&stLocalMinBoxPoint, hGeometricObject->d_stListOfPoints);
				}
				else
				{
#if defined(U64)
				MTH_tdxReal xTemp;
				xTemp = MTH_M_xFloatToReal( (float)sqrt(2.0f) * hGeometricObject->fRadius );
				MTH3D_M_vSetVectorElements( &stLocalMaxBoxPoint, xTemp, xTemp, xTemp );
				MTH3D_M_vNegVector( &stLocalMinBoxPoint, &stLocalMaxBoxPoint );
#else
				MTH3D_M_vNullVector(&stLocalMaxBoxPoint);
				MTH3D_M_vNullVector(&stLocalMinBoxPoint);
#endif /* U64 */
				}
				MTH3D_M_vMulMatrixVector ( &stGlobalMaxBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
				MTH3D_M_vMulMatrixVector ( &stGlobalMinBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
				GEO_fn_vAddObjectToBox(hGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);	
				if(hCollideGeometricObject)
					GEO_fn_vAddObjectToBox(hCollideGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint,&stGlobalMinBoxPoint);	
		}
		if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror))/*provisoire*/
		{
			assert(0);
			hFatherBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj);
			if(!hFatherBox)
				GEO_fn_vCreateParallelBox(&hFatherBox);
			hGeometricObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
#ifdef USE_ALTIMAPS
			if( hGeometricObject->d_xListOfElementsTypes[0] == GEO_C_xElementAltimap )
			{
				MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
				MTH3D_M_vCopyVector(&stLocalMinBoxPoint, &(((GEO_tdstElementAltimap *)(hGeometricObject->d_stListOfElements[0]))->stOrigin));
			}
			else
#endif /*USE_ALTIMAPS*/
			/* Oliv' - 19/05/1998*/
			if( hGeometricObject->d_stListOfPoints )
			{
				MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, hGeometricObject->d_stListOfPoints);
				MTH3D_M_vCopyVector(&stLocalMinBoxPoint, hGeometricObject->d_stListOfPoints);
			}
			else
			{
#if defined(U64)
				MTH_tdxReal xTemp;
				xTemp = MTH_M_xFloatToReal( (float)sqrt(2.0f) * hGeometricObject->fRadius );
				MTH3D_M_vSetVectorElements( &stLocalMaxBoxPoint, xTemp, xTemp, xTemp );
				MTH3D_M_vNegVector( &stLocalMinBoxPoint, &stLocalMaxBoxPoint );
#else
				MTH3D_M_vNullVector(&stLocalMaxBoxPoint);
				MTH3D_M_vNullVector(&stLocalMinBoxPoint);
#endif /* U64 */
			}
 
			MTH3D_M_vMulMatrixVector ( &stGlobalMaxBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
			MTH3D_M_vMulMatrixVector ( &stGlobalMinBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
			GEO_fn_vAddObjectToBox(hGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);	
		}
		/* The bounding volumes of the sectors are computed in another function*/
		if(lType != HIE_C_ulSector)
		{
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
			stGlobalMaxBoxPoint.xX = (float) (( (long)( (stGlobalMaxBoxPoint.xX*fScale) + 0.5) ) / fScale);		
			stGlobalMaxBoxPoint.xY = (float) (( (long)( (stGlobalMaxBoxPoint.xY*fScale) + 0.5) ) / fScale);		
			stGlobalMaxBoxPoint.xZ = (float) (( (long)( (stGlobalMaxBoxPoint.xZ*fScale) + 0.5) ) / fScale);		
			
			stGlobalMinBoxPoint.xX = (float) (( (long)( (stGlobalMinBoxPoint.xX*fScale) + 0.5) ) / fScale);		
			stGlobalMinBoxPoint.xY = (float) (( (long)( (stGlobalMinBoxPoint.xY*fScale) + 0.5) ) / fScale);		
			stGlobalMinBoxPoint.xZ = (float) (( (long)( (stGlobalMinBoxPoint.xZ*fScale) + 0.5) ) / fScale);		

#endif //U64CONVERTLOG
// } fin N64-format
			
			GEO_fn_vSetMaxPointOfParallelBox(hFatherBox, &stGlobalMaxBoxPoint);
			GEO_fn_vSetMinPointOfParallelBox(hFatherBox, &stGlobalMinBoxPoint);
			HIE_fn_vSetSuperObjectBoundingVolume(_hSprObj, (void *)hFatherBox);		

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
			if (tab2 != NULL)
				fprintf (dump,"%s%s\n%smin : %f,%f,%f\n%smax : %f,%f,%f\n",tab,tab2,tab,stGlobalMinBoxPoint.xX,stGlobalMinBoxPoint.xY,stGlobalMinBoxPoint.xZ,tab,stGlobalMaxBoxPoint.xX,stGlobalMaxBoxPoint.xY,stGlobalMaxBoxPoint.xZ);
			else
				fprintf (dump,"%s-- no name --\n%smin : %f,%f,%f\n%smax : %f,%f,%f\n",tab,tab,stGlobalMinBoxPoint.xX,stGlobalMinBoxPoint.xY,stGlobalMinBoxPoint.xZ,tab,stGlobalMaxBoxPoint.xX,stGlobalMaxBoxPoint.xY,stGlobalMaxBoxPoint.xZ);

			fflush (dump);

#endif //U64CONVERTLOG
// } fin N64-format
		}
	}
	else
	{
		if(lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
		{
			/* if the linked object is a PhysicalObject gets its Bounding Volume */
			hFatherSphere=(GEO_tdxHandleToBoundingSphere)PO_fn_hGetBoundingVolume((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
		}
		
		if(lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
		{
			/* if the linked object is a PhysicalObject gets its Bounding Volume */
			hFatherSphere=(GEO_tdxHandleToBoundingSphere)PO_fn_hGetBoundingVolume(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)));
		}
		if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror))/*provisoire*/
		{
			hGeometricObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
			MTH3D_M_vCopyVector(&stFatherCenter, hGeometricObject->d_stListOfPoints/*beurk*/);
			xFatherRadius=0.0f;
			GEO_fn_vAddObjectToSphere(hGeometricObject, &stFatherCenter, &xFatherRadius);
			GEO_fn_vCreateBoundingSphere(&hFatherSphere);
			GEO_fn_vSetBoundingSphere(hFatherSphere, &stFatherCenter, xFatherRadius);
 
		}	
		HIE_fn_vSetSuperObjectBoundingVolume(_hSprObj, (void *)hFatherSphere);			
	}
 
	HIE_M_ForEachChildOf(_hSprObj, hChild, xIndex)
	{
		ACP_tdxBool							bChildBoundingBox;
		GEO_tdxHandleToBoundingSphere		hChildSphere;
		GEO_tdxHandleToParallelBox			hChildBox;
		MTH3D_tdstVector					stTranslation;
		
		bChildBoundingBox = HIE_fn_SO_bHasABoxBoundingVolume(hChild);
	
		hLocalMatrix = HIE_fn_hGetSuperObjectMatrix(hChild);
		POS_fn_vGetTranslationVector(hLocalMatrix, &stTranslation);
		
		HIE_fn_vComputeAllBoundingVolumes(hChild);
		
		if(lType & (HIE_C_ulPO | HIE_C_ulIPO | HIE_C_ulEDT_Geometric | HIE_C_ulMirror | HIE_C_ulPO_Mirror| HIE_C_ulIPO_Mirror))
		{
			if(bFatherBoundingBox)
			{
				if(bChildBoundingBox)
					/* Father ---> Box*/
					/* Child  ---> Box*/
				{
					hChildBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(hChild);	
					if(!HIE_fn_bIsChildInsideHisFather(bFatherBoundingBox, (void *)hFatherBox , bChildBoundingBox, (void *)hChildBox, &stTranslation))
						HIE_fn_SO_vSetFlags (_hSprObj, HIE_fn_SO_ulGetFlags (_hSprObj) | HIE_C_Flag_ulCheckChildren);
				}
				else
					/* Father ---> Box*/
					/* Child  ---> Sphere*/
				{
					hChildSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(hChild);	
					if(!HIE_fn_bIsChildInsideHisFather(bFatherBoundingBox, (void *)hFatherBox , bChildBoundingBox, (void *)hChildSphere, &stTranslation))
						HIE_fn_SO_vSetFlags (_hSprObj, HIE_fn_SO_ulGetFlags (_hSprObj) | HIE_C_Flag_ulCheckChildren);					
				}
			}
			else
			{
				if(bChildBoundingBox)
					/* Father ---> Sphere*/
					/* Child  ---> Box*/
				{
					hChildBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(hChild);	
					if(!HIE_fn_bIsChildInsideHisFather(bFatherBoundingBox, hFatherSphere , bChildBoundingBox, (ACP_tdxHandleOfObject)hChildBox, &stTranslation))
						HIE_fn_SO_vSetFlags (_hSprObj, HIE_fn_SO_ulGetFlags (_hSprObj) | HIE_C_Flag_ulCheckChildren);					
				}
				else
					/* Father ---> Sphere*/
					/* Child  ---> Sphere*/
				{
					hChildSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(hChild);	
					if(!HIE_fn_bIsChildInsideHisFather(bFatherBoundingBox, hFatherSphere , bChildBoundingBox, hChildSphere, &stTranslation))
						HIE_fn_SO_vSetFlags (_hSprObj, HIE_fn_SO_ulGetFlags (_hSprObj) | HIE_C_Flag_ulCheckChildren);					
				}				
			}
		}
	}
// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	level--;

#endif //U64CONVERTLOG
// } fin N64-format
}
/*-----------------------------------------------------------------------------*/
void HIE_fn_vComputePoAndIpoBoundingVolumes(HIE_tdxHandleToSuperObject _hSprObj)
{
	MTH3D_tdstVector				stLocalCenter;
	MTH_tdxReal						xRadius;
	GEO_tdxHandleToBoundingSphere	hBoundingSphere;
	ACP_tdxHandleOfObject			hGeometricObject;
	ACP_tdxIndex					xIndex;
	HIE_tdxHandleToSuperObject		hChild;
	PO_tdxHandleToPhysicalObject	hTempPo = NULL;
	long							lType;
	
  
 
  /*--- Node Examination ---*/
  HIE_M_ForEachChildOf(_hSprObj, hChild, xIndex)
  {
    HIE_fn_vPushMatrix(hChild);
    HIE_fn_vComputePoAndIpoBoundingVolumes(hChild);
    HIE_fn_vPopMatrix();
  }
 
  lType=HIE_fn_ulGetSuperObjectType(_hSprObj);
			
  if(lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror))
  {
	  HIE_fn_vComputeOnePoBoundingVolume(HIE_fn_hGetSuperObjectObject(_hSprObj));
	  hTempPo=(PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj);
  }
			
  if(lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror))
  {
	  hTempPo=IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj));
  }
 
  xRadius=MTH_C_ZERO;
  
  if( lType & (HIE_C_ulPO | HIE_C_ulIPO | HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror))
	{
		GEO_fn_vCreateBoundingSphere(&hBoundingSphere);
		hGeometricObject = M_hGetRepositionZoneFromPo(hTempPo);
 
#ifndef U64
#ifdef USE_ALTIMAPS
		if( hGeometricObject->d_xListOfElementsTypes[ 0 ] == GEO_C_xElementAltimap )
		{
      /*--- Altimap ---*/
			GEO_vGetAltimapOrigin( hGeometricObject, 0, &stLocalCenter );
			GEO_fn_vAddAltimapToSphere(hGeometricObject,&stLocalCenter,&xRadius);
		}
		else	
#endif /*USE_ALTIMAPS*/
		{
			/*--- NOT Altimap ---*/
			if( hGeometricObject->d_stListOfPoints )
			{
			MTH3D_M_vCopyVector(&stLocalCenter, hGeometricObject->d_stListOfPoints);
			GEO_fn_vAddObjectToSphere(hGeometricObject,&stLocalCenter,&xRadius);
			}
		}
#else
#ifdef USE_ALTIMAPS
		if( hGeometricObject->d_xListOfElementsTypes[ 0 ] == GEO_C_xElementAltimap )
		{
			/*--- Altimap ---*/
			GEO_vGetAltimapOrigin( hGeometricObject, 0, &stLocalCenter );
			GEO_fn_vAddAltimapToSphere(hGeometricObject,&stLocalCenter,&xRadius);
		}
    else 
#endif /*USE_ALTIMAPS*/
      if( hGeometricObject->d_stListOfPoints!=NULL)
      {
        /*--- NOT Altimap ---*/
        MTH3D_M_vCopyVector(&stLocalCenter, hGeometricObject->d_stListOfPoints);
        GEO_fn_vAddObjectToSphere(hGeometricObject,&stLocalCenter,&xRadius);
      }
      else
      {
/* Oliv' - 12/06/1998 - GeoObjs are now always centered...*/
/*        MTH3D_M_vSetVectorElements(&stLocalCenter,
          MTH_M_xFloatToReal(hGeometricObject->a3_fCenter[0]),
          MTH_M_xFloatToReal(hGeometricObject->a3_fCenter[1]),
          MTH_M_xFloatToReal(hGeometricObject->a3_fCenter[2]));*/
		    MTH3D_M_vSetVectorElements(&stLocalCenter,MTH_C_ZERO,MTH_C_ZERO,MTH_C_ZERO);
/* EndOfOliv'*/
		  xRadius=MTH_M_xFloatToReal(hGeometricObject->fRadius);
      }
#endif
 
      GEO_fn_vSetBoundingSphere(hBoundingSphere, &stLocalCenter, xRadius);
      PO_fn_vSetBoundingVolume(hTempPo ,hBoundingSphere);
  }
}
/*-----------------------------------------------------------------------------*/
void HIE_fn_vComputeSectorBoundingVolume(HIE_tdxHandleToSuperObject hSector)
{
	SECT_tdxHandleOfSectorObject	hSectorObject;
	HIE_tdxHandleToSuperObject		hSectorChild;
	ACP_tdxHandleOfObject			hGeometricObject;
	MTH3D_tdstVector				stGlobalMaxBoxPoint;
	MTH3D_tdstVector				stGlobalMinBoxPoint;
	MTH3D_tdstVector				stLocalMaxBoxPoint;
	MTH3D_tdstVector				stLocalMinBoxPoint;
	ACP_tdxIndex					xInd;
	ACP_tdxBool						bFirstChild=TRUE;
	MTH_tdxReal						xTemp;
	GEO_tdxHandleToParallelBox		hParallelBox;
 
	hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hSector);
	hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(hSector);
	if(!hParallelBox)
		GEO_fn_vCreateParallelBox(&hParallelBox);
 
	HIE_M_ForEachChildOf(hSector, hSectorChild, xInd)
	{
		GEO_tdxHandleToMatrix				hGlobalMatrix;		
 
		hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(hSectorChild);
 
		switch (HIE_fn_ulGetSuperObjectType(hSectorChild))
		{
			case HIE_C_ulEDT_Geometric:
				hGeometricObject = (ACP_tdxHandleOfObject) HIE_fn_hGetSuperObjectObject(hSectorChild);
				break;
 
			case HIE_C_ulIPO:
			case HIE_C_ulIPO_Mirror:
				GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(hSectorChild))),
					0L,
					&xTemp,
					&hGeometricObject);
				break;
 
			case HIE_C_ulPO:
				GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hSectorChild)),
					0L,
					&xTemp,
					&hGeometricObject);
                break;
 
            default:
                hGeometricObject = NULL;
                break;
		}
		
		if(( hGeometricObject->d_stListOfPoints ) && (bFirstChild))
			
		{
			bFirstChild = 0;
			MTH3D_M_vCopyVector(&stLocalMaxBoxPoint, hGeometricObject->d_stListOfPoints);
			MTH3D_M_vCopyVector(&stLocalMinBoxPoint, hGeometricObject->d_stListOfPoints);
#ifndef U64				
			MTH3D_M_vMulMatrixVector (&stGlobalMaxBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
			MTH3D_M_vMulMatrixVector (&stGlobalMinBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
#else
			POS_fn_vMulMatrixVertex (&stGlobalMaxBoxPoint, hGlobalMatrix, &stLocalMaxBoxPoint);
			POS_fn_vMulMatrixVertex (&stGlobalMinBoxPoint, hGlobalMatrix, &stLocalMinBoxPoint);
#endif
		}
		else
		{
			if(bFirstChild)
			{
				MTH3D_M_vNullVector(&stLocalMaxBoxPoint);
				MTH3D_M_vNullVector(&stLocalMinBoxPoint);
#ifndef U64				
				MTH3D_M_vMulMatrixVector (&stGlobalMaxBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMaxBoxPoint);
				MTH3D_M_vMulMatrixVector (&stGlobalMinBoxPoint, &hGlobalMatrix->stTransformMatrix, &stLocalMinBoxPoint);
#else
				POS_fn_vMulMatrixVertex (&stGlobalMaxBoxPoint, hGlobalMatrix, &stLocalMaxBoxPoint);
				POS_fn_vMulMatrixVertex (&stGlobalMinBoxPoint, hGlobalMatrix, &stLocalMinBoxPoint);
#endif
			}
		}
 
        if (hGeometricObject) 
#ifndef U64
			GEO_fn_vAddObjectToBox(hGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);	
#else
			GEO_fn_vAddObjectToBox2(hGeometricObject, hGlobalMatrix, &stGlobalMaxBoxPoint, &stGlobalMinBoxPoint);
#endif
 
	}

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	stGlobalMaxBoxPoint.xX = (float) (( (long)( (stGlobalMaxBoxPoint.xX*fScale) + 0.5) ) / fScale);		
	stGlobalMaxBoxPoint.xY = (float) (( (long)( (stGlobalMaxBoxPoint.xY*fScale) + 0.5) ) / fScale);		
	stGlobalMaxBoxPoint.xZ = (float) (( (long)( (stGlobalMaxBoxPoint.xZ*fScale) + 0.5) ) / fScale);		

	stGlobalMinBoxPoint.xX = (float) (( (long)( (stGlobalMinBoxPoint.xX*fScale) + 0.5) ) / fScale);		
	stGlobalMinBoxPoint.xY = (float) (( (long)( (stGlobalMinBoxPoint.xY*fScale) + 0.5) ) / fScale);		
	stGlobalMinBoxPoint.xZ = (float) (( (long)( (stGlobalMinBoxPoint.xZ*fScale) + 0.5) ) / fScale);		

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

	GEO_fn_vSetMaxPointOfParallelBox(hParallelBox, &stGlobalMaxBoxPoint);
	GEO_fn_vSetMinPointOfParallelBox(hParallelBox, &stGlobalMinBoxPoint);
	HIE_fn_vSetSuperObjectBoundingVolume(hSector, (void *)hParallelBox);		

// FBF N64-format pour coords, et logfile dans x:\exe\geodump.log{
#ifdef U64CONVERTETLOG
	fprintf (dump,"Bounding Volume Secteur %s :\nmin : %f,%f,%f\nmax : %f,%f,%f\n",hSectorObject->szSectorName,stGlobalMinBoxPoint.xX,stGlobalMinBoxPoint.xY,stGlobalMinBoxPoint.xZ,stGlobalMaxBoxPoint.xX,stGlobalMaxBoxPoint.xY,stGlobalMaxBoxPoint.xZ);
	fflush(dump);

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


}
/*-----------------------------------------------------------------------------*/
void HIE_fn_vComputeBoundingVolumeOfSuperObjectBranch(HIE_tdxHandleToSuperObject _hSprObj)
{
    HIE_tdxHandleToSuperObject	hChild;
    ACP_tdxIndex				xIndex;
	long						lType;
 
 
	HIE_M_ForEachChildOf(_hSprObj, hChild, xIndex)
	{
		lType = HIE_fn_ulGetSuperObjectType(hChild);
		if(lType == HIE_C_ulSector)
			HIE_fn_vComputeSectorBoundingVolume(hChild);
		HIE_fn_vComputeAllBoundingVolumes( hChild );
	}
}
/*-----------------------------------------------------------------------------*/
