1055 lines
49 KiB
C
1055 lines
49 KiB
C
|
|
/*******************************************************************************/
|
|
/* 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(xT<xFirstT)
|
|
{
|
|
xFirstT = xT;
|
|
/* We compute the Hit point from the static local axis system to the global one */
|
|
POS_fn_vMulMatrixVertex ( &stHitPoint, p_stGV->p_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(xT<xFirstT)
|
|
{
|
|
xFirstT = xT;
|
|
/* We compute the Hit point from the static local axis system to the global one */
|
|
POS_fn_vMulMatrixVertex ( &stHitPoint, p_stGV->p_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*/
|