// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "nel/misc/types_nl.h" #include "nel/misc/time_nl.h" #include "nel/misc/config_file.h" #include "nel/misc/debug.h" #include "nel/misc/path.h" #include "nel/misc/common.h" #include "nel/misc/displayer.h" #include "nel/misc/file.h" #include "nel/3d/register_3d.h" #include "build_surf.h" #include "build_rbank.h" #include "prim_checker.h" #include "nel/../../src/pacs/global_retriever.h" #include "nel/../../src/pacs/retriever_bank.h" #include "nel/../../src/pacs/surface_quad.h" #include "nel/../../src/pacs/local_retriever.h" #include "nel/../../src/pacs/retriever_instance.h" #include <string> #include <deque> #include <stdlib.h> using namespace std; using namespace NLMISC; using namespace NL3D; #ifndef NL_BRB_CFG #define NL_BRB_CFG "." #endif // NL_BRB_CFG #define LOG_ALL_INFO_TO_FILE string OutputRootPath; string OutputDirectory; string OutputPath; string TessellationPath; string IGBoxes; uint TessellateLevel; bool ReduceSurfaces; bool SmoothBorders; bool ComputeElevation; bool ComputeLevels; vector<string> ZoneNames; string ZoneExt; string ZoneNHExt = ".zonenhw"; string ZoneLookUpPath; bool ProcessAllPasses; bool CheckPrims; bool TessellateZones; bool MoulineZones; bool TessellateAndMoulineZones; bool ProcessRetrievers; string PreprocessDirectory; float WaterThreshold = 0.0f; bool UseZoneSquare; string ZoneUL; string ZoneDR; string GlobalRetriever; string RetrieverBank; string GlobalUL; string GlobalDR; bool ProcessGlobal; string LevelDesignWorldPath; string IgLandPath; string IgVillagePath; bool Verbose = false; bool CheckConsistency = true; CPrimChecker PrimChecker; /****************************************************************\ initMoulinette \****************************************************************/ int getInt(CConfigFile &cf, const string &varName, int defaultValue=0) { CConfigFile::CVar *var = cf.getVarPtr(varName); if (Verbose) { if (var) nlinfo("Read %s = %d", varName.c_str(), var->asInt()); else nlinfo("Couldn't read %s, using default = %d", varName.c_str(), defaultValue); } return var ? var->asInt() : defaultValue; } float getFloat(CConfigFile &cf, const string &varName, float defaultValue=0.0) { CConfigFile::CVar *var = cf.getVarPtr(varName); if (Verbose) { if (var) nlinfo("Read %s = %f", varName.c_str(), var->asFloat()); else nlinfo("Couldn't read %s, using default = %f", varName.c_str(), defaultValue); } return var ? var->asFloat() : defaultValue; } string getString(CConfigFile &cf, const string &varName, const string &defaultValue="") { CConfigFile::CVar *var = cf.getVarPtr(varName); if (Verbose) { if (var) nlinfo("Read %s = '%s'", varName.c_str(), var->asString().c_str()); else nlinfo("Couldn't read %s, using default = '%s'", varName.c_str(), defaultValue.c_str()); } return var ? var->asString() : defaultValue; } bool getBool(CConfigFile &cf, const string &varName, bool defaultValue=false) { CConfigFile::CVar *var = cf.getVarPtr(varName); if (Verbose) { if (var) nlinfo("Read %s = %s", varName.c_str(), (var->asInt()!=0 ? "true" : "false")); else nlinfo("Couldn't read %s, using default = '%s'", varName.c_str(), (defaultValue ? "true" : "false")); } return var ? (var->asInt() != 0) : defaultValue; } void initMoulinette() { registerSerial3d(); try { #ifdef NL_OS_UNIX std::string homeDir = getenv("HOME"); NLMISC::CPath::addSearchPath( homeDir + "/.nel"); #endif // NL_OS_UNIX NLMISC::CPath::addSearchPath(NL_BRB_CFG); CConfigFile cf; uint i; cf.load("build_rbank.cfg"); CConfigFile::CVar *verboseVar = cf.getVarPtr("Verbose"); if (verboseVar && verboseVar->asInt() != 0) Verbose = true; // Read paths CConfigFile::CVar *cvPathes = cf.getVarPtr("Pathes"); for (i=0; cvPathes != NULL && i<cvPathes->size(); ++i) CPath::addSearchPath(cvPathes->asString(i)); ProcessAllPasses = getBool(cf, "ProcessAllPasses", false); CheckPrims = getBool(cf, "CheckPrims", false); TessellateZones = getBool(cf, "TessellateZones", false); MoulineZones = getBool(cf, "MoulineZones", false); TessellateAndMoulineZones = getBool(cf, "TessellateAndMoulineZones", false); ProcessRetrievers = getBool(cf, "ProcessRetrievers", false); ProcessGlobal = getBool(cf, "ProcessGlobal", false); OutputRootPath = getString(cf, "OutputRootPath"); UseZoneSquare = getBool(cf, "UseZoneSquare", false); WaterThreshold = getFloat(cf, "WaterThreshold", 1.0); CheckConsistency = getBool(cf, "CheckConsistency", true); //if (TessellateZones || MoulineZones) { ZoneExt = getString(cf, "ZoneExt", ".zonew"); ZoneNHExt = getString(cf, "ZoneNHExt", ".zonenhw"); ZoneLookUpPath = getString(cf, "ZonePath", "./"); CPath::addSearchPath(ZoneLookUpPath); TessellationPath = getString(cf, "TessellationPath"); TessellateLevel = getInt(cf, "TessellateLevel"); } //if (MoulineZones) { LevelDesignWorldPath = getString(cf, "LevelDesignWorldPath"); IgLandPath = getString(cf, "IgLandPath"); IgVillagePath = getString(cf, "IgVillagePath"); IGBoxes = getString(cf, "IGBoxes", "./temp.bbox"); ReduceSurfaces = getBool(cf, "ReduceSurfaces", true); ComputeElevation = getBool(cf, "ComputeElevation", false); ComputeLevels = getBool(cf, "ComputeLevels", true); } //if (MoulineZones || ProcessRetrievers || ProcessGlobal) { SmoothBorders = getBool(cf, "SmoothBorders", true); PreprocessDirectory = getString(cf, "PreprocessDirectory"); if (SmoothBorders) OutputDirectory = getString(cf, "SmoothDirectory"); else OutputDirectory = getString(cf, "RawDirectory"); OutputPath = OutputRootPath+OutputDirectory; } //if (ProcessGlobal) { GlobalRetriever = getString(cf, "GlobalRetriever"); RetrieverBank = getString(cf, "RetrieverBank"); GlobalUL = getString(cf, "GlobalUL"); GlobalDR = getString(cf, "GlobalDR"); } ZoneNames.clear(); if (UseZoneSquare) { ZoneUL = getString(cf, "ZoneUL"); ZoneDR = getString(cf, "ZoneDR"); uint ul = getZoneIdByName(ZoneUL), dr = getZoneIdByName(ZoneDR); uint x0 = ul%256, y0 = ul/256, x1 = dr%256, y1 = dr/256; uint x, y; for (y=y0; y<=y1; ++y) for (x=x0; x<=x1; ++x) ZoneNames.push_back(getZoneNameById(x+y*256)); } else { CConfigFile::CVar *cvZones = cf.getVarPtr("Zones"); for (i=0; cvZones != NULL && i<cvZones->size(); i++) ZoneNames.push_back(cvZones->asString(i)); } } catch (EConfigFile &e) { nlwarning("Problem in config file : %s\n", e.what ()); } } /****************************************************************\ moulineZones \****************************************************************/ void moulineZones(vector<string> &zoneNames) { uint i; if (CheckPrims) { PrimChecker.build(LevelDesignWorldPath, IgLandPath, IgVillagePath); } PrimChecker.load(); if (ProcessAllPasses) { for (i=0; i<zoneNames.size(); ++i) { nlinfo("Generate final .lr for zone %s", zoneNames[i].c_str()); processAllPasses(zoneNames[i]); } } if (ProcessGlobal) { nlinfo("Process .gr and .rbank"); processGlobalRetriever(); } } /****************************************************************\ MAIN \****************************************************************/ int main(int argc, char **argv) { // Filter addSearchPath NLMISC::createDebug(); InfoLog->addNegativeFilter ("adding the path"); CFileDisplayer fd(getLogDirectory() + "evallog.log", true); #ifdef LOG_ALL_INFO_TO_FILE createDebug(); DebugLog->addDisplayer (&fd); ErrorLog->addDisplayer (&fd); WarningLog->addDisplayer (&fd); InfoLog->addDisplayer (&fd); AssertLog->addDisplayer (&fd); ErrorLog->removeDisplayer("DEFAULT_MBD"); #endif try { // Init the moulinette initMoulinette(); // Compute the zone surfaces TTime before, after; uint i; if (argc > 1) { ZoneNames.clear(); for (i=1; i<(uint)argc; ++i) { if (argv[i][0] != '-') { ZoneNames.push_back(string(argv[i])); } else { switch (argv[i][1]) { case 'C': CheckPrims = true; break; case 'c': CheckPrims = false; break; case 'P': ProcessAllPasses = true; break; case 'p': ProcessAllPasses = false; break; case 'G': ProcessGlobal = true; break; case 'g': ProcessGlobal = false; break; case 'T': case 't': case 'M': case 'm': case 'L': case 'l': nlwarning("Option %c is not more valid", argv[i][1]); break; } } } } before = CTime::getLocalTime(); moulineZones(ZoneNames); after = CTime::getLocalTime(); uint totalSeconds = (uint)((after-before)/1000); uint workDay = totalSeconds/86400, workHour = (totalSeconds-86400*workDay)/3600, workMinute = (totalSeconds-86400*workDay-3600*workHour)/60, workSecond = (totalSeconds-86400*workDay-3600*workHour-60*workMinute); if (Verbose) nlinfo("total computation time: %d days, %d hours, %d minutes and %d seconds", workDay, workHour, workMinute, workSecond); } catch (Exception &e) { nlwarning ("main trapped an exception: '%s'\n", e.what ()); } #ifndef NL_DEBUG /* catch (...) { nlwarning("main trapped an unknown exception\n"); }*/ #endif // NL_DEBUG return 0; }