/* 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é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ée par la camé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; }