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

215 lines
11 KiB
C

/*
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--------------------------------------------------------------------------------
-- Description : Geometric object collision part : Elt - Edg
--------------------------------------------------------------------------------
-- Creation date : 15 may 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#include "acp_base.h"
#include "MTH.h"
#include "MEC.h"
#include "GMT.h"
#include "GEO.h"
#include "GLI.h"
#include "COL/CsEltEdg.h"
#include "COL/CsSphElt.h"
/*--------------------------------------------------------------------------------*/
/*-- Description : COL_fn_vCollideDynamicSphereWithStaticEdge()*/
/*--------------------------------------------------------------------------------*/
/*-- Creation date : 08 jan 1996 Author : FPI*/
/*--------------------------------------------------------------------------------*/
/* used*/
void COL_fn_vCollideStaticSphereWithStaticEdge (COL_tdstGVForCollision *p_stGV,
/* ANNECY AV {*/
MTH3D_tdstVector * p_stNormal)
/* END ANNECY AV }*/
{
/* WARNING : p_stVertex2 is now the point which DOES NOT BELONG to the edge and not the second point of the edge*/
#define C_xTwoEpsilon (MTH_M_xDoubleToReal (0.002))
#define C_xOneMinusTwoEpsilon (MTH_M_xDoubleToReal (0.998))
COL_fn_vUseEnlargeSphere (p_stGV);
if (INT_fn_bDetectIntersectSegmentWithSphere ( p_stGV->p_stVertex1, &p_stGV->stEdgeVector,
&p_stGV->stDinST0Point, p_stGV->xDynamicRadius))
{
/* Here, we have collision with the 'end' position. We test now a collision with the 'start' position*/
MTH3D_tdstVector stMovementVector;
/* stDinST01Vector is the translation to go from the 'end' position to the 'start' position of the sphere center*/
/* and we need the translation to go from the 'start' position to the 'end' position*/
MTH3D_M_vNegVector (& stMovementVector, & p_stGV->stDinST01Vector);
/* jt 220399 : restore real radius of ZDM */
COL_fn_vUseInitialSphere (p_stGV);
if (INT_fn_bDetectIntersectSegmentWithSphere (p_stGV->p_stVertex1, & p_stGV->stEdgeVector,
& p_stGV->stDinST1Point, p_stGV->xDynamicRadius))
{
/* Here, we have collision with the 'end' and the 'start' position*/
MTH3D_tdstVector stVertex1ToCenter;
MTH_tdxReal xDotProduct;
MTH3D_tdstVector stTempHit;
MTH3D_tdstVector stTempNormal;
MTH3D_tdstVector stTempDistance;
MTH3D_tdstVector stEndPosition;
ACP_tdxIndex xEdgeEntity;
/* The hit is the projection of the center of the sphere onto the edge*/
MTH3D_M_vSubVector (& stVertex1ToCenter , & p_stGV->stDinST0Point , p_stGV->p_stVertex1);
xDotProduct = MTH3D_M_xDotProductVector (& stVertex1ToCenter , & p_stGV->stEdgeVector);
xDotProduct = MTH_M_xDiv (xDotProduct , MTH3D_M_xSqrVector (& p_stGV->stEdgeVector));
/* DotProduct must be between 2 x epsilon and 1 - 2 x epsilon*/
if (MTH_M_bLess (xDotProduct , C_xTwoEpsilon )) xDotProduct = C_xTwoEpsilon;
else
if (MTH_M_bGreater (xDotProduct , C_xOneMinusTwoEpsilon)) xDotProduct = C_xOneMinusTwoEpsilon;
MTH3D_M_vMulAddVector (& stTempHit , xDotProduct , & p_stGV->stEdgeVector , p_stGV->p_stVertex1);
/* The normal is the normalized vector from the hit to the center*/
MTH3D_M_vSubVector (& stTempDistance , & p_stGV->stDinST0Point , & stTempHit);
POS_fn_vMulMatrixVector (& stTempDistance , p_stGV->p_stStaticGeomObjMatrix , & stTempDistance);
/* ANNECY AV {*/
/* MTH3D_M_vNormalizeVector (& stTempNormal , & stTempDistance);*/
/* Modification : the normal is the normal of the triangle : this function MUST be called for a specific triangle*/
/* If the static object has a zoom, we must not use it to compute the normal, so we use RotateVector and not MulMatrixVector*/
/* POS_fn_vRotateVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal);*/
MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal);
/* END ANNECY AV }*/
/* The translation vector is Radius x normal - stTempDistance*/
/* ANNECY AV {*/
/* MTH3D_M_vNegVector (& stTempDistance , & stTempDistance);*/
/* MTH3D_M_vMulAddVector (& stTempDistance , p_stGV->xDynamicRadius , & stTempNormal , & stTempDistance);*/
/* jt 130499 : il faut enlever le scale au rayon de la zone !!! */
xDotProduct = MTH_M_xSub ( MTH_M_xMul(p_stGV->xDynamicRadius,p_stGV->xStaticScale) , MTH3D_M_xDotProductVector (& stTempDistance , & stTempNormal));
/* end jt 130499 */
MTH3D_M_vMulScalarVector (& stTempDistance , xDotProduct , & stTempNormal);
/* END ANNECY AV }*/
if (MTH_M_bGreaterEqual (MTH3D_M_xGetZofVector (p_stGV->p_stVertex2), MTH3D_M_xGetZofVector (& stTempHit)))
xEdgeEntity = COL_C_xHighEdgeEntity;
else xEdgeEntity = COL_C_xLowEdgeEntity;
POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stTempHit);
POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector);
POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point);
/* We register the collision with Time = -1 to say that there was already a collision at the 'start' position*/
COL_fn_vAddInStaticCollisionTable (MTH_C_MinusONE , & stTempDistance , & stTempHit , & stTempNormal ,
p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial ,
COL_C_xSphereEntity , xEdgeEntity ,
p_stGV->p_vParameter1 , p_stGV->sParameter2 ,
& stMovementVector,p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition);
}
else
{
/* Here, we have collision during the movement : we call the dynamic collision*/
MTH_tdxReal xT;
MTH3D_tdstVector stTempVector;
MTH3D_tdstVector stHit;
MTH3D_tdstVector stNormal;
MTH3D_tdstVector stTempHit;
MTH3D_tdstVector stTempDistance;
MTH3D_tdstVector stTempNormal;
MTH3D_tdstVector stEndPosition;
ACP_tdxIndex xEdgeEntity;
if (INT_fn_bIntersectSegmentWithCylinder (& p_stGV->stDinST1Point , & stMovementVector ,
p_stGV->p_stVertex1 , & p_stGV->stEdgeVector , p_stGV->xDynamicRadius ,
&xT, &stHit, &stNormal )) /* normal is the hit on the edge !*/
{
if (MTH_M_bGreaterEqual (MTH3D_M_xGetZofVector (p_stGV->p_stVertex2), MTH3D_M_xGetZofVector (& stNormal)))
xEdgeEntity = COL_C_xHighEdgeEntity;
else xEdgeEntity = COL_C_xLowEdgeEntity;
/* The hit*/
POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stNormal );
/* The normal*/
MTH3D_M_vSubVector ( &stTempVector, &stHit, &stNormal );
MTH3D_M_vDivScalarVector ( &stTempVector, &stTempVector, p_stGV->xDynamicRadius);
/* ANNECY AV {*/
/* POS_fn_vMulMatrixVector ( &stTempNormal, p_stGV->p_stStaticGeomObjMatrix, &stTempVector );*/
/* Modification : the normal is the normal of the triangle : this function MUST be called for a specific triangle*/
/* POS_fn_vMulMatrixVector (& stTempNormal , p_stGV->p_stStaticGeomObjMatrix , p_stNormal);*/
MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal);
/* END ANNECY AV }*/
/* The translation is not used*/
MTH3D_M_vNullVector (& stTempDistance);
POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector);
POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point);
COL_fn_vAddInStaticCollisionTable (xT, & stTempDistance, & stTempHit, & stTempNormal,
p_stGV->hDynamicMaterial, p_stGV->hStaticMaterial,
COL_C_xSphereEntity, xEdgeEntity,
p_stGV->p_vParameter1, p_stGV->sParameter2,
& stMovementVector, p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition);
}
/* ??? If there is no collision during the movement, the collision is in fact with the point and with be treated somewhere else
*/
/* jt 240399 */
else
{
/* test collision with point */
if (INT_fn_bDetectIntersectSegmentWithSphere ( p_stGV->p_stVertex1, &p_stGV->stEdgeVector, &p_stGV->stDinST0Point, p_stGV->xDynamicRadius))
{
MTH3D_tdstVector stVertex1ToCenter;
MTH_tdxReal xDotProduct;
// The hit is the projection of the center of the sphere onto the edge
MTH3D_M_vSubVector (& stVertex1ToCenter , & p_stGV->stDinST0Point , p_stGV->p_stVertex1);
xDotProduct = MTH3D_M_xDotProductVector (& stVertex1ToCenter , & p_stGV->stEdgeVector);
xDotProduct = MTH_M_xDiv (xDotProduct , MTH3D_M_xSqrVector (& p_stGV->stEdgeVector));
MTH3D_M_vMulAddVector (& stTempHit , xDotProduct , & p_stGV->stEdgeVector , p_stGV->p_stVertex1);
// The normal is the normalized vector from the hit to the center
MTH3D_M_vSubVector (& stTempDistance , & p_stGV->stDinST0Point , & stTempHit);
POS_fn_vMulMatrixVector (& stTempDistance , p_stGV->p_stStaticGeomObjMatrix , & stTempDistance);
MTH3D_M_vNormalizeVector (& stTempNormal , & stTempDistance);
// The translation vector is Radius x normal - stTempDistance
MTH3D_M_vNegVector (& stTempDistance , & stTempDistance);
MTH3D_M_vMulAddVector (& stTempDistance , p_stGV->xDynamicRadius , & stTempNormal , & stTempDistance);
POS_fn_vMulMatrixVertex (& stTempHit , p_stGV->p_stStaticGeomObjMatrix , & stTempHit);
/* use real normal */
MTH3D_M_vMulMatrixVectorWithoutBuffer (& stTempNormal, & p_stGV->p_stStaticGeomObjMatrix->stRotationMatrix, p_stNormal);
POS_fn_vMulMatrixVector (& stMovementVector , p_stGV->p_stStaticGeomObjMatrix , & stMovementVector);
POS_fn_vMulMatrixVertex (& stEndPosition , p_stGV->p_stStaticGeomObjMatrix , & p_stGV->stDinST0Point);
// we register with Time=1.5 to say :
// - we don't know the real xRate
// - translation is ok
// - point type collision
COL_fn_vAddInStaticCollisionTable (MTH_M_xDoubleToReal(1.5) , & stTempDistance , & stTempHit , & stTempNormal ,
p_stGV->hDynamicMaterial , p_stGV->hStaticMaterial ,
COL_C_xSphereEntity , COL_C_xLowEdgeEntity ,
p_stGV->p_vParameter1 , p_stGV->sParameter2 , & stMovementVector,
p_stGV->p_stDynamicIndexedSphere->xRadius, & stEndPosition);
}
}
/* end jt 240399 */
}
}
}