320 lines
12 KiB
C
320 lines
12 KiB
C
/*=========================================================================
|
|
*
|
|
* 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);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|