 
/*******************************************************************************/
/* 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*/
