/*******************************************************************************/ /* To use the functions of this file, define USE_ZDM_BOX*/ /*******************************************************************************/ #ifdef USE_ZDM_BOX /* 0 1 2 3 4 5 6 7 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -------------------------------------------------------------------------------- -- Description : Geometric object (static) collision part : Box - Elt -------------------------------------------------------------------------------- -- Creation date : 04 Mar 98 Author : Thierry Quere -------------------------------------------------------------------------------- */ #include "acp_base.h" #include "MTH.h" #include "MEC.h" #include "GMT.h" #include "GEO.h" #include "GLI.h" #include "COL/CsBoxElt.h" #include "PRF.h" #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 ) ) /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticAlignedBoxWithStaticIndexedTriangle*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticAlignedBoxWithStaticIndexedTriangle (COL_tdstGVForCollision *p_stGV, ACP_tdxBool bFaceMapInsteadOfIndexedTriangle) { MTH3D_tdstVector *p_stVertex1; MTH3D_tdstVector *p_stVertex2; MTH3D_tdstVector *p_stVertex3; MTH3D_tdstVector *p_stNormal; MTH3D_tdstVector stHitPoint; MTH3D_tdstVector stFinalHit; MTH3D_tdstVector stNormal; MTH3D_tdstVector stTrans; MTH_tdxReal xTrans; MTH3D_tdstVector stMovementVector; MTH3D_tdstVector stEndPosition; ACP_tdxIndex xVertexIndex; { /* 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; } /* We test wether there is collision with the final position or not */ if(INT_fn_bIntersectTriangleWithBoxWithHit(p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint, &stFinalHit)) { MTH3D_M_vMiddleVector (& stEndPosition , & p_stGV->stDinST0Point , & p_stGV->stDinST1Point); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & stEndPosition); /* There is collision with the final position We wonder if there was already collision with the initial position */ if (INT_fn_bIntersectTriangleWithBoxWithHit(p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal, &p_stGV->stDinST1MinPoint, &p_stGV->stDinST1MaxPoint, &stHitPoint)) { /* There was already collision with the initial position */ /* We compute Hit point and Triangle face normal from local to global axis system */ POS_fn_vMulMatrixVertex (& stHitPoint , p_stGV->p_stStaticGeomObjMatrix , &stHitPoint); POS_fn_vMulMatrixVertex (& stNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal); /* stTrans represents the point of the box that is "deeper" in the triangle after collision */ stTrans.xX = ((MTH_M_bLessEqualZero(p_stNormal->xX)) ? p_stGV->stDinST0MaxPoint.xX : p_stGV->stDinST0MinPoint.xX); stTrans.xY = ((MTH_M_bLessEqualZero(p_stNormal->xY)) ? p_stGV->stDinST0MaxPoint.xY : p_stGV->stDinST0MinPoint.xY); stTrans.xZ = ((MTH_M_bLessEqualZero(p_stNormal->xZ)) ? p_stGV->stDinST0MaxPoint.xZ : p_stGV->stDinST0MinPoint.xZ); /* Now, we want to obtain the movement vector of the point that collides ... This data is usefull for DNM */ for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) { if(M_bIsVectorsEqualWithEpsilon(&p_stGV->a8_stDinST08VBox[xVertexIndex], &stTrans, 0.005)) { MTH3D_M_vCopyVector(&stMovementVector, &p_stGV->a8_stDinST01Vect[xVertexIndex]); /* The vector we have is from the final to the initial position, we want the opposite */ MTH3D_M_vNegVector (&stMovementVector, &stMovementVector) POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); break; } } /* Vector ("Deeper" point of the box in the triangle) -> (One Point of the Triangle) */ MTH3D_M_vSubVector ( &stTrans , p_stVertex1, &stTrans); /* Value of the translation needed to move the box out of the triangle */ xTrans = MTH3D_M_xDotProductVector (&stTrans , p_stNormal); /* Translation vector */ MTH3D_M_vMulScalarVector (&stTrans , xTrans , p_stNormal); /* We compute the translation vector from the local axis sytem to the global one */ POS_fn_vMulMatrixVector (&stTrans , p_stGV->p_stStaticGeomObjMatrix , &stTrans); /* There, we have collision with both the initial and final positions */ /* We register the collision with Time = -1 to precise that there was already collision at the very beginning */ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , &stTrans , &stHitPoint , &stNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xAlignedBoxEntity , COL_C_xTriangleEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2, &stMovementVector,MTH_C_ZERO/*???*/, & stEndPosition); } else { /* There was NOT collision at the start position ... */ /* We call the dynamic collision */ MTH_tdxReal xDPlan; MTH_tdxReal xT; MTH_tdxReal xFirstT = 1.0; MTH_tdxReal xDotProduct; MTH3D_tdstVector stNormal; MTH3D_tdstVector stTrans; MTH3D_tdstVector stFirstNormal; MTH3D_tdstVector stFirstHitPoint; MTH3D_tdstVector stFirstMovementVector; ACP_tdxBool bColDyn; /* If the dynamic collision don't give us the collision we want, we will be obliged to call back the static collision that need the Hit point */ /*MTH3D_M_vCopyVector(&stDummy, &stHitPoint);*/ bColDyn = FALSE; /* Plan of the triangle */ xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) ); for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) { MTH3D_M_vNegVector (&stMovementVector, &p_stGV->a8_stDinST01Vect[xVertexIndex]); xDotProduct = MTH3D_M_xDotProductVector (p_stNormal , & stMovementVector); if(INT_fn_bIntersectSegmentWithTriangle2 ( &(p_stGV->a8_stDinST18VBox[xVertexIndex]), &stMovementVector, p_stVertex1, p_stVertex2, p_stVertex3, p_stNormal, xDPlan, xDotProduct, &xT, &stHitPoint)) { if(xTp_stStaticGeomObjMatrix, &stHitPoint); /* We compute the movement vector */ POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); /* The translation vector is not usefull in that case */ MTH3D_M_vNullVector (& stTrans); /* We compute the triangle face normal from the local to the global axis system */ POS_fn_vMulMatrixVector ( &stNormal, p_stGV->p_stStaticGeomObjMatrix, p_stNormal ); /* Those point will be added in the collision table */ MTH3D_M_vCopyVector(&stFirstNormal, &stNormal); MTH3D_M_vCopyVector(&stFirstMovementVector, &stMovementVector); MTH3D_M_vCopyVector(&stFirstHitPoint, &stHitPoint); /* We have found a dynamic collision */ bColDyn = TRUE; } } } if(bColDyn) COL_fn_vAddInStaticCollisionTable (xFirstT, &stTrans, & stFirstHitPoint, &stFirstNormal, p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial, COL_C_xAlignedBoxEntity, COL_C_xTriangleEntity, p_stGV->p_vParameter1, p_stGV->sParameter2, &stFirstMovementVector,MTH_C_ZERO/*???*/, & 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_M_vCopyVector(&stHitPoint, &stFinalHit); POS_fn_vMulMatrixVertex (&stHitPoint , p_stGV->p_stStaticGeomObjMatrix , &stHitPoint); POS_fn_vMulMatrixVertex (&stNormal, p_stGV->p_stStaticGeomObjMatrix , p_stNormal); /* stTrans represents the point of the box that is "deeper" in the triangle after collision */ /* 0 ou 1 */ stTrans.xX = ((MTH_M_bLessEqualZero(p_stNormal->xX)) ? p_stGV->stDinST0MaxPoint.xX : p_stGV->stDinST0MinPoint.xX); stTrans.xY = ((MTH_M_bLessEqualZero(p_stNormal->xY)) ? p_stGV->stDinST0MaxPoint.xY : p_stGV->stDinST0MinPoint.xY); stTrans.xZ = ((MTH_M_bLessEqualZero(p_stNormal->xZ)) ? p_stGV->stDinST0MaxPoint.xZ : p_stGV->stDinST0MinPoint.xZ); /* Now, we want to obtain the movement vector of the point that collides ... This data is usefull for DNM */ for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) { if(M_bIsVectorsEqualWithEpsilon(&p_stGV->a8_stDinST08VBox[xVertexIndex], &stTrans, 0.005)) { MTH3D_M_vCopyVector(&stMovementVector, &p_stGV->a8_stDinST01Vect[xVertexIndex]); /* The vector we have is from the final to the initial position, we want the opposite */ MTH3D_M_vNegVector (&stMovementVector, &stMovementVector); POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); break; } } /* Vector ("Deeper" point of the box in the triangle) -> (One Point of the Triangle) */ MTH3D_M_vSubVector ( &stTrans , p_stVertex1, &stTrans); /* Value of the translation needed to move the box out of the triangle */ xTrans = MTH3D_M_xDotProductVector (&stTrans , p_stNormal); /* Translation vector */ MTH3D_M_vMulScalarVector (&stTrans , xTrans , p_stNormal); /* We compute the translation vector from the local axis sytem to the global one */ POS_fn_vMulMatrixVector (&stTrans , p_stGV->p_stStaticGeomObjMatrix , &stTrans); /* There, we have collision with both the initial and final positions */ /* We register the collision with Time = -1 to precise that there was already collision at the very beginning */ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , &stTrans , &stHitPoint , &stNormal , p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xAlignedBoxEntity , COL_C_xTriangleEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2, &stMovementVector,MTH_C_ZERO/*???*/, & stEndPosition); } } } } /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementIndexedTriangles*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementIndexedTriangles (COL_tdstGVForCollision *p_stGV) { ACP_tdxIndex xVertexIndex; MTH3D_tdstVector stCenterPoint; MTH3D_tdstVector stPointinS; MTH_tdxReal xHalfEdge; MTH_tdxReal yHalfEdge; MTH_tdxReal zHalfEdge; for ( p_stGV->xDynamicIndexedAlignedBoxIndex = 0 ; p_stGV->xDynamicIndexedAlignedBoxIndex < p_stGV->p_stDynamicElementAlignedBoxes->xNbAlignedBoxes ; p_stGV->xDynamicIndexedAlignedBoxIndex++ ) { /* Several infos about the box */ p_stGV->p_stDynamicIndexedAlignedBox = p_stGV->p_stDynamicElementAlignedBoxes->d_stListOfAlignedBoxes + p_stGV->xDynamicIndexedAlignedBoxIndex; p_stGV->p_stDynamicMinPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMinPoint; p_stGV->p_stDynamicMaxPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMaxPoint; /* We compute the "center" point of the box */ MTH3D_M_vMiddleVector(&stCenterPoint, p_stGV->p_stDynamicMinPoint, p_stGV->p_stDynamicMaxPoint); xHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xX, stCenterPoint.xX); yHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xY, stCenterPoint.xY); zHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xZ, stCenterPoint.xZ); /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the FINAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT0DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the FINAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points in that system */ /* but first we have to compute the size of the box in the static axis system (scale) */ xHalfEdge = MTH_M_xDiv ( xHalfEdge, p_stGV->xStaticScale ); yHalfEdge = MTH_M_xDiv ( yHalfEdge, p_stGV->xStaticScale ); zHalfEdge = MTH_M_xDiv ( zHalfEdge, p_stGV->xStaticScale ); p_stGV->stDinST0MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST0MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the FINAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST08VBox, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint ); /*-------------------------------------------------------------------------------------------*/ /* THE FOLLOWING LINES ARE IDENTICAL TO THE PREVIOUS ONES BUT DEAL WITH THE INITIAL POSITION */ /*-------------------------------------------------------------------------------------------*/ /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the INITIAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT1DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the INITIAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points */ p_stGV->stDinST1MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST1MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the INITIAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST18VBox, &p_stGV->stDinST1MinPoint, &p_stGV->stDinST1MaxPoint ); /* We also need the 8 "translation" vertices */ /* (Final position) Vertice i -> Vertice i (Initial Position) */ for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) MTH3D_M_vSubVector ( &(p_stGV->a8_stDinST01Vect[xVertexIndex]), &(p_stGV->a8_stDinST18VBox[xVertexIndex]), &(p_stGV->a8_stDinST08VBox[xVertexIndex]) ); for ( p_stGV->xStaticIndexedTriangleIndex = 0 ; p_stGV->xStaticIndexedTriangleIndex < p_stGV->p_stStaticElementIndexedTriangles->xNbFaces ; p_stGV->xStaticIndexedTriangleIndex++ ) { p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedAlignedBox->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial; COL_fn_vCollideStaticAlignedBoxWithStaticIndexedTriangle (p_stGV, FALSE ); } } } /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticAlignedBoxWithStaticSphere*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticAlignedBoxWithStaticSphere (COL_tdstGVForCollision *p_stGV) { MTH3D_tdstVector stHitPoint; MTH3D_tdstVector stVectCenterHit; MTH3D_tdstVector stPointBox; MTH3D_tdstVector stNormal; MTH3D_tdstVector stTrans; MTH3D_tdstVector stMovementVector; MTH_tdxReal xTrans; MTH_tdxReal a6_Distance[6]; ACP_tdxIndex xIndexClosest; ACP_tdxIndex xIndex; MTH3D_tdstVector stEndPosition; /* The center of the static sphere */ p_stGV->p_stStaticCenter = p_stGV->p_stStaticGeomObj->d_stListOfPoints + p_stGV->p_stStaticIndexedSphere->xCenterPoint; /* Is there collision with the FINAL position box ?? */ if(INT_fn_bIntersectSphereWithBox(p_stGV->p_stStaticCenter, p_stGV->p_stStaticIndexedSphere->xRadius, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint)) { MTH3D_M_vMiddleVector (& stEndPosition , & p_stGV->stDinST0Point , & p_stGV->stDinST1Point); POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & stEndPosition); /* Is there also collision with the INITIAL position box ??*/ if(INT_fn_bIntersectSphereWithBox(p_stGV->p_stStaticCenter, p_stGV->p_stStaticIndexedSphere->xRadius, &p_stGV->stDinST1MinPoint, &p_stGV->stDinST1MaxPoint)) { /* Yes, there is already collision at the INITIAL position */ /* The Hit point */ xIndex = 0; if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MaxPoint.xX)) stHitPoint.xX = p_stGV->stDinST0MaxPoint.xX; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MinPoint.xX)) stHitPoint.xX = p_stGV->stDinST0MinPoint.xX; else { stHitPoint.xX = p_stGV->p_stStaticCenter->xX; xIndex ++; } if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MaxPoint.xY)) stHitPoint.xY = p_stGV->stDinST0MaxPoint.xY; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MinPoint.xY)) stHitPoint.xY = p_stGV->stDinST0MinPoint.xY; else { stHitPoint.xY = p_stGV->p_stStaticCenter->xY; xIndex ++; } if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MaxPoint.xZ)) stHitPoint.xZ = p_stGV->stDinST0MaxPoint.xZ; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MinPoint.xZ)) stHitPoint.xZ = p_stGV->stDinST0MinPoint.xZ; else { stHitPoint.xZ = p_stGV->p_stStaticCenter->xZ; xIndex ++; } MTH3D_M_vCopyVector(&stPointBox, &stHitPoint); if(xIndex==3) { /* There, we are in the case where the center of the sphere is inside the box We have to find the point of the box that is the closest from the center */ /* In that case, the hit point is the center of the sphere */ a6_Distance[0]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xX, p_stGV->p_stStaticCenter->xX); xIndexClosest = 0; a6_Distance[1]= MTH_M_xSub(p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MinPoint.xX); if(MTH_M_bLess(a6_Distance[1], a6_Distance[xIndexClosest])) xIndexClosest = 1; a6_Distance[2]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xY, p_stGV->p_stStaticCenter->xY); if(MTH_M_bLess(a6_Distance[2], a6_Distance[xIndexClosest])) xIndexClosest = 2; a6_Distance[3]= MTH_M_xSub(p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MinPoint.xY); if(MTH_M_bLess(a6_Distance[3], a6_Distance[xIndexClosest])) xIndexClosest = 3; a6_Distance[4]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xZ, p_stGV->p_stStaticCenter->xZ); if(MTH_M_bLess(a6_Distance[4], a6_Distance[xIndexClosest])) xIndexClosest = 4; a6_Distance[5]= MTH_M_xSub(p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MinPoint.xZ); if(MTH_M_bLess(a6_Distance[5], a6_Distance[xIndexClosest])) xIndexClosest = 5; switch(xIndexClosest) { case 0: stPointBox.xX = p_stGV->stDinST0MaxPoint.xX; break; case 1: stPointBox.xX = p_stGV->stDinST0MinPoint.xX; break; case 2: stPointBox.xY = p_stGV->stDinST0MaxPoint.xY; break; case 3: stPointBox.xY = p_stGV->stDinST0MinPoint.xY; break; case 4: stPointBox.xZ = p_stGV->stDinST0MaxPoint.xZ; break; case 5: stPointBox.xZ = p_stGV->stDinST0MinPoint.xZ; break; } /* We compute the vector (Center of the sphere) -> (Hit point) */ MTH3D_M_vSubVector(&stVectCenterHit, &stPointBox, p_stGV->p_stStaticCenter); /* We normalize this vector */ MTH3D_M_vNormalizeVector(&stNormal, &stVectCenterHit); xTrans = MTH_M_xAdd( p_stGV->p_stStaticIndexedSphere->xRadius, MTH3D_M_xDotProductVector(&stNormal, &stVectCenterHit) ); MTH3D_M_vMulScalarVector (&stTrans , xTrans , &stNormal); /* We want this vector but in the opposite direction */ /* because we are out of the box */ MTH3D_M_vNegVector (&stTrans, &stTrans); } else /* there, xindex!=3 */ { /* We compute the vector (Center of the sphere) -> (Hit point) */ MTH3D_M_vSubVector(&stVectCenterHit, &stPointBox, p_stGV->p_stStaticCenter); /* We normalize this vector */ MTH3D_M_vNormalizeVector(&stNormal, &stVectCenterHit); xTrans = MTH_M_xSub( p_stGV->p_stStaticIndexedSphere->xRadius, MTH3D_M_xDotProductVector(&stNormal, &stVectCenterHit) ); MTH3D_M_vMulScalarVector (&stTrans , xTrans , &stNormal); } /* We have to find the movement vector of the hit point */ /* The following line is a test ...*/ MTH3D_M_vCopyVector(&stMovementVector, &p_stGV->a8_stDinST01Vect[0]); /* The vector we have is from the final to the initial position, we want the opposite */ MTH3D_M_vNegVector (&stMovementVector, &stMovementVector) /* We compute the differents points in the GLOBAL axis system */ POS_fn_vMulMatrixVertex (&stHitPoint , p_stGV->p_stStaticGeomObjMatrix , &stHitPoint); POS_fn_vMulMatrixVector (&stNormal , p_stGV->p_stStaticGeomObjMatrix , &stNormal); POS_fn_vMulMatrixVector (&stTrans , p_stGV->p_stStaticGeomObjMatrix , &stTrans); POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); /* We register the collision with Time = -1 to precise that there was already collision at the very beginning */ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , &stTrans , &stHitPoint , &stNormal, p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xAlignedBoxEntity , COL_C_xSphereEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2, &stMovementVector,MTH_C_ZERO/*???*/, & stEndPosition); } else { /* There, we have NOT collision at the INITIAL position */ /* We call the dynamic collision */ MTH_tdxReal xT; MTH_tdxReal xFirstT = 1.0; MTH3D_tdstVector stMovementVector; ACP_tdxIndex xVertexIndex; ACP_tdxBool bColDyn; MTH3D_tdstVector stFirstNormal; MTH3D_tdstVector stFirstHitPoint; MTH3D_tdstVector stFirstMovementVector; bColDyn = FALSE; for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) { MTH3D_M_vNegVector (&stMovementVector, &p_stGV->a8_stDinST01Vect[xVertexIndex]); if (INT_fn_bIntersectSegmentWithSphere ( &(p_stGV->a8_stDinST18VBox[xVertexIndex]), &stMovementVector, p_stGV->p_stStaticCenter, p_stGV->p_stStaticIndexedSphere->xRadius, &xT,&stHitPoint,&stNormal )) { if(xTp_stStaticGeomObjMatrix, &stHitPoint ); /* We compute the movement vector */ POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); /* The Tralation vector is not used by DNM in that particular case */ MTH3D_M_vNullVector (& stTrans); /* We compute the collision normal from the local to the global axis system */ POS_fn_vMulMatrixVector ( &stNormal, p_stGV->p_stStaticGeomObjMatrix, &stNormal ); /* Those points will have to be added into the collision table */ MTH3D_M_vCopyVector(&stFirstNormal, &stNormal); MTH3D_M_vCopyVector(&stFirstMovementVector, &stMovementVector); MTH3D_M_vCopyVector(&stFirstHitPoint, &stHitPoint); /* We have found a dynamic collision */ bColDyn = TRUE; } } } if(bColDyn) COL_fn_vAddInStaticCollisionTable (xFirstT, &stTrans, & stFirstHitPoint, &stFirstNormal, p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial, COL_C_xAlignedBoxEntity, COL_C_xTriangleEntity, p_stGV->p_vParameter1, p_stGV->sParameter2, &stFirstMovementVector,MTH_C_ZERO/*???*/, & stEndPosition); else { /* The hit point */ xIndex = 0; if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MaxPoint.xX)) stHitPoint.xX = p_stGV->stDinST0MaxPoint.xX; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MinPoint.xX)) stHitPoint.xX = p_stGV->stDinST0MinPoint.xX; else { stHitPoint.xX = p_stGV->p_stStaticCenter->xX; xIndex ++; } if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MaxPoint.xY)) stHitPoint.xY = p_stGV->stDinST0MaxPoint.xY; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MinPoint.xY)) stHitPoint.xY = p_stGV->stDinST0MinPoint.xY; else { stHitPoint.xY = p_stGV->p_stStaticCenter->xY; xIndex ++; } if(MTH_M_bGreater( p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MaxPoint.xZ)) stHitPoint.xZ = p_stGV->stDinST0MaxPoint.xZ; else if (MTH_M_bLess( p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MinPoint.xZ)) stHitPoint.xZ = p_stGV->stDinST0MinPoint.xZ; else { stHitPoint.xZ = p_stGV->p_stStaticCenter->xZ; xIndex ++; } MTH3D_M_vCopyVector(&stPointBox, &stHitPoint); if(xIndex==3) { /* There, we are in the case where the center of the sphere is inside the box We have to find the point of the box that is the closest from the center */ /* In that case, the hit point is the center of the sphere */ a6_Distance[0]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xX, p_stGV->p_stStaticCenter->xX); xIndexClosest = 0; a6_Distance[1]= MTH_M_xSub(p_stGV->p_stStaticCenter->xX, p_stGV->stDinST0MinPoint.xX); if(MTH_M_bLess(a6_Distance[1], a6_Distance[xIndexClosest])) xIndexClosest = 1; a6_Distance[2]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xY, p_stGV->p_stStaticCenter->xY); if(MTH_M_bLess(a6_Distance[2], a6_Distance[xIndexClosest])) xIndexClosest = 2; a6_Distance[3]= MTH_M_xSub(p_stGV->p_stStaticCenter->xY, p_stGV->stDinST0MinPoint.xY); if(MTH_M_bLess(a6_Distance[3], a6_Distance[xIndexClosest])) xIndexClosest = 3; a6_Distance[4]= MTH_M_xSub(p_stGV->stDinST0MaxPoint.xZ, p_stGV->p_stStaticCenter->xZ); if(MTH_M_bLess(a6_Distance[4], a6_Distance[xIndexClosest])) xIndexClosest = 4; a6_Distance[5]= MTH_M_xSub(p_stGV->p_stStaticCenter->xZ, p_stGV->stDinST0MinPoint.xZ); if(MTH_M_bLess(a6_Distance[5], a6_Distance[xIndexClosest])) xIndexClosest = 5; switch(xIndexClosest) { case 0: stPointBox.xX = p_stGV->stDinST0MaxPoint.xX; break; case 1: stPointBox.xX = p_stGV->stDinST0MinPoint.xX; break; case 2: stPointBox.xY = p_stGV->stDinST0MaxPoint.xY; break; case 3: stPointBox.xY = p_stGV->stDinST0MinPoint.xY; break; case 4: stPointBox.xZ = p_stGV->stDinST0MaxPoint.xZ; break; case 5: stPointBox.xZ = p_stGV->stDinST0MinPoint.xZ; break; } /* We compute the vector (Center of the sphere) -> (Hit point) */ MTH3D_M_vSubVector(&stVectCenterHit, &stPointBox, p_stGV->p_stStaticCenter); /* We normalize this vector */ MTH3D_M_vNormalizeVector(&stNormal, &stVectCenterHit); xTrans = MTH_M_xAdd( p_stGV->p_stStaticIndexedSphere->xRadius, MTH3D_M_xDotProductVector(&stNormal, &stVectCenterHit)); MTH3D_M_vMulScalarVector (&stTrans , xTrans , &stNormal); /* We want this vector but in the opposite direction */ /* because we are out of the box */ MTH3D_M_vNegVector (&stTrans, &stTrans); } else /* there xIndex != 3, the center is out of the box*/ { /* We compute the vector (Center of the sphere) -> (Hit point) */ MTH3D_M_vSubVector(&stVectCenterHit, &stPointBox, p_stGV->p_stStaticCenter); /* We normalize this vector */ MTH3D_M_vNormalizeVector(&stNormal, &stVectCenterHit); xTrans = MTH_M_xSub( p_stGV->p_stStaticIndexedSphere->xRadius, MTH3D_M_xDotProductVector(&stNormal, &stVectCenterHit)); MTH3D_M_vMulScalarVector (&stTrans , xTrans , &stNormal); } /* We have to find the movement vector of the hit point */ /* The following line is a test ...*/ MTH3D_M_vCopyVector(&stMovementVector, &p_stGV->a8_stDinST01Vect[0]); /* The vector we have is from the final to the initial position, we want the opposite */ MTH3D_M_vNegVector (&stMovementVector, &stMovementVector); /* We compute the differents points in the GLOBAL axis system */ POS_fn_vMulMatrixVertex (&stHitPoint , p_stGV->p_stStaticGeomObjMatrix , &stHitPoint); POS_fn_vMulMatrixVector (&stNormal , p_stGV->p_stStaticGeomObjMatrix , &stNormal); POS_fn_vMulMatrixVector (&stTrans , p_stGV->p_stStaticGeomObjMatrix , &stTrans); POS_fn_vMulMatrixVector ( &stMovementVector, p_stGV->p_stStaticGeomObjMatrix, &stMovementVector ); /* We register the collision with Time = -1 to precise that there was already collision at the very beginning */ COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , &stTrans , &stHitPoint , &stNormal, p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial , COL_C_xAlignedBoxEntity , COL_C_xSphereEntity , p_stGV->p_vParameter1 , p_stGV-> sParameter2, &stMovementVector,MTH_C_ZERO/*???*/, & stEndPosition); } } } } /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementSpheres*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementSpheres (COL_tdstGVForCollision *p_stGV) { ACP_tdxIndex xVertexIndex; MTH3D_tdstVector stCenterPoint; MTH3D_tdstVector stPointinS; MTH_tdxReal xHalfEdge; MTH_tdxReal yHalfEdge; MTH_tdxReal zHalfEdge; for ( p_stGV->xDynamicIndexedAlignedBoxIndex = 0 ; p_stGV->xDynamicIndexedAlignedBoxIndex < p_stGV->p_stDynamicElementAlignedBoxes->xNbAlignedBoxes ; p_stGV->xDynamicIndexedAlignedBoxIndex++ ) { /* Several infos about the box */ p_stGV->p_stDynamicIndexedAlignedBox = p_stGV->p_stDynamicElementAlignedBoxes->d_stListOfAlignedBoxes + p_stGV->xDynamicIndexedAlignedBoxIndex; p_stGV->p_stDynamicMinPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMinPoint; p_stGV->p_stDynamicMaxPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMaxPoint; /* We compute the "center" point of the box */ MTH3D_M_vMiddleVector(&stCenterPoint, p_stGV->p_stDynamicMinPoint, p_stGV->p_stDynamicMaxPoint); xHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xX, stCenterPoint.xX); yHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xY, stCenterPoint.xY); zHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xZ, stCenterPoint.xZ); /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the FINAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT0DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the FINAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points in that system */ /* but first we have to compute the size of the box in the static axis system (scale) */ xHalfEdge = MTH_M_xDiv ( xHalfEdge, p_stGV->xStaticScale ); yHalfEdge = MTH_M_xDiv ( yHalfEdge, p_stGV->xStaticScale ); zHalfEdge = MTH_M_xDiv ( zHalfEdge, p_stGV->xStaticScale ); p_stGV->stDinST0MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST0MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the FINAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST08VBox, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint ); /*-------------------------------------------------------------------------------------------*/ /* THE FOLLOWING LINES ARE IDENTICAL TO THE PREVIOUS ONES BUT DEAL WITH THE INITIAL POSITION */ /*-------------------------------------------------------------------------------------------*/ /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the INITIAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT1DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the INITIAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points */ p_stGV->stDinST1MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST1MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the INITIAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST18VBox, &p_stGV->stDinST1MinPoint, &p_stGV->stDinST1MaxPoint ); /* We also need the 8 "translation" vertices */ /* (Final position) Vertice i -> Vertice i (Initial Position) */ for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) MTH3D_M_vSubVector ( &(p_stGV->a8_stDinST01Vect[xVertexIndex]), &(p_stGV->a8_stDinST18VBox[xVertexIndex]), &(p_stGV->a8_stDinST08VBox[xVertexIndex]) ); for ( p_stGV->xStaticIndexedSphereIndex = 0 ; p_stGV->xStaticIndexedSphereIndex < p_stGV->p_stStaticElementSpheres->xNbSpheres ; p_stGV->xStaticIndexedSphereIndex++ ) { p_stGV->p_stStaticIndexedSphere = p_stGV->p_stStaticElementSpheres->d_stListOfSpheres + p_stGV->xStaticIndexedSphereIndex; p_stGV->hDynamicMaterial = p_stGV->p_stDynamicIndexedAlignedBox->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticIndexedSphere->hMaterial; COL_fn_vCollideStaticAlignedBoxWithStaticSphere ( p_stGV ); } } } /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticElementSpheresWithStaticOctree*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticElementAlignedBoxesWithStaticOctree (COL_tdstGVForCollision *p_stGV) { ACP_tdxIndex xVertexIndex; COL_tdxFaceIndex *p_xListIndex; ACP_tdxIndex xNodeIndex; COL_tdxFaceIndex xIndex; ACP_tdxIndex xDataElementIndex; MTH_tdxReal xHalfEdge; MTH_tdxReal yHalfEdge; MTH_tdxReal zHalfEdge; /* MTH_tdxReal xT;*/ MTH3D_tdstVector stCenterPoint; MTH3D_tdstVector stPointinS; /* MTH3D_tdstVector stNormal;*/ /* MTH3D_tdstVector stHitPoint;*/ /* MTH3D_tdstVector stTrans;*/ /* MTH3D_tdstVector stMovementVector;*/ ACP_tdxIndex xNbElements; for ( p_stGV->xDynamicIndexedAlignedBoxIndex = 0 ; p_stGV->xDynamicIndexedAlignedBoxIndex < p_stGV->p_stDynamicElementAlignedBoxes->xNbAlignedBoxes ; p_stGV->xDynamicIndexedAlignedBoxIndex++ ) { /* Infos about the box */ p_stGV->p_stDynamicIndexedAlignedBox = p_stGV->p_stDynamicElementAlignedBoxes->d_stListOfAlignedBoxes + p_stGV->xDynamicIndexedAlignedBoxIndex; p_stGV->p_stDynamicMinPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMinPoint; p_stGV->p_stDynamicMaxPoint = p_stGV->p_stDynamicGeomObj->d_stListOfPoints + p_stGV->p_stDynamicIndexedAlignedBox->xMaxPoint; /* Center point of the box */ MTH3D_M_vMiddleVector(&stCenterPoint, p_stGV->p_stDynamicMinPoint, p_stGV->p_stDynamicMaxPoint); xHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xX, stCenterPoint.xX); yHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xY, stCenterPoint.xY); zHalfEdge = MTH_M_xSub(p_stGV->p_stDynamicMaxPoint->xZ, stCenterPoint.xZ); /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the FINAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT0DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the FINAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points in that system */ /* but first we have to compute the size of the box in the static axis system (scale) */ xHalfEdge = MTH_M_xDiv ( xHalfEdge, p_stGV->xStaticScale ); yHalfEdge = MTH_M_xDiv ( yHalfEdge, p_stGV->xStaticScale ); zHalfEdge = MTH_M_xDiv ( zHalfEdge, p_stGV->xStaticScale ); p_stGV->stDinST0MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST0MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST0MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST0MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the FINAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST08VBox, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint ); /*-------------------------------------------------------------------------------------------*/ /* THE FOLLOWING LINES ARE IDENTICAL TO THE PREVIOUS ONES BUT DEAL WITH THE INITIAL POSITION */ /*-------------------------------------------------------------------------------------------*/ /* The box is oriented according to the global world axis system but WITHOUT the translation of the object ...*/ /* We add the translation of the object to obtain the coordinates of the center of the box at the INITIAL position in the global axis system */ MTH3D_M_vAddVector (&stPointinS, &stCenterPoint, &p_stGV->p_stT1DynamicGeomObjMatrix->stTranslationVector); /* Now, we want to obtain the coordinates of the center at the INITIAL position in the static object axis system */ if(p_stGV->bStaticGeomObjHasNoTransformationMatrix) { MTH3D_M_vSubVector (&stPointinS, &stPointinS, &p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); } else { POS_fn_vMulMatrixVertex (&stPointinS, &p_stGV->stInvMatrix, &stPointinS); } /* We compute the min/max points */ /* but first we have to compute the size of the box in the static axis system (scale) */ xHalfEdge = MTH_M_xDiv ( xHalfEdge, p_stGV->xStaticScale ); yHalfEdge = MTH_M_xDiv ( yHalfEdge, p_stGV->xStaticScale ); zHalfEdge = MTH_M_xDiv ( zHalfEdge, p_stGV->xStaticScale ); p_stGV->stDinST1MaxPoint.xX = MTH_M_xAdd(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MinPoint.xX = MTH_M_xSub(stPointinS.xX, xHalfEdge); p_stGV->stDinST1MaxPoint.xY = MTH_M_xAdd(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MinPoint.xY = MTH_M_xSub(stPointinS.xY, yHalfEdge); p_stGV->stDinST1MaxPoint.xZ = MTH_M_xAdd(stPointinS.xZ, zHalfEdge); p_stGV->stDinST1MinPoint.xZ = MTH_M_xSub(stPointinS.xZ, zHalfEdge); /* We find the 8 box vertices describing the box with the max/min points */ /* Those vertices are computed in the static object local axis system */ /* and represent the position of the box at the INITIAL position */ COL_fn_vMinMaxBox2VerticesBox ( p_stGV->a8_stDinST18VBox, &p_stGV->stDinST1MinPoint, &p_stGV->stDinST1MaxPoint ); /* We also need the 8 "translation" vertices */ /* (Final position) Vertice i -> Vertice i (Initial Position) */ for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ ) MTH3D_M_vSubVector ( &(p_stGV->a8_stDinST01Vect[xVertexIndex]), &(p_stGV->a8_stDinST18VBox[xVertexIndex]), &(p_stGV->a8_stDinST08VBox[xVertexIndex]) ); COL_fn_vExploreOctreeWithBox ( p_stGV->p_stOctree, &p_stGV->stDinST0MinPoint, &p_stGV->stDinST0MaxPoint, p_stGV->aDEF_pstSelectedNode, &p_stGV->xNumberOfSelectedNodes ); COL_g_lFacesTagCounter ++; for ( xNodeIndex = 0 ; xNodeIndex < p_stGV->xNumberOfSelectedNodes ; xNodeIndex++ ) { 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; } 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_ulDynamicBoxWithStaticITr ) { 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_stDynamicIndexedAlignedBox->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticElementIndexedTriangles->hMaterial; COL_fn_vCollideStaticAlignedBoxWithStaticIndexedTriangle (p_stGV, FALSE); } break; case GEO_C_xElementSpheres : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticSph ) { 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_stDynamicIndexedAlignedBox->hMaterial; p_stGV->hStaticMaterial = p_stGV->p_stStaticIndexedSphere->hMaterial; COL_fn_vCollideStaticAlignedBoxWithStaticSphere ( p_stGV ); } break; default : break; } COL_g_d_lTaggedFacesTable[p_stGV->p_stOctree->d_xElementBasesTable[p_stGV->xStaticElementIndex] + xDataElementIndex] = COL_g_lFacesTagCounter; } } } } } /*--------------------------------------------------------------------------------------*/ /* Name : COL_fn_vCollideStaticElementAlignedBoxesWithStaticElements*/ /* Author : Thierry QUERE*/ /* Date : 04/03/98*/ /* Description : */ /*--------------------------------------------------------------------------------------*/ /* used*/ void COL_fn_vCollideStaticElementAlignedBoxesWithStaticElements (COL_tdstGVForCollision *p_stGV) { PRF_fn_vSetIndependantVariable( PRF_C_ulIdpCollComputed, 1 ); if ( p_stGV->p_stOctree == NULL ) { for ( p_stGV->xStaticElementIndex = 0 ; p_stGV->xStaticElementIndex < p_stGV->p_stStaticGeomObj->xNbElements ; p_stGV->xStaticElementIndex++ ) { switch ( p_stGV->p_stStaticGeomObj->d_xListOfElementsTypes[p_stGV->xStaticElementIndex] ) { case GEO_C_xElementIndexedTriangles : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticITr ) { p_stGV->p_stStaticElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementIndexedTriangles ( p_stGV ); } break; case GEO_C_xElementSpheres : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticSph ) { p_stGV->p_stStaticElementSpheres = (GEO_tdstElementSpheres *)(p_stGV->p_stStaticGeomObj->d_stListOfElements[p_stGV->xStaticElementIndex]); COL_fn_vCollideStaticElementAlignedBoxesWithStaticElementSpheres ( p_stGV ); } break; default : break; } } } else { if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticElt ) { COL_fn_vCollideStaticElementAlignedBoxesWithStaticOctree ( p_stGV ); } } } #endif /* USE_ZDM_BOX*/