reman3/Rayman_X/cpa/tempgrp/COL/CollGO.c

462 lines
22 KiB
C
Raw Blame History

/*
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--------------------------------------------------------------------------------
-- Description : Geometric object collision part
--------------------------------------------------------------------------------
-- Creation date : 15 may 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#include "acp_base.h"
#include "MTH.h"
#include "GMT.h"
#include "GEO.h"
#include "GLI.h"
#include "PCS.h"
#define PO_FRIEND
#include "PO.h"
#define HieFriend
#include "SPO.h"
#include "MEC.h"
#include "COL/CollGO.h"
/*
--------------------------------------------------------------------------------
-- Description : Static with static geometric objects collision detection test
--------------------------------------------------------------------------------
-- Creation date : March 3, 1998 Author : Alexis Vaisse
--------------------------------------------------------------------------------
*/
/* Collision detection test between two static geometric objects */
/* used*/
ACP_tdxBool COL_fn_bDetectCollisionStaticGeomObjWithStaticGeomObj ( GEO_tdxHandleToBoundingSphere _hDynamicGeometricObject, /* Always a sphere*/
POS_tdstCompletePosition *_p_stDynamicGeometricObjectMatrix,
void *_hStaticGeometricObject, /* Either a Box or a sphere ...*/
POS_tdstCompletePosition *_p_stStaticGeometricObjectMatrix,
ACP_tdxBool _bStaticGeomObjHasNoTransformationMatrix,
ACP_tdxBool _bDynamicGeomObjHasZoomInsteadOfScale,
ACP_tdxBool _bHasABoxBoundingVolume)
{
MTH3D_tdstVector stDinGPoint; /* Coordinates of the center of the dynamic bounding volume in the global axis*/
MTH3D_tdstVector stSinGPoint; /* Coordinates of the center of the static bounding volume in the global axis*/
MTH3D_tdstVector * p_stSMaxBoxPoint;
MTH3D_tdstVector * p_stSMinBoxPoint;
MTH3D_tdstVector stMaxDinGPoint;
MTH3D_tdstVector stMinDinGPoint;
MTH3D_tdstVector stMaxSinGPoint;
MTH3D_tdstVector stMinSinGPoint;
MTH_tdxReal xRadiusSum;
MTH_tdxReal xRadiusDinG;
/* on se place dans global */
/* transformation de CDT0 dans global */
POS_fn_vMulMatrixVertex(&stDinGPoint, _p_stDynamicGeometricObjectMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hDynamicGeometricObject));
if(!_bHasABoxBoundingVolume)
/*The Bounding Volume of the Static Geo.Object is a SPHERE ...*/
{
/* transformation de CS dans global */
if (_bStaticGeomObjHasNoTransformationMatrix) /* No transformation matrix -> only a translation*/
{
MTH3D_M_vAddVector (& stSinGPoint, GEO_fn_pGetCenterPointOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject), & _p_stStaticGeometricObjectMatrix -> stTranslationVector);
}
else
{
POS_fn_vMulMatrixVertex ( &stSinGPoint, _p_stStaticGeometricObjectMatrix, GEO_fn_pGetCenterPointOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject));
}
xRadiusSum = MTH_M_xAdd (
/* Radius of the dynamic sphere*/
MTH_M_xMul ((GEO_fn_xGetRadiusOfBoundingSphere(_hDynamicGeometricObject)), POS_fn_xGetMaxScale ( _p_stDynamicGeometricObjectMatrix )),
/* Plus radius of the static sphere*/
_bStaticGeomObjHasNoTransformationMatrix ?
GEO_fn_xGetRadiusOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject)
: MTH_M_xMul ( GEO_fn_xGetRadiusOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject), POS_fn_xGetMaxScale ( _p_stStaticGeometricObjectMatrix )) );
/* The distance between the two centers must be less that the sum of the two radius*/
return MTH_M_bLessEqual (MTH3D_M_xVectorGapSqr (& stDinGPoint , & stSinGPoint) , MTH_M_xSqr (xRadiusSum));
}
else
/*The Bounding Volume of the Static Geom. Object is a BOX*/
{
/* The static parallel box in the local axis*/
p_stSMaxBoxPoint = GEO_fn_pGetMaxPointOfParallelBox((GEO_tdxHandleToParallelBox)_hStaticGeometricObject);
p_stSMinBoxPoint = GEO_fn_pGetMinPointOfParallelBox((GEO_tdxHandleToParallelBox)_hStaticGeometricObject);
/* The static parallel box in the global axis*/
MTH3D_M_vAddVector(& stMaxSinGPoint , & _p_stStaticGeometricObjectMatrix->stTranslationVector , p_stSMaxBoxPoint);
MTH3D_M_vAddVector(& stMinSinGPoint , & _p_stStaticGeometricObjectMatrix->stTranslationVector , p_stSMinBoxPoint);
/* We compute the parallel box that includes the sphere bounding volume*/
xRadiusDinG = MTH_M_xMul ((GEO_fn_xGetRadiusOfBoundingSphere(_hDynamicGeometricObject)), POS_fn_xGetMaxScale ( _p_stDynamicGeometricObjectMatrix ));
/* The dynamic parallel box in the global axis*/
COL_fn_vComputeBoundingBoxOfSphere (& stMinDinGPoint , & stMaxDinGPoint , & stDinGPoint , xRadiusDinG);
return COL_fn_bDetectCollisionBetweenTwoParallelBoxes (&stMaxSinGPoint, &stMinSinGPoint, &stMaxDinGPoint, &stMinDinGPoint);
}
}
/*
--------------------------------------------------------------------------------
-- Description : Static with static geometric objects collision test init
--------------------------------------------------------------------------------
-- Creation date : 15 may 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* init de collision entre deux objets geometriques */
/* used*/
void COL_fn_vInitCollideStaticGeomObjWithStaticGeomObj ( COL_tdstGVForCollision *p_stGV )
{
/* jt 070699 */
/* MTH3D_tdstVector stNegVector; */
/* end jt 070699 */
/* init des matrices*/
POS_fn_vSetIdentityMatrix ( &p_stGV->stInvMatrix );
POS_fn_vSetIdentityMatrix ( &p_stGV->stD2ST0TransformMatrix );
POS_fn_vSetIdentityMatrix ( &p_stGV->stD2ST1TransformMatrix );
POS_fn_vSetIdentityMatrix ( &p_stGV->stS2DT0TransformMatrix );
POS_fn_vSetIdentityMatrix ( &p_stGV->stS2DT1TransformMatrix );
/* calcul des deux matrices de transformation */
/* inversion de la matrice statique */
/* jt 070699 */
/* Faut quand m<>me pas trop exag<61>rer! On en fait quoi de la rotation ? */
/* if (p_stGV->bStaticGeomObjHasNoTransformationMatrix) */
/* { */ /* No transformation matrix -> the invert matrix is the identity matrix with the opposite translation vector*/
/* MTH3D_M_vNegVector (& stNegVector , & p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); */
/* POS_fn_vSetTranslationVector (& p_stGV->stInvMatrix , & stNegVector); */
/* } */
/* else */
/* { */
POS_fn_vInvertMatrix( &p_stGV->stInvMatrix, p_stGV->p_stStaticGeomObjMatrix );
/* } */
/* end jt 070699 */
/* calcul de la matrice de passage entre dynamique et statique a T0 */
POS_fn_vMulMatrixMatrix( &p_stGV->stD2ST0TransformMatrix, &p_stGV->stInvMatrix, p_stGV->p_stT0DynamicGeomObjMatrix );
/* We need the T1 point*/
/* Maybe one could compute them only when the first collision is detected (???)*/
/* calcul de la matrice de passage entre dynamique et statique a T1 */
POS_fn_vMulMatrixMatrix( &p_stGV->stD2ST1TransformMatrix, &p_stGV->stInvMatrix, p_stGV->p_stT1DynamicGeomObjMatrix );
/* optimisation sur la surface */
p_stGV->bSurfacicDynamicElement = COL_fn_bGetSurfaceInGeometricObject ( p_stGV->p_stDynamicGeomObj );
/* suppression des cas inutiles */
if ( !p_stGV->bSurfacicDynamicElement )
{
p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticPts );
p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEdgWithStaticEdg );
p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEdgWithStaticElt );
p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticEdg );
p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticElt );
}
/* optimisation transformation des points statiques */
p_stGV->bDynamicSphereAndPointOnly = COL_fn_bGetSphereAndPointOnlyInGeometricObject ( p_stGV->p_stDynamicGeomObj );
p_stGV->p_stOctree = p_stGV->p_stStaticGeomObj->p_stOctree;
if ( p_stGV->p_stOctree != NULL )
{
p_stGV->xNbStaticPoints = 0;
p_stGV->xNbStaticEdges = 0;
}
if (p_stGV->bStaticGeomObjHasNoTransformationMatrix)
{
p_stGV->xStaticScale = 1;
}
else
{
p_stGV->xStaticScale = POS_fn_xGetMaxScale ( p_stGV->p_stStaticGeomObjMatrix );
}
}
/*
--------------------------------------------------------------------------------
-- Description : Static with static geometric objects collision test
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* test de collision entre deux objets geometriques */
/* used*/
void COL_fn_vComputeCollisionStaticGeomObjWithStaticGeomObj ( COL_tdstGVForCollision *p_stGV )
{
/* init */
COL_fn_vInitCollideStaticGeomObjWithStaticGeomObj ( p_stGV );
/* elements de dynamique contre elements de statique */
if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicEltWithStaticElt )
{
for ( p_stGV->xDynamicElementIndex = 0 ; p_stGV->xDynamicElementIndex < p_stGV->p_stDynamicGeomObj->xNbElements ; p_stGV->xDynamicElementIndex++ )
{
switch ( p_stGV->p_stDynamicGeomObj->d_xListOfElementsTypes[p_stGV->xDynamicElementIndex] )
{
case GEO_C_xElementSpheres :
if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticElt )
{
p_stGV->p_stDynamicElementSpheres = (GEO_tdstElementSpheres *)(p_stGV->p_stDynamicGeomObj->d_stListOfElements[p_stGV->xDynamicElementIndex]);
/* th element always exists, but can have no sphere*/
if ( p_stGV->p_stDynamicElementSpheres->xNbSpheres )
COL_fn_vCollideStaticElementSpheresWithStaticElements ( p_stGV );
}
break;
#ifdef USE_ZDM_BOX
case GEO_C_xElementAlignedBoxes :
if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticElt )
{
p_stGV->p_stDynamicElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGV->p_stDynamicGeomObj->d_stListOfElements[p_stGV->xDynamicElementIndex]);
/* th element always exists, but can have no box*/
if ( p_stGV->p_stDynamicElementAlignedBoxes->xNbAlignedBoxes )
COL_fn_vCollideStaticElementAlignedBoxesWithStaticElements ( p_stGV );
}
break;
#endif
}
}
}
}
/*
--------------------------------------------------------------------------------
-- Description : Static with static geometric objects collision test
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* test de collision entre deux objets geometriques */
/* used*/
void COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2 ( ACP_tdxHandleOfObject _hGeometricObject1,
POS_tdstCompletePosition *_p_stGeometricObjectStartMatrix1,
POS_tdstCompletePosition *_p_stGeometricObjectEndMatrix1,
ACP_tdxHandleOfObject _hGeometricObject2,
POS_tdstCompletePosition *_p_stGeometricObjectMatrix2,
void * _p_vParameter1 ,
short _sParameter2 ,
ACP_tdxBool _bStaticGeomObjHasNoTransformationMatrix,
ACP_tdxBool _bDynamicGeomObjHasZoomInsteadOfScale)
{
/* init des parametres du test */
COL_g_stGVForCol.bStaticGeomObjHasNoTransformationMatrix = _bStaticGeomObjHasNoTransformationMatrix;
COL_g_stGVForCol.bDynamicGeomObjHasZoomInsteadOfScale = _bDynamicGeomObjHasZoomInsteadOfScale;
COL_g_stGVForCol.p_stDynamicGeomObj = _hGeometricObject1;
COL_g_stGVForCol.p_stT0DynamicGeomObjMatrix = _p_stGeometricObjectEndMatrix1; /* The matrix that will be used for calculation*/
COL_g_stGVForCol.p_stT1DynamicGeomObjMatrix = _p_stGeometricObjectStartMatrix1; /* This matrix will only be used when a collision is detected*/
COL_g_stGVForCol.p_stStaticGeomObj = _hGeometricObject2;
COL_g_stGVForCol.p_stStaticGeomObjMatrix = _p_stGeometricObjectMatrix2;
COL_g_stGVForCol.ulSelectedCollisionCases = COL_C_ulDynamicAllWithStaticAll;
COL_g_stGVForCol.p_vParameter1 = _p_vParameter1;
COL_g_stGVForCol.sParameter2 = _sParameter2;
/* cas de rejection immediate */
if (_hGeometricObject1 == NULL ||
_hGeometricObject2 == NULL ||
_hGeometricObject1->xNbPoints == 0 ||
_hGeometricObject2->xNbPoints == 0 ||
_hGeometricObject1->xNbElements == 0 ||
_hGeometricObject2->xNbElements == 0)
{
return;
}
COL_fn_vComputeCollisionStaticGeomObjWithStaticGeomObj ( &COL_g_stGVForCol );
}
/*--------------------------------------------------------------------------------*/
/* COL_fn_lFindNormalFromGeometricObject*/
/**/
/* This function finds the triangles of the geometric object containing the given point (on an edge),*/
/* fill an array with the normals of these triangles (two triangles maximum)*/
/* and return the number of triangles found*/
/*--------------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
/*long COL_fn_lFindNormalFromGeometricObject (GEO_tdstGeometricObject * _p_stGeometricObject ,
MTH3D_tdstVector * _p_stPoint ,
MTH3D_tdstVector * _p_a2_stNormal)
{
#define C_xEpsilon MTH_M_xFloatToReal ((float) 0.001)
#define C_xLargeEpsilon MTH_M_xFloatToReal ((float) 0.1)
if (_p_stGeometricObject -> p_stOctree)
{
ACP_tdxIndex xResult;
MTH3D_tdstVector stMinPoint , stMaxPoint;
COL_tdpstOctreeNode a_pstSelectedNode [COL_C_xMaxSelectedNodes];
ACP_tdxIndex xNumberOfSelectedNodes;
ACP_tdxIndex xNodeIndex , xFaceIndex;
COL_tdxFaceIndex * p_xListIndex;
ACP_tdxIndex xElementIndex , xDataElementIndex;
GEO_tdstElementIndexedTriangles * p_stElementIndexedTriangles;
// GEO_tdstElementFaceMapDescriptors * p_stElementFaceMapDescriptors;
GEO_tdstTripledIndex * p_st3Idx;
ACP_tdxIndex xNbElements;
xResult = 0;
MTH3D_M_vSubScalarVector (& stMinPoint , C_xEpsilon , _p_stPoint);
MTH3D_M_vAddScalarVector (& stMaxPoint , C_xEpsilon , _p_stPoint);
COL_fn_vExploreOctreeWithBox (_p_stGeometricObject -> p_stOctree , & stMinPoint , & stMaxPoint ,
a_pstSelectedNode , & xNumberOfSelectedNodes);
// For each selected nodes
for (xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
// For the list of faces
//p_xListIndex = a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList;
xNbElements = *((COL_tdxFaceIndexDouble*)a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList)+1);
for (xFaceIndex = 0 ; xFaceIndex < xNbElements ; xFaceIndex ++)
{
#ifndef U64
if ((*p_xListIndex) < COL_C_MaxIndex) xElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++));
else xElementIndex = (ACP_tdxIndex) ((* (((COL_tdxFaceIndexDouble*)p_xListIndex)++)) & ~COL_C_OverflowIndex);
if ((*p_xListIndex) < COL_C_MaxIndex) xDataElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++));
else xDataElementIndex = (ACP_tdxIndex) ((* (((COL_tdxFaceIndexDouble*)p_xListIndex)++)) & ~COL_C_OverflowIndex);
#else //U64
if ((*p_xListIndex) < COL_C_MaxIndex)
xElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++));
else
{
ACP_tdxIndex xData;
xData=(ACP_tdxIndex)(* (p_xListIndex ++));
xData<<=8;
xData+=(ACP_tdxIndex)(* (p_xListIndex ++));
xData&=~COL_C_OverflowIndex;
xElementIndex = 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;
}
#endif //U64
switch (_p_stGeometricObject -> d_xListOfElementsTypes [xElementIndex])
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *) (_p_stGeometricObject -> d_stListOfElements [xElementIndex]);
p_st3Idx = & p_stElementIndexedTriangles -> d_stListOfFacesTripled [xDataElementIndex];
if (INT_fn_bIsOnTriangle (_p_stPoint , _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [0] ,
_p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [1] ,
_p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [2]))
{
MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , p_stElementIndexedTriangles -> d_stListOfFacesNormals + xDataElementIndex);
if (++ xResult == 2) return xResult; // We have found two triangles -> it's finished
}
break;
}
}
}
return xResult;
}
else
{
GEO_tdstElementIndexedTriangles *p_stETIT;
// GEO_tdstElementFaceMapDescriptors *p_stEFMD;
GEO_tdstTripledIndex *p_st3Idx;
// GEO_tdstFaceMapTriangle *p_stFMT;
ACP_tdxIndex xIndexElement , xIndexInElement;
ACP_tdxIndex xResult;
xResult = 0;
for ( xIndexElement = 0 ; xIndexElement < _p_stGeometricObject -> xNbElements ; xIndexElement++ )
{
switch ( _p_stGeometricObject -> d_xListOfElementsTypes[ xIndexElement ] )
{
case GEO_C_xElementIndexedTriangles:
p_stETIT = (GEO_tdstElementIndexedTriangles*) ( _p_stGeometricObject -> d_stListOfElements[ xIndexElement ] );
p_st3Idx = p_stETIT -> d_stListOfFacesTripled;
for ( xIndexInElement = 0 ; xIndexInElement < p_stETIT -> xNbFaces ; xIndexInElement++, p_st3Idx++ )
{
if( INT_fn_bIsOnTriangle( _p_stPoint, _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[0],
_p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[1],
_p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[2] ) )
{
MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , p_stETIT -> d_stListOfFacesNormals + xIndexInElement );
if (++ xResult == 2) return xResult; // We have found two triangles -> it's finished
}
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap :
{
GEO_tdstElementAltimap *p_stElementAltimap;
ACP_tdxIndex xAx, xAy, xBx, xBy, xLoopX, xLoopY, xLoopV, xIndex;
MTH3D_tdstVector stV1, stV2, stV3, stNorm, stP1, stP2;
ACP_tdxBool xBoolA, xBoolB;
MTH3D_M_vSubScalarVector( &stP1, C_xLargeEpsilon, _p_stPoint );
MTH3D_M_vAddScalarVector( &stP2, C_xLargeEpsilon, _p_stPoint );
p_stElementAltimap = (GEO_tdstElementAltimap *)(_p_stGeometricObject->d_stListOfElements[ xIndexElement ]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, &stP1, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, &stP2, &xBx, &xBy );
COL_M_vClipSquareSelection( p_stElementAltimap, xAx, xAy, xBoolA );
COL_M_vClipSquareSelection( p_stElementAltimap, xBx, xBy, xBoolB );
COL_M_vScanSelectedSquares( xLoopX, xLoopY, xLoopV, p_stElementAltimap->xWidth, xAx, xAy, xBx, xBy )
{
unsigned char ucType;
ucType = p_stElementAltimap->d_stSquare[ xLoopV ].ucType;
while( ucType )
{
ucType = COL_ucBuildAltimapSquareTriangle( p_stElementAltimap, xLoopX, xLoopY, ucType,
&stV1, &stV2, &stV3, &stNorm, &xIndex );
if( INT_fn_bIsOnTriangle( _p_stPoint, &stV1, &stV2, &stV3 ) )
{
MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , &stNorm );
if (++ xResult == 2)
return xResult; // We have found two triangles -> it's finished
}
}
}
}
break;
#endif //USE_ALTIMAPS
return xResult;
}
}
}
}
*/
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */