/* *======================================================================================= * Name : MecBase.c * Author : J Thénoz Date : 01/05/98 * Description : Mechanic functions for Base model *======================================================================================= */ /*FB030898*/ #define HIE_FRIEND /*END FB*/ #include "cpa_expt.h" #include "ACP_Base.h" #include "MEC/MECInc.h" #include "MEC/DnmDynam.h" #include "MEC/ParsData.h" #include "MEC/DNMSurSt.h" #include "MEC/mbase.h" #include "Extheade.h" #include "COL.h" #include "MEC/MecDef.h" #include "MEC/MECOpt.h" #include "MEC/MECBhv.h" #include "MEC/MECCol.h" #include "MEC/MECPfm.h" #include "MEC/MECTools.h" #include "PCS.h" /* Physical Collide Set */ #include "SCT.h" /* SeCTor*/ #include "FIL.h" /* SeCTor*/ #include "PRT.h" /* PaRTicules*/ #include "GAM.h" /* GAMe*/ /* global */ MTH_tdxReal MEC_g_xClimbSpeedLimit = MTH_M_xDoubleToReal(0.7); MTH_tdxReal MEC_g_xBaseCoeff = C_xDNM_BASE_COEF; MTH_tdxReal MEC_g_xWalkCoeff = C_xDNM_WALK_COEF; extern POS_tdstCompletePosition * POS_g_p_stIdentityMatrix; extern long g_lCallCounter; extern ACP_tdxBool g_bHighSpeed; /* internal functions */ long MEC_fn_lComputeCall ( struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, MTH_tdxReal xDT, MTH_tdxReal xCoef ) { long lNbFrame, lCall; POS_tdxHandleToPosition hPreviousMatrix, hCurrentMatrix; MTH3D_tdstVector *p_stPreviousPosition, *p_stCurrentPosition; MTH3D_tdstVector stVector; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); hPreviousMatrix = DNM_M_p_stDynamicsGetPreviousMatrix (p_stDynamic); p_stPreviousPosition = POS_fn_p_stGetTranslationVector ( hPreviousMatrix ); p_stCurrentPosition = POS_fn_p_stGetTranslationVector ( hCurrentMatrix ); MTH3D_M_vSubVector ( &stVector, p_stCurrentPosition, p_stPreviousPosition ); if ((fn_ulStandardGameGetCustomBitsSO(hSupObj) & C_ulDNM_RAYMAN_CUSTOM_BIT) == C_ulDNM_RAYMAN_CUSTOM_BIT) lCall = MTH_M_xRealToLong (MTH_M_xAdd( MTH_M_xMul(MTH_M_xDiv(MTH3D_M_xNormVector(&stVector),C_ulDNM_RAYMAN_ZDM_RADIUS),xCoef) ,MTH_C_ONE)); else { lNbFrame = MTH_M_xRealToLong (MTH_M_xAdd(MTH_M_xDiv (xDT,M_xGetFrameLength(g_stEngineStructure.stEngineTimer)),MTH_C_Inv2)); lCall = 1; if (lNbFrame>4 && MTH_M_bGreater(MTH3D_M_xNormVector(&stVector),MTH_C_Inv2) ) lCall = 2; } return lCall; } void MEC_fn_vBaseManager ( struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, MTH_tdxReal xDT ) { long lCall, lCounter; if ( DNM_M_bDynamicsIsDontUseNewMechanic(p_stDynamic) || MTH_M_bEqualZero(MEC_g_xBaseCoeff) ) MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); else { lCall = MEC_fn_lComputeCall ( p_stDynamic, hSupObj, xDT, MEC_g_xBaseCoeff ); MEC_fn_vSlowMode (p_stDynamic,lCall); MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); for (lCounter=1; lCounterstRotationMatrix), DNM_M_p_stDynamicsGetImposeRotationMatrix(p_stDynamic) ); /* init collision counter */ if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { if ( DNM_M_cDynamicsGetCollideCounter(p_stDynamic) <= 0 ) DNM_M_vDynamicsSetCollideCounter ( p_stDynamic, fn_ucCollSetGetCollComputeFrequencySO(hSupObj) ); } /* shoot mechanic */ if (DNM_M_bDynamicsIsShoot (p_stDynamic)) { bImposeRotation = DNM_M_bDynamicsIsImposeRotation(p_stDynamic); /* shoot mechanic */ MTH3D_M_vMulScalarVector ( &stVector, xDT, DNM_M_pDynamicsGetPreviousSpeed ( p_stDynamic ) ); MEC_fn_vSetInitialFrameTranslation ( p_stDynamic, &stVector ); POS_fn_vCopyMatrix ( hPreviousReferenceMatrix, hPreviousMatrix ); /* Impose speed ? */ if (DNM_M_bDynamicsIsImposeSpeed(p_stDynamic)) { MEC_fn_vImposeSpeed (p_stDynamic,xDT,hRefMatrix,hInvRefMatrix); DNM_M_vDynamicsSetImposeSpeedX ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeSpeedY ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeSpeedZ ( p_stDynamic, FALSE ); } /* Impose rotation ? */ if ( bImposeRotation ) { MEC_fn_vImposeRotation (p_stDynamic); DNM_M_vDynamicsSetImposeRotation ( p_stDynamic, FALSE ); } if (DNM_M_bDynamicsIsCollide(p_stDynamic)) { if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { DNM_M_vDynamicsDecCollideCounter (p_stDynamic); if ( DNM_M_cDynamicsGetCollideCounter (p_stDynamic)==0 ) { // MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); MEC_fn_vBaseManager ( p_stDynamic, hSupObj, xDT ); if (fn_ucCollSetGetCollComputeFrequencySO(hSupObj)>1) MEC_fn_vRegisterCollisionTranslation (p_stDynamic,hCurrentMatrix); } } // else MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); else MEC_fn_vBaseManager ( p_stDynamic, hSupObj, xDT ); } MEC_fn_vComputeSpeed ( p_stDynamic, xDT ); /* adjust matrix to get scale */ MEC_fn_vCorrectMatrix ( p_stDynamic, hCurrentMatrix ); if(!MEC_fn_bIsEqualMatrix (hGlobalMatrix,hCurrentMatrix)) { POS_fn_vCopyMatrix ( hGlobalMatrix, hCurrentMatrix ); HIE_fn_vComputeNewRelativeMatrix (hSupObj); } /* platform and pushed objects update */ if ( fn_bStandardGameIsAPlatform(hSupObj) ) { if(!MEC_fn_bIsEqualMatrix (hPreviousMatrix,hCurrentMatrix)) { HIE_fn_vRefreshHierarchy (hSupObj); /* invert matrix only if usefull */ if (bImposeRotation) { hInvPreviousReferenceMatrix = (POS_tdxHandleToPosition)&stInvPreviousReferenceMatrix; POS_fn_vInvertMatrix (hInvPreviousReferenceMatrix,hPreviousReferenceMatrix); } else { MEC_fn_vInvertMatrix (p_stDynamic,hInvRefMatrix,hRefMatrix); hInvPreviousReferenceMatrix = hInvRefMatrix; } MEC_fn_vUpdatePlatform (p_stDynamic,hSupObj, hPreviousReferenceMatrix, hInvPreviousReferenceMatrix); } } else if ( (fn_ulStandardGameGetCustomBitsSO(hSupObj) & C_ulDNM_COMPUTE_CHANNEL) && !MEC_fn_bIsEqualMatrix (hPreviousMatrix,hCurrentMatrix)) { HIE_fn_vRefreshHierarchy (hSupObj); } MEC_fn_vInitMatrix (p_stDynamic); MEC_fn_vFillCollisionReport (p_stDynamic); return p_stDynamic; } /* number of frame */ lNbFrame = MTH_M_xRealToLong (MTH_M_xAdd(MTH_M_xDiv (xDT,M_xGetFrameLength(g_stEngineStructure.stEngineTimer)),MTH_C_Inv2)); /* stable position */ POS_fn_vGetTranslationVector ( hPreviousMatrix, &stStablePreviousPosition ); /* copy previous reference */ POS_fn_vCopyMatrix ( hPreviousReferenceMatrix, hPreviousMatrix ); if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) POS_fn_vCopyMatrix ( hPrevPreviousReferenceMatrix, hPrevPreviousMatrix ); /* reset platform crash */ DNM_M_bDynamicsSetPlatformCrash (p_stDynamic,FALSE); DNM_M_bDynamicsSetCanFall (p_stDynamic,FALSE); if ( DNM_M_bDynamicsIsScale(p_stDynamic) && MEC_fn_bIsScale(p_stDynamic) ) MEC_fn_vAdjustScaleData (p_stDynamic,hRefMatrix,hInvRefMatrix); MTH3D_M_vMulScalarVector ( DNM_M_p_stDynamicsGetSpeedAnim(p_stDynamic), M_xGetFrameLength(g_stEngineStructure.stEngineTimer), DNM_M_p_stDynamicsGetSpeedAnim(p_stDynamic) ); POS_fn_vRotateVector ( DNM_M_p_stDynamicsGetSpeedAnim(p_stDynamic), hCurrentMatrix, DNM_M_p_stDynamicsGetSpeedAnim(p_stDynamic) ); /* init frame */ MTH3D_M_vDivScalarVector (DNM_M_pDynamicsGetAddTranslation(p_stDynamic),DNM_M_pDynamicsGetAddTranslation(p_stDynamic), MTH_M_xDoubleToReal(lNbFrame)); /* translate matrix on */ MEC_fn_vTranslateMatrixOn (p_stDynamic,&stMatrixTranslation); for (lFrame=0; lFrame previous */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) POS_fn_vCopyMatrix ( hPrevPreviousMatrix, hPreviousMatrix ); POS_fn_vCopyMatrix ( hPreviousMatrix, hCurrentMatrix ); /* optimisation */ if ( MTH3D_M_bIsNullVector (DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic)) ) lFrame=lNbFrame; } /* restore values */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) POS_fn_vCopyMatrix ( hPrevPreviousMatrix, hPrevPreviousReferenceMatrix ); POS_fn_vCopyMatrix ( hPreviousMatrix, hPreviousReferenceMatrix ); /* translate matrix off */ MEC_fn_vTranslateMatrixOff (p_stDynamic,&stMatrixTranslation); /* adjust speed */ MEC_fn_vAdjustSpeed (p_stDynamic, xDT); /* Tilt */ if (DNM_M_bDynamicsIsTilt(p_stDynamic)) MEC_fn_vAddTiltSpeed (p_stDynamic,xDT); /* need to collide ? */ bNeedToCollide = MEC_fn_bDynamicsNeedCollide(p_stDynamic); /* platform ? */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) bPlatform = MEC_fn_bIsPlatform(p_stDynamic); DNM_M_vDynamicsSetNoGravity (p_stDynamic,FALSE); if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { /* dec collision counter */ DNM_M_vDynamicsDecCollideCounter (p_stDynamic); /* Obstacle part */ if (DNM_M_cDynamicsGetCollideCounter (p_stDynamic)==0) { if ( bNeedToCollide || bPlatform || fn_bGetCharacterForceCollisionWhenNotMoving(hSupObj) ) { if (DNM_M_bDynamicsIsGi (p_stDynamic)) MEC_fn_vGiObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsClimb (p_stDynamic)) { MEC_fn_vClimbObstacleManagement ( p_stDynamic, hSupObj, xDT ); /* if actor moves just a little, actor don't move at all.*/ if (MTH_M_bLess ( MTH3D_M_xNormVector(DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic)), MEC_g_xClimbSpeedLimit )) { MTH3D_M_vCopyVector ( POS_fn_p_stGetTranslationVector(hCurrentMatrix), POS_fn_p_stGetTranslationVector(hPreviousMatrix) ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic) ); } } // else if (DNM_M_bDynamicsIsOnGround (p_stDynamic)) MEC_fn_vGroundObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsOnGround (p_stDynamic)) MEC_fn_vWalkManager ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsSpider (p_stDynamic)) MEC_fn_vSpiderObstacleManagement ( p_stDynamic, hSupObj, xDT ); // else if (DNM_M_bDynamicsIsCollide(p_stDynamic)) MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsCollide(p_stDynamic)) MEC_fn_vBaseManager ( p_stDynamic, hSupObj, xDT ); } /* else*/ /* {*/ /* collide only with other actors */ /* if (fn_bGetCharacterForceCollisionWhenNotMoving(hSupObj))*/ /* {*/ /* ACP_tdxBool bCollisionState;*/ /* bCollisionState = fn_bGetCharacterNoCollisionWithMap (hSupObj);*/ /* fn_vSetCharacterNoCollisionWithMap (hSupObj,TRUE);*/ /* if (MEC_fn_bInCollision(p_stDynamic,hSupObj) && !bCollisionState)*/ /* {*/ /* fn_vSetCharacterNoCollisionWithMap (hSupObj,bCollisionState);*/ /* if (DNM_M_bDynamicsIsGi (p_stDynamic)) MEC_fn_vGiObstacleManagement ( p_stDynamic, hSupObj, xDT );*/ /* else if (DNM_M_bDynamicsIsClimb (p_stDynamic)) MEC_fn_vClimbObstacleManagement ( p_stDynamic, hSupObj, xDT );*/ /* else if ((p_stDynamic)) MEC_fn_vGroundObstacleManagement ( p_stDynamic, hSupObj, xDT, FALSE );*/ /* else if (DNM_M_bDynamicsIsCollide(p_stDynamic)) MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT );*/ /* }*/ /* else*/ /* {*/ /* fn_vSetCharacterNoCollisionWithMap (hSupObj,bCollisionState);*/ /* DNM_M_ulReportSetSurfaceState ( p_stReport, DNM_M_ulReportGetPrevSurfaceState (p_stReport) );*/ /* }*/ /* }*/ /* }*/ /* bCollide = TRUE;*/ /* register collision */ if (fn_ucCollSetGetCollComputeFrequencySO(hSupObj)>1) MEC_fn_vRegisterCollisionTranslation (p_stDynamic,hCurrentMatrix); } else { if (DNM_M_bDynamicsIsOnGround (p_stDynamic)) MEC_fn_vGroundGuess (p_stDynamic,xDT); if (DNM_M_bDynamicsIsCollisionReport(p_stDynamic)) /* current collision state = previous one */ DNM_M_ulReportSetSurfaceState ( p_stReport, DNM_M_ulReportGetPrevSurfaceState (p_stReport) ); } } else /* no advanced mechanic so collide every frame */ { if ( bNeedToCollide || fn_bGetCharacterForceCollisionWhenNotMoving(hSupObj) ) { if (DNM_M_bDynamicsIsGi (p_stDynamic)) MEC_fn_vGiObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsClimb (p_stDynamic)) { MEC_fn_vClimbObstacleManagement ( p_stDynamic, hSupObj, xDT ); /* if actor moves just a little, actor don't move at all.*/ if (MTH_M_bLess ( MTH3D_M_xNormVector(DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic)), MEC_g_xClimbSpeedLimit )) { MTH3D_M_vCopyVector ( POS_fn_p_stGetTranslationVector(hCurrentMatrix), POS_fn_p_stGetTranslationVector(hPreviousMatrix) ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic) ); } } // else if (DNM_M_bDynamicsIsOnGround (p_stDynamic)) MEC_fn_vGroundObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsOnGround (p_stDynamic)) MEC_fn_vWalkManager ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsSpider (p_stDynamic)) MEC_fn_vSpiderObstacleManagement ( p_stDynamic, hSupObj, xDT ); // else if (DNM_M_bDynamicsIsCollide(p_stDynamic)) MEC_fn_vBaseObstacleManagement ( p_stDynamic, hSupObj, xDT ); else if (DNM_M_bDynamicsIsCollide(p_stDynamic)) MEC_fn_vBaseManager ( p_stDynamic, hSupObj, xDT ); } } /* check position limit */ MEC_fn_vPositionLimit ( p_stDynamic, &stStablePreviousPosition ); /* Platform Management */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) bPlatformChange = MEC_fn_vBasePlatformManagement ( p_stDynamic, hSupObj ); /* correct scale */ MEC_fn_vCorrectMatrix ( p_stDynamic, hCurrentMatrix ); /* speed */ p_stCurrentTranslation = POS_fn_p_stGetTranslationVector (hCurrentMatrix); /* XB 05/05/99 : move the following line 7 lines after */ /* p_stAbsolutePreviousTranslation = POS_fn_p_stGetTranslationVector (hAbsolutePreviousMatrix); */ /* End XB 05/05/99 */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic) && DNM_M_bDynamicsIsCollisionReport(p_stDynamic)) { /* XB 05/05/99 */ p_stAbsolutePreviousTranslation = POS_fn_p_stGetTranslationVector (hAbsolutePreviousMatrix); /* End XB 05/05/99 */ /* absolute speed */ MTH3D_M_vSubVector (&stSpeed,p_stCurrentTranslation,p_stAbsolutePreviousTranslation); MTH3D_M_vDivScalarVector (&stSpeed, &stSpeed, xDT); /* Update Dynamic Report speed linear -> to keep speed variable in IA */ /* to CB's camera */ POS_fn_vGetRotationVector ( hAbsolutePreviousMatrix, &p_stPreviousX, &p_stPreviousY, &p_stPreviousZ ); /* XB 05/05/99 : unused !!!! */ /* check |xDotProd|<=1 */ /* xDotProd = MTH_M_xMin ( MTH_M_xMax ( xDotProd, MTH_C_MinusONE ), MTH_C_ONE ); */ /* End XB 05/05/99 */ /* keep Y of hAbsolutePreviousMatrix in &stMove */ /* will be used to update real angular position if required by camera */ MTH_M_MoveSetAngularPosition ( &stMove, MTH_C_ONE, p_stPreviousY ); MTH_M_MoveSetLinear ( &stMove, &stSpeed ); DNM_M_ReportSetAbsoluteCurrSpeed ( DNM_M_p_stDynamicsGetReport (p_stDynamic), &stMove ); } /* Update Gli position */ if(!MEC_fn_bIsEqualMatrix (hGlobalMatrix,hCurrentMatrix) || bPlatformChange) { POS_fn_vCopyMatrix ( hGlobalMatrix, hCurrentMatrix ); HIE_fn_vComputeNewRelativeMatrix (hSupObj); DNM_M_vDynamicsSetActorMove (p_stDynamic,TRUE); } /* platform and pushed objects update */ if ( fn_bStandardGameIsAPlatform(hSupObj) ) { if(!MEC_fn_bIsEqualMatrix (hPreviousMatrix,hCurrentMatrix)) { HIE_fn_vRefreshHierarchy (hSupObj); /* invert matrix only if usefull */ if (DNM_M_bDynamicsIsImposeRotation(p_stDynamic)) { hInvPreviousReferenceMatrix = (POS_tdxHandleToPosition)&stInvPreviousReferenceMatrix; POS_fn_vInvertMatrix (hInvPreviousReferenceMatrix,hPreviousReferenceMatrix); } else { MEC_fn_vInvertMatrix (p_stDynamic,hInvRefMatrix,hRefMatrix); hInvPreviousReferenceMatrix = hInvRefMatrix; } MEC_fn_vUpdatePlatform (p_stDynamic,hSupObj, hPreviousReferenceMatrix, hInvPreviousReferenceMatrix); } } else if ( (fn_ulStandardGameGetCustomBitsSO(hSupObj) & C_ulDNM_COMPUTE_CHANNEL) && !MEC_fn_bIsEqualMatrix (hPreviousMatrix,hCurrentMatrix)) { HIE_fn_vRefreshHierarchy (hSupObj); } /* Update Matrix */ MEC_fn_vInitMatrix (p_stDynamic); /* Update Dynamic Report position linear -> to keep position varaiable in IA */ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic) && DNM_M_bDynamicsIsCollisionReport(p_stDynamic)) { MTH3D_M_vCopyVector ( &stVector, p_stCurrentTranslation ); MTH_M_MoveSetAngularToNull ( &stMove ); MTH_M_MoveSetLinear ( &stMove, &stVector ); DNM_M_ReportSetAbsoluteCurrPosition (DNM_M_p_stDynamicsGetReport (p_stDynamic),&stMove); } MEC_fn_vFillCollisionReport (p_stDynamic); /* Update report state */ if (DNM_M_bDynamicsIsCollisionReport(p_stDynamic)) DNM_M_ulReportSetPrevSurfaceState ( p_stReport, DNM_M_ulReportGetSurfaceState (p_stReport) ); /* update Nb Frame */ DNM_M_vDynamicsSetNbFrame ( p_stDynamic, (unsigned char)lNbFrame ); /* End */ MTH3D_M_vNullVector ( DNM_M_pDynamicsGetImposeSpeed (p_stDynamic) ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetProposeSpeed (p_stDynamic) ); MTH3D_M_vNullVector ( DNM_M_p_stDynamicsGetSpeedAnim(p_stDynamic) ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetAddTranslation(p_stDynamic) ); DNM_M_bDynamicsSetAbsoluteImposeSpeed ( p_stDynamic, FALSE ); DNM_M_bDynamicsSetAbsoluteProposeSpeed ( p_stDynamic, FALSE ); DNM_M_bDynamicsSetAbsoluteAddSpeed ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeSpeedX ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeSpeedY ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeSpeedZ ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetProposeSpeedX ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetProposeSpeedY ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetProposeSpeedZ ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetAddSpeedX ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetAddSpeedY ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetAddSpeedZ ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeRotation ( p_stDynamic, FALSE ); DNM_M_vDynamicsSetImposeTranslation ( p_stDynamic, FALSE ); DNM_M_bDynamicsSetMechanicChange( p_stDynamic,FALSE); DNM_M_vDynamicsSetChangeScale( p_stDynamic, FALSE ); /* reset coeff */ MEC_g_xBaseCoeff = C_xDNM_BASE_COEF; MEC_g_xWalkCoeff = C_xDNM_WALK_COEF; if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { p_stObstacle = DNM_M_p_stReportGetObstacle (&g_stReport); if ( p_stObstacle && ((DNM_M_ulReportGetSurfaceState(&g_stReport))!=C_WOT_ulNoObstacle) ) DNM_M_vDynamicsSetPreviousSlide(p_stDynamic,MEC_fn_xGetSlide (p_stDynamic,p_stObstacle)); else DNM_M_vDynamicsSetPreviousSlide(p_stDynamic,MTH_C_ZERO); } p_stObstacle = DNM_M_p_stReportGetGround(&g_stReport); if ( p_stObstacle && ((DNM_M_ulReportGetSurfaceState(&g_stReport)&C_WOT_ulGround)==C_WOT_ulGround) && MTH_M_bDifferent(MEC_fn_xGetSlide (p_stDynamic,p_stObstacle),MTH_C_ZERO) ) DNM_M_vDynamicsSetSlidingGround(p_stDynamic,TRUE); else DNM_M_vDynamicsSetSlidingGround(p_stDynamic,FALSE); if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { MTH3D_M_vNullVector ( DNM_M_pDynamicsGetAddSpeed (p_stDynamic) ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetStreamSpeed (p_stDynamic) ); } return p_stDynamic; } /* Impose rotation matrix */ void MEC_vImposeRotationMatrix ( struct DNM_stDynamics *p_stDynamic, POS_tdxHandleToPosition hRotationMatrix ) { POS_tdxHandleToPosition hCurrentMatrix; MTH3D_tdstVector *p_stCurrentTranslation, *p_stMatrixTranslation; MTH3D_tdstVector stMove; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); /* impose rotation */ DNM_M_vDynamicsSetImposeRotation (p_stDynamic,TRUE); DNM_M_vDynamicsSetImposeRotationMatrix (p_stDynamic,&(hRotationMatrix->stRotationMatrix)); /* translation without rotation */ p_stCurrentTranslation = POS_fn_p_stGetTranslationVector ( hCurrentMatrix ); p_stMatrixTranslation = POS_fn_p_stGetTranslationVector ( hRotationMatrix ); MTH3D_M_vSubVector (&stMove,p_stMatrixTranslation,p_stCurrentTranslation); DNM_M_vDynamicsSetAddTranslation (p_stDynamic,&stMove); if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) MEC_fn_vCancelTilt (p_stDynamic); } void MEC_vImposeRotationVector ( struct DNM_stDynamics *p_stDynamic, MTH3D_tdstVector *p_stX, MTH3D_tdstVector *p_stY, MTH3D_tdstVector *p_stZ ) { MTH3D_tdstMatrix* p_stImposeRotationMatrix; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; p_stImposeRotationMatrix = DNM_M_p_stDynamicsGetImposeRotationMatrix (p_stDynamic); MTH3D_M_vSetVectorsInMatrix( p_stImposeRotationMatrix, p_stX, p_stY, p_stZ); /* impose rotation */ DNM_M_vDynamicsSetImposeRotation (p_stDynamic,TRUE); } /* Impose relative rotation */ void MEC_vImposeRelativeRotation ( struct DNM_stDynamics *p_stDynamic, MTH3D_tdstMatrix *p_stRotationMatrix ) { MTH3D_tdstVector *p_stI, *p_stJ, *p_stK; MTH3D_tdstMatrix stMatrix; POS_tdxHandleToPosition hCurrentMatrix; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); POS_fn_vGetRotationVector ( hCurrentMatrix, &p_stI, &p_stJ, &p_stK ); MTH3D_M_vSetVectorsInMatrix ( &stMatrix, p_stI, p_stJ, p_stK ); MTH3D_M_vMulMatrixMatrix ( &stMatrix, &stMatrix, p_stRotationMatrix ); MTH3D_M_vGetVectorsInMatrix ( p_stI, p_stJ, p_stK, &stMatrix ); MEC_fn_vUpdateMatrix (p_stDynamic,hCurrentMatrix); if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) MEC_fn_vCancelTilt (p_stDynamic); } /* Impose absolute translation */ void MEC_vImposeTranslation ( struct DNM_stDynamics *p_stDynamic, MTH3D_tdstVector* p_stVector ) { MTH3D_tdstVector stVector; MTH3D_tdstVector* p_stCurrentTranslation; POS_tdxHandleToPosition hCurrentMatrix; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; DNM_M_vDynamicsSetImposeTranslation ( p_stDynamic, TRUE ); hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); p_stCurrentTranslation = POS_fn_p_stGetTranslationVector (hCurrentMatrix); MTH3D_M_vSubVector ( &stVector, p_stVector, p_stCurrentTranslation ); DNM_M_vDynamicsSetAddTranslation (p_stDynamic,&stVector); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic) ); } /* Init translation */ void MEC_vInitTranslation ( struct DNM_stDynamics *p_stDynamic, HIE_tdxHandleToSuperObject hSupObj, MTH3D_tdstVector* p_stVector ) { POS_tdxHandleToPosition hCurrentMatrix, hPreviousMatrix, hAbsolutePreviousMatrix, hPrevPreviousMatrix, hGlobalMatrix; if (DNM_M_bDynamicsIsInit(p_stDynamic)) { hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (hSupObj); POS_fn_vSetTranslationVector (hGlobalMatrix,p_stVector); } else { /*--- Base ---*/ hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); hPreviousMatrix = DNM_M_p_stDynamicsGetPreviousMatrix (p_stDynamic); hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (hSupObj); POS_fn_vSetTranslationVector (hCurrentMatrix,p_stVector); POS_fn_vSetTranslationVector (hPreviousMatrix,p_stVector); POS_fn_vCopyMatrix ( hGlobalMatrix, hCurrentMatrix ); /*--- Complex ---*/ if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) { hAbsolutePreviousMatrix = DNM_M_p_stDynamicsGetAbsolutePreviousMatrix (p_stDynamic); hPrevPreviousMatrix = DNM_M_p_stDynamicsGetPrevPreviousMatrix (p_stDynamic); POS_fn_vSetTranslationVector (hAbsolutePreviousMatrix,p_stVector); POS_fn_vSetTranslationVector (hPrevPreviousMatrix,p_stVector); } } HIE_fn_vComputeNewRelativeMatrix (hSupObj); /* reset data */ /*--- Base ---*/ MTH3D_M_vNullVector (DNM_M_pDynamicsGetPreviousSpeed (p_stDynamic)); MTH3D_M_vNullVector (DNM_M_pDynamicsGetAddTranslation(p_stDynamic)); /*--- Advanced ---*/ if (DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) { MTH3D_M_vNullVector (DNM_M_pDynamicsGetInertiaTranslation(p_stDynamic)); } } void MEC_fn_vImposeActorMatrix ( HIE_tdxHandleToSuperObject hSupObj ) { POS_tdxHandleToPosition hCurrentMatrix, hPreviousMatrix, hAbsolutePreviousMatrix, hPrevPreviousMatrix, hGlobalMatrix; struct DNM_stDynamics *p_stDynamic; p_stDynamic = fn_p_stDynamGetDynamicsSO (hSupObj); if (!p_stDynamic) return; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); hPreviousMatrix = DNM_M_p_stDynamicsGetPreviousMatrix (p_stDynamic); hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (hSupObj); POS_fn_vCopyMatrix ( hCurrentMatrix, hGlobalMatrix ); POS_fn_vCopyMatrix ( hPreviousMatrix, hGlobalMatrix ); MTH3D_M_vNullVector ( DNM_M_pDynamicsGetPreviousSpeed(p_stDynamic) ); DNM_M_vDynamicsSetActorMove (p_stDynamic,TRUE); if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) { hAbsolutePreviousMatrix = DNM_M_p_stDynamicsGetAbsolutePreviousMatrix (p_stDynamic); hPrevPreviousMatrix = DNM_M_p_stDynamicsGetPrevPreviousMatrix (p_stDynamic); POS_fn_vCopyMatrix ( hAbsolutePreviousMatrix, hGlobalMatrix ); POS_fn_vCopyMatrix ( hPrevPreviousMatrix, hGlobalMatrix ); } } void MEC_vTurnAroundZAxis ( struct DNM_stDynamics *p_stDynamic, MTH_tdxReal xAngle ) { POS_tdxHandleToPosition hCurrentMatrix; MTH3D_tdstVector stVectorZ; MTH3D_tdstVector stMove; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; if (MTH_M_bIsNull(xAngle)) return; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); if (DNM_M_bDynamicsIsTilt(p_stDynamic)) { MTH3D_tdstVector stI, stJ, stK; MTH_tdxReal xCos, xSin; POS_tdxHandleToPosition hMatrix; POS_tdstCompletePosition stMatrix; hMatrix = &stMatrix; xCos = MTH_M_xCos ( xAngle ); xSin = MTH_M_xSin ( xAngle ); /*FB030898*/ /*POS_fn_vGetTranslationVector ( hCurrentMatrix, &stMove );*/ MTH3D_M_vCopyVector(&stMove, &(hCurrentMatrix->stTranslationVector) ); /*END FB*/ /*FB030898*/ /*POS_fn_vSetIdentityMatrix ( hMatrix );*/ POS_fn_vCopyMatrix(hMatrix, (POS_tdstCompletePosition *) POS_g_p_stIdentityMatrix); /*END FB*/ MTH3D_M_vSetVectorElements ( &stI, xCos, xSin, MTH_C_ZERO ); MTH3D_M_vSetVectorElements ( &stJ, MTH_M_xNeg(xSin), xCos, MTH_C_ZERO ); MTH3D_M_vSetBaseKVector ( &stK ); POS_fn_vSetRotationMatrix ( hMatrix, &stI, &stJ, &stK ); POS_fn_vMulMatrixMatrix ( hCurrentMatrix, hMatrix, hCurrentMatrix ); /*FB030898*/ /*POS_fn_vSetTranslationVector ( hCurrentMatrix, &stMove );*/ MTH3D_M_vCopyVector( &(hCurrentMatrix->stTranslationVector), &stMove ); /*END FB*/ return; } /*FB030898*/ /*POS_fn_vGetTranslationVector ( hCurrentMatrix, &stMove );*/ MTH3D_M_vCopyVector(&stMove, &(hCurrentMatrix->stTranslationVector) ); /*END FB*/ MTH3D_M_vSetVectorElements ( &stVectorZ, MTH_C_ZERO, MTH_C_ZERO, MTH_C_MinusONE ); POS_fn_vRotatePositionAroundAxis (hCurrentMatrix, &stVectorZ, xAngle); /*FB030898*/ /*POS_fn_vSetTranslationVector ( hCurrentMatrix, &stMove );*/ MTH3D_M_vCopyVector( &(hCurrentMatrix->stTranslationVector), &stMove ); /*END FB*/ } void MEC_vTurnAbsolute ( struct DNM_stDynamics *p_stDynamic, MTH3D_tdstVector* p_stVector ) { POS_tdxHandleToPosition hCurrentMatrix; MTH3D_tdstVector *p_stI, *p_stJ, *p_stK; if (DNM_M_bDynamicsIsInit(p_stDynamic)) return; if (MTH3D_M_bIsNullVector(p_stVector)) return; hCurrentMatrix = DNM_M_p_stDynamicsGetCurrentMatrix (p_stDynamic); POS_fn_vGetRotationVector (hCurrentMatrix,&p_stI,&p_stJ,&p_stK); MTH3D_M_vNormalizeVector ( p_stJ,p_stVector); MTH3D_M_vNegVector ( p_stJ, p_stJ ); MTH3D_M_vCrossProductVector (p_stI,p_stJ,p_stK); MTH3D_M_vCrossProductVector (p_stJ,p_stK,p_stI); MEC_fn_vUpdateMatrix ( p_stDynamic, hCurrentMatrix ); if (DNM_M_bDynamicsIsComplexSize(p_stDynamic)) MEC_fn_vCancelTilt (p_stDynamic); } void DNM_fn_vSetHangingLimit ( struct DNM_stDynamics *p_stDynamic, MTH_tdxReal xValue ) { if (MEC_fn_bIsPlatform(p_stDynamic)) DNM_M_vDynamicsSetHangingLimit (p_stDynamic,MTH_M_xSub ( xValue, MTH3D_M_xGetZofVector(POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(DNM_M_hDynamicsGetPlatformSO(p_stDynamic)))) ) ); else DNM_M_vDynamicsSetHangingLimit (p_stDynamic,xValue); } /* Update speed for camera */ void MEC_fn_vUpdateSpeed (HIE_tdxHandleToSuperObject hSupObj) { MS_tdxHandleToDynam h_Dynam; struct DNM_stDynamics *p_stDynamic; MTH3D_tdstVector *p_stSpeed; POS_tdxHandleToPosition hPreviousMatrix; MTH3D_tdstVector *p_stCurrentX, *p_stCurrentY, *p_stCurrentZ; MTH3D_tdstVector stPreviousY; MTH3D_tdstVector stAxis; MTH3D_tdstVector stCrossProduct; MTH_tdstMove* p_stMove; MTH_tdxReal xDotProd, xAngle; h_Dynam = M_GetMSHandle(hSupObj,Dynam); if (!h_Dynam) return; p_stDynamic = fn_p_stDynamGetDynamics(h_Dynam); if ( !DNM_M_bDynamicsIsComplexSize(p_stDynamic) || !DNM_M_bDynamicsIsCollisionReport(p_stDynamic) ) return; p_stSpeed = DNM_M_pDynamicsGetPreviousSpeed (p_stDynamic); hPreviousMatrix = DNM_M_p_stDynamicsGetPreviousMatrix (p_stDynamic); /* Update Dynamic Report speed linear -> to keep speed variable in IA */ /* to CB's camera */ POS_fn_vGetRotationVector ( hPreviousMatrix, &p_stCurrentX, &p_stCurrentY, &p_stCurrentZ ); p_stMove = DNM_M_p_stReportGetAbsoluteCurrSpeed ( DNM_M_p_stDynamicsGetReport (p_stDynamic) ); MTH3D_M_vCopyVector (&stPreviousY,MTH_M_p_stRotationGetAxis(MTH_M_p_stMoveGetAngular(p_stMove))); xDotProd = MTH3D_M_xDotProductVector (&stPreviousY,p_stCurrentY); MTH3D_M_vCrossProductVectorWithoutBuffer (&stCrossProduct, &stPreviousY, p_stCurrentY); /* check |xDotProd|<=1 */ xDotProd = MTH_M_xMin ( MTH_M_xMax ( xDotProd, MTH_C_MinusONE ), MTH_C_ONE ); if (MTH_M_bGreater(MTH3D_M_xGetZofVector(&stCrossProduct),MTH_C_ZERO)) xAngle = MTH_M_xACos (xDotProd); else xAngle = MTH_M_xNeg (MTH_M_xACos(xDotProd)); MTH3D_M_vSetBaseKVector (&stAxis); MTH_M_MoveSetAngularPosition ( p_stMove, xAngle, &stAxis ); }