/*========================================================================= * * A3dSave.c - save A3D file * * Version 1.0 * Revision date * *=======================================================================*/ #include "A3dSave.h" #include "conventi.h" #include "print.h" #include "system.h" #include "Banks.h" #include "Borders.h" #include "ModLib.h" //-------------------------------------------------------------------- /**************************************************************************** * Description: save A3d file header * * Parameters: p_stFile : script file pointer * sFileName : file name * p_vPtr : data pointer * xAction : script action *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vSaveA3dHeader (SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { xString mes; SCR_fn_v_SvL1_DeleteSection(p_stFile); SCR_M_SvL0_SaveScriptFileHeader(p_stFile); //save the header section of a3d file sprintf(mes, "%s%s", M_A3D_HEADER, SCR_CC_sz_Cfg_SectionIdMark); SCR_M_SvL0_SaveBeginSection(p_stFile, mes, SCR_CC_C_Cfg_EOL); SCR_M_SvL0_SaveEntry(p_stFile, M_OBJActionFileType, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%s", "Animations"); SCR_M_SvL0_SaveEntry(p_stFile, M_OBJActionVersionNumber, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 6); SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); } /**************************************************************************** * Description: Save A3D file * * Parameters: p_stFile : script file pointer * sFileName : file name * p_vPtr : data pointer * xAction : script action *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vSaveA3dFile (SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { xString sFile, sAction, sIdent, mes, sSection; float stQ[4]; int i; SCR_fn_v_SvL1_ToEndSection(p_stFile); // string table sprintf(mes, "%d()", 2*g_lGeometricIndex+1); sprintf(sFile, "%s.a3d", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_A3dStringsTable, mes); SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL); for (i = 0; i < g_lGeometricIndex; i++) { SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); if (i == 0) { sprintf(mes, "%s%d", "Channel", i+1); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%s", 0, mes); } else { if (i == 1) { SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%s", 1, sFile); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); } sprintf(mes, "%s%d", "Channel", i+1); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%s", i+1, mes); } } for (i = g_lGeometricIndex; i < 2*g_lGeometricIndex; i++) { SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i-g_lGeometricIndex]->sName, sFile, sAction, sIdent); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%s", 1+i, sIdent); } SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); // vertex table sprintf(mes, "%d()", g_lGeometricIndex+2); sprintf(sFile, "%s.a3d", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_A3dVertexesTable, mes); SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 5, "%d,%.5f,%.5f,%.5f", 0, 0.0, 0.0, 0.0); //position matrix!!!!! MLT_vGetPositions (&g_hBankRoot); for (i = 0; i < g_lGeometricIndex; i++) { SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 5, "%d,%.5f,%.5f,%.5f", i+1, g_hGeometricInFile[i]->p_stMatrix->stTranslation.xX, g_hGeometricInFile[i]->p_stMatrix->stTranslation.xY, g_hGeometricInFile[i]->p_stMatrix->stTranslation.xZ); } SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 5, "%d,%.5f,%.5f,%.5f", g_lGeometricIndex+1, 1.0, 1.0, 1.0); SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); // quaternion table sprintf(mes, "%d()", 2*g_lGeometricIndex + 1 ); sprintf(sFile, "%s.a3d", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_A3dQuaternionsTable, mes); SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 6, "%d,%d,%d,%d,%d", 0, 0, 0, 0, 1); for (i = 0; i < g_lGeometricIndex; i++) { //compute the quaternion for the rotation matrix MLT_vSetQuaternionFromMatrix( g_hGeometricInFile[i]->p_stMatrix->a9_xRotMatrix, stQ); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 6, "%d,%e,%e,%e,%f", i+1, stQ[0], stQ[1], stQ[2], stQ[3]); } for (i = g_lGeometricIndex; i < 2*g_lGeometricIndex; i++) { //compute the quaternion for the scale matrix MLT_vSetQuaternionFromMatrix( g_hGeometricInFile[i-g_lGeometricIndex]->p_stMatrix->a9_xScaleMatrix, stQ); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionAdd, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 6, "%d,%e,%e,%e,%f", i+1, stQ[0], stQ[1], stQ[2], stQ[3]); } SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); // general section sprintf(mes, "%s%s", M_A3dAnimationGENERAL, SCR_CC_sz_Cfg_SectionIdMark); SCR_M_SvL0_SaveBeginSection(p_stFile, mes, SCR_CC_C_Cfg_EOL); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionActor, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%s", g_sFileIn ); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionNumberOfChannels, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", g_lGeometricIndex); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionNumberOfFrames, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionCurrentFrame, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionTransOffset, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 0); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionRotationOffset, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 0); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionReferenceChannel, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 0); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionSpeed, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 15); SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); // channel sections for (i = 0; i < g_lGeometricIndex; i++) { if (i == 0) sprintf(mes, "%d(%d)", i+1, i); else sprintf(mes, "%d(%d)", i+1, i+1); sprintf(sFile, "%s.a3d", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_A3dChannel, mes); SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL); SCR_g_ui_SvL0_IndentationLevel = 1; //first frame sprintf(mes, "1()"); sprintf(sFile, "%s.a3d", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_A3dFrame, mes); SCR_M_SvL0_SaveBeginSection(p_stFile, MLT_p_cGetSectionName(sSection), SCR_CC_C_Cfg_EOL); SCR_M_SvL0_SaveEntry(p_stFile, M_OBJActionObjectType, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%s", "3dObject" ); SCR_M_SvL0_SaveEntry(p_stFile, M_OBJActionBank, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", 1 ); SCR_M_SvL0_SaveEntry(p_stFile, M_OBJActionObject, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", i+ g_lGeometricIndex+1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionNumberInTable, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", i+1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionPosition, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", i+1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionOrientation, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d", i+1); SCR_M_SvL0_SaveEntry(p_stFile, M_A3DActionScale, SCR_CC_C_Cfg_NoChar); SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 3, "%d,%d", i+g_lGeometricIndex+1, g_lGeometricIndex+1); SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); SCR_g_ui_SvL0_IndentationLevel = 0; SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL); } } /**************************************************************************** * Description: Compute the global positions * * Parameters: p_hRoot : root of the bank *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vGetPositions (MLT_tdxHandleToSuperObject *p_hRoot) { int i; if (!(*p_hRoot)) return; for (i=0; i<(*p_hRoot)->lNbChild; i++) { (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xX = (*p_hRoot)->p_stMatrix->stTranslation.xX + (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xX; (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xY = (*p_hRoot)->p_stMatrix->stTranslation.xY + (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xY; (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xZ = (*p_hRoot)->p_stMatrix->stTranslation.xZ + (*p_hRoot)->d_hChild[i]->p_stMatrix->stTranslation.xZ; } // iteration on next level for (i=0; i<(*p_hRoot)->lNbChild; i++) { MLT_vGetPositions(&(*p_hRoot)->d_hChild[i]); } } /**************************************************************************** * Description: Compute the quaternion * * Parameters: stMatrix : a matrix for computing the quaternion * stQ : the computed quaternion *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vSetQuaternionFromMatrix( MTH_tdxReal stMatrix[3][3], float stQ[4]) { int X=0, Y=1, Z=2, W=3; // compute quaternion from matrix double trace, s; trace = (double)MTH_M_xRealToFloat( stMatrix[0][0] + stMatrix[1][1] + stMatrix[2][2] ); if ( trace > 0.0 ) { s = sqrt( trace + 1.0 ); stQ[W] = (float)(0.5 * s); s = 0.5 / s; stQ[X] = (float)(( stMatrix[2][1] - stMatrix[1][2] ) * s); stQ[Y] = (float)(( stMatrix[0][2] - stMatrix[2][0] ) * s); stQ[Z] = (float)(( stMatrix[1][0] - stMatrix[0][1] ) * s); } else { int iNext[3] = { Y, Z, X }; int i, j, k; i = X; if ( stMatrix[1][1] > stMatrix[0][0] ) i = Y; if ( stMatrix[2][2] > stMatrix[i][i] ) i = Z; j = iNext[i]; k = iNext[j]; s = sqrt( ( stMatrix[i][i] - ( stMatrix[j][j] + stMatrix[k][k] ) ) + 1.0 ); stQ[i] = (float)(s * 0.5); s = 0.5 / s; stQ[W] = (float)(( stMatrix[k][j] - stMatrix[j][k] ) * s); stQ[j] = (float)(( stMatrix[i][j] + stMatrix[j][i] ) * s); stQ[k] = (float)(( stMatrix[i][k] + stMatrix[k][i] ) * s); } }