/* 0 1 2 3 4 5 6 7 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -------------------------------------------------------------------------------- -- Description : Geometric object collision part -------------------------------------------------------------------------------- -- Creation date : 22 aug 1996 Author : FPI -------------------------------------------------------------------------------- */ #include "acp_base.h" #include "MTH.h" #include "MEC.h" #include "GMT.h" #include "GEO.h" #include "GLI.h" #include "COL/CollGOCo.h" /*XB 98/09/11*/ #include "PRF.h" /*End XB*/ /* ANNECY AV {*/ #define C_wDoubleEdge 2 /* END ANNECY AV }*/ /* -------------------------------------------------------------------------------- -- Description : Global variables -------------------------------------------------------------------------------- */ /* cas de collision */ /* Global Collisiosn Array */ COL_tdstCollisionCase COL_g_stCollisionCase [COL_C_xMaxNumberOfCollisions]; /* Pointer to Beginning of Array to be computed /* Usually COL_g_stCollisionCaseReal = COL_g_stCollisionCase /* but it can be usefull to compute collisions in two steps /* then COL_g_stCollisionCaseReal = COL_g_stCollisionCase + Number of collisions computed in first step */ COL_tdstCollisionCase *COL_g_stCollisionCaseReal = COL_g_stCollisionCase; COL_tdstGVForCollision COL_g_stGVForCol; long COL_g_lNbElementsInTable = COL_C_xMaxNumberOfCollisions; /* Number of elements added in Collision Array */ /* size free for collide array /* usually COL_g_lMaxNumberOfCollisions = COL_C_xMaxNumberOfCollisions /* but it can be usefull to compute collisions in two steps /* then COL_g_lMaxNumberOfCollisions = COL_C_xMaxNumberOfCollisions - Number of collisions computed in first step */ extern long COL_g_lMaxNumberOfCollisions; /* -------------------------------------------------------------------------------- -- Description : Initialize the collision table -------------------------------------------------------------------------------- -- Creation date : 23 oct 1996 Author : FPI -------------------------------------------------------------------------------- */ //#define COL_fn_vInitCollisionTable() COL_g_lNbElementsInTable = 0 /* init de la table de collision */ /* passer en macro */ //void COL_fn_vInitCollisionTable ( void ) //{ /* Anthony */ /*COL_tdstCollisionCase * p; COL_tdstCollisionCase * end;*/ /* opti par Yann Le Guyader 07/99 */ //if (COL_g_lNbElementsInTable) //{ /*end = &COL_g_stCollisionCaseReal[COL_g_lNbElementsInTable];*/ // COL_g_lNbElementsInTable = 0; //} /*else return;*/ /*for (p = COL_g_stCollisionCaseReal; p < end ; p ++) { /* temps de collision */ //p -> xCollisionTime = MTH_C_2; //}*/ //} /* -------------------------------------------------------------------------------- -- Description : Add a collision case in the collision table -------------------------------------------------------------------------------- -- Creation date : 06 oct 1997 Author : FPI -------------------------------------------------------------------------------- */ /* ajout dans la table de collision */ void COL_fn_vAddInStaticCollisionTable (MTH_tdxReal _xT, MTH3D_tdstVector *_p_stTranslation, MTH3D_tdstVector *_p_stHit, MTH3D_tdstVector *_p_stNormal, GMT_tdxHandleToGameMaterial _hDynMat, GMT_tdxHandleToGameMaterial _hStatMat, ACP_tdxIndex _xDynamicGeomEntity, ACP_tdxIndex _xStaticGeomEntity, void *_p_vParameter1, short _sParameter2, MTH3D_tdstVector *_p_stMovement, MTH_tdxReal _xSphereRadius, MTH3D_tdstVector * _p_stEndPosition) { #ifdef USE_PROFILER /*XB 98/09/11*/ static long s_l_MaxNbCollisions=0; /*End XB*/ #endif /* USE_PROFILER */ long i; COL_tdstCollisionCase * p_stCollisionCase; /* jt 120599 */ GMT_tdxHandleToCollideMaterial hCollideMaterial; /* end jt 120599 */ #define M_bIsVectorsEqualWithEpsilon( VectA, VectB, Eps ) \ ( MTH_M_bEqualWithEpsilon( MTH3D_M_xGetXofVector( VectA ), MTH3D_M_xGetXofVector( VectB ), Eps ) && \ MTH_M_bEqualWithEpsilon( MTH3D_M_xGetYofVector( VectA ), MTH3D_M_xGetYofVector( VectB ), Eps ) && \ MTH_M_bEqualWithEpsilon( MTH3D_M_xGetZofVector( VectA ), MTH3D_M_xGetZofVector( VectB ), Eps ) ) /* jt 120599 : no registration if hand type zone hurt something else than a hang material type */ hCollideMaterial = GMT_fn_hGetCollideMaterial (_hDynMat); /* zone has a collide material with hand type */ if ( (hCollideMaterial!=GMT_C_InvalidCollideMaterial) && (GMT_fn_hGetCollideMaterialIdentifier(hCollideMaterial)&(1<<3)) ) { /* this is a ground */ hCollideMaterial = GMT_fn_hGetCollideMaterial (_hStatMat); if ( (hCollideMaterial==GMT_C_InvalidCollideMaterial) || ((GMT_fn_hGetCollideMaterialIdentifier(hCollideMaterial)&4)!=4) ) /* the ground hasn't hand type material */ return; } /* end jt 120599 */ if (_xStaticGeomEntity == COL_C_xHighEdgeEntity || _xStaticGeomEntity == COL_C_xLowEdgeEntity) /* The function can be called twice for the same edge : we have to detect this*/ { /* anthony */ /*p_stCollisionCase = COL_g_stCollisionCase;*/ p_stCollisionCase = COL_g_stCollisionCaseReal; for (i = 0 ; i < COL_g_lNbElementsInTable ; i ++) { { /* If the collision with the edge is already registered, we do nothing*/ if (p_stCollisionCase -> xStaticGeomEntity == _xStaticGeomEntity && p_stCollisionCase -> p_vParameter1 == _p_vParameter1 && /* Is it the same super object ?*/ MTH_M_bEqualWithEpsilon (p_stCollisionCase -> xCollisionTime , _xT , 0.001) && M_bIsVectorsEqualWithEpsilon (& p_stCollisionCase -> stCollisionPoint , _p_stHit , 0.005) && M_bIsVectorsEqualWithEpsilon (& p_stCollisionCase -> stCollisionNormal , _p_stNormal , 0.005)) { /* Say that the edge is present twice*/ p_stCollisionCase -> sParameter2 |= C_wDoubleEdge; return; } } p_stCollisionCase ++; } } /* anthony */ /*p_stCollisionCase = COL_g_stCollisionCase;*/ p_stCollisionCase = COL_g_stCollisionCaseReal; for (i = 0 ; i < COL_g_lNbElementsInTable ; i ++) { if(MTH_M_bEqualWithEpsilon(_xT, p_stCollisionCase->xCollisionTime, 0.0001f)) { if(_p_stNormal->xX < p_stCollisionCase->stCollisionNormal.xX) { int iNumberOfElementToCopy = 0; COL_tdstCollisionCase * p = p_stCollisionCase; /*COL_tdstCollisionCase * end = COL_g_stCollisionCase + COL_g_lNbElementsInTable ;*/ /* anthony */ COL_tdstCollisionCase * end = COL_g_stCollisionCaseReal + COL_g_lNbElementsInTable ; while (p ++ < end) iNumberOfElementToCopy ++; /* Not to go over array Boudary in memmove*/ if (p == (COL_g_stCollisionCase + (COL_C_xMaxNumberOfCollisions+1))) iNumberOfElementToCopy --; if (iNumberOfElementToCopy ) memmove (p_stCollisionCase + 1 , p_stCollisionCase , iNumberOfElementToCopy * sizeof (COL_g_stCollisionCase [0])); break; } } else { if (_xT < p_stCollisionCase -> xCollisionTime) { int iNumberOfElementToCopy = 0; COL_tdstCollisionCase * p = p_stCollisionCase; /*COL_tdstCollisionCase * end = COL_g_stCollisionCase + COL_g_lNbElementsInTable ;*/ /* anthony */ COL_tdstCollisionCase * end = COL_g_stCollisionCaseReal + COL_g_lNbElementsInTable ; /* Not to go over array Boudary in memmove*/ while (p ++ < end) iNumberOfElementToCopy ++; if (p == (COL_g_stCollisionCase + (COL_C_xMaxNumberOfCollisions + 1))) iNumberOfElementToCopy --; if (iNumberOfElementToCopy) memmove (p_stCollisionCase + 1 , p_stCollisionCase , iNumberOfElementToCopy * sizeof (COL_g_stCollisionCase [0])); break; } } p_stCollisionCase ++; } //if (i == COL_C_xMaxNumberOfCollisions) return; /* The table is full*/ if (i == COL_g_lMaxNumberOfCollisions) return; /* anthony */ /*XB 98/09/11*/ #ifdef USE_PROFILER if(s_l_MaxNbCollisions xCollisionTime = _xT; MTH3D_M_vCopyVector (& p_stCollisionCase -> stTranslation , _p_stTranslation); MTH3D_M_vCopyVector (& p_stCollisionCase -> stCollisionPoint , _p_stHit); MTH3D_M_vCopyVector (& p_stCollisionCase -> stCollisionNormal , _p_stNormal); MTH3D_M_vCopyVector (& p_stCollisionCase -> stMovement , _p_stMovement); MTH3D_M_vCopyVector (& p_stCollisionCase -> stEndPosition , _p_stEndPosition); p_stCollisionCase -> hDynamicMaterial = _hDynMat; p_stCollisionCase -> hStaticMaterial = _hStatMat; p_stCollisionCase -> xDynamicGeomEntity = _xDynamicGeomEntity; p_stCollisionCase -> xStaticGeomEntity = _xStaticGeomEntity; p_stCollisionCase -> xSphereRadius = _xSphereRadius; p_stCollisionCase -> p_vParameter1 = _p_vParameter1; p_stCollisionCase -> sParameter2 = _sParameter2; /* p_stCollisionCase -> bCollisionState = TRUE;*/ /* not usefull anymore */ if (COL_g_lNbElementsInTable == COL_g_lMaxNumberOfCollisions) return; else COL_g_lNbElementsInTable++; } /* -------------------------------------------------------------------------------- -- Description : Get of collision result -------------------------------------------------------------------------------- -- Creation date : 22 apr 1997 Author : FPI -------------------------------------------------------------------------------- qq*/ /* get du resultat des collisions */ /* #ifndef _FIRE_DEADCODE_U64_ ACP_tdxBool COL_fn_bGetResultCollision ( COL_tdstCollisionCase * p_stCollisionCaseDst ) { // resultat if ( COL_g_stCollisionCase [0] . bCollisionState ) { MTH3D_M_vNormalizeVector (& COL_g_stCollisionCase [0] . stCollisionNormal , & COL_g_stCollisionCase [0] . stCollisionNormal); memcpy (p_stCollisionCaseDst , & COL_g_stCollisionCase [0] , sizeof (COL_tdstCollisionCase)); } return COL_g_stCollisionCase [0] . bCollisionState; } #endif */ /* -------------------------------------------------------------------------------- -- Description : Get several collision results -------------------------------------------------------------------------------- -- Creation date : March 3, 1998 Author : Alexis Vaisse -------------------------------------------------------------------------------- */ ACP_tdxBool COL_fn_bGetMultipleResultCollision (COL_tdstCollisionCase * * _p_p_stCollisionCaseDst) { ACP_tdxBool temp; /* return a pointer to the array of collision case*/ //* _p_p_stCollisionCaseDst = COL_g_stCollisionCase; * _p_p_stCollisionCaseDst = COL_g_stCollisionCaseReal; //return COL_g_stCollisionCase [0] . bCollisionState; /* If there is a collision, the position 0 is not empty*/ return temp = (COL_g_lNbElementsInTable!=0); /* long i , lNumberOfElementToCopy; COL_tdstCollisionCase * p; p = p_stCollisionCaseDst; for (i = 0 ; i < COL_C_xMaxNumberOfCollisions ; i ++) { (p ++) -> bCollisionState = FALSE; } // Normalize the normals p = COL_g_stCollisionCase; for (i = 0 ; i < COL_C_xMaxNumberOfCollisions ; i ++) { if (p -> bCollisionState) { MTH3D_M_vNormalizeVector (& p -> stCollisionNormal , & p -> stCollisionNormal); } else break; // No collision : it is not necessary to use the next elements of the array p ++; } lNumberOfElementToCopy = (i < COL_C_xMaxNumberOfCollisions) ? (i + 1) : COL_C_xMaxNumberOfCollisions; // Copy only the minimum memcpy (p_stCollisionCaseDst , & COL_g_stCollisionCase , sizeof (COL_tdstCollisionCase) * lNumberOfElementToCopy); return COL_g_stCollisionCase [0] . bCollisionState; // If there is a collision, the position 0 is not empty */ }