reman3/Rayman_X/cpa/Appli/Max23Dos/src/A3dSave.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);
}
}