/* ***********************************************************************************/ /* * "a3x_intn.c" **/ /* * Written by : Sébastien Rubens **/ /* * Tabulations : 4 char **/ /* ***********************************************************************************/ #define A3X_INTN_C /* ***********************************************************************************/ /* Included files*/ #include /*#define LST2_StaticIsOptimised*/ #include "ACP_Base.h" #include "cpa_std.h" #include "TOOLSCPA.h" #include "STRUCTUR/Anim_s.h" #define D_ObjsTbls_Define #include "STRUCTUR/ObjsTbls.h" #include "MTH.h" #include "POS.h" #include "PlayAnim/Interpol/specif/a3x_pref.h" #include "chanlist.h" #include "PlayAnim/Interpol/a3x_glob.h" #include "PlayAnim/Interpol/a3x_int.h" #include "PlayAnim/Interpol/a3x_intn.h" #include "PlayAnim/Interpol/a3x_mem.h" #include "PlayAnim/Interpol/a3x_cach.h" #include "PlayAnim/PlayEvts.h" /* for allocation*/ #include "ZeMem.h" #define M_Abs( x ) \ ( ((x) > xZero) ? (x) : -(x) ) /* temp*/ extern SEB_xReal xEps; extern SEB_xReal xOneSubEps; /*AR9902 To be cleaned...*/ extern tdstA3dHeader* p_stA3dHeaders; /* ***********************************************************************************/ void fn_v_InterpolBetweenKeys( tdstKeyFrame *_p_stKey1, tdstKeyFrame *_p_stKey2, tdstChannel *_p_stChannel, POS_tdxHandleToPosition _p_stCompletePosition, register unsigned short _uwInterpolated, register SEB_xReal _xT ) { tdxMatrix33 a3a3_xMtxOri, a3a3_xMtxTra; tdxVector3 a3_xPosition; static tdxQuater4 a4_xQuatI, a4_xQuatS1, a4_xQuatS2; static tdxMatrix33 a3a3_xMtxOriSca, a3a3_xMtxSca; static tdxVector3 a3_xVecSca; register SEB_xReal xSinOmega; register SEB_xReal xCoef1, xCoef2; /* register SEB_xReal xOmega, xCosOmega, xTbyOmega;*/ register tdxVector3 *p_Vect1, *p_Vect2; register signed short swOmega, swCosOmega, swTbyOmega; #ifdef ANIM_DEBUG if(_p_stCompletePosition==NULL) { osSyncPrintf("Position is null in fn_v_InterpolBetweenKeys\n"); ASM_BREAK; } #endif POS_fn_vSetIdentityMatrix(_p_stCompletePosition); MTH3D_M_vSetIdentityMatrix((MTH3D_tdstMatrix*)&a3a3_xMtxOri); MTH3D_M_vSetIdentityMatrix((MTH3D_tdstMatrix*)&a3a3_xMtxTra); MTH3D_M_vNullVector((MTH3D_tdstVector*)&a3_xPosition); /* -- Interpolation of orientation -------*/ if ( (_xT == xZero) || ((_p_stKey1->uwMask & SEB_xMaskQuatOri) != 0x0000) ) { /* We are on the first KeyFrame or we have a non interpolated quaternion*/ if ((_p_stKey1->uwMask & SEB_xMaskIdQuatOri) == 0x0000) { /* Copy of first (KeyFrame) quaternion*/ fn_v_ExpandQuat( a4_xQuatI, p_a4_xQuaternions[_p_stKey1->uwNumOfQuatOri] ); fn_v_QuatToMatrix( a3a3_xMtxOri, a4_xQuatI ); POS_fn_vSetRotationMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxOri[0], (MTH3D_tdstVector*)a3a3_xMtxOri[1] , (MTH3D_tdstVector*)a3a3_xMtxOri[2] ); } } else { /* Interpolation of orientation*/ fn_v_ExpandQuat( a4_xQuatS1, p_a4_xQuaternions[_p_stKey1->uwNumOfQuatOri] ); fn_v_ExpandQuat( a4_xQuatS2, p_a4_xQuaternions[_p_stKey2->uwNumOfQuatOri] ); fn_v_InterpolQuatWithOmega( a4_xQuatI, a4_xQuatS1, a4_xQuatS2, _xT, _p_stKey1->uwAngQuatOri ); fn_v_QuatToMatrix( a3a3_xMtxOri, a4_xQuatI ); POS_fn_vSetRotationMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxOri[0], (MTH3D_tdstVector*)a3a3_xMtxOri[1] , (MTH3D_tdstVector*)a3a3_xMtxOri[2] ); } /* -- Linear interpolation of ScaleValues -------*/ if ( ((_p_stKey1->uwMask & (SEB_xMaskScaleValues|SEB_xMaskIdScaleValues)) == (SEB_xMaskScaleValues|SEB_xMaskIdScaleValues)) || ((_xT==xZero) && ((_p_stKey1->uwMask & SEB_xMaskIdScaleValues) != 0x0000)) ) { /* Identity vector (we don't use scale)*/ MTH3D_M_vCopyMatrix((MTH3D_tdstMatrix*)&a3a3_xMtxTra,(MTH3D_tdstMatrix*)&a3a3_xMtxOri); } /*else we have a non "identity" scale vector*/ /* -- Interpolation of whole scale -------*/ /* -- and creation of TransformMatrix -------*/ else { /* Interpolated of ScaleValues*/ fn_v_InterpolVect( a3_xVecSca, p_a3_xVectors[_p_stKey1->uwNumOfScaleValues], p_a3_xVectors[_p_stKey2->uwNumOfScaleValues], _xT ); if ( (_xT == xZero) || ((_p_stKey1->uwMask & SEB_xMaskQuatSca) != 0x0000) ) { /* We are on the first KeyFrame or we have a non interpolated quaternion*/ if ((_p_stKey1->uwMask & SEB_xMaskIdQuatSca) != 0x0000) { /* Identity quaternion*/ /* Create final Transform matrix*/ /* Final matrix= [scale dir. matrix]*[values scale matrix]*[scale dir. matrix]^-1*/ if(MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[1],MTH_M_xFloatToReal(0.01)) && MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[2],MTH_M_xFloatToReal(0.01))) { POS_fn_vSetZoomMatrix( _p_stCompletePosition , (MTH_tdxReal)a3_xVecSca[0] ); POS_fn_vGetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } else { fn_v_MatrixByDia( a3a3_xMtxTra, a3a3_xMtxOri, a3_xVecSca ); POS_fn_vSetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } } else { /* Copy of first (KeyFrame) quaternion*/ fn_v_ExpandQuat( a4_xQuatI, p_a4_xQuaternions[_p_stKey1->uwNumOfQuatSca] ); fn_v_QuatToMatrix( a3a3_xMtxOriSca, a4_xQuatI ); /* Create final scale matrix*/ /* Final matrix= [scale dir. matrix]*[values scale matrix]*[scale dir. matrix]^-1*/ if(MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[1],MTH_M_xFloatToReal(0.01)) && MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[2],MTH_M_xFloatToReal(0.01))) { POS_fn_vSetZoomMatrix( _p_stCompletePosition , (MTH_tdxReal)a3_xVecSca[0] ); POS_fn_vGetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } else { fn_v_InvRotDiaRot( a3a3_xMtxSca, a3a3_xMtxOriSca, a3_xVecSca ); /* Create final Transform matrix*/ fn_v_MultMatrix( a3a3_xMtxTra, a3a3_xMtxOri, a3a3_xMtxSca ); POS_fn_vSetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } } } else { /* Interpolation of scale direction*/ fn_v_ExpandQuat( a4_xQuatS1, p_a4_xQuaternions[_p_stKey1->uwNumOfQuatSca] ); fn_v_ExpandQuat( a4_xQuatS2, p_a4_xQuaternions[_p_stKey2->uwNumOfQuatSca] ); fn_v_InterpolQuatWithOmega( a4_xQuatI, a4_xQuatS1, a4_xQuatS2, _xT, _p_stKey1->uwAngQuatSca ); fn_v_QuatToMatrix( a3a3_xMtxOriSca, a4_xQuatI ); /* Create final scale matrix*/ /* Final matrix= [scale dir. matrix]*[values scale matrix]*[scale dir. matrix]^-1*/ if(MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[1],MTH_M_xFloatToReal(0.01)) && MTH_M_bEqualWithEpsilon(a3_xVecSca[0],a3_xVecSca[2],MTH_M_xFloatToReal(0.01))) { POS_fn_vSetZoomMatrix( _p_stCompletePosition , (MTH_tdxReal)a3_xVecSca[0] ); POS_fn_vGetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } else { fn_v_InvRotDiaRot( a3a3_xMtxSca, a3a3_xMtxOriSca, a3_xVecSca ); /* Create final Transform matrix*/ fn_v_MultMatrix( a3a3_xMtxTra, a3a3_xMtxOri, a3a3_xMtxSca ); POS_fn_vSetTransformMatrix( _p_stCompletePosition , (MTH3D_tdstVector*)a3a3_xMtxTra[0], (MTH3D_tdstVector*)a3a3_xMtxTra[1] , (MTH3D_tdstVector*)a3a3_xMtxTra[2] ); } } } /* -- Interpolation of position -------*/ if ( (_xT == xZero) || (_p_stKey1->uwMask & SEB_xMaskPosition) != 0x0000 ) { register SEB_xReal r_xDistMaster; p_Vect1= &p_a3_xVectors[_p_stKey1->uwNumOfPosition]; r_xDistMaster= _p_stKey1->xDistMaster; a3_xPosition[0]= (*p_Vect1)[0] * r_xDistMaster; a3_xPosition[1]= (*p_Vect1)[1] * r_xDistMaster; a3_xPosition[2]= (*p_Vect1)[2] * r_xDistMaster; POS_fn_vSetTranslationVector( _p_stCompletePosition , (MTH3D_tdstVector*)a3_xPosition ); } else { if ( _uwInterpolated == 0x0000 ) { /* Interpolation with the pivot*/ /* Rotate pivot (local to object)*/ fn_v_MatrixByVector( a3_xVecSca, a3a3_xMtxTra, p_a3_xVectors[_p_stChannel->uwNumOfLocalPivotPos] ); /* Pivot (linear) interpolation in world axes*/ fn_v_InterpolVect( a3_xPosition, _p_stKey1->a3_xWorldPivotPosition, _p_stKey2->a3_xWorldPivotPosition, _xT ); /* Computes the interpolated position*/ a3_xPosition[0]-= a3_xVecSca[0]; a3_xPosition[1]-= a3_xVecSca[1]; a3_xPosition[2]-= a3_xVecSca[2]; POS_fn_vSetTranslationVector( _p_stCompletePosition , (MTH3D_tdstVector*)a3_xPosition ); } else { /* Interpolation with Hierarchy*/ if ( (_p_stKey1->xDistMaster > xEps) || (_p_stKey2->xDistMaster > xEps) ) { p_Vect1= &p_a3_xVectors[_p_stKey1->uwNumOfPosition]; if ((_p_stKey1->uwMask & SEB_xMaskZeroAngCentre) != 0x0000) { /* Linear interpolation of vector length*/ xCoef1= ( _p_stKey2->xDistMaster - _p_stKey1->xDistMaster ) * _xT + _p_stKey1->xDistMaster; /* Computes the interpolated position*/ a3_xPosition[0]= xCoef1 * (*p_Vect1)[0]; a3_xPosition[1]= xCoef1 * (*p_Vect1)[1]; a3_xPosition[2]= xCoef1 * (*p_Vect1)[2]; POS_fn_vSetTranslationVector( _p_stCompletePosition , (MTH3D_tdstVector*)a3_xPosition ); } else { p_Vect2= &p_a3_xVectors[_p_stKey2->uwNumOfPosition]; swOmega= _p_stKey1->uwAngObjCentre; /* Computes values for "Geodesic" interpolation*/ swCosOmega= ax_SinTab[ swOmega ]; if ( swCosOmega != 0 ) { xSinOmega= xOne / swCosOmega; swTbyOmega= (signed short) (_xT * swOmega); /* Always 0 < slTbyOmega < _slOmega*/ xCoef1= ax_SinTab[ swOmega - swTbyOmega ] * xSinOmega; xCoef2= ax_SinTab[ swTbyOmega ] * xSinOmega; } else { xCoef1= xOne - _xT; xCoef2= _xT; } /* Linear interpolation of vector length*/ xSinOmega= ( _p_stKey2->xDistMaster - _p_stKey1->xDistMaster ) * _xT + _p_stKey1->xDistMaster; xCoef1*= xSinOmega; xCoef2*= xSinOmega; /* Computes the interpolated position*/ a3_xPosition[0]= xCoef1 * (*p_Vect1)[0] + xCoef2 * (*p_Vect2)[0]; a3_xPosition[1]= xCoef1 * (*p_Vect1)[1] + xCoef2 * (*p_Vect2)[1]; a3_xPosition[2]= xCoef1 * (*p_Vect1)[2] + xCoef2 * (*p_Vect2)[2]; POS_fn_vSetTranslationVector( _p_stCompletePosition , (MTH3D_tdstVector*)a3_xPosition ); } } } } } /* ***********************************************************************************/ #ifdef A3X_CUT unsigned short fn_uw_GetNumOfA3dGENERAL( unsigned short _uwNumOfA3dGENERAL, unsigned short _uwT ) { register unsigned short uwNumOfA3dGENERAL; uwNumOfA3dGENERAL= _uwNumOfA3dGENERAL; while ( _uwT >= p_stCuttedAnim[uwNumOfA3dGENERAL].uwEndFrame ) { uwNumOfA3dGENERAL= p_stCuttedAnim[uwNumOfA3dGENERAL].uwNextAnim; if (uwNumOfA3dGENERAL == 0xFFFF) { #ifdef ANIM_DEBUG osSyncPrintf("Cut anim not found\n"); osSyncPrintf("Anim = %d, Frame = %d\n",_uwNumOfA3dGENERAL,_uwT); ASM_BREAK; /* temporary*/ #endif return 0xFFFF; } } p_uwLastA3dGENERAL[_uwNumOfA3dGENERAL]= uwNumOfA3dGENERAL; return uwNumOfA3dGENERAL; } #endif /* ***********************************************************************************/ tdstEvent *fn_p_GetEventsAddress( tdstAnim3d *_p_stAnim3d, unsigned long _ulFrame, tdxHandleToObjectsTablesList _h_ObjectsTablesListElement) { #ifdef U64 int i; tdstEvent * p_stEvent, * p_stEventNeverPlay; if ( _p_stAnim3d->uwNumOfA3dGENERAL != C_uwAnimNotInterpolated ) { /* Animation is a interpolated animation*/ /* Set Events*/ if ( _p_stAnim3d->ucNumberOfEvents == 0 ) _p_stAnim3d->d_stAnimEvent= NULL; else { tdstA3dGENERAL *p_stCurrentA3dGENERAL; #ifndef FORCE_REAL_TIME_LOAD if(g_bRealTimeAnimationLoad) #endif p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL(p_uwLastA3dGENERAL[_p_stAnim3d->uwNumOfA3dGENERAL], _ulFrame); #ifndef FORCE_REAL_TIME_LOAD else p_stCurrentA3dGENERAL= fn_p_GetA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL, _ulFrame ); #endif _p_stAnim3d->d_stAnimEvent= &p_stEvents[ p_stCurrentA3dGENERAL->uwNumOfFirstEvent ]; /* Update event pointer with sort*/ for(i=0,p_stEvent=NULL,p_stEventNeverPlay=_p_stAnim3d->d_stAnimEvent;i<_p_stAnim3d->ucNumberOfEvents;++i,p_stEventNeverPlay++) { if(p_stEventNeverPlay->p_stfEventInTBL==NULL) { /* set the tbl event*/ p_stEventNeverPlay->p_stfEventInTBL= (tdstEventInTable*)_h_ObjectsTablesListElement->d_stObjectsTable[p_stEventNeverPlay->usEventNumberInTBL].h_Target; /* found first non never play event*/ #ifdef ANIM_DEBUG if(p_stEventNeverPlay->p_stfEventInTBL==NULL) { osSyncPrintf("Probleme d'evenements : p_stfEventInTBL==NULL\n"); osSyncPrintf("Anim = %d, Frame = %d, number in table = %d\n",_p_stAnim3d->uwNumOfA3dGENERAL,_ulFrame,p_stEventNeverPlay->usEventNumberInTBL); } #endif if (!p_stEvent && (GAM_fn_ucGetFirstCallOfEvent(p_stEventNeverPlay) != C_ucNeverPlay)) p_stEvent = p_stEventNeverPlay; /* found a never play */ else if (GAM_fn_ucGetFirstCallOfEvent(p_stEventNeverPlay) == C_ucNeverPlay) { /* set the frame & channel to 0*/ p_stEventNeverPlay->uwChannelNumber = p_stEventNeverPlay->uwFrameNumber = 0; /* there is a non never play before*/ if (p_stEvent) { tdstEvent * p_stTmpEvent; /* we move up the never play event until the first non never play*/ for(p_stTmpEvent = p_stEventNeverPlay-1;p_stTmpEvent >= p_stEvent;p_stTmpEvent--) { /* permute Event*/ tdstEvent stEvent = *(p_stTmpEvent+1); *(p_stTmpEvent+1) = *p_stTmpEvent; *p_stTmpEvent = stEvent; } /* now the fisrt non never play has moved 1 place down*/ p_stEvent++; } } } } } } #endif /*U64*/ return _p_stAnim3d->d_stAnimEvent; } /* ***********************************************************************************/ void fn_v_CalculateGeneral(tdstAnim3d * _p_stAnim3d,unsigned long _ulFrame ) { #ifndef FORCE_REAL_TIME_LOAD tdstA3dGENERAL *p_stCurrentA3dGENERAL; /* tdxQuater4 a4_xQuat;*/ /* tdxMatrix33 a3x3_Matrix;*/ if(!g_bRealTimeAnimationLoad) { p_stCurrentA3dGENERAL = fn_p_GetA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL,_ulFrame); _p_stAnim3d->uwNumberOfFrames = p_stCurrentA3dGENERAL->uwNumberOfFrames; _p_stAnim3d->ucFrameRate= (unsigned char) p_stCurrentA3dGENERAL->uwAnimationSpeed; _p_stAnim3d->ucMaxNumberOfElements= (unsigned char) p_stCurrentA3dGENERAL->uwNumberOfChannels; _p_stAnim3d->ucNumberOfEvents= (unsigned char) p_stCurrentA3dGENERAL->uwNumberOfEvents; if ( (p_a3_xVectors[p_stCurrentA3dGENERAL->uwNumOfAnimationTranslationOffset][0] != xZero) || (p_a3_xVectors[p_stCurrentA3dGENERAL->uwNumOfAnimationTranslationOffset][1] != xZero) || (p_a3_xVectors[p_stCurrentA3dGENERAL->uwNumOfAnimationTranslationOffset][2] != xZero) ) { /* POS_fn_vSetTranslationVector( &(_p_stAnim3d->stOffsetMatrix) , (MTH3D_tdstVector*)p_a3_xVectors[p_stCurrentA3dGENERAL->uwNumOfAnimationTranslationOffset] );*/ memcpy(&(_p_stAnim3d->stOffsetMatrix),(MTH3D_tdstVector*)p_a3_xVectors[p_stCurrentA3dGENERAL->uwNumOfAnimationTranslationOffset],sizeof(MTH3D_tdstVector)); } else memset(&_p_stAnim3d->stOffsetMatrix,0,sizeof(MTH3D_tdstVector)); /*AR9811*/ /* if ( (p_a4_xQuaternions[p_stCurrentA3dGENERAL->uwNumOfAnimationRotationOffset][0] != 0) || (p_a4_xQuaternions[p_stCurrentA3dGENERAL->uwNumOfAnimationRotationOffset][1] != 0) || (p_a4_xQuaternions[p_stCurrentA3dGENERAL->uwNumOfAnimationRotationOffset][2] != 0) || (p_a4_xQuaternions[p_stCurrentA3dGENERAL->uwNumOfAnimationRotationOffset][3] != lOne) ) { fn_v_ExpandQuat( a4_xQuat, p_a4_xQuaternions[p_stCurrentA3dGENERAL->uwNumOfAnimationRotationOffset] ); fn_v_QuatToMatrix( a3x3_Matrix , a4_xQuat ); POS_fn_vSetRotationMatrix( &(_p_stAnim3d->stOffsetMatrix) , (MTH3D_tdstVector*)a3x3_Matrix[0] , (MTH3D_tdstVector*)a3x3_Matrix[1] , (MTH3D_tdstVector*)a3x3_Matrix[2] ); } */ /* Set Events*/ if ( _p_stAnim3d->ucNumberOfEvents == 0 ) _p_stAnim3d->d_stAnimEvent= NULL; else _p_stAnim3d->d_stAnimEvent= &p_stEvents[p_stCurrentA3dGENERAL->uwNumOfFirstEvent]; /* Set Morph table*/ if ( p_stCurrentA3dGENERAL->uwNumberOfMorphData == 0 ) _p_stAnim3d->d_stMorphDataArray = NULL; else _p_stAnim3d->d_stMorphDataArray = &p_stMorphData[p_stCurrentA3dGENERAL->uwNumOfFirstMorphData]; } else { #endif #ifdef A3X_CUT /* If we are in realtime load system, we don't need to load the entire animations, here.*/ register tdstShortA3dGENERAL *p_stShortA3dGENERAL; p_stShortA3dGENERAL= fn_p_ReadShortAnimFromROM(_p_stAnim3d->uwNumOfA3dGENERAL); _p_stAnim3d->uwNumberOfFrames= p_stShortA3dGENERAL->uwNumberOfFrames; _p_stAnim3d->ucFrameRate= p_stShortA3dGENERAL->uwFrameRate; _p_stAnim3d->ucMaxNumberOfElements= p_stShortA3dGENERAL->uwMaxNumberOfElements; _p_stAnim3d->ucNumberOfEvents= p_stShortA3dGENERAL->uwNumberOfEvents; if((p_stShortA3dGENERAL->a3_xAnimationTranslationOffset[0] != xZero)|| (p_stShortA3dGENERAL->a3_xAnimationTranslationOffset[1] != xZero)|| (p_stShortA3dGENERAL->a3_xAnimationTranslationOffset[2] != xZero)) /* POS_fn_vSetTranslationVector(&(_p_stAnim3d->stOffsetMatrix) , (MTH3D_tdstVector*)p_stShortA3dGENERAL->a3_xAnimationTranslationOffset );*/ memcpy(&(_p_stAnim3d->stOffsetMatrix),(MTH3D_tdstVector*)p_stShortA3dGENERAL->a3_xAnimationTranslationOffset,sizeof(MTH3D_tdstVector)); /*AR9811*/ else memset(&_p_stAnim3d->stOffsetMatrix,0,sizeof(MTH3D_tdstVector)); /*AR9811*/ /* if ((p_stShortA3dGENERAL->a4_uwAnimationRotationOffset[0] != 0) || (p_stShortA3dGENERAL->a4_uwAnimationRotationOffset[1] != 0) || (p_stShortA3dGENERAL->a4_uwAnimationRotationOffset[2] != 0) || (p_stShortA3dGENERAL->a4_uwAnimationRotationOffset[3] != lOne) ) { fn_v_ExpandQuat(a4_xQuat, p_stShortA3dGENERAL->a4_uwAnimationRotationOffset ); fn_v_QuatToMatrix( a3x3_Matrix , a4_xQuat ); POS_fn_vSetRotationMatrix( &(_p_stAnim3d->stOffsetMatrix) , (MTH3D_tdstVector*)a3x3_Matrix[0] , (MTH3D_tdstVector*)a3x3_Matrix[1] , (MTH3D_tdstVector*)a3x3_Matrix[2] ); } */ /* Set Events*/ if ( _p_stAnim3d->ucNumberOfEvents == 0 ) _p_stAnim3d->d_stAnimEvent= NULL; else _p_stAnim3d->d_stAnimEvent= (struct tdstEvent_ *)0xCCCCCCCC; /* Updated later*/ /* Set Morph table*/ if ( p_stShortA3dGENERAL->uwNumberOfMorphData == 0 ) _p_stAnim3d->d_stMorphDataArray = NULL; else _p_stAnim3d->d_stMorphDataArray = (struct stMorphData *)0xCCCCCCCC; /* Updated later*/ #endif #ifndef FORCE_REAL_TIME_LOAD } #endif } /* ****************************************************************** fn_vUpdateFrame*/ /* Update Frame structure if it wasn't - but matrix isn't update*/ /* Set Linear and Angular Speed (Alloc or Free Matrix)*/ /* Set Hierarchy*/ /* Fill Element3D Array : ElementNuber,ElementType,ActiveStatus,ChannelNumber*/ /**/ /* 17/07/98 - Carlos Torres*/ /* ***********************************************************************************/ void fn_vUpdateFrame(void * _p_stSuperObject,tdstFrame3d * _p_stFrame,tdstAnim3d * _p_stAnim3d,unsigned short _uwFrame) { tdstA3dGENERAL * p_stCurrentA3dGENERAL; tdstOnlyFrame * p_stCurrentOnlyFrame; tdstChannel * p_stCurrentChannel; unsigned short uwT_NTTO; unsigned short uwCnt1,uwNumOfA3dGENERAL; tdstElement3d * p_stCurrentElement3d; unsigned short uwCorrectedFrame; ACP_tdxBool bMustTest=TRUE; /* AR9902*/ /* Before returning, we must be sure that the animation is still loaded into the animation cache*/ /* and that it is loaded into the same cache entry*/ /* ----------------------------------------------------------------------------------*/ /* Get A3D General Info*/ #ifdef A3X_N64 #ifndef FORCE_REAL_TIME_LOAD if(g_bRealTimeAnimationLoad) #endif uwNumOfA3dGENERAL= fn_uw_GetNumOfA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL, _uwFrame); #ifndef FORCE_REAL_TIME_LOAD else #endif #endif #ifndef FORCE_REAL_TIME_LOAD uwNumOfA3dGENERAL= _p_stAnim3d->uwNumOfA3dGENERAL; #endif #ifdef A3X_N64 if((p_stA3dHeaders[uwNumOfA3dGENERAL].uwNumOfCacheEntry == SEB_Invalid) ||(_p_stFrame->ucCacheEntry!=(unsigned char)p_stA3dHeaders[uwNumOfA3dGENERAL].uwNumOfCacheEntry)) { /* Animation isn't loaded*/ /* We must load it and fill again the _p_stFrame because the old values aren't valid anymore*/ bMustTest=FALSE; } else #endif /*A3X_N64*/ bMustTest=TRUE; if(bMustTest) { /* if uwFrame>uwNumberOfFrames, no update*/ if ( _uwFrame >= _p_stAnim3d->uwNumberOfFrames ) return; /* Can occur sometimes... AR9808*/ /* check if the frame is already updated*/ if ((_p_stFrame->p_stAnim == _p_stAnim3d) && (_p_stFrame->uwFrameNumber == _uwFrame)) return; } else { if ( _uwFrame >= _p_stAnim3d->uwNumberOfFrames ) _uwFrame = ( unsigned short ) ( _p_stAnim3d->uwNumberOfFrames - 1 ) ; /*last valid frame*/ } /* ----------------------------------------------------------------------------------*/ /* set ref of the frame*/ _p_stFrame->p_stAnim = _p_stAnim3d; _p_stFrame->uwFrameNumber = _uwFrame; _p_stFrame->ucMatrixUpdated = FALSE; /* Here, we load the animation in cache again*/ p_stCurrentA3dGENERAL = fn_p_GetA3dGENERAL(uwNumOfA3dGENERAL,_uwFrame); /* ----------------------------------------------------------------------------------*/ /* check if anim cutting is well done*/ #if defined(A3X_N64) && defined(ANIM_DEBUG) if ((_uwFrame < p_stCurrentA3dGENERAL->uwStartFrame) || (_uwFrame >= p_stCurrentA3dGENERAL->uwEndFrame) ) { osSyncPrintf("Probleme decoupage d'animation (anim= %d, Frame= %d, StartFrame= %d, EndFrame= %d)\n", uwNumOfA3dGENERAL, _uwFrame, p_stCurrentA3dGENERAL->uwStartFrame, p_stCurrentA3dGENERAL->uwEndFrame); ASM_BREAK; } #endif /* ANIM_DEBUG */ #ifdef A3X_N64 if(!bMustTest) { /*Here, the anim has been loaded and we can updade the number of the cache entry into the frame structure*/ _p_stFrame->ucCacheEntry=(unsigned char)p_stA3dHeaders[uwNumOfA3dGENERAL].uwNumOfCacheEntry; } /* End of AR9902*/ #endif /*A3X_N64*/ uwCorrectedFrame = (unsigned short) (_uwFrame - p_stCurrentA3dGENERAL->uwStartFrame); /* ----------------------------------------------------------------------------------*/ /* Get information to update frame info*/ p_stCurrentChannel = &p_stChannels [p_stCurrentA3dGENERAL->uwNumOfFirstChannel]; p_stCurrentOnlyFrame = &p_stOnlyFrames[p_stCurrentA3dGENERAL->uwNumOfFirstOnlyFrame + uwCorrectedFrame]; uwT_NTTO = p_stCurrentOnlyFrame->uwNumOfSavedFrame; /* ----------------------------------------------------------------------------------*/ /* Set Angular Speed Matrix if exist*/ #ifndef U64 if (p_stCurrentOnlyFrame->uwNumOfAngularSpeedQuat == SEB_Invalid) { /* free matrix if allocated*/ if (_p_stFrame->p_stAngularSpeedMatrix) { MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeSpeedMatrix , 0 ); TMP_M_Free(_p_stFrame->p_stAngularSpeedMatrix); } _p_stFrame->p_stAngularSpeedMatrix= NULL; } else { tdxQuater4 a4_xQuatOri; /* allocate matrix if it wasn't*/ if (!_p_stFrame->p_stAngularSpeedMatrix) { MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeSpeedMatrix , 0 ); _p_stFrame->p_stAngularSpeedMatrix = TMP_M_p_Malloc(sizeof(MTH3D_tdstMatrix)); } fn_v_ExpandQuat(a4_xQuatOri,p_a4_xQuaternions[p_stCurrentOnlyFrame->uwNumOfAngularSpeedQuat]); fn_v_QuatToMatrix(*((tdxMatrix33 *) (_p_stFrame->p_stAngularSpeedMatrix)),a4_xQuatOri); } /* ----------------------------------------------------------------------------------*/ /* Set Linear Speed Vector if exist*/ if (p_stCurrentOnlyFrame->uwNumOfSpeedVector == SEB_Invalid) { _p_stFrame->p_stLinearSpeedVector = NULL; } else { _p_stFrame->p_stLinearSpeedVector = (MTH3D_tdstVector *) &p_a3_xVectors[p_stCurrentOnlyFrame->uwNumOfSpeedVector]; } #endif /* ---------------------------------------------------------------------------------- */ /* Set Hierarchy */ if (p_stCurrentOnlyFrame->uwHierarchyNbCouples) { #ifdef U64 /* Begin AR9902 Copy hierarchy instead of pointing it */ if(_p_stFrame->stHierarchy.d_stCouples!=NULL) { if((memcmp(_p_stFrame->stHierarchy.d_stCouples, &p_stHierarchies[p_stCurrentOnlyFrame->uwNumOfFirstHierarchyCouple], sizeof(tdstCouple)*p_stCurrentOnlyFrame->uwHierarchyNbCouples)!=0) || (p_stCurrentOnlyFrame->uwHierarchyNbCouples != _p_stFrame->stHierarchy.ulNbOfCouples)) { /* hierarchy is different */ MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeHierarchies , 0 ); _p_stFrame->stHierarchy.d_stCouples = TMP_M_p_Malloc(sizeof(tdstCouple)*p_stCurrentOnlyFrame->uwHierarchyNbCouples); memcpy(_p_stFrame->stHierarchy.d_stCouples, &p_stHierarchies[p_stCurrentOnlyFrame->uwNumOfFirstHierarchyCouple], sizeof(tdstCouple)*p_stCurrentOnlyFrame->uwHierarchyNbCouples); /* The old hierarchy is freed into the anim player (PLA_fn_vInitAllChildInHeapNewAnim) */ } } else { /* no previous hierarchy */ MMG_fn_vAddMemoryInfo( MMG_C_lTypeInterpol , MMG_C_lSubTypeHierarchies , 0 ); _p_stFrame->stHierarchy.d_stCouples = TMP_M_p_Malloc(sizeof(tdstCouple)*p_stCurrentOnlyFrame->uwHierarchyNbCouples); memcpy(_p_stFrame->stHierarchy.d_stCouples, &p_stHierarchies[p_stCurrentOnlyFrame->uwNumOfFirstHierarchyCouple], sizeof(tdstCouple)*p_stCurrentOnlyFrame->uwHierarchyNbCouples); } /* End AR9902 */ #else _p_stFrame->stHierarchy.d_stCouples = (tdstCouple *) &p_stHierarchies[p_stCurrentOnlyFrame->uwNumOfFirstHierarchyCouple]; #endif } else _p_stFrame->stHierarchy.d_stCouples = NULL; _p_stFrame->stHierarchy.ulNbOfCouples = p_stCurrentOnlyFrame->uwHierarchyNbCouples; /* ----------------------------------------------------------------------------------*/ /* Set Frame Info - don't compute matrix*/ for (uwCnt1=0,p_stCurrentElement3d=_p_stFrame->p_stArrayOfElts3d;uwCnt1uwNumberOfChannels;uwCnt1++) { tdstFrame * p_stCurrentFrame; /* Get Current Frame info*/ p_stCurrentFrame = &p_stFrames[p_stCurrentChannel->uwNumOfFirstFrame + uwT_NTTO]; /* ----------------------------------------------------------------------------------*/ /* Fill element 3D structure*/ if(p_stCurrentFrame->uwNumOfNTTO!=(unsigned short)0xFFFF) /* empty object AR9810*/ { /* Element Number in TBL*/ p_stCurrentElement3d->wElement = p_stNTTO[p_stCurrentFrame->uwNumOfNTTO].ucNumberInTable; /* Channel Number*/ p_stCurrentElement3d->ucChannelNumber = (unsigned char)(p_stCurrentChannel->uwChannelNumber); /* Active Status*/ p_stCurrentElement3d->bf1ActiveStatus = TRUE; /* Type Of Element*/ p_stCurrentElement3d->eTypeOfElement = (tdeTypeOfElement)(p_stNTTO[p_stCurrentFrame->uwNumOfNTTO].uwTypeOfObject & 0x00FF); /* ucTransparency*/ p_stCurrentElement3d->ucTransparency= p_stNTTO[ p_stCurrentFrame->uwNumOfNTTO ].ucTransparency; } else { /* XB 05/05/99 : typeof(wElement)=unsigned char on N64 !! */ #ifndef U64 p_stCurrentElement3d->wElement = (unsigned short) -1; #else p_stCurrentElement3d->wElement = (unsigned char) -1; #endif /* End XB 05/05/99 */ p_stCurrentElement3d->ucChannelNumber = (unsigned char)(p_stCurrentChannel->uwChannelNumber); p_stCurrentElement3d->bf1ActiveStatus = TRUE; p_stCurrentElement3d->eTypeOfElement = TE_EmptyObject; p_stCurrentElement3d->ucTransparency = 0; } p_stCurrentChannel++; p_stCurrentElement3d++; } } /* ************************************************************ fn_vUpdateFrameMatrix*/ /* Update Frame if it wasn't update*/ /* Update Matrix in Channel Array*/ /* if they weren't updated*/ /* or if bolean ForceUpdate is TRUE*/ /**/ /* 17/07/98 - Carlos Torres*/ /* ***********************************************************************************/ void fn_vUpdateFrameMatrix(void * _p_stSuperObject,tdstFrame3d * _p_stFrame,tdstAnim3d * _p_stAnim3d, unsigned short _uwFrame,unsigned char ucForceUpdate,tdstAChannel * d_stChannelArray) { tdstA3dGENERAL * p_stCurrentA3dGENERAL; tdstChannel * p_stCurrentChannel; unsigned short uwT_NTTO; unsigned short uwCnt1,uwNumOfA3dGENERAL; unsigned short uwCorrectedFrame; ACP_tdxBool bHierarchized; /* ----------------------------------------------------------------------------------*/ /* update frame*/ fn_vUpdateFrame(_p_stSuperObject,_p_stFrame,_p_stAnim3d,_uwFrame); /* ----------------------------------------------------------------------------------*/ /* check if the frame matrix is already updated*/ if (_p_stFrame->ucMatrixUpdated && !ucForceUpdate) return; /* ----------------------------------------------------------------------------------*/ /* set ref of the frame*/ _p_stFrame->ucMatrixUpdated = TRUE; /* ----------------------------------------------------------------------------------*/ /* Get A3D General Info*/ #ifdef A3X_N64 #ifndef FORCE_REAL_TIME_LOAD if(g_bRealTimeAnimationLoad) #endif uwNumOfA3dGENERAL= fn_uw_GetNumOfA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL, _uwFrame); #ifndef FORCE_REAL_TIME_LOAD else #endif #endif #ifndef FORCE_REAL_TIME_LOAD uwNumOfA3dGENERAL= _p_stAnim3d->uwNumOfA3dGENERAL; #endif p_stCurrentA3dGENERAL = fn_p_GetA3dGENERAL(uwNumOfA3dGENERAL,_uwFrame); #ifdef A3X_N64 /* ----------------------------------------------------------------------------------*/ /* check if anim cutting is well done*/ #ifdef ANIM_DEBUG if ((_uwFrame < p_stCurrentA3dGENERAL->uwStartFrame) || (_uwFrame >= p_stCurrentA3dGENERAL->uwEndFrame) ) { osSyncPrintf("Probleme decoupage d'animation (anim= %d, frame= %d, StartFrame= %d, EndFrame= %d)\n", uwNumOfA3dGENERAL, _uwFrame, p_stCurrentA3dGENERAL->uwStartFrame, p_stCurrentA3dGENERAL->uwEndFrame); osSyncPrintf("Numéro original d'anim : %d\n",_p_stAnim3d->uwNumOfA3dGENERAL); ASM_BREAK; } #endif /* ANIM_DEBUG */ #endif uwCorrectedFrame = (unsigned short) (_uwFrame - p_stCurrentA3dGENERAL->uwStartFrame); /* ----------------------------------------------------------------------------------*/ /* Get information to update frame info*/ p_stCurrentChannel = &p_stChannels [p_stCurrentA3dGENERAL->uwNumOfFirstChannel]; uwT_NTTO = p_stOnlyFrames[p_stCurrentA3dGENERAL->uwNumOfFirstOnlyFrame + uwCorrectedFrame].uwNumOfSavedFrame; /* ----------------------------------------------------------------------------------*/ /* Interpolate all channels Matrix*/ for (uwCnt1=0;uwCnt1uwNumberOfChannels;uwCnt1++) { tdstFrame * p_stCurrentFrame; tdstFrameKF * p_stCurrentFrameKF; tdstKeyFrame * p_stCurrentKeyFrame, * p_stOldKeyFrame; register SEB_xReal xDT= xZero; /* TEMP ANTI BUG - to avoid crash with bad Anim*/ /* Later replace by an assert in debuf version*/ if ((p_stCurrentChannel->uwChannelNumber != SEB_Invalid) && (!d_stChannelArray[p_stCurrentChannel->uwChannelNumber].bControlledChannel)) { /* Get Current frame information*/ p_stCurrentFrame = &p_stFrames[p_stCurrentChannel->uwNumOfFirstFrame + uwT_NTTO]; p_stCurrentFrameKF = &p_stFramesKF[p_stCurrentChannel->ulNumOfFirstFrameKF + uwCorrectedFrame]; p_stOldKeyFrame = &p_stKeyFrames[p_stCurrentFrameKF->uwNumOfKeyFrame]; /* get key frame for interpolation*/ if ((p_stOldKeyFrame->uwMask & SEB_xMaskLastKey) != 0x0000) { if ((p_stOldKeyFrame->uwMask & SEB_xTypeWrapLastKey) != 0x0000) { p_stCurrentKeyFrame= &p_stKeyFrames[ p_stFramesKF[p_stCurrentChannel->ulNumOfFirstFrameKF].uwNumOfKeyFrame ]; xDT= ((SEB_xReal) (_uwFrame - p_stOldKeyFrame->uwFrameNumber)) / ((SEB_xReal) (p_stCurrentA3dGENERAL->uwNumberOfFrames + p_stCurrentKeyFrame->uwFrameNumber - p_stOldKeyFrame->uwFrameNumber)); } else { p_stCurrentKeyFrame = p_stOldKeyFrame; xDT = xZero; } } else { p_stCurrentKeyFrame = p_stOldKeyFrame + 1; if (p_stCurrentKeyFrame->uwFrameNumber == p_stOldKeyFrame->uwFrameNumber) xDT = xZero; else xDT = ((SEB_xReal)(_uwFrame - p_stOldKeyFrame->uwFrameNumber)) / ((SEB_xReal)(p_stCurrentKeyFrame->uwFrameNumber - p_stOldKeyFrame->uwFrameNumber)); } /* InterpolationParameter*/ if ( (p_stOldKeyFrame->swInterpolationParameter != 0x0000) && (xDT != xZero) ) { register SEB_xReal xTmp; xTmp= p_stCurrentKeyFrame->swInterpolationParameter * ((SEB_xReal) (1.0f / 8192.0f)); xDT= xDT * (xDT * xTmp + xOne - xTmp); } if(p_stNTTO[p_stCurrentFrame->uwNumOfNTTO].uwTypeOfObject!=(unsigned short)0xFFFF) bHierarchized=(ACP_tdxBool)(p_stNTTO[p_stCurrentFrame->uwNumOfNTTO].uwTypeOfObject & SEB_xTypeHierarchized); else bHierarchized=FALSE; /* Interpolate channel matrix*/ fn_v_InterpolBetweenKeys( p_stOldKeyFrame, p_stCurrentKeyFrame, p_stCurrentChannel, d_stChannelArray[p_stCurrentChannel->uwChannelNumber].hSupObject->hLocalMatrix, bHierarchized, xDT); } p_stCurrentChannel++; } } /* ****************************************************** fn_p_stGetLinearSpeedVector*/ /* Return the Linear Speed Vector*/ /* the vector returned is a reference so*/ /* DON'T Modify it or Free it*/ /* if there is no speed, return NULL*/ /* reference remain valid until animation is free*/ /**/ /* 20/07/98 - Carlos Torres*/ /* ***********************************************************************************/ MTH3D_tdstVector * fn_p_stGetLinearSpeedVector(tdstAnim3d * _p_stAnim3d,unsigned short _uwFrame) { unsigned short uwNumOfA3dGENERAL; tdstA3dGENERAL * p_stCurrentA3dGENERAL; tdstOnlyFrame * p_stCurrentOnlyFrame; if ( _uwFrame >= _p_stAnim3d->uwNumberOfFrames ) return NULL; /* Can occur sometimes... AR9808*/ /* ----------------------------------------------------------------------------------*/ /* Get A3D General Info*/ #ifdef A3X_N64 #ifndef FORCE_REAL_TIME_LOAD if(g_bRealTimeAnimationLoad) #endif uwNumOfA3dGENERAL= fn_uw_GetNumOfA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL, _uwFrame); #ifndef FORCE_REAL_TIME_LOAD else #endif #endif #ifndef FORCE_REAL_TIME_LOAD uwNumOfA3dGENERAL= _p_stAnim3d->uwNumOfA3dGENERAL; #endif p_stCurrentA3dGENERAL = fn_p_GetA3dGENERAL(uwNumOfA3dGENERAL,_uwFrame); #ifdef A3X_N64 /* ----------------------------------------------------------------------------------*/ /* check if anim cutting is well done*/ #ifdef ANIM_DEBUG if ((_uwFrame < p_stCurrentA3dGENERAL->uwStartFrame) || (_uwFrame >= p_stCurrentA3dGENERAL->uwEndFrame) ) { osSyncPrintf("Probleme decoupage d'animation (anim= %d, Frame= %d, StartFrame= %d, EndFrame= %d)\n", uwNumOfA3dGENERAL, _uwFrame, p_stCurrentA3dGENERAL->uwStartFrame, p_stCurrentA3dGENERAL->uwEndFrame); osSyncPrintf("Numero original d'anim : %d\n",_p_stAnim3d->uwNumOfA3dGENERAL); ASM_BREAK; } #endif /* ANIM_DEBUG */ #endif #ifndef U64 #pragma warning(disable:4244) #endif _uwFrame -= p_stCurrentA3dGENERAL->uwStartFrame; #ifndef U64 #pragma warning(default:4244) #endif /* ----------------------------------------------------------------------------------*/ /* Get information to update frame info*/ p_stCurrentOnlyFrame = &p_stOnlyFrames[p_stCurrentA3dGENERAL->uwNumOfFirstOnlyFrame + _uwFrame]; /* ----------------------------------------------------------------------------------*/ /* Set Linear Speed Vector if exist*/ if (p_stCurrentOnlyFrame->uwNumOfSpeedVector == SEB_Invalid) { return NULL; } else { return (MTH3D_tdstVector *) &p_a3_xVectors[p_stCurrentOnlyFrame->uwNumOfSpeedVector]; } } /* ***************************************************** fn_p_stGetAngularSpeedMatrix*/ /* Return the Angular Speed Matrix*/ /* Fill the Matrix if exist and return pointer*/ /* If no angular speed return NULL*/ /* The matrix pass in parameter must be allocate by the calling function*/ /**/ /* 20/07/98 - Carlos Torres*/ /* ***********************************************************************************/ MTH3D_tdstMatrix * fn_p_stGetAngularSpeedMatrix(tdstAnim3d * _p_stAnim3d,unsigned short _uwFrame,MTH3D_tdstMatrix * p_stMatrix) { unsigned short uwNumOfA3dGENERAL; tdstA3dGENERAL * p_stCurrentA3dGENERAL; tdstOnlyFrame * p_stCurrentOnlyFrame; if ( _uwFrame >= _p_stAnim3d->uwNumberOfFrames ) return NULL; /* Can occur sometimes... AR9808*/ /* ----------------------------------------------------------------------------------*/ /* Get A3D General Info*/ #ifdef A3X_N64 #ifndef FORCE_REAL_TIME_LOAD if(g_bRealTimeAnimationLoad) #endif uwNumOfA3dGENERAL= fn_uw_GetNumOfA3dGENERAL(_p_stAnim3d->uwNumOfA3dGENERAL, _uwFrame); #ifndef FORCE_REAL_TIME_LOAD else #endif #endif #ifndef FORCE_REAL_TIME_LOAD uwNumOfA3dGENERAL= _p_stAnim3d->uwNumOfA3dGENERAL; #endif p_stCurrentA3dGENERAL = fn_p_GetA3dGENERAL(uwNumOfA3dGENERAL,_uwFrame); #ifdef A3X_N64 /* ----------------------------------------------------------------------------------*/ /* check if anim cutting is well done*/ #ifdef ANIM_DEBUG if ((_uwFrame < p_stCurrentA3dGENERAL->uwStartFrame) || (_uwFrame >= p_stCurrentA3dGENERAL->uwEndFrame) ) { osSyncPrintf("Probleme decoupage d'animation (anim= %d, Frame= %d, StartFrame= %d, EndFrame= %d)\n", uwNumOfA3dGENERAL, _uwFrame, p_stCurrentA3dGENERAL->uwStartFrame, p_stCurrentA3dGENERAL->uwEndFrame); osSyncPrintf("Animation originelle : %d\n",_p_stAnim3d->uwNumOfA3dGENERAL); ASM_BREAK; } #endif /* ANIM_DEBUG */ #endif /*A3X_N64*/ #ifndef U64 #pragma warning(disable:4244) #endif _uwFrame -= p_stCurrentA3dGENERAL->uwStartFrame; #ifndef U64 #pragma warning(default:4244) #endif /* ----------------------------------------------------------------------------------*/ /* Get information to update frame info*/ p_stCurrentOnlyFrame = &p_stOnlyFrames[p_stCurrentA3dGENERAL->uwNumOfFirstOnlyFrame + _uwFrame]; /* ----------------------------------------------------------------------------------*/ /* Set Angular Speed Matrix if exist*/ if (p_stCurrentOnlyFrame->uwNumOfAngularSpeedQuat == SEB_Invalid) { return NULL; } else { tdxQuater4 a4_xQuatOri; fn_v_ExpandQuat(a4_xQuatOri,p_a4_xQuaternions[p_stCurrentOnlyFrame->uwNumOfAngularSpeedQuat]); /* if (_uwFrame != 1) fn_v_InterpolQuatWithOmega( a4_xQuatOri, a4_xQuater1, a4_xQuatOri, (SEB_xReal)_uwFrame, p_stCurrentOnlyFrame->uwAngSpeedQuat ); */ fn_v_QuatToMatrix(*((tdxMatrix33 *) (p_stMatrix)),a4_xQuatOri); return p_stMatrix; } } #undef A3X_INTN_C