/*========================================================================= * * RLISave.c - Saving functions for RLI file * * Version 1.0 * Revision date * *=======================================================================*/ #include #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; iiRLI); 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; ilNbChild-(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; jlNbStaticLights; 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; iMatrix) 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; ixNbPoints; 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; ixNbPoints; 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; ixNbPoints; 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; ixNbPoints; 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; ixNbPoints; 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; jxNbPoints*sizeof(MLT_tdstColor)); for(k=0; kxNbPoints; 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; jbNotCompute) { 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; jstSector.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; jsPhysicalSection, 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; kxNbPoints; 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; jsPhysicalSection, 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; kxNbPoints; 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; ilNbChild; 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; ixR += 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; isName, 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; ilNbChild; i++) MLT_vComputeSector(hSupObj->d_hChild[i]); }