// ********************************************************************************** // * "l_optim_v6.c" * // * Written by : Sébastien Rubens * // * Tabulations : 4 char * // ********************************************************************************** #define L_OPTIM_V6_C // ********************************************************************************** // Included files #include #include #include #include #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 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 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 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> 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 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 skip it if (TabValidAnimations[uwCnt1] == 1) continue; slNumOfOnlyFrames= ax_tdstA3dGENERAL[uwCnt1].slNumOfOnlyFrames; slNumOfChannels= ax_tdstA3dGENERAL[uwCnt1].slNumOfChannels; for ( uwCnt2=0 ; uwCnt2 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 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 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 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 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 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 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 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 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=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 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 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 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 ; uwCnt2uwFrameNumber>b->uwFrameNumber) return 1; else if(a->uwFrameNumberuwFrameNumber) return -1; else if(a->uwChannelNumber>b->uwChannelNumber) return 1; else if(a->uwChannelNumberuwChannelNumber) 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 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>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 ; uwCnt2uwChannelNumber > 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].uwNumberOfSavedQuaternions); for ( uwCnt2=0 ; uwCnt2 ax_tdstA3dGENERAL[uwCnt1].uwNumberOfHierarchies); for ( uwCnt2=0 ; uwCnt2 ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedNTTO); for ( uwCnt2=0 ; uwCnt2 ax_tdstA3dGENERAL[uwCnt1].uwNumberOfChannels); for ( uwCnt2=0 ; uwCnt2 (uwFileNumOfFrames + ax_tdstA3dGENERAL[uwCnt1].uwNumberOfSavedFrames)); for ( uwCnt3=0 ; uwCnt3 (uwFileNumOfKeyFrames + ax_tdstA3dGENERAL[uwCnt1].uwNumberOfFrames)); for ( uwCnt3=0 ; uwCnt3 ax_tdstA3dGENERAL[uwCnt1].uwNumberOfEvents); for ( uwCnt2=0 ; uwCnt2 ax_tdstA3dGENERAL[uwCnt1].uwNumberOfMorphData); for ( uwCnt2=0 ; uwCnt2> 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 ; uwCnt20) && (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 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 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 %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 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