2759 lines
115 KiB
C++
2759 lines
115 KiB
C++
// **********************************************************************************
|
|
// * "l_optim_v6.c" *
|
|
// * Written by : Sébastien Rubens *
|
|
// * Tabulations : 4 char *
|
|
// **********************************************************************************
|
|
#define L_OPTIM_V6_C
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
// Included files
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include "SCR.h"
|
|
|
|
#include "specif\\a3x_pref.h"
|
|
#include "structur\\anim_s.h"
|
|
|
|
|
|
#include "a3x_glob.h"
|
|
#include "makeanim.h"
|
|
#include "l_Tbl_v6.h"
|
|
#include "l_global_v6.h"
|
|
#include "l_optim_v6.h"
|
|
#include "a3x_int.h"
|
|
#include "a3x_intb.h"
|
|
|
|
// **********************************************************************************
|
|
// define Files Path
|
|
#define ERROR_DIR "MakeAnim\\ErrorFile"
|
|
#define WARNING_DIR "MakeAnim\\WarningFile"
|
|
#define SIZEOF_DIR "MakeAnim\\SizeOf"
|
|
#define EVENT_DIR "MakeAnim\\EventIn"
|
|
|
|
#define A3xDebug
|
|
//#define MoveEvent
|
|
|
|
#define SeuilAngCentre 4
|
|
|
|
// parametrable variables
|
|
extern SEB_xReal xEps;
|
|
extern SEB_xReal xOneSubEps;
|
|
|
|
// Frequence of forced KeyFrame
|
|
int iKeyFreq = 1;
|
|
|
|
// **********************************************************************************
|
|
unsigned short a100_TabNbElt[100];
|
|
|
|
static unsigned long ulSToMem0, ulSToKeyFrame0, ulSToFrame0, ulSToChannel0, ulSToOnlyFrame0, ulSToHierarchy0, ulSToGeneral0, ulSToEvents0;
|
|
static unsigned long ulSToMem1, ulSToKeyFrame1, ulSToFrame1, ulSToChannel1, ulSToOnlyFrame1, ulSToHierarchy1, ulSToGeneral1, ulSToEvents1;
|
|
static unsigned long ulSToMem2, ulSToKeyFrame2, ulSToFrame2, ulSToChannel2, ulSToOnlyFrame2, ulSToHierarchy2, ulSToGeneral2, ulSToEvents2;
|
|
static unsigned long ulTotMem0, ulTotKeyFrame0, ulTotFrame0, ulTotChannel0, ulTotOnlyFrame0, ulTotHierarchy0, ulTotGeneral0, ulTotEvents0;
|
|
static unsigned long ulTotMem1, ulTotKeyFrame1, ulTotFrame1, ulTotChannel1, ulTotOnlyFrame1, ulTotHierarchy1, ulTotGeneral1, ulTotEvents1;
|
|
static unsigned long ulTotMem2, ulTotKeyFrame2, ulTotFrame2, ulTotChannel2, ulTotOnlyFrame2, ulTotHierarchy2, ulTotGeneral2, ulTotEvents2;
|
|
static signed long slNbTotVect, slNbTotQuat;
|
|
static unsigned long ulNbVect1, ulNbQuat1; // Total number of quaternions equals to identity
|
|
SEB_xReal fSToTime2, fTotTime2;
|
|
|
|
static signed short uwOrder, uwCalc;
|
|
static signed short swReadedWord;
|
|
static signed long slReadedLong;
|
|
static float fReadedFloat;
|
|
|
|
static unsigned long ulTotNbAnims= 0;
|
|
static unsigned long ax_MemSizes[2000], ax_RomSizes[2000];
|
|
|
|
static unsigned short ax_uwTabSavedChannels[500];
|
|
static unsigned short ax_uwTabSavedFrames[500];
|
|
static unsigned short ax_uwTabChannelWithOnlyEvents[500];
|
|
static unsigned short ax_uwTabMoveEventToChannel[500];
|
|
//static signed short ax_swUsedChannelForHierarchy[1000];
|
|
|
|
#ifdef A3xDebug
|
|
static unsigned short uwA3xDebug= 1;
|
|
#else
|
|
static unsigned short uwA3xDebug= 0;
|
|
#endif
|
|
|
|
static unsigned short uwDirectory= 1; // Animation in directory
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
void fn_v_ShowVect( FILE *out, tdxVector3 _p_a3_xVect )
|
|
{
|
|
fprintf( out, "(%3.8f, %3.8f, %3.8f)\n", _p_a3_xVect[0],
|
|
_p_a3_xVect[1],
|
|
_p_a3_xVect[2] );
|
|
}
|
|
|
|
|
|
|
|
void fn_v_ShowQuat( FILE *out, tdxQuater4 _p_a4_xQuat )
|
|
{
|
|
fprintf( out, "(%3.8f, %3.8f, %3.8f, %3.8f)\n", _p_a4_xQuat[0],
|
|
_p_a4_xQuat[1],
|
|
_p_a4_xQuat[2],
|
|
_p_a4_xQuat[3] );
|
|
}
|
|
|
|
|
|
// **********************************************************************************
|
|
// Modif 23/07/98 Kill couple when a channel have invalid channel number - Carlos Torres
|
|
void fn_v_VerifyAnimationV6i( unsigned short uwNbAnims )
|
|
{ signed long uwCnt1, uwCnt2, uwCnt3, uwCnt4, uwMax1, uwMax2;
|
|
signed long slNumOfVector, slNumOfQuaternion;
|
|
signed long slNumOfOnlyFrames, slNumOfChannels;
|
|
signed long slNumOfFrames, slNumOfHierarchyCouples, slNumOfHierarchyCouples2;
|
|
signed long uwInterpol, uwLastAttribute, uwLastKeyFrame;
|
|
signed short uwEmpty;
|
|
unsigned short uwLastSavedChannel;
|
|
tdxMatrix33 a3a3_xMtxOri, a3a3_xMtxSca, a3a3_xScaleMatrix;
|
|
tdxVector3 a3_xTmpVec;
|
|
#ifdef MoveEvent
|
|
signed long uwCnt5, slNumChannel, slNumOfEvents, slNumOfFrames2;
|
|
signed short uwEmpty, uwEmptyEvent, uwMove1, uwMove2;
|
|
#endif
|
|
|
|
printf("Verifications ------------------\n");
|
|
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel= 1;
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].uwGenerateChannel= 0;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwChildrenInHierarchy= 0;
|
|
}
|
|
}
|
|
|
|
// Kill empty (or only with sound) channels -------------------------------------
|
|
#ifdef KillChannels
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
|
|
// For each Frame
|
|
uwEmpty= 0; // Not used !
|
|
ax_uwTabChannelWithOnlyEvents[uwCnt2]= 1;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) == TE_Event )
|
|
{ // If we have an event
|
|
if ( (ax_tdstTabTBL[ ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable ].ucTypeOfEvent == C_ucMECHANIC_EVENT) ||
|
|
(ax_tdstTabTBL[ ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable ].ucTypeOfEvent == C_ucSOUND_EVENT) )
|
|
{ // If we have a mechanic ou a sound event -> transform it to empty object
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject= (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0xFF00) | TE_EmptyObject;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable= -1;
|
|
|
|
}
|
|
// GENERATE
|
|
if (ax_tdstTabTBL[ ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable ].ucTypeOfEvent == C_ucGENERATE_EVENT)
|
|
{ ax_tdstChannels[slNumOfChannels + uwCnt2].uwGenerateChannel= 1;
|
|
uwEmpty= 1;
|
|
}
|
|
// GENERIC
|
|
else if (ax_tdstTabTBL[ ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable ].ucTypeOfEvent == C_ucGENERIC_EVENT)
|
|
uwEmpty= 1;
|
|
}
|
|
else
|
|
{ // We don't have an event
|
|
if ( ((ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) != TE_EmptyObject) )
|
|
{ // We don't have (an EmptyObject or an UndefinedObject)
|
|
ax_uwTabChannelWithOnlyEvents[uwCnt2]= 0;
|
|
uwEmpty= 1; // Object is not empty => no empty channel
|
|
}
|
|
}
|
|
|
|
}
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel= uwEmpty;
|
|
// if (uwEmpty == 1)
|
|
// fprintf( WarningFile, "Empty channel (%d) : %s\n", uwCnt2+1, szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
|
|
#ifdef MoveEvent
|
|
// Reduce number of channels events
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// If we have a channel only with events
|
|
if ( (ax_uwTabChannelWithOnlyEvents[uwCnt2] == 1) &&
|
|
(ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1) )
|
|
{ uwMove1= 0;
|
|
// For each frames
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have an event
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) == TE_Event )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eDoubleKey;
|
|
|
|
uwMove2= 0;
|
|
// For all the rest of channels
|
|
for ( uwCnt4=(uwCnt2+1) ; uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt4++ )
|
|
{ slNumOfFrames2= ax_tdstChannels[slNumOfChannels + uwCnt4].slNumOfFrames;
|
|
// If we have a channel only with events
|
|
if ( (ax_uwTabChannelWithOnlyEvents[uwCnt4] == 1) &&
|
|
(ax_tdstChannels[slNumOfChannels + uwCnt4].uwUsedChannel == 1) )
|
|
{ // If we have an event
|
|
if ( (ax_tdstFrames[slNumOfFrames2 + uwCnt3].uwTypeOfObject & 0x00FF) == TE_EmptyObject )
|
|
{ // We can move the event
|
|
ax_uwTabMoveEventToChannel[uwCnt2]= (unsigned short) uwCnt4;
|
|
uwMove2= 1;
|
|
}
|
|
}
|
|
}
|
|
if ( uwMove2 == 0 )
|
|
uwMove1= 1; // We can't move channel
|
|
}
|
|
}
|
|
// Move the event infos if possible
|
|
if ( uwMove1 == 0 )
|
|
{ ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel= 0;
|
|
slNumOfFrames2= ax_tdstChannels[slNumOfChannels + ax_uwTabMoveEventToChannel[uwCnt2]].slNumOfFrames;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have an event
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) == TE_Event )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable= ax_tdstFrames[slNumOfFrames2 + uwCnt3].swNumberInTable;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject= ax_tdstFrames[slNumOfFrames2 + uwCnt3].uwTypeOfObject;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwFrameNumber= ax_tdstFrames[slNumOfFrames2 + uwCnt3].uwFrameNumber;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].xDistMaster= ax_tdstFrames[slNumOfFrames2 + uwCnt3].xDistMaster;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask= ax_tdstFrames[slNumOfFrames2 + uwCnt3].uwMask;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= ax_tdstFrames[slNumOfFrames2 + uwCnt3].uwAttribute;
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri, ax_tdstFrames[slNumOfFrames2 + uwCnt3].a4_xQuatOri );
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca, ax_tdstFrames[slNumOfFrames2 + uwCnt3].a4_xQuatSca );
|
|
fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues, ax_tdstFrames[slNumOfFrames2 + uwCnt3].a3_xScaleValues );
|
|
fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition, ax_tdstFrames[slNumOfFrames2 + uwCnt3].a3_xPosition );
|
|
fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition, ax_tdstFrames[slNumOfFrames2 + uwCnt3].a3_xWorldPivotPosition );
|
|
}
|
|
}
|
|
// Change channel references
|
|
uwCnt4= ax_tdstChannels[slNumOfChannels + uwCnt2].uwChannelNumber;
|
|
uwCnt5= ax_tdstChannels[slNumOfChannels + ax_uwTabMoveEventToChannel[uwCnt2]].uwChannelNumber;
|
|
slNumOfEvents= ax_tdstA3dGENERAL[uwCnt1].slNumOfEvents;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents ; uwCnt3++ )
|
|
{ if ( (ax_tdstEvents[slNumOfEvents + uwCnt3].uwTypeOfEvent == C_ucGENERIC_EVENT) ||
|
|
(ax_tdstEvents[slNumOfEvents + uwCnt3].uwTypeOfEvent == C_ucGENERATE_EVENT) )
|
|
{ slNumChannel= (ax_tdstEvents[slNumOfEvents + uwCnt3].ulValue & 0x00FFFF00) >> 8;
|
|
if ( (unsigned short) slNumChannel == uwCnt4 )
|
|
{ ax_tdstEvents[slNumOfEvents + uwCnt3].ulValue&= 0x000000FF;
|
|
ax_tdstEvents[slNumOfEvents + uwCnt3].ulValue|= (uwCnt5 << 8);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Rebuild hierarchy for killed channels
|
|
uwLastSavedChannel= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ ax_uwTabSavedChannels[uwCnt2]= uwLastSavedChannel;
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
uwLastSavedChannel++;
|
|
}
|
|
|
|
// Kill unused hierarchies
|
|
// For channel unused
|
|
// For bad channal with undefined channel number
|
|
slNumOfHierarchyCouples= ax_tdstA3dGENERAL[uwCnt1].slNumOfHierarchies;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies ; uwCnt2++ ) {
|
|
if ((ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild].uwUsedChannel == 0) ||
|
|
(ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild].uwChannelNumber == SEB_Invalid) ||
|
|
(ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather].uwUsedChannel == 0) ||
|
|
(ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather].uwChannelNumber == SEB_Invalid) )
|
|
{
|
|
// bad child
|
|
if ((ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild].uwUsedChannel == 0) ||
|
|
(ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild].uwChannelNumber == SEB_Invalid) )
|
|
{
|
|
// channel killed
|
|
if (ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild].uwUsedChannel == 0)
|
|
fprintf(ErrorFile, "Hierarchy Couple suppressed : An unused channel (%d) is Child of hierarchy !!! (%s)\n",ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild+1,szAnimName(&stAnims[uwCnt1]));
|
|
// bad channel number
|
|
else
|
|
fprintf(ErrorFile, "Hierarchy Couple suppressed : channel %d with Bad name is Child of hierarchy !!! (%s)\n",ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwChild+1,szAnimName(&stAnims[uwCnt1]));
|
|
|
|
ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwChild= SEB_Invalid;
|
|
}
|
|
// bad father
|
|
if ((ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather].uwUsedChannel == 0) ||
|
|
(ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather].uwChannelNumber == SEB_Invalid) )
|
|
{
|
|
// channel killed
|
|
if (ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather].uwUsedChannel == 0)
|
|
fprintf(ErrorFile, "Hierarchy Couple suppressed : An unused channel (%d) is Father of hierarchy !!! (%s)\n",ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather,szAnimName(&stAnims[uwCnt1]));
|
|
// bad channel number
|
|
else
|
|
fprintf(ErrorFile, "Hierarchy Couple suppressed : channel %d with Bad name is Father of hierarchy !!! (%s)\n",ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt2].uwFather,szAnimName(&stAnims[uwCnt1]));
|
|
|
|
ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwFather= SEB_Invalid;
|
|
}
|
|
}
|
|
}
|
|
|
|
// For only frames, count used hierarchies
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples;
|
|
uwCnt4= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples ; uwCnt3++ )
|
|
{
|
|
if ( (ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwChild == SEB_Invalid) ||
|
|
(ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwFather == SEB_Invalid) )
|
|
{
|
|
uwCnt4--;
|
|
}
|
|
}
|
|
ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples= (unsigned short) uwCnt4;
|
|
// Calculate new hierachy indice in table
|
|
slNumOfHierarchyCouples= ax_tdstA3dGENERAL[uwCnt1].slNumOfHierarchies;
|
|
uwCnt4= slNumOfHierarchyCouples;
|
|
for ( uwCnt3=slNumOfHierarchyCouples ; uwCnt3<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples ; uwCnt3++ )
|
|
{ if ( (ax_tdstHierarchies[ uwCnt3 ].uwChild != SEB_Invalid) &&
|
|
(ax_tdstHierarchies[ uwCnt3 ].uwFather != SEB_Invalid) )
|
|
{ uwCnt4++;
|
|
|
|
}
|
|
}
|
|
ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples= uwCnt4;
|
|
}
|
|
|
|
// Calculate new hierarchy indice in table and total number of hierarchies
|
|
uwCnt3= 0;
|
|
slNumOfHierarchyCouples= ax_tdstA3dGENERAL[uwCnt1].slNumOfHierarchies;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies ; uwCnt2++ )
|
|
{ if ( (ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwChild != SEB_Invalid) &&
|
|
(ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwFather != SEB_Invalid) )
|
|
{ ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwChild= ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwChild;
|
|
ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwFather= ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt2 ].uwFather;
|
|
uwCnt3++;
|
|
}
|
|
}
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies= (unsigned short) uwCnt3;
|
|
|
|
// To avoid problem with zero channel animation after simplification
|
|
// For each Channel
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
uwCnt3= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ uwCnt3+= ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel;
|
|
}
|
|
|
|
if (uwCnt3 == 0)
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels].slNumOfFrames;
|
|
|
|
fprintf(WarningFile, "Zero channels in animation %s\n",szAnimName(&stAnims[uwCnt1]));
|
|
|
|
// First elements of vector table and quaternion table
|
|
slNumOfVector= ax_tdstA3dGENERAL[uwCnt1].slNumOfVectors;
|
|
slNumOfQuaternion= ax_tdstA3dGENERAL[uwCnt1].slNumOfQuaternions;
|
|
fn_v_SetZeroVector( axa3_xVertexes[slNumOfVector] );
|
|
fn_v_SetIdQuater( axa4_xBinQuaternions[slNumOfQuaternion] );
|
|
|
|
// New first channel infos
|
|
ax_tdstChannels[slNumOfChannels].uwUsedChannel= 1; // Channel is used
|
|
ax_tdstChannels[slNumOfChannels].uwNumberOfKeys= 1;
|
|
ax_tdstChannels[slNumOfChannels].uwGenerateChannel= 0;
|
|
ax_tdstChannels[slNumOfChannels].slNumOfLocalPivotPos= slNumOfVector;
|
|
fn_v_SetZeroVector( ax_tdstChannels[slNumOfChannels].a3_xLocalPivotPos );
|
|
|
|
// For all frame
|
|
for ( uwCnt3=1 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject= TE_EmptyObject;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable= -1;
|
|
fn_v_SetIdQuater( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri );
|
|
fn_v_SetIdQuater( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca );
|
|
fn_v_SetZeroVector( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues );
|
|
fn_v_SetZeroVector( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition );
|
|
fn_v_SetZeroVector( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition );
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].xDistMaster= xOne;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask= 0x0000;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eNoKey;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatOri= slNumOfQuaternion;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatSca= slNumOfQuaternion;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfScaleValues= slNumOfVector;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfPosition= slNumOfVector;
|
|
}
|
|
|
|
// For first frame
|
|
ax_tdstFrames[slNumOfFrames + 0].uwMask= (SEB_xMaskLastKey|SEB_xMaskIdScaleValues|SEB_xMaskIdQuatSca|SEB_xMaskIdQuatOri|SEB_xMaskAllLow);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Test for empty module with ChildrenInHierarchy
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples ; uwCnt3++ )
|
|
{ ax_tdstFrames[ ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwFather
|
|
].slNumOfFrames + uwCnt2 ].uwChildrenInHierarchy= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Test for (intro) bug of hierarchy and CHL ---------------------------------
|
|
/*for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (TabValidAnimations[uwCnt1] == 1)
|
|
continue;
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<1000 ; uwCnt3++ )
|
|
ax_swUsedChannelForHierarchy[uwCnt3]= -1;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples ; uwCnt3++ )
|
|
{
|
|
uwCnt4= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwChild;
|
|
if (ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber == SEB_Invalid)
|
|
{ fprintf( ErrorFile, "(Child) Channel %d without a name is hierarchized , frame %d (%s)\n", (uwCnt4+1), (uwCnt2+1), szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
else
|
|
{
|
|
if (ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ] < 0)
|
|
{ ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ]= (signed short) uwCnt4;
|
|
}
|
|
else
|
|
{
|
|
if (ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ] != uwCnt4)
|
|
fprintf( ErrorFile, "CHL / Hierarchy (child) problem on channel %d, frame %d (%s)\n", (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwChild+1), (uwCnt2+1), szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
}
|
|
|
|
uwCnt4= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwFather;
|
|
if (ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber == SEB_Invalid)
|
|
{ fprintf( ErrorFile, "(Father) Channel %d without a name is hierarchized , frame %d (%s)\n", (uwCnt4+1), (uwCnt2+1), szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
else
|
|
{
|
|
if (ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ] < 0)
|
|
{ ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ]= (signed short) uwCnt4;
|
|
}
|
|
else
|
|
{
|
|
if (ax_swUsedChannelForHierarchy[ ax_tdstChannels[slNumOfChannels + uwCnt4].uwChannelNumber ] != uwCnt4)
|
|
fprintf( ErrorFile, "CHL / Hierarchy (father) problem on channel %d, frame %d (%s)\n", (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwFather+1), (uwCnt2+1), szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
// Verify keys and reset interpolation mask -------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ static unsigned long ulLastMask;
|
|
int iNextKeyFrame = 1; // first forced key frame always on the first frame
|
|
|
|
slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// For each Frame
|
|
uwInterpol= 0; // Datas is non interpolated
|
|
uwLastAttribute= 0;
|
|
ulLastMask= 0; // Last interpolation mask
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute == eNoKey ) // If we have no Key
|
|
{
|
|
// If (we are not interpolated) or (we are interpolated and the mask is incomplete)
|
|
if ( (uwInterpol == 0) ||
|
|
((uwInterpol != 0) && (ulLastMask != 0x00000777)) )
|
|
{
|
|
|
|
if ((uwInterpol != 0) && (ulLastMask != 0x00000777))
|
|
{ fprintf( WarningFile, "Channel %d, frame %d, mask is incomplete in %s\n", (uwCnt2+1), (uwCnt3+1), szAnimName(&stAnims[uwCnt1]) );
|
|
}
|
|
|
|
// Force a Key for non-optimized anim
|
|
if (!(--iNextKeyFrame) || (uwCnt3 == (ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames - 1))) {
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute = eDoubleKey; // We set a Key
|
|
iNextKeyFrame = iKeyFreq;
|
|
}
|
|
|
|
if ((ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) == TE_EmptyObject)
|
|
{ // Reset datas because we have an empty object
|
|
if ( (ax_tdstChannels[slNumOfChannels + uwCnt2].uwGenerateChannel == 0) &&
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].uwChildrenInHierarchy == 0) )
|
|
{
|
|
fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition, a3_xVector0 );
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri, a4_xQuater1 );
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca, a4_xQuater1 );
|
|
fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues, a3_xVector1 );
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eDoubleKey;
|
|
}
|
|
// else
|
|
// {
|
|
// printf("%s (channel %d , frame %d)\n", szAnimName(&stAnims[uwCnt1]), uwCnt2+1, uwCnt3+1);
|
|
// }
|
|
// Reset other values
|
|
fn_v_QuatToMatrix( a3a3_xMtxSca, ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca );
|
|
fn_v_QuatToMatrix( a3a3_xMtxOri, ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri );
|
|
fn_v_InvRotDiaRot( a3a3_xScaleMatrix, a3a3_xMtxSca, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues );
|
|
fn_v_MatrixByVector( a3_xTmpVec, a3a3_xScaleMatrix, ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos );
|
|
fn_v_MatrixByVector( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition, a3a3_xMtxOri, a3_xTmpVec );
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition[0]+= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[0];
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition[1]+= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[1];
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xWorldPivotPosition[2]+= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[2];
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].xDistMaster= fn_x_VectorLength( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition );
|
|
}
|
|
}
|
|
}
|
|
else if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute == eSimpleKey )
|
|
{ if (uwInterpol == 0) // If we have a simple key
|
|
uwInterpol= 1; // We begin interpolation
|
|
else uwInterpol= 0; // Else We stop interpolation
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eDoubleKey;
|
|
uwLastAttribute= eSimpleKey;
|
|
ulLastMask= ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask;
|
|
uwLastKeyFrame= uwCnt3;
|
|
}
|
|
else //if ( tdstFrames[slNumOfFrames + uwCnt3].uwAttribute == eDoubleKey )
|
|
{ uwInterpol= 1; // Begin interpolation
|
|
uwLastAttribute= eDoubleKey;
|
|
uwLastKeyFrame= uwCnt3;
|
|
ulLastMask= ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask;
|
|
}
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask= 0x0000;
|
|
}
|
|
if ( (uwInterpol == 1) && (uwLastAttribute == eDoubleKey) )
|
|
fprintf( WarningFile, "Channel %d terminated by a double key in %s\n", (uwCnt2+1), szAnimName(&stAnims[uwCnt1]) );
|
|
|
|
if (uwLastAttribute != eNoKey)
|
|
{ for ( uwCnt3=uwLastKeyFrame+1; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) != TE_EmptyObject )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eDoubleKey;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Set hierarchies bit ---------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples;
|
|
|
|
// SEB_xTypeHierarchized
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples ; uwCnt3++ )
|
|
{ ax_tdstFrames[ ax_tdstChannels[slNumOfChannels + ax_tdstHierarchies[ slNumOfHierarchyCouples + uwCnt3 ].uwChild
|
|
].slNumOfFrames + uwCnt2 ].uwTypeOfObject |= SEB_xTypeHierarchized;
|
|
}
|
|
|
|
// SEB_xTypeChangeOfHierarchy
|
|
uwMax1= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].uwHierarchyNbCouples;
|
|
if (uwCnt2 == (ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames-1))
|
|
uwMax2= ax_tdstOnlyFrames[slNumOfOnlyFrames].uwHierarchyNbCouples;
|
|
else uwMax2= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2 + 1].uwHierarchyNbCouples;
|
|
|
|
slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2].slNumOfHierarchyCouples;
|
|
if (uwCnt2 == (ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames-1))
|
|
slNumOfHierarchyCouples2= ax_tdstOnlyFrames[slNumOfOnlyFrames].slNumOfHierarchyCouples;
|
|
else slNumOfHierarchyCouples2= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt2 + 1].slNumOfHierarchyCouples;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<uwMax1 ; uwCnt3++ )
|
|
{ register unsigned short uwFlag;
|
|
|
|
uwFlag= 0;
|
|
for ( uwCnt4=0 ; uwCnt4<uwMax2 ; uwCnt4++ )
|
|
{
|
|
if ( (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwChild == ax_tdstHierarchies[slNumOfHierarchyCouples2 + uwCnt4].uwChild ) &&
|
|
(ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwFather == ax_tdstHierarchies[slNumOfHierarchyCouples2 + uwCnt4].uwFather) )
|
|
{ uwFlag= 1;
|
|
break;
|
|
}
|
|
}
|
|
if (uwFlag == 0)
|
|
{ register signed long slTmp;
|
|
|
|
uwCnt4= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwChild;
|
|
slTmp= ax_tdstChannels[slNumOfChannels + uwCnt4].slNumOfFrames + uwCnt2;
|
|
ax_tdstFrames[slTmp].uwTypeOfObject |= SEB_xTypeChangeOfHierarchy;
|
|
if ( ax_tdstFrames[slTmp + 1].uwAttribute == eNoKey )
|
|
{ fprintf( ErrorFile, "Change of hierarchy (type 1) not on KeyFrame (%s, channel #%d, frame #%d)\n", szAnimName(&stAnims[uwCnt1]), uwCnt4+1, uwCnt2+2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( uwCnt4=0 ; uwCnt4<uwMax2 ; uwCnt4++ )
|
|
{ register unsigned short uwFlag;
|
|
|
|
uwFlag= 0;
|
|
for ( uwCnt3=0 ; uwCnt3<uwMax1 ; uwCnt3++ )
|
|
{
|
|
if ( (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwChild == ax_tdstHierarchies[slNumOfHierarchyCouples2 + uwCnt4].uwChild ) &&
|
|
(ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt3].uwFather == ax_tdstHierarchies[slNumOfHierarchyCouples2 + uwCnt4].uwFather) )
|
|
{ uwFlag= 1;
|
|
break;
|
|
}
|
|
}
|
|
if (uwFlag == 0)
|
|
{ register signed long slTmp;
|
|
|
|
uwCnt3= ax_tdstHierarchies[slNumOfHierarchyCouples2 + uwCnt4].uwChild;
|
|
slTmp= ax_tdstChannels[slNumOfChannels + uwCnt3].slNumOfFrames + uwCnt2;
|
|
ax_tdstFrames[slTmp].uwTypeOfObject |= SEB_xTypeChangeOfHierarchy;
|
|
if ( ax_tdstFrames[slTmp + 1].uwAttribute == eNoKey )
|
|
{ fprintf( ErrorFile, "Change of hierarchy (type 2) not on KeyFrame (%s, channel #%d, frame #%d)\n", szAnimName(&stAnims[uwCnt1]), uwCnt3+1, uwCnt2+2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
// SEB_xTypeChangeOfHierarchy ("Object" frame t, Empty frame t+1)
|
|
if (uwCnt3 < (ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames - 1))
|
|
{
|
|
if ( ((ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) != TE_EmptyObject) &&
|
|
((ax_tdstFrames[slNumOfFrames + uwCnt3 + 1].uwTypeOfObject & 0x00FF) == TE_EmptyObject) )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject |= SEB_xTypeChangeOfHierarchy;
|
|
// if ( ax_tdstFrames[slNumOfFrames + uwCnt3 + 1].uwAttribute == eNoKey )
|
|
// { fprintf( ErrorFile, "Change of hierarchy (type 3) not on KeyFrame (%s, channel #%d, frame #%d)\n", szAnimName(&stAnims[uwCnt1]), uwCnt2+1, uwCnt3+1 );
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Calcule number of key frame --------------------------------------------------
|
|
//printf("Number of key frames NumberOfChannels * NumberOfFrames Total channel\n");
|
|
ulTotGeneral0= uwNbAnims;
|
|
ulTotMem0= 0;
|
|
ulTotKeyFrame0= 0;
|
|
ulTotFrame0= 0;
|
|
ulTotChannel0= 0;
|
|
ulTotOnlyFrame0= 0;
|
|
ulTotHierarchy0= 0;
|
|
ulTotEvents0= 0;
|
|
|
|
fprintf( SizeOut, "Après chargement du fichier\n" );
|
|
fprintf( SizeOut, "KeyFrame Frame Channel OnlyFrame Hierarchy General Events Place Memoire\n" );
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
ulSToGeneral0= 1;
|
|
ulSToKeyFrame0= 0;
|
|
ulSToHierarchy0= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies;
|
|
ulSToOnlyFrame0= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
ulSToChannel0= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels;
|
|
ulSToEvents0= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents;
|
|
ulSToFrame0= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels * ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// For each key frame
|
|
uwCnt4= 0;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
uwCnt4++;
|
|
}
|
|
ulSToKeyFrame0+= uwCnt4;
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].uwNumberOfKeys= (unsigned short) uwCnt4;
|
|
}
|
|
ulSToMem0= ulSToGeneral0 * 64L + ulSToChannel0 * 16L + ulSToOnlyFrame0 * 6L +
|
|
ulSToKeyFrame0 * 32L + ulSToHierarchy0 * 4L + ulSToFrame0 * 4L +
|
|
ulSToOnlyFrame0 * (8+12); // + quaternions et vecteurs speed !!!
|
|
|
|
fprintf( SizeOut, "%8d %6d %7d %9d %9d %7d %6d %13d %s\n",
|
|
ulSToKeyFrame0, ulSToFrame0, ulSToChannel0, ulSToOnlyFrame0, ulSToHierarchy0, ulSToGeneral0,
|
|
ulSToEvents0, ulSToMem0, szAnimName(&stAnims[uwCnt1]) );
|
|
|
|
ulTotMem0+= ulSToMem0;
|
|
ulTotKeyFrame0+= ulSToKeyFrame0;
|
|
ulTotFrame0+= ulSToFrame0;
|
|
ulTotChannel0+= ulSToChannel0;
|
|
ulTotOnlyFrame0+= ulSToOnlyFrame0;
|
|
ulTotHierarchy0+= ulSToHierarchy0;
|
|
ulTotEvents0+= ulSToEvents0;
|
|
|
|
}
|
|
fprintf( SizeOut, "Totaux\n" );
|
|
fprintf( SizeOut, "%8d %6d %7d %9d %9d %7d %6d %10d\n",
|
|
ulTotKeyFrame0, ulTotFrame0, ulTotChannel0, ulTotOnlyFrame0, ulTotHierarchy0, ulTotGeneral0, ulTotEvents0, ulTotMem0 );
|
|
fprintf( SizeOut, "\n" );
|
|
|
|
printf("ulTotKeyFrame0= %d\n", ulTotKeyFrame0 );
|
|
printf("ulTotFrame0= %d\n", ulTotFrame0 );
|
|
printf("ulTotChannel0= %d\n", ulTotChannel0 );
|
|
printf("ulTotOnlyFrame0= %d\n", ulTotOnlyFrame0 );
|
|
printf("ulTotHierarchy0= %d\n", ulTotHierarchy0 );
|
|
printf("ulTotGeneral0= %d\n", ulTotGeneral0 );
|
|
printf("ulTotEvents0= %d\n", ulTotEvents0 );
|
|
|
|
printf("Memoire utilisee %d\n\n", ulTotMem0 );
|
|
}
|
|
|
|
|
|
#define Inv_128 0.0078125
|
|
#define Inv_256 0.00390625
|
|
|
|
// **********************************************************************************
|
|
void fn_v_DiscretizeScal( tdxVector3 _a3_xVect ) {
|
|
if ((fabs(_a3_xVect[0]) < Inv_256) && (fabs(_a3_xVect[0]) > xEps))
|
|
_a3_xVect[0] = Inv_128;
|
|
else
|
|
_a3_xVect[0]= (SEB_xReal)(((signed long) (_a3_xVect[0]*128.0+0.5)) / 128.0);
|
|
|
|
if ((fabs(_a3_xVect[1]) < Inv_256) && (fabs(_a3_xVect[1]) > xEps))
|
|
_a3_xVect[1] = Inv_128;
|
|
else
|
|
_a3_xVect[1]= (SEB_xReal)(((signed long) (_a3_xVect[1]*128.0+0.5)) / 128.0);
|
|
|
|
if ((fabs(_a3_xVect[2]) < Inv_256) && (fabs(_a3_xVect[2]) > xEps))
|
|
_a3_xVect[2] = Inv_128;
|
|
else
|
|
_a3_xVect[2]= (SEB_xReal)(((signed long) (_a3_xVect[2]*128.0+0.5)) / 128.0);
|
|
}
|
|
|
|
|
|
|
|
void fn_v_ClassicVector( tdxVector3 _a3_xVect )
|
|
{ unsigned short uwCnt;
|
|
|
|
for ( uwCnt=0 ; uwCnt<3 ; uwCnt++ )
|
|
if ( fabs(_a3_xVect[uwCnt]) < xEps )
|
|
_a3_xVect[uwCnt]= xZero;
|
|
|
|
for ( uwCnt=0 ; uwCnt<3 ; uwCnt++ )
|
|
if ( fabs(xOne - _a3_xVect[uwCnt]) < xEps )
|
|
_a3_xVect[uwCnt]= xOne;
|
|
}
|
|
|
|
void fn_v_ClassicQuaternion( tdxQuater4 _a4_xQuat )
|
|
{ tdxQuater4 a4_xQuatTest;
|
|
unsigned short uwCnt;
|
|
|
|
for ( uwCnt=0 ; uwCnt<4 ; uwCnt++ )
|
|
{ fn_v_CopyQuat( a4_xQuatTest, a4_xQuater0 );
|
|
a4_xQuatTest[uwCnt]= xOne;
|
|
if ( fn_uw_AreSameQuat( _a4_xQuat, a4_xQuatTest ) == 0 )
|
|
{ _a4_xQuat[0]= xZero;
|
|
_a4_xQuat[1]= xZero;
|
|
_a4_xQuat[2]= xZero;
|
|
_a4_xQuat[3]= xZero;
|
|
_a4_xQuat[uwCnt]= xOne;
|
|
return;
|
|
}
|
|
a4_xQuatTest[uwCnt]= -xOne;
|
|
if ( fn_uw_AreSameQuat( _a4_xQuat, a4_xQuatTest ) == 0 )
|
|
{ _a4_xQuat[0]= xZero;
|
|
_a4_xQuat[1]= xZero;
|
|
_a4_xQuat[2]= xZero;
|
|
_a4_xQuat[3]= xZero;
|
|
_a4_xQuat[uwCnt]= -xOne;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
SEB_xReal fn_uw_BinAngleBetweenVect( tdxVector3 _a3_xVec1,
|
|
tdxVector3 _a3_xVec2 )
|
|
{ register SEB_xReal xAngle;
|
|
|
|
xAngle= (SEB_xReal) acos( _a3_xVec1[0] * _a3_xVec2[0] +
|
|
_a3_xVec1[1] * _a3_xVec2[1] +
|
|
_a3_xVec1[2] * _a3_xVec2[2] );
|
|
return xAngle;
|
|
}
|
|
|
|
|
|
SEB_xReal fn_uw_BinAngleBetweenQuat( tdxQuater4 _a4_xQuat1,
|
|
tdxQuater4 _a4_xQuat2 )
|
|
{ register SEB_xReal xAngle;
|
|
|
|
xAngle= (SEB_xReal) acos( _a4_xQuat1[eQX] * _a4_xQuat2[eQX] +
|
|
_a4_xQuat1[eQY] * _a4_xQuat2[eQY] +
|
|
_a4_xQuat1[eQZ] * _a4_xQuat2[eQZ] +
|
|
_a4_xQuat1[eQW] * _a4_xQuat2[eQW] );
|
|
return xAngle;
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
void fn_v_OptimiseAnimationV6i( unsigned short uwNbAnims )
|
|
{ signed long uwCnt1, uwCnt2, uwCnt3, uwCnt4, uwCnt5, uwCnt6;
|
|
signed long slNumOfOnlyFrames, slNumOfChannels, slNumOfHierarchyCouples;
|
|
signed long slNumOfFrames;
|
|
tdxQuater4 a4_xQuatOri, a4_xQuatSca;
|
|
tdxMatrix33 a3a3_xMtxOri, a3a3_xMtxSca;
|
|
tdxVector3 a3_xPosition, a3_xVecSca;
|
|
|
|
printf("Optimisations ------------------\n");
|
|
|
|
// use default precision for classic vector
|
|
xEps = xDefaultEps;
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
|
|
// Set classic quaternions and vectors -----------------------------------------
|
|
// In StackVertexes
|
|
for ( uwCnt1=0 ; uwCnt1<M_GetStackPos(eStackBinVertexes) ; uwCnt1++ )
|
|
fn_v_ClassicVector( axa3_xVertexes[uwCnt1] );
|
|
// In StackQuaternions
|
|
for ( uwCnt1=0 ; uwCnt1<M_GetStackPos(eStackBinQuaternions) ; uwCnt1++ )
|
|
fn_v_ClassicQuaternion( axa4_xBinQuaternions[uwCnt1] );
|
|
// In StackChannels
|
|
for ( uwCnt1=0 ; uwCnt1<M_GetStackPos(eStackBinChannels) ; uwCnt1++ )
|
|
fn_v_ClassicVector( ax_tdstChannels[uwCnt1].a3_xLocalPivotPos );
|
|
// In StackOnlyFrames
|
|
for ( uwCnt1=0 ; uwCnt1<M_GetStackPos(eStackBinOnlyFrames) ; uwCnt1++ )
|
|
{ fn_v_ClassicQuaternion( ax_tdstOnlyFrames[uwCnt1].tdxAngularSpeedQuat );
|
|
fn_v_ClassicVector( ax_tdstOnlyFrames[uwCnt1].tdxSpeedVector );
|
|
}
|
|
// In StackFrames
|
|
for ( uwCnt1=0 ; uwCnt1<M_GetStackPos(eStackBinFrames) ; uwCnt1++ )
|
|
{ fn_v_ClassicQuaternion( ax_tdstFrames[uwCnt1].a4_xQuatOri );
|
|
fn_v_ClassicQuaternion( ax_tdstFrames[uwCnt1].a4_xQuatSca );
|
|
fn_v_ClassicVector( ax_tdstFrames[uwCnt1].a3_xScaleValues );
|
|
fn_v_ClassicVector( ax_tdstFrames[uwCnt1].a3_xPosition );
|
|
fn_v_DiscretizeScal( ax_tdstFrames[uwCnt1].a3_xScaleValues );
|
|
}
|
|
|
|
|
|
// Reset pivot positions -------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
uwCnt5= 1;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
// If we don't have a hierarchized objet
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & SEB_xTypeHierarchized) == 0x0000 )
|
|
uwCnt5= 0;
|
|
}
|
|
if (uwCnt5 == 1)
|
|
fn_v_SetZeroVector( ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos );
|
|
}
|
|
}
|
|
|
|
|
|
// Reset scale quaternion -------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{ tdxMatrix33 a3a3_xMtxOriSca, a3a3_xMtxSca;
|
|
|
|
// We have a diagonal matrix ?
|
|
fn_v_QuatToMatrix( a3a3_xMtxOriSca, ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca );
|
|
fn_v_InvRotDiaRot( a3a3_xMtxSca, a3a3_xMtxOriSca, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues );
|
|
if ( fn_uw_IsDiagonale(a3a3_xMtxSca) == 0 )
|
|
fn_v_SetIdQuater(ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca);
|
|
|
|
// Search next KeyFrame (k+1)
|
|
uwCnt4= uwCnt3 + 1;
|
|
while ( (uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute==eNoKey) )
|
|
uwCnt4++;
|
|
|
|
if ( uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames )
|
|
{ // Set scale quaternion
|
|
if ( (fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues, a3_xVector1) == 0) &&
|
|
(fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xScaleValues, a3_xVector1) == 0) )
|
|
{ // Copy identity vector and quaternion for all keys
|
|
for ( uwCnt5=uwCnt3 ; uwCnt5<=uwCnt4 ; uwCnt5++ )
|
|
{ fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt5].a3_xScaleValues, a3_xVector1 );
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt5].a4_xQuatSca, a4_xQuater1 );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ // Set last scale quaternion on last KeyFrame
|
|
if ( fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues, a3_xVector1) == 0 )
|
|
{ fn_v_CopyVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues, a3_xVector1 );
|
|
fn_v_CopyQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca, a4_xQuater1 );
|
|
}
|
|
}
|
|
uwCnt3= uwCnt4-1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Optimize KeyFrames ---------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
//if (ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1)
|
|
if ( (ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1) &&
|
|
(ax_tdstChannels[slNumOfChannels + uwCnt2].uwGenerateChannel == 0) ) // We are not on GenerateChannel
|
|
{
|
|
// For each KeyFrame
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{ signed long uwCntZ, uwFlag;
|
|
signed long uwFather3, uwFather4, uwFather5;
|
|
|
|
// Search next KeyFrame (k+1)
|
|
uwCnt4= uwCnt3 + 1;
|
|
while ( (uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute==eNoKey))
|
|
uwCnt4++;
|
|
|
|
// Search next next KeyFrame (k+2)
|
|
uwCnt5= uwCnt4 + 1;
|
|
while ( (uwCnt5<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt5].uwAttribute==eNoKey))
|
|
uwCnt5++;
|
|
|
|
if ( (uwCnt4 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) &&
|
|
(uwCnt5 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) )
|
|
{
|
|
uwFather3= -1;
|
|
uwFather4= -1;
|
|
uwFather5= -1;
|
|
|
|
slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt3].slNumOfHierarchyCouples;
|
|
for ( uwCnt6=0 ; uwCnt6<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt3].uwHierarchyNbCouples ; uwCnt6++ )
|
|
{
|
|
if (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwChild == uwCnt2)
|
|
{ uwFather3= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwFather;
|
|
break;
|
|
}
|
|
}
|
|
slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt4].slNumOfHierarchyCouples;
|
|
for ( uwCnt6=0 ; uwCnt6<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt3].uwHierarchyNbCouples ; uwCnt6++ )
|
|
{
|
|
if (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwChild == uwCnt2)
|
|
{ uwFather4= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwFather;
|
|
break;
|
|
}
|
|
}
|
|
slNumOfHierarchyCouples= ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt5].slNumOfHierarchyCouples;
|
|
for ( uwCnt6=0 ; uwCnt6<ax_tdstOnlyFrames[slNumOfOnlyFrames + uwCnt3].uwHierarchyNbCouples ; uwCnt6++ )
|
|
{
|
|
if (ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwChild == uwCnt2)
|
|
{ uwFather5= ax_tdstHierarchies[slNumOfHierarchyCouples + uwCnt6].uwFather;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// Test the hierarchy
|
|
if ((uwFather3 == uwFather4) && (uwFather4 == uwFather5))
|
|
{
|
|
// Optimize EmptyObject KeyFrames
|
|
uwFlag= 0;
|
|
for ( uwCntZ=uwCnt3+1 ; uwCntZ<uwCnt5 ; uwCntZ++ ) {
|
|
if ( ((ax_tdstFrames[slNumOfFrames + uwCntZ].uwTypeOfObject & 0x00FF) != TE_EmptyObject) ||
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].uwChildrenInHierarchy == 1) )
|
|
uwFlag= 1;
|
|
}
|
|
// All objects equal to EmptyObject
|
|
if (uwFlag == 0)
|
|
{
|
|
if ((ax_tdstFrames[slNumOfFrames + uwCnt5].uwTypeOfObject & 0x00FF) != TE_EmptyObject)
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= (SEB_xMaskQuatOri|SEB_xMaskQuatSca|SEB_xMaskScaleValues|SEB_xMaskPosition);
|
|
}
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey;
|
|
uwCnt3--;
|
|
}
|
|
else
|
|
{
|
|
if (ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask != (SEB_xMaskQuatOri|SEB_xMaskQuatSca|SEB_xMaskScaleValues|SEB_xMaskPosition))
|
|
{
|
|
fn_v_BinInterpolBetweenKeys( &ax_tdstFrames[slNumOfFrames + uwCnt3],
|
|
&ax_tdstFrames[slNumOfFrames + uwCnt5],
|
|
a3a3_xMtxOri,
|
|
a3a3_xMtxSca,
|
|
a3_xPosition,
|
|
(uwCnt4-uwCnt3)/(SEB_xReal)(uwCnt5-uwCnt3),
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos,
|
|
a4_xQuatOri,
|
|
a4_xQuatSca,
|
|
a3_xVecSca
|
|
);
|
|
if ( (fn_uw_AreSameQuat(ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatOri , a4_xQuatOri ) == 0) &&
|
|
(fn_uw_AreSameQuat(ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatSca , a4_xQuatSca ) == 0) &&
|
|
(fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xScaleValues, a3_xVecSca) == 0) &&
|
|
(fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xPosition, a3_xPosition) == 0) )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey; // Delete KeyFrame
|
|
uwCnt3--; // Dont change first KeyFrame
|
|
}
|
|
else
|
|
uwCnt3= uwCnt4 - 1; // Change of KeyFrame
|
|
}
|
|
else
|
|
uwCnt3= uwCnt4 - 1;
|
|
}
|
|
}
|
|
else
|
|
{ uwCnt3= uwCnt4 - 1;
|
|
}
|
|
}
|
|
else
|
|
{ if (uwCnt4 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames)
|
|
{
|
|
uwFlag= 0;
|
|
for ( uwCntZ=uwCnt3+1 ; uwCntZ<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCntZ++ ) {
|
|
if ( ((ax_tdstFrames[slNumOfFrames + uwCntZ].uwTypeOfObject & 0x00FF) != TE_EmptyObject) ||
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].uwChildrenInHierarchy == 1) )
|
|
uwFlag= 1;
|
|
}
|
|
// All objects equal to EmptyObject
|
|
if ( uwFlag == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey;
|
|
}
|
|
uwCnt3= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Optimize KeyFrames ---------------------------------------------------------
|
|
/* for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ )
|
|
{ slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
if (ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 0)
|
|
{
|
|
// For each KeyFrame
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{ signed long uwCntZ, uwFlag;
|
|
|
|
// Search next KeyFrame (k+1)
|
|
uwCnt4= uwCnt3 + 1;
|
|
while ( (uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute==eNoKey))
|
|
uwCnt4++;
|
|
// Search next next KeyFrame (k+2)
|
|
uwCnt5= uwCnt4 + 1;
|
|
while ( (uwCnt5<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt5].uwAttribute==eNoKey))
|
|
uwCnt5++;
|
|
|
|
// Optimize EmptyObject KeyFrames
|
|
if ( (uwCnt4 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) &&
|
|
(uwCnt5 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) )
|
|
{
|
|
uwFlag= 0;
|
|
for ( uwCntZ=uwCnt3+1 ; uwCntZ<uwCnt5 ; uwCntZ++ )
|
|
{ if ((ax_tdstFrames[slNumOfFrames + uwCntZ].uwTypeOfObject & 0x00FF) != TE_EmptyObject)
|
|
uwFlag= 1;
|
|
}
|
|
// All objects equal to EmptyObject
|
|
if (uwFlag == 0)
|
|
{
|
|
if ((ax_tdstFrames[slNumOfFrames + uwCnt5].uwTypeOfObject & 0x00FF) != TE_EmptyObject)
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= (SEB_xMaskQuatOri|SEB_xMaskQuatSca|SEB_xMaskScaleValues|SEB_xMaskPosition);
|
|
}
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey;
|
|
uwCnt3--;
|
|
}
|
|
else
|
|
{
|
|
fn_v_BinInterpolBetweenKeys( &ax_tdstFrames[slNumOfFrames + uwCnt3],
|
|
&ax_tdstFrames[slNumOfFrames + uwCnt5],
|
|
a3a3_xMtxOri,
|
|
a3a3_xMtxSca,
|
|
a3_xPosition,
|
|
(uwCnt4-uwCnt3)/(SEB_xReal)(uwCnt5-uwCnt3),
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos,
|
|
a4_xQuatOri,
|
|
a4_xQuatSca,
|
|
a3_xVecSca
|
|
);
|
|
if ( (fn_uw_AreSameQuat(ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatOri , a4_xQuatOri ) == 0) &&
|
|
(fn_uw_AreSameQuat(ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatSca , a4_xQuatSca ) == 0) &&
|
|
(fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xScaleValues, a3_xVecSca) == 0) &&
|
|
(fn_uw_AreSameVect(ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xPosition, a3_xPosition) == 0) )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey; // Delete KeyFrame
|
|
uwCnt3--; // Dont change first KeyFrame
|
|
}
|
|
else uwCnt3= uwCnt4 - 1; // Change of KeyFrame
|
|
}
|
|
}
|
|
else
|
|
{ if (uwCnt4 < ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames)
|
|
{
|
|
uwFlag= 0;
|
|
for ( uwCntZ=uwCnt3+1 ; uwCntZ<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCntZ++ )
|
|
{ if ( (ax_tdstFrames[slNumOfFrames + uwCntZ].uwTypeOfObject & 0x00FF) != TE_EmptyObject )
|
|
uwFlag= 1;
|
|
}
|
|
// All objects equal to EmptyObject
|
|
if ( uwFlag == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute= eNoKey;
|
|
}
|
|
uwCnt3= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
|
|
// Sort hierarchy couples -----------------------------------------------------
|
|
// A tester mais certainement pas plus rapide
|
|
|
|
// Set interpolation mask -----------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{ // Search next key
|
|
uwCnt4= uwCnt3 + 1;
|
|
while ( (uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames) && (ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute==eNoKey))
|
|
uwCnt4++;
|
|
|
|
if ( uwCnt4<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames )
|
|
{ tdxVector3 a3_xPosition1, a3_xPosition2;
|
|
|
|
// To avoid problems with interpolation between "normal" key and empty "key"
|
|
if ( (uwCnt4 == (uwCnt3+1)) && ((ax_tdstFrames[slNumOfFrames + uwCnt4].uwTypeOfObject & 0x00FF)== TE_EmptyObject))
|
|
{
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatOri;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatSca;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskScaleValues;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskPosition;
|
|
}
|
|
else
|
|
{
|
|
//ax_tdstFrames[slNumOfFrames + uwCnt4].uwMask= 0x0000;
|
|
if ( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatOri ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatOri;
|
|
if ( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].a4_xQuatSca ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatSca;
|
|
if ( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xScaleValues ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskScaleValues;
|
|
if ( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xPosition ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskPosition;
|
|
}
|
|
|
|
fn_v_CopyVect( a3_xPosition1, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition );
|
|
fn_v_CopyVect( a3_xPosition2, ax_tdstFrames[slNumOfFrames + uwCnt4].a3_xPosition );
|
|
fn_v_NormalizeVector( a3_xPosition1 );
|
|
fn_v_NormalizeVector( a3_xPosition2 );
|
|
uwCnt5= fn_uw_AngleBetweenVect( a3_xPosition1, a3_xPosition2 );
|
|
// if (uwCnt5 < SeuilAngCentre)
|
|
// ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskZeroAngCentre;
|
|
}
|
|
else
|
|
{ // Set Mask between last and first key
|
|
if ( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatOri ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatOri;
|
|
if ( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatSca ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskQuatSca;
|
|
if ( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues,
|
|
ax_tdstFrames[slNumOfFrames ].a3_xScaleValues ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskScaleValues;
|
|
if ( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition,
|
|
ax_tdstFrames[slNumOfFrames ].a3_xPosition ) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskPosition;
|
|
|
|
{ tdxVector3 a3_xPosition1, a3_xPosition2;
|
|
|
|
fn_v_CopyVect( a3_xPosition1, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition );
|
|
fn_v_CopyVect( a3_xPosition2, ax_tdstFrames[slNumOfFrames ].a3_xPosition );
|
|
fn_v_NormalizeVector( a3_xPosition1 );
|
|
fn_v_NormalizeVector( a3_xPosition2 );
|
|
uwCnt5= fn_uw_AngleBetweenVect( a3_xPosition1, a3_xPosition2 );
|
|
// if (uwCnt5 < SeuilAngCentre)
|
|
// ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskZeroAngCentre;
|
|
}
|
|
// Set mask (SEB_xTypeWrapLastKey) for wrapping animations
|
|
/* { register SEB_xReal xCompX, xCompY, xCompZ, xAngleOri, xAngleSca, xScaleVal, xDistance;
|
|
|
|
xAngleOri= fn_uw_BinAngleBetweenQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatOri );
|
|
xAngleSca= fn_uw_BinAngleBetweenQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatSca );
|
|
xCompX= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[0] - ax_tdstFrames[slNumOfFrames].a3_xPosition[0];
|
|
xCompY= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[1] - ax_tdstFrames[slNumOfFrames].a3_xPosition[1];
|
|
xCompZ= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition[2] - ax_tdstFrames[slNumOfFrames].a3_xPosition[2];
|
|
xScaleVal= xCompX*xCompX + xCompY*xCompY + xCompZ*xCompZ;
|
|
xCompX= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues[0] - ax_tdstFrames[slNumOfFrames].a3_xScaleValues[0];
|
|
xCompY= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues[1] - ax_tdstFrames[slNumOfFrames].a3_xScaleValues[1];
|
|
xCompZ= ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues[2] - ax_tdstFrames[slNumOfFrames].a3_xScaleValues[2];
|
|
xDistance= xCompX*xCompX + xCompY*xCompY + xCompZ*xCompZ;
|
|
if ( (xAngleOri < 0.005) &&
|
|
(xAngleSca < 0.005) &&
|
|
(xScaleVal < 0.005) &&
|
|
(xDistance < 0.005) )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xTypeWrapLastKey;
|
|
}
|
|
}*/
|
|
}
|
|
uwCnt3= uwCnt4-1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Kill extra KeyFrames ---------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
if (ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1)
|
|
{
|
|
// Search Last KeyFrame
|
|
uwCnt3= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames - 1;
|
|
while ( (uwCnt3>=0) && (ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute==eNoKey) )
|
|
uwCnt3--;
|
|
// Search Last Last KeyFrame
|
|
uwCnt4= uwCnt3 - 1;
|
|
while ( (uwCnt4>=0) && (ax_tdstFrames[slNumOfFrames + uwCnt4].uwAttribute==eNoKey) )
|
|
uwCnt4--;
|
|
|
|
// Optimize same KeyFrames
|
|
if ( ((uwCnt3>=0) && ((ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask & SEB_xMaskAllLow) == SEB_xMaskAllLow)) &&
|
|
((uwCnt4>=0) && ((ax_tdstFrames[slNumOfFrames + uwCnt4].uwMask & SEB_xMaskAllLow) == SEB_xMaskAllLow)) &&
|
|
( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatOri ) == 0 ) &&
|
|
( fn_uw_AreSameQuat( ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca,
|
|
ax_tdstFrames[slNumOfFrames ].a4_xQuatSca ) == 0 ) &&
|
|
( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues,
|
|
ax_tdstFrames[slNumOfFrames ].a3_xScaleValues ) == 0 ) &&
|
|
( fn_uw_AreSameVect( ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition,
|
|
ax_tdstFrames[slNumOfFrames ].a3_xPosition ) == 0 ) )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute= eNoKey; // NoKey
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Calculate number of KeyFrame -------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// For each KeyFrame
|
|
uwCnt4= 0;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ // If we have a KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
uwCnt4++;
|
|
}
|
|
ax_tdstChannels[slNumOfChannels + uwCnt2].uwNumberOfKeys= (unsigned short) uwCnt4;
|
|
}
|
|
}
|
|
|
|
|
|
// Clear Events -----------------------------------------------------------------
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{
|
|
// For each Frame
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ if ( (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0x00FF) == TE_Event )
|
|
{ ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject= (ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject & 0xFF00) | TE_EmptyObject;
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable= -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//printf("Number of key frames NumberOfChannels * NumberOfFrames Total channel\n");
|
|
ulTotGeneral1= uwNbAnims;
|
|
ulTotMem1= 0;
|
|
ulTotKeyFrame1= 0;
|
|
ulTotFrame1= 0;
|
|
ulTotChannel1= 0;
|
|
ulTotOnlyFrame1= 0;
|
|
ulTotHierarchy1= 0;
|
|
ulTotEvents1= 0;
|
|
|
|
fprintf( SizeOut, "Optimisations niveau 1\n" );
|
|
fprintf( SizeOut, "KeyFrame Frame Channel OnlyFrame Hierarchy General Events Place Memoire\n" );
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
ulSToGeneral1= 1;
|
|
ulSToKeyFrame1= 0;
|
|
ulSToHierarchy1= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies;
|
|
ulSToOnlyFrame1= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
ulSToChannel1= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels;
|
|
ulSToEvents1= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents;
|
|
ulSToFrame1= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels * ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
|
|
ulSToKeyFrame1= 0;
|
|
// For each Channel
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
ulSToKeyFrame1+= ax_tdstChannels[slNumOfChannels + uwCnt2].uwNumberOfKeys;
|
|
|
|
ulSToMem1= ulSToGeneral1 * 64L + ulSToChannel1 * 16L + ulSToOnlyFrame1 * 6L +
|
|
ulSToKeyFrame1 * 32L + ulSToHierarchy1 * 4L + ulSToFrame1 * 4L +
|
|
ulSToOnlyFrame1 * (8+12); // + quaternions et vecteurs speed !!!
|
|
|
|
fprintf( SizeOut, "%8d %6d %7d %9d %9d %7d %6d %13d %s\n",
|
|
ulSToKeyFrame1, ulSToFrame1, ulSToChannel1, ulSToOnlyFrame1, ulSToHierarchy1, ulSToGeneral1,
|
|
ulSToEvents1, ulSToMem1, szAnimName(&stAnims[uwCnt1]) );
|
|
|
|
ulTotMem1+= ulSToMem1;
|
|
ulTotKeyFrame1+= ulSToKeyFrame1;
|
|
ulTotFrame1+= ulSToFrame1;
|
|
ulTotChannel1+= ulSToChannel1;
|
|
ulTotOnlyFrame1+= ulSToOnlyFrame1;
|
|
ulTotHierarchy1+= ulSToHierarchy1;
|
|
ulTotEvents1+= ulSToEvents1;
|
|
}
|
|
fprintf( SizeOut, "Totaux\n" );
|
|
fprintf( SizeOut, "%8d %6d %7d %9d %9d %7d %6d %10d\n",
|
|
ulTotKeyFrame1, ulTotFrame1, ulTotChannel1, ulTotOnlyFrame1, ulTotHierarchy1, ulTotGeneral1, ulTotEvents1, ulTotMem1 );
|
|
fprintf( SizeOut, "\n" );
|
|
|
|
printf("ulTotKeyFrame1= %d\n", ulTotKeyFrame1);
|
|
printf("ulTotFrame1= %d\n", ulTotFrame1);
|
|
printf("ulTotChannel1= %d\n", ulTotChannel1);
|
|
printf("ulTotOnlyFrame1= %d\n", ulTotOnlyFrame1);
|
|
printf("ulTotHierarchy1= %d\n", ulTotHierarchy1);
|
|
printf("ulTotGeneral1= %d\n", ulTotGeneral1);
|
|
printf("ulTotEvents1= %d\n", ulTotEvents1);
|
|
|
|
printf("Memoire utilisee %d\n\n", ulTotMem1 );
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
unsigned long fn_uw_InsertVector( signed long _slStackStart,
|
|
tdxVector3 _tdxVect )
|
|
{ signed long slCnt1;
|
|
|
|
if ( fn_uw_CompVect( _tdxVect, a3_xVector1 ) == 0 )
|
|
ulNbVect1++;
|
|
|
|
for ( slCnt1=_slStackStart ; slCnt1<M_GetStackPos(eStackSavedVertexes) ; slCnt1++ )
|
|
{
|
|
if ( fn_uw_AreSameVect( ax_tdxSavedVertexes[slCnt1], _tdxVect ) == 0 )
|
|
return slCnt1;
|
|
}
|
|
fn_v_AllocateOnStack( eStackSavedVertexes, 1 );
|
|
fn_v_CopyVect( ax_tdxSavedVertexes[ M_GetStackAlloc(eStackSavedVertexes) ], _tdxVect );
|
|
|
|
return slCnt1;
|
|
}
|
|
|
|
|
|
|
|
unsigned long fn_uw_InsertQuater( signed long _slStackStart,
|
|
tdxQuater4 _tdxQuat )
|
|
{ signed long slCnt1;
|
|
|
|
if ( fn_uw_CompQuat( _tdxQuat, a4_xQuater1 ) == 0 )
|
|
ulNbQuat1++;
|
|
|
|
for ( slCnt1=_slStackStart ; slCnt1<M_GetStackPos(eStackSavedQuaternions) ; slCnt1++ )
|
|
{
|
|
if ( fn_uw_AreSameQuat( ax_tdxSavedQuaternions[slCnt1], _tdxQuat ) == 0 )
|
|
return slCnt1;
|
|
}
|
|
fn_v_AllocateOnStack( eStackSavedQuaternions, 1 );
|
|
fn_v_CopyQuat( ax_tdxSavedQuaternions[ M_GetStackAlloc(eStackSavedQuaternions) ], _tdxQuat );
|
|
return slCnt1;
|
|
}
|
|
|
|
|
|
|
|
unsigned long fn_uw_InsertNTTO( signed long _slStackStart,
|
|
signed short _swNumberInTable,
|
|
unsigned short _uwTypeOfObject,
|
|
unsigned char _ucTransparency )
|
|
{ signed long slCnt1;
|
|
|
|
for ( slCnt1=_slStackStart ; slCnt1<M_GetStackPos(eStackSavedNTTO) ; slCnt1++ )
|
|
{
|
|
if ( (ax_tdstSavedNTTO[slCnt1].ucNumberInTable == _swNumberInTable) &&
|
|
(ax_tdstSavedNTTO[slCnt1].uwTypeOfObject == _uwTypeOfObject) &&
|
|
(ax_tdstSavedNTTO[slCnt1].ucTransparency == _ucTransparency) )
|
|
return slCnt1;
|
|
}
|
|
fn_v_AllocateOnStack( eStackSavedNTTO, 1 );
|
|
ax_tdstSavedNTTO[ M_GetStackAlloc(eStackSavedNTTO) ].ucNumberInTable= _swNumberInTable;
|
|
ax_tdstSavedNTTO[ M_GetStackAlloc(eStackSavedNTTO) ].uwTypeOfObject= _uwTypeOfObject;
|
|
ax_tdstSavedNTTO[ M_GetStackAlloc(eStackSavedNTTO) ].ucTransparency= _ucTransparency;
|
|
return slCnt1;
|
|
}
|
|
|
|
|
|
|
|
/* comparison function for qsorting events on frame number */
|
|
|
|
static int fn_iCmpEventsOnFrameAndChannel(const void *va, const void *vb)
|
|
{
|
|
tdstBinEvent *a, *b;
|
|
|
|
a=(tdstBinEvent *)va;
|
|
b=(tdstBinEvent *)vb;
|
|
|
|
if(a->uwFrameNumber>b->uwFrameNumber)
|
|
return 1;
|
|
else if(a->uwFrameNumber<b->uwFrameNumber)
|
|
return -1;
|
|
else if(a->uwChannelNumber>b->uwChannelNumber)
|
|
return 1;
|
|
else if(a->uwChannelNumber<b->uwChannelNumber)
|
|
return -1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
// **********************************************************************************
|
|
void fn_v_OptimiseAnimation2V6i( unsigned short uwNbAnims )
|
|
{ signed long uwCnt1, uwCnt2, uwCnt3;
|
|
signed long slNumOfOnlyFrames, slNumOfChannels, slNumOfFrames;
|
|
signed long uwMinInVectors, uwMinInQuaternions, uwMinOfPositions, uwMinInNTTO;
|
|
signed long uwNumOfLastFrame, uwFlagChangeFrame;
|
|
signed long ulTotVectors2, ulTotQuaternions2;
|
|
|
|
printf("Optimisations2 ----------------\n");
|
|
|
|
// Kill duplicated vectors and quaternions -------------------------------------
|
|
ulTotGeneral2= uwNbAnims;
|
|
ulTotMem2= 0;
|
|
ulTotKeyFrame2= 0;
|
|
ulTotFrame2= 0;
|
|
ulTotChannel2= 0;
|
|
ulTotOnlyFrame2= 0;
|
|
ulTotHierarchy2= 0;
|
|
ulTotEvents2= 0;
|
|
ulTotVectors2= 0;
|
|
ulTotQuaternions2= 0;
|
|
fTotTime2= xZero;
|
|
|
|
ulNbQuat1= 0;
|
|
ulNbVect1= 0;
|
|
|
|
fprintf( SizeOut, "Optimisations niveau 2\n" );
|
|
fprintf( SizeOut, "KeyFrame Vectors Quaternions VectorsOpt QuaternionsOpt Place Memoire Temps\n" );
|
|
for ( uwCnt1=0 ; uwCnt1<uwNbAnims ; uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedVectors= M_GetStackPos(eStackSavedVertexes);
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedQuaternions= M_GetStackPos(eStackSavedQuaternions);
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedNTTO= M_GetStackPos(eStackSavedNTTO);
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
|
|
uwMinInVectors= M_GetStackPos(eStackSavedVertexes);
|
|
uwMinInQuaternions= M_GetStackPos(eStackSavedQuaternions);
|
|
uwMinInNTTO= M_GetStackPos(eStackSavedNTTO);
|
|
|
|
ulSToGeneral2= 1;
|
|
ulSToKeyFrame2= 0;
|
|
ulSToHierarchy2= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies;
|
|
ulSToOnlyFrame2= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
ulSToChannel2= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels;
|
|
ulSToEvents2= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents;
|
|
ulSToFrame2= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels * ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames;
|
|
slNbTotVect+= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfVectors;
|
|
slNbTotQuat+= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfQuaternions;
|
|
|
|
// Insert zero vector and identity quaternion
|
|
//fn_uw_InsertVector( uwMinInVectors, a3_xVector0 );
|
|
//fn_uw_InsertQuater( uwMinInQuaternions, a4_xQuater0 );
|
|
|
|
// If the channel is used
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfAnimationTranslationOffset= fn_uw_InsertVector( uwMinInVectors, ax_tdstA3dGENERAL[uwCnt1].uwAnimationTranslationOffset );
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfAnimationRotationOffset= fn_uw_InsertQuater( uwMinInQuaternions, ax_tdstA3dGENERAL[uwCnt1].uwAnimationRotationOffset );
|
|
|
|
// For each (only) frame
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{
|
|
if (ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfAngularSpeedQuat != 0xFFFFFFFF)
|
|
ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfAngularSpeedQuat= fn_uw_InsertQuater( uwMinInQuaternions, ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].tdxAngularSpeedQuat );
|
|
if (ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfSpeedVector != 0xFFFFFFFF)
|
|
ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfSpeedVector= fn_uw_InsertVector( uwMinInVectors, ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].tdxSpeedVector );
|
|
}
|
|
|
|
// For each Channel
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfKeyFrames= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{
|
|
ulSToKeyFrame2+= ax_tdstChannels[slNumOfChannels + uwCnt2].uwNumberOfKeys;
|
|
ax_tdstChannels[uwCnt2 + slNumOfChannels].slNumOfLocalPivotPos= fn_uw_InsertVector( uwMinInVectors, ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos );
|
|
|
|
// For each frame
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatOri= fn_uw_InsertQuater( uwMinInQuaternions, ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatOri );
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatSca= fn_uw_InsertQuater( uwMinInQuaternions, ax_tdstFrames[slNumOfFrames + uwCnt3].a4_xQuatSca );
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfScaleValues= fn_uw_InsertVector( uwMinInVectors, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xScaleValues );
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfKeyFrames++;
|
|
if ( fn_uw_CompQuat(ax_tdxSavedQuaternions[ ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatOri ], a4_xQuater1) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskIdQuatOri;
|
|
if ( fn_uw_CompQuat(ax_tdxSavedQuaternions[ ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatSca ], a4_xQuater1) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskIdQuatSca;
|
|
if ( fn_uw_CompVect(ax_tdxSavedVertexes [ ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfScaleValues ], a3_xVector1) == 0 )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask|= SEB_xMaskIdScaleValues;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Set SEB_xMaskLastKey flag
|
|
// For each Channel
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfKeyFrames= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{
|
|
ax_tdstChannels[uwCnt2 + slNumOfChannels].slNumOfLocalPivotPos= fn_uw_InsertVector( uwMinInVectors, ax_tdstChannels[slNumOfChannels + uwCnt2].a3_xLocalPivotPos );
|
|
|
|
// For each frame
|
|
uwNumOfLastFrame= 0;
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{ uwNumOfLastFrame= uwCnt3;
|
|
}
|
|
}
|
|
ax_tdstFrames[slNumOfFrames + uwNumOfLastFrame].uwMask|= SEB_xMaskLastKey;
|
|
}
|
|
}
|
|
|
|
// Copy of Positions in Vertexes Stack
|
|
uwMinOfPositions= M_GetStackPos(eStackSavedVertexes);
|
|
ax_tdstA3dGENERAL[uwCnt1].slNumOfPositions= uwMinOfPositions;
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{
|
|
// For each frame
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{ if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfPosition= fn_uw_InsertVector( uwMinOfPositions, ax_tdstFrames[slNumOfFrames + uwCnt3].a3_xPosition );
|
|
|
|
// Insert uwFrameNumber and uwTypeOfObject
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfNTTO= fn_uw_InsertNTTO( uwMinInNTTO, ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject,
|
|
ax_tdstFrames[slNumOfFrames + uwCnt3].ucTransparency );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Optimise Frames redondancy
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames= 1;
|
|
uwNumOfLastFrame= 0;
|
|
ax_tdstOnlyFrames[slNumOfOnlyFrames].uwNumOfSavedFrame= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames - 1;
|
|
|
|
for ( uwCnt2=1 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ // For each frame after the first
|
|
uwFlagChangeFrame= 0;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt3++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt3].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt3].uwUsedChannel == 1 )
|
|
{
|
|
if ( (ax_tdstFrames[slNumOfFrames + uwNumOfLastFrame].swNumberInTable != ax_tdstFrames[slNumOfFrames + uwCnt2].swNumberInTable) ||
|
|
(ax_tdstFrames[slNumOfFrames + uwNumOfLastFrame].uwTypeOfObject != ax_tdstFrames[slNumOfFrames + uwCnt2].uwTypeOfObject ) ||
|
|
(ax_tdstFrames[slNumOfFrames + uwNumOfLastFrame].ucTransparency != ax_tdstFrames[slNumOfFrames + uwCnt2].ucTransparency ) )
|
|
uwFlagChangeFrame= 1;
|
|
}
|
|
}
|
|
|
|
if ( uwFlagChangeFrame != 0 )
|
|
{ uwNumOfLastFrame= uwCnt2;
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames++;
|
|
}
|
|
ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].uwNumOfSavedFrame= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames - 1;
|
|
}
|
|
|
|
//-------------------------------
|
|
// Sort Events on FrameNumbers (and, on second key, on channel number)
|
|
qsort(&ax_tdstEvents[ax_tdstA3dGENERAL[uwCnt1].slNumOfEvents], ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents, sizeof(tdstBinEvent), fn_iCmpEventsOnFrameAndChannel);
|
|
//-------------------------------
|
|
|
|
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors= (unsigned short) (M_GetStackPos(eStackSavedVertexes) - uwMinInVectors);
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions= (unsigned short) (M_GetStackPos(eStackSavedQuaternions) - uwMinInQuaternions);
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO= (unsigned short) (M_GetStackPos(eStackSavedNTTO) - uwMinInNTTO);
|
|
|
|
|
|
fSToTime2= (SEB_xReal) ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames / (SEB_xReal) ax_tdstA3dGENERAL[uwCnt1].uwAnimationSpeed;
|
|
ulSToMem2= ulSToGeneral2 * sizeof(tdstFileA3dAnimationGENERAL) +
|
|
ulSToChannel2 * sizeof(tdstFileChannel) +
|
|
ulSToOnlyFrame2 * sizeof(tdstFileOnlyFrame) +
|
|
ulSToKeyFrame2 * sizeof(tdstFileKeyFrame) +
|
|
ulSToHierarchy2 * sizeof(tdstHierarchy) +
|
|
ulSToFrame2 * sizeof(tdstFileFrame) +
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors * sizeof(tdxVector3) +
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions * sizeof(tdxSShortQuater4);
|
|
|
|
fprintf( SizeOut, "%8d %7d %11d %10d %14d %13d %4.2f sec %s\n",
|
|
ulSToKeyFrame2, ax_tdstA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstA3dGENERAL[uwCnt1].uwNumberOfQuaternions,
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors, ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions,
|
|
ulSToMem2, fSToTime2, szAnimName(&stAnims[uwCnt1]) );
|
|
|
|
ulTotMem2+= ulSToMem2;
|
|
ulTotKeyFrame2+= ulSToKeyFrame2;
|
|
ulTotFrame2+= ulSToFrame2;
|
|
ulTotChannel2+= ulSToChannel2;
|
|
ulTotOnlyFrame2+= ulSToOnlyFrame2;
|
|
ulTotHierarchy2+= ulSToHierarchy2;
|
|
ulTotEvents2+= ulSToEvents2;
|
|
ulTotVectors2+= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors;
|
|
ulTotQuaternions2+= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions;
|
|
fTotTime2+= fSToTime2;
|
|
}
|
|
fprintf( SizeOut, "Totaux\n" );
|
|
fprintf( SizeOut, "%8d %7d %11d %10d %14d %13d %4.2f sec %s\n",
|
|
ulTotKeyFrame2, slNbTotVect, slNbTotQuat,
|
|
ulTotVectors2, ulTotQuaternions2, ulTotMem2, fTotTime2, szAnimName(&stAnims[uwCnt1]) );
|
|
fprintf( SizeOut, "\n" );
|
|
|
|
printf("ulTotKeyFrame2= %d\n", ulTotKeyFrame2);
|
|
printf("ulTotFrame2= %d\n", ulTotFrame2);
|
|
printf("ulTotChannel2= %d\n", ulTotChannel2);
|
|
printf("ulTotOnlyFrame2= %d\n", ulTotOnlyFrame2);
|
|
printf("ulTotHierarchy2= %d\n", ulTotHierarchy2);
|
|
printf("ulTotGeneral2= %d\n", ulTotGeneral2);
|
|
printf("ulTotEvents2= %d\n", ulTotEvents2);
|
|
|
|
ulTotMem2= ulTotGeneral2 * sizeof(tdstFileA3dAnimationGENERAL) +
|
|
ulTotChannel2 * sizeof(tdstFileChannel) +
|
|
ulTotOnlyFrame2 * sizeof(tdstFileOnlyFrame) +
|
|
ulTotKeyFrame2 * sizeof(tdstFileKeyFrame) +
|
|
ulTotHierarchy2 * sizeof(tdstHierarchy) +
|
|
ulTotFrame2 * sizeof(tdstFileFrame) +
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors * sizeof(tdxVector3) +
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions * sizeof(tdxSShortQuater4);
|
|
printf("Memoire utilisee %d\n\n", ulTotMem2 );
|
|
|
|
printf( "ulNbQuat1= %8d\n", ulNbQuat1 );
|
|
printf( "ulNbVect1= %8d\n", ulNbVect1 );
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
unsigned short fn_uw_SwapWord( unsigned short x )
|
|
{
|
|
#ifdef A3X_PC
|
|
if ( uwOrder == 0 )
|
|
#else
|
|
if ( uwOrder != 0 )
|
|
#endif
|
|
return ( ((x<<8)&0xFF00) | ((x>>8)&0x00FF) );
|
|
else return x;
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
unsigned long fn_ul_SwapLong( unsigned long x )
|
|
{
|
|
#ifdef A3X_PC
|
|
if ( uwOrder == 0 )
|
|
#else
|
|
if ( uwOrder != 0 )
|
|
#endif
|
|
return ( ((x<<24)&0xFF000000L) | ((x<<8)&0x00FF0000L) | ((x>>24)&0x000000FFL) | ((x>>8)&0x0000FF00L) );
|
|
else return x;
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
unsigned long fn_v_WriteHunk( char HunkName[4],
|
|
char *Buffer,
|
|
unsigned long ulSize,
|
|
unsigned long ulCount,
|
|
FILE *Stream )
|
|
{ unsigned long ulSavedSize;
|
|
|
|
ulSavedSize= fn_ul_SwapLong(ulSize*ulCount);
|
|
if ( uwA3xDebug == 1 )
|
|
{ fwrite( HunkName , 4, 1, Stream );
|
|
fwrite( &ulSavedSize, 4, 1, Stream );
|
|
}
|
|
if (fwrite(Buffer,ulSize,ulCount,Stream) != ulCount) {
|
|
fprintf(ErrorFile, "Anim Save FAIL, write in file error\n");
|
|
//assert(FALSE);
|
|
}
|
|
|
|
ulSavedSize= ulSize*ulCount;
|
|
return ulSavedSize;
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
void fn_v_Verify( char *sText,
|
|
unsigned short uwMax,
|
|
unsigned short uwNum )
|
|
{ if ( (uwNum) > (uwMax) )
|
|
{ printf("Erreur sauvegarde : %s", sText);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
// Modif : 16/07/98 Replace Element number by channel number before saving - Carlos Torres
|
|
// Modif : 20/07/98 Sort channel by channel number - Carlos Torres
|
|
// Modif : 30/07/98 Add a Save Dir aprameter - Carlos
|
|
// Modif : 27/08/98 Fill the new morph struct - Carlos
|
|
// Modif : 28/08/98 Save A3i Version a tthe beginning of the A3i - Carlos
|
|
// Modif : 06/09/98 Change alignement before event - Carlos
|
|
void fn_v_WriteAnimationV6i(unsigned short uwCnt1,char * p_szSaveDir)
|
|
{ signed long uwCnt2, uwCnt3;
|
|
signed long slNumOfOnlyFrames, slNumOfChannels;
|
|
signed long slNumOfSavedVectors, slNumOfSavedQuaternions, slNumOfHierarchies, slNumOfSavedNTTO, slNumOfFramesNTTO, slNumOfEvents, slNumOfFrames, slNumOfMorphData;
|
|
signed long uwFileNumOfFrames, uwFileNumOfChannel, uwFileNumOfKeyFrames;
|
|
signed long ulRealNumOfChannel, ulRealNumOfFrame;
|
|
unsigned short uwRealNumberOfChannels, uwRealNumberOfKeyFrames, uwAlign= 0;
|
|
unsigned long ulSavedSize, ulSizeOfAnim;
|
|
signed long slNumOfRealFrame, uwLastChangeFrame, uwLastRealFrame;
|
|
char FileName[500];
|
|
FILE *Out;
|
|
short wVersion = A3i_Version;
|
|
|
|
// Output Directory Name
|
|
sprintf(FileName,"%s\\%s",p_szSaveDir,szAnimName(&stAnims[uwCnt1]));
|
|
|
|
if ( uwOrder == 0 )
|
|
FileName[ strlen(FileName) - 1 ]= 'm'; // Motorola order
|
|
else FileName[ strlen(FileName) - 1 ]= 'i'; // Intel order
|
|
|
|
if ( uwA3xDebug == 0 )
|
|
FileName[ strlen(FileName) - 3 ]= 'A'; // A3x normal mode
|
|
else FileName[ strlen(FileName) - 3 ]= 'D'; // Debug mode
|
|
|
|
|
|
if (!bValid(&stAnims[uwCnt1]))
|
|
{
|
|
if ( uwA3xDebug == 0 )
|
|
{ if ( uwOrder == 0 )
|
|
printf("Save *.a3m : %s\n", FileName); // Motorola order
|
|
else printf("Save *.a3i : %s\n", FileName); // Intel order
|
|
}
|
|
else
|
|
{ if ( uwOrder == 0 )
|
|
printf("Save *.d3m : %s\n", FileName); // Motorola order
|
|
else printf("Save *.d3i : %s\n", FileName); // Intel order
|
|
}
|
|
|
|
|
|
slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames;
|
|
slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels;
|
|
slNumOfSavedVectors= ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedVectors;
|
|
slNumOfSavedQuaternions= ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedQuaternions;
|
|
slNumOfHierarchies= ax_tdstA3dGENERAL[uwCnt1].slNumOfHierarchies;
|
|
slNumOfSavedNTTO= ax_tdstA3dGENERAL[uwCnt1].slNumOfSavedNTTO;
|
|
slNumOfFramesNTTO= ax_tdstA3dGENERAL[uwCnt1].slNumOfFramesNTTO;
|
|
slNumOfEvents= ax_tdstA3dGENERAL[uwCnt1].slNumOfEvents;
|
|
slNumOfMorphData= ax_tdstA3dGENERAL[uwCnt1].slNumOfMorphData;
|
|
|
|
// With channel killing !
|
|
uwRealNumberOfChannels= 0;
|
|
uwRealNumberOfKeyFrames= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{ uwRealNumberOfChannels++;
|
|
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
uwRealNumberOfKeyFrames++;
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------
|
|
// change Hierarchies
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies ; uwCnt2++ ) {
|
|
// Replace Element number by channel number
|
|
ax_tdstHierarchies[slNumOfHierarchies+uwCnt2].uwChild =
|
|
ax_tdstChannels[slNumOfChannels+ax_tdstHierarchies[slNumOfHierarchies+uwCnt2].uwChild].uwChannelNumber;
|
|
ax_tdstHierarchies[slNumOfHierarchies+uwCnt2].uwFather =
|
|
ax_tdstChannels[slNumOfChannels+ax_tdstHierarchies[slNumOfHierarchies+uwCnt2].uwFather].uwChannelNumber;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------
|
|
// sort channel
|
|
{
|
|
int iNbChannelUnsorted,iLeftToPermute;
|
|
|
|
// sort channel
|
|
for (iNbChannelUnsorted=ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels-1;iNbChannelUnsorted;iNbChannelUnsorted--)
|
|
{
|
|
int bPermuteDone=0;
|
|
tdstBinChannel * p_stChannel, * p_stNextChannel,tdstTempChannel;
|
|
|
|
p_stChannel = &ax_tdstChannels[slNumOfChannels];
|
|
p_stNextChannel = p_stChannel+1;
|
|
|
|
for (iLeftToPermute=0;iLeftToPermute<iNbChannelUnsorted;iLeftToPermute++,p_stChannel=p_stNextChannel,p_stNextChannel++)
|
|
{
|
|
// permutation to have ascendant channel number
|
|
if (p_stChannel->uwChannelNumber > p_stNextChannel->uwChannelNumber) {
|
|
tdstTempChannel=*p_stChannel;
|
|
*p_stChannel=*p_stNextChannel;
|
|
*p_stNextChannel=tdstTempChannel;
|
|
bPermuteDone=1;
|
|
}
|
|
}
|
|
|
|
// If no permutation channels is sorted
|
|
if (!bPermuteDone)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Copy GENERAL
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwAnimationSpeed; // uwAnimationSpeed
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwAnimationSpeed= fn_uw_SwapWord( swReadedWord );
|
|
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors; // uwNumberOfVectors
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions; // uwNumberOfQuaternions
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies; // uwNumberOfHierarchies
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfHierarchies= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO; // uwNumberOfSavedNTTO
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO= fn_uw_SwapWord( swReadedWord );
|
|
|
|
//swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels; // uwNumberOfChannels
|
|
//ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfChannels= fn_uw_SwapWord( swReadedWord );
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfChannels= fn_uw_SwapWord( uwRealNumberOfChannels );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames; // uwNumberOfFrames
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfFrames= fn_uw_SwapWord( swReadedWord );
|
|
//swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfKeyFrames; // uwNumberOfKeyFrames
|
|
//ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfKeyFrames= fn_uw_SwapWord( swReadedWord );
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfKeyFrames= fn_uw_SwapWord( uwRealNumberOfKeyFrames );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents; // uwNumberOfEvents
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfEvents= fn_uw_SwapWord( swReadedWord );
|
|
|
|
swReadedWord= (signed short) // uwNumOfAnimationTranslationOffset
|
|
(ax_tdstA3dGENERAL[uwCnt1].slNumOfAnimationTranslationOffset - slNumOfSavedVectors);
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumOfAnimationTranslationOffset= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) // uwNumOfAnimationRotationOffset
|
|
(ax_tdstA3dGENERAL[uwCnt1].slNumOfAnimationRotationOffset - slNumOfSavedQuaternions);
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumOfAnimationRotationOffset= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short)
|
|
(ax_tdstA3dGENERAL[uwCnt1].slNumOfPositions - slNumOfSavedVectors);
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumOfFirstPosition= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames; // uwNumberOfSavedFrames
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfSavedFrames= fn_uw_SwapWord( swReadedWord );
|
|
|
|
swReadedWord=ax_tdstA3dGENERAL[uwCnt1].uwNumberOfMorphData;
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfMorphData= fn_uw_SwapWord( swReadedWord );
|
|
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwStartFrame= fn_uw_SwapWord( 0 );
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwEndFrame= fn_uw_SwapWord( ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames );
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwFlags= fn_uw_SwapWord( ax_tdstA3dGENERAL[uwCnt1].uwFlags );
|
|
ax_tdstFileA3dGENERAL[uwCnt1].uwFakeAnimSpeed= fn_uw_SwapWord( ax_tdstA3dGENERAL[uwCnt1].uwFakeAnimSpeed );
|
|
// ax_tdstFileA3dGENERAL[uwCnt1].uwAlign= 0x0000;
|
|
|
|
// Copy vertexes
|
|
assert(MaxInFileVertexesTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors ; uwCnt2++ )
|
|
{
|
|
fReadedFloat= (float) ax_tdxSavedVertexes[uwCnt2 + slNumOfSavedVectors][0];
|
|
slReadedLong= *( (signed long *) &fReadedFloat );
|
|
ax_tdxFileVertexes[uwCnt2][0]= fn_ul_SwapLong( slReadedLong );
|
|
fReadedFloat= (float) ax_tdxSavedVertexes[uwCnt2 + slNumOfSavedVectors][1];
|
|
slReadedLong= *( (signed long *) &fReadedFloat );
|
|
ax_tdxFileVertexes[uwCnt2][1]= fn_ul_SwapLong( slReadedLong );
|
|
fReadedFloat= (float) ax_tdxSavedVertexes[uwCnt2 + slNumOfSavedVectors][2];
|
|
slReadedLong= *( (signed long *) &fReadedFloat );
|
|
ax_tdxFileVertexes[uwCnt2][2]= fn_ul_SwapLong( slReadedLong );
|
|
}
|
|
|
|
// Copy quaternions
|
|
assert(MaxInFileQuaternionsTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions ; uwCnt2++ )
|
|
{ swReadedWord= (signed short) (ax_tdxSavedQuaternions[uwCnt2 + slNumOfSavedQuaternions][0] * xCompactValue);
|
|
ax_tdxFileQuaternions[uwCnt2][0]= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) (ax_tdxSavedQuaternions[uwCnt2 + slNumOfSavedQuaternions][1] * xCompactValue);
|
|
ax_tdxFileQuaternions[uwCnt2][1]= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) (ax_tdxSavedQuaternions[uwCnt2 + slNumOfSavedQuaternions][2] * xCompactValue);
|
|
ax_tdxFileQuaternions[uwCnt2][2]= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) (ax_tdxSavedQuaternions[uwCnt2 + slNumOfSavedQuaternions][3] * xCompactValue);
|
|
ax_tdxFileQuaternions[uwCnt2][3]= fn_uw_SwapWord( swReadedWord );
|
|
}
|
|
|
|
// Copy hierarchies
|
|
assert(MaxInFileHierarchyTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies ; uwCnt2++ )
|
|
{ swReadedWord= (signed short) ax_tdstHierarchies[uwCnt2 + slNumOfHierarchies].uwChild;
|
|
ax_tdstFileHierarchy[uwCnt2].uwChild= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) ax_tdstHierarchies[uwCnt2 + slNumOfHierarchies].uwFather;
|
|
ax_tdstFileHierarchy[uwCnt2].uwFather= fn_uw_SwapWord( swReadedWord );
|
|
}
|
|
|
|
// Copy NTTO
|
|
assert(MaxInFileNTTOTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO ; uwCnt2++ ) {
|
|
swReadedWord = ax_tdstTabTBL[ax_tdstSavedNTTO[uwCnt2 + slNumOfSavedNTTO].ucNumberInTable].swNewObjectNumber;
|
|
ax_tdstFileNTTO[uwCnt2].ucNumberInTable= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) ax_tdstSavedNTTO[uwCnt2 + slNumOfSavedNTTO].uwTypeOfObject;
|
|
ax_tdstFileNTTO[uwCnt2].uwTypeOfObject= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short) ax_tdstSavedNTTO[uwCnt2 + slNumOfSavedNTTO].ucTransparency;
|
|
ax_tdstFileNTTO[uwCnt2].ucTransparency= (unsigned char)fn_uw_SwapWord( swReadedWord );
|
|
}
|
|
|
|
|
|
// Copy OnlyFrames infos
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{ swReadedWord= ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].uwHierarchyNbCouples;
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwHierarchyNbCouples= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short)
|
|
(ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfHierarchyCouples - slNumOfHierarchies);
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwNumOfHierarchyCouples= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short)
|
|
(ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].uwNumOfSavedFrame);
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSavedFrame= fn_uw_SwapWord( swReadedWord );
|
|
if (ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfAngularSpeedQuat != 0xFFFFFFFF)
|
|
{ swReadedWord= (signed short)
|
|
(ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfAngularSpeedQuat - slNumOfSavedQuaternions);
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwNumOfAngularSpeedQuat= fn_uw_SwapWord( swReadedWord );
|
|
}
|
|
else
|
|
{ swReadedWord= (signed short) SEB_Invalid;
|
|
}
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwNumOfAngularSpeedQuat= fn_uw_SwapWord( swReadedWord );
|
|
if (ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfSpeedVector != 0xFFFFFFFF)
|
|
{ swReadedWord= (signed short)
|
|
(ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].slNumOfSpeedVector - slNumOfSavedVectors);
|
|
}
|
|
else
|
|
{ swReadedWord= (signed short) SEB_Invalid;
|
|
}
|
|
ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSpeedVector= fn_uw_SwapWord( swReadedWord );
|
|
}
|
|
|
|
|
|
// ----------------------
|
|
ax_uwTabSavedFrames[0]= ax_tdstOnlyFrames[slNumOfOnlyFrames].uwNumOfSavedFrame;
|
|
uwLastChangeFrame= 0;
|
|
uwLastRealFrame= 0;
|
|
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{
|
|
if ( ax_tdstOnlyFrames[uwCnt2 + slNumOfOnlyFrames].uwNumOfSavedFrame != ax_tdstOnlyFrames[uwLastChangeFrame + slNumOfOnlyFrames].uwNumOfSavedFrame )
|
|
{ uwLastChangeFrame= uwCnt2;
|
|
uwLastRealFrame++;
|
|
ax_uwTabSavedFrames[uwLastRealFrame]= (unsigned short) uwCnt2;
|
|
}
|
|
}
|
|
|
|
// ----------------------
|
|
|
|
// Copy Channels, Frames and KeyFrames
|
|
// For each Channel
|
|
uwFileNumOfFrames= 0;
|
|
uwFileNumOfChannel= 0;
|
|
uwFileNumOfKeyFrames= 0;
|
|
assert(MaxInFileChannelTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
// With channel killing !
|
|
if ( ax_tdstChannels[slNumOfChannels + uwCnt2].uwUsedChannel == 1 )
|
|
{
|
|
// Copy Channel
|
|
swReadedWord= ax_tdstChannels[uwCnt2 + slNumOfChannels].uwNumberOfKeys;
|
|
ax_tdstFileChannel[uwFileNumOfChannel].uwNumberOfKeys= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstChannels[uwCnt2 + slNumOfChannels].uwChannelNumber;
|
|
ax_tdstFileChannel[uwFileNumOfChannel].uwChannelNumber= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (unsigned short)
|
|
(ax_tdstChannels[uwCnt2 + slNumOfChannels].slNumOfLocalPivotPos - slNumOfSavedVectors);
|
|
ax_tdstFileChannel[uwFileNumOfChannel].uwNumOfLocalPivotPos= fn_uw_SwapWord( swReadedWord );
|
|
|
|
// For each SavedFrames
|
|
assert(MaxInFileFrameTab > (uwFileNumOfFrames + ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames));
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames ; uwCnt3++ )
|
|
{
|
|
slNumOfRealFrame= ax_uwTabSavedFrames[uwCnt3];
|
|
swReadedWord= (unsigned short) (ax_tdstFrames[slNumOfFrames + slNumOfRealFrame].slNumOfNTTO - slNumOfSavedNTTO);
|
|
ax_tdstFileFrame[uwFileNumOfFrames].uwNumOfNTTO= fn_uw_SwapWord( swReadedWord );
|
|
uwFileNumOfFrames++;
|
|
}
|
|
|
|
// For each Frames
|
|
assert(MaxInFileKeyFrameTab > (uwFileNumOfKeyFrames + ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames));
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt3++ )
|
|
{
|
|
// Copy Frame
|
|
// swReadedWord= ax_tdstFrames[slNumOfFrames + uwCnt3].swNumberInTable;
|
|
// ax_tdstFileFrame[uwFileNumOfFrames].swNumberInTable= fn_uw_SwapWord( swReadedWord );
|
|
// swReadedWord= ax_tdstFrames[slNumOfFrames + uwCnt3].uwTypeOfObject;
|
|
// ax_tdstFileFrame[uwFileNumOfFrames].uwTypeOfObject= fn_uw_SwapWord( swReadedWord );
|
|
// uwFileNumOfFrames++;
|
|
|
|
// Copy KeyFrame
|
|
if ( ax_tdstFrames[slNumOfFrames + uwCnt3].uwAttribute != eNoKey )
|
|
{
|
|
swReadedWord= ax_tdstFrames[slNumOfFrames + uwCnt3].uwFrameNumber;
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwFrameNumber= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= ax_tdstFrames[slNumOfFrames + uwCnt3].uwMask;
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwMask= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (unsigned short)
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatOri - slNumOfSavedQuaternions);
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfQuatOri= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (unsigned short)
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfQuatSca - slNumOfSavedQuaternions);
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfQuatSca= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (unsigned short)
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfScaleValues - slNumOfSavedVectors);
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfScaleValues= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (unsigned short)
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].slNumOfPosition - slNumOfSavedVectors);
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfPosition= fn_uw_SwapWord( swReadedWord );
|
|
swReadedWord= (signed short)
|
|
(ax_tdstFrames[slNumOfFrames + uwCnt3].xInterpolationParameter * 8192.0);
|
|
ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].swInterpolationParameter= fn_uw_SwapWord( swReadedWord );
|
|
uwFileNumOfKeyFrames++;
|
|
}
|
|
}
|
|
uwFileNumOfChannel++;
|
|
}
|
|
}
|
|
|
|
// Copy Events
|
|
assert(MaxInFileEventTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents ; uwCnt2++ )
|
|
{
|
|
ax_tdstFileEvent[uwCnt2].uwFrameNumber = ax_tdstEvents[slNumOfEvents + uwCnt2].uwFrameNumber;
|
|
ax_tdstFileEvent[uwCnt2].usEventNumberInTBL=ax_tdstTabTBL[ax_tdstEvents[slNumOfEvents + uwCnt2].usEventNumberInTBL].swNewObjectNumber;
|
|
ax_tdstFileEvent[uwCnt2].uwChannelNumber = ax_tdstEvents[slNumOfEvents + uwCnt2].uwChannelNumber;
|
|
}
|
|
|
|
// Copy and optimize morphing data with compact modifications
|
|
assert(MaxInFileMorphTab > ax_tdstA3dGENERAL[uwCnt1].uwNumberOfMorphData);
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfMorphData ; uwCnt2++ )
|
|
{
|
|
ax_tdstFileMorphInfos[uwCnt2].ucTarget= (unsigned char)
|
|
ax_tdstTabTBL[ax_tdstBinMorphInfos[slNumOfMorphData+uwCnt2].ucTarget].swNewObjectNumber;
|
|
ax_tdstFileMorphInfos[uwCnt2].ucMorphingAmount=
|
|
ax_tdstBinMorphInfos[slNumOfMorphData+uwCnt2].ucMorphingAmount;
|
|
ax_tdstFileMorphInfos[uwCnt2].uwChannelNumber=
|
|
ax_tdstBinMorphInfos[slNumOfMorphData+uwCnt2].uwChannelNumber;
|
|
ax_tdstFileMorphInfos[uwCnt2].uwFrameNumber=
|
|
ax_tdstBinMorphInfos[slNumOfMorphData+uwCnt2].uwFrameNumber;
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// Verify animation
|
|
#ifdef A3X_PC
|
|
if ( uwOrder != 0 )
|
|
#else
|
|
if ( uwOrder == 0 )
|
|
#endif
|
|
{
|
|
if ( uwCalc == 1 )
|
|
{
|
|
ulSizeOfAnim= sizeof(tdstA3dGENERAL) +
|
|
12 * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors +
|
|
sizeof(tdxSShortQuater4)* (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions +
|
|
sizeof(tdstHierarchy) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfHierarchies +
|
|
sizeof(tdstNTTO) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO +
|
|
sizeof(tdstOnlyFrame) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfFrames +
|
|
sizeof(tdstChannel) * (unsigned long) uwFileNumOfChannel +
|
|
sizeof(tdstFrame) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfSavedFrames *
|
|
(unsigned long) uwFileNumOfChannel +
|
|
sizeof(tdstFrameKF) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfFrames *
|
|
(unsigned long) uwFileNumOfChannel;
|
|
if ( ((ulSizeOfAnim) & 0x0002) != 0x0000 )
|
|
ulSizeOfAnim+= 2;
|
|
ulSizeOfAnim+= sizeof(tdstKeyFrame) * (unsigned long) uwFileNumOfKeyFrames +
|
|
sizeof(tdstEvent) * (unsigned long) ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfEvents;
|
|
ax_MemSizes[ulTotNbAnims]= ulSizeOfAnim;
|
|
if ( (ulSizeOfAnim & 0x03FF) == 0 ) // mod 1024
|
|
ulSizeOfAnim= (ulSizeOfAnim >> 10) - 1; // div 1024 - 1
|
|
else ulSizeOfAnim= (ulSizeOfAnim >> 10); // div 1024
|
|
a100_TabNbElt[ ulSizeOfAnim ]++;
|
|
}
|
|
|
|
|
|
// A3dGENERAL
|
|
fn_v_Verify( "A3dGENERAL", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstFileA3dGENERAL[uwCnt1].uwNumOfAnimationTranslationOffset );
|
|
fn_v_Verify( "A3dGENERAL", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions, ax_tdstFileA3dGENERAL[uwCnt1].uwNumOfAnimationRotationOffset );
|
|
|
|
// Hierarchies
|
|
/*for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies ; uwCnt2++ )
|
|
{
|
|
fn_v_Verify( "Hierarchies (Child)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfChannels, ax_tdstFileHierarchy[uwCnt2].uwChild );
|
|
fn_v_Verify( "Hierarchies (Father)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfChannels, ax_tdstFileHierarchy[uwCnt2].uwFather );
|
|
|
|
}*/
|
|
|
|
// NTTO
|
|
|
|
// OnlyFrames
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames ; uwCnt2++ )
|
|
{
|
|
if (ax_tdstFileOnlyFrame[uwCnt2].uwNumOfAngularSpeedQuat != SEB_Invalid)
|
|
fn_v_Verify( "OnlyFrames (Angular speed)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfAngularSpeedQuat );
|
|
if (ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSpeedVector != SEB_Invalid)
|
|
fn_v_Verify( "OnlyFrames (Translation speed)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSpeedVector );
|
|
//fn_v_Verify( "OnlyFrames (hierarchy)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfHierarchies, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfHierarchyCouples );
|
|
//fn_v_Verify( "OnlyFrames (hierarchy)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfHierarchies, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfHierarchyCouples + ax_tdstFileOnlyFrame[uwCnt2].uwHierarchyNbCouples );
|
|
fn_v_Verify( "OnlyFrames (hierarchy)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfHierarchies, ax_tdstFileOnlyFrame[uwCnt2].uwHierarchyNbCouples );
|
|
fn_v_Verify( "OnlyFrames (FrameNTTO)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfSavedFrames, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSavedFrame );
|
|
if ( (uwCnt2>0) && (ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSavedFrame < ax_tdstFileOnlyFrame[uwCnt2 - 1].uwNumOfSavedFrame) )
|
|
{ printf("Erreur sauvegarde : SavedFrame (rupture accroissement frame #%d (%d), frame #%d (%d))",
|
|
uwCnt2-1, ax_tdstFileOnlyFrame[uwCnt2].uwNumOfSavedFrame, uwCnt2, ax_tdstFileOnlyFrame[uwCnt2 - 1].uwNumOfSavedFrame );
|
|
}
|
|
}
|
|
|
|
// Channels, Frames and KeyFrames
|
|
// For each Channel
|
|
uwFileNumOfFrames= 0;
|
|
uwFileNumOfChannel= 0;
|
|
uwFileNumOfKeyFrames= 0;
|
|
ulRealNumOfChannel= 0;
|
|
for ( uwCnt2=0 ; uwCnt2<ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfChannels ; uwCnt2++ )
|
|
{ slNumOfFrames= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
ulRealNumOfFrame= ax_tdstChannels[slNumOfChannels + uwCnt2].slNumOfFrames;
|
|
|
|
while ( ax_tdstChannels[slNumOfChannels + ulRealNumOfChannel].uwUsedChannel == 0 )
|
|
ulRealNumOfChannel++;
|
|
|
|
// Channel
|
|
fn_v_Verify( "Channels", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstFileChannel[uwFileNumOfChannel].uwNumOfLocalPivotPos );
|
|
|
|
// For each Frames (NTTO)
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames ; uwCnt3++ )
|
|
{ fn_v_Verify( "bad NTTO", ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO, ax_tdstFileFrame[uwFileNumOfFrames].uwNumOfNTTO );
|
|
uwFileNumOfFrames++;
|
|
}
|
|
|
|
// For each KeyFrames
|
|
for ( uwCnt3=0 ; uwCnt3<ax_tdstFileChannel[uwFileNumOfChannel].uwNumberOfKeys ; uwCnt3++ )
|
|
{
|
|
fn_v_Verify( "KeyFrame (FrameNumber)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfFrames, ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwFrameNumber );
|
|
fn_v_Verify( "KeyFrame (QuatOri)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions, ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfQuatOri );
|
|
fn_v_Verify( "KeyFrame (QuatSca)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfQuaternions, ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfQuatSca );
|
|
fn_v_Verify( "KeyFrame (ScaleValues)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfScaleValues );
|
|
fn_v_Verify( "KeyFrame (NumOfPosition)", ax_tdstFileA3dGENERAL[uwCnt1].uwNumberOfVectors, ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwNumOfPosition );
|
|
// We are on the last key
|
|
if ( uwCnt3 < (ax_tdstFileChannel[uwFileNumOfChannel].uwNumberOfKeys - 1) )
|
|
{ if ( (ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwMask & SEB_xMaskLastKey) == SEB_xMaskLastKey )
|
|
{ printf( "KeyFrame (is not SEB_xMaskLastKey), channel #%d, keyframe #%d (/%d)", uwCnt2, uwCnt3, ax_tdstFileChannel[uwFileNumOfChannel].uwNumberOfKeys );
|
|
}
|
|
}
|
|
else
|
|
{ if ( (ax_tdstFileKeyFrame[uwFileNumOfKeyFrames].uwMask & SEB_xMaskLastKey) != SEB_xMaskLastKey )
|
|
{ printf( "KeyFrame (must be SEB_xMaskLastKey), channel #%d, keyframe #%d (/%d)", uwCnt2, uwCnt3, ax_tdstFileChannel[uwFileNumOfChannel].uwNumberOfKeys );
|
|
}
|
|
}
|
|
uwFileNumOfKeyFrames++;
|
|
}
|
|
ulRealNumOfChannel++;
|
|
uwFileNumOfChannel++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
Out= fopen( FileName, "wb+" );
|
|
|
|
// Put Version
|
|
fwrite(&wVersion,2,1,Out);
|
|
|
|
// Save GENERAL
|
|
ulSavedSize= fn_v_WriteHunk( "GENE",
|
|
(char *) &ax_tdstFileA3dGENERAL[uwCnt1],
|
|
sizeof(tdstFileA3dAnimationGENERAL),
|
|
1,
|
|
Out );
|
|
// Save vertexes
|
|
ulSavedSize+= fn_v_WriteHunk( "VERT",
|
|
(char *) ax_tdxFileVertexes,
|
|
sizeof(signed long)*3,
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedVectors,
|
|
Out );
|
|
// Save quaternions
|
|
ulSavedSize+= fn_v_WriteHunk( "QUAT",
|
|
(char *) ax_tdxFileQuaternions,
|
|
sizeof(signed short)*4,
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedQuaternions,
|
|
Out );
|
|
// Save hierarchies
|
|
ulSavedSize+= fn_v_WriteHunk( "HIER",
|
|
(char *) ax_tdstFileHierarchy,
|
|
sizeof(tdstFileHierarchy),
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies,
|
|
Out );
|
|
// Save NTTO (NumberInTable and TypeOfObject Table)
|
|
ulSavedSize+= fn_v_WriteHunk( "NTTO",
|
|
(char *) ax_tdstFileNTTO,
|
|
sizeof(tdstNTTO),
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO,
|
|
Out );
|
|
// Save OnlyFrames infos
|
|
ulSavedSize+= fn_v_WriteHunk( "OFRM",
|
|
(char *) ax_tdstFileOnlyFrame,
|
|
sizeof(tdstFileOnlyFrame),
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames,
|
|
Out );
|
|
// Save Channels
|
|
ulSavedSize+= fn_v_WriteHunk( "CHAN",
|
|
(char *) ax_tdstFileChannel,
|
|
sizeof(tdstFileChannel),
|
|
uwFileNumOfChannel,
|
|
Out );
|
|
// Save Frames
|
|
ulSavedSize+= fn_v_WriteHunk( "FRMS",
|
|
(char *) ax_tdstFileFrame,
|
|
sizeof(tdstFileFrame),
|
|
uwFileNumOfChannel * ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames,
|
|
Out );
|
|
// Save KeyFrames
|
|
ulSavedSize+= fn_v_WriteHunk( "KFRM",
|
|
(char *) ax_tdstFileKeyFrame,
|
|
sizeof(tdstFileKeyFrame),
|
|
uwFileNumOfKeyFrames,
|
|
Out );
|
|
// align data
|
|
while( (ulSavedSize % 4) != 0 )
|
|
ulSavedSize+= fwrite( &uwAlign, 1, 1, Out );
|
|
|
|
// Save Events
|
|
ulSavedSize+= fn_v_WriteHunk( "EVNT",
|
|
(char *) ax_tdstFileEvent,
|
|
sizeof(tdstFileEvent),
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents,
|
|
Out );
|
|
|
|
//align data
|
|
while( (ulSavedSize % 4) != 0 )
|
|
ulSavedSize+= fwrite( &uwAlign, 1, 1, Out );
|
|
|
|
// Save Morphing array
|
|
ulSavedSize+= fn_v_WriteHunk( "MORP",
|
|
(char *) ax_tdstFileMorphInfos,
|
|
sizeof(tdstFileMorphData),
|
|
ax_tdstA3dGENERAL[uwCnt1].uwNumberOfMorphData,
|
|
Out );
|
|
|
|
fclose( Out );
|
|
|
|
#ifdef A3X_PC
|
|
if ( uwOrder != 0 )
|
|
#else
|
|
if ( uwOrder == 0 )
|
|
#endif
|
|
{
|
|
if ( uwCalc == 1 )
|
|
{
|
|
ax_RomSizes[ulTotNbAnims]= ulSavedSize;
|
|
ulTotNbAnims++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ printf("Don't save (not animation) : %s\n", FileName);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
// Modif 30/07/98 : Anims are located in two dir
|
|
// Save Binary anim in good directory - Carlos Torres
|
|
// Modif 17/08/98 : Generalized function -> Save N Anims beginning at anim uwNbFirstAnims - Carlos Torres
|
|
void fn_v_SaveAnimationV6i(unsigned short uwNbFirstAnim,unsigned short uwNbAnims,char * p_szSaveDir)
|
|
{ unsigned short uwCnt1;
|
|
|
|
printf("Sauvegarde des animations...\n");
|
|
uwCalc= 0;
|
|
|
|
// For each animation
|
|
for ( uwCnt1=uwNbFirstAnim;uwCnt1<uwNbFirstAnim+uwNbAnims;uwCnt1++ ) {
|
|
// bad anim --> skip it
|
|
if (bValid(&stAnims[uwCnt1]))
|
|
continue;
|
|
else {
|
|
xEps = xPrecision(&stAnims[uwCnt1]);
|
|
xOneSubEps = (SEB_xReal)(1.0 - xEps);
|
|
}
|
|
|
|
uwCalc= 1;
|
|
uwA3xDebug= 0; // A3x Normal mode
|
|
// uwOrder= 0; // Motorola order
|
|
// fn_v_WriteAnimationV6i( uwCnt1 );
|
|
uwOrder= 1; // Intel order
|
|
|
|
fn_v_WriteAnimationV6i(uwCnt1,p_szSaveDir);
|
|
// uwCalc= 0;
|
|
// uwA3xDebug= 1; // A3x Debug mode
|
|
// uwOrder= 0; // Motorola order
|
|
// fn_v_WriteAnimationV6i( uwCnt1 );
|
|
// uwOrder= 1; // Intel order
|
|
// fn_v_WriteAnimationV6i( uwCnt1 );
|
|
}
|
|
|
|
printf("End of saving\n\n");
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************** fn_v_StartA3dV6i
|
|
// Open files to make Log
|
|
// Error File
|
|
// SizeOf File
|
|
// Event File
|
|
// If file cannot be open, use stdout
|
|
//
|
|
// Sebastien Rubens
|
|
// Modif 16/10/98 Add Warning File - Carlos Torres
|
|
// **********************************************************************************
|
|
void fn_v_StartA3dV6i( void ) {
|
|
char FileName[200];
|
|
|
|
slNbTotVect = 0;
|
|
slNbTotQuat = 0;
|
|
fn_v_ResetStacks();
|
|
|
|
// Open Error File
|
|
sprintf(FileName,"%s\\%s.txt",ERROR_DIR,szFamilyName);
|
|
ErrorFile = fopen(FileName,"w+");
|
|
if (ErrorFile == NULL)
|
|
ErrorFile = stdout;
|
|
|
|
// Open Warning File
|
|
sprintf(FileName,"%s\\%s.txt",WARNING_DIR,szFamilyName);
|
|
WarningFile = fopen(FileName,"w+");
|
|
if (WarningFile == NULL)
|
|
WarningFile = stdout;
|
|
|
|
// Open SizeOf File
|
|
sprintf(FileName,"%s\\%s.txt",SIZEOF_DIR,szFamilyName);
|
|
SizeOut = fopen(FileName,"w+");
|
|
if (SizeOut == NULL)
|
|
SizeOut = stdout;
|
|
|
|
// Open Event File
|
|
sprintf(FileName,"%s\\%s.txt",EVENT_DIR,szFamilyName);
|
|
EventFile = fopen(FileName,"w+");
|
|
if (EventFile == NULL)
|
|
EventFile = stdout;
|
|
}
|
|
|
|
|
|
|
|
// ******************************************************************* fn_v_EndA3dV6i
|
|
// Close Log if use (not stdout)
|
|
// Error File
|
|
// SizeOf File
|
|
// Event File
|
|
//
|
|
// Sebastien Rubens
|
|
// Modif 23/07/98 Remove Empty Error File - Carlos Torres
|
|
// Modif 16/10/98 Add Warning File - Carlos Torres
|
|
// **********************************************************************************
|
|
void fn_v_EndA3dV6i(void) {
|
|
// Close Error File
|
|
if (ErrorFile != stdout) {
|
|
// get position in file
|
|
int bError = ftell(ErrorFile);
|
|
|
|
fclose(ErrorFile);
|
|
|
|
// remove file if no error
|
|
if (!bError) {
|
|
char szFileName[200];
|
|
|
|
sprintf(szFileName,"%s\\%s.txt",ERROR_DIR,szFamilyName);
|
|
remove(szFileName);
|
|
}
|
|
}
|
|
|
|
// Close Warning File
|
|
if (WarningFile != stdout) {
|
|
// get position in file
|
|
int bWarning = ftell(WarningFile);
|
|
|
|
fclose(WarningFile);
|
|
|
|
// remove file if no warning
|
|
if (!bWarning) {
|
|
char szFileName[200];
|
|
|
|
sprintf(szFileName,"%s\\%s.txt",WARNING_DIR,szFamilyName);
|
|
remove(szFileName);
|
|
}
|
|
}
|
|
|
|
// Close SizeOf File
|
|
if (SizeOut != stdout)
|
|
fclose(SizeOut);
|
|
|
|
// Close Event File
|
|
if (EventFile != stdout)
|
|
fclose(EventFile);
|
|
}
|
|
|
|
// ******************************************************************** fn_bIsNewAnim
|
|
// Check if an anim name is allready in the general table
|
|
//
|
|
// Carlos Torres
|
|
// **********************************************************************************
|
|
int fn_bIsNewAnim(char * szAnimName) {
|
|
int i;
|
|
|
|
for(i=0;i<g_uwTotalNumOfAnim;i++) {
|
|
if (!stricmp(szAnimName,szAnimName(&stAnims[i])))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// ****************************************************************** fn_uw_GetDirV6i
|
|
// Fill a table with all anim file name found in the actor Dir
|
|
// Return the number of anim found
|
|
//
|
|
// Sebastien Rubens
|
|
// Modif 30/07/98 : Add anim name table in parameter - Carlos Torres
|
|
// Modif 25/08/98 : Get all anim found or just new name - Carlos Torres
|
|
// **********************************************************************************
|
|
unsigned short fn_uw_GetDirV6i(char * LongActorName,unsigned char bTreatAll) {
|
|
FILE *Directory;
|
|
char ExecCommand[500];
|
|
unsigned short uwAnimNumber;
|
|
|
|
// Get all A3D files of the directory in DIR.A3D file
|
|
sprintf(ExecCommand,"DIR %s\\*.A3D /B /ON > %s\\A3D.DIR",LongActorName,LongActorName);
|
|
system(ExecCommand);
|
|
|
|
// Read all A3D files for perso
|
|
sprintf(LongFileName,"%s\\A3D.DIR",LongActorName);
|
|
Directory = fopen(LongFileName,"r");
|
|
|
|
// Fill table with anim name and default value
|
|
// Default
|
|
// General precision
|
|
// set anim valid
|
|
uwAnimNumber = 0;
|
|
if (Directory) {
|
|
while (fgets(szAnimName(&stAnims[g_uwTotalNumOfAnim]),50,Directory)) {
|
|
// suppress last char (EOL)
|
|
szAnimName(&stAnims[g_uwTotalNumOfAnim])[strlen(szAnimName(&stAnims[g_uwTotalNumOfAnim]))-1] = NULL;
|
|
|
|
// keep anim if treat all or if it is a new name
|
|
if (bTreatAll || fn_bIsNewAnim(szAnimName(&stAnims[g_uwTotalNumOfAnim]))) {
|
|
uwAnimNumber++;
|
|
g_uwTotalNumOfAnim++;
|
|
|
|
xPrecision(&stAnims[g_uwTotalNumOfAnim]) = xDefaultEps;
|
|
bValid(&stAnims[g_uwTotalNumOfAnim]) = 0;
|
|
|
|
assert(g_uwTotalNumOfAnim<NombreDanimationsParDirectory);
|
|
}
|
|
}
|
|
|
|
fclose(Directory);
|
|
}
|
|
|
|
return uwAnimNumber;
|
|
}
|
|
|
|
// ******************************************************** fn_v_InitSaveAnimationV6i
|
|
// **********************************************************************************
|
|
void fn_v_InitSaveAnimationV6i(void) {
|
|
unsigned short uwCnt;
|
|
|
|
// Reset Table
|
|
for ( uwCnt=0 ; uwCnt<100 ; uwCnt++ )
|
|
a100_TabNbElt[uwCnt] = 0;
|
|
}
|
|
|
|
// **********************************************************************************
|
|
void fn_v_EndSaveAnimationV6i( void )
|
|
{ unsigned short uwCnt;
|
|
double xMemMoy, xRomMoy, xMemEcart, xRomEcart, xMaxMem, xMaxRom;
|
|
/*FILE *stream;
|
|
|
|
stream= fopen( "D:\\sizes.txt", "w+" );
|
|
fprintf( stream, "Nombre d'animations inferieures ou egales a :\n");
|
|
for ( uwCnt=0 ; uwCnt<100 ; uwCnt++ )
|
|
{ if ((uwCnt % 10) == 0)
|
|
fprintf( stream, "\n" );
|
|
fprintf( stream, "%3d Ko : %d\n", (uwCnt+1), a100_TabNbElt[uwCnt] );
|
|
}
|
|
fclose(stream);*/
|
|
|
|
|
|
// ------------------------------------------------------------------------------
|
|
xMemMoy= 0.0;
|
|
xRomMoy= 0.0;
|
|
xMemEcart= 0.0;
|
|
xRomEcart= 0.0;
|
|
|
|
// Calcul des moyennes et de "la variance"
|
|
xMaxMem= 0;
|
|
xMaxRom= 0;
|
|
for ( uwCnt=0 ; uwCnt<ulTotNbAnims ; uwCnt++ )
|
|
{ xMemMoy+= ax_MemSizes[uwCnt];
|
|
xRomMoy+= ax_RomSizes[uwCnt];
|
|
xMemEcart+= ax_MemSizes[uwCnt] * ax_MemSizes[uwCnt];
|
|
xRomEcart+= ax_RomSizes[uwCnt] * ax_RomSizes[uwCnt];
|
|
if ( ax_MemSizes[uwCnt] > xMaxMem )
|
|
xMaxMem= ax_MemSizes[uwCnt];
|
|
if ( ax_RomSizes[uwCnt] > xMaxRom )
|
|
xMaxRom= ax_RomSizes[uwCnt];
|
|
}
|
|
xMemMoy/= ulTotNbAnims; // E[x]
|
|
xRomMoy/= ulTotNbAnims;
|
|
xMemEcart/= ulTotNbAnims; // E[x²]
|
|
xRomEcart/= ulTotNbAnims;
|
|
|
|
xMemEcart= xMemEcart - xMemMoy * xMemMoy; // V= E[x²] - E[x]²
|
|
xRomEcart= xRomEcart - xRomMoy * xRomMoy;
|
|
|
|
xMemEcart= sqrt( xMemEcart ); // Ecart type
|
|
xRomEcart= sqrt( xRomEcart );
|
|
|
|
printf("\n");
|
|
printf("Nombre total d'animations : %d\n", ulTotNbAnims);
|
|
printf("Moyenne MEM : %10.4f\n", xMemMoy );
|
|
printf("Moyenne ROM : %10.4f\n", xRomMoy );
|
|
printf("Ecart type MEM : %10.4f\n", xMemEcart );
|
|
printf("Ecart type ROM : %10.4f\n", xRomEcart );
|
|
printf("Taille max MEM : %10.4f\n", xMaxMem );
|
|
printf("Taille max ROM : %10.4f\n", xMaxRom );
|
|
}
|
|
|
|
|
|
|
|
// **********************************************************************************
|
|
#undef L_OPTIM_V6_C
|