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

2974 lines
121 KiB
C
Raw Blame History

/*
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
--------------------------------------------------------------------------------
-- Description : Geometric object intersection
--------------------------------------------------------------------------------
-- 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/IntersGO.h"
#ifdef USE_ALTIMAPS
/*.-----------------------------------------------------------------------.*/
/*| |*/
/*| Functions useful for Altimap intersections |*/
/*| |*/
/*'-----------------------------------------------------------------------'*/
/***********************************************************************************************/
/* Name : COL_bSelectAltimapSquare*/
/* Description : Sets the square coords of the square placed below or above the point*/
/* Return val. : True if the point is above or below the altimap. False otherwise*/
/* 0 : On the map*/
/* 1 : Left*/
/* 2 : Right*/
/* 4 : Below*/
/* 8 : Above*/
/* Author : Marc FASCIA*/
/* Date : 18/03/98*/
/* Optimized ? : No*/
/***********************************************************************************************/
unsigned char COL_ucSelectAltimapSquare( GEO_tdstElementAltimap * p_Altimap,
MTH3D_tdstVector * p_TestPoint,
ACP_tdxIndex * p_xCoordX,
ACP_tdxIndex * p_xCoordY )
{
MTH3D_tdstVector stVector;
unsigned char ucRetCode;
ucRetCode = 0;
/*--- Places the test point and the Altimap at the same origin*/
MTH3D_M_vSubVector( &stVector, (p_TestPoint), &((p_Altimap)->stOrigin) );
/*--- First, we have to find the right square*/
*p_xCoordX = (short) MTH_M_xRealToLong( ( stVector.xX / (p_Altimap)->xDeltaX ) );
*p_xCoordY = (short) MTH_M_xRealToLong( ( stVector.xY / (p_Altimap)->xDeltaY ) );
if( *p_xCoordX < 0 )
ucRetCode |= 1; /* On the Left*/
else
if( *p_xCoordX > (p_Altimap)->xWidth - 1)
ucRetCode |= 2; /* On the Right*/
if( *p_xCoordY < 0 )
ucRetCode |= 4; /* Below*/
else
if( *p_xCoordY > (p_Altimap)->xDepth - 1)
ucRetCode |= 8; /* Above*/
return ucRetCode;
}
/***********************************************************************************************/
/* Name : COL_ucBuildAltimapSquareTriangle*/
/* Description : */
/* Return val. : The type of the next triangle in this square*/
/* Author : Marc FASCIA*/
/* Date : 18/03/98*/
/* Optimized ? : No*/
/***********************************************************************************************/
unsigned char COL_ucBuildAltimapSquareTriangle( GEO_tdstElementAltimap * p_Altimap, /* The altimap*/
ACP_tdxIndex xSx, /* Square coord X*/
ACP_tdxIndex xSy, /* Square coord Y*/
unsigned char ucTriangle, /* Which triangle of this square*/
MTH3D_tdstVector * p_stV1, /* Triplet of points*/
MTH3D_tdstVector * p_stV2, /* ''*/
MTH3D_tdstVector * p_stV3, /* ''*/
MTH3D_tdstVector * p_stNormal, /* Normal vector*/
ACP_tdxIndex * p_xFaceIndex ) /* Index of built face*/
{
ACP_tdxIndex xSquare, xVertex, xOpposite;
/*--- We compute the square index*/
xSquare = xSy * (p_Altimap)->xWidth + xSx;
/*--- And teh base vertex index of this square*/
xVertex = xSquare + ( xSquare / (p_Altimap)->xWidth );
xOpposite = xVertex + (p_Altimap->xWidth + 1) + 1;
/*--- We need to know how this square is divided*/
/*--------------------------------------------------------------------------------------------------------*/
if( ucTriangle & GEO_C_xAltiSquareTopRight )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex + 1 ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite - 1 ] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return (ucTriangle & ~GEO_C_xAltiSquareTopRight) << 4;
}
/*--------------------------------------------------------------------------------------------------------*/
if( ucTriangle & GEO_C_xAltiSquareBottomLeft )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex + 1 ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite - 1 ] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return 0;
}
/*--------------------------------------------------------------------------------------------------------*/
if( (ucTriangle >> 4) & GEO_C_xAltiSquareBottomLeft )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex + 1 ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite - 1 ] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex + 1;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return 0;
}
/*--------------------------------------------------------------------------------------------------------*/
if( ucTriangle & GEO_C_xAltiSquareTopLeft )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite - 1 ] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return (ucTriangle & ~GEO_C_xAltiSquareTopLeft) << 4;
}
/*--------------------------------------------------------------------------------------------------------*/
if( ucTriangle & GEO_C_xAltiSquareBottomRight )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex + 1 ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return 0;
}
/*--------------------------------------------------------------------------------------------------------*/
if( (ucTriangle >> 4) & GEO_C_xAltiSquareBottomRight )
{
/*--- 2 points of the diagonal*/
MTH3D_M_vSetVectorElements( p_stV1, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex ] );
MTH3D_M_vSetVectorElements( p_stV2, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy ),
p_Altimap->d_xHeight[ xVertex + 1 ] );
MTH3D_M_vSetVectorElements( p_stV3, p_Altimap->stOrigin.xX + p_Altimap->xDeltaX * MTH_M_xLongToReal( xSx+1 ),
p_Altimap->stOrigin.xY + p_Altimap->xDeltaY * MTH_M_xLongToReal( xSy+1 ),
p_Altimap->d_xHeight[ xOpposite] );
*p_xFaceIndex = p_Altimap->d_stSquare[xSquare].xFaceIndex + 1;
*p_stNormal = p_Altimap->d_stFaces[ *p_xFaceIndex ].stNormal;
return 0;
}
return GEO_C_xAltiSquareVoid;
}
/*----------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------*/
#endif /*USE_ALTIMAPS*/
/*
--------------------------------------------------------------------------------
-- Description : View and add face in list a data of element
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
void INT_fn_vViewAndAddFaceElementInList ( ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement,
MTH3D_tdstVector *p_stVertexA,
ACP_tdxBool bBack,
MTH3D_tdstVector *p_stHit,
ACP_tdxIndex xElements,
ACP_tdxIndex xDataElementIndex )
{
ACP_tdxIndex xFaceIndex;
MTH_tdxReal xDistance;
if ( !(bBack) )
{
xDistance = MTH3D_M_xVectorGap ( p_stHit, p_stVertexA );
/* index sur le dernier element */
xFaceIndex = *p_xNbElements;
while ( ( 0 < xFaceIndex ) && ( xDistance < d_stDataOfElement[xFaceIndex-1].xDistance ) )
{
if ( xFaceIndex < xNbMaxElements )
{
/* xFaceIndex <- xFaceIndex - 1 */
memcpy ( &(d_stDataOfElement[xFaceIndex]), &(d_stDataOfElement[xFaceIndex-1]), sizeof ( struct GLI_tdstDataOfElement_ ) );
}
xFaceIndex--;
}
if ( xFaceIndex < xNbMaxElements )
{
/* xFaceIndex */
MTH3D_M_vCopyVector ( &(d_stDataOfElement[xFaceIndex].stHit), p_stHit );
d_stDataOfElement[xFaceIndex].xDistance = xDistance;
d_stDataOfElement[xFaceIndex].xElements = xElements;
d_stDataOfElement[xFaceIndex].xIndexOfFace = xDataElementIndex;
if ( (*p_xNbElements) < xNbMaxElements )
(*p_xNbElements)++;
}
}
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with face of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 03 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
/* YLG*/
unsigned long g_xMask = 0;
/*DONE//*/
/* used*/
ACP_tdxBool INT_fn_bIntersectSegmentWithFaceOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVertexB,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xElementIndex;
COL_tdxFaceIndex * p_xListIndex;
GEO_tdstElementIndexedTriangles * p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors * p_stElementFaceMapDescriptors;*/
/* GEO_tdstElementTMeshes * p_stElementTMeshes;*/
GEO_tdstElementSpheres * p_stElementSpheres;
GEO_tdstElementAlignedBoxes * p_stElementAlignedBoxes;
ACP_tdxIndex xDataElementIndex;
ACP_tdxIndex xNodeIndex;
/* ACP_tdxIndex xAtomIndex;*/
COL_tdxFaceIndex xIndex;
/* ACP_tdxBool bPointsSpin;*/
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector *p_stNormal;
MTH_tdxReal xDPlan;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
MTH3D_tdstVector *p_stCenter;
MTH3D_tdstVector *p_stMinPoint;
MTH3D_tdstVector *p_stMaxPoint;
MTH3D_tdstVector stNormal;
ACP_tdxBool bBack = FALSE;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
ACP_tdxIndex xNumberOfSelectedNodes;
COL_tdpstOctreeNode aDEF_pstSelectedNode[COL_C_xMaxSelectedNodes];
MTH_tdxReal aDEF_xSelectedT[COL_C_xMaxSelectedNodes];
ACP_tdxIndex xNbElements;
GMT_tdxHandleToGameMaterial hMaterial = NULL;
GMT_tdxHandleToCollideMaterial hCM = NULL;
*p_xNbElements = 0;
if ( p_stGeomObj->p_stOctree == NULL )
{
/* pour les elements */
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
if ( g_xMask != 0 )
{
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL )
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & g_xMask ) == 0x0000 )
break;
}
else
break;
}
else
break;
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &xT, &stHit )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
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;
ACP_tdxBool xBoolA, xBoolB;
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexA, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexB, &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 );
/*--- Equation of face's plan*/
xDPlan = MTH_M_xNeg( MTH3D_M_xDotProductVector( &stNorm, &stV1 ) );
if( INT_fn_bIntersectSegmentWithTriangle( p_stVertexA, p_stVectAB,
&stV1, &stV2, &stV3,
&stNorm, xDPlan, &xT, &stHit ) )
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xIndex );
}
}
}
break;
#endif /*USE_ALTIMAPS*/
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bIntersectSegmentWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bIntersectSegmentWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
break;
default :
break;
}
}
}
else
{
COL_fn_vExploreOctreeWithSegment ( p_stGeomObj->p_stOctree, p_stVertexA, p_stVectAB,
aDEF_pstSelectedNode, aDEF_xSelectedT, &xNumberOfSelectedNodes );
COL_g_lFacesTagCounter++;
/* pour les noeuds selectionnes */
for ( xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
xNbElements = *((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1);
for (xIndex = 0 ; xIndex < xNbElements ; xIndex++)
{
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;
}
/* verif tag */
if
(
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
!= COL_g_lFacesTagCounter
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
if (g_xMask != 0)
{
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & g_xMask ) == 0x0000 )
break;
}
else
break;
}
else
break;
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &xT, &stHit )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bIntersectSegmentWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bIntersectSegmentWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap:
#endif /*USE_ALTIMAPS*/
default :
break;
}
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
= COL_g_lFacesTagCounter;
}
}
}
}
return (*p_xNbElements) > 0;
}
/*
--------------------------------------------------------------------------------
-- Description : Segment with first face of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 29 may 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/*DONE//*/
#ifndef U64
/* used only for complex shadow calculation*/
ACP_tdxBool INT_fn_bIntersectSegmentWithFirstFaceOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVertexB,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
MTH3D_tdstVector *p_stHitPoint,
ACP_tdxIndex *p_xElement,
ACP_tdxIndex *p_xDataElement )
{
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
GEO_tdstElementSpheres *p_stElementSpheres;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes;
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector *p_stNormal;
MTH_tdxReal xDPlan;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
MTH3D_tdstVector *p_stCenter;
MTH3D_tdstVector *p_stMinPoint;
MTH3D_tdstVector *p_stMaxPoint;
MTH3D_tdstVector stNormal;
ACP_tdxBool bFound;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
MTH_tdxReal xDistance;
COL_tdxFaceIndex *p_xListIndex;
ACP_tdxIndex xNodeIndex;
COL_tdxFaceIndex xIndex;
ACP_tdxIndex xNumberOfSelectedNodes;
COL_tdpstOctreeNode aDEF_pstSelectedNode[COL_C_xMaxSelectedNodes];
MTH_tdxReal aDEF_xSelectedT[COL_C_xMaxSelectedNodes];
ACP_tdxIndex xNbElements;
bFound = FALSE;
xDistance = MTH_C_2;
if ( p_stGeomObj->p_stOctree == NULL )
{
/* pour les elements */
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &xT, &stHit )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
}
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;
ACP_tdxBool xBoolA, xBoolB;
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexA, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexB, &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 );
/*--- Equation of face's plan*/
xDPlan = MTH_M_xNeg( MTH3D_M_xDotProductVector( &stNorm, &stV1 ) );
if( INT_fn_bIntersectSegmentWithTriangle( p_stVertexA, p_stVectAB,
&stV1, &stV2, &stV3,
&stNorm, xDPlan, &xT, &stHit ) )
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xIndex;
}
}
}
}
break;
#endif /*USE_ALTIMAPS*/
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bIntersectSegmentWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&xT, &stHit, &stNormal )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bIntersectSegmentWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&xT, &stHit, &stNormal )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
}
break;
default :
break;
}
}
}
else
{
COL_fn_vExploreOctreeWithSegment ( p_stGeomObj->p_stOctree, p_stVertexA, p_stVectAB,
aDEF_pstSelectedNode, aDEF_xSelectedT, &xNumberOfSelectedNodes );
COL_g_lFacesTagCounter++;
/* pour les noeuds selectionnes */
for ( xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
xNbElements = *((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1);
for (xIndex = 0 ; xIndex < xNbElements ; xIndex++)
{
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;
}
/* verif tag */
if
(
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
!= COL_g_lFacesTagCounter
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &xT, &stHit )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
break;
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bIntersectSegmentWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&xT, &stHit, &stNormal )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bIntersectSegmentWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&xT, &stHit, &stNormal )
)
{
if ( MTH_M_bLess ( xT, xDistance ) )
{
bFound = TRUE;
xDistance = xT;
MTH3D_M_vCopyVector ( p_stHitPoint, &stHit );
*p_xElement = xElementIndex;
*p_xDataElement = xDataElementIndex;
}
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap:
#endif /*USE_ALTIMAPS*/
default :
break;
}
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
= COL_g_lFacesTagCounter;
}
}
}
}
return bFound;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Segment with face of geometric object intersection detection
--------------------------------------------------------------------------------
-- Creation date : 15 jun 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/*ANNECY CB On prend en compte le mat<61>riaux.*/
/*S'il n'est pas collisionnable, on ne tient*/
/*pas compte de ce qu'on pick (le test n'est*/
/*meme pas fait).*/
/*Fonction uniquement utilis<69>e par la cam<61>ra*/
/*au moment de la modif (11/02/98)*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* used */
ACP_tdxBool INT_fn_bDetectIntersectSegmentWithFaceOfGeometricObject
(
MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj
)
{
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
GEO_tdstElementSpheres *p_stElementSpheres;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes;
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector *p_stNormal;
/* MTH3D_tdstVector stVertexB;*/
MTH_tdxReal xDPlan;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
MTH3D_tdstVector *p_stCenter;
MTH3D_tdstVector *p_stMinPoint;
MTH3D_tdstVector *p_stMaxPoint;
COL_tdxFaceIndex *p_xListIndex;
ACP_tdxIndex xNodeIndex;
COL_tdxFaceIndex xIndex;
ACP_tdxIndex xNumberOfSelectedNodes;
COL_tdpstOctreeNode aDEF_pstSelectedNode[COL_C_xMaxSelectedNodes];
MTH_tdxReal aDEF_xSelectedT[COL_C_xMaxSelectedNodes];
GMT_tdxHandleToCollideMaterial hCollidedCollideMaterial;
ACP_tdxIndex xNbElements;
if ( p_stGeomObj->p_stOctree == NULL )
{
/* pour les elements */
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stElementIndexedTriangles->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
break;
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bDetectIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan )
)
{
return TRUE;
}
}
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;
ACP_tdxBool xBoolA, xBoolB;
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexA, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, &stVertexB, &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 & 0x0000000F;*/
ucType = p_stElementAltimap->d_stSquare[ xLoopV ].ucType;
while( ucType )
{
ucType = COL_ucBuildAltimapSquareTriangle( p_stElementAltimap, xLoopX, xLoopY, ucType,
&stV1, &stV2, &stV3, &stNorm, &xIndex );
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial( p_stElementAltimap->d_hMaterial[ p_stElementAltimap->d_stFaces[ xIndex ].ucMatIndex ] );
if( (hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000) )
continue;
/*--- Equation of face's plan*/
xDPlan = MTH_M_xNeg( MTH3D_M_xDotProductVector( &stNorm, &stV1 ) );
if( INT_fn_bDetectIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
&stV1, &stV2, &stV3, &stNorm, xDPlan ) )
return TRUE;
}
}
}
break;
#endif /*USE_ALTIMAPS*/
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stIndexedSphere->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
continue;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bDetectIntersectSegmentWithSphere
(
p_stVertexA,
p_stVectAB,
p_stCenter,
p_stIndexedSphere->xRadius
)
)
{
return TRUE;
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stIndexedAlignedBox->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
continue;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bDetectIntersectSegmentWithBox ( p_stVertexA, p_stVectAB,
p_stMinPoint, p_stMaxPoint, NULL )
)
{
return TRUE;
}
}
break;
default :
break;
}
}
}
else
{
COL_fn_vExploreOctreeWithSegment ( p_stGeomObj->p_stOctree, p_stVertexA, p_stVectAB,
aDEF_pstSelectedNode, aDEF_xSelectedT, &xNumberOfSelectedNodes );
COL_g_lFacesTagCounter++;
/* pour les noeuds selectionnes */
for ( xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
xNbElements = *((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1);
for (xIndex = 0 ; xIndex < xNbElements ; xIndex++)
{
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;
}
/* verif tag */
if
(
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
!= COL_g_lFacesTagCounter
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stElementIndexedTriangles->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
break;
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bDetectIntersectSegmentWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan )
)
{
return TRUE;
}
break;
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stIndexedSphere->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
break;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bDetectIntersectSegmentWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius )
)
{
return TRUE;
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
hCollidedCollideMaterial = GMT_fn_hGetCollideMaterial(p_stIndexedAlignedBox->hMaterial);
if
(
(hCollidedCollideMaterial != GMT_C_InvalidCollideMaterial)
&& (GMT_fn_hGetCollideMaterialIdentifier(hCollidedCollideMaterial) & 0xC000)
)
break;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bDetectIntersectSegmentWithBox ( p_stVertexA, p_stVectAB,
p_stMinPoint, p_stMaxPoint, NULL )
)
{
return TRUE;
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap:
#endif /*USE_ALTIMAPS*/
default :
break;
}
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
= COL_g_lFacesTagCounter;
}
}
}
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with face of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#if defined(ACTIVE_EDITOR)
/*active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithFaceOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVertexB,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xElementIndex;
COL_tdxFaceIndex *p_xListIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
/* GEO_tdstElementTMeshes *p_stElementTMeshes;*/
GEO_tdstElementSpheres *p_stElementSpheres;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes;
GEO_tdstElementCones *p_stElementCones;
ACP_tdxIndex xNodeIndex;
ACP_tdxIndex xDataElementIndex;
/* ACP_tdxIndex xAtomIndex;*/
COL_tdxFaceIndex xIndex;
/* ACP_tdxBool bPointsSpin;*/
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector *p_stNormal;
MTH_tdxReal xDPlan;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
GEO_tdstIndexedCone *p_stIndexedCone;
MTH3D_tdstVector *p_stCenter;
MTH3D_tdstVector *p_stMinPoint;
MTH3D_tdstVector *p_stMaxPoint;
MTH3D_tdstVector *p_stTopPoint;
MTH3D_tdstVector *p_stBasePoint;
MTH3D_tdstVector stNormal;
ACP_tdxBool bBack;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
ACP_tdxIndex xNumberOfSelectedNodes;
COL_tdpstOctreeNode aDEF_pstSelectedNode[COL_C_xMaxSelectedNodes];
MTH_tdxReal aDEF_xSelectedT[COL_C_xMaxSelectedNodes];
GMT_tdxHandleToGameMaterial hMaterial = NULL;
GMT_tdxHandleToCollideMaterial hCM = NULL;
ACP_tdxIndex xNbElements;
*p_xNbElements = 0;
if ( p_stGeomObj->p_stOctree == NULL )
{
/* pour les elements */
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
if (g_xMask != 0)
{
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & g_xMask ) == 0x0000 )
break;
}
else
break;
}
else
break;
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection semiaxe - triangle */
if
(
INT_fn_bIntersectSemiAxeWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &bBack, &xT, &stHit )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
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;
ACP_tdxBool xBoolA, xBoolB;
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexA, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stVertexB, &xBx, &xBy );
COL_M_vClipSquareSelection( p_stElementAltimap, xAx, xAy, xBoolA );
COL_M_vClipSquareSelection( p_stElementAltimap, xBx, xBy, xBoolB );
COL_M_vSortSquareSelection( xAx, xBx );
COL_M_vSortSquareSelection( xAy, xBy );
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 );
/*--- Equation of face's plan*/
xDPlan = MTH_M_xNeg( MTH3D_M_xDotProductVector( &stNorm, &stV1 ) );
if( INT_fn_bIntersectSemiAxeWithTriangle( p_stVertexA, p_stVectAB,
&stV1, &stV2, &stV3,
&stNorm, xDPlan, &bBack, &xT, &stHit ) )
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xIndex );
}
}
}
break;
#endif /*USE_ALTIMAPS*/
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection semiaxe - sphere */
if
(
INT_fn_bIntersectSemiAxeWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&bBack, &xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection semiaxe - boite */
if
(
INT_fn_bIntersectSemiAxeWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&bBack, &xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
break;
case GEO_C_xElementCones :
p_stElementCones = (GEO_tdstElementCones *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les cones */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementCones->xNbCones ; xDataElementIndex++ )
{
/* cone */
p_stIndexedCone = p_stElementCones->d_stListOfCones + xDataElementIndex;
/* points de la boite */
p_stTopPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedCone->xTopPoint;
p_stBasePoint = p_stGeomObj->d_stListOfPoints + p_stIndexedCone->xBasePoint;
/* intersection semiaxe - cone */
if
(
INT_fn_bIntersectSemiAxeWithCone ( p_stVertexA, p_stVectAB,
p_stTopPoint, p_stBasePoint, p_stIndexedCone->xBaseRadius,
&bBack, &xT, &stHit )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
}
break;
default :
break;
}
}
}
else
{
COL_fn_vExploreOctreeWithSemiAxe ( p_stGeomObj->p_stOctree, p_stVertexA, p_stVertexB, p_stVectAB,
aDEF_pstSelectedNode, aDEF_xSelectedT, &xNumberOfSelectedNodes );
COL_g_lFacesTagCounter++;
/* pour les noeuds selectionnes */
for ( xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
xNbElements = *((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1);
for (xIndex = 0 ; xIndex < xNbElements ; xIndex++)
{
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;
}
/* verif tag */
if
(
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
!= COL_g_lFacesTagCounter
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
if (g_xMask != 0)
{
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & g_xMask ) == 0x0000 )
break;
}
else
break;
}
else
break;
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
/* intersection segment - triangle */
if
(
INT_fn_bIntersectSemiAxeWithTriangle ( p_stVertexA, p_stVectAB,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &bBack, &xT, &stHit )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
p_stCenter = p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint;
/* intersection segment - sphere */
if
(
INT_fn_bIntersectSemiAxeWithSphere ( p_stVertexA, p_stVectAB,
p_stCenter, p_stIndexedSphere->xRadius,
&bBack, &xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
p_stMinPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint;
p_stMaxPoint = p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint;
/* intersection segment - boite */
if
(
INT_fn_bIntersectSemiAxeWithBox ( p_stVertexA, p_stVertexB, p_stVectAB,
p_stMinPoint, p_stMaxPoint,
&bBack, &xT, &stHit, &stNormal )
)
{
INT_fn_vViewAndAddFaceElementInList ( xNbMaxElements, p_xNbElements, d_stDataOfElement,
p_stVertexA, bBack, &stHit, xElementIndex, xDataElementIndex );
}
break;
default :
break;
}
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
= COL_g_lFacesTagCounter;
}
}
}
}
return (*p_xNbElements) > 0;
}
#endif /* ACTIVE_EDITOR*/
/*
--------------------------------------------------------------------------------
-- Description : View and add face in list a data of element
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#ifndef U64
/* used only for complex shadow calculation*/
void INT_fn_vViewAndAddFaceElementInShadowList ( ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
COL_tdstShadowElement *d_stShadowElement,
/* MTH_tdxReal xT,*/
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xElementIndex,
ACP_tdxIndex xDataElementIndex )
{
ACP_tdxIndex xFaceIndex;
GMT_tdxHandleToGameMaterial hMaterial;
GMT_tdxHandleToCollideMaterial hCM;
hMaterial = NULL;
switch (GEO_xGetElementType( p_stGeomObj, xElementIndex ) )
{
case GEO_C_xElementIndexedTriangles:
{
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
break;
}
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap:
{
GEO_tdstElementAltimap * p_stAltimap;
p_stAltimap = (GEO_tdstElementAltimap *) p_stGeomObj->d_stListOfElements[ xElementIndex ];
hMaterial = p_stAltimap->d_hMaterial[ p_stAltimap->d_stFaces[ xDataElementIndex ].ucMatIndex ];
break;
}
#endif /*USE_ALTIMAPS*/
/*
case GEO_C_xElementFaceMapDescriptors:
{
break;
}
*/
}
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0xE000 ) != 0x0000 )
return;
}
}
/* index sur le dernier element */
xFaceIndex = *p_xNbElements;
if ( xFaceIndex < xNbMaxElements )
{
/* xFaceIndex */
d_stShadowElement[xFaceIndex].xElementIndex = xElementIndex;
d_stShadowElement[xFaceIndex].xDataElementIndex = xDataElementIndex;
if ( (*p_xNbElements) < xNbMaxElements )
(*p_xNbElements)++;
}
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with shadow face of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 29 may 1997 Author : FPI
--------------------------------------------------------------------------------
*/
#ifndef U64
/* used only for complex shadow calculation*/
ACP_tdxBool INT_fn_bIntersectSegmentWithShadowFaceOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVertexB,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
MTH3D_tdstVector *p_stHit,
ACP_tdxIndex *p_xElement,
ACP_tdxIndex *p_xDataElements
)
{
ACP_tdxBool bIntersect = FALSE;
GMT_tdxHandleToGameMaterial hMaterial = NULL;
GMT_tdxHandleToCollideMaterial hCM = NULL;
*p_xElement = 0;
if
(
INT_fn_bIntersectSegmentWithFirstFaceOfGeometricObject ( p_stVertexA, p_stVertexB, p_stVectAB, p_stGeomObj,
p_stHit, p_xElement, p_xDataElements )
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[*p_xElement] )
{
case GEO_C_xElementIndexedTriangles :
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, *p_xElement, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
{
/* //any bit of NoShadow, Water or Uncollidable cancels shadow projection
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0xE000 ) == 0x0000 )
*/
/*any bit of Water or Uncollidable cancels shadow projection */
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0xA000 ) == 0x0000 )
bIntersect = TRUE;
}
else
bIntersect = TRUE;
}
else
bIntersect = TRUE;
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap :
bIntersect = TRUE;
break;
#endif /*USE_ALTIMAPS*/
/*
case GEO_C_xElementFaceMapDescriptors :
bIntersect = TRUE;
break;
*/
default :
break;
}
}
return bIntersect;
/* return (*p_xNbElements) > 0;*/
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Sphere with shadow face of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 05 jun 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/*DONE//*/
#ifndef U64
/* used only for complex shadow calculation*/
ACP_tdxBool INT_fn_bIntersectSphereWithShadowFaceOfGeometricObject ( MTH3D_tdstVector *p_stCenter,
MTH_tdxReal _xRadius,
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
COL_tdstShadowElement *d_stShadowElement,
ACP_tdxBool *p_bBadMaterial)
{
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector stVect12;
MTH3D_tdstVector stVect23;
MTH3D_tdstVector stVect31;
MTH3D_tdstVector stMinPoint;
MTH3D_tdstVector stMaxPoint;
COL_tdxFaceIndex *p_xListIndex;
ACP_tdxIndex xNodeIndex;
COL_tdxFaceIndex xIndex;
ACP_tdxIndex xNumberOfSelectedNodes;
COL_tdpstOctreeNode aDEF_pstSelectedNode[COL_C_xMaxSelectedNodes];
MTH_tdxReal xRadius;
GMT_tdxHandleToGameMaterial hMaterial = NULL;
GMT_tdxHandleToCollideMaterial hCM = NULL;
ACP_tdxIndex xNbElements;
*p_xNbElements = 0;
*p_bBadMaterial = FALSE;
xRadius = MTH_M_xSqr ( _xRadius );
if ( p_stGeomObj->p_stOctree == NULL )
{
/* pour les elements */
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0xE000 ) != 0x0000 )
{
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0x6000 ) != 0x0000 )
*p_bBadMaterial = TRUE;
break;
}
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
MTH3D_M_vSubVector ( &stVect12, p_stVertex2, p_stVertex1 );
MTH3D_M_vSubVector ( &stVect23, p_stVertex3, p_stVertex2 );
MTH3D_M_vSubVector ( &stVect31, p_stVertex1, p_stVertex3 );
if
(
MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex1, &stVect12 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex2, &stVect23 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex3, &stVect31 ), xRadius )
)
{
INT_fn_vViewAndAddFaceElementInShadowList ( xNbMaxElements, p_xNbElements, d_stShadowElement,
p_stGeomObj, xElementIndex, xDataElementIndex );
}
}
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;
ACP_tdxBool xBoolA, xBoolB;
MTH3D_tdstVector stVertexA, stVertexB;
MTH3D_M_vSubScalarVector( &stVertexA, _xRadius * MTH_C_Sqrt2, p_stCenter );
MTH3D_M_vAddScalarVector( &stVertexB, _xRadius * MTH_C_Sqrt2, p_stCenter );
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, &stVertexA, &xAx, &xAy );
xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, &stVertexB, &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 );
MTH3D_M_vSubVector ( &stVect12, &stV2, &stV1 );
MTH3D_M_vSubVector ( &stVect23, &stV3, &stV2 );
MTH3D_M_vSubVector ( &stVect31, &stV1, &stV3 );
if( MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, &stV1, &stVect12 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, &stV2, &stVect23 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, &stV3, &stVect31 ), xRadius ) )
{
INT_fn_vViewAndAddFaceElementInShadowList ( xNbMaxElements, p_xNbElements, d_stShadowElement,
p_stGeomObj, xElementIndex, xIndex );
}
}
}
}
break;
#endif /*USE_ALTIMAPS*/
default :
break;
}
}
}
else
{
COL_fn_vComputeBoundingBoxOfSphere ( &stMinPoint, &stMaxPoint, p_stCenter, _xRadius );
COL_fn_vExploreOctreeWithBox ( p_stGeomObj->p_stOctree, &stMinPoint, &stMaxPoint,
aDEF_pstSelectedNode, &xNumberOfSelectedNodes );
COL_g_lFacesTagCounter++;
/* pour les noeuds selectionnes */
for ( xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ )
{
xNbElements = *((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList);
p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)aDEF_pstSelectedNode[xNodeIndex]->d_xFaceIndexList)+1);
for (xIndex = 0 ; xIndex < xNbElements ; xIndex++)
{
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;
}
/* verif tag */
if
(
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
!= COL_g_lFacesTagCounter
)
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
GEO_vGetGameMaterialOfIndexedTriangles( p_stGeomObj, xElementIndex, &hMaterial );
if ( hMaterial != NULL)
{
hCM = GMT_fn_hGetCollideMaterial( hMaterial );
if (hCM != GMT_C_InvalidCollideMaterial)
/*any bit of NoShadow, Water or Uncollidable cancels shadow projection*/
if ((GMT_fn_hGetCollideMaterialIdentifier( hCM ) & 0xE000 ) != 0x0000 )
{
*p_bBadMaterial = TRUE;
break;
}
}
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
MTH3D_M_vSubVector ( &stVect12, p_stVertex2, p_stVertex1 );
MTH3D_M_vSubVector ( &stVect23, p_stVertex3, p_stVertex2 );
MTH3D_M_vSubVector ( &stVect31, p_stVertex1, p_stVertex3 );
if
(
MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex1, &stVect12 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex2, &stVect23 ), xRadius )
|| MTH_M_bLessEqual ( INT_fn_xSqrDistancePointToSegment ( p_stCenter, p_stVertex3, &stVect31 ), xRadius )
)
{
INT_fn_vViewAndAddFaceElementInShadowList ( xNbMaxElements, p_xNbElements, d_stShadowElement,
p_stGeomObj, xElementIndex, xDataElementIndex );
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap:
#endif /*USE_ALTIMAPS*/
default :
break;
}
COL_g_d_lTaggedFacesTable[(p_stGeomObj->p_stOctree)->d_xElementBasesTable[xElementIndex] + xDataElementIndex]
= COL_g_lFacesTagCounter;
}
}
}
}
return (*p_xNbElements) > 0;
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Search and replace point in elements
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
void INT_fn_vSearchAndReplacePointInElement ( GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xDataList;
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
GEO_tdstElementSpheres *p_stElementSpheres;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes;
GEO_tdstElementPoints *p_stElementPoints;
GEO_tdstElementLines *p_stElementLines;
ACP_tdxIndex xPointIndex;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
for ( xDataList = 0 ; xDataList < xNbElements ; xDataList++ )
{
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle */
for ( xPointIndex = 0 ; xPointIndex < 3 ; xPointIndex++ )
{
if ( (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[xPointIndex] == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
}
}
break;
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
/* centre de la sphere */
if ( p_stIndexedSphere->xCenterPoint == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
/* points de la boite */
if ( p_stIndexedAlignedBox->xMinPoint == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
if ( p_stIndexedAlignedBox->xMaxPoint == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
}
break;
case GEO_C_xElementPoints :
p_stElementPoints = (GEO_tdstElementPoints *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les points */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementPoints->xNbPoints ; xDataElementIndex++ )
{
if ( *(p_stElementPoints->d_xListOfPointIndex + xDataElementIndex) == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
d_stDataOfElement[xDataList].xIndexOfPoint = xDataElementIndex;
}
}
break;
case GEO_C_xElementLines :
p_stElementLines = (GEO_tdstElementLines *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les lignes */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementLines->xNbLines ; xDataElementIndex++ )
{
/* points de la ligne */
if ( (p_stElementLines->d_stListOfLineIndex + xDataElementIndex)->a2_xIndex[0] == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
if ( (p_stElementLines->d_stListOfLineIndex + xDataElementIndex)->a2_xIndex[1] == d_stDataOfElement[xDataList].xIndexOfPoint )
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
}
break;
default :
break;
}
}
}
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with point of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#if defined(ACTIVE_EDITOR)
/* active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithPointOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xPointIndex;
MTH3D_tdstVector *p_stPoint;
MTH_tdxReal xDistance;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
ACP_tdxIndex xPointListIndex;
*p_xNbElements = 0;
/* pour les points */
for ( xPointIndex = 0 ; xPointIndex < p_stGeomObj->xNbPoints ; xPointIndex++ )
{
p_stPoint = p_stGeomObj->d_stListOfPoints + xPointIndex;
/* distance demi-axe point */
xDistance = INT_fn_xDistancePointToLine ( p_stPoint, p_stVertexA, p_stVectAB, &xT, &stHit );
if ( MTH_M_bGreaterZero ( xT ) )
{
/* index sur le dernier element */
xPointListIndex = *p_xNbElements;
while ( ( 0 < xPointListIndex ) && ( xDistance < d_stDataOfElement[xPointListIndex-1].xDistance ) )
{
if ( xPointListIndex < xNbMaxElements )
{
/* xPointListIndex <- xPointListIndex - 1 */
memcpy ( &(d_stDataOfElement[xPointListIndex]), &(d_stDataOfElement[xPointListIndex-1]), sizeof ( struct GLI_tdstDataOfElement_ ) );
}
xPointListIndex--;
}
if ( xPointListIndex < xNbMaxElements )
{
/* xPointListIndex */
MTH3D_M_vCopyVector ( &(d_stDataOfElement[xPointListIndex].stHit), &stHit );
d_stDataOfElement[xPointListIndex].xDistance = xDistance;
d_stDataOfElement[xPointListIndex].xElements = xPointIndex;
d_stDataOfElement[xPointListIndex].xIndexOfPoint = xPointIndex;
if ( (*p_xNbElements) < xNbMaxElements )
(*p_xNbElements)++;
}
}
}
INT_fn_vSearchAndReplacePointInElement ( p_stGeomObj, *p_xNbElements, d_stDataOfElement );
return (*p_xNbElements) > 0;
}
#endif ACTIVE_EDITOR
/*
--------------------------------------------------------------------------------
-- Description : Edge part of a triangle
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
ACP_tdxBool INT_fn_bEdgePartOfTriangle ( ACP_tdxIndex xEdge1,
ACP_tdxIndex xEdge2,
ACP_tdxIndex xPoint1,
ACP_tdxIndex xPoint2,
ACP_tdxIndex xPoint3 )
{
return ( ( xEdge1 == xPoint1 ) || ( xEdge1 == xPoint2 ) || ( xEdge1 == xPoint3 ) ) &&
( ( xEdge2 == xPoint1 ) || ( xEdge2 == xPoint2 ) || ( xEdge2 == xPoint3 ) );
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Search and replace edge in elements
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#ifdef ACTIVE_EDITOR
/* active editor only*/
void INT_fn_vSearchAndReplaceEdgeInElement ( GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xDataList;
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
/* GEO_tdstElementFaceMapDescriptors *p_stElementFaceMapDescriptors;*/
/* GEO_tdstElementLines *p_stElementLines;*/
for ( xDataList = 0 ; xDataList < xNbElements ; xDataList++ )
{
d_stDataOfElement[xDataList].xElements = GEO_C_xElementNULL;
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( *(p_stGeomObj->d_xListOfElementsTypes + xElementIndex) )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(*(p_stGeomObj->d_stListOfElements + xElementIndex));
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
if
(
INT_fn_bEdgePartOfTriangle ( p_stGeomObj->d_stListOfEdges[d_stDataOfElement[xDataList].xIndexOfEdge].a2_xIndex[0],
p_stGeomObj->d_stListOfEdges[d_stDataOfElement[xDataList].xIndexOfEdge].a2_xIndex[1],
(p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0],
(p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1],
(p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2] )
)
{
d_stDataOfElement[xDataList].xElements = xElementIndex;
}
}
break;
default :
break;
}
}
}
}
#endif
/*
--------------------------------------------------------------------------------
-- Description : Semiaxe with edge of geometric object intersection test
--------------------------------------------------------------------------------
-- Creation date : 18 nov 1996 Author : FPI
--------------------------------------------------------------------------------
*/
#if defined(ACTIVE_EDITOR)
/* active editor only*/
ACP_tdxBool INT_fn_bIntersectSemiAxeWithEdgeOfGeometricObject ( MTH3D_tdstVector *p_stVertexA,
MTH3D_tdstVector *p_stVectAB,
GEO_tdstGeometricObject *p_stGeomObj,
ACP_tdxIndex xNbMaxElements,
ACP_tdxIndex *p_xNbElements,
struct GLI_tdstDataOfElement_ *d_stDataOfElement )
{
ACP_tdxIndex xEdgeIndex;
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector stVect12;
MTH3D_tdstVector stSegmentPoint;
MTH_tdxReal xDistance;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
ACP_tdxIndex xEdgeListIndex;
*p_xNbElements = 0;
/* pour les points */
for ( xEdgeIndex = 0 ; xEdgeIndex < p_stGeomObj->xNbEdges ; xEdgeIndex++ )
{
p_stVertex1 = p_stGeomObj->d_stListOfPoints + p_stGeomObj->d_stListOfEdges[xEdgeIndex].a2_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + p_stGeomObj->d_stListOfEdges[xEdgeIndex].a2_xIndex[1];
MTH3D_M_vSubVector ( &stVect12, p_stVertex2, p_stVertex1 );
/* distance demi-axe segment */
xDistance = INT_fn_xDistanceSegmentToLine ( p_stVertex1, &stVect12, p_stVertexA, p_stVectAB, &xT, &stSegmentPoint, &stHit );
if ( MTH_M_bGreaterZero ( xT ) )
{
/* index sur le dernier element */
xEdgeListIndex = *p_xNbElements;
while ( ( 0 <= xEdgeListIndex ) && ( xDistance < d_stDataOfElement[xEdgeListIndex].xDistance ) )
{
if ( xEdgeListIndex < xNbMaxElements )
{
/* xEdgeListIndex <- xEdgeListIndex - 1 */
memcpy ( &(d_stDataOfElement[xEdgeListIndex]), &(d_stDataOfElement[xEdgeListIndex-1]), sizeof ( struct GLI_tdstDataOfElement_ ) );
}
xEdgeListIndex--;
}
if ( xEdgeListIndex < xNbMaxElements )
{
/* xEdgeListIndex */
MTH3D_M_vCopyVector ( &(d_stDataOfElement[xEdgeListIndex].stHit), &stHit );
d_stDataOfElement[xEdgeListIndex].xDistance = xDistance;
d_stDataOfElement[xEdgeListIndex].xElements = xEdgeIndex;
d_stDataOfElement[xEdgeListIndex].xIndexOfPoint = xEdgeIndex;
if ( (*p_xNbElements) < xNbMaxElements )
(*p_xNbElements)++;
}
}
}
INT_fn_vSearchAndReplaceEdgeInElement ( p_stGeomObj, *p_xNbElements, d_stDataOfElement );
return (*p_xNbElements) > 0;
}
#endif /*ACTIVE_EDITOR*/
/*
--------------------------------------------------------------------------------
-- Description : Get inclusion of a point in a geometric object
--------------------------------------------------------------------------------
-- Creation date : 17 jan 1997 Author : FPI-OLJ
--------------------------------------------------------------------------------
*/
/* usefull*/
ACP_tdxBool INT_fn_bGetInclusionPointInGeometricObject ( MTH3D_tdstVector *p_stPoint,
GEO_tdstGeometricObject *p_stGeomObj )
{
ACP_tdxIndex xElementIndex;
ACP_tdxIndex xDataElementIndex;
GEO_tdstElementIndexedTriangles *p_stElementIndexedTriangles;
GEO_tdstElementSpheres *p_stElementSpheres;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes;
GEO_tdstElementCones *p_stElementCones;
GEO_tdstIndexedSphere *p_stIndexedSphere;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox;
GEO_tdstIndexedCone *p_stIndexedCone;
MTH3D_tdstVector *p_stVertex1;
MTH3D_tdstVector *p_stVertex2;
MTH3D_tdstVector *p_stVertex3;
MTH3D_tdstVector *p_stNormal;
MTH_tdxReal xDPlan;
MTH_tdxReal xT;
MTH3D_tdstVector stHit;
MTH3D_tdstVector stZNormal = { MTH_C_ZERO, MTH_C_ZERO, MTH_C_ONE };
ACP_tdxIndex xNbIntersect;
for ( xElementIndex = 0 ; xElementIndex < p_stGeomObj->xNbElements ; xElementIndex++ )
{
switch ( p_stGeomObj->d_xListOfElementsTypes[xElementIndex] )
{
case GEO_C_xElementIndexedTriangles :
p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xNbIntersect = 0;
/* pour les triangles */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementIndexedTriangles->xNbFaces ; xDataElementIndex++ )
{
/* points du triangle statique */
p_stVertex1 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[0];
p_stVertex2 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[1];
p_stVertex3 = p_stGeomObj->d_stListOfPoints + (p_stElementIndexedTriangles->d_stListOfFacesTripled + xDataElementIndex)->a3_xIndex[2];
/* calcul de la normale */
p_stNormal = p_stElementIndexedTriangles->d_stListOfFacesNormals + xDataElementIndex;
/* calcul de d de l equation du plan */
xDPlan = MTH_M_xNeg ( MTH3D_M_xDotProductVector ( p_stNormal, p_stVertex1 ) );
if
(
INT_fn_bIntersectSegmentWithTriangle ( p_stPoint, &stZNormal,
p_stVertex1, p_stVertex2, p_stVertex3,
p_stNormal, xDPlan, &xT, &stHit )
)
{
xNbIntersect ++;
}
}
if ( (xNbIntersect % 2) != 0 )
{
return TRUE;
}
break;
#ifdef USE_ALTIMAPS
case GEO_C_xElementAltimap :
{
GEO_tdstElementAltimap *p_stElementAltimap;
ACP_tdxIndex xAx, xAy, xLoopX, xLoopY, xLoopV, xIndex;
MTH3D_tdstVector stV1, stV2, stV3, stNorm;
ACP_tdxBool xBoolA;
p_stElementAltimap = (GEO_tdstElementAltimap *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, p_stPoint, &xAx, &xAy );
COL_M_vClipSquareSelection( p_stElementAltimap, xAx, xAy, xBoolA );
COL_M_vScanSelectedSquares( xLoopX, xLoopY, xLoopV, p_stElementAltimap->xWidth, xAx, xAy, xAx, xAy )
{
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 );
/*--- Equation of face's plan*/
xDPlan = MTH_M_xNeg( MTH3D_M_xDotProductVector( &stNorm, &stV1 ) );
if( INT_fn_bIntersectSegmentWithTriangle( p_stPoint, &stZNormal,
&stV1, &stV2, &stV3,
&stNorm, xDPlan, &xT, &stHit ) )
xNbIntersect ++;
}
}
if ( (xNbIntersect % 2) != 0 )
return TRUE;
}
break;
#endif /*USE_ALTIMAPS*/
case GEO_C_xElementSpheres :
p_stElementSpheres = (GEO_tdstElementSpheres *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les spheres */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementSpheres->xNbSpheres ; xDataElementIndex++ )
{
/* sphere */
p_stIndexedSphere = p_stElementSpheres->d_stListOfSpheres + xDataElementIndex;
if ( INT_fn_bGetInclusionPointInSphere ( p_stPoint, p_stGeomObj->d_stListOfPoints + p_stIndexedSphere->xCenterPoint,
p_stIndexedSphere->xRadius ) )
{
return TRUE;
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les boites */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementAlignedBoxes->xNbAlignedBoxes ; xDataElementIndex++ )
{
/* boite */
p_stIndexedAlignedBox = p_stElementAlignedBoxes->d_stListOfAlignedBoxes + xDataElementIndex;
if ( INT_fn_bGetInclusionPointInBox ( p_stPoint, p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMinPoint,
p_stGeomObj->d_stListOfPoints + p_stIndexedAlignedBox->xMaxPoint ) )
{
return TRUE;
}
}
break;
case GEO_C_xElementCones :
p_stElementCones = (GEO_tdstElementCones *)(p_stGeomObj->d_stListOfElements[xElementIndex]);
/* pour les cones */
for ( xDataElementIndex = 0 ; xDataElementIndex < p_stElementCones->xNbCones ; xDataElementIndex++ )
{
/* cone */
p_stIndexedCone = p_stElementCones->d_stListOfCones + xDataElementIndex;
if ( INT_fn_bGetInclusionPointInCone ( p_stPoint, p_stGeomObj->d_stListOfPoints + p_stIndexedCone->xTopPoint,
p_stGeomObj->d_stListOfPoints + p_stIndexedCone->xBasePoint,
p_stIndexedCone->xBaseRadius ) )
{
return TRUE;
}
}
break;
default :
break;
}
}
return FALSE;
}
/*
--------------------------------------------------------------------------------
-- Description : Two geometric objects intersection detection (sphere and box )
--------------------------------------------------------------------------------
-- Creation date : 29 apr 1997 Author : FPI
--------------------------------------------------------------------------------
*/
/* useful*/
ACP_tdxBool INT_fn_bDetectIntersectGeomObjWithGeomObj ( GEO_tdstGeometricObject *p_stGeomObj1,
POS_tdstCompletePosition *_p_stMatrix1,
GEO_tdstGeometricObject *p_stGeomObj2,
POS_tdstCompletePosition *_p_stMatrix2,
GMT_tdxHandleToGameMaterial *_p_hMat1,
GMT_tdxHandleToGameMaterial *_p_hMat2 )
{
POS_tdstCompletePosition stInvMatrix2;
POS_tdstCompletePosition st12TransformMatrix;
POS_tdstCompletePosition st21TransformMatrix;
MTH_tdxReal xScale1;
MTH_tdxReal xScale2;
ACP_tdxIndex xElementIndex1;
ACP_tdxIndex xDataElementIndex1;
GEO_tdstElementSpheres *p_stElementSpheres1;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes1;
GEO_tdstIndexedSphere *p_stIndexedSphere1;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox1;
ACP_tdxIndex xElementIndex2;
ACP_tdxIndex xDataElementIndex2;
GEO_tdstElementSpheres *p_stElementSpheres2;
GEO_tdstElementAlignedBoxes *p_stElementAlignedBoxes2;
GEO_tdstIndexedSphere *p_stIndexedSphere2;
GEO_tdstIndexedAlignedBox *p_stIndexedAlignedBox2;
MTH3D_tdstVector stCenter1in2;
MTH3D_tdstVector stCenter2in1;
MTH3D_tdstVector stCenter1 , stCenter2;
COL_tda8st8VerticesBox a8_st8VBox2;
COL_tda8st8VerticesBox a8_st8VBox2in1;
COL_tda8st8VerticesBox a8_st8VBox1;
COL_tda8st8VerticesBox a8_st8VBox1in2;
MTH3D_tdstVector stEdgeVector;
ACP_tdxIndex xVertexIndex;
ACP_tdxIndex xEdgeIndex;
xScale1 = POS_fn_xGetMaxScale ( _p_stMatrix1 );
xScale2 = POS_fn_xGetMaxScale ( _p_stMatrix2 );
for ( xElementIndex1 = 0 ; xElementIndex1 < p_stGeomObj1->xNbElements ; xElementIndex1++ )
{
switch ( p_stGeomObj1->d_xListOfElementsTypes[xElementIndex1] )
{
case GEO_C_xElementSpheres :
p_stElementSpheres1 = (GEO_tdstElementSpheres *)(p_stGeomObj1->d_stListOfElements[xElementIndex1]);
/* pour les spheres */
for ( xDataElementIndex1 = 0 ; xDataElementIndex1 < p_stElementSpheres1->xNbSpheres ; xDataElementIndex1++ )
{
/* sphere */
p_stIndexedSphere1 = p_stElementSpheres1->d_stListOfSpheres + xDataElementIndex1;
/* Get the coordinate of the center in the global axis*/
POS_fn_vMulMatrixVertex (& stCenter1 , _p_stMatrix1 , p_stGeomObj1 -> d_stListOfPoints + p_stIndexedSphere1 -> xCenterPoint);
for ( xElementIndex2 = 0 ; xElementIndex2 < p_stGeomObj2->xNbElements ; xElementIndex2++ )
{
switch ( p_stGeomObj2->d_xListOfElementsTypes[xElementIndex2] )
{
case GEO_C_xElementSpheres :
p_stElementSpheres2 = (GEO_tdstElementSpheres *)(p_stGeomObj2->d_stListOfElements[xElementIndex2]);
/* pour les spheres */
for ( xDataElementIndex2 = 0 ; xDataElementIndex2 < p_stElementSpheres2->xNbSpheres ; xDataElementIndex2++ )
{
/* sphere */
p_stIndexedSphere2 = p_stElementSpheres2->d_stListOfSpheres + xDataElementIndex2;
/* Get the coordinate of the center in the global axis*/
POS_fn_vMulMatrixVertex (& stCenter2 , _p_stMatrix2 , p_stGeomObj2 -> d_stListOfPoints + p_stIndexedSphere2 -> xCenterPoint);
if (INT_fn_bIntersectSphereWithSphere (& stCenter1 , MTH_M_xMul (p_stIndexedSphere1 -> xRadius , xScale1) ,
& stCenter2 , MTH_M_xMul (p_stIndexedSphere2 -> xRadius , xScale2)))
{
*_p_hMat1 = p_stIndexedSphere1->hMaterial;
*_p_hMat2 = p_stIndexedSphere2->hMaterial;
return TRUE;
}
}
break;
case GEO_C_xElementAlignedBoxes :
{
/* inversion de la matrice statique */
POS_fn_vInvertMatrix( &stInvMatrix2, _p_stMatrix2 );
/* calcul de la matrice de passage entre 1 et 2 */
POS_fn_vMulMatrixMatrix( &st12TransformMatrix, &stInvMatrix2, _p_stMatrix1 );
/* inversion de la matrice statique */
/* POS_fn_vInvertMatrix( &st21TransformMatrix, &st12TransformMatrix ); Not used anymore*/
/* transformation du centre1 ds repere 2*/
POS_fn_vMulMatrixVertex ( &stCenter1in2, &st12TransformMatrix, p_stGeomObj1->d_stListOfPoints + p_stIndexedSphere1->xCenterPoint );
p_stElementAlignedBoxes2 = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj2->d_stListOfElements[xElementIndex2]);
/* pour les boites*/
for ( xDataElementIndex2 = 0 ; xDataElementIndex2 < p_stElementAlignedBoxes2->xNbAlignedBoxes ; xDataElementIndex2++ )
{
/* boite*/
p_stIndexedAlignedBox2 = p_stElementAlignedBoxes2->d_stListOfAlignedBoxes + xDataElementIndex2;
if (INT_fn_bIntersectSphereWithBox ( &stCenter1in2, MTH_M_xDiv ( MTH_M_xMul ( p_stIndexedSphere1->xRadius, xScale1 ), xScale2 ),
p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMinPoint,
p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMaxPoint ) )
{
*_p_hMat1 = p_stIndexedSphere1->hMaterial;
*_p_hMat2 = p_stIndexedAlignedBox2->hMaterial;
return TRUE;
}
}
}
break;
default :
break;
}
}
}
break;
case GEO_C_xElementAlignedBoxes :
{
/* inversion de la matrice statique */
POS_fn_vInvertMatrix( &stInvMatrix2, _p_stMatrix2 );
/* calcul de la matrice de passage entre 1 et 2 */
POS_fn_vMulMatrixMatrix( &st12TransformMatrix, &stInvMatrix2, _p_stMatrix1 );
/* inversion de la matrice statique */
POS_fn_vInvertMatrix( &st21TransformMatrix, &st12TransformMatrix );
p_stElementAlignedBoxes1 = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj1->d_stListOfElements[xElementIndex1]);
/* pour les boites*/
for ( xDataElementIndex1 = 0 ; xDataElementIndex1 < p_stElementAlignedBoxes1->xNbAlignedBoxes ; xDataElementIndex1++ )
{
/* boite*/
p_stIndexedAlignedBox1 = p_stElementAlignedBoxes1->d_stListOfAlignedBoxes + xDataElementIndex1;
for ( xElementIndex2 = 0 ; xElementIndex2 < p_stGeomObj2->xNbElements ; xElementIndex2++ )
{
switch ( p_stGeomObj2->d_xListOfElementsTypes[xElementIndex2] )
{
case GEO_C_xElementSpheres :
p_stElementSpheres2 = (GEO_tdstElementSpheres *)(p_stGeomObj2->d_stListOfElements[xElementIndex2]);
/* pour les spheres*/
for ( xDataElementIndex2 = 0 ; xDataElementIndex2 < p_stElementSpheres2->xNbSpheres ; xDataElementIndex2++ )
{
/* sphere*/
p_stIndexedSphere2 = p_stElementSpheres2->d_stListOfSpheres + xDataElementIndex2;
/* transformation du centre2 ds repere 1*/
POS_fn_vMulMatrixVertex ( &stCenter2in1, &st21TransformMatrix, p_stGeomObj2->d_stListOfPoints + p_stIndexedSphere2->xCenterPoint );
if (INT_fn_bIntersectSphereWithBox ( &stCenter2in1, MTH_M_xDiv ( MTH_M_xMul ( p_stIndexedSphere2->xRadius, xScale2 ), xScale1 ),
p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMinPoint,
p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMaxPoint ) )
{
*_p_hMat1 = p_stIndexedAlignedBox1->hMaterial;
*_p_hMat2 = p_stIndexedSphere2->hMaterial;
return TRUE;
}
}
break;
case GEO_C_xElementAlignedBoxes :
p_stElementAlignedBoxes2 = (GEO_tdstElementAlignedBoxes *)(p_stGeomObj2->d_stListOfElements[xElementIndex2]);
/* pour les boites*/
for ( xDataElementIndex2 = 0 ; xDataElementIndex2 < p_stElementAlignedBoxes2->xNbAlignedBoxes ; xDataElementIndex2++ )
{
/* boite*/
p_stIndexedAlignedBox2 = p_stElementAlignedBoxes2->d_stListOfAlignedBoxes + xDataElementIndex2;
/* transformation de la boite2 ds repere 1*/
/* decompression de la boite dynamique*/
COL_fn_vMinMaxBox2VerticesBox ( a8_st8VBox2, p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMinPoint,
p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMaxPoint );
/* trajectoires des points de la boite dynamique dans statique*/
for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ )
{
/* calcul des trajectoires des points de dynamique dans statique*/
POS_fn_vMulMatrixVertex ( &(a8_st8VBox2in1[xVertexIndex]), &st21TransformMatrix, &(a8_st8VBox2[xVertexIndex]) );
}
for ( xEdgeIndex = 0 ; xEdgeIndex < COL_C_xNbEdgesPerBox ; xEdgeIndex++ )
{
MTH3D_M_vSubVector ( &stEdgeVector, &(a8_st8VBox2in1[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[1]]),
&(a8_st8VBox2in1[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[0]]) );
if ( INT_fn_bDetectIntersectSegmentWithBox ( &(a8_st8VBox2in1[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[0]]),
&stEdgeVector,
p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMinPoint,
p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMaxPoint, NULL ) )
{
*_p_hMat1 = p_stIndexedAlignedBox1->hMaterial;
*_p_hMat2 = p_stIndexedAlignedBox2->hMaterial;
return TRUE;
}
}
/* transformation de la boite1 ds repere 2*/
/* decompression de la boite dynamique*/
COL_fn_vMinMaxBox2VerticesBox ( a8_st8VBox1, p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMinPoint,
p_stGeomObj1->d_stListOfPoints + p_stIndexedAlignedBox1->xMaxPoint );
/* trajectoires des points de la boite dynamique dans statique*/
for ( xVertexIndex = 0 ; xVertexIndex < COL_C_xNbVerticesPerBox ; xVertexIndex++ )
{
/* calcul des trajectoires des points de dynamique dans statique*/
POS_fn_vMulMatrixVertex ( &(a8_st8VBox1in2[xVertexIndex]), &st12TransformMatrix, &(a8_st8VBox1[xVertexIndex]) );
}
for ( xEdgeIndex = 0 ; xEdgeIndex < COL_C_xNbEdgesPerBox ; xEdgeIndex++ )
{
MTH3D_M_vSubVector ( &stEdgeVector, &(a8_st8VBox1in2[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[1]]),
&(a8_st8VBox1in2[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[0]]) );
if ( INT_fn_bDetectIntersectSegmentWithBox ( &(a8_st8VBox1in2[COL_g_a12_stBoxEdges[xEdgeIndex].a2_xIndex[0]]),
&stEdgeVector,
p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMinPoint,
p_stGeomObj2->d_stListOfPoints + p_stIndexedAlignedBox2->xMaxPoint, NULL ) )
{
*_p_hMat1 = p_stIndexedAlignedBox1->hMaterial;
*_p_hMat2 = p_stIndexedAlignedBox2->hMaterial;
return TRUE;
}
}
}
break;
default :
break;
}
}
}
}
break;
default :
break;
}
}
return FALSE;
}