/* 0 1 2 3 4 5 6 7 01234567890123456789012345678901234567890123456789012345678901234567890123456789 -------------------------------------------------------------------------------- -- Description : Geometric object collision part -------------------------------------------------------------------------------- -- Creation date : 15 may 1997 Author : FPI -------------------------------------------------------------------------------- */ #include "acp_base.h" #include "MTH.h" #include "GMT.h" #include "GEO.h" #include "GLI.h" #include "PCS.h" #define PO_FRIEND #include "PO.h" #define HieFriend #include "SPO.h" #include "MEC.h" #include "COL/CollGO.h" /* -------------------------------------------------------------------------------- -- Description : Static with static geometric objects collision detection test -------------------------------------------------------------------------------- -- Creation date : March 3, 1998 Author : Alexis Vaisse -------------------------------------------------------------------------------- */ /* Collision detection test between two static geometric objects */ /* used*/ ACP_tdxBool COL_fn_bDetectCollisionStaticGeomObjWithStaticGeomObj ( GEO_tdxHandleToBoundingSphere _hDynamicGeometricObject, /* Always a sphere*/ POS_tdstCompletePosition *_p_stDynamicGeometricObjectMatrix, void *_hStaticGeometricObject, /* Either a Box or a sphere ...*/ POS_tdstCompletePosition *_p_stStaticGeometricObjectMatrix, ACP_tdxBool _bStaticGeomObjHasNoTransformationMatrix, ACP_tdxBool _bDynamicGeomObjHasZoomInsteadOfScale, ACP_tdxBool _bHasABoxBoundingVolume) { MTH3D_tdstVector stDinGPoint; /* Coordinates of the center of the dynamic bounding volume in the global axis*/ MTH3D_tdstVector stSinGPoint; /* Coordinates of the center of the static bounding volume in the global axis*/ MTH3D_tdstVector * p_stSMaxBoxPoint; MTH3D_tdstVector * p_stSMinBoxPoint; MTH3D_tdstVector stMaxDinGPoint; MTH3D_tdstVector stMinDinGPoint; MTH3D_tdstVector stMaxSinGPoint; MTH3D_tdstVector stMinSinGPoint; MTH_tdxReal xRadiusSum; MTH_tdxReal xRadiusDinG; /* on se place dans global */ /* transformation de CDT0 dans global */ POS_fn_vMulMatrixVertex(&stDinGPoint, _p_stDynamicGeometricObjectMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hDynamicGeometricObject)); if(!_bHasABoxBoundingVolume) /*The Bounding Volume of the Static Geo.Object is a SPHERE ...*/ { /* transformation de CS dans global */ if (_bStaticGeomObjHasNoTransformationMatrix) /* No transformation matrix -> only a translation*/ { MTH3D_M_vAddVector (& stSinGPoint, GEO_fn_pGetCenterPointOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject), & _p_stStaticGeometricObjectMatrix -> stTranslationVector); } else { POS_fn_vMulMatrixVertex ( &stSinGPoint, _p_stStaticGeometricObjectMatrix, GEO_fn_pGetCenterPointOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject)); } xRadiusSum = MTH_M_xAdd ( /* Radius of the dynamic sphere*/ MTH_M_xMul ((GEO_fn_xGetRadiusOfBoundingSphere(_hDynamicGeometricObject)), POS_fn_xGetMaxScale ( _p_stDynamicGeometricObjectMatrix )), /* Plus radius of the static sphere*/ _bStaticGeomObjHasNoTransformationMatrix ? GEO_fn_xGetRadiusOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject) : MTH_M_xMul ( GEO_fn_xGetRadiusOfBoundingSphere((GEO_tdxHandleToBoundingSphere)_hStaticGeometricObject), POS_fn_xGetMaxScale ( _p_stStaticGeometricObjectMatrix )) ); /* The distance between the two centers must be less that the sum of the two radius*/ return MTH_M_bLessEqual (MTH3D_M_xVectorGapSqr (& stDinGPoint , & stSinGPoint) , MTH_M_xSqr (xRadiusSum)); } else /*The Bounding Volume of the Static Geom. Object is a BOX*/ { /* The static parallel box in the local axis*/ p_stSMaxBoxPoint = GEO_fn_pGetMaxPointOfParallelBox((GEO_tdxHandleToParallelBox)_hStaticGeometricObject); p_stSMinBoxPoint = GEO_fn_pGetMinPointOfParallelBox((GEO_tdxHandleToParallelBox)_hStaticGeometricObject); /* The static parallel box in the global axis*/ MTH3D_M_vAddVector(& stMaxSinGPoint , & _p_stStaticGeometricObjectMatrix->stTranslationVector , p_stSMaxBoxPoint); MTH3D_M_vAddVector(& stMinSinGPoint , & _p_stStaticGeometricObjectMatrix->stTranslationVector , p_stSMinBoxPoint); /* We compute the parallel box that includes the sphere bounding volume*/ xRadiusDinG = MTH_M_xMul ((GEO_fn_xGetRadiusOfBoundingSphere(_hDynamicGeometricObject)), POS_fn_xGetMaxScale ( _p_stDynamicGeometricObjectMatrix )); /* The dynamic parallel box in the global axis*/ COL_fn_vComputeBoundingBoxOfSphere (& stMinDinGPoint , & stMaxDinGPoint , & stDinGPoint , xRadiusDinG); return COL_fn_bDetectCollisionBetweenTwoParallelBoxes (&stMaxSinGPoint, &stMinSinGPoint, &stMaxDinGPoint, &stMinDinGPoint); } } /* -------------------------------------------------------------------------------- -- Description : Static with static geometric objects collision test init -------------------------------------------------------------------------------- -- Creation date : 15 may 1997 Author : FPI -------------------------------------------------------------------------------- */ /* init de collision entre deux objets geometriques */ /* used*/ void COL_fn_vInitCollideStaticGeomObjWithStaticGeomObj ( COL_tdstGVForCollision *p_stGV ) { /* jt 070699 */ /* MTH3D_tdstVector stNegVector; */ /* end jt 070699 */ /* init des matrices*/ POS_fn_vSetIdentityMatrix ( &p_stGV->stInvMatrix ); POS_fn_vSetIdentityMatrix ( &p_stGV->stD2ST0TransformMatrix ); POS_fn_vSetIdentityMatrix ( &p_stGV->stD2ST1TransformMatrix ); POS_fn_vSetIdentityMatrix ( &p_stGV->stS2DT0TransformMatrix ); POS_fn_vSetIdentityMatrix ( &p_stGV->stS2DT1TransformMatrix ); /* calcul des deux matrices de transformation */ /* inversion de la matrice statique */ /* jt 070699 */ /* Faut quand même pas trop exagérer! On en fait quoi de la rotation ? */ /* if (p_stGV->bStaticGeomObjHasNoTransformationMatrix) */ /* { */ /* No transformation matrix -> the invert matrix is the identity matrix with the opposite translation vector*/ /* MTH3D_M_vNegVector (& stNegVector , & p_stGV->p_stStaticGeomObjMatrix->stTranslationVector); */ /* POS_fn_vSetTranslationVector (& p_stGV->stInvMatrix , & stNegVector); */ /* } */ /* else */ /* { */ POS_fn_vInvertMatrix( &p_stGV->stInvMatrix, p_stGV->p_stStaticGeomObjMatrix ); /* } */ /* end jt 070699 */ /* calcul de la matrice de passage entre dynamique et statique a T0 */ POS_fn_vMulMatrixMatrix( &p_stGV->stD2ST0TransformMatrix, &p_stGV->stInvMatrix, p_stGV->p_stT0DynamicGeomObjMatrix ); /* We need the T1 point*/ /* Maybe one could compute them only when the first collision is detected (???)*/ /* calcul de la matrice de passage entre dynamique et statique a T1 */ POS_fn_vMulMatrixMatrix( &p_stGV->stD2ST1TransformMatrix, &p_stGV->stInvMatrix, p_stGV->p_stT1DynamicGeomObjMatrix ); /* optimisation sur la surface */ p_stGV->bSurfacicDynamicElement = COL_fn_bGetSurfaceInGeometricObject ( p_stGV->p_stDynamicGeomObj ); /* suppression des cas inutiles */ if ( !p_stGV->bSurfacicDynamicElement ) { p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticPts ); p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEdgWithStaticEdg ); p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEdgWithStaticElt ); p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticEdg ); p_stGV->ulSelectedCollisionCases = p_stGV->ulSelectedCollisionCases & ( ~COL_C_ulDynamicEltWithStaticElt ); } /* optimisation transformation des points statiques */ p_stGV->bDynamicSphereAndPointOnly = COL_fn_bGetSphereAndPointOnlyInGeometricObject ( p_stGV->p_stDynamicGeomObj ); p_stGV->p_stOctree = p_stGV->p_stStaticGeomObj->p_stOctree; if ( p_stGV->p_stOctree != NULL ) { p_stGV->xNbStaticPoints = 0; p_stGV->xNbStaticEdges = 0; } if (p_stGV->bStaticGeomObjHasNoTransformationMatrix) { p_stGV->xStaticScale = 1; } else { p_stGV->xStaticScale = POS_fn_xGetMaxScale ( p_stGV->p_stStaticGeomObjMatrix ); } } /* -------------------------------------------------------------------------------- -- Description : Static with static geometric objects collision test -------------------------------------------------------------------------------- -- Creation date : 06 oct 1997 Author : FPI -------------------------------------------------------------------------------- */ /* test de collision entre deux objets geometriques */ /* used*/ void COL_fn_vComputeCollisionStaticGeomObjWithStaticGeomObj ( COL_tdstGVForCollision *p_stGV ) { /* init */ COL_fn_vInitCollideStaticGeomObjWithStaticGeomObj ( p_stGV ); /* elements de dynamique contre elements de statique */ if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicEltWithStaticElt ) { for ( p_stGV->xDynamicElementIndex = 0 ; p_stGV->xDynamicElementIndex < p_stGV->p_stDynamicGeomObj->xNbElements ; p_stGV->xDynamicElementIndex++ ) { switch ( p_stGV->p_stDynamicGeomObj->d_xListOfElementsTypes[p_stGV->xDynamicElementIndex] ) { case GEO_C_xElementSpheres : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicSphWithStaticElt ) { p_stGV->p_stDynamicElementSpheres = (GEO_tdstElementSpheres *)(p_stGV->p_stDynamicGeomObj->d_stListOfElements[p_stGV->xDynamicElementIndex]); /* th element always exists, but can have no sphere*/ if ( p_stGV->p_stDynamicElementSpheres->xNbSpheres ) COL_fn_vCollideStaticElementSpheresWithStaticElements ( p_stGV ); } break; #ifdef USE_ZDM_BOX case GEO_C_xElementAlignedBoxes : if ( p_stGV->ulSelectedCollisionCases & COL_C_ulDynamicBoxWithStaticElt ) { p_stGV->p_stDynamicElementAlignedBoxes = (GEO_tdstElementAlignedBoxes *)(p_stGV->p_stDynamicGeomObj->d_stListOfElements[p_stGV->xDynamicElementIndex]); /* th element always exists, but can have no box*/ if ( p_stGV->p_stDynamicElementAlignedBoxes->xNbAlignedBoxes ) COL_fn_vCollideStaticElementAlignedBoxesWithStaticElements ( p_stGV ); } break; #endif } } } } /* -------------------------------------------------------------------------------- -- Description : Static with static geometric objects collision test -------------------------------------------------------------------------------- -- Creation date : 06 oct 1997 Author : FPI -------------------------------------------------------------------------------- */ /* test de collision entre deux objets geometriques */ /* used*/ void COL_fn_vCollideStaticGeomObj1WithStaticGeomObj2 ( ACP_tdxHandleOfObject _hGeometricObject1, POS_tdstCompletePosition *_p_stGeometricObjectStartMatrix1, POS_tdstCompletePosition *_p_stGeometricObjectEndMatrix1, ACP_tdxHandleOfObject _hGeometricObject2, POS_tdstCompletePosition *_p_stGeometricObjectMatrix2, void * _p_vParameter1 , short _sParameter2 , ACP_tdxBool _bStaticGeomObjHasNoTransformationMatrix, ACP_tdxBool _bDynamicGeomObjHasZoomInsteadOfScale) { /* init des parametres du test */ COL_g_stGVForCol.bStaticGeomObjHasNoTransformationMatrix = _bStaticGeomObjHasNoTransformationMatrix; COL_g_stGVForCol.bDynamicGeomObjHasZoomInsteadOfScale = _bDynamicGeomObjHasZoomInsteadOfScale; COL_g_stGVForCol.p_stDynamicGeomObj = _hGeometricObject1; COL_g_stGVForCol.p_stT0DynamicGeomObjMatrix = _p_stGeometricObjectEndMatrix1; /* The matrix that will be used for calculation*/ COL_g_stGVForCol.p_stT1DynamicGeomObjMatrix = _p_stGeometricObjectStartMatrix1; /* This matrix will only be used when a collision is detected*/ COL_g_stGVForCol.p_stStaticGeomObj = _hGeometricObject2; COL_g_stGVForCol.p_stStaticGeomObjMatrix = _p_stGeometricObjectMatrix2; COL_g_stGVForCol.ulSelectedCollisionCases = COL_C_ulDynamicAllWithStaticAll; COL_g_stGVForCol.p_vParameter1 = _p_vParameter1; COL_g_stGVForCol.sParameter2 = _sParameter2; /* cas de rejection immediate */ if (_hGeometricObject1 == NULL || _hGeometricObject2 == NULL || _hGeometricObject1->xNbPoints == 0 || _hGeometricObject2->xNbPoints == 0 || _hGeometricObject1->xNbElements == 0 || _hGeometricObject2->xNbElements == 0) { return; } COL_fn_vComputeCollisionStaticGeomObjWithStaticGeomObj ( &COL_g_stGVForCol ); } /*--------------------------------------------------------------------------------*/ /* COL_fn_lFindNormalFromGeometricObject*/ /**/ /* This function finds the triangles of the geometric object containing the given point (on an edge),*/ /* fill an array with the normals of these triangles (two triangles maximum)*/ /* and return the number of triangles found*/ /*--------------------------------------------------------------------------------*/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ /*long COL_fn_lFindNormalFromGeometricObject (GEO_tdstGeometricObject * _p_stGeometricObject , MTH3D_tdstVector * _p_stPoint , MTH3D_tdstVector * _p_a2_stNormal) { #define C_xEpsilon MTH_M_xFloatToReal ((float) 0.001) #define C_xLargeEpsilon MTH_M_xFloatToReal ((float) 0.1) if (_p_stGeometricObject -> p_stOctree) { ACP_tdxIndex xResult; MTH3D_tdstVector stMinPoint , stMaxPoint; COL_tdpstOctreeNode a_pstSelectedNode [COL_C_xMaxSelectedNodes]; ACP_tdxIndex xNumberOfSelectedNodes; ACP_tdxIndex xNodeIndex , xFaceIndex; COL_tdxFaceIndex * p_xListIndex; ACP_tdxIndex xElementIndex , xDataElementIndex; GEO_tdstElementIndexedTriangles * p_stElementIndexedTriangles; // GEO_tdstElementFaceMapDescriptors * p_stElementFaceMapDescriptors; GEO_tdstTripledIndex * p_st3Idx; ACP_tdxIndex xNbElements; xResult = 0; MTH3D_M_vSubScalarVector (& stMinPoint , C_xEpsilon , _p_stPoint); MTH3D_M_vAddScalarVector (& stMaxPoint , C_xEpsilon , _p_stPoint); COL_fn_vExploreOctreeWithBox (_p_stGeometricObject -> p_stOctree , & stMinPoint , & stMaxPoint , a_pstSelectedNode , & xNumberOfSelectedNodes); // For each selected nodes for (xNodeIndex = 0 ; xNodeIndex < xNumberOfSelectedNodes ; xNodeIndex++ ) { // For the list of faces //p_xListIndex = a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList; xNbElements = *((COL_tdxFaceIndexDouble*)a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList); p_xListIndex = (COL_tdxFaceIndex*)(((COL_tdxFaceIndexDouble*)a_pstSelectedNode [xNodeIndex] -> d_xFaceIndexList)+1); for (xFaceIndex = 0 ; xFaceIndex < xNbElements ; xFaceIndex ++) { #ifndef U64 if ((*p_xListIndex) < COL_C_MaxIndex) xElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++)); else xElementIndex = (ACP_tdxIndex) ((* (((COL_tdxFaceIndexDouble*)p_xListIndex)++)) & ~COL_C_OverflowIndex); if ((*p_xListIndex) < COL_C_MaxIndex) xDataElementIndex = (ACP_tdxIndex) (* (p_xListIndex ++)); else xDataElementIndex = (ACP_tdxIndex) ((* (((COL_tdxFaceIndexDouble*)p_xListIndex)++)) & ~COL_C_OverflowIndex); #else //U64 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; } #endif //U64 switch (_p_stGeometricObject -> d_xListOfElementsTypes [xElementIndex]) { case GEO_C_xElementIndexedTriangles : p_stElementIndexedTriangles = (GEO_tdstElementIndexedTriangles *) (_p_stGeometricObject -> d_stListOfElements [xElementIndex]); p_st3Idx = & p_stElementIndexedTriangles -> d_stListOfFacesTripled [xDataElementIndex]; if (INT_fn_bIsOnTriangle (_p_stPoint , _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [0] , _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [1] , _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex [2])) { MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , p_stElementIndexedTriangles -> d_stListOfFacesNormals + xDataElementIndex); if (++ xResult == 2) return xResult; // We have found two triangles -> it's finished } break; } } } return xResult; } else { GEO_tdstElementIndexedTriangles *p_stETIT; // GEO_tdstElementFaceMapDescriptors *p_stEFMD; GEO_tdstTripledIndex *p_st3Idx; // GEO_tdstFaceMapTriangle *p_stFMT; ACP_tdxIndex xIndexElement , xIndexInElement; ACP_tdxIndex xResult; xResult = 0; for ( xIndexElement = 0 ; xIndexElement < _p_stGeometricObject -> xNbElements ; xIndexElement++ ) { switch ( _p_stGeometricObject -> d_xListOfElementsTypes[ xIndexElement ] ) { case GEO_C_xElementIndexedTriangles: p_stETIT = (GEO_tdstElementIndexedTriangles*) ( _p_stGeometricObject -> d_stListOfElements[ xIndexElement ] ); p_st3Idx = p_stETIT -> d_stListOfFacesTripled; for ( xIndexInElement = 0 ; xIndexInElement < p_stETIT -> xNbFaces ; xIndexInElement++, p_st3Idx++ ) { if( INT_fn_bIsOnTriangle( _p_stPoint, _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[0], _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[1], _p_stGeometricObject -> d_stListOfPoints + p_st3Idx -> a3_xIndex[2] ) ) { MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , p_stETIT -> d_stListOfFacesNormals + xIndexInElement ); if (++ xResult == 2) return xResult; // We have found two triangles -> it's finished } } 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, stP1, stP2; ACP_tdxBool xBoolA, xBoolB; MTH3D_M_vSubScalarVector( &stP1, C_xLargeEpsilon, _p_stPoint ); MTH3D_M_vAddScalarVector( &stP2, C_xLargeEpsilon, _p_stPoint ); p_stElementAltimap = (GEO_tdstElementAltimap *)(_p_stGeometricObject->d_stListOfElements[ xIndexElement ]); xBoolA = COL_ucSelectAltimapSquare( p_stElementAltimap, &stP1, &xAx, &xAy ); xBoolB = COL_ucSelectAltimapSquare( p_stElementAltimap, &stP2, &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 ); if( INT_fn_bIsOnTriangle( _p_stPoint, &stV1, &stV2, &stV3 ) ) { MTH3D_M_vCopyVector( _p_a2_stNormal + xResult , &stNorm ); if (++ xResult == 2) return xResult; // We have found two triangles -> it's finished } } } } break; #endif //USE_ALTIMAPS return xResult; } } } } */ #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */