reman3/Rayman_X/cpa/Appli/Max23Dos/src/SpoLoad.c

948 lines
31 KiB
C

/*=========================================================================
*
* SpoLoad.c - Loading functions for SPO file
*
* Version 1.0
* Revision date
*
*=======================================================================*/
#include "SpoLoad.h"
#include "conventi.h"
#include "main.h"
#include "print.h"
#include "system.h"
#include "vertex.h"
#include "ModLib.h"
//--- Defines ---------------------------------------------------------------
#define C_szTransparencyFlag "TL"
#define C_iTransparencyLength 2
//--- Global defines --------------------------------------------------------
BOOL g_bSubFile = FALSE;
//--- Global statics --------------------------------------------------------
BOOL gs_bHierarchyAlreadyFree;
MLT_tdstSPOFlags g_stSPOFlags[32];
int g_iEditorSPOFlags[32];
int g_iNbEditorSPOFlags;
//--------------------------------------------------------------------
/****************************************************************************
* Description: register the loading function for the SPO file
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vInitSPOLoad()
{
SCR_fn_v_RdL0_RegisterCallback(M_SuperObject, MLT_xLoadSuperObject,SCR_CRC_c_RdL0_ForSection);
SCR_fn_v_RdL0_RegisterCallback(M_Matrix, MLT_xLoadMatrix,SCR_CRC_c_RdL0_ForSection);
}
/****************************************************************************
* Description: load super-object section in SPO file
*
* Parameters: p_stFile : script file pointer
* szAction : section or entry name
* szParams : parameters
* cType : action type
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadSuperObject(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
MLT_tdxHandleToSuperObject hSuperObject;
MLT_tdxHandleToSuperObject hNewSuperObject;
MLT_tdstGeometricObject *p_stObj;
MLT_tdstSubMaps *p_stSubMaps;
xString sFile, sAction, sIdent, sIdent2;
char *p_Char1, *p_Char2, *p_sConstraintAxis;
char sValue[20], szName[100];
long i;
switch (cType)
{
case SCR_EA_Anl_BeginSection:
hSuperObject = (MLT_tdxHandleToSuperObject)calloc(1,sizeof(MLT_tdstSprObj));
// init parameter
hSuperObject->lNbChild = 0;
hSuperObject->iGeomProp = 0;
hSuperObject->ulSPOFlags = 0;
hSuperObject->fTransparency = -1.0;
hSuperObject->stSector.lNbSecteurGraphic = 0;
hSuperObject->stSector.lNbSecteurActivity = 0;
hSuperObject->stSector.lNbSecteurCollision = 0;
hSuperObject->stSector.bIsVirtual = FALSE;
// get minimal name
SCR_fn_v_RdL0_SplitSectionName(SCR_M_RdL0_GetCompleteSectionNameR(0), sFile, sAction, sIdent);
// check for submaps
if (strstr(sFile, ".sub"))
{
g_bSubFile=TRUE;
SCR_M_RdL0_GetContextLong(-1,0,MLT_tdstSubMaps*,p_stSubMaps);
}
// check for mirror
if ((p_Char1=strstr(sIdent, "#mir"))!=NULL)
hSuperObject->iFlags |= MAYBE_MIRROR;
else
hSuperObject->iFlags =0;
// check for collision flag
if (strstr(sIdent, "!nocol"))
hSuperObject->ulSPOFlags |= 1 << g_stSPOFlags[MLT_iGetIndexSPOFlags("NC")].sFlag;
// compute super-object flags
MLT_vSetSPOFlags(&hSuperObject->ulSPOFlags, &hSuperObject->fTransparency, &sIdent);
// compute geometric properties
p_sConstraintAxis = (char *)malloc(7*sizeof(char));
if (p_sConstraintAxis)
{
MLT_vGeomProp( &hSuperObject->iGeomProp, &sIdent, &hSuperObject->cGeom, &hSuperObject->fGeom, &p_sConstraintAxis);
strcpy(hSuperObject->sConstraintAxis, p_sConstraintAxis);
free(p_sConstraintAxis);
}
// add the "SPO_" prefix if necessary
if( (strcmp(sIdent, M_Root) != 0) && (strstr(sIdent, M_SPO_) == NULL) )
sprintf(sIdent2, "SPO_%s", sIdent);
else
sprintf(sIdent2, "%s", sIdent);
SCR_fn_v_RdL0_ComputeSectionName(hSuperObject->sName, sFile, sAction, sIdent2);
SCR_M_RdL0_SetSectionLong(0,0,(unsigned long)hSuperObject);
SCR_M_RdL0_SetContextLong(0,0,(unsigned long)hSuperObject);
break;
case SCR_EA_Anl_Entry:
// submap sections have their own function
if (!g_bSubFile)
{
SCR_M_RdL0_GetContextLong(0,0,MLT_tdxHandleToSuperObject,hSuperObject);
// read the comment line and concatenate it to the name of the object
if (strcmp(szAction,M_SPOActionComment)==0)
{
strcat(hSuperObject->sName, szParams[0]);
SCR_fn_v_RdL0_SplitSectionName(hSuperObject->sName, sFile, sAction, sIdent);
// check for mirror
if ((p_Char1=strstr(sIdent, "#mir"))!=NULL)
hSuperObject->iFlags |= MAYBE_MIRROR;
else
hSuperObject->iFlags =0;
// check for SPO flags
MLT_vSetSPOFlags(&hSuperObject->ulSPOFlags, &hSuperObject->fTransparency, &sIdent);
// check for symmetry
if (((p_Char1=strstr(sIdent, "#Sym("))!=NULL) ||
((p_Char1=strstr(sIdent, "#SYM("))!=NULL) ||
((p_Char1=strstr(sIdent, "#sym("))!=NULL))
{
// take first the axe and the center
p_Char1=strstr(sIdent, "(");
if (p_Char1)
{ hSuperObject->cGeom = (sIdent)[strlen(sIdent)-strlen(p_Char1)+1];
p_Char1=strstr(sIdent, ",");
p_Char2=strstr(p_Char1, ")");
i=0;
while (p_Char1!=p_Char2)
{ sValue[i]=(sIdent)[strlen(sIdent)-strlen(p_Char1)+1];
p_Char1++;
i++;
}
sValue[i]='\0';
hSuperObject->fGeom = atof(sValue);
}
if (((p_Char1=strstr(sIdent, "#Sym"))!=NULL) ||
((p_Char1=strstr(sIdent, "#sym"))!=NULL) ||
((p_Char1=strstr(sIdent, "#SYM"))!=NULL))
{
p_Char2=strstr(sIdent, ")");
(sIdent)[strlen(sIdent)-strlen(p_Char1)]='\0';
strcpy(szName, sIdent);
if (*p_Char2 != 0)
strcat(szName, p_Char2+1);
strcpy(sIdent, szName);
}
hSuperObject->iGeomProp |= MAYBE_SYM;
}
// check for geometric properties
p_sConstraintAxis = (char *)malloc(7*sizeof(char));
if (p_sConstraintAxis)
{ MLT_vGeomProp( &hSuperObject->iGeomProp, &sIdent, &hSuperObject->cGeom, &hSuperObject->fGeom, &p_sConstraintAxis);
strcpy(hSuperObject->sConstraintAxis, p_sConstraintAxis);
free(p_sConstraintAxis);
}
// compute corresponding name
SCR_fn_v_RdL0_ComputeSectionName(hSuperObject->sName, sFile, sAction, sIdent2);
}
// load a Child SuperObject
if (strcmp(szAction,M_SPOActionAddChild)==0)
{
SCR_tdst_Cxt_Values *p_stVal;
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szParams[0], SCR_CDF_uw_Anl_Normal);
hNewSuperObject = (MLT_tdxHandleToSuperObject)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
hSuperObject->d_hChild[hSuperObject->lNbChild] = hNewSuperObject;
hSuperObject->lNbChild++;
}
// read the value from the flags in the .spo file
if (strcmp(szAction,M_SPOActionFlags)==0)
{
hSuperObject->ulSPOFlags=atoi(szParams[0]);
}
// read the value from the transparency in the .spo file
if (strcmp(szAction,M_SPOActionTransparency)==0)
{
hSuperObject->fTransparency=(float) atof(szParams[0]);
}
// read the Matrix
if (strcmp(szAction,M_SPOActionPutMatrix)==0)
{
MLT_tdstMatrix *p_stMatrix;
SCR_tdst_Cxt_Values *p_stVal;
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szParams[0], SCR_CDF_uw_Anl_Normal);
p_stMatrix = (MLT_tdstMatrix*)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
hSuperObject->p_stMatrix = p_stMatrix;
}
// load the associated Geometric Object
if (strcmp(szAction,M_SPOActionGeometric)==0)
{
sprintf(hSuperObject->sGeometric, "%s", szParams[0]);
SCR_fn_v_RdL0_SplitSectionName(hSuperObject->sGeometric, sFile, sAction, sIdent);
//remove the $flag$flag from its name
p_Char1=sIdent;
MLT_vRemoveFlags(&p_Char1);
strcpy(sIdent, p_Char1);
//remove the #geomprop#geomprop from its name
p_Char1=sIdent;
MLT_vRemoveGeomProp(&p_Char1);
strcpy(sIdent, p_Char1);
// compute result name
SCR_fn_v_RdL0_ComputeSectionName(hSuperObject->sGeometric, sFile, sAction, sIdent);
// check if object exists
if((p_stObj=MLT_pFindInLib(hSuperObject->sGeometric)) == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSuperObject->sGeometric);
}
// then update the property flags of the object from its super-object
else
{
p_stObj->iFlags =0;
if (hSuperObject->iGeomProp & MAYBE_SYM)
{
p_stObj->cGeom = hSuperObject->cGeom;
p_stObj->fGeom = hSuperObject->fGeom;
p_stObj->iFlags |= MAYBE_SYM;
}
if (hSuperObject->iGeomProp & MAYBE_ALTIMAP)
p_stObj->iFlags |= MAYBE_ALTIMAP;
if (hSuperObject->iGeomProp & IS_LOOKAT)
{ p_stObj->iFlags |= IS_LOOKAT;
strcpy(p_stObj->sConstraintAxis, hSuperObject->sConstraintAxis);
}
if (hSuperObject->iGeomProp & IS_SEMI_LA)
{ p_stObj->iFlags |= IS_SEMI_LA;
strcpy(p_stObj->sConstraintAxis, hSuperObject->sConstraintAxis);
}
if (hSuperObject->iGeomProp & MAYBE_SPH)
p_stObj->iFlags |= MAYBE_SPH;
// update the matrix of the obejct
p_stObj->p_stMatrix = hSuperObject->p_stMatrix;
}
}
// load the linked Object
if (strcmp(szAction,M_SPOActionLinkedObject)==0)
{
sprintf(hSuperObject->sLinkedObject, "%s", szParams[0]);
if((MLT_pFindInLib(hSuperObject->sLinkedObject) == NULL) && (strcmp(sFile, "temp.spo")))
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSuperObject->sLinkedObject);
}
}
}
break;
case SCR_EA_Anl_EndSection:
break;
}
return SCR_ERV_Anl_NormalReturn;
}
/****************************************************************************
* Description: load matrix section in SPO file
*
* Parameters: p_stFile : script file pointer
* szAction : section or entry name
* szParams : parameters
* cType : action type
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadMatrix(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
MTH3D_tdstVector stI,stJ,stK;
MLT_tdstSubMaps *p_stSubMaps;
MLT_tdstMatrix *p_stMatrix;
MTH_tdxReal a_xVertex[9];
xString sFile, sAction, sIdent, sIdent2;
long i;
switch (cType)
{
case SCR_EA_Anl_BeginSection:
// allocate and init matrix to identity
p_stMatrix=(MLT_tdstMatrix*)malloc(sizeof(MLT_tdstMatrix));
MLT_xSetIdentityMatrix(p_stMatrix);
SCR_fn_v_RdL0_SplitSectionName(SCR_M_RdL0_GetCompleteSectionNameR(0), sFile, sAction, sIdent);
// check for submaps
if (strstr(sFile, ".sub"))
{
g_bSubFile=TRUE;
SCR_M_RdL0_GetContextLong(-1,0,MLT_tdstSubMaps*,p_stSubMaps);
}
// if necessary add the "SPO_" prefix
if( (strcmp(sIdent, M_Root) != 0) && (strstr(sIdent, M_SPO_) == NULL) )
sprintf(sIdent2, "SPO_%s", sIdent);
else
sprintf(sIdent2, "%s", sIdent);
SCR_fn_v_RdL0_ComputeSectionName(p_stMatrix->sName, sFile, sAction, sIdent2);
SCR_M_RdL0_SetSectionLong(0,0,(unsigned long)p_stMatrix);
SCR_M_RdL0_SetContextLong(0,0,(unsigned long)p_stMatrix);
break;
case SCR_EA_Anl_Entry:
// submap sections have their own function
if (!g_bSubFile)
{
SCR_M_RdL0_GetContextLong(0,0,MLT_tdstMatrix*,p_stMatrix);
// load the translation
if (strcmp(szAction,M_MATActionTranslation)==0)
{
for (i=0;i<3;i++)
a_xVertex[i]=(MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[i])*MLT_dGetUnitInMeterInFile(p_fFile->a_szOpenFileName));
MLT_M_SetVertexXYZ(&stI,a_xVertex[0],a_xVertex[1],a_xVertex[2]);
MLT_xSetTranslationMatrix(p_stMatrix,&stI);
}
// load the rotation
if (strcmp(szAction,M_MATActionRotation)==0)
{
for (i=0;i<9;i++)
a_xVertex[i]=(MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[i]));
MLT_M_SetVertexXYZ(&stI,a_xVertex[0],a_xVertex[1],a_xVertex[2]);
MLT_M_SetVertexXYZ(&stJ,a_xVertex[3],a_xVertex[4],a_xVertex[5]);
MLT_M_SetVertexXYZ(&stK,a_xVertex[6],a_xVertex[7],a_xVertex[8]);
MLT_xSetRotationMatrix(p_stMatrix,&stI,&stJ,&stK);
}
// load the scale
if (strcmp(szAction,M_MATActionScale)==0)
{
for (i=0;i<9;i++)
a_xVertex[i]=(MTH_tdxReal)MTH_M_xFloatToReal(atof(szParams[i]));
MLT_M_SetVertexXYZ(&stI,a_xVertex[0],a_xVertex[1],a_xVertex[2]);
MLT_M_SetVertexXYZ(&stJ,a_xVertex[3],a_xVertex[4],a_xVertex[5]);
MLT_M_SetVertexXYZ(&stK,a_xVertex[6],a_xVertex[7],a_xVertex[8]);
MLT_xSetScaleMatrix(p_stMatrix,&stI,&stJ,&stK);
}
}
break;
case SCR_EA_Anl_EndSection:
break;
}
return SCR_ERV_Anl_NormalReturn;
}
/****************************************************************************
* Description: read the SPOFlags file to init the flag values
*
* Parameters: sRawData : source directory
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vReadSPOFlagsFile (xString sRawData)
{
FILE *fileR;
xString sDirectory, sRead, sDir, sIdent, sIniFile;
char szEditorFlags[10][15];
char *p_char, *p_Char1;
int i=0, j=0;
//create a structure with the corresponding values and strings
for (i=0; i<32; i++)
{
strcpy(g_stSPOFlags[i].szFlag, "");
g_stSPOFlags[i].sFlag = -1;
}
// change directory
GetCurrentDirectory(256, sDirectory);
SetCurrentDirectory(g_sInitialDir);
// open file, in main directory or in rawdata directory
fileR = fopen("SuperObjectsFlags.txt", "rt");
i=0;
if (!fileR)
{
if (g_bStandardConfig)
{
strcpy(sDir, sRawData);
strcat(sDir, "\\World\\Levels");
}
else
strcpy(sDir, g_szLevels);
SetCurrentDirectory(sDir);
fileR = fopen("SuperObjectsFlags.txt", "rt");
if (!fileR)
{
SetCurrentDirectory(sDirectory);
if (g_bStandardConfig)
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No file SuperObjectsFlags.txt in the RawData\\World\\Levels neither in the directory of the program ");
else
MLT_vOutput( C_ComRes_cErrorLine, "\nError : No file SuperObjectsFlags.txt in the Levels directory, neither in the directory of the program ");
return;
}
}
// read the file
while(fgets(sRead, 256, fileR) != NULL)
{
if( (p_char=strstr(sRead, "=")) != NULL)
{
// complete the structure with the names and the values taken from the .ini file
sRead[strlen(sRead)-strlen(p_char)-1]='\0';
strcpy(g_stSPOFlags[i].szFlag, sRead+1);
g_stSPOFlags[i].sFlag = atoi(p_char+1);
i++;
}
}
fclose(fileR);
// read the editor flags
sprintf(sIniFile, "%s\\GIData.ini", g_sInitialDir);
GetPrivateProfileString( "EditorFlags", "SuperObject", "", sIdent, MAX_PATH, sIniFile );
j=0;
if (strcmp(sIdent, ""))
{
p_Char1=sIdent;
while( (*p_Char1 != ',') && (*p_Char1 != 0))
{
i=0;
while( (*p_Char1 != ',') && (*p_Char1 != 0))
{
szEditorFlags[j][i]=*p_Char1;
p_Char1++;
i++;
}
szEditorFlags[j][i] = '\0';
if (*p_Char1 != 0)
p_Char1++;
j++;
}
}
g_iNbEditorSPOFlags= j;
// identify the editor flags
for (i=0; i<g_iNbEditorSPOFlags; i++)
g_iEditorSPOFlags[i] = MLT_iGetIndexSPOFlags(szEditorFlags[i]);
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: compute the SPO flags and remove them from the given name
*
* Parameters: p_ulSPOFlags : returns the flags
* p_fTransparency : returns the transparency
* sIdent : name to check and update
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vSetSPOFlags (unsigned long *p_ulSPOFlags, float *p_fTransparency, xString *sIdent)
{
char *p_Char1, *p_Char2;
char szName[50], szFlags[5];
int i;
// flags are identified with $
if ((p_Char1=strstr(*sIdent, "$"))!=NULL)
{
p_Char2=p_Char1;
// flags are separated by $ or _
while ((*p_Char1 == '$') || (*p_Char1 == '_'))
{
p_Char1++;
i=0;
// look for separation characters
while((*p_Char1 != 0) && (*p_Char1 != '|')
&& (*p_Char1 != '#') && (*p_Char1 != '&')
&& (*p_Char1 != '=') && (*p_Char1 != '_')
&& (*p_Char1 != '$') && (*p_Char1 != '!'))
{
szFlags[i]=*p_Char1;
p_Char1++;
i++;
}
szFlags[i] = '\0';
// specific flag: transparency level
if (!strncmp(szFlags, C_szTransparencyFlag, C_iTransparencyLength))
*p_fTransparency = (float) atof(szFlags + C_iTransparencyLength);
//complete the flag for the object
else
*p_ulSPOFlags |= 1 << g_stSPOFlags[MLT_iGetIndexSPOFlags(szFlags)].sFlag;
}
//remove the $flag$flag from the name
(*sIdent)[strlen(*sIdent)-strlen(p_Char2)]='\0';
strcpy(szName, *sIdent);
if (*p_Char1 != 0)
strcat(szName, p_Char1);
strcpy(*sIdent, szName);
}
}
/****************************************************************************
* Description: get the index of the flag in the flag array
*
* Parameters: szFlag : flag to search for
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
int MLT_iGetIndexSPOFlags (char *szFlag)
{
int i;
for (i=0; i<32; i++)
{
if (!strcmp(g_stSPOFlags[i].szFlag, szFlag))
return i;
}
return -1;
}
/****************************************************************************
* Description: compute the geometric properties and remove them from the given name
*
* Parameters: p_iGeomProp : returns the geometric flags
* sIdent : name to check and update
* p_cGeom : returns the geometric properties
* p_fGeom : returns the geometric values
* p_sConstraintAxis : returns the constraint axis
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vGeomProp (int * p_iGeomProp, xString *sIdent, char *p_cGeom, double* p_fGeom, char * p_sConstraintAxis[4] )
{
char *p_Char1, *p_Char2;
long i;
char sValue[20];
// ini parameters
(*p_sConstraintAxis)[0] = '\0';
// check for mirror
if (((p_Char1=strstr(*sIdent, "#mir"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#MIR"))!=NULL))
{
//remove from name #mir
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#mir");
strcpy(*sIdent, p_Char1);
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#MIR");
strcpy(*sIdent, p_Char1);
}
// check for altimap
if (((p_Char1=strstr(*sIdent, "#alt"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#ALT"))!=NULL))
{
//remove from name #alt
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#alt");
strcpy(*sIdent, p_Char1);
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#ALT");
strcpy(*sIdent, p_Char1);
*p_iGeomProp |= MAYBE_ALTIMAP;
}
// check for symmetry
if (((p_Char1=strstr(*sIdent, "#Sym"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#SYM"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#sym"))!=NULL))
{
// remove from name #sym
if (((p_Char1=strstr(*sIdent, "#Sym"))!=NULL) || ((p_Char1=strstr(*sIdent, "#sym"))!=NULL)|| ((p_Char1=strstr(*sIdent, "#SYM"))!=NULL))
{
p_Char2=p_Char1;
p_Char1+=4;
i=0;
*p_cGeom = *p_Char1;
//take the point
while( (*p_Char1 != 0) && (*p_Char1 != '|')
&& (*p_Char1 != '$') && (*p_Char1 != '&')
&& (*p_Char1 != '=') && (*p_Char1 != '_')
&& (*p_Char1 != '#') && (*p_Char1 != '!'))
{ sValue[i]=(*sIdent)[strlen(*sIdent)-strlen(p_Char1)+1];
p_Char1++; i++;
}
sValue[i]='\0';
*p_fGeom=atof(sValue);
}
(*sIdent)[strlen(*sIdent)-strlen(p_Char2)]='\0';
strcat(*sIdent, p_Char1);
*p_iGeomProp |= MAYBE_SYM;
}
// check for lookat
if (((p_Char1=strstr(*sIdent, "#la"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#LA"))!=NULL))
{
//remove from name #la
if (((p_Char1=strstr(*sIdent, "#la"))!=NULL) || ((p_Char1=strstr(*sIdent, "#LA"))!=NULL))
{
p_Char2=p_Char1;
p_Char1+=3;
i=0;
//take the ConstraintAxe
while( (*p_Char1 != 0) && (*p_Char1 != '|')
&& (*p_Char1 != '$') && (*p_Char1 != '&')
&& (*p_Char1 != '=') && (*p_Char1 != '_')
&& (*p_Char1 != '#') && (*p_Char1 != '!')
&& (i<7))
{ (*p_sConstraintAxis)[i]=(*p_Char1);
p_Char1++; i++;
}
(*p_sConstraintAxis)[i] = '\0';
(*sIdent)[strlen(*sIdent)-strlen(p_Char2)]='\0';
strcat(*sIdent, p_Char1);
*p_iGeomProp |= (i>0) ? IS_SEMI_LA : IS_LOOKAT;
}
}
// check for sphere
if (((p_Char1=strstr(*sIdent, "#sph"))!=NULL) ||
((p_Char1=strstr(*sIdent, "#SPH"))!=NULL))
{
//remove from name #sph
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#sph");
strcpy(*sIdent, p_Char1);
p_Char1=*sIdent;
MLT_vExtractPropFromName(&p_Char1, "#SPH");
strcpy(*sIdent, p_Char1);
*p_iGeomProp |= MAYBE_SPH;
}
}
/****************************************************************************
* Description: load the hierarchy from the SPO file
*
* Parameters: p_hRoot : pointer on the root that must be loaded
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vLoadHierarchy (MLT_tdxHandleToSuperObject *p_hRoot)
{
SCR_tdst_Cxt_Values *p_stVal;
xString sSection, sFileSpo;
xString sDirectory;
// save directory
GetCurrentDirectory(256, sDirectory);
sprintf(sFileSpo, "%s.spo", g_sFileIn);
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFileSpo, M_SuperObject, M_Root);
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sSection, SCR_CDF_uw_Anl_Normal);
*p_hRoot = (MLT_tdxHandleToSuperObject)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
if (*p_hRoot == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load hierarchy %s", sFileSpo);
MLT_vExitSystem();
}
gs_bHierarchyAlreadyFree = FALSE;
// restore directory
SetCurrentDirectory(sDirectory);
}
/****************************************************************************
* Description: check the hierarchy for the mirror objects (recursive function)
*
* Parameters: p_hRoot : pointer on the hierarchy root
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vCheckHierarchy (MLT_tdxHandleToSuperObject *p_hRoot)
{
int i, j, iNumberGeometric;
char szName[500];
MLT_tdstGeometricObject *p_stGeometric, *p_stGeometricFather;
if (!(*p_hRoot))
return;
if ((*p_hRoot)->iFlags & MAYBE_MIRROR)
{
// the object is a mirror
if ((*p_hRoot)->lNbChild)
{
for (i=0; i<(*p_hRoot)->lNbChild; i++)
{
// check each child
strcpy(szName, (*p_hRoot)->d_hChild[i]->sGeometric);
// check for the geometric object
if ((p_stGeometric=MLT_pFindInLib(szName))!=NULL)
{
// the number of the vertexes in a mirror is 4
if (p_stGeometric->xNbPoints==4)
{
// find object father
p_stGeometricFather=MLT_pFindInLib((*p_hRoot)->sGeometric);
if(p_stGeometricFather == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", (*p_hRoot)->sGeometric);
return;
}
// update father with mirror object
p_stGeometricFather->xNbPoints+=4;
p_stGeometricFather->d_stListOfPoints=
(MTH3D_tdstVector*)realloc(p_stGeometricFather->d_stListOfPoints,(p_stGeometricFather->xNbPoints)*sizeof(MTH3D_tdstVector));
if (p_stGeometricFather->d_stListOfPoints==NULL)
return;
for (j=0; j<4; j++)
{ p_stGeometricFather->d_stListOfPoints[p_stGeometricFather->xNbPoints-4+j].xX = p_stGeometric->d_stListOfPoints[j].xX;
p_stGeometricFather->d_stListOfPoints[p_stGeometricFather->xNbPoints-4+j].xY = p_stGeometric->d_stListOfPoints[j].xY;
p_stGeometricFather->d_stListOfPoints[p_stGeometricFather->xNbPoints-4+j].xZ = p_stGeometric->d_stListOfPoints[j].xZ;
}
p_stGeometricFather->d_stListOfPointsNormals=(MTH3D_tdstVector*)realloc(p_stGeometricFather->d_stListOfPointsNormals, p_stGeometricFather->xNbPoints*sizeof(MTH3D_tdstVector));
if (p_stGeometricFather->d_stListOfPointsNormals==NULL)
return;
for (j=0; j<4; j++)
{ p_stGeometricFather->d_stListOfPointsNormals[p_stGeometricFather->xNbPoints-4+j].xX = p_stGeometric->d_stListOfPointsNormals[j].xX;
p_stGeometricFather->d_stListOfPointsNormals[p_stGeometricFather->xNbPoints-4+j].xY = p_stGeometric->d_stListOfPointsNormals[j].xY;
p_stGeometricFather->d_stListOfPointsNormals[p_stGeometricFather->xNbPoints-4+j].xZ = p_stGeometric->d_stListOfPointsNormals[j].xZ;
}
p_stGeometricFather->d_stListOfPointsReceivedLightIntensity=(MLT_tdstColor*)realloc(p_stGeometricFather->d_stListOfPointsReceivedLightIntensity, p_stGeometricFather->xNbPoints*sizeof(MLT_tdstColor));
if (p_stGeometricFather->d_stListOfPointsReceivedLightIntensity==NULL)
return;
for (j=0; j<4; j++)
{ p_stGeometricFather->d_stListOfPointsReceivedLightIntensity[p_stGeometricFather->xNbPoints-4+j].xR = p_stGeometric->d_stListOfPointsReceivedLightIntensity[j].xR;
p_stGeometricFather->d_stListOfPointsReceivedLightIntensity[p_stGeometricFather->xNbPoints-4+j].xG = p_stGeometric->d_stListOfPointsReceivedLightIntensity[j].xG;
p_stGeometricFather->d_stListOfPointsReceivedLightIntensity[p_stGeometricFather->xNbPoints-4+j].xB = p_stGeometric->d_stListOfPointsReceivedLightIntensity[j].xB;
}
// remove miror object from the library
iNumberGeometric=MLT_lGetNumberObjectInLib();
iNumberGeometric--;
MLT_vEraseObjInLib(p_stGeometric);
// remove mirror object from the hierarchy
strcpy((*p_hRoot)->d_hChild[i]->sGeometric, "");
MLT_vDeleteHierarchy((*p_hRoot)->d_hChild[i]);
// update root
(*p_hRoot)->lNbChild=0;
(*p_hRoot)->iFlags |= IS_MIRROR;
return;
}
}
}
}
}
// iteration on next level
for (i=0; i<(*p_hRoot)->lNbChild; i++)
{
MLT_vCheckHierarchy(&(*p_hRoot)->d_hChild[i]);
}
}
/****************************************************************************
* Description: delete the complete hierarchy (recursive function)
*
* Parameters: hSprObj : hierarchy root
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vDeleteHierarchy (MLT_tdxHandleToSuperObject hSprObj)
{
long i;
if(gs_bHierarchyAlreadyFree) return;
if(hSprObj == NULL) return;
free(hSprObj->p_stMatrix);
for(i=0; i<hSprObj->lNbChild; i++)
{
MLT_vDeleteHierarchy(hSprObj->d_hChild[i]);
hSprObj->d_hChild[i] = NULL;
}
hSprObj->lNbChild = 0;
free(hSprObj);
gs_bHierarchyAlreadyFree = TRUE;
}
/****************************************************************************
* Description: find object with the given name in the hierarchy (recursive function)
*
* Parameters: sName : name of object to search for
* hSprObj : hierarchy root
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
MLT_tdxHandleToSuperObject MLT_hFindInHierarchy (char *sName, MLT_tdxHandleToSuperObject hSprObj)
{
long i;
if (hSprObj == NULL)
return NULL;
// compare name
if(strstr(hSprObj->sName, sName) != NULL)
return hSprObj;
// search next level
else
{
for(i=0; i<hSprObj->lNbChild; i++)
{
MLT_tdxHandleToSuperObject hTmp;
hTmp = MLT_hFindInHierarchy(sName, hSprObj->d_hChild[i]);
if (hTmp != NULL)
return hTmp;
}
return NULL;
}
}
/****************************************************************************
* Description: find sector with the given name in the hierarchy
*
* Parameters: sName : name of sector to search for
* hSprObj : hierarchy root
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
MLT_tdxHandleToSuperObject MLT_hFindInHierarchySector (char *sName, MLT_tdxHandleToSuperObject hSprObj)
{
long i;
char sLwrName[256], sLwrSprObjName[256];
char sFile[256], sAction[256];
strcpy(sLwrName, sName);
if(hSprObj == NULL)
return NULL;
// compare with super object
SCR_fn_v_RdL0_SplitSectionName(hSprObj->sName, sFile, sAction, sLwrSprObjName);
if (stricmp(sLwrSprObjName, sLwrName) == 0)
return hSprObj;
if (!strncmp(sLwrSprObjName, "SPO_", 4) && !stricmp(sLwrSprObjName+4, sLwrName))
return hSprObj;
// compare with childs
for(i=0; i<hSprObj->lNbChild; i++)
{
SCR_fn_v_RdL0_SplitSectionName(hSprObj->d_hChild[i]->sName, sFile, sAction, sLwrSprObjName);
if (stricmp(sLwrSprObjName, sLwrName) == 0)
return hSprObj->d_hChild[i];
if (!strncmp(sLwrSprObjName, "SPO_", 4) && !stricmp(sLwrSprObjName+4, sLwrName))
return hSprObj->d_hChild[i];
}
// not found
return NULL;
}
/****************************************************************************
* Description: compare the name of a super-object with the section name of a sector
*
* Parameters: sName : name of super-object
* sSector : section name of sector
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
BOOL MLT_bIsNotSameSector (char *sName, char *sSector)
{
char sFile[256], sAction[256], sIdent[256];
SCR_fn_v_RdL0_SplitSectionName(sSector, sFile, sAction, sIdent);
return (stricmp(sName+4, sIdent) != 0);
}
/****************************************************************************
* Description: get unit (in meter) for geometric objets
*
* Parameters: szGeometricFile : name of the geometric file
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
double MLT_dGetUnitInMeterInFile (char *szGeometricFile)
{
double ret;
SCR_M_RdL0_GetFileDouble(0, 1, ret);
return ret;
}