reman3/Rayman_X/cpa/Appli/CvrtA3DtoA3i/Src/l_optim_v6.cpp

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