reman3/Rayman_X/cpa/tempgrp/SPO/HieBdVol.c

704 lines
28 KiB
C

/* (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 );
}
}
/*-----------------------------------------------------------------------------*/