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

959 lines
30 KiB
C

/*=========================================================================
*
* RLISave.c - Saving functions for RLI file
*
* Version 1.0
* Revision date
*
*=======================================================================*/
#include <Windows.h>
#include "RliSave.h"
#include "conventi.h"
#include "print.h"
#include "system.h"
#include "vertex.h"
#include "Levels.h"
#include "ModLib.h"
#include "Submaps.h"
#include "VseSave.h"
//--- Global defines --------------------------------------------------------
long g_lLightIndex = 0;
//--- Global statics --------------------------------------------------------
MLT_Light **gs_hLights = NULL;
char *gs_LightTypes[] = {"Spherical", "Ambient", "HotSpot", "Parallel"};
char *gs_LightPrefix[] = {"_paint", "_alpha", "_list"};
//--- Mathematic functions --------------------------------------------------------
// compute the power2
float sqr(float x)
{
return x*x;
}
// compute the scalar product between 2 3D vectors
float ScalarProduct(MTH3D_tdstVector *v1, MTH3D_tdstVector *v2)
{
return v1->xX*v2->xX + v1->xY*v2->xY + v1->xZ*v2->xZ;
}
//--------------------------------------------------------------------
/****************************************************************************
* Description: Load a LG2 file
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vLoadLG2()
{
SCR_tdst_Cxt_Values *p_stVal;
xString szFileName;
int f;
sprintf(szFileName, "%s.lg2", g_sFileIn);
MLT_vDeleteAllLights();
SCR_fn_v_RdL0_RegisterCallback(M_Light, MLT_xLoadLight, SCR_CRC_c_RdL0_ForSection);
f = _open(szFileName, O_RDONLY, S_IREAD);
if(f != -1)
{
_close(f);
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_ForceAnalyse);
}
SCR_fn_v_RdL0_DeleteRegisterCallback(M_Light, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
}
/****************************************************************************
* Description: Load a LGT file
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_LoadLGT()
{
SCR_tdst_Cxt_Values *p_stVal;
xString szFileName;
int f;
sprintf(szFileName, "%s.lgt", g_sFileIn);
MLT_vDeleteAllLights();
SCR_fn_v_RdL0_RegisterCallback(M_Light, MLT_xLoadLight, SCR_CRC_c_RdL0_ForSection);
f = _open(szFileName, O_RDONLY, S_IREAD);
if(f != -1)
{
_close(f);
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(szFileName, SCR_CDF_uw_Anl_ForceAnalyse);
}
SCR_fn_v_RdL0_DeleteRegisterCallback(M_Light, SCR_CRC_c_RdL0_ForSection, SCR_CDR_c_RdL0_Match);
}
/****************************************************************************
* Description: create and save the RLI file
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vCreateRLI ()
{
MLT_tdxHandleToSuperObject hRoot;
SCR_tdst_File_Description stFile;
SCR_tdst_Cxt_Values *p_stVal;
MLT_tdstMatrix stMatrix;
MLT_tdstColor **rli;
xString sRoot, sFileSpo, sDir, sRawBank;
xString sFile, sAction, sIdent, sSection;
int i, j, nRLI = 0;
g_bExistSpoBank=FALSE;
if (!g_bLevel)
{
// find SPO file
if (g_bStandardConfig)
{
switch (g_iRaw)
{
case 0:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks", g_sRawCommon);
break;
case 1:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks", g_sRawSpecific1);
break;
case 2:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks", g_sRawSpecific2);
break;
}
}
else
sprintf(sRawBank, g_szBanks);
}
else
{
if (g_bStandardConfig)
{
switch (g_iRaw)
{
case 0:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sRawCommon, g_sFileIn);
break;
case 1:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sRawSpecific1, g_sFileIn);
break;
case 2:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sRawSpecific2, g_sFileIn);
break;
}
}
else
sprintf(sRawBank, "%s\\%s", g_szLevels, g_sFileIn);
}
GetCurrentDirectory(256, sDir);
SetCurrentDirectory(sRawBank);
sprintf(sFileSpo, "%s.spo", g_sFileIn);
if (!g_bLevel)
{
SCR_fn_v_RdL0_ComputeSectionName(sRoot, sFileSpo, M_SuperObject, M_Root);
// load module hierarchy
if(SCR_fn_c_RdL0_IsSectionExists(sRoot))
{
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sRoot, SCR_CDF_uw_Anl_Normal);
hRoot = (MLT_tdxHandleToSuperObject)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
g_bExistSpoBank = TRUE;
MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate RLI...");
}
else
g_bExistSpoBank = FALSE;
}
else
hRoot = g_hRoot;
if (g_bExistSpoBank || g_bLevel)
{
if (!g_bLevel)
{
// find SPO file
switch (g_iData)
{
case 0:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks\\%s", g_sGameCommon, g_sFileIn);
break;
case 1:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks\\%s", g_sGameSpecific1, g_sFileIn);
break;
case 2:
sprintf(sRawBank, "%s\\World\\Graphics\\Objects\\Banks\\%s", g_sGameSpecific2, g_sFileIn);
break;
}
}
else
{
switch (g_iData)
{
case 0:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sGameCommon, g_sFileIn);
break;
case 1:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sGameSpecific1, g_sFileIn);
break;
case 2:
sprintf(sRawBank, "%s\\World\\Levels\\%s", g_sGameSpecific2, g_sFileIn);
break;
}
}
SetCurrentDirectory(sRawBank);
// init RLI file
sprintf(stFile.a_szFileName,"%s.rli", g_sFileIn);
remove(stFile.a_szFileName);
strcpy(stFile.a_szOpenFileName, stFile.a_szFileName);
stFile.p_stHandle = (SCR_tdst_File_Handle*)malloc(sizeof(SCR_tdst_File_Handle));
stFile.p_stHandle->xHandle = (FILE*)_open(stFile.a_szFileName, O_WRONLY | O_CREAT | _O_TEXT, S_IREAD | S_IWRITE);;
stFile.p_stHandle->p_cBase = stFile.p_stHandle->p_cCurrent = 0;
stFile.p_stHandle->iCnt = 0;
stFile.d_stFirstPage = stFile.d_stLastPage = stFile.d_stCurPage = NULL;
stFile.iCurPosInPage = 0;
if(stFile.p_stHandle->xHandle != 0)
{
// number of RLI tables
for (i = 0; i<g_lLightIndex; i++)
nRLI = max(nRLI, gs_hLights[i]->iRLI);
nRLI++;
rli = (MLT_tdstColor **)malloc(nRLI*sizeof(MLT_tdstColor *));
// loop in modules hierarchy
MLT_xSetIdentityMatrix(&stMatrix);
if (g_bLevel)
{
sprintf(sFile, "%s.sct", g_sFileIn);
if(! SCR_fn_c_RdL0_IsSectionExists(sFile))
return;
for(i=0; i<hRoot->lNbChild-(g_iUnivSectors+1); i++)
{
// recover the old sector
SCR_fn_v_RdL0_SplitSectionName(hRoot->d_hChild[i]->stSector.sName, sFile, sSection, sIdent);
SCR_fn_v_RdL0_ComputeSectionName(sAction, sFile, M_Sector, sIdent);
if(SCR_fn_c_RdL0_IsSectionExists(sAction))
{
MLT_tdstSector *p_stOldSector;
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sAction, SCR_CDF_uw_Anl_Normal);
p_stOldSector = (MLT_tdstSector*) SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0);
// copy lights
for (j=0; j<p_stOldSector->lNbStaticLights; j++)
strcpy(hRoot->d_hChild[i]->stSector.a_sStaticLights[j], p_stOldSector->a_sStaticLights[j]);
hRoot->d_hChild[i]->stSector.lNbStaticLights = p_stOldSector->lNbStaticLights;
}
}
for (i = 0; i < hRoot->lNbChild; i++)
{
for (j = 0; j < hRoot->d_hChild[i]->lNbChild; j++)
{
hRoot->d_hChild[i]->d_hChild[j]->stSector = hRoot->d_hChild[i]->stSector;
MLT_vComputeSector (hRoot->d_hChild[i]->d_hChild[j]);
}
}
}
MLT_vComputeOneRLI(hRoot, &stMatrix, rli, nRLI, &stFile);
free(rli);
}
_close((int)stFile.p_stHandle->xHandle);
free(stFile.p_stHandle);
// MLT_vDeleteAllLights();
}
else
SetCurrentDirectory(sDir);
}
/****************************************************************************
* Description: Clears the light list
*
* Parameters:
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vDeleteAllLights()
{
int i;
if(g_lLightIndex)
{
for(i=0; i<g_lLightIndex; i++)
{
if(gs_hLights[i]->Matrix) free(gs_hLights[i]->Matrix);
free(gs_hLights[i]);
}
free(gs_hLights);
gs_hLights = NULL;
g_lLightIndex = 0;
}
}
/****************************************************************************
* Description: Light section callback
*
* Parameters: p_stFile : script file pointer
* szAction : section or entry name
* szParams : parameters
* cType : action type
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadLight(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
SCR_tdst_Cxt_Values *p_stVal;
MLT_Light *l;
char *c;
switch (cType)
{
case SCR_EA_Anl_BeginSection:
l = (MLT_Light*)malloc(sizeof(MLT_Light));
SCR_M_RdL0_SetSectionLong(0,0,(long)l);
SCR_M_RdL0_SetContextLong(0,0,(long)l);
gs_hLights = (MLT_Light**)realloc(gs_hLights, (++g_lLightIndex)*sizeof(MLT_Light*));
gs_hLights[g_lLightIndex - 1] = l;
l->iGeomType = MLT_iGetLightType(szParams[0]);
sprintf(l->sName,"%s",SCR_M_RdL0_GetCompleteSectionNameR(0));
if ( strstr(l->sName, "FORCE_FULL_LIGHT_"))
l->bNotCompute = TRUE;
else
l->bNotCompute = FALSE;
l->Matrix = NULL;
l->iState = 0;
l->iRLI = 0;
l->iType = L_RGB;
if(strstr(l->sName, gs_LightPrefix[0])) l->iType |= L_PAINT;
if(strstr(l->sName, gs_LightPrefix[1])) l->iType |= L_ALPHA;
c = l->sName;
do c = strstr(c+1, gs_LightPrefix[2]);
while(c && (!isdigit(c[5]) || !isdigit(c[6])));
if(c) l->iRLI = atoi(c+5);
break;
case SCR_EA_Anl_Entry:
SCR_M_RdL0_GetContextLong(0, 0, MLT_Light*, l);
// set light's state
if(!lstrcmpi(szAction, M_LGTActionSetState)) l->iState = atoi(szParams[0]);
if(!lstrcmpi(szAction, M_LGTActionSetColor))
{
l->color.xR = (float) atof(szParams[0]);
l->color.xG = (float) atof(szParams[1]);
l->color.xB = (float) atof(szParams[2]);
if(l->iType & L_ALPHA)
l->color.xA = (float) atof(szParams[0]);
else
l->color.xA = (float) atof(szParams[3]);
}
// matrix name
if(!lstrcmpi(szAction, M_LGTActionSetMatrix))
{
c = strchr(szParams[0], '^');
if(c)
{
*(c-1) = '*';
p_stVal = SCR_fnp_st_RdL0_AnalyseSection(c-1, SCR_CDF_uw_Anl_Normal);
l->Matrix = (MLT_tdstMatrix*)SCR_M_ul_RdL0_ExtractLongValue(p_stVal, 0);
}
}
// Near/Far parameters
if(!lstrcmpi(szAction, M_LGTActionSetNearFar))
{
l->fNearFar[0] = (float)atof(szParams[0]);
l->fNearFar[1] = (float)atof(szParams[1]);
}
// Alpha angles
if(!lstrcmpi(szAction, M_LGTActionSetAlphas))
{
l->fAlphas[0] = (float)atof(szParams[0]);
l->fAlphas[1] = (float)atof(szParams[1]);
}
break;
case SCR_EA_Anl_EndSection:
break;
}
return SCR_ERV_Anl_NormalReturn;
}
/****************************************************************************
* Description: Light matrix section callback
*
* Parameters: p_stFile : script file pointer
* szAction : section or entry name
* szParams : parameters
* cType : action type
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
SCR_tde_Anl_ReturnValue MLT_xLoadMatrixRLI(SCR_tdst_File_Description *p_fFile, char *szAction, char *szParams[], SCR_tde_Anl_Action cType)
{
long i;
xString sFile, sAction, sIdent, sIdent2;
MTH_tdxReal a_xVertex[9];
MLT_tdstMatrix *p_stMatrix;
MTH3D_tdstVector stI,stJ,stK;
switch (cType)
{
case SCR_EA_Anl_BeginSection:
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);
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:
{
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_M_SetVertexXYZ(&stI,a_xVertex[0],a_xVertex[1],a_xVertex[2]);
MLT_xSetTranslationMatrix(p_stMatrix,&stI);
}
// 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);
}
// 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);
}
}
break;
case SCR_EA_Anl_EndSection:
break;
}
return SCR_ERV_Anl_NormalReturn;
}
/****************************************************************************
* Description: compute RLI for Full Light
*
* Parameters: obj : geometric object
* rli : rli list
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeFullRLI(MLT_tdstGeometricObject *obj, MLT_tdstColor *rli)
{
int i;
for(i=0; i<obj->xNbPoints; i++)
{
(rli+i)->xR = (float) 255.0;
(rli+i)->xG = (float) 255.0;
(rli+i)->xB = (float) 255.0;
(rli+i)->xA = (float) 255.0;
}
}
/****************************************************************************
* Description: compute RLI for Spherical Light
*
* Parameters: p_stMatrix : current matrix
* light : current light
* obj : geometric object
* rli : rli list
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeSphericalRLI (MLT_tdstMatrix *p_stMatrix, MLT_Light *light, MLT_tdstGeometricObject *obj, MLT_tdstColor *rli)
{
MTH3D_tdstVector dist, lightpos, norm, realpoint;
MTH3D_tdstVector *point = obj->d_stListOfPoints;
MTH3D_tdstVector *normal = obj->d_stListOfPointsNormals;
float near2 = sqr(light->fNearFar[0]);
float far2 = sqr(light->fNearFar[1]);
float delta, d, coef;
int i;
delta = far2 - near2 > 1e-8 ? 1.f/(far2 - near2) : 1.f;
MLT_xGetTranslationMatrix(light->Matrix, &lightpos);
// for all object's points
for (i=0; i<obj->xNbPoints; i++)
{
MTH3D_M_vCopyVector(&norm, normal+i);
MTH3D_M_vNormalizeVector(&norm, &norm);
MLT_xMulMatrixVertex(&realpoint, p_stMatrix, point+i);
// compute the vector light-point
MTH3D_M_vSubVector(&dist, &lightpos, &realpoint);
// compute the square distance
d = sqr(dist.xX) + sqr(dist.xY) + sqr(dist.xZ);
// if point may be in the light action zone
if (d < far2)
{
// compute the reflexion coeficient
coef = -ScalarProduct(&dist, &norm) / (float)(d > 1e-4 ? sqrt(d) : 1e-2);
// if PaintLight, then no backface
if (light->iType|L_PAINT && coef<0)
coef = -coef;
// update the coeficient
if (d >= near2)
coef *= (far2 - d)*delta;
// adds the light effect to RLI
if (coef > 0)
MLT_vAddLightEffect(rli+i, &light->color, coef);
}
}
}
/****************************************************************************
* Description: compute RLI for Ambiant Light
*
* Parameters: p_stMatrix : current matrix
* light : current light
* obj : geometric object
* rli : rli list
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeAmbientRLI (MLT_tdstMatrix *p_stMatrix, MLT_Light *light, MLT_tdstGeometricObject *obj, MLT_tdstColor *rli)
{
int i;
for (i=0; i<obj->xNbPoints; i++)
MLT_vAddLightEffect(rli+i, &light->color, 1.f);
}
/****************************************************************************
* Description: compute RLI for HotSpot Light
*
* Parameters: p_stMatrix : current matrix
* light : current light
* obj : geometric object
* rli : rli list
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeHotSpotRLI (MLT_tdstMatrix *p_stMatrix, MLT_Light *light, MLT_tdstGeometricObject *obj, MLT_tdstColor *rli)
{
MTH3D_tdstVector dist, c0, c1, c2, norm, realpoint;
MTH3D_tdstVector *point = obj->d_stListOfPoints;
MTH3D_tdstVector *normal = obj->d_stListOfPointsNormals;
float near2 = sqr(light->fNearFar[0]);
float far2 = sqr(light->fNearFar[1]);
float ltan = (float)tan(light->fAlphas[0]/2);
float btan = (float)tan(light->fAlphas[1]/2);
float delta, deltatg, d, coef;
int i;
delta = far2 - near2 > 1e-8 ? 1.f/(far2 - near2) : 1.f;
deltatg = btan - ltan > 1e-8 ? 1.f/(btan - ltan) : 1.f;
// for all object's points
for (i=0; i<obj->xNbPoints; i++)
{
MTH3D_M_vCopyVector(&norm, normal+i);
MTH3D_M_vNormalizeVector(&norm, &norm)
MLT_xMulMatrixVertex(&realpoint, p_stMatrix, point+i);
// get the light-point vector
MTH3D_M_vSubVector(&c2, &light->Matrix->stTranslation, &realpoint);
// get the rotation matrix on columns
MLT_xGetRotationMatrix(light->Matrix, &c0, &c1, &dist);
dist.xZ = ScalarProduct(&dist, &c2);
dist.xY = ScalarProduct(&c1, &c2);
dist.xX = ScalarProduct(&c0, &c2);
// compute the partial square distance
d = sqr(dist.xY) + sqr(dist.xZ);
// if point may be in the light spot
if (dist.xX < light->fNearFar[1] && dist.xX > 1e-4f && d < far2)
{
// get the light-point axis tangent in the light space
float tangent = (float)(sqrt(d) / dist.xX);
// if point may be in the light spot
if(tangent < btan)
{
// compute the full square distance
d += sqr(dist.xZ);
// compute the reflexion coeficient
coef = d < near2 ? 1.f : (far2 - d) * delta;
// update the coeficient
if(tangent > ltan)
coef *= (btan - tangent) * deltatg;
coef *= ScalarProduct(&c0, &norm);
// if PaintLight then no backface
if(light->iType|L_PAINT && coef<0)
coef = -coef;
// adds the light effect to RLI
if(coef > 0)
MLT_vAddLightEffect(rli+i, &light->color, coef);
}
}
}
}
/****************************************************************************
* Description: compute RLI for Parallel Light
*
* Parameters: p_stMatrix : current matrix
* light : current light
* obj : geometric object
* rli : rli list
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeParallelRLI (MLT_tdstMatrix *p_stMatrix, MLT_Light *light, MLT_tdstGeometricObject *obj, MLT_tdstColor *rli)
{
MTH3D_tdstVector c0, c1, c2, norm;
MTH3D_tdstVector *normal = obj->d_stListOfPointsNormals;
float coef;
int i;
// get the rotation matrix on columns, so get the light's vector in the world space
MLT_xGetRotationMatrix(light->Matrix, &c0, &c1, &c2);
// for all object's points
for(i=0; i<obj->xNbPoints; i++)
{
MTH3D_M_vCopyVector(&norm, normal+i);
MTH3D_M_vNormalizeVector(&norm, &norm)
// compute the reflexion coeficient
coef = -ScalarProduct(&c2, &norm);
if(light->iType|L_PAINT && coef<0)
coef = -coef;
// adds the light effect to RLI
if(coef > 0)
MLT_vAddLightEffect(rli+i, &light->color, coef);
}
}
/****************************************************************************
* Description: compute one RLI
*
* Parameters: hSupObj : current super-object
* p_stMatrix : current matrix
* rli : pointer on rli lists
* nRLI : nb of rli lists
* p_stFile : script pointer of the rli file
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeOneRLI (MLT_tdxHandleToSuperObject hSupObj, MLT_tdstMatrix *p_stMatrix, MLT_tdstColor **rli, int nRLI, SCR_tdst_File_Description *p_stFile)
{
MLT_tdstMatrix stMatrix;
xString sFile, sAction, sIdent, sSection;
xString sName, sForme, sHabillage;
long lNoPhy, lNoLod;
int i, j, k;
MLT_xMulMatrixMatrix(&stMatrix, hSupObj->p_stMatrix, p_stMatrix);
// look for geometry
if (strcmp(hSupObj->sGeometric, ""))
{
// find geometry
MLT_tdstGeometricObject *obj = MLT_pFindInLib(hSupObj->sGeometric);
if(obj == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSupObj->sGeometric);
return;
}
if(strlen(obj->sPhysicalSection) || g_bLevel)
{
// create the RLI list
for(j=0; j<nRLI; j++)
{
rli[j] = (MLT_tdstColor *)malloc(obj->xNbPoints*sizeof(MLT_tdstColor));
for(k=0; k<obj->xNbPoints; k++)
{
rli[j][k].xR = rli[j][k].xG = rli[j][k].xB = 0; // initialize the RLI list
rli[j][k].xA = 255; // initialize the RLI list
}
}
if (!g_bLevel)
{
// for all lights
for(j=0; j<g_lLightIndex; j++)
{
MLT_Light *light = gs_hLights[j];
if (light->bNotCompute)
{
MLT_vComputeFullRLI(obj, rli[light->iRLI]);
}
// if the light is ON
else if(light->iState && light->Matrix)
{
// Compute the RLI lists
switch(light->iGeomType)
{
case SPHERICAL: MLT_vComputeSphericalRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case AMBIENT: MLT_vComputeAmbientRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case HOTSPOT: MLT_vComputeHotSpotRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case PARALLEL: MLT_vComputeParallelRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
}
}
}
}
else //for the level uses just the lights specified in sct file
{
for(j=0; j<hSupObj->stSector.lNbStaticLights; j++)
{
MLT_Light *light = MLT_hGetLight(hSupObj->stSector.a_sStaticLights[j], gs_hLights);
if (light == NULL)
{
MLT_vOutput( C_ComRes_cErrorLine, "\nError : The light %s doesn't exist", hSupObj->stSector.a_sStaticLights[j]);
continue;
}
if(light->iState && light->Matrix) // if the light is ON
{
// Compute the RLI lists
switch(light->iGeomType)
{
case SPHERICAL: MLT_vComputeSphericalRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case AMBIENT: MLT_vComputeAmbientRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case HOTSPOT: MLT_vComputeHotSpotRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
case PARALLEL: MLT_vComputeParallelRLI(&stMatrix, light, obj, rli[light->iRLI]); break;
}
}
}
}
// Save the RLI data
if (g_bLevel)
{
MLT_vMakePhysicalInLib();
SCR_fn_v_RdL0_SplitSectionName(obj->sPhysicalSection, sFile, sAction, sIdent);
for(j=0; j<nRLI; j++)
{
SCR_fn_v_RdL0_SplitSectionName(obj->sPhysicalSection, sFile, sAction, sIdent);
sprintf(sFile, "%s.vse", g_sFileIn);
MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName);
MLT_vComputeVisualSetSectionName(sIdent, sForme, sHabillage, sName);
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_VS, sIdent);
obj->lNbLod = MLT_lSaveLodInFile(sSection);
wsprintf(sSection, "ISI:ISI_%s(NBRLOD, %d)", sIdent, obj->lNbLod);
SCR_M_SvL0_SaveBeginSection(p_stFile, sSection, SCR_CC_C_Cfg_EOL);
SCR_M_SvL0_SaveEntry(p_stFile, M_RLIActionAddLOD, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%d", 0, obj->xNbPoints);
for(k=0; k<obj->xNbPoints; k++)
{
SCR_M_SvL0_SaveEntry(p_stFile, M_RLIActionAddVertexLOD, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 5, "%d,%d,%d,%d,%d", k, (int)rli[j][k].xR, (int)rli[j][k].xG, (int)rli[j][k].xB, (int)rli[j][k].xA);
}
SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
free(rli[j]);
}
}
else
{
SCR_fn_v_RdL0_SplitSectionName(obj->sPhysicalSection, sFile, sAction, sIdent);
sprintf(sSection, "RLI:%s(NBRLI, %d)", sIdent, nRLI);
SCR_M_SvL0_SaveBeginSection(p_stFile, sSection, SCR_CC_C_Cfg_EOL);
for(j=0; j<nRLI; j++)
{
SCR_fn_v_RdL0_SplitSectionName(obj->sPhysicalSection, sFile, sAction, sIdent);
sprintf(sFile, "%s.vse", g_sFileIn);
MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName);
MLT_vComputeVisualSetSectionName(sIdent, sForme, sHabillage, sName);
SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_VS, sIdent);
obj->lNbLod = MLT_lSaveLodInFile(sSection);
wsprintf(sSection, "IS2:ISI_RLI%02d(NBRLOD, %d)", j, obj->lNbLod);
SCR_M_SvL0_SaveBeginSection(p_stFile, sSection, SCR_CC_C_Cfg_EOL);
SCR_M_SvL0_SaveEntry(p_stFile, M_RLIActionAddLOD, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 2, "%d,%d", 0, obj->xNbPoints);
for(k=0; k<obj->xNbPoints; k++)
{
SCR_M_SvL0_SaveEntry(p_stFile, M_RLIActionAddVertexLOD, SCR_CC_C_Cfg_NoChar);
SCR_fn_v_SvL0_SaveParameters_MP(p_stFile, SCR_EF_SvL0_Scanf, 5, "%d,%d,%d,%d,%d", k, (int)rli[j][k].xR, (int)rli[j][k].xG, (int)rli[j][k].xB, (int)rli[j][k].xA);
}
SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
free(rli[j]);
}
SCR_M_SvL0_SaveEndSection(p_stFile, SCR_CC_C_Cfg_EOL);
}
}
}
// loop on each child
for (i=0; i<hSupObj->lNbChild; i++)
MLT_vComputeOneRLI(hSupObj->d_hChild[i], &stMatrix, rli, nRLI, p_stFile);
}
/****************************************************************************
* Description: Get the light type from it's name
*
* Parameters: type : name to parse
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
int MLT_iGetLightType(char *type)
{
int i;
for (i=0; i<sizeof(gs_LightTypes)/sizeof(char*); i++)
{
if (!lstrcmpi(type, gs_LightTypes[i]))
return i;
}
return 0;
}
/****************************************************************************
* Description: adds the light effect to the rli, with the given coefficient
*
* Parameters: dst : destination color
* src : source color
* coef : coefficient
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vAddLightEffect(MLT_tdstColor *dst, MLT_tdstColor *src, float coef)
{
dst->xR += src->xR * coef * 255;
dst->xG += src->xG * coef * 255;
dst->xB += src->xB * coef * 255;
if (!g_bLevel)
dst->xA -= src->xA * coef * 255;
else
dst->xA += src->xA * coef * 255;
if (!g_bLevel)
{
dst->xR = (dst->xR > 255.0) ? (float) 255.0 : dst->xR;
dst->xG = (dst->xG > 255.0) ? (float) 255.0 : dst->xG;
dst->xB = (dst->xB > 255.0) ? (float) 255.0 : dst->xB;
dst->xA = (dst->xA > 255.0) ? (float) 255.0 : dst->xA;
dst->xA = (dst->xA < 0.0) ? (float) 0.0 : dst->xA;
}
}
/****************************************************************************
* Description: get a light from its name in the array of light
*
* Parameters: sStaticLight : name of the light to find
* g_hLights : array of light to search
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
MLT_Light *MLT_hGetLight (xString sStaticLight, MLT_Light **g_hLights)
{
MLT_Light *p_stLight = NULL;
char * p_sShortName;
int i;
// get short name (without level name)
p_sShortName = strstr(sStaticLight, "\\");
if (!p_sShortName)
p_sShortName = sStaticLight;
else
p_sShortName++;
for (i=0; i<g_lLightIndex; i++)
{
if (!stricmp(g_hLights[i]->sName, p_sShortName))
return g_hLights[i];
}
return p_stLight;
}
/****************************************************************************
* Description: compute the sector parameters
*
* Parameters: hSupObj : root
*---------------------------------------------------------------------------
* Revision date: Author:
*****************************************************************************/
void MLT_vComputeSector (MLT_tdxHandleToSuperObject hSupObj)
{
int i;
// loop on each child
for (i = 0; i < hSupObj->lNbChild; i++)
hSupObj->d_hChild[i]->stSector = hSupObj->stSector;
for (i=0; i<hSupObj->lNbChild; i++)
MLT_vComputeSector(hSupObj->d_hChild[i]);
}