990 lines
38 KiB
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
|