/* 0 1 2 3 4 5 6 7 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -------------------------------------------------------------------------------- -- Description : Geometric object collision part : Sph - Elt -------------------------------------------------------------------------------- -- Creation date : 15 may 1997 Author : FPI -------------------------------------------------------------------------------- */ #include "acp_base.h" #include "MTH.h" #include "MEC.h" #include "GMT.h" #include "GEO.h" #include "GLI.h" #include "PRF.h" #include "COL/CsSphElt.h" /* -------------------------------------------------------------------------------- -- Description : Constants -------------------------------------------------------------------------------- */ #define COL_C_lUsesAllElements 0xFFFFFFFF /* -------------------------------------------------------------------------------- -- Description : Macros -------------------------------------------------------------------------------- */ #define COL_M_vSetBitOfLong( lValue, lBitNumber ) (lValue) |= ( 1 << (lBitNumber) ) #define COL_M_bIsSetBitOfLong( lValue, lBitNumber ) ( (lValue) & ( 1 << (lBitNumber) ) ) /* -------------------------------------------------------------------------------- -- Description : local prototypes -------------------------------------------------------------------------------- */ ACP_tdxBool COL_fn_bCollideStaticElementSpheresWithStaticBoundingVolumes( COL_tdstGVForCollision *p_stGV , long *_aDEF_lBitsFieldInCollision , ACP_tdxBool _bPartialResult); /*--------------------------------------------------------------------------------*/ /*-- Description : COL_fn_vEnlargeSphereIfNecessary ()*/ /* If the deplacement of a sphere is bigger than its diameter,*/ /* make the sphere bigger so that it cannot go through a wall*/ /*--------------------------------------------------------------------------------*/ /*-- Creation date : March 13, 1998 Author : Alexis Vaisse*/ /*--------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vEnlargeSphereIfNecessary (COL_tdstGVForCollision * p_stGV) { /* Square distance between the start center and the end center of the dynamic sphere*/ MTH_tdxReal xSqrDistance; MTH_tdxReal xDistance; MTH_tdxReal xNewRadius; MTH_tdxReal xCoef; MTH3D_tdstVector stDeplacement; p_stGV->xSwapRadius = p_stGV->xDynamicRadius; MTH3D_M_vCopyVector (& p_stGV->stSwapDinST0Point, & p_stGV->stDinST0Point); xSqrDistance = MTH3D_M_xSqrVector (& p_stGV->stDinST01Vector); if (MTH_M_bLess(xSqrDistance,MTH_M_xDoubleToReal(1e-3))) { p_stGV->bUseEnlargeSphere=FALSE; return; } /* Here, the distance is greater than the diameter : we have to make the radius bigger*/ xDistance = MTH_M_xSqrt (xSqrDistance); /* jt 240399 */ xNewRadius = MTH_M_xDiv ( MTH_M_xAdd(xDistance,MTH_M_xMul(p_stGV->xDynamicRadius,MTH_C_2)), MTH_C_2 ); /* New T0 point*/ xCoef = MTH_M_xDiv (MTH_M_xSub (xNewRadius,p_stGV->xDynamicRadius) , xDistance); /* end jt 240399 */ MTH3D_M_vMulScalarVector (& stDeplacement , xCoef , & p_stGV->stDinST01Vector); MTH3D_M_vAddVector (& p_stGV->stDinST0Point , & p_stGV->stDinST0Point , & stDeplacement); /* New radius*/ p_stGV->xDynamicRadius = xNewRadius; p_stGV->bUseEnlargeSphere=TRUE; } /* jt 260399 */ void COL_fn_vUseInitialSphere (COL_tdstGVForCollision * p_stGV) { MTH_tdxReal xTmpRadius; MTH3D_tdstVector stTmpVector; if (p_stGV->bUseEnlargeSphere) { xTmpRadius = p_stGV->xDynamicRadius; p_stGV->xDynamicRadius = p_stGV->xSwapRadius; p_stGV->xSwapRadius = xTmpRadius; MTH3D_M_vCopyVector (&stTmpVector, & p_stGV->stDinST0Point); MTH3D_M_vCopyVector (& p_stGV->stDinST0Point,& p_stGV->stSwapDinST0Point); MTH3D_M_vCopyVector (& p_stGV->stSwapDinST0Point, &stTmpVector); p_stGV->bUseEnlargeSphere = FALSE; } } void COL_fn_vUseEnlargeSphere (COL_tdstGVForCollision * p_stGV) { MTH_tdxReal xTmpRadius; MTH3D_tdstVector stTmpVector; if (!p_stGV->bUseEnlargeSphere) { xTmpRadius = p_stGV->xDynamicRadius; p_stGV->xDynamicRadius = p_stGV->xSwapRadius; p_stGV->xSwapRadius = xTmpRadius; MTH3D_M_vCopyVector (&stTmpVector, & p_stGV->stDinST0Point); MTH3D_M_vCopyVector (& p_stGV->stDinST0Point,& p_stGV->stSwapDinST0Point); MTH3D_M_vCopyVector (& p_stGV->stSwapDinST0Point, &stTmpVector); p_stGV->bUseEnlargeSphere = TRUE; } } /* end jt 260399 */ /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicSphereWithStaticIndexedTriangle() -------------------------------------------------------------------------------- -- Creation date : 27 dec 1996 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ ACP_tdxBool COL_fn_bCollideStaticSphereWithStaticIndexedTriangle ( COL_tdstGVForCollision *p_stGV , ACP_tdxBool bFaceMapInsteadOfIndexedTriangle) { MTH3D_tdstVector *p_stVertex1; MTH3D_tdstVector *p_stVertex2; MTH3D_tdstVector *p_stVertex3; MTH3D_tdstVector *p_stNormal; MTH_tdxReal xDPlan; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stSegmentStartPoint; MTH3D_tdstVector stSegmentVector; { /* points du triangle statique*/ p_stVertex1 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[0]; p_stVertex2 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[1]; p_stVertex3 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[2]; /* calcul de la normale*/ p_stNormal = p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesNormals + p_stGV->xStaticIndexedTriangleIndex; } /* calcul de de l'équation du plan */ xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) ); /* jt 260399 */ COL_fn_vUseEnlargeSphere (p_stGV); MTH3D_M_vMulScalarVector (& stTempNormal, p_stGV->xDynamicRadius , p_stNormal ); MTH3D_M_vAddVector (& stSegmentStartPoint , & p_stGV->stDinST0Point , & stTempNormal); /* Start point of the segment*/ MTH3D_M_vMulScalarVector (& stSegmentVector , MTH_C_Minus2 , & stTempNormal); if (INT_fn_bDetectIntersectSegmentWithTriangle (& stSegmentStartPoint , & stSegmentVector , p_stVertex1 , p_stVertex2 , p_stVertex3 , p_stNormal , xDPlan)) { /* Here, we have collision with the 'end' position*/ /* Now, we test collision with the 'start' position*/ MTH3D_tdstVector stMovementVector; /* jt 260399 */ COL_fn_vUseInitialSphere (p_stGV); MTH3D_M_vMulScalarVector (& stTempNormal, p_stGV->xDynamicRadius , p_stNormal ); MTH3D_M_vMulScalarVector (& stSegmentVector , MTH_C_Minus2 , & stTempNormal); /* end jt 220399 */ /* stDinST01Vector is the translation to go from the 'end' position to the 'start' position of the sphere center*/ /* and we need the translation to go from the 'start' position to the 'end' position*/ MTH3D_M_vNegVector (& stMovementVector, & p_stGV->stDinST01Vector); MTH3D_M_vAddVector (& stSegmentStartPoint , & p_stGV->stDinST1Point , & stTempNormal); /* Start point of the segment*/ if (INT_fn_bDetectIntersectSegmentWithTriangle (& stSegmentStartPoint , & stSegmentVector , p_stVertex1 , p_stVertex2 , p_stVertex3 , p_stNormal , xDPlan)) { /* Here we have already collision at the 'start' position*/ MTH3D_tdstVector stT0AVector; MTH3D_tdstVector stT1AVector; MTH_tdxReal xDotProduct; MTH_tdxReal xDistance; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stEndPosition; /* The translation*/ MTH3D_M_vSubVector ( & stT0AVector , p_stVertex1 , & p_stGV->stDinST0Point); MTH3D_M_vSubVector ( & stT1AVector , p_stVertex1 , & p_stGV->stDinST1Point); xDotProduct = MTH3D_M_xDotProductVector (& stT0AVector , p_stNormal); xDistance = MTH_M_xAdd (xDotProduct , p_stGV->xDynamicRadius); /* jt 080499 */ /* la ZDM a franchi la face en back-face : la ZDM grossie collisionne la face a la position d'arrivée la ZDM non grossie ne collisionne pas la face à la position d'arrivée dans ce cas, tout beigne et on ne reporte pas d'obstacle */ if (MTH_M_bLessEqualZero(xDistance)) return FALSE; /* end jt 080499 */ /* jt 200799 */ /* il ne faut pas collisionner l'obstacle quand : - la ZDM grossie collisionne la face à la position d'arrivée - la ZDM non grossie collisionne la face à la position de départ - la ZDM non grossie ne collionne pas la face à la position d'arrivée - le point de départ et le point d'arrivée sont du même côté de l'obstacle */ // if ( // MTH_M_bGreater(MTH3D_M_xDotProductVector (& stT1AVector , p_stNormal),MTH_M_xDoubleToReal(1e-3)) // && // MTH_M_bGreater(xDotProduct,p_stGV->xDynamicRadius) // ) // return FALSE; /* end jt 200799 */ MTH3D_M_vMulScalarVector (& stTempDistance , xDistance , p_stNormal); POS_fn_vMulMatrixVector (& stTempDistance , p_stGV->p_stStaticGeomObjMatrix , & stTempDistance); /* The hit*/ MTH3D_M_vMulScalarVector (& stTempHit , xDotProduct , p_stNormal); MTH3D_M_vAddVector (& stTempHit , & p_stGV->stDinST0Point , & stTempHit); /* jt 270499 */ /* si la sphère est recallée en dehors du trinagle, on l'ignore. */ /* On compte sur les arêtes pour détecter le cas */ if ( !INT_fn_bGetPointInTriangle ( & stTempHit, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal ) ) return FALSE; /* end jt 270499 */ POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stTempHit); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal);*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, &p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT */ POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity , COL_C_xTriangleEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2 , & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else { /* We have collision during the movement : we call the dynamic collision*/ MTH3D_tdstVector stT1Center; MTH_tdxReal xDotProduct; MTH_tdxReal xT; MTH3D_tdstVector stHit; xDotProduct = MTH3D_M_xDotProductVector (p_stNormal , & stMovementVector); /* Calculation of the new center of the sphere*/ MTH3D_M_vMulAddVector (& stT1Center, MTH_M_xNeg ( p_stGV->xDynamicRadius ), p_stNormal, &p_stGV->stDinST1Point); if (INT_fn_bIntersectSegmentWithTriangle2 (& stT1Center , & stMovementVector , p_stVertex1 , p_stVertex2 , p_stVertex3, p_stNormal , xDPlan , xDotProduct , &xT , &stHit)) { /* Here, we have collision during the movement*/ MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stEndPosition; /* The hit*/ POS_fn_vMulMatrixVertex ( &stTempHit, p_stGV->p_stStaticGeomObjMatrix, &(stHit) ); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector ( &stTempNormal, p_stGV->p_stStaticGeomObjMatrix, p_stNormal );*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT*/ /* The translation is not used*/ MTH3D_M_vNullVector (& stTempDistance); POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); COL_fn_vAddInStaticCollisionTable (xT, & stTempDistance, & stTempHit, &stTempNormal, p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial, COL_C_xSphereEntity, COL_C_xTriangleEntity, p_stGV->p_vParameter1, p_stGV->sParameter2, & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } /* jt 230399 */ #ifdef toto else { /* Here, we don't have collision during the movement : check if it is because of a back face or not*/ MTH3D_tdstVector stT0AVector; MTH_tdxReal xDotProduct; MTH_tdxReal xDistance; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stEndPosition; if (MTH_M_bGreater (MTH3D_M_xDotProductVector (& stMovementVector , p_stNormal) , MTH_C_ZERO)) { /* The movement and the normal are in the same direction -> back face : we register with time = -1*/ /* The translation*/ MTH3D_M_vSubVector ( & stT0AVector , p_stVertex1 , & p_stGV->stDinST0Point); xDotProduct = MTH3D_M_xDotProductVector (& stT0AVector , p_stNormal); xDistance = MTH_M_xAdd (xDotProduct , p_stGV->xDynamicRadius); MTH3D_M_vMulScalarVector (& stTempDistance , xDistance , p_stNormal); POS_fn_vMulMatrixVector (& stTempDistance , p_stGV->p_stStaticGeomObjMatrix , & stTempDistance); /* The hit*/ MTH3D_M_vMulScalarVector (& stTempHit , xDotProduct , p_stNormal); MTH3D_M_vAddVector (& stTempHit , & p_stGV->stDinST0Point , & stTempHit); POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stTempHit); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal);*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT*/ POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity , COL_C_xTriangleEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2 , & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else return FALSE; /* No collision;*/ } #endif return FALSE; /* end jt 230399 */ } return TRUE; /* Collision*/ } else { return FALSE; /* No collision*/ } } #ifdef USE_ALTIMAPS /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicSphereWithStaticAltimap() -------------------------------------------------------------------------------- -- Creation date : 27 dec 1996 Author : FPI -------------------------------------------------------------------------------- */ ACP_tdxBool COL_fn_bCollideStaticSphereWithStaticAltimap( COL_tdstGVForCollision *p_stGV , MTH3D_tdstVector *p_stVertex1, MTH3D_tdstVector *p_stVertex2, MTH3D_tdstVector *p_stVertex3, MTH3D_tdstVector *p_stNormal ) { MTH_tdxReal xDPlan; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stSegmentStartPoint; MTH3D_tdstVector stSegmentVector; /* calcul de de l'équation du plan */ xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) ); MTH3D_M_vMulScalarVector (& stTempNormal, p_stGV->xDynamicRadius , p_stNormal ); MTH3D_M_vAddVector (& stSegmentStartPoint , & p_stGV->stDinST0Point , & stTempNormal); /* Start point of the segment*/ MTH3D_M_vMulScalarVector (& stSegmentVector , MTH_C_Minus2 , & stTempNormal); if( INT_fn_bDetectIntersectSegmentWithTriangle( &stSegmentStartPoint, &stSegmentVector, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal, xDPlan ) ) { /* Here, we have collision with the 'end' position. Now, we test collision with the 'start' position*/ MTH3D_tdstVector stMovementVector; /* stDinST01Vector is the translation to go from the 'end' position to the 'start' position of the sphere center*/ /* and we need the translation to go from the 'start' position to the 'end' position*/ MTH3D_M_vNegVector (& stMovementVector, & p_stGV->stDinST01Vector); MTH3D_M_vAddVector (& stSegmentStartPoint , & p_stGV->stDinST1Point , & stTempNormal); /* Start point of the segment*/ if( INT_fn_bDetectIntersectSegmentWithTriangle( &stSegmentStartPoint, & stSegmentVector, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal, xDPlan ) ) { /* Here we have already collision at the 'start' position*/ MTH3D_tdstVector stT0AVector; MTH_tdxReal xDotProduct; MTH_tdxReal xDistance; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stEndPosition; /* The translation*/ MTH3D_M_vSubVector ( & stT0AVector , p_stVertex1 , & p_stGV->stDinST0Point); xDotProduct = MTH3D_M_xDotProductVector (& stT0AVector , p_stNormal); xDistance = MTH_M_xAdd (xDotProduct , p_stGV->xDynamicRadius); MTH3D_M_vMulScalarVector (& stTempDistance , xDistance , p_stNormal); POS_fn_vMulMatrixVector (& stTempDistance , p_stGV->p_stStaticGeomObjMatrix , & stTempDistance); /* The hit*/ MTH3D_M_vMulScalarVector (& stTempHit , xDotProduct , p_stNormal); MTH3D_M_vAddVector (& stTempHit , & p_stGV->stDinST0Point , & stTempHit); POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stTempHit); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal);*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, &p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT*/ POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity , COL_C_xTriangleEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2 , & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else { /* We have collision during the movement : we call the dynamic collision*/ MTH3D_tdstVector stT1Center; MTH_tdxReal xDotProduct; MTH_tdxReal xT; MTH3D_tdstVector stHit; xDotProduct = MTH3D_M_xDotProductVector (p_stNormal , & stMovementVector); /* Calculation of the new center of the sphere*/ MTH3D_M_vMulAddVector (& stT1Center, MTH_M_xNeg ( p_stGV->xDynamicRadius ), p_stNormal, &p_stGV->stDinST1Point); if (INT_fn_bIntersectSegmentWithTriangle2 (& stT1Center , & stMovementVector , p_stVertex1 , p_stVertex2 , p_stVertex3, p_stNormal , xDPlan , xDotProduct , &xT , &stHit)) { /* Here, we have collision during the movement*/ MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stEndPosition; /* The hit*/ POS_fn_vMulMatrixVertex ( &stTempHit, p_stGV->p_stStaticGeomObjMatrix, &(stHit) ); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector ( &stTempNormal, p_stGV->p_stStaticGeomObjMatrix, p_stNormal );*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, &p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT*/ /* The translation is not used*/ MTH3D_M_vNullVector (& stTempDistance); POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); COL_fn_vAddInStaticCollisionTable (xT, & stTempDistance, & stTempHit, &stTempNormal, p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial, COL_C_xSphereEntity, COL_C_xTriangleEntity, p_stGV->p_vParameter1, p_stGV->sParameter2, & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else { /* Here, we don't have collision during the movement (because of the back face, for instance)*/ /* We do as if there was a collision at the 'start' position*/ MTH3D_tdstVector stT0AVector; MTH_tdxReal xDotProduct; MTH_tdxReal xDistance; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stEndPosition; /* The translation*/ if (MTH_M_bGreater (MTH3D_M_xDotProductVector (& stMovementVector , p_stNormal) , MTH_C_ZERO)) { /* The movement and the normal are in the same direction -> back face : we register with time = -1*/ MTH3D_M_vSubVector ( & stT0AVector , p_stVertex1 , & p_stGV->stDinST0Point); xDotProduct = MTH3D_M_xDotProductVector (& stT0AVector , p_stNormal); xDistance = MTH_M_xAdd (xDotProduct , p_stGV->xDynamicRadius); MTH3D_M_vMulScalarVector( &stTempDistance, xDistance, p_stNormal ); POS_fn_vMulMatrixVector ( &stTempDistance, p_stGV->p_stStaticGeomObjMatrix, & stTempDistance ); /* The hit*/ MTH3D_M_vMulScalarVector( &stTempHit, xDotProduct, p_stNormal ); MTH3D_M_vAddVector ( &stTempHit, &p_stGV->stDinST0Point, &stTempHit ); POS_fn_vMulMatrixVertex ( &stTempHit, p_stGV->p_stStaticGeomObjMatrix, & stTempHit ); /* The normal*/ /* JT 271198*/ /* POS_fn_vMulMatrixVector( &stTempNormal, p_stGV->p_stStaticGeomObjMatrix , p_stNormal );*/ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal); /* JT*/ POS_fn_vMulMatrixVector( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix , &stMovementVector ); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable( MTH_C_MinusONE, &stTempDistance, &stTempHit, &stTempNormal, p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial, COL_C_xSphereEntity, COL_C_xTriangleEntity, p_stGV->p_vParameter1, p_stGV-> sParameter2, & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else return FALSE; } } return TRUE; /* Collision*/ } else { return FALSE; /* No collision*/ } } #endif /*USE_ALTIMAPS*/ /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticElementIndexedTriangles() -------------------------------------------------------------------------------- -- Creation date : 30 oct 1996 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ void COL_fn_vCollideStaticElementSpheresWithStaticElementIndexedTriangles ( COL_tdstGVForCollision *p_stGV ) { /* pour les spheres */ for ( p_stGV->xDynamicIndexedSphereIndex = 0 ; p_stGV->xDynamicIndexedSphereIndex < p_stGV->p_stDynamicElementSpheres->xNbSpheres ; p_stGV->xDynamicIndexedSphereIndex++ ) { if( (p_stGV->lBitsFieldOfIndexedSpheresInCollision == COL_C_lUsesAllElements) || COL_M_bIsSetBitOfLong( p_stGV->lBitsFieldOfIndexedSpheresInCollision, p_stGV->xDynamicIndexedSphereIndex ) ) { /* sphere */ p_stGV->p_stDynamicIndexedSphere = p_stGV->p_stDynamicElementSpheres->d_stListOfSpheres + p_stGV->xDynamicIndexedSphereIndex; /* centre de la sphere */ p_stGV->p_stDynamicCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedSphere->xCenterPoint; /* calcul de la trajectoire du centre de dynamique */ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST0Point, &p_stGV->stD2ST0TransformMatrix, p_stGV->p_stDynamicCenter ); /* We need the T1 point and the T01 vector*/ /* Maybe one could compute them only when the first collision is detected (???)*/ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST1Point, &p_stGV->stD2ST1TransformMatrix, p_stGV->p_stDynamicCenter ); MTH3D_M_vSubVector ( &p_stGV->stDinST01Vector, &p_stGV->stDinST1Point, &p_stGV->stDinST0Point ); /* jt 300399 */ /* on oublie surtout pas d'initialiser le rayon, ca serait trop dommage d'utiliser celui de la collision précédente ! */ p_stGV->xDynamicRadius = MTH_M_xDiv ( p_stGV->p_stDynamicIndexedSphere->xRadius, p_stGV->xStaticScale ); /* jt 220399 */ COL_fn_vEnlargeSphereIfNecessary (p_stGV); /* pour les triangles */ for ( p_stGV->xStaticIndexedTriangleIndex = 0 ; p_stGV->xStaticIndexedTriangleIndex < p_stGV->p_stStaticElementIndexedTriangles->xNbFaces ; p_stGV->xStaticIndexedTriangleIndex++ ) { p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial; COL_fn_bCollideStaticSphereWithStaticIndexedTriangle ( p_stGV , FALSE); /* pour les aretes */ for ( p_stGV->xStaticEdgeIndex = 0 ; p_stGV->xStaticEdgeIndex < 3 ; p_stGV->xStaticEdgeIndex++ ) { p_stGV->p_stVertex1 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[p_stGV->xStaticEdgeIndex]; p_stGV->p_stVertex2 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[(p_stGV->xStaticEdgeIndex+1)%3]; MTH3D_M_vSubVector ( &p_stGV->stEdgeVector, p_stGV->p_stVertex2, p_stGV->p_stVertex1 ); /* ANNECY AV {*/ /* WARNING : p_stVertex2 is now the point which DOES NOT BELONG to the edge and not the second point of the edge*/ p_stGV->p_stVertex2 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + p_stGV->xStaticIndexedTriangleIndex)->a3_xIndex[(p_stGV->xStaticEdgeIndex+2)%3]; /* END ANNECY AV }*/ /*p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial;*/ /*p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial;*/ /* ANNECY AV {*/ COL_fn_vCollideStaticSphereWithStaticEdge (p_stGV, p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesNormals + p_stGV->xStaticIndexedTriangleIndex); /* END ANNECY AV }*/ } } } } } #ifdef USE_ALTIMAPS /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticElementAltimap -------------------------------------------------------------------------------- -- Creation date : 30 oct 1996 Author : FPI -------------------------------------------------------------------------------- */ #define COL_M_bIsTaggedPoint( xStart, xCur, xTabDim, yStart, yCur ) \ d_ucTestFlag[ (xCur - xStart) + (yCur - yStart) * xTabDim ] #define COL_M_vTagPoint( xStart, xCur, xTabDim, yStart, yCur ) \ d_ucTestFlag[ (xCur - xStart) + (yCur - yStart) * xTabDim ] = 1 #define COL_M_vUntagPoint( xStart, xCur, xTabDim, yStart, yCur ) \ d_ucTestFlag[ (xCur - xStart) + (yCur - yStart) * xTabDim ] = 0 void COL_fn_vCollideStaticElementSpheresWithStaticElementAltimap( COL_tdstGVForCollision *p_stGV ) { ACP_tdxIndex xAx, xAy, xBx, xBy, xLoopX, xLoopY, xLoopV, xIndex; MTH3D_tdstVector stV1, stV2, stV3, stNorm; ACP_tdxBool xBoolA, xBoolB; /* pour les spheres */ for ( p_stGV->xDynamicIndexedSphereIndex = 0 ; p_stGV->xDynamicIndexedSphereIndex < p_stGV->p_stDynamicElementSpheres->xNbSpheres ; p_stGV->xDynamicIndexedSphereIndex++ ) { if( (p_stGV->lBitsFieldOfIndexedSpheresInCollision == COL_C_lUsesAllElements) || COL_M_bIsSetBitOfLong( p_stGV->lBitsFieldOfIndexedSpheresInCollision, p_stGV->xDynamicIndexedSphereIndex ) ) { /* sphere */ p_stGV->p_stDynamicIndexedSphere = p_stGV->p_stDynamicElementSpheres->d_stListOfSpheres + p_stGV->xDynamicIndexedSphereIndex; /* centre de la sphere */ p_stGV->p_stDynamicCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedSphere->xCenterPoint; /* rayon de la sphere */ p_stGV->xDynamicRadius = MTH_M_xDiv ( p_stGV->p_stDynamicIndexedSphere->xRadius, p_stGV->xStaticScale ); /* calcul de la trajectoire du centre de dynamique */ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST0Point, &p_stGV->stD2ST0TransformMatrix, p_stGV->p_stDynamicCenter ); /* We need the T1 point and the T01 vector*/ /* Maybe one could compute them only when the first collision is detected (???)*/ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST1Point, &p_stGV->stD2ST1TransformMatrix, p_stGV->p_stDynamicCenter ); MTH3D_M_vSubVector ( &p_stGV->stDinST01Vector, &p_stGV->stDinST1Point, &p_stGV->stDinST0Point ); COL_fn_vEnlargeSphereIfNecessary (p_stGV); xBoolA = COL_ucSelectAltimapSquare( p_stGV->p_stStaticElementAltimap, &p_stGV->stDinST1Point, &xAx, &xAy ); xBoolB = COL_ucSelectAltimapSquare( p_stGV->p_stStaticElementAltimap, &p_stGV->stDinST0Point, &xBx, &xBy ); COL_M_vClipSquareSelection( p_stGV->p_stStaticElementAltimap, xAx, xAy, xBoolA ); COL_M_vClipSquareSelection( p_stGV->p_stStaticElementAltimap, xBx, xBy, xBoolB ); p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->xStaticElementIndex = 0; COL_M_vSortSquareSelection( xAx, xBx ); COL_M_vSortSquareSelection( xAy, xBy ); COL_M_vScanSelectedSquares( xLoopX, xLoopY, xLoopV, p_stGV->p_stStaticElementAltimap->xWidth, xAx, xAy, xBx, xBy ) { unsigned char ucType; ucType = p_stGV->p_stStaticElementAltimap->d_stSquare[ xLoopV ].ucType; while( ucType ) { ucType = COL_ucBuildAltimapSquareTriangle( p_stGV->p_stStaticElementAltimap, xLoopX, xLoopY, ucType, &stV1, &stV2, &stV3, &stNorm, &xIndex ); p_stGV->hStaticMaterial = p_stGV->p_stStaticElementAltimap->d_hMaterial[ p_stGV->p_stStaticElementAltimap->d_stFaces[ xIndex ].ucMatIndex ]; /*--- Tests if there where a collision with the triangle*/ if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticITr ) if( COL_fn_bCollideStaticSphereWithStaticAltimap( p_stGV, &stV1, &stV2, &stV3, &stNorm ) ) continue; /*--- There were no collisions with this triangle. We will now test with its points and edges*/ /*------- Points -------*/ /* if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticPts ) { p_stGV->p_stStaticPoint = &stV1; if( !COL_M_bIsTaggedPoint( xAx, xLoopX, (xBx + 1) - xAx, xAy, xLoopY ) ) COL_fn_vCollideStaticSphereWithStaticPoint2( p_stGV ); p_stGV->p_stStaticPoint = &stV2; if( !COL_M_bIsTaggedPoint( xAx, xLoopX, (xBx + 1) - xAx, xAy, xLoopY ) ) COL_fn_vCollideStaticSphereWithStaticPoint2( p_stGV ); p_stGV->p_stStaticPoint = &stV3; if( !COL_M_bIsTaggedPoint( xAx, xLoopX, (xBx + 1) - xAx, xAy, xLoopY ) ) COL_fn_vCollideStaticSphereWithStaticPoint2( p_stGV ); //------- Tagging points ------- switch( ucSaveType - ucType ) { case 1: COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY + 1 ); COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY + 1 ); break; case 2: COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY + 1 ); break; case 4: COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY + 1 ); COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY + 1 ); break; case 8: COL_M_vTagPoint( xAx, xLoopX , (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY ); COL_M_vTagPoint( xAx, xLoopX + 1, (xBx + 1) - xAx, xAy, xLoopY + 1 ); break; } }*/ /*------ Edges ------*/ if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticEdg ) { p_stGV->p_stVertex1 = &stV1; p_stGV->p_stVertex2 = &stV2; MTH3D_M_vSubVector ( &p_stGV->stEdgeVector, p_stGV->p_stVertex2, p_stGV->p_stVertex1 ); COL_fn_vCollideStaticSphereWithStaticEdge ( p_stGV, &stNorm ); p_stGV->p_stVertex1 = &stV2; p_stGV->p_stVertex2 = &stV3; MTH3D_M_vSubVector ( &p_stGV->stEdgeVector, p_stGV->p_stVertex2, p_stGV->p_stVertex1 ); COL_fn_vCollideStaticSphereWithStaticEdge ( p_stGV, &stNorm ); p_stGV->p_stVertex1 = &stV3; p_stGV->p_stVertex2 = &stV1; MTH3D_M_vSubVector ( &p_stGV->stEdgeVector, p_stGV->p_stVertex2, p_stGV->p_stVertex1 ); COL_fn_vCollideStaticSphereWithStaticEdge ( p_stGV, &stNorm ); } } } } } } #endif /*USE_ALTIMAPS*/ /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticElementFaceMapDescriptors() -------------------------------------------------------------------------------- -- Creation date : 30 oct 1996 Author : FPI -------------------------------------------------------------------------------- */ /* void COL_fn_vCollideStaticElementSpheresWithStaticElementFaceMapDescriptors ( COL_tdstGVForCollision *p_stGV ) { // pour les spheres for ( p_stGV->xDynamicIndexedSphereIndex = 0 ; p_stGV->xDynamicIndexedSphereIndex < p_stGV->p_stDynamicElementSpheres->xNbSpheres ; p_stGV->xDynamicIndexedSphereIndex++ ) { if( (p_stGV->lBitsFieldOfIndexedSpheresInCollision == COL_C_lUsesAllElements) || COL_M_bIsSetBitOfLong( p_stGV->lBitsFieldOfIndexedSpheresInCollision, p_stGV->xDynamicIndexedSphereIndex ) ) { // sphere p_stGV->p_stDynamicIndexedSphere = p_stGV->p_stDynamicElementSpheres->d_stListOfSpheres + p_stGV->xDynamicIndexedSphereIndex; // centre de la sphere p_stGV->p_stDynamicCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedSphere->xCenterPoint; // rayon de la sphere p_stGV->xDynamicRadius = MTH_M_xDiv ( p_stGV->p_stDynamicIndexedSphere->xRadius, p_stGV->xStaticScale ); // calcul de la trajectoire du centre de dynamique POS_fn_vMulMatrixVertex ( &p_stGV->stDinST0Point, &p_stGV->stD2ST0TransformMatrix, p_stGV->p_stDynamicCenter ); // We need the T1 point and the T01 vector // Maybe one could compute them only when the first collision is detected (???) POS_fn_vMulMatrixVertex ( &p_stGV->stDinST1Point, &p_stGV->stD2ST1TransformMatrix, p_stGV->p_stDynamicCenter ); MTH3D_M_vSubVector ( &p_stGV->stDinST01Vector, &p_stGV->stDinST1Point, &p_stGV->stDinST0Point ); COL_fn_vEnlargeSphereIfNecessary (p_stGV); // pour les triangles for ( p_stGV->xStaticFaceMapTriangleIndex = 0 ; p_stGV->xStaticFaceMapTriangleIndex < p_stGV->p_stStaticElementFaceMapDescriptors->xNbFaces ; p_stGV->xStaticFaceMapTriangleIndex++ ) { GEO_xGetFaceMapDescriptorGameMaterial ( (p_stGV->p_stStaticElementFaceMapDescriptors->d_stListOfFacesQuadrupled + p_stGV->xStaticFaceMapTriangleIndex)->hFaceMapDescriptor, &p_stGV->hStaticMaterial ); p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; COL_fn_bCollideStaticSphereWithStaticIndexedTriangle ( p_stGV , TRUE); } } } } */ /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicSphereWithStaticSphere() -------------------------------------------------------------------------------- -- Creation date : 27 dec 1996 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ void COL_fn_vCollideStaticSphereWithStaticSphere ( COL_tdstGVForCollision *p_stGV ) { MTH_tdxReal xRadiusSum; /* centre de la sphere */ p_stGV->p_stStaticCenter = p_stGV->p_stStaticGeomObj->d_stListOfPoints + p_stGV->p_stStaticIndexedSphere->xCenterPoint; /* rayon virtuel */ xRadiusSum = MTH_M_xAdd (p_stGV->xDynamicRadius , p_stGV->p_stStaticIndexedSphere->xRadius); if (INT_fn_bGetInclusionPointInSphere (& p_stGV->stDinST0Point, p_stGV->p_stStaticCenter, xRadiusSum)) { /* Here, we have collision with the 'end' position*/ /* Now, we test collision with the 'start' position*/ MTH3D_tdstVector stMovementVector; /* stDinST01Vector is the translation to go from the 'end' position to the 'start' position of the sphere center*/ /* and we need the translation to go from the 'start' position to the 'end' position*/ MTH3D_M_vNegVector (& stMovementVector, & p_stGV->stDinST01Vector); /* jt 010499*/ COL_fn_vUseInitialSphere (p_stGV); xRadiusSum = MTH_M_xAdd (p_stGV->xDynamicRadius , p_stGV->p_stStaticIndexedSphere->xRadius); if (INT_fn_bGetInclusionPointInSphere (& p_stGV->stDinST1Point , p_stGV->p_stStaticCenter , xRadiusSum)) { /* Here we have already collision at the 'start' position*/ MTH3D_tdstVector stCenterToCenter; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stEndPosition; /* The normal : it is the normalized vector from the static center to the dynamic center*/ MTH3D_M_vSubVector (& stCenterToCenter , & p_stGV->stDinST0Point , p_stGV->p_stStaticCenter); POS_fn_vMulMatrixVector (& stCenterToCenter , p_stGV->p_stStaticGeomObjMatrix , & stCenterToCenter); MTH3D_M_vNormalizeVector (& stTempNormal , & stCenterToCenter); /* The hit = static center + static radius x normal*/ POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , p_stGV->p_stStaticCenter); MTH3D_M_vMulAddVector (& stTempHit , p_stGV->p_stStaticIndexedSphere->xRadius , & stTempNormal , & stTempHit); /* The translation*/ /* jt 060799 */ MTH3D_M_vMulScalarVector (& stTempDistance , MTH_M_xAdd(xRadiusSum,MTH_M_xDoubleToReal(0.001)) , & stTempNormal); /* end jt 060799 */ /* jt 300499 */ MTH3D_M_vSubVector (& stTempDistance , & stTempDistance , & stCenterToCenter); // MTH3D_M_vSubVector (& stTempDistance , & stCenterToCenter , & stTempDistance); /* end jt 300499 */ POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity , COL_C_xSphereEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2 , & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } else { /* Here, there is collision during the movement : we call the dynamic collision*/ MTH_tdxReal xT; MTH3D_tdstVector stHit; MTH3D_tdstVector stNormal; MTH3D_tdstVector stTempHit; MTH3D_tdstVector stTempNormal; MTH3D_tdstVector stTempDistance; MTH3D_tdstVector stEndPosition; POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point); if (INT_fn_bIntersectSegmentWithSphere (& p_stGV->stDinST1Point , & stMovementVector , p_stGV->p_stStaticCenter , xRadiusSum , & xT , & stHit , & stNormal)) { /* The hit*/ MTH3D_M_vLinearInterpolVector (& stHit , & stHit , p_stGV->p_stStaticCenter , MTH_M_xDiv (p_stGV->xDynamicRadius , xRadiusSum)); POS_fn_vMulMatrixVertex (& stTempHit, p_stGV->p_stStaticGeomObjMatrix , & stHit); /* The normal*/ /* jt 080499 */ /* POS_fn_vMulMatrixVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , & stNormal); */ MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, & stNormal); /* end jt */ /* The translation is not used*/ MTH3D_M_vNullVector (& stTempDistance); POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); COL_fn_vAddInStaticCollisionTable (xT , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity, COL_C_xSphereEntity, p_stGV->p_vParameter1, p_stGV->sParameter2, & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } /* jt 010499 */ #ifdef toto else { /* Here, we don't have collision during the movement (because of the back face, for instance)*/ /* We do as if there was a collision at the 'start' position*/ MTH3D_tdstVector stCenterToCenter; /* The normal : it is the normalized vector from the static center to the dynamic center*/ MTH3D_M_vSubVector (& stCenterToCenter , & p_stGV->stDinST0Point , p_stGV->p_stStaticCenter); POS_fn_vMulMatrixVector (& stCenterToCenter , p_stGV->p_stStaticGeomObjMatrix , & stCenterToCenter); MTH3D_M_vNormalizeVector (& stTempNormal , & stCenterToCenter); /* The hit = static center + static radius x normal*/ POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , p_stGV->p_stStaticCenter); MTH3D_M_vMulAddVector (& stTempHit , p_stGV->p_stStaticIndexedSphere->xRadius , & stTempNormal , & stTempHit); /* The translation*/ MTH3D_M_vMulScalarVector (& stTempDistance , xRadiusSum , & stTempNormal); MTH3D_M_vSubVector (& stTempDistance , & stTempDistance , & stCenterToCenter); POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector); /* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xSphereEntity , COL_C_xSphereEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2 , & stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition); } #endif } } } /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticElementSpheres() -------------------------------------------------------------------------------- -- Creation date : 30 oct 1996 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ void COL_fn_vCollideStaticElementSpheresWithStaticElementSpheres ( COL_tdstGVForCollision *p_stGV ) { /* pour les spheres */ for ( p_stGV->xDynamicIndexedSphereIndex = 0 ; p_stGV->xDynamicIndexedSphereIndex < p_stGV->p_stDynamicElementSpheres->xNbSpheres ; p_stGV->xDynamicIndexedSphereIndex++ ) { /* sphere */ p_stGV->p_stDynamicIndexedSphere = p_stGV->p_stDynamicElementSpheres->d_stListOfSpheres + p_stGV->xDynamicIndexedSphereIndex; /* centre de la sphere */ p_stGV->p_stDynamicCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedSphere->xCenterPoint; /* rayon de la sphere */ p_stGV->xDynamicRadius = MTH_M_xDiv ( p_stGV->p_stDynamicIndexedSphere->xRadius, p_stGV->xStaticScale ); /* calcul de la trajectoire du centre de dynamique */ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST0Point, &p_stGV->stD2ST0TransformMatrix, p_stGV->p_stDynamicCenter ); /* We need the T1 point and the T01 vector*/ /* Maybe one could compute them only when the first collision is detected (???)*/ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST1Point, &p_stGV->stD2ST1TransformMatrix, p_stGV->p_stDynamicCenter ); MTH3D_M_vSubVector ( &p_stGV->stDinST01Vector, &p_stGV->stDinST1Point, &p_stGV->stDinST0Point ); COL_fn_vEnlargeSphereIfNecessary (p_stGV); /* pour les spheres */ for ( p_stGV->xStaticIndexedSphereIndex = 0 ; p_stGV->xStaticIndexedSphereIndex < p_stGV->p_stStaticElementSpheres->xNbSpheres ; p_stGV->xStaticIndexedSphereIndex++ ) { /* sphere */ p_stGV->p_stStaticIndexedSphere = p_stGV->p_stStaticElementSpheres->d_stListOfSpheres + p_stGV->xStaticIndexedSphereIndex; p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticIndexedSphere->hMaterial; COL_fn_vCollideStaticSphereWithStaticSphere ( p_stGV ); } } } /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticOctree() -------------------------------------------------------------------------------- -- Creation date : 30 dec 1996 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ void COL_fn_vCollideStaticElementSpheresWithStaticOctree ( COL_tdstGVForCollision *p_stGV ) { COL_tdxFaceIndex *p_xListIndex; ACP_tdxIndex xNodeIndex; COL_tdxFaceIndex xIndex; ACP_tdxIndex xDataElementIndex; MTH3D_tdstVector stMinPoint; MTH3D_tdstVector stMaxPoint; ACP_tdxIndex xNbElements; /* pour les spheres */ for ( p_stGV->xDynamicIndexedSphereIndex = 0 ; p_stGV->xDynamicIndexedSphereIndex < p_stGV->p_stDynamicElementSpheres->xNbSpheres ; p_stGV->xDynamicIndexedSphereIndex++ ) { /* sphere */ p_stGV->p_stDynamicIndexedSphere = p_stGV->p_stDynamicElementSpheres->d_stListOfSpheres + p_stGV->xDynamicIndexedSphereIndex; /* centre de la sphere */ p_stGV->p_stDynamicCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedSphere->xCenterPoint; /* rayon de la sphere */ p_stGV->xDynamicRadius = MTH_M_xDiv ( p_stGV->p_stDynamicIndexedSphere->xRadius, p_stGV->xStaticScale ); /* calcul de la trajectoire du centre de dynamique */ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST0Point, &p_stGV->stD2ST0TransformMatrix, p_stGV->p_stDynamicCenter ); /* We need the T1 point and the T01 vector*/ /* Maybe one could compute them only when the first collision is detected (???)*/ POS_fn_vMulMatrixVertex ( &p_stGV->stDinST1Point, &p_stGV->stD2ST1TransformMatrix, p_stGV->p_stDynamicCenter ); MTH3D_M_vSubVector ( &p_stGV->stDinST01Vector, &p_stGV->stDinST1Point, &p_stGV->stDinST0Point ); /* jt 260399 */ COL_fn_vEnlargeSphereIfNecessary (p_stGV); /* transformation de la sphere en boite */ COL_fn_vComputeBoundingBoxOfSphere ( &stMinPoint, &stMaxPoint, &p_stGV->stDinST0Point, p_stGV->xDynamicRadius ); /* avec octree */ COL_fn_vExploreOctreeWithBox ( p_stGV->p_stOctree, &stMinPoint, &stMaxPoint, p_stGV->aDEF_pstSelectedNode, &p_stGV->xNumberOfSelectedNodes ); COL_g_lFacesTagCounter ++; /* pour les noeuds selectionnes */ for ( xNodeIndex = 0 ; xNodeIndex < p_stGV->xNumberOfSelectedNodes ; xNodeIndex++ ) { /* pour la liste des faces */ xNbElements = *((COL_tdxFaceIndexDouble*)p_stGV->aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList); p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)p_stGV->aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1); for (xIndex = 0 ; xIndex < xNbElements ; xIndex++) { if ((*p_xListIndex) < COL_C_MaxIndex) p_stGV->xStaticElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++)); else { ACP_tdxIndex xData; xData=(ACP_tdxIndex)(* (p_xListIndex ++)); xData<<=8; xData+=(ACP_tdxIndex)(* (p_xListIndex ++)); xData&=~COL_C_OverflowIndex; p_stGV->xStaticElementIndex = xData; } if ((*p_xListIndex) < COL_C_MaxIndex) xDataElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++)); else { ACP_tdxIndex xData; xData=(ACP_tdxIndex)(* (p_xListIndex ++)); xData<<=8; xData+=(ACP_tdxIndex)(* (p_xListIndex ++)); xData&=~COL_C_OverflowIndex; xDataElementIndex = xData; } /* verif tag */ if ( COL_g_d_lTaggedFacesTable[p_stGV->p_stOctree->d_xElementBasesTable[p_stGV->xStaticElementIndex] + xDataElementIndex] != COL_g_lFacesTagCounter ) { switch ( p_stGV->p_stStaticGeomObj->d_xListOfElementsTypes[p_stGV->xStaticElementIndex] ) { case GEO_C_xElementIndexedTriangles : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticITr ) { p_stGV->p_stStaticElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); p_stGV->xStaticIndexedTriangleIndex = xDataElementIndex; p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial; /* If there is a collision with the triangle, it is not necessary to test the edges and the points*/ if (COL_fn_bCollideStaticSphereWithStaticIndexedTriangle ( p_stGV , FALSE)) break; } if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticEdg ) { /* pour les aretes du triangle*/ for ( p_stGV->xStaticEdgeIndex = 0 ; p_stGV->xStaticEdgeIndex < 3 ; p_stGV->xStaticEdgeIndex++ ) { p_stGV->p_stVertex1 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[p_stGV->xStaticEdgeIndex]; p_stGV->p_stVertex2 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[(p_stGV->xStaticEdgeIndex+1)%3]; MTH3D_M_vSubVector ( &p_stGV->stEdgeVector, p_stGV->p_stVertex2, p_stGV->p_stVertex1 ); /* WARNING : p_stVertex2 is now the point which DOES NOT BELONG to the edge and not the second point of the edge*/ p_stGV->p_stVertex2 = p_stGV->p_stStaticGeomObj->d_stListOfPoints + (p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[(p_stGV->xStaticEdgeIndex+2)%3]; p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial; COL_fn_vCollideStaticSphereWithStaticEdge (p_stGV, p_stGV->p_stStaticElementIndexedTriangles->d_stListOfFacesNormals + p_stGV->xStaticIndexedTriangleIndex); } } break; case GEO_C_xElementSpheres : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticSph ) { p_stGV->p_stStaticElementSpheres = (GEO_tdstElementSpheres *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); p_stGV->xStaticIndexedSphereIndex = xDataElementIndex; /* sphere */ p_stGV->p_stStaticIndexedSphere = p_stGV->p_stStaticElementSpheres->d_stListOfSpheres + p_stGV->xStaticIndexedSphereIndex; p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedSphere->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticIndexedSphere->hMaterial; COL_fn_vCollideStaticSphereWithStaticSphere ( p_stGV ); } break; } COL_g_d_lTaggedFacesTable[p_stGV->p_stOctree->d_xElementBasesTable[p_stGV->xStaticElementIndex] + xDataElementIndex] = COL_g_lFacesTagCounter; } } } } } /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticElements() -------------------------------------------------------------------------------- -- Creation date : 03 jan 1997 Author : FPI -------------------------------------------------------------------------------- */ /* used*/ void COL_fn_vCollideStaticElementSpheresWithStaticElements ( COL_tdstGVForCollision *p_stGV ) { long a_DEF_lBitsFieldOfCollisionsWithBoundingBox[COL_C_xMaxStaticBoundingBoxes]; ACP_tdxIndex xIndexBox; if (p_stGV->p_stStaticGeomObj->xNbParallelBoxes && ! COL_fn_bCollideStaticElementSpheresWithStaticBoundingVolumes( p_stGV, a_DEF_lBitsFieldOfCollisionsWithBoundingBox , (ACP_tdxBool) (p_stGV-> p_stOctree != NULL) ) ) return; PRF_fn_vSetIndependantVariable( PRF_C_ulIdpCollComputed, 1 ); if ( p_stGV->p_stOctree == NULL ) { /* pour les elements de statique */ for ( p_stGV->xStaticElementIndex = 0 ; p_stGV->xStaticElementIndex < p_stGV->p_stStaticGeomObj->xNbElements ; p_stGV->xStaticElementIndex++ ) { if (p_stGV->p_stStaticGeomObj->xNbParallelBoxes) { xIndexBox = GEO_xGetParallelBoxIndexOfElement( p_stGV->p_stStaticGeomObj, p_stGV->xStaticElementIndex ); p_stGV->lBitsFieldOfIndexedSpheresInCollision = (xIndexBox == GEO_C_xNoParallelBox) ? COL_C_lUsesAllElements : a_DEF_lBitsFieldOfCollisionsWithBoundingBox[ xIndexBox ]; if (p_stGV->lBitsFieldOfIndexedSpheresInCollision == 0) continue; } else p_stGV->lBitsFieldOfIndexedSpheresInCollision = COL_C_lUsesAllElements; switch ( p_stGV->p_stStaticGeomObj->d_xListOfElementsTypes[p_stGV->xStaticElementIndex] ) { case GEO_C_xElementIndexedTriangles : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticITr ) { p_stGV->p_stStaticElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); COL_fn_vCollideStaticElementSpheresWithStaticElementIndexedTriangles ( p_stGV ); } break; #ifdef USE_ALTIMAPS case GEO_C_xElementAltimap : /* if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticIAlt )*/ /* {*/ p_stGV->p_stStaticElementAltimap = (GEO_tdstElementAltimap *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); COL_fn_vCollideStaticElementSpheresWithStaticElementAltimap ( p_stGV ); /* }*/ break; #endif /*USE_ALTIMAPS*/ case GEO_C_xElementSpheres : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticSph ) { p_stGV->p_stStaticElementSpheres = (GEO_tdstElementSpheres *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); COL_fn_vCollideStaticElementSpheresWithStaticElementSpheres ( p_stGV ); } break; } } } else { if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticElt ) { COL_fn_vCollideStaticElementSpheresWithStaticOctree ( p_stGV ); } } } /* -------------------------------------------------------------------------------- -- Description : COL_fn_vCollideDynamicElementSpheresWithStaticBoundingVolumes() -------------------------------------------------------------------------------- -- Creation date : 01 apr 1998 Author : MT -------------------------------------------------------------------------------- */ /* used*/ ACP_tdxBool COL_fn_bCollideStaticElementSpheresWithStaticBoundingVolumes( COL_tdstGVForCollision *p_stGV , long *_aDEF_lBitsFieldInCollision, ACP_tdxBool _bPartialResult) { ACP_tdxIndex xIndexBox , xIndexSphere; long *p_lCurrentBitsField; GEO_tdxHandleToParallelBox hBox; MTH3D_tdstVector *p_stMinPointBox , *p_stMaxPointBox; MTH3D_tdstVector *p_stCenter , stFirstCenter , stMinPointSphere , stMaxPointSphere , stMinPointLocalSphere , stMaxPointLocalSphere ; MTH_tdxReal xRadius; ACP_tdxBool bResult; bResult = FALSE; /* recupère le centre de la première sphere pour initialiser le min et le max*/ p_stCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ 0 ] . xCenterPoint; POS_fn_vMulMatrixVertex ( & stFirstCenter , & p_stGV -> stD2ST0TransformMatrix , p_stCenter ); /* calcul du rayon*/ xRadius = MTH_M_xDiv ( p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ 0 ] . xRadius, p_stGV -> xStaticScale ); /**/ COL_fn_vComputeBoundingBoxOfSphere ( & stMinPointSphere , & stMaxPointSphere , & stFirstCenter , xRadius ); /**/ /* calcul des spheres*/ for ( xIndexSphere = 1 ; xIndexSphere < p_stGV -> p_stDynamicElementSpheres -> xNbSpheres ; xIndexSphere++ ) { /* recupère le centre de la sphere*/ p_stCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ xIndexSphere ] . xCenterPoint; POS_fn_vMulMatrixVertex ( & stFirstCenter , & p_stGV -> stD2ST0TransformMatrix , p_stCenter ); /* calcul du rayon*/ xRadius = MTH_M_xDiv ( p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ xIndexSphere ] . xRadius, p_stGV -> xStaticScale ); /**/ COL_fn_vComputeBoundingBoxOfSphereAndBox ( & stMinPointSphere , & stMaxPointSphere , & stFirstCenter , xRadius , & stMinPointSphere , & stMaxPointSphere ); } /**/ for ( xIndexBox = 0 , hBox = p_stGV->p_stStaticGeomObj->d_stListOfParallelBoxes , p_lCurrentBitsField = _aDEF_lBitsFieldInCollision ; xIndexBox < p_stGV->p_stStaticGeomObj->xNbParallelBoxes ; xIndexBox++ , hBox++, p_lCurrentBitsField++ ) { *p_lCurrentBitsField = 0; p_stMinPointBox = & hBox -> stMinPoint ; p_stMaxPointBox = & hBox -> stMaxPoint ; /**/ if( COL_fn_bDetectCollisionBetweenTwoParallelBoxes( & stMaxPointSphere , & stMinPointSphere , p_stMaxPointBox , p_stMinPointBox ) ) { for ( xIndexSphere = 0 ; xIndexSphere < p_stGV -> p_stDynamicElementSpheres -> xNbSpheres ; xIndexSphere++ ) { /* recupère le centre de la sphere*/ p_stCenter = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ xIndexSphere ] . xCenterPoint; POS_fn_vMulMatrixVertex ( & stFirstCenter , & p_stGV -> stD2ST0TransformMatrix , p_stCenter ); /* calcul du rayon*/ xRadius = MTH_M_xDiv ( p_stGV -> p_stDynamicElementSpheres -> d_stListOfSpheres [ xIndexSphere ] . xRadius, p_stGV -> xStaticScale ); /**/ COL_fn_vComputeBoundingBoxOfSphere ( & stMinPointLocalSphere , & stMaxPointLocalSphere , & stFirstCenter , xRadius ); if( COL_fn_bDetectCollisionBetweenTwoParallelBoxes( & stMaxPointLocalSphere , & stMinPointLocalSphere , p_stMaxPointBox , p_stMinPointBox ) ) { COL_M_vSetBitOfLong( *p_lCurrentBitsField, xIndexSphere ); bResult = TRUE; if (_bPartialResult) return TRUE; } } } } return bResult; }