948 lines
31 KiB
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|