reman3/Rayman_X/cpa/tempgrp/COL/CsBoxElt.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*/