reman3/Rayman_X/cpa/tempgrp/GAM/PlayAnim/Interpol/a3x_intn.c

990 lines
38 KiB
C

/* ***********************************************************************************/
/* * "a3x_intn.c" **/
/* * Written by : Sébastien Rubens **/
/* * Tabulations : 4 char **/
/* ***********************************************************************************/
#define A3X_INTN_C
/* ***********************************************************************************/
/* Included files*/
#include <math.h>
/*#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;uwCnt1<p_stCurrentA3dGENERAL->uwNumberOfChannels;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;uwCnt1<p_stCurrentA3dGENERAL->uwNumberOfChannels;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