215 lines
11 KiB
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 */
|
|
}
|
|
}
|
|
}
|