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

333 lines
12 KiB
C

/*
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--------------------------------------------------------------------------------
-- Description : Geometric object collision part
--------------------------------------------------------------------------------
-- Creation date : 22 aug 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#include "acp_base.h"
#include "MTH.h"
#include "MEC.h"
#include "GMT.h"
#include "GEO.h"
#include "GLI.h"
#include "COL/CollGOCo.h"
/*XB 98/09/11*/
#include "PRF.h"
/*End XB*/
/* ANNECY AV {*/
#define C_wDoubleEdge 2
/* END ANNECY AV }*/
/*
--------------------------------------------------------------------------------
-- Description : Global variables
--------------------------------------------------------------------------------
*/
/* cas de collision */
/* Global Collisiosn Array */
COL_tdstCollisionCase COL_g_stCollisionCase [COL_C_xMaxNumberOfCollisions];
/* Pointer to Beginning of Array to be computed
/* Usually COL_g_stCollisionCaseReal = COL_g_stCollisionCase
/* but it can be usefull to compute collisions in two steps
/* then COL_g_stCollisionCaseReal = COL_g_stCollisionCase + Number of collisions computed in first step */
COL_tdstCollisionCase *COL_g_stCollisionCaseReal = COL_g_stCollisionCase;
COL_tdstGVForCollision COL_g_stGVForCol;
long COL_g_lNbElementsInTable = COL_C_xMaxNumberOfCollisions; /* Number of elements added in Collision Array */
/* size free for collide array
/* usually COL_g_lMaxNumberOfCollisions = COL_C_xMaxNumberOfCollisions
/* but it can be usefull to compute collisions in two steps
/* then COL_g_lMaxNumberOfCollisions = COL_C_xMaxNumberOfCollisions - Number of collisions computed in first step */
extern long COL_g_lMaxNumberOfCollisions;
/*
--------------------------------------------------------------------------------
-- Description : Initialize the collision table
--------------------------------------------------------------------------------
-- Creation date : 23 oct 1996 Author : FPI
--------------------------------------------------------------------------------
*/
//#define COL_fn_vInitCollisionTable() COL_g_lNbElementsInTable = 0
/* init de la table de collision */
/* passer en macro */
//void COL_fn_vInitCollisionTable ( void )
//{
/* Anthony */
/*COL_tdstCollisionCase * p;
COL_tdstCollisionCase * end;*/
/* opti par Yann Le Guyader 07/99 */
//if (COL_g_lNbElementsInTable)
//{
/*end = &COL_g_stCollisionCaseReal[COL_g_lNbElementsInTable];*/
// COL_g_lNbElementsInTable = 0;
//}
/*else return;*/
/*for (p = COL_g_stCollisionCaseReal; p < end ; p ++)
{
/* temps de collision */
//p -> xCollisionTime = MTH_C_2;
//}*/
//}
/*
--------------------------------------------------------------------------------
-- Description : Add a collision case in the collision table
--------------------------------------------------------------------------------
-- Creation date : 06 oct 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* ajout dans la table de collision */
void COL_fn_vAddInStaticCollisionTable (MTH_tdxReal _xT,
MTH3D_tdstVector *_p_stTranslation,
MTH3D_tdstVector *_p_stHit,
MTH3D_tdstVector *_p_stNormal,
GMT_tdxHandleToGameMaterial _hDynMat,
GMT_tdxHandleToGameMaterial _hStatMat,
ACP_tdxIndex _xDynamicGeomEntity,
ACP_tdxIndex _xStaticGeomEntity,
void *_p_vParameter1,
short _sParameter2,
MTH3D_tdstVector *_p_stMovement,
MTH_tdxReal _xSphereRadius,
MTH3D_tdstVector * _p_stEndPosition)
{
#ifdef USE_PROFILER
/*XB 98/09/11*/
static long s_l_MaxNbCollisions=0;
/*End XB*/
#endif /* USE_PROFILER */
long i;
COL_tdstCollisionCase * p_stCollisionCase;
/* jt 120599 */
GMT_tdxHandleToCollideMaterial hCollideMaterial;
/* end jt 120599 */
#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 ) )
/* jt 120599 : no registration if hand type zone hurt something else than a hang material type */
hCollideMaterial = GMT_fn_hGetCollideMaterial (_hDynMat);
/* zone has a collide material with hand type */
if ( (hCollideMaterial!=GMT_C_InvalidCollideMaterial) && (GMT_fn_hGetCollideMaterialIdentifier(hCollideMaterial)&(1<<3)) )
{
/* this is a ground */
hCollideMaterial = GMT_fn_hGetCollideMaterial (_hStatMat);
if ( (hCollideMaterial==GMT_C_InvalidCollideMaterial) || ((GMT_fn_hGetCollideMaterialIdentifier(hCollideMaterial)&4)!=4) )
/* the ground hasn't hand type material */
return;
}
/* end jt 120599 */
if (_xStaticGeomEntity == COL_C_xHighEdgeEntity ||
_xStaticGeomEntity == COL_C_xLowEdgeEntity) /* The function can be called twice for the same edge : we have to detect this*/
{
/* anthony */
/*p_stCollisionCase = COL_g_stCollisionCase;*/
p_stCollisionCase = COL_g_stCollisionCaseReal;
for (i = 0 ; i < COL_g_lNbElementsInTable ; i ++)
{
{
/* If the collision with the edge is already registered, we do nothing*/
if (p_stCollisionCase -> xStaticGeomEntity == _xStaticGeomEntity &&
p_stCollisionCase -> p_vParameter1 == _p_vParameter1 && /* Is it the same super object ?*/
MTH_M_bEqualWithEpsilon (p_stCollisionCase -> xCollisionTime , _xT , 0.001) &&
M_bIsVectorsEqualWithEpsilon (& p_stCollisionCase -> stCollisionPoint , _p_stHit , 0.005) &&
M_bIsVectorsEqualWithEpsilon (& p_stCollisionCase -> stCollisionNormal , _p_stNormal , 0.005))
{
/* Say that the edge is present twice*/
p_stCollisionCase -> sParameter2 |= C_wDoubleEdge;
return;
}
}
p_stCollisionCase ++;
}
}
/* anthony */
/*p_stCollisionCase = COL_g_stCollisionCase;*/
p_stCollisionCase = COL_g_stCollisionCaseReal;
for (i = 0 ; i < COL_g_lNbElementsInTable ; i ++)
{
if(MTH_M_bEqualWithEpsilon(_xT, p_stCollisionCase->xCollisionTime, 0.0001f))
{
if(_p_stNormal->xX < p_stCollisionCase->stCollisionNormal.xX)
{
int iNumberOfElementToCopy = 0;
COL_tdstCollisionCase * p = p_stCollisionCase;
/*COL_tdstCollisionCase * end = COL_g_stCollisionCase + COL_g_lNbElementsInTable ;*/ /* anthony */
COL_tdstCollisionCase * end = COL_g_stCollisionCaseReal + COL_g_lNbElementsInTable ;
while (p ++ < end) iNumberOfElementToCopy ++;
/* Not to go over array Boudary in memmove*/
if (p == (COL_g_stCollisionCase + (COL_C_xMaxNumberOfCollisions+1))) iNumberOfElementToCopy --;
if (iNumberOfElementToCopy )
memmove (p_stCollisionCase + 1 , p_stCollisionCase , iNumberOfElementToCopy * sizeof (COL_g_stCollisionCase [0]));
break;
}
}
else
{
if (_xT < p_stCollisionCase -> xCollisionTime)
{
int iNumberOfElementToCopy = 0;
COL_tdstCollisionCase * p = p_stCollisionCase;
/*COL_tdstCollisionCase * end = COL_g_stCollisionCase + COL_g_lNbElementsInTable ;*/ /* anthony */
COL_tdstCollisionCase * end = COL_g_stCollisionCaseReal + COL_g_lNbElementsInTable ;
/* Not to go over array Boudary in memmove*/
while (p ++ < end) iNumberOfElementToCopy ++;
if (p == (COL_g_stCollisionCase + (COL_C_xMaxNumberOfCollisions + 1))) iNumberOfElementToCopy --;
if (iNumberOfElementToCopy)
memmove (p_stCollisionCase + 1 , p_stCollisionCase , iNumberOfElementToCopy * sizeof (COL_g_stCollisionCase [0]));
break;
}
}
p_stCollisionCase ++;
}
//if (i == COL_C_xMaxNumberOfCollisions) return; /* The table is full*/
if (i == COL_g_lMaxNumberOfCollisions) return; /* anthony */
/*XB 98/09/11*/
#ifdef USE_PROFILER
if(s_l_MaxNbCollisions<i)
{
s_l_MaxNbCollisions=i;
}
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpMaxNbCollisions,s_l_MaxNbCollisions );
PRF_fn_vSetIndependantVariable( PRF_C_ulIdpAllowedNbCollisions,COL_C_xMaxNumberOfCollisions );
#endif /* USE_PROFILER */
/*End XB*/
p_stCollisionCase -> xCollisionTime = _xT;
MTH3D_M_vCopyVector (& p_stCollisionCase -> stTranslation , _p_stTranslation);
MTH3D_M_vCopyVector (& p_stCollisionCase -> stCollisionPoint , _p_stHit);
MTH3D_M_vCopyVector (& p_stCollisionCase -> stCollisionNormal , _p_stNormal);
MTH3D_M_vCopyVector (& p_stCollisionCase -> stMovement , _p_stMovement);
MTH3D_M_vCopyVector (& p_stCollisionCase -> stEndPosition , _p_stEndPosition);
p_stCollisionCase -> hDynamicMaterial = _hDynMat;
p_stCollisionCase -> hStaticMaterial = _hStatMat;
p_stCollisionCase -> xDynamicGeomEntity = _xDynamicGeomEntity;
p_stCollisionCase -> xStaticGeomEntity = _xStaticGeomEntity;
p_stCollisionCase -> xSphereRadius = _xSphereRadius;
p_stCollisionCase -> p_vParameter1 = _p_vParameter1;
p_stCollisionCase -> sParameter2 = _sParameter2;
/* p_stCollisionCase -> bCollisionState = TRUE;*/ /* not usefull anymore */
if (COL_g_lNbElementsInTable == COL_g_lMaxNumberOfCollisions)
return;
else
COL_g_lNbElementsInTable++;
}
/*
--------------------------------------------------------------------------------
-- Description : Get of collision result
--------------------------------------------------------------------------------
-- Creation date : 22 apr 1997 Author : FPI
--------------------------------------------------------------------------------
qq*/
/* get du resultat des collisions */
/*
#ifndef _FIRE_DEADCODE_U64_
ACP_tdxBool COL_fn_bGetResultCollision ( COL_tdstCollisionCase * p_stCollisionCaseDst )
{
// resultat
if ( COL_g_stCollisionCase [0] . bCollisionState )
{
MTH3D_M_vNormalizeVector (& COL_g_stCollisionCase [0] . stCollisionNormal , & COL_g_stCollisionCase [0] . stCollisionNormal);
memcpy (p_stCollisionCaseDst , & COL_g_stCollisionCase [0] , sizeof (COL_tdstCollisionCase));
}
return COL_g_stCollisionCase [0] . bCollisionState;
}
#endif
*/
/*
--------------------------------------------------------------------------------
-- Description : Get several collision results
--------------------------------------------------------------------------------
-- Creation date : March 3, 1998 Author : Alexis Vaisse
--------------------------------------------------------------------------------
*/
ACP_tdxBool COL_fn_bGetMultipleResultCollision (COL_tdstCollisionCase * * _p_p_stCollisionCaseDst)
{
ACP_tdxBool temp;
/* return a pointer to the array of collision case*/
//* _p_p_stCollisionCaseDst = COL_g_stCollisionCase;
* _p_p_stCollisionCaseDst = COL_g_stCollisionCaseReal;
//return COL_g_stCollisionCase [0] . bCollisionState; /* If there is a collision, the position 0 is not empty*/
return temp = (COL_g_lNbElementsInTable!=0);
/*
long i , lNumberOfElementToCopy;
COL_tdstCollisionCase * p;
p = p_stCollisionCaseDst;
for (i = 0 ; i < COL_C_xMaxNumberOfCollisions ; i ++)
{
(p ++) -> bCollisionState = FALSE;
}
// Normalize the normals
p = COL_g_stCollisionCase;
for (i = 0 ; i < COL_C_xMaxNumberOfCollisions ; i ++)
{
if (p -> bCollisionState)
{
MTH3D_M_vNormalizeVector (& p -> stCollisionNormal , & p -> stCollisionNormal);
}
else break; // No collision : it is not necessary to use the next elements of the array
p ++;
}
lNumberOfElementToCopy = (i < COL_C_xMaxNumberOfCollisions) ? (i + 1) : COL_C_xMaxNumberOfCollisions;
// Copy only the minimum
memcpy (p_stCollisionCaseDst , & COL_g_stCollisionCase , sizeof (COL_tdstCollisionCase) * lNumberOfElementToCopy);
return COL_g_stCollisionCase [0] . bCollisionState; // If there is a collision, the position 0 is not empty
*/
}