/*ANNECY CB Attention, tout a été modifié dans ce fichier !!!*/ #include "ACP_base.h" #include "GMT.h" #include "GEO.h" #include "GLI.h" #include "PCS.h" #include "COL.h" #include "lst.h" #include "PO.h" #include "FIL.h" #include "snd.h" #include "gld.h" #include "mec.h" #ifdef USE_IPT_DX5 #include "IPT_DX5.h" /* InPuT (absolutely before GAM.h)*/ #else /* USE_IPT_WIN */ #include "IPT.h" /* InPuT (absolutely before GAM.h)*/ #endif /* USE_IPT_WIN */ #include "sct.h" #ifndef D_THROW_PRT #include "PRT.h" #endif /* D_THROW_PRT */ #include "gam.h" #include "tmr.h" /*XB980821*/ #ifndef D_THROW_IPO #include "IPO.h" #endif /* D_THROW_IPO */ /*End XB*/ #undef extern #include "SPO/HieConst.h" #include "LST.h" #include "SPO/HieSpObj.h" #include "SPO/HieHand.h" #include "SPO/HieDef.h" #include "SPO/HieMacro.h" #include "SPO/HieMtStk.h" #include "SPO/HieExt.h" #include "SPO/HiePick.h" /*HP 180698*/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ MTH_tdxReal VoidReal; #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ ACP_tdxHandleOfObject GeoHandle; #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ #ifndef D_THROW_VISUAL_SET #define M_hGetFirstLodOfVisualSetFromPo(Po) (GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle) #define M_hGetRepositionZoneFromPo(Po) (GLI_vGetVisualSetLOD(PO_fn_hGetVisualSet(Po), 0, &VoidReal, &GeoHandle), GeoHandle) #else #define M_hGetFirstLodOfVisualSetFromPo(Po) PO_fn_hGetGeometricObject(Po) #define M_hGetRepositionZoneFromPo(Po) PO_fn_hGetGeometricObject(Po) #endif /* D_THROW_VISUAL_SET */ extern BOOL fn_bIsEditorsActive(void); extern unsigned long fn_ulStandardGameGetCustomBitsSO (HIE_tdxHandleToSuperObject hSupObj); extern ACP_tdxHandleOfObject fn_hMakeOneObjectFromManyZdx (unsigned char _ucZoneType, HIE_tdxHandleToSuperObject _hCharacter); unsigned long g_ulSpoMask = 0; /* *================================================================================================= *================================================================================================= */ #ifdef ACTIVE_EDITOR /* active editor only*/ static ACP_tdxBool fn_bIsBoundingVolumeIntersect ( GEO_tdxHandleToMatrix _p_stCurrentMatrix, MTH3D_tdstVector * _p_stVertexA, MTH3D_tdstVector * _p_stVectAB, GEO_tdxHandleToBoundingSphere _hBoundingSphere ) { MTH3D_tdstVector stGlobalSphereCenter; MTH_tdxReal xScaledRadius; MTH3D_M_vMulMatrixVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stRotationMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hBoundingSphere)); MTH3D_M_vAddVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stTranslationVector, &stGlobalSphereCenter); xScaledRadius = GEO_fn_xGetRadiusOfBoundingSphere(_hBoundingSphere) * POS_fn_xGetMaxScale(_p_stCurrentMatrix); return INT_fn_bDetectIntersectSemiAxeWithSphere (_p_stVertexA, _p_stVectAB, &stGlobalSphereCenter, xScaledRadius); } #endif /* used*/ ACP_tdxBool fn_bDetectIntersectSegmentWithBoundingSphere ( GEO_tdxHandleToMatrix _p_stCurrentMatrix, MTH3D_tdstVector * _p_stVertexA, MTH3D_tdstVector * _p_stVectAB, GEO_tdxHandleToBoundingSphere _hBoundingSphere ) { MTH3D_tdstVector stGlobalSphereCenter; MTH_tdxReal xScaledRadius; MTH3D_M_vMulMatrixVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stRotationMatrix, GEO_fn_pGetCenterPointOfBoundingSphere(_hBoundingSphere)); MTH3D_M_vAddVector(&stGlobalSphereCenter, &_p_stCurrentMatrix->stTranslationVector, &stGlobalSphereCenter); xScaledRadius = GEO_fn_xGetRadiusOfBoundingSphere(_hBoundingSphere) * POS_fn_xGetMaxScale(_p_stCurrentMatrix); return INT_fn_bDetectIntersectSegmentWithSphere (_p_stVertexA, _p_stVectAB, &stGlobalSphereCenter, xScaledRadius); } /* *================================================================================================= *================================================================================================= */ #ifdef ACTIVE_EDITOR /* active editor only*/ static ACP_tdxIndex fn_xIntersectSemiAxeWithRepositioningSuperObject ( GLI_tdeModePicking xModePicking, MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVertexB, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject _hSprObj, HIE_tdstPickInfo *p_stPickInfo , ACP_tdxIndex *p_xNbPickInfo ) { static GEO_tdxHandleToBoundingSphere hBoundingSphere; static GEO_tdxHandleToParallelBox hParallelBox; static ACP_tdxHandleOfObject hSentObject; static MTH3D_tdstVector stMinPoint; static MTH3D_tdstVector stMaxPoint; static ACP_tdxBool bBoxBoundingVolume,bIntersect; ACP_tdxIndex i; static long lType,lCustomBits; HIE_tdxHandleToSuperObject hChild; static MTH3D_tdstVector stVertexALocal, stVectAB; static POS_tdstCompletePosition stInvMatrix; static GLI_tdstPickedObject stPickedObject; /* eliminate every object that must be ignored...*/ if (HIE_fn_SO_bIsNotPickable( _hSprObj )) { return *p_xNbPickInfo; } lType=HIE_fn_ulGetSuperObjectType(_hSprObj); /* we test if the character is rayman (has the custombit 32)*/ /* we also ignore the character if he can't be hit by ray tracing.*/ /* we also ignore inactive characters*/ if (lType==HIE_C_ulActor) { lCustomBits = fn_ulStandardGameGetCustomBitsSO(_hSprObj); if ( !(lCustomBits & GAM_C_CustBitRayHit) || /* not hit by ray tracing*/ !(fn_bf1StandardGameGetIsActive(M_GetMSHandle(_hSprObj,StandardGame))) || /* inactive*/ (lCustomBits & (1<<31)) ) /* Rayman*/ { return *p_xNbPickInfo; } } /* ok, now we can pick*/ hBoundingSphere = NULL; hParallelBox = NULL; hSentObject = NULL; HIE_fn_vPushMatrix (_hSprObj); /* do we have a bounding sphere or a bounding box ??*/ bBoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj); if(bBoxBoundingVolume) { /* this is a BOX !! */ hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); if (hParallelBox) { /* the box realy exists, compute its 2 points in world coordinates*/ MTH3D_tdstVector *p_stMinPoint; MTH3D_tdstVector *p_stMaxPoint; MTH3D_tdstVector stTranslation; p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox); p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox); stTranslation = (HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj))->stTranslationVector; MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , &stTranslation); MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , &stTranslation); } } else { /* this is a SPHERE, get it*/ hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); } /* test intersection*/ if (!hBoundingSphere && !hParallelBox) { /* if there are no bounding volume at all (no box nor sphere) --> go further*/ bIntersect = TRUE; } else if (!bBoxBoundingVolume) { /* if there is a BV Sphere, seek an intersect between the sphere and the axe*/ bIntersect = fn_bIsBoundingVolumeIntersect(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere); } else { /*if there is a BV Box, seek an intersect between the box and the axe */ bIntersect = INT_fn_bDetectIntersectSemiAxeWithBox(p_stVertexA, p_stVertexB, p_stVectAB, &stMinPoint, &stMaxPoint); } if(bIntersect) { if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror)) { hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj); } else if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror)) { PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)); /*AR9809*/ hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL; } #ifndef D_THROW_IPO else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) { PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet (IPO_fn_hGetPhysicalObject ((IPO_tdxHandleToInstanciatedPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj))); hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL; } #endif else if( lType == HIE_C_ulActor ) { hSentObject=fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr, _hSprObj); } /* intersection test*/ if (hSentObject) { /* convertion local coordinate system*/ POS_fn_vInvertMatrix(&stInvMatrix, g_p_stCurrentMatrix); MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVectAB, &(stInvMatrix.stTransformMatrix), p_stVectAB); MTH3D_M_vAddVector(&stVectAB, &(stInvMatrix.stTranslationVector), &stVectAB); MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVertexALocal, &(stInvMatrix.stTransformMatrix), p_stVertexA); MTH3D_M_vAddVector(&stVertexALocal, &(stInvMatrix.stTranslationVector), &stVertexALocal); if (PIC_bIntersectSemiAxeWithGeometricObject (xModePicking,&stVertexALocal,&stVectAB,hSentObject,&stPickedObject)) { ACP_tdxIndex i; i=(*p_xNbPickInfo)-1; while( (i >= 0) && (stPickedObject.aDEF_stDataOfElement[0].xDistance < p_stPickInfo[i].stPickedObject.aDEF_stDataOfElement[0].xDistance) ) { if ( i < (HIE_C_DepthPickingObjects-1) ) p_stPickInfo[i+1] = p_stPickInfo[i]; i--; } if ( i < (HIE_C_DepthPickingObjects-1) ) { p_stPickInfo[i+1].stPickedObject = stPickedObject; p_stPickInfo[i+1].hSprObject = _hSprObj; p_stPickInfo[i+1].hGeoObject=hSentObject; if ( (*p_xNbPickInfo) < HIE_C_DepthPickingObjects ) (*p_xNbPickInfo)++; } } } } if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj)) { /* node examination*/ HIE_M_ForEachChildOf(_hSprObj, hChild, i) { /* recurence*/ fn_xIntersectSemiAxeWithRepositioningSuperObject(xModePicking, p_stVertexA, p_stVertexB, p_stVectAB, hChild, p_stPickInfo, p_xNbPickInfo); } } HIE_fn_vPopMatrix (); return *p_xNbPickInfo; } #endif /* ACTIVE_EDITOR*/ /* *================================================================================================= *================================================================================================= */ #ifdef ACTIVE_EDITOR /* active editor only*/ ACP_tdxIndex fn_xIntersectSemiAxeWithVisualSuperObject ( GLI_tdeModePicking xModePicking, MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVertexB, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject _hSprObj, HIE_tdstPickInfo *p_stPickInfo , ACP_tdxIndex *p_xNbPickInfo ) { ACP_tdxHandleOfObject hSentObject = NULL; ACP_tdxIndex i; HIE_tdxHandleToSuperObject hChild; long lType; HIE_fn_vPushMatrix(_hSprObj); lType=HIE_fn_ulGetSuperObjectType(_hSprObj); { if ( HIE_fn_SO_bIsNotPickable( _hSprObj ) #ifdef ACTIVE_EDITOR && !fn_bIsEditorsActive() #endif ) { HIE_fn_vPopMatrix (); return *p_xNbPickInfo; } if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulPO | HIE_C_ulIPO | HIE_C_ulMirror| HIE_C_ulPO_Mirror | HIE_C_ulIPO_Mirror)) { MTH3D_tdstVector stVertexALocal, stVertexBLocal, stVectAB; POS_tdstCompletePosition stInvMatrix; GLI_tdstPickedObject stPickedObject; /* convertion loacal coordinate system*/ POS_fn_vInvertMatrix(&stInvMatrix, g_p_stCurrentMatrix);/*!!!*/ POS_fn_vMulMatrixVertex(&stVertexALocal, &stInvMatrix, p_stVertexA); POS_fn_vMulMatrixVertex(&stVertexBLocal, &stInvMatrix, p_stVertexB); MTH3D_M_vSubVector(&stVectAB, &stVertexBLocal, &stVertexALocal); if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror)) hSentObject=(ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj); if(lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror)) hSentObject=M_hGetFirstLodOfVisualSetFromPo((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)); /*XB980821*/ #ifndef D_THROW_IPO if(lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) hSentObject=M_hGetFirstLodOfVisualSetFromPo(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj))); #endif /* D_THROW_IPO */ /*End XB*/ /* intersection test*/ if( PIC_bIntersectSemiAxeWithGeometricObject(xModePicking, &stVertexALocal, /* &stVertexBLocal,*/ &stVectAB, hSentObject, &stPickedObject) ) { /* l'objet est sous la souris*/ ACP_tdxIndex i; i=(*p_xNbPickInfo)-1; while( (i >= 0) && (stPickedObject.aDEF_stDataOfElement[0].xDistance < p_stPickInfo[i].stPickedObject.aDEF_stDataOfElement[0].xDistance) ) { if ( i < (HIE_C_DepthPickingObjects-1) ) p_stPickInfo[i+1] = p_stPickInfo[i]; i--; } if ( i < (HIE_C_DepthPickingObjects-1) ) { p_stPickInfo[i+1].stPickedObject = stPickedObject; p_stPickInfo[i+1].hSprObject = _hSprObj; p_stPickInfo[i+1].hGeoObject=hSentObject; if ( (*p_xNbPickInfo) < HIE_C_DepthPickingObjects ) (*p_xNbPickInfo)++; } } } /* node examination*/ HIE_M_ForEachChildOf(_hSprObj, hChild, i) { /* recurence*/ fn_xIntersectSemiAxeWithVisualSuperObject(xModePicking, p_stVertexA, p_stVertexB, p_stVectAB, hChild, p_stPickInfo, p_xNbPickInfo); } } HIE_fn_vPopMatrix (); return *p_xNbPickInfo; } #endif /* ACTIVE_EDITOR*/ /* *================================================================================================= *================================================================================================= */ #ifdef ACTIVE_EDITOR /* active editor only*/ ACP_tdxIndex HIE_xIsSuperObjectPick ( GLI_tdeModePicking xModePicking, GLD_tdhDevice hDev, GLD_tdhViewport hVp, GLI_tdst2DVertex *p_stSouris2D, HIE_tdxHandleToSuperObject hSprObj, HIE_tdstPickInfo *p_stPickInfo ) { MTH3D_tdstVector stSouris3D, stVertex12, stCameraPos; ACP_tdxIndex xNbPickInfo=0; /* calcul des positions 3d de la camera et de la souris dans le repere global*/ PIC_vGetPosCamAndMouse(hDev, hVp, p_stSouris2D, &stSouris3D, &stCameraPos); MTH3D_M_vSubVector(&stVertex12, &stSouris3D, &stCameraPos); return fn_xIntersectSemiAxeWithVisualSuperObject ( xModePicking, &stCameraPos, &stSouris3D, &stVertex12, hSprObj, p_stPickInfo, &xNbPickInfo ); } #endif /* *================================================================================================= *================================================================================================= */ #ifdef ACTIVE_EDITOR /* active editor only*/ ACP_tdxIndex HIE_bIntersectSemiAxeWithSuperObject ( GLI_tdeModePicking xModePicking, MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVertexB, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject hSprObj, HIE_tdstPickInfo *p_stPickInfo ) { ACP_tdxIndex xNbPickInfo = 0; ACP_tdxIndex iRet; HIE_fn_bLoadIdentity(); iRet = fn_xIntersectSemiAxeWithRepositioningSuperObject ( xModePicking, p_stVertexA, p_stVertexB, p_stVectAB, hSprObj, p_stPickInfo, &xNbPickInfo ); HIE_fn_vPopMatrix(); return iRet; } #endif /* *================================================================================================= *================================================================================================= */ /* *================================================================================================= *================================================================================================= */ /* used*/ static ACP_tdxIndex fn_xIntersectSegmentWithRepositioningSuperObject ( MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject _hSprObj, HIE_tdstPickInfo *p_stPickInfo , ACP_tdxIndex *p_xNbPickInfo ) { static GEO_tdxHandleToBoundingSphere hBoundingSphere; static GEO_tdxHandleToParallelBox hParallelBox; static ACP_tdxHandleOfObject hSentObject; static MTH3D_tdstVector stMinPoint; static MTH3D_tdstVector stMaxPoint; static ACP_tdxBool bBoxBoundingVolume,bIntersect; ACP_tdxIndex i; /* XB 05/05/99 */ /* static long lType,lCustomBits; */ static long lType; /* End XB 05/05/99 */ HIE_tdxHandleToSuperObject hChild; static MTH3D_tdstVector stVertexALocal, stVectAB; static POS_tdstCompletePosition stInvMatrix; static GLI_tdstPickedObject stPickedObject; register unsigned long ulSpoFlags; ulSpoFlags = HIE_M_xGetSuperObjectMember(_hSprObj,ulFlags); /* eliminate every object that has the No_Collision flag*/ if (ulSpoFlags & HIE_C_Flag_ulNotPickable) { return *p_xNbPickInfo; } lType=HIE_fn_ulGetSuperObjectType(_hSprObj); /* if object is not an actor, check the flags with the given mask...*/ /* else, check the custom bit */ if (lType != HIE_C_ulActor) { if (ulSpoFlags & g_ulSpoMask) return *p_xNbPickInfo; } else { if (!fn_ulStandardGameGetCustomBitsSO(_hSprObj) & GAM_C_CustBitShadowOnMe) { return *p_xNbPickInfo; } } hBoundingSphere = NULL; hParallelBox = NULL; hSentObject = NULL; HIE_fn_vPushMatrix(_hSprObj); /* do we have a bounding sphere or a bounding box ??*/ bBoxBoundingVolume = (unsigned char)(ulSpoFlags & HIE_C_Flag_ulTypeOfBoundingVolume); if(bBoxBoundingVolume) { /* this is a BOX !! */ hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); if (hParallelBox) { /* the box realy exists, compute its 2 points in world coordinates*/ MTH3D_tdstVector *p_stMinPoint; MTH3D_tdstVector *p_stMaxPoint; MTH3D_tdstVector stTranslation; p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox); p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox); stTranslation = (HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj))->stTranslationVector; MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , &stTranslation); MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , &stTranslation); } } else { /* this is a SPHERE, get it*/ hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); } /* test intersection*/ if (!hBoundingSphere && !hParallelBox) { /* if there are no bounding volume at all (no box nor sphere) --> go further*/ bIntersect = TRUE; } else if (!bBoxBoundingVolume) { /* if there is a BV Sphere, seek an intersect between the sphere and the axe*/ bIntersect = fn_bDetectIntersectSegmentWithBoundingSphere(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere); } else { /*if there is a BV Box, seek an intersect between the box and the axe */ bIntersect = INT_fn_bDetectIntersectSegmentWithBox(p_stVertexA, p_stVectAB, &stMinPoint, &stMaxPoint,NULL); } if(bIntersect) { /* we found an intersection between the segment and the bounding volume --> let's see if we must get down to the faces*/ #ifndef U64 /* no editor objects on u64*/ if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror)) { hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj); } else #endif if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror)) { PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet((PO_tdxHandleToPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj)); /*AR9809*/ hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL; } #ifndef D_THROW_IPO else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) { PCS_tdxHandleToPhysicalCollSet hCollSet = PO_fn_hGetCollideSet (IPO_fn_hGetPhysicalObject ((IPO_tdxHandleToInstanciatedPhysicalObject) HIE_fn_hGetSuperObjectObject (_hSprObj))); hSentObject = hCollSet ? PCS_fn_hGetZdrGeoObjOfPhysicalCollSet (hCollSet) : NULL; } #endif else if( lType == HIE_C_ulActor ) { hSentObject=fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr, _hSprObj); } if (hSentObject) { /* the detected objetc is relevant, let's see if there is a collision with its faces...*/ /*Convertion local coordinate system.*/ if (ulSpoFlags & HIE_C_Flag_ulNoTransformationMatrix) { /* Only translation, compute A i local*/ MTH3D_M_vSubVector (&stVertexALocal , p_stVertexA , &_hSprObj->hGlobalMatrix->stTranslationVector); /* and nothing for the vector AB...*/ MTH3D_M_vCopyVector(&stVectAB,p_stVectAB); } else { POS_fn_vInvertMatrix(&stInvMatrix,_hSprObj->hGlobalMatrix); /* MTH3D_M_vTranspMatrixWithoutBuffer(&stInvMatrix,&_hSprObj->hGlobalMatrix->stRotationMatrix);*/ /* here, stVectAB is used only as a temporary variable and has no meaning...*/ /* compute A in local coordinates*/ /* MTH3D_M_vSubVector (&stVectAB , p_stVertexA , &_hSprObj->hGlobalMatrix->stTranslationVector);*/ /* MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVertexALocal, &stInvMatrix, &stVectAB);*/ POS_fn_vMulMatrixVertex(&stVertexALocal,&stInvMatrix, p_stVertexA); /* compute AB in local coordinates*/ POS_fn_vMulMatrixVector(&stVectAB, &stInvMatrix, p_stVectAB); /* MTH3D_M_vMulMatrixVectorWithoutBuffer(&stVectAB, &stInvMatrix, p_stVectAB);*/ } if (PIC_bIntersectSegmentWithGeometricObject (&stVertexALocal,&stVectAB,hSentObject,&stPickedObject)) { /* yes, we got an intersection !!*/ /* if it is the first one, then remember it*/ if (*p_xNbPickInfo == 0) { /* first one !*/ p_stPickInfo[0].stPickedObject = stPickedObject; p_stPickInfo[0].hSprObject = _hSprObj; p_stPickInfo[0].hGeoObject = hSentObject; *p_xNbPickInfo = 1; /* and reduce the lenght of the segment */ MTH3D_M_vSubVector(p_stVectAB, &(stPickedObject.aDEF_stDataOfElement[0].stHit),p_stVertexA); } else { /* there has already been a collision in this search, so check distance*/ /* compare this detection with the previous one*/ if (stPickedObject.aDEF_stDataOfElement[0].xDistance < p_stPickInfo[0].stPickedObject.aDEF_stDataOfElement[0].xDistance) { /* ok, the new one is nearer*/ /* lets remember the data*/ p_stPickInfo[0].stPickedObject = stPickedObject; p_stPickInfo[0].hSprObject = _hSprObj; p_stPickInfo[0].hGeoObject = hSentObject; /* and reduce the lenght of the segment */ MTH3D_M_vSubVector(p_stVectAB, &(stPickedObject.aDEF_stDataOfElement[0].stHit),p_stVertexA); } } } } } /* keep going on the sons of this SO */ if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj)) { HIE_M_ForEachChildOf(_hSprObj, hChild, i) { /* recurence*/ fn_xIntersectSegmentWithRepositioningSuperObject ( p_stVertexA, p_stVectAB, hChild, p_stPickInfo, p_xNbPickInfo ); } } HIE_fn_vPopMatrix (); return *p_xNbPickInfo; } /* *================================================================================================= *================================================================================================= */ /* used*/ ACP_tdxIndex HIE_bIntersectSegmentWithSuperObject ( MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject hSprObj, HIE_tdstPickInfo *p_stPickInfo ) { ACP_tdxIndex xNbPickInfo = 0, xReturnValue; HIE_fn_bLoadIdentity(); xReturnValue = fn_xIntersectSegmentWithRepositioningSuperObject ( p_stVertexA, p_stVectAB, hSprObj, p_stPickInfo, &xNbPickInfo ); HIE_fn_bPopMatrix(); return xReturnValue; } /* *================================================================================================= *================================================================================================= */ /* used*/ /* compute the intersection between the segment [A, A+AB], and the hSprObj and its descendants*/ ACP_tdxBool HIE_bIntersectSegmentWithFirstSuperObject(MTH3D_tdstVector *_p_stVertexA, MTH3D_tdstVector *_p_stVectAB, HIE_tdxHandleToSuperObject hSprObj, MTH3D_tdstVector *_p_stHit, MTH3D_tdstVector *_p_stNormal, HIE_tdxHandleToSuperObject *_p_hSprObjHit ) { HIE_aDEF_stTabOfPickInfo aDEF_stIntersInfo; GEO_tdstGeometricObject *p_stGeomObj; GLI_tdstDataOfElement *p_stDataOfElement; MTH3D_tdstVector stNormal; long lType; if( HIE_bIntersectSegmentWithSuperObject(_p_stVertexA,_p_stVectAB,hSprObj,aDEF_stIntersInfo) > 0) { /* detection !!!*/ p_stGeomObj = aDEF_stIntersInfo[0].hGeoObject; p_stDataOfElement = &(aDEF_stIntersInfo[0].stPickedObject.aDEF_stDataOfElement[0]); lType = HIE_fn_ulGetSuperObjectType(aDEF_stIntersInfo[0].hSprObject); if(lType & (HIE_C_ulEDT_Geometric | HIE_C_ulPO | HIE_C_ulMirror | HIE_C_ulPO_Mirror | HIE_C_ulActor | HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) { *_p_hSprObjHit = aDEF_stIntersInfo[0].hSprObject; } else { *_p_hSprObjHit = NULL; } MTH3D_M_vCopyVector( _p_stHit, &(p_stDataOfElement->stHit)); if (_p_hSprObjHit && p_stGeomObj->d_xListOfElementsTypes[p_stDataOfElement->xElements] == GEO_C_xElementSpheres) { MTH3D_tdstVector stSphereCenter; /* Get the sphere element*/ GEO_tdstElementSpheres * p_stElementSpheres = (GEO_tdstElementSpheres *) p_stGeomObj->d_stListOfElements[p_stDataOfElement->xElements]; /* The normal is the vector from the center of the sphere to the hit point (in the global axis)*/ POS_fn_vMulMatrixVertex (& stSphereCenter, HIE_fn_hGetSuperObjectGlobalMatrix(* _p_hSprObjHit), & p_stGeomObj->d_stListOfPoints[p_stElementSpheres->d_stListOfSpheres[p_stDataOfElement->xIndexOfFace].xCenterPoint]); MTH3D_M_vSubVector (_p_stNormal, _p_stHit, & stSphereCenter); MTH3D_M_vNormalizeVector (_p_stNormal, _p_stNormal); } else { GEO_vGetNormalOfGeometricObjectElement(p_stGeomObj,p_stDataOfElement->xElements,p_stDataOfElement->xIndexOfFace,&stNormal); POS_fn_vMulMatrixVector(_p_stNormal, HIE_fn_hGetSuperObjectGlobalMatrix(* _p_hSprObjHit), &stNormal); /* don't forget to normalize in case the target had scale... */ MTH3D_M_vNormalizeVector (_p_stNormal, _p_stNormal); } return TRUE; } else { return FALSE; } } /* ****************************************************************************************************** ****************************************************************************************************** ****************************************************************************************************** ****************************************************************************************************** */ /* *================================================================================================= * Picking function for camera. *================================================================================================= */ /* used*/ ACP_tdxBool HIE_bDetectIntersectSegmentWithSuperObject ( MTH3D_tdstVector *p_stVertexA, MTH3D_tdstVector *p_stVectAB, HIE_tdxHandleToSuperObject _hSprObj ) { static GEO_tdxHandleToBoundingSphere hBoundingSphere; static GEO_tdxHandleToParallelBox hParallelBox; static MTH3D_tdstVector stMinPoint; static MTH3D_tdstVector stMaxPoint; static MTH3D_tdstVector *p_stTranslation; static ACP_tdxBool bBoxBoundingVolume,bIntersect; static ACP_tdxHandleOfObject hSentObject; ACP_tdxIndex i; HIE_tdxHandleToSuperObject hChild; static long lType; /* XB 05/05/99 */ /* static MTH3D_tdstVector stVertexALocal, stVertexBLocal, stVectAB; */ static MTH3D_tdstVector stVertexALocal, stVectAB; /* End XB 05/05/99 */ static POS_tdstCompletePosition stInvMatrix; hBoundingSphere = NULL; hParallelBox = NULL; hSentObject = NULL; p_stTranslation = &_hSprObj->hGlobalMatrix->stTranslationVector; bBoxBoundingVolume = HIE_fn_SO_bHasABoxBoundingVolume(_hSprObj); if(bBoxBoundingVolume) { hParallelBox = (GEO_tdxHandleToParallelBox)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); if (hParallelBox) { MTH3D_tdstVector *p_stMinPoint; MTH3D_tdstVector *p_stMaxPoint; /* get the min and max points in world coordinates*/ p_stMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox); p_stMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox); MTH3D_M_vAddVector(&stMinPoint, p_stMinPoint , p_stTranslation); MTH3D_M_vAddVector(&stMaxPoint, p_stMaxPoint , p_stTranslation); } } else { /* get the bounding sphere*/ hBoundingSphere = (GEO_tdxHandleToBoundingSphere)HIE_fn_hGetSuperObjectBoundingVolume(_hSprObj); } /* test intersection*/ if (!hBoundingSphere && !hParallelBox) { /* if there are no bounding volume at all (no box nor sphere) --> go further*/ bIntersect = TRUE; } else if (!bBoxBoundingVolume) { /* if there is a BV Sphere, seek an intersect between the sphere and the axe*/ bIntersect = fn_bDetectIntersectSegmentWithBoundingSphere(HIE_fn_hGetSuperObjectGlobalMatrix(_hSprObj), p_stVertexA, p_stVectAB, hBoundingSphere); } else { /*if there is a BV Box, seek an intersect between the box and the axe */ bIntersect = INT_fn_bDetectIntersectSegmentWithBox(p_stVertexA, p_stVectAB, &stMinPoint, &stMaxPoint,NULL); } if(bIntersect) { lType = HIE_fn_ulGetSuperObjectType(_hSprObj); #ifndef U64 /* no editor objects on u64*/ if( lType & (HIE_C_ulEDT_Geometric | HIE_C_ulMirror )) { hSentObject = (ACP_tdxHandleOfObject)HIE_fn_hGetSuperObjectObject(_hSprObj); } else #endif if( lType & (HIE_C_ulPO | HIE_C_ulPO_Mirror)) { hSentObject = M_hGetRepositionZoneFromPo((PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj)); } #ifndef D_THROW_IPO else if( lType & (HIE_C_ulIPO | HIE_C_ulIPO_Mirror)) { hSentObject = M_hGetRepositionZoneFromPo(IPO_fn_hGetPhysicalObject((IPO_tdxHandleToInstanciatedPhysicalObject)HIE_fn_hGetSuperObjectObject(_hSprObj))); } #endif /* D_THROW_IPO */ else if (lType == HIE_C_ulActor) { hSentObject = fn_hMakeOneObjectFromManyZdx(C_ucTypeZdr,_hSprObj); } if (hSentObject) { /*Convertion local coordinate system.*/ if (HIE_fn_SO_bHasNoTransformationMatrix (_hSprObj)) { /* Only translation, compute A i local*/ MTH3D_M_vSubVector (&stVertexALocal , p_stVertexA , p_stTranslation); /* and nothing for the vector AB...*/ MTH3D_M_vCopyVector(&stVectAB,p_stVectAB); } else { POS_fn_vInvertMatrix(&stInvMatrix,_hSprObj->hGlobalMatrix); /* compute A in local coordinates*/ POS_fn_vMulMatrixVertex(&stVertexALocal,&stInvMatrix, p_stVertexA); /* compute AB in local coordinates*/ POS_fn_vMulMatrixVector(&stVectAB, &stInvMatrix, p_stVectAB); } /* * Intersection test. */ if( INT_fn_bDetectIntersectSegmentWithFaceOfGeometricObject(&stVertexALocal, &stVectAB, hSentObject)) { return TRUE; } } } if (bIntersect || HIE_fn_SO_bCheckChildren(_hSprObj)) { /* keep going on the sons of this SO, only if they are not actors */ HIE_M_ForEachChildOf(_hSprObj, hChild, i) { if( (HIE_fn_ulGetSuperObjectType(hChild) != HIE_C_ulActor) && (HIE_bDetectIntersectSegmentWithSuperObject(p_stVertexA,p_stVectAB,hChild)) ) { return TRUE; } } } return FALSE; } /* *================================================================================================= *================================================================================================= */