/*========================================================================= * * Levels.c - Level conversion * * Version 1.0 * Revision date * *=======================================================================*/ #include #include "Levels.h" #include "SCR.h" #include "conventi.h" #include "defines.h" #include "main.h" #include "print.h" #include "system.h" #include "util.h" #include "ModLib.h" #include "LgtLoad.h" #include "PlgLoad.h" #include "SpoLoad.h" #include "IpoSave.h" #include "ModSave.h" #include "PhySave.h" #include "RliSave.h" #include "SctSave.h" #include "SpoSave.h" #include "VseSave.h" #include "ZooSave.h" #include "Actors.h" #include "Borders.h" #include "Normals.h" #include "Submaps.h" #include "MatStack.h" #include "Merge.h" #include "SaveModifLst.h" //--- Global defines -------------------------------------------------------- MLT_tdxHandleToSuperObject g_hRoot; MLT_tdstMatrix g_stMatrixCenter; xString g_sLevelFileIn; BOOL g_bLevel = FALSE; // multitextures BOOL g_bExistTex; //--- Global statics -------------------------------------------------------- MTH3D_tdstVector gs_stMinPointOfMap; MTH3D_tdstVector gs_stMaxPointOfMap; //--- header functions -------------------------------------------------------- void MLT_vSaveEmptyLg2Header(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyLvlHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyWayHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyWpHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyPgbHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyDscHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyAlwHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyAiHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyDecHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyEdeHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyEmaHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyEmcHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyErfHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyEruHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyEsbHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyMacHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyRfxHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } void MLT_vSaveEmptyRulHeader(SCR_tdst_File_Description *p_stFile, char *sFileName, void *p_vPtr, SCR_tde_Ntfy_Action xAction) { } //-------------------------------------------------------------------- /**************************************************************************** * Description: compute all the levels found in the source directory * * Parameters: sRawData : source directory * sGameData : destination directory *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vComputeAllLevels (char *sRawData, char *sGameData) { xString sDirectory; HANDLE hHandle; WIN32_FIND_DATA stFindFileData; // change directory GetCurrentDirectory(256, sDirectory); SetCurrentDirectory(sRawData); // search all the levels files memset(&stFindFileData,0,sizeof(stFindFileData)); hHandle = FindFirstFile("World\\Levels\\*.*", &stFindFileData); if( hHandle == INVALID_HANDLE_VALUE) { SetCurrentDirectory(sDirectory); fprintf(stderr, "\nError : Can't find Levels directory\n"); return; } do if(stFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if(strlen(stFindFileData.cFileName) == 0) break; if(strcmp(stFindFileData.cFileName, ".") == 0) continue; if(strcmp(stFindFileData.cFileName, "..") == 0) continue; // compute the level MLT_vComputeOneLevel(stFindFileData.cFileName, sRawData, sGameData); } while(FindNextFile(hHandle, &stFindFileData)); FindClose(hHandle); // restore directory SetCurrentDirectory(sDirectory); } /**************************************************************************** * Description: compute the specified level * * Parameters: sLevelName : level to convert * sRawData : source directory * sGameData : destination directory *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vComputeOneLevel (char *sLevelName, char *sRawData, char *sGameData) { char *sTmp; BOOL bIsOK = FALSE; xString sFileSearch; HANDLE hHandle; WIN32_FIND_DATA stFindFileData; // WIN version #ifdef _WINDOWS char szInterm[50]; if( ((sTmp=strstr(sLevelName, "\\")) == NULL) && ((sTmp=strstr(sLevelName, "/")) == NULL) ) { if (g_bStandardConfig) { // get SPO name sprintf(sFileSearch, "World\\Levels\\%s\\*.spo", sLevelName); // change directory SetCurrentDirectory(sRawData); } else sprintf(sFileSearch, "%s\\%s\\*.spo", g_szLevels, sLevelName); // search for the level file memset(&stFindFileData,0,sizeof(stFindFileData)); hHandle = FindFirstFile(sFileSearch, &stFindFileData); if( hHandle == INVALID_HANDLE_VALUE) { sprintf(szInterm, "\nError : Can't find %s level\n", sLevelName); fn_vAfxOutputStringRes( szInterm, C_ComRes_cErrorLine); return; } do { if(strlen(stFindFileData.cFileName) == 0) break; // compute the SPO file MLT_vComputeOneSpo(sLevelName, MLT_p_cGetFileNameWithoutExt(stFindFileData.cFileName), sRawData, sGameData); bIsOK = TRUE; } while(FindNextFile(hHandle, &stFindFileData)); FindClose(hHandle); // if file was not found raise an error if (!bIsOK) { sprintf(szInterm, "\nError : Can't find %s\n", sFileSearch); fn_vAfxOutputStringRes( szInterm, C_ComRes_cErrorLine); return; } } else MLT_vComputeOneSpo(sLevelName, sLevelName, sRawData, sGameData); // DOS version #else // get SPO name if( ((sTmp=strstr(sLevelName, "\\")) == NULL) && ((sTmp=strstr(sLevelName, "/")) == NULL) ) sprintf(sFileSearch, "World\\Levels\\%s\\*.spo", sLevelName); else { sprintf(sFileSearch, "World\\Levels\\%s", sLevelName); *sTmp = 0; } // change directory SetCurrentDirectory(sRawData); // search for the level file memset(&stFindFileData,0,sizeof(stFindFileData)); hHandle = FindFirstFile(sFileSearch, &stFindFileData); if( hHandle == INVALID_HANDLE_VALUE) { fprintf(stderr, "\nError : Can't find %s level\n", sLevelName); return; } do { if(strlen(stFindFileData.cFileName) == 0) break; // compute the SPO file MLT_vComputeOneSpo(sLevelName, MLT_p_cGetFileNameWithoutExt(stFindFileData.cFileName), sRawData, sGameData); bIsOK = TRUE; } while(FindNextFile(hHandle, &stFindFileData)); FindClose(hHandle); // if file was not found raise an error if(! bIsOK) { fprintf(stderr, "\nError : Can't find %s\n", sFileSearch); return; } #endif } /**************************************************************************** * Description: compute the SPO file in the specified level * * Parameters: sLevelName : level to convert * sFileSpo : file to convert * sRawData : source directory * sGameData : destination directory *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vComputeOneSpo (char *sLevelName, char *sFileSpo, char *sRawData, char *sGameData) { int i, f; char szFile[256], szLev[256]; BOOL bRLI = FALSE; FILE *file; xString sDirectory, sDir, sRawDir, sRead; xString sRawLevel, sGameLevel, sFile, sFileM, sFile1; // init min and max point of the map MTH3D_M_vSetVectorElements(&gs_stMinPointOfMap, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus); MTH3D_M_vSetVectorElements(&gs_stMaxPointOfMap, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus); // register globals sprintf(g_sFileIn, "%s", sFileSpo); sprintf(g_sLevelFileIn, "%s", sFileSpo); sprintf(g_sFileMaterial, "%s", sLevelName); sprintf(g_sDirectorySave, "%s\\", sLevelName); // init directories if (g_bStandardConfig) sprintf(sRawLevel, "%s\\World\\Levels\\%s", sRawData, g_sDirectorySave); else sprintf(sRawLevel, "%s\\%s", g_szLevels, g_sDirectorySave); sprintf(sGameLevel, "%s\\World\\Levels\\%s", sGameData, g_sDirectorySave); // DISPLAY MLT_vOutput( C_ComRes_cTitleLine, "\nLevel %s\\%s.spo",sLevelName, sFileSpo); // change directory GetCurrentDirectory(256, sDirectory); CreateDirectory(sGameLevel, NULL); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tCopy..."); // change directory SetCurrentDirectory(sGameLevel); // update or create level world MLT_vUpdateLevelWorld(sGameLevel, sLevelName, sGameData); // notify and update all static files of the level MLT_vUpdateLevelStaticFiles(sGameLevel); // notify and update all dynamyc files of the level MLT_vUpdateLevelDynamicFiles(sGameLevel, sRawLevel, sLevelName); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tLoad..."); // change directory SetCurrentDirectory(sRawLevel); // init loading parameters g_lNbSector = 0; MLT_xInitMatrixStack(); // load MOD file MLT_vLoadModFileInLib(); MLT_vEraseDuplicatedPoints(); // load PLG file MLT_vLoadPLGFileInLib(); // load SPO file MLT_vLoadHierarchy(&g_hRoot); // check hierarchy for submaps MLT_vCheckHierarchyForSubmaps(g_hRoot, sGameLevel, sRawLevel); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tCompute normals..."); // get the indexes of the faces for each geometric objects for (i=0; i= 1024.0) || (gs_stMaxPointOfMap.xY - gs_stMinPointOfMap.xY >= 1024.0) || (gs_stMaxPointOfMap.xZ - gs_stMinPointOfMap.xZ >= 1024.0)) { MLT_vOutput( C_ComRes_cErrorLine, "\n\n !!! Warning N64 : The map is too big for N64 (> 512m) !!!\n"); } // save center of the map in SPO MLT_xSetIdentityMatrix(&g_stMatrixCenter); strcpy(g_stMatrixCenter.sName, M_MatrixCenter); g_stMatrixCenter.stTranslation.xX = (gs_stMaxPointOfMap.xX + gs_stMinPointOfMap.xX)/2; g_stMatrixCenter.stTranslation.xY = (gs_stMaxPointOfMap.xY + gs_stMinPointOfMap.xY)/2; g_stMatrixCenter.stTranslation.xZ = (gs_stMaxPointOfMap.xZ + gs_stMinPointOfMap.xZ)/2; // DISPLAY if (!g_bRaymanII) MLT_vOutput( C_ComRes_cNormalLine, "\n\tErase Borders..."); // clean borders in hierarchy MLT_xInitMatrixStack(); MLT_vEraseBorderInHierarchy(g_hRoot, ""); // erase unused points MLT_vEraseUnusedPoints(); // DISPLAY if (!g_bRaymanII) MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Gothroughs..."); // build borders in library MLT_vMakeGoThroughInLib(g_hRoot); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Instantiated Physicals..."); // merge all the splitted objects MLT_vMergeObjectsInHierarchy(g_hRoot); // compute RLIs if (g_bGenerateRLI) { //test if the LGT file exist strcpy(szFile, sGameLevel); strcat(szFile, "\\"); strcpy(szLev, g_sDirectorySave); szLev[strlen(szLev)-1]='\0'; strcat(szFile, szLev); strcat(szFile, ".lgt"); if (!(file=fopen(szFile, "r"))) bRLI = FALSE; else { fclose(file); bRLI= TRUE; //test if the SCT file exist strcpy(szFile, sGameLevel); strcat(szFile, "\\"); strcpy(szLev, g_sDirectorySave); szLev[strlen(szLev)-1]='\0'; strcat(szFile, szLev); strcat(szFile, ".sct"); if (!(file=fopen(szFile, "r"))) bRLI = FALSE; else { fclose(file); bRLI = TRUE; } } if (bRLI) { MLT_vLoadLGTFileInLib(); //compute the RLI g_bLevel = TRUE; MLT_vCreateRLI(); g_bLevel = FALSE; } } // create IPOs MLT_vMakeIpoInHierarchy(g_hRoot); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tCreate Physicals..."); // create POs MLT_vMakePhysicalInLib(); // change directory SetCurrentDirectory(sGameLevel); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tSave..."); // save SPO file MLT_vSaveHierarchy(g_hRoot); // save MOD file MLT_vSaveLibInModFile(TRUE, FALSE, TRUE, TRUE); // save PLG file MLT_vSaveLibInPLGFile(); // if necessary, remove modification files g_bExistMdf = FALSE; g_bExistMdt = FALSE; if (g_bEraseMdf) { strcpy (sFile, sGameLevel); sprintf(sFileM, "%s.mdf", sLevelName); strcat(sFile, sFileM); _chmod(sFile, _S_IREAD | _S_IWRITE ); f=remove(sFile); if (f != -1) g_bExistMdf = TRUE; strcpy (sFile, sGameLevel); sprintf(sFileM, "%s.mdt", sLevelName); strcat(sFile, sFileM); _chmod(sFile, _S_IREAD | _S_IWRITE ); f=remove(sFile); if (f != -1) g_bExistMdt = TRUE; } // save all notified sections SCR_fn_v_SvL1_UpdateAllNotify(); // update SCT file sprintf(sFile, "%s.sct", g_sFileIn); MLT_vUpdateSctFile(sFile); // if necessary, update submap SCT file if (g_hRoot2) { sprintf(sFile, "%s_Submap.sct", g_sFileIn); MLT_vUpdateSctFile(sFile); } // clean MOD library MLT_vEraseLib(); // clean PLG library MLT_vErasePLGLib(); // clean ALW library MLT_vEraseALWLib(); // clean LGT library if (bRLI && g_bGenerateRLI ) MLT_vEraseLGTLib(); // clean SPO hierarchy MLT_vDeleteHierarchy(g_hRoot); // change directory SetCurrentDirectory(sDirectory); // update ModifLst file MLT_vUpdatePathInModifFile(sGameLevel); // remove temporary files MLT_vRemoveLevelTemporaryFiles(sGameLevel); // DISPLAY MLT_vOutput( C_ComRes_cResultLine, "\nLevel %s converted\n",sLevelName); // clean all opened structures for (i=3; i<256; i++) _close((int)i); MLT_vInitSystem(); // multitextures if (g_bIgnoreTex && g_bExistTex) { FILE *fileR; strcpy (sFile, sGameLevel); sprintf(sFileM, "%s.tex", sLevelName); strcat(sFile, sFileM); strcpy (sFile1, sGameLevel); strcat(sFile1, "temp.tex"); fileR=fopen(sFile1, "rt"); file =fopen(sFile, "r+"); if (!fileR) return; if (!file) return; while (!feof(fileR)) { fgets(sRead, 256, fileR); if (strstr(sRead, "Texture")) { //a new section begins MLT_vSearch(sRead, file); fputs(sRead, file); fgets(sRead, 256, fileR); while (!strstr(sRead, "}")) { fputs(sRead, file); fgets(sRead, 256, fileR); } } } fclose(file); fclose(fileR); remove(sFile1); } } /**************************************************************************** * Description: create or update the world character of the level * * Parameters: sGameLevel : directory of the level * sLevelName : level to convert * sGameData : destination directory *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vUpdateLevelWorld (char *sGameLevel, char *sLevelName, char *sGameData) { xString sDirectory; xString sDir, sName; xString sGameLevelMy, sGameLevelMyChar; xString sLevelDefaultDir, sDefaultCharDir; // change directory GetCurrentDirectory(256, sDirectory); // create or update the world associated to the level sprintf(sDir, "%s\\World\\Levels\\_Common\\Families\\World", sGameData); CreateDirectory(sDir, NULL); // create world level directory strcat(sDir, "\\Level"); strcat(sDir, sLevelName); CreateDirectory(sDir, NULL); strcpy(sGameLevelMy, sDir); // create world character directory strcat(sDir,"\\Charact" ); CreateDirectory(sDir, NULL); strcpy(sGameLevelMyChar, sDir); // change directory SetCurrentDirectory(sGameLevel); // get default world files strcpy(sLevelDefaultDir, g_sGameCommon); strcat(sLevelDefaultDir, "\\default\\LevelDefault"); strcpy(sDefaultCharDir, sLevelDefaultDir); strcat(sDefaultCharDir, "\\Charact"); // update character file sprintf(sName, "world.car"); MLT_vCopyAndUpdateFile("world.car", sDefaultCharDir, "world.car", sGameLevelMyChar, "", sLevelName, FALSE); // change directory SetCurrentDirectory(sGameLevel); sprintf(sDir, "%s\\Default\\LevelDefault", sGameData); // update AI file sprintf(sName, "Level%s.ai", sLevelName); MLT_vCopyAndUpdateFile("LevelDefault.ai", sDir, sName, sGameLevelMy, "", sLevelName, FALSE); // update DEC file sprintf(sName, "Level%s.dec", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.dec", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update EDE file sprintf(sName, "Level%s.ede", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.ede", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update EMA file sprintf(sName, "Level%s.ema", sLevelName); MLT_vCopyAndUpdateFile("LevelDefault.ema", sLevelDefaultDir, sName, sGameLevelMy, "", sLevelName, FALSE); // update EMC file sprintf(sName, "Level%s.emc", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.emc", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update ERF file sprintf(sName, "Level%s.erf", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.erf", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update ERU file sprintf(sName, "Level%s.eru", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.eru", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update ESB file sprintf(sName, "Level%s.esb", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.esb", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update MAC file sprintf(sName, "Level%s.mac", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.mac", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update RFX file sprintf(sName, "Level%s.rfx", sLevelName); MLT_vCopyAndRenameFile("LevelDefault.rfx", sLevelDefaultDir, sName, sGameLevelMy, FALSE); // update RUL file sprintf(sName, "Level%s.rul", sLevelName); MLT_vCopyAndUpdateFile("LevelDefault.rul", sLevelDefaultDir, sName, sGameLevelMy, "", sLevelName, FALSE); // restore directory SetCurrentDirectory(sDirectory); } /**************************************************************************** * Description: notify and update the static files of the level * * Parameters: sGameLevel : directory of the level *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vUpdateLevelStaticFiles (char *sGameLevel) { xString sDirectory; xString sFile; int i; // change directory GetCurrentDirectory(256, sDirectory); SetCurrentDirectory(sGameLevel); // check if the destination SPO file already exist strcpy(sFile, g_sFileIn); strcat(sFile, ".spo"); if(! SCR_fn_c_RdL0_IsSectionExists(sFile)) g_bCreatedSpo=FALSE; else g_bCreatedSpo=TRUE; // if necessary, save it as temporary file if (g_bCreatedSpo) CopyFile(sFile, "temp.spo", FALSE); else remove(sFile); // Notify SPO file sprintf(sFile, "%s.spo", g_sFileIn); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveEmptySpoHeader, NULL, SCR_EA_Ntfy_AddOrModifySection); // Notify MOD file sprintf(sFile, "%s.mod", g_sFileIn); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveEmptyModHeader, NULL, SCR_EA_Ntfy_AddOrModifySection); // multitextures // Notify TEX file sprintf(sFile, "%s.tex", g_sFileIn); if (! SCR_fn_c_RdL0_IsSectionExists(sFile)) { SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveTexFile, NULL, SCR_EA_Ntfy_AddOrModifySection); g_bExistTex = FALSE; } else g_bExistTex= TRUE; // Notify VMT file sprintf(sFile, "%s.vmt", g_sFileIn); if (! SCR_fn_c_RdL0_IsSectionExists(sFile)) SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveVmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection); // Notify GMT file sprintf(sFile, "%s.gmt", g_sFileIn); if (! SCR_fn_c_RdL0_IsSectionExists(sFile)) { SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection); g_bCreatedGmt=FALSE; } else g_bCreatedGmt=TRUE; // if the .gmt file exist, check if it must be rebuilt if (g_bCreatedGmt) { //remove it is we want to ignore it if (g_bIgnoreGmt) { remove(sFile); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection); } // else save it as temporary file else { CopyFile(sFile, "temp.gmt", FALSE); remove(sFile); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveGmtFile, NULL, SCR_EA_Ntfy_AddOrModifySection); } } // Notify IPO file sprintf(sFile, "%s.ipo", g_sFileIn); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveIpoFile, NULL, SCR_EA_Ntfy_AddSection); // Notify PHY file sprintf(sFile, "%s.phy", g_sFileIn); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSavePhyFile, NULL, SCR_EA_Ntfy_AddSection); // Notify VSE file sprintf(sFile, "%s.vse", g_sFileIn); SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveVseFile, NULL, SCR_EA_Ntfy_AddSection); // Notify ZOO file sprintf(sFile, "%s.zoo", g_sFileIn); if (! SCR_fn_c_RdL0_IsSectionExists(sFile)) SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveZooFile, NULL, SCR_EA_Ntfy_AddSection); // if the ZOO file exists, check if it must be rebuilt else { if (g_bIgnoreZoo) { i=remove(sFile); if (!i) SCR_fn_v_SvL1_RegisterNotify(sFile, MLT_vSaveZooFile, NULL, SCR_EA_Ntfy_AddSection); } else { xString sSection; CopyFile(sFile, "temp.zoo", FALSE); SCR_fn_v_RdL0_ComputeSectionName(sSection, sFile, M_AllCollideSets, ""); SCR_fn_v_SvL1_RegisterNotify(sSection/*sFile*/, MLT_vSaveAllCollideSetsSection, NULL, SCR_EA_Ntfy_RebuildSection); } } // save all notified sections SCR_fn_v_SvL1_UpdateAllNotify(); // restore directory SetCurrentDirectory(sDirectory); } /**************************************************************************** * Description: notify and update the dynamic files of the level * * Parameters: sGameLevel : destination directory of the level * sRawLevel : source directory of the level * sLevelName : level to convert *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vUpdateLevelDynamicFiles (char *sGameLevel, char *sRawLevel, char *sLevelName) { xString sDirectory; xString sDefaultDir, sGameDefault; xString sFileMem, sGameLevelMem; xString sName, sRoot; HANDLE hHandle; WIN32_FIND_DATA stFindFileData; SCR_tdst_Cxt_Values *p_stVal; MLT_tdstInsertCharacter *hInsert; // change directory GetCurrentDirectory(256, sDirectory); SetCurrentDirectory(sGameLevel); // get level default directory strcpy(sDefaultDir, g_sGameCommon); strcat(sDefaultDir, "\\default"); // compute the name of the level MEM file strcpy(sFileMem, g_sDirectorySave); sFileMem[strlen(sFileMem)-1]='\0'; strcat(sFileMem, ".mem"); strcpy(sGameLevelMem, sGameLevel); // compute the name of the default MEM file strcat(sGameLevelMem, sFileMem); strcpy(sGameDefault, g_sGameCommon); strcat(sGameDefault, "\\Default\\"); // change directory SetCurrentDirectory(sGameDefault); // search for default MEM file memset(&stFindFileData,0,sizeof(stFindFileData)); hHandle = FindFirstFile("Default.mem", &stFindFileData); if( hHandle == INVALID_HANDLE_VALUE) { MLT_vOutput( C_ComRes_cErrorLine, "\nError: No Default.mem file in the Default directory"); FindClose(hHandle); } else { FindClose(hHandle); CopyFile("Default.mem", sGameLevelMem, FALSE); } // ALW file sprintf(sName, "%s.alw", sLevelName); // if necessary, create ALW file if (! SCR_fn_c_RdL0_IsSectionExists(sName)) { MLT_vCopyAndRenameFile("Default.alw", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyAlwHeader, NULL, SCR_EA_Ntfy_AddSection); } // otherwise, load it else { MLT_vLoadALWFileInLib(); MLT_vSaveLibInALWFile(); } // DSC file sprintf(sName, "%s.dsc", sLevelName); MLT_vCopyAndRenameFile("Default.dsc", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyDscHeader, NULL, SCR_EA_Ntfy_AddSection); // PGB file sprintf(sName, "%s.pgb", sLevelName); MLT_vCopyAndRenameFile("Default.pgb", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyPgbHeader, NULL, SCR_EA_Ntfy_AddSection); // WP file sprintf(sName, "%s.wp", sLevelName); MLT_vCopyAndRenameFile("Default.wp", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyWpHeader, NULL, SCR_EA_Ntfy_AddSection); // WAY file sprintf(sName, "%s.way", sLevelName); MLT_vCopyAndRenameFile("Default.way", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyWayHeader, NULL, SCR_EA_Ntfy_AddSection); // LVL file sprintf(sName, "%s.lvl", sLevelName); MLT_vCopyAndRenameFile("Default.lvl", sDefaultDir, sName, sGameLevel, FALSE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyLvlHeader, NULL, SCR_EA_Ntfy_AddSection); // LG2 file sprintf(sName, "%s.lg2", sLevelName); MLT_vCopyAndRenameFile(sName, sRawLevel, sName, sGameLevel, TRUE); SCR_fn_v_SvL1_RegisterNotify(sName, MLT_vSaveEmptyLg2Header, NULL, SCR_EA_Ntfy_AddSection); // DISPLAY MLT_vOutput( C_ComRes_cNormalLine, "\n\tDelete RLI..."); // remove the RLI file SetCurrentDirectory(sGameLevel); sprintf(sName, "%s.rli", sLevelName); remove(sName); // if necessary, update world character in LVL file SetCurrentDirectory(sGameLevel); sprintf(sName, "%s.lvl", sLevelName); SCR_fn_v_RdL0_ComputeSectionName(sRoot, sName, "InsertCharacter", "W"); // load module hierarchy if (SCR_fn_c_RdL0_IsSectionExists(sRoot)) { p_stVal = SCR_fnp_st_RdL0_AnalyseSection(sRoot, SCR_CDF_uw_Anl_Normal); hInsert = (MLT_tdstInsertCharacter *)SCR_M_ul_RdL0_ExtractLongValue(p_stVal,0); SCR_fn_v_SvL1_RegisterNotify(hInsert->sName, MLT_vSaveInsertCharacter, hInsert, SCR_EA_Ntfy_AddOrModifySection); } // restore directory SetCurrentDirectory(sDirectory); } /**************************************************************************** * Description: remove the temporary files created for the level * * Parameters: sGameLevel : destination directory of the level *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vRemoveLevelTemporaryFiles (char *sGameLevel) { xString sDirectory, sFile; // if necessary, remove temporary SPO file if (g_bCreatedSpo) { GetCurrentDirectory(256, sDirectory); SetCurrentDirectory(sGameLevel); remove("temp.spo"); SetCurrentDirectory(sDirectory); } // if necessary, remove temporary GMT file if (g_bCreatedGmt && !g_bIgnoreGmt) { SCR_fn_v_RdL0_Close(); strcpy (sFile, sGameLevel); strcat(sFile, "temp.gmt"); _chmod(sFile, _S_IREAD | _S_IWRITE ); remove(sFile); MLT_vInitSystem(); } // remove temporary VSE file SCR_fn_v_RdL0_Close(); strcpy(sFile, sGameLevel); strcat(sFile, "temp.vse"); remove(sFile); MLT_vInitSystem(); // if necessary, remove temporary ZOO file if (!g_bIgnoreZoo) { SCR_fn_v_RdL0_Close(); strcpy (sFile, sGameLevel); strcat(sFile, "temp.zoo"); remove(sFile); MLT_vInitSystem(); } // if necessary, remove temporary SUB file if (g_bSubmaps) { SCR_fn_v_RdL0_Close(); strcpy (sFile, sGameLevel); strcat(sFile, "temp.sub"); remove(sFile); MLT_vInitSystem(); } // clean root1 for submaps if (g_hRoot1) { free(g_hRoot1); g_hRoot1 = NULL; } // clean root2 for submaps if (g_hRoot2) { free(g_hRoot2); g_hRoot2 = NULL; g_iUnivSectors = 0; } } /**************************************************************************** * Description: search for all the sectors in first level of the hierarchy * * Parameters: hRoot : root of the hierarchy *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vSearchAllSector(MLT_tdxHandleToSuperObject hRoot) { xString sFile, sAction, sIdent, sIdent2; long i; // there must at least one sector if(hRoot->lNbChild == 0) { MLT_vOutput( C_ComRes_cErrorLine, "\nError : No sector"); } // cover the sectors (first level in the hierarchy) for(i=0; ilNbChild; i++) { SCR_fn_v_RdL0_SplitSectionName(hRoot->d_hChild[i]->sName, sFile, sAction, sIdent); sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_)); MLT_vAddSector(sIdent2); } } /**************************************************************************** * Description: set the identity matrix for all the objects on the first level * * Parameters: hRoot : root of the hierarchy *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMatrixIdentityHierarchy(MLT_tdxHandleToSuperObject hRoot) { xString sName, sFile, sAction, sIdent, sIdent2; long i; // there must at least one sector if(hRoot->lNbChild == 0) { MLT_vOutput( C_ComRes_cErrorLine, "\nError : No sector"); } // cover the sectors (first floor in the hierarchy) for(i=0; ilNbChild; i++) { SCR_fn_v_RdL0_SplitSectionName(hRoot->d_hChild[i]->sName, sFile, sAction, sIdent); sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_)); MLT_vAddSector(sIdent2); // update the matrix sprintf(sName, "%s", hRoot->d_hChild[i]->p_stMatrix->sName); MLT_xMulMatrixMatrix(hRoot->d_hChild[i]->p_stMatrix, hRoot->p_stMatrix, hRoot->d_hChild[i]->p_stMatrix); sprintf(hRoot->d_hChild[i]->p_stMatrix->sName, "%s", sName); // the sector's matrix must be no identity if(strstr(hRoot->d_hChild[i]->sName, M_Surface) == NULL) { MLT_vMatrixIdentitySector(hRoot->d_hChild[i]); } } MLT_xSetIdentityMatrix (hRoot->p_stMatrix); } /**************************************************************************** * Description: force the sector's matrix to be identity * * Parameters: hRoot : sector super object *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMatrixIdentitySector(MLT_tdxHandleToSuperObject hSprObj) { xString sName; long i; // there must at least one child in the sector if(hSprObj->lNbChild == 0) { if (g_bRaymanII) MLT_vOutput( C_ComRes_cErrorLine, "\nError : No object or bounding box in sector %s", hSprObj->sName); else MLT_vOutput( C_ComRes_cErrorLine, "\nError : No object in sector %s", hSprObj->sName); } // cover the visibles borders (second floor in the hierarchy) for(i=0; ilNbChild; i++) { // sector's matrix not identity sprintf(sName, "%s", hSprObj->d_hChild[i]->p_stMatrix->sName); MLT_xMulMatrixMatrix(hSprObj->d_hChild[i]->p_stMatrix, hSprObj->p_stMatrix, hSprObj->d_hChild[i]->p_stMatrix); sprintf(hSprObj->d_hChild[i]->p_stMatrix->sName, "%s", sName); // manage special objects if(strstr(hSprObj->d_hChild[i]->sName, M_Surface) == NULL) { if (strstr(hSprObj->d_hChild[i]->sName, "=") == NULL) MLT_vMatrixIdentityFronteer(hSprObj->d_hChild[i]); } } MLT_xSetIdentityMatrix (hSprObj->p_stMatrix); } /**************************************************************************** * Description: force the border's matrix to be identity * * Parameters: hRoot : fronteer super object *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMatrixIdentityFronteer (MLT_tdxHandleToSuperObject hSprObj) { MLT_tdstGeometricObject *p_stObj; xString sName; long i; // cover the statics objets (third floor in the hierarchy) for(i=0; ilNbChild; i++) { sprintf(sName, "%s", hSprObj->d_hChild[i]->p_stMatrix->sName); MLT_xMulMatrixMatrix(hSprObj->d_hChild[i]->p_stMatrix, hSprObj->p_stMatrix, hSprObj->d_hChild[i]->p_stMatrix); sprintf(hSprObj->d_hChild[i]->p_stMatrix->sName, "%s", sName); } // spread to the geometric object if(strlen(hSprObj->sGeometric) != 0) { p_stObj = MLT_pFindInLib(hSprObj->sGeometric); if(p_stObj == NULL) { MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSprObj->sGeometric); } else { // compute absolute vertex for(i=0; ixNbPoints; i++) { MLT_xMulMatrixVertex(p_stObj->d_stListOfPoints+i, hSprObj->p_stMatrix, p_stObj->d_stListOfPoints+i); } } } // specific case : spo is a dummy grouping several elements else { int j; // compute the minmax points for each element for (j=0; jlNbChild; j++) { if (strstr(hSprObj->d_hChild[j]->sName, "&") != NULL) { p_stObj = MLT_pFindInLib(hSprObj->d_hChild[j]->sGeometric); if(p_stObj == NULL) { MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hSprObj->d_hChild[j]->sGeometric); } else { // compute absolute vertex for(i=0; ixNbPoints; i++) { MLT_xMulMatrixVertex(p_stObj->d_stListOfPoints+i, hSprObj->d_hChild[j]->p_stMatrix, p_stObj->d_stListOfPoints+i); } } } } } MLT_xSetIdentityMatrix (hSprObj->p_stMatrix); } /**************************************************************************** * Description: create the sectors in the hierarchy * * Parameters: hSprObj : root super-object *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMakeSectorInHierarchy(MLT_tdxHandleToSuperObject hSprObj) { long i, lNbChild; xString sFile, sAction, sIdent; lNbChild = 0; // check all children for (i=0; ilNbChild; i++ ) { lNbChild++; // detect a bad border among the sector if (strstr(hSprObj->d_hChild[i]->sName, "frt") != NULL) { MLT_vOutput( C_ComRes_cErrorLine, "\nError : No frontier among the sectors : %s", hSprObj->d_hChild[i]->sName); continue; } // init the flag for the sector telling if it has a new or old frontier hSprObj->d_hChild[i]->stSector.iFlag |= 0x00; // create sector MLT_vCreateSector(hSprObj->d_hChild[i]); // if in a sector, we have both types of frontier generate a warning if ((hSprObj->d_hChild[i]->stSector.iFlag & IS_OLDFRONTIER) && (hSprObj->d_hChild[i]->stSector.iFlag & IS_NEWFRONTIER)) { SCR_fn_v_RdL0_SplitSectionName(hSprObj->d_hChild[i]->stSector.sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, "\nWarning : New and old frontier for the %s sector", sIdent); } // compute the surfaces if (strstr(hSprObj->d_hChild[i]->sName, M_Surface) != NULL) { MLT_bAttachSurfaceToSector(hSprObj, hSprObj->d_hChild[i], g_sDirectorySave); // delete the surface from the hierarchy MLT_vDeleteHierarchy(hSprObj->d_hChild[i]); hSprObj->d_hChild[i] = NULL; lNbChild--; } } // for submaps : create Univers sectors for (i=0; id_hChild[i]->sName, sFile, sAction, sIdent); MLT_vCreateUniversSector(hSprObj, sIdent+7); lNbChild++; } // insert Univers sector MLT_vCreateUniversSector(hSprObj, ""); lNbChild++; // update sub hierarchy for(i=0; id_hChild[j] == NULL) j++; hTemp = hSprObj->d_hChild[j]; hSprObj->d_hChild[j] = NULL; hSprObj->d_hChild[i] = hTemp; } hSprObj->lNbChild = lNbChild; } /**************************************************************************** * Description: create the sector structure * * Parameters: hSprObj : sector super-object *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vCreateSector (MLT_tdxHandleToSuperObject hSprObj) { MLT_tdxHandleToSuperObject hChild; MLT_tdstGeometricObject *p_stObj; MTH3D_tdstVector stPointMin; MTH3D_tdstVector stPointMax; xString sAction, sIdent, sFile, sIdent2; xString sName1, sIdent1; long i, lNbChild; //set the initial values for the minimum and maximum of the bounding box MTH3D_M_vSetVectorElements(&stPointMin, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus); MTH3D_M_vSetVectorElements(&stPointMax, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus); // the super-object must not be a surface if (strstr(hSprObj->sName, M_Surface) == NULL) { // get super-object name SCR_fn_v_RdL0_SplitSectionName(hSprObj->sName, sFile, sAction, sIdent); // build corresponding sector name sprintf(sFile, "%s.sct", g_sFileIn); sprintf(sIdent2, "%s", sIdent+strlen(M_SPO_)); SCR_fn_v_RdL0_ComputeSectionName(hSprObj->stSector.sName, sFile, M_Sector, sIdent2); // init sectr parameter hSprObj->stSector.lNbSurface = 0; // (Rayman2 version only) if (g_bRaymanII) { //set the initial values for the min and max of the bounding box MTH3D_M_vSetVectorElements(&hSprObj->stSector.stPointMin, MLT_C_InfinitPlus, MLT_C_InfinitPlus, MLT_C_InfinitPlus); MTH3D_M_vSetVectorElements(&hSprObj->stSector.stPointMax, MLT_C_InfinitMinus, MLT_C_InfinitMinus, MLT_C_InfinitMinus); } // (TonicTrouble version only) else { // detect surfaces under the sector lNbChild = 0; SCR_fn_v_RdL0_SplitSectionName(hSprObj->stSector.sName, sFile, sAction, sIdent); for(i=0; ilNbChild; i++ ) { lNbChild++; // add the surface : the test is in the function MLT_vAddSurfaceToSector(g_hRoot, hSprObj->d_hChild[i]->sName, sIdent, g_sDirectorySave); //set the flag to tell if it is a new or old frontier if(strstr(hSprObj->d_hChild[i]->sName, M_NewFronRever) != NULL) hSprObj->stSector.iFlag |= IS_NEWFRONTIER; if(strstr(hSprObj->d_hChild[i]->sName, M_FronRever) != NULL) hSprObj->stSector.iFlag |= IS_OLDFRONTIER; // delete the surface from the hierarchy if(strstr(hSprObj->d_hChild[i]->sName, M_Surface) != NULL) { MLT_vDeleteHierarchy(hSprObj->d_hChild[i]); hSprObj->d_hChild[i] = NULL; lNbChild--; } } // reorganization of the sub hierarchy for (i=0; id_hChild[j] == NULL) j++; hTemp = hSprObj->d_hChild[j]; hSprObj->d_hChild[j] = NULL; hSprObj->d_hChild[i] = hTemp; } hSprObj->lNbChild = lNbChild; } } else { sprintf(hSprObj->stSector.sName, ""); } // (Rayman2 version only) if (g_bRaymanII) { //for all the children of the sector for(i=0; ilNbChild; i++ ) { hChild = hSprObj->d_hChild[i]; // if there is a bouding box, use it if (strstr(hChild->sName, M_BoundingBox) != NULL) { p_stObj = MLT_pFindInLib(hChild->sGeometric); if(p_stObj == NULL) MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->sGeometric); else MLT_vComputeMinMaxPointOfBorder (p_stObj, &hSprObj->stSector.stPointMin, &hSprObj->stSector.stPointMax); } // use geometric children to compute the real bouding box else { // instance if (strstr(hChild->sName, "=") != NULL) { // save name strcpy(sName1, hChild->sName); // create dummy name SCR_fn_v_RdL0_SplitSectionName(sName1, sFile, sAction, sIdent); strcpy(sIdent1, "SPO_dum_"); if (!strstr(sIdent, "SPO_")) strcat(sIdent1, sIdent); else strcat(sIdent1, sIdent+4); SCR_fn_v_RdL0_ComputeSectionName(hChild->sName, sFile, sAction, sIdent1); // create new child and copy instance hChild->d_hChild[0] = (MLT_tdxHandleToSuperObject)malloc(sizeof(MLT_tdstSprObj)); strcpy(hChild->d_hChild[0]->sName, sName1); strcpy(hChild->d_hChild[0]->sGeometric, hChild->sGeometric); strcpy(hChild->d_hChild[0]->sLinkedObject, hChild->sLinkedObject); hChild->d_hChild[0]->fTransparency = hChild->fTransparency; hChild->d_hChild[0]->p_stMatrix = hChild->p_stMatrix; hChild->d_hChild[0]->ulSPOFlags = hChild->ulSPOFlags; hChild->d_hChild[0]->stSector = hChild->stSector; hChild->d_hChild[0]->lNbChild = 0; hChild->d_hChild[0]->iFlags = hChild->iFlags; // update dummy hChild->lNbChild=1; strcpy(hChild->sGeometric, ""); hChild->p_stMatrix = (MLT_tdstMatrix*)malloc(sizeof(MLT_tdstMatrix)); MLT_xSetIdentityMatrix(hChild->p_stMatrix); SCR_fn_v_RdL0_SplitSectionName(hChild->sName, sFile, sAction, sIdent); SCR_fn_v_RdL0_ComputeSectionName(hChild->p_stMatrix->sName, sFile, M_Matrix, sIdent); // compute minmax from the instance p_stObj = MLT_pFindInLib(hChild->d_hChild[0]->sGeometric); if(p_stObj == NULL) MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->d_hChild[0]->sGeometric); else MLT_vComputeMinMaxPointWithMatrix (p_stObj, &stPointMin, &stPointMax, hChild->d_hChild[0]->p_stMatrix); } // dummy grouping some elements else if (strlen(hChild->sGeometric) == 0) { int j; // compute the minmax points for each element for (j=0; jlNbChild; j++) { if (strstr(hChild->d_hChild[j]->sName, "&") != NULL) { p_stObj = MLT_pFindInLib(hChild->d_hChild[j]->sGeometric); if(p_stObj == NULL) MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->d_hChild[j]->sGeometric); else MLT_vComputeMinMaxPointOfBorder (p_stObj, &stPointMin, &stPointMax); } } } // normal case : child is a geometric one else { p_stObj = MLT_pFindInLib(hChild->sGeometric); if(p_stObj == NULL) MLT_vOutput( C_ComRes_cErrorLine, "\nError : Can't load %s", hChild->sGeometric); else MLT_vComputeMinMaxPointOfBorder (p_stObj, &stPointMin, &stPointMax); } } } // set the final values of the bounding box : max size of frtb and graphic children if (hSprObj->stSector.stPointMin.xX == MLT_C_InfinitPlus) MTH3D_M_vSetXofVector(&hSprObj->stSector.stPointMin, stPointMin.xX); if (hSprObj->stSector.stPointMin.xY == MLT_C_InfinitPlus) MTH3D_M_vSetYofVector(&hSprObj->stSector.stPointMin, stPointMin.xY); if (hSprObj->stSector.stPointMin.xZ == MLT_C_InfinitPlus) MTH3D_M_vSetZofVector(&hSprObj->stSector.stPointMin, stPointMin.xZ); if (hSprObj->stSector.stPointMax.xX == MLT_C_InfinitMinus) MTH3D_M_vSetXofVector(&hSprObj->stSector.stPointMax, stPointMax.xX); if (hSprObj->stSector.stPointMax.xY == MLT_C_InfinitMinus) MTH3D_M_vSetYofVector(&hSprObj->stSector.stPointMax, stPointMax.xY); if (hSprObj->stSector.stPointMax.xZ == MLT_C_InfinitMinus) MTH3D_M_vSetZofVector(&hSprObj->stSector.stPointMax, stPointMax.xZ); // check min and max points for the map if (gs_stMinPointOfMap.xX > stPointMin.xX) MTH3D_M_vSetXofVector(&gs_stMinPointOfMap, stPointMin.xX); if (gs_stMinPointOfMap.xY > stPointMin.xY) MTH3D_M_vSetYofVector(&gs_stMinPointOfMap, stPointMin.xY); if (gs_stMinPointOfMap.xZ > stPointMin.xZ) MTH3D_M_vSetZofVector(&gs_stMinPointOfMap, stPointMin.xZ); if (gs_stMaxPointOfMap.xX < stPointMax.xX) MTH3D_M_vSetXofVector(&gs_stMaxPointOfMap, stPointMax.xX); if (gs_stMaxPointOfMap.xY < stPointMax.xY) MTH3D_M_vSetYofVector(&gs_stMaxPointOfMap, stPointMax.xY); if (gs_stMaxPointOfMap.xZ < stPointMax.xZ) MTH3D_M_vSetZofVector(&gs_stMaxPointOfMap, stPointMax.xZ); } } /**************************************************************************** * Description: create the Univers sector, for global or for submap * * Parameters: hSprObj : root super-object * sSubmapName : name of submap, or empty string for global *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vCreateUniversSector (MLT_tdxHandleToSuperObject hSprObj, xString sSubmapName) { xString sFile, sSuperObject, sSector; // build the name of the sector accroding to its status (submap or global) if (strcmp(sSubmapName, "")) { sprintf(sSuperObject, "%s_%s", M_SPO_Univers, sSubmapName); sprintf(sSector, "%s_%s", M_Univers, sSubmapName); } else { strcpy(sSuperObject, M_SPO_Univers); strcpy(sSector, M_Univers); } // allocate Univers super-object as last child of the root hSprObj->d_hChild[hSprObj->lNbChild] = (MLT_tdxHandleToSuperObject)calloc(1, sizeof(MLT_tdstSprObj)); // compute corresponding section name sprintf(sFile, "%s.spo", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->sName, sFile, M_SuperObject, sSuperObject); // allocate Univers matrix (default value : identity) hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix = (MLT_tdstMatrix*)calloc(1, sizeof(MLT_tdstMatrix)); MLT_xSetIdentityMatrix(hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix); // compute corresponding section name sprintf(sFile, "%s.spo", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->p_stMatrix->sName, sFile, M_Matrix, sSuperObject); // init Univers sector hSprObj->d_hChild[hSprObj->lNbChild]->stSector.lNbSurface = 0; // compute corresponding section name sprintf(sFile, "%s.sct", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(hSprObj->d_hChild[hSprObj->lNbChild]->stSector.sName, sFile, M_Sector, sSector); // update the number of children hSprObj->lNbChild++; } /**************************************************************************** * Description: Insert an Ipo between SuperObject and Geometric * * Parameters: hSprObj : root of the hierarchy *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMakeIpoInHierarchy (MLT_tdxHandleToSuperObject hSprObj) { long i; // check if super-object encapsulate a geometric object if (strlen(hSprObj->sGeometric) != 0) { xString sFile, sAction, sIdent, sForme, sHabillage, sSection, sName; long lNoPhy, lNoLod; // get minimal geometric name SCR_fn_v_RdL0_SplitSectionName(hSprObj->sGeometric, sFile, sAction, sIdent); MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName); // compute corresponding PO name MLT_vComputePhysicalSectionName(sSection, sForme, sHabillage, lNoPhy, sName); // compute corresponding IPO section name sprintf(sFile, "%s.ipo", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(hSprObj->sLinkedObject, sFile, M_Ipo, sSection); // remove the geometric entry sprintf(hSprObj->sGeometric, ""); } // iteration on next level for (i=0; ilNbChild; i++) { MLT_vMakeIpoInHierarchy(hSprObj->d_hChild[i]); } } /**************************************************************************** * Description: compute the name of Physical from the name of Geometric * * Parameters: *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vMakePhysicalInLib () { MLT_tdstGeometricObject *p_stObj; xString sFile, sAction, sIdent, sForme ,sHabillage, sName; long i, lNbObjInLib, lNoPhy, lNoLod; // search the library lNbObjInLib = MLT_lGetNumberObjectInLib(); for(i=0; isName, M_NameGothrough) != NULL) { sprintf(p_stObj->sComment, ""); sprintf(p_stObj->sPhysicalSection, ""); continue; } // No Physical for the surfaces if(strstr(p_stObj->sName, M_Surface) != NULL) { sprintf(p_stObj->sPhysicalSection, ""); continue; } // get minimal geometric name SCR_fn_v_RdL0_SplitSectionName(p_stObj->sName, sFile, sAction, sIdent); MLT_vSplitModuleSectionName(sIdent, sForme, sHabillage, &lNoPhy, &lNoLod, sName); // compute corresponding physical name MLT_vComputePhysicalSectionName(sIdent, sForme, sHabillage, lNoPhy, ""); // compute corresponding section name sprintf(sFile, "%s.phy", g_sFileIn); SCR_fn_v_RdL0_ComputeSectionName(p_stObj->sPhysicalSection, sFile, M_Phy, sIdent); // register index in library p_stObj->lNumberInTable = i; } } /**************************************************************************** * Description: Detect and erase the unused points in all geometric objects of the hierarchy * * Parameters: *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vEraseUnusedPoints () { MLT_tdstElementIndexedTriangles *p_stLocalElement; MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD; xString sFile, sAction, sIdent; BOOL bIsSprite; char buf[5]; int xIndex, iIndexM=0; int i, j, m, n, k; // check all the geometric objects for (i=0; ixNbPoints*sizeof(MTH3D_tdstVector)); p_stListOfPointsNormals = (MTH3D_tdstVector *) malloc(g_hGeometricInFile[i]->xNbPoints*sizeof(MTH3D_tdstVector)); p_stListOfColors = (MLT_tdstColor *) malloc(g_hGeometricInFile[i]->xNbPoints*sizeof(MLT_tdstColor)); p_iIndex=(int *)malloc(sizeof(int) * g_hGeometricInFile[i]->xNbPoints); } for (m=0; mxNbPoints; m++) { iIndexM = 0; for (xIndex=0; xIndexxNbElements; xIndex++) { if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles ) { p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); for (j=0; jxNbFaces; j++) //for all faces { if ((m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[0]) ||(m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[1]) ||(m == p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[2])) iIndexM++; } } else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors) { p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); for (j=0; jxNbFaces; j++) { if ((m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[0]) ||(m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[1]) ||(m == p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[2])) iIndexM++; } } else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementSprites) bIsSprite = TRUE; } // the point m is not used in any face if (!iIndexM && !bIsSprite) { if (g_bEraseUnused) { MLT_vOutput( C_ComRes_cWarningLine, "\n\tFrom the object "); //MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cErrorLine, sIdent); MLT_vOutput( C_ComRes_cWarningLine, " was deleted the unused point n°"); sprintf(buf, "%d", m); MLT_vOutput( C_ComRes_cErrorLine, buf); p_iIndex[m] = -1; //the point is not anymore } else { MLT_vOutput( C_ComRes_cErrorLine, "\n\tIn the object "); //MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, sIdent); MLT_vOutput( C_ComRes_cErrorLine, " the point n°"); sprintf(buf, "%d", m); MLT_vOutput( C_ComRes_cWarningLine, buf); MLT_vOutput( C_ComRes_cErrorLine, " is not used."); } } //the points is still used, so completye the new structure else { if (g_bEraseUnused) { MTH3D_M_vSetVectorElements(&p_stListOfPoints[n], g_hGeometricInFile[i]->d_stListOfPoints[m].xX, g_hGeometricInFile[i]->d_stListOfPoints[m].xY, g_hGeometricInFile[i]->d_stListOfPoints[m].xZ); MTH3D_M_vSetVectorElements(&p_stListOfPointsNormals[n], g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xX, g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xY, g_hGeometricInFile[i]->d_stListOfPointsNormals[m].xZ); p_stListOfColors[n].xR = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xR; p_stListOfColors[n].xG = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xG; p_stListOfColors[n].xB = g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xB; p_iIndex[m] = n; n++; } } } if (g_bEraseUnused) { g_hGeometricInFile[i]->xNbPoints = n; for (m=0; md_stListOfPoints[m], p_stListOfPoints[m].xX, p_stListOfPoints[m].xY, p_stListOfPoints[m].xZ); MTH3D_M_vSetVectorElements(&g_hGeometricInFile[i]->d_stListOfPointsNormals[m], p_stListOfPointsNormals[m].xX, p_stListOfPointsNormals[m].xY, p_stListOfPointsNormals[m].xZ); g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xR = p_stListOfColors[m].xR; g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xG = p_stListOfColors[m].xG; g_hGeometricInFile[i]->d_stListOfPointsReceivedLightIntensity[m].xB = p_stListOfColors[m].xB; } for (xIndex=0; xIndex < g_hGeometricInFile[i]->xNbElements; xIndex++) { if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles ) { MLT_tdstTripledIndex *p_stListOfFacesTripled; p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); p_stListOfFacesTripled = (MLT_tdstTripledIndex *)malloc(sizeof(MLT_tdstTripledIndex)* p_stLocalElement->xNbFaces); for (j=0; jxNbFaces; j++) { for (k=0; k<3; k++) p_stListOfFacesTripled[j].a3_xIndex[k] = p_iIndex[p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]]; } for (j=0; jxNbFaces; j++) { for (k=0; k<3; k++) p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k] = p_stListOfFacesTripled[j].a3_xIndex[k]; } free(p_stListOfFacesTripled); } else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors) { MLT_tdstTripledIndex *p_stListOfFacesTripled; p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); p_stListOfFacesTripled = (MLT_tdstTripledIndex *)malloc(sizeof(MLT_tdstTripledIndex)* p_stLocalElement->xNbFaces); for (j=0; jxNbFaces; j++) { for (k=0; k<3; k++) p_stListOfFacesTripled[j].a3_xIndex[k] = p_iIndex[p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k]]; } for (j=0; jxNbFaces; j++) { for (k=0; k<3; k++) p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k] = p_stListOfFacesTripled[j].a3_xIndex[k]; } free(p_stListOfFacesTripled); } } free(p_stListOfPoints); free(p_stListOfPointsNormals); free(p_stListOfColors); } } } } /**************************************************************************** * Description: Detect and erase the duplicated points in all geometric objects of the hierarchy * * Parameters: *--------------------------------------------------------------------------- * Revision date: Author: *****************************************************************************/ void MLT_vEraseDuplicatedPoints () { MLT_tdstElementIndexedTriangles *p_stLocalElement; MLT_tdstElementFaceMapDescriptors *p_stLocalElementFMD; xString sFile, sAction, sIdent; char buf[5]; int xIndex; int i, j, k, l, m, n, p, p1; // check all geometric objects for (i=0; ixNbElements; xIndex++) { MLT_tdstTripledIndex *p_stListOfFacesTripled = NULL; MLT_tdstTripledIndex *p_stListOfFacesTripledIndexUV = NULL; MTH3D_tdstVector *p_stListOfFaceNormals = NULL; n=0; if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles ) { p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); p_stListOfFacesTripled = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex)); p_stListOfFacesTripledIndexUV = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex)); p_stListOfFaceNormals = (MTH3D_tdstVector *) malloc(p_stLocalElement->xNbFaces*sizeof(MTH3D_tdstVector)); //for all faces for (j=0; jxNbFaces; j++) { MTH3D_tdstVector stPoint[3]; BOOL bNot = FALSE; for (k=0; k<3; k++) MTH3D_M_vSetVectorElements(&stPoint[k], // k -> pk (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xX, (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xY, (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k])->xZ); for (k=0; k<3; k++) { for (l=k+1; l<3; l++) { if ((fabs(stPoint[k].xX - stPoint[l].xX) <= g_fLimit3) && (fabs(stPoint[k].xY - stPoint[l].xY) <= g_fLimit3) && (fabs(stPoint[k].xZ - stPoint[l].xZ) <= g_fLimit3)) //duplicate points { if (g_bEraseDuplicated) { //erase the face from the object bNot = TRUE; MLT_vOutput( C_ComRes_cWarningLine, "\nWarning: From the object "); //MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cErrorLine, sIdent); MLT_vOutput( C_ComRes_cWarningLine, " in the element "); //MLT_vOutput( C_ComRes_cWarningLine, p_stLocalElement->sName); SCR_fn_v_RdL0_SplitSectionName(p_stLocalElement->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cErrorLine, sIdent); MLT_vOutput( C_ComRes_cWarningLine, " was deleted the face n° "); sprintf(buf, "%d", j); MLT_vOutput( C_ComRes_cErrorLine, buf); MLT_vOutput( C_ComRes_cWarningLine, " which contained the duplicated points n° "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]); MLT_vOutput( C_ComRes_cErrorLine, buf); MLT_vOutput( C_ComRes_cWarningLine, " and "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]); MLT_vOutput( C_ComRes_cErrorLine, buf); } else { MLT_vOutput( C_ComRes_cErrorLine, "\nError: In the object "); //MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, sIdent); MLT_vOutput( C_ComRes_cErrorLine, " in the element "); //MLT_vOutput( C_ComRes_cErrorLine, p_stLocalElement->sName); SCR_fn_v_RdL0_SplitSectionName(p_stLocalElement->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, sIdent); MLT_vOutput( C_ComRes_cErrorLine, " was detected the face n° "); sprintf(buf, "%d", j); MLT_vOutput( C_ComRes_cWarningLine, buf); MLT_vOutput( C_ComRes_cErrorLine, " which contains the duplicated points n° "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]); MLT_vOutput( C_ComRes_cWarningLine, buf); MLT_vOutput( C_ComRes_cErrorLine, " and "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]); MLT_vOutput( C_ComRes_cWarningLine, buf); } } } } if (!bNot) // the face remains, complete the new structures { for (p=0; p<3; p++) { p_stListOfFacesTripled[n].a3_xIndex[p] = p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[p]; p_stListOfFacesTripledIndexUV[n].a3_xIndex[p] = p_stLocalElement->d_stListOfFacesTripledIndexUV[j].a3_xIndex[p]; } MTH3D_M_vSetVectorElements(&p_stListOfFaceNormals[n], p_stLocalElement->d_stListOfFacesNormals[j].xX, p_stLocalElement->d_stListOfFacesNormals[j].xY, p_stLocalElement->d_stListOfFacesNormals[j].xZ); n++; } } } else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors) { p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); p_stListOfFacesTripled = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex)); p_stListOfFacesTripledIndexUV = (MLT_tdstTripledIndex *) malloc(p_stLocalElement->xNbFaces*sizeof(MLT_tdstTripledIndex)); p_stListOfFaceNormals = (MTH3D_tdstVector *) malloc(p_stLocalElement->xNbFaces*sizeof(MTH3D_tdstVector)); for (j=0; jxNbFaces; j++) { MTH3D_tdstVector stPoint[3]; BOOL bNot = FALSE; for (k=0; k<3; k++) MTH3D_M_vSetVectorElements(&stPoint[k], // k -> pk (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xX, (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xY, (g_hGeometricInFile[i]->d_stListOfPoints + p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[k])->xZ); for (k=0; k<3; k++) { for (l=k+1; l<3; l++) { if ((fabs(stPoint[k].xX - stPoint[l].xX) <= g_fLimit3)&& (fabs(stPoint[k].xY - stPoint[l].xY) <= g_fLimit3)&& (fabs(stPoint[k].xZ - stPoint[l].xZ) <= g_fLimit3)) //duplicate points { if (g_bEraseDuplicated) { //erase the face from the object bNot = TRUE; MLT_vOutput( C_ComRes_cWarningLine, "\nError: From the object "); //MLT_vOutput( C_ComRes_cWarningLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cErrorLine, sIdent); MLT_vOutput( C_ComRes_cWarningLine, " in the element "); //MLT_vOutput( C_ComRes_cWarningLine, p_stLocalElementFMD->sName); SCR_fn_v_RdL0_SplitSectionName(p_stLocalElementFMD->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cErrorLine, sIdent); MLT_vOutput( C_ComRes_cWarningLine, " was deleted the face n° "); sprintf(buf, "%d", j); MLT_vOutput( C_ComRes_cErrorLine, buf); MLT_vOutput( C_ComRes_cWarningLine, " which contained the duplicated points n° "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]); MLT_vOutput( C_ComRes_cErrorLine, buf); MLT_vOutput( C_ComRes_cWarningLine, " and "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]); MLT_vOutput( C_ComRes_cErrorLine, buf); } else { MLT_vOutput( C_ComRes_cErrorLine, "\nError: In the object "); //MLT_vOutput( C_ComRes_cErrorLine, g_hGeometricInFile[i]->sName); SCR_fn_v_RdL0_SplitSectionName(g_hGeometricInFile[i]->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, sIdent); MLT_vOutput( C_ComRes_cErrorLine, " in the element "); //MLT_vOutput( C_ComRes_cErrorLine, p_stLocalElementFMD->sName); SCR_fn_v_RdL0_SplitSectionName(p_stLocalElementFMD->sName, sFile, sAction, sIdent); MLT_vOutput( C_ComRes_cWarningLine, sIdent); MLT_vOutput( C_ComRes_cErrorLine, " was detected the face n° "); sprintf(buf, "%d", j); MLT_vOutput( C_ComRes_cWarningLine, buf); MLT_vOutput( C_ComRes_cErrorLine, " which contains the duplicated points n° "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[k]); MLT_vOutput( C_ComRes_cWarningLine, buf); MLT_vOutput( C_ComRes_cErrorLine, " and "); sprintf(buf, "%d", p_stLocalElement->d_stListOfFacesTripled[j].a3_xIndex[l]); MLT_vOutput( C_ComRes_cWarningLine, buf); } } } } if (!bNot) // the face remains { for (p=0; p<3; p++) p_stListOfFacesTripled[n].a3_xIndex[p] = p_stLocalElementFMD->d_stListOfFacesQuadrupled[j].stFaceTripled.a3_xIndex[p]; MTH3D_M_vSetVectorElements(&p_stListOfFaceNormals[n], p_stLocalElementFMD->d_stListOfFacesNormals[j].xX, p_stLocalElementFMD->d_stListOfFacesNormals[j].xY, p_stLocalElementFMD->d_stListOfFacesNormals[j].xZ); n++; } } } if ( g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementIndexedTriangles ) { p_stLocalElement = ((MLT_tdstElementIndexedTriangles *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); for (p=0; pd_stListOfFacesTripled[p].a3_xIndex[p1] = p_stListOfFacesTripled[p].a3_xIndex[p1]; p_stLocalElement->d_stListOfFacesTripledIndexUV[p].a3_xIndex[p1] = p_stListOfFacesTripledIndexUV[p].a3_xIndex[p1]; } MTH3D_M_vSetVectorElements(&p_stLocalElement->d_stListOfFacesNormals[p], p_stListOfFaceNormals[p].xX, p_stListOfFaceNormals[p].xY, p_stListOfFaceNormals[p].xZ); } p_stLocalElement->xNbFaces = n; } else if (g_hGeometricInFile[i]->d_xListOfElementsTypes[xIndex] == MLT_C_xElementFaceMapDescriptors) { p_stLocalElementFMD = ((MLT_tdstElementFaceMapDescriptors *)g_hGeometricInFile[i]->d_stListOfElements[xIndex]); for (p=0; pd_stListOfFacesQuadrupled[p].stFaceTripled.a3_xIndex[p1] = p_stListOfFacesTripled[p].a3_xIndex[p1]; MTH3D_M_vSetVectorElements(&p_stLocalElementFMD->d_stListOfFacesNormals[p], p_stListOfFaceNormals[p].xX, p_stListOfFaceNormals[p].xY, p_stListOfFaceNormals[p].xZ); } p_stLocalElementFMD->xNbFaces = n; } if (p_stListOfFacesTripled) free(p_stListOfFacesTripled); if (p_stListOfFacesTripledIndexUV) free(p_stListOfFacesTripledIndexUV); if (p_stListOfFaceNormals) free(p_stListOfFaceNormals); } } } // multitextures void MLT_vSearch (char *sRead, FILE*file) { long lIndex; char sRead1[256]; fseek(file, 0L, 0); fgets(sRead1, 256, file); while(!strstr(sRead1, sRead)) { lIndex=ftell(file); fgets(sRead1, 256, file); } fseek(file, lIndex, 0); }