// 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 <vector> #include <stdlib.h> #include "nel/misc/config_file.h" #include "nel/misc/time_nl.h" #include "nel/misc/file.h" #include "nel/pacs/collision_mesh_build.h" #include "nel/pacs/local_retriever.h" #include "nel/pacs/retriever_instance.h" #include "nel/pacs/global_retriever.h" #include "nel/pacs/retriever_bank.h" #include "nel/pacs/u_global_position.h" #include "mouline.h" using namespace std; using namespace NLPACS; using namespace NLMISC; #ifndef NL_BIRB_CFG #define NL_BIRB_CFG "." #endif // NL_BIB_CFG bool AddToRetriever = true; bool Merge = true; string MergePath = "c:/data_test/"; string MergeInputPrefix = "fyros"; string MergeOutputPrefix = "city_landscape_fyros"; string MeshPath = "c:/data_test/"; vector<string> Meshes; string OutputPath = "c:/data_test/"; string OutputPrefix = "city_fyros"; CVector getZoneCenterById(uint16 id) { CAABBox bbox; uint x, y; const float zdim = 160.0f; x = id%256; y = id/256; return CVector(zdim*((float)x+0.5f), -zdim*((float)y+0.5f), 0.0f); } uint32 getIdByCoord(uint x, uint y) { return y*256+x; } uint16 getZoneIdByName(string &name) { sint y = 0, x = 0; const char *str = name.c_str(); while (*str != '_') y = y*10 + *(str++)-'0'; ++str; x = (str[0]-'A')*26+(str[1]-'A'); return (y-1)*256+x; } template<class A> void serialAndSave(A &a, string fn) { COFile f; f.open(fn); f.serial(a); f.close(); } template<class A> void openAndSerial(A &a, string fn) { CIFile f; f.open(fn); f.serial(a); f.close(); } // config management int getInt(CConfigFile &cf, const string &varName) { CConfigFile::CVar &var = cf.getVar(varName); return var.asInt(); } string getString(CConfigFile &cf, const string &varName) { CConfigFile::CVar &var = cf.getVar(varName); return var.asString(); } void initConfig() { try { #ifdef NL_OS_UNIX NLMISC::CPath::addSearchPath(NLMISC::CPath::getApplicationDirectory("NeL")); #endif // NL_OS_UNIX NLMISC::CPath::addSearchPath(NL_BIRB_CFG); CConfigFile cf; cf.load("build_indoor_rbank.cfg"); Merge = getInt(cf, "Merge") != 0; AddToRetriever = getInt(cf, "AddToRetriever") != 0; MergePath = getString(cf, "MergePath"); MergeInputPrefix = getString(cf, "MergeInputPrefix"); MergeOutputPrefix = getString(cf, "MergeOutputPrefix"); MeshPath = getString(cf, "MeshPath"); OutputPath = getString(cf, "OutputPath"); OutputPrefix = getString(cf, "OutputPrefix"); CConfigFile::CVar &meshes = cf.getVar("Meshes"); uint i; for (i=0; i<(uint)meshes.size(); i++) Meshes.push_back(meshes.asString(i)); } catch (const EConfigFile &e) { printf ("Problem in config file : %s\n", e.what ()); } } // void makeGlobalRetriever(vector<CVector> &translation) { CGlobalRetriever gr; CRetrieverBank rb; if (Merge) { openAndSerial(rb, MergePath+MergeInputPrefix+".rbank"); gr.setRetrieverBank(&rb); openAndSerial(gr, MergePath+MergeInputPrefix+".gr"); } else { gr.setRetrieverBank(&rb); gr.init(); } TTime start, end; start = CTime::getLocalTime(); vector<uint> ninst; uint i; for (i=0; i<Meshes.size(); ++i) { CLocalRetriever lr; try { openAndSerial(lr, OutputPath+Meshes[i]+".lr"); uint rid = rb.addRetriever(lr); if (AddToRetriever) { uint iid = (gr.makeInstance(rid, 0, -translation[i])).getInstanceId(); ninst.push_back(iid); } } catch (const Exception &e) { nlwarning("WARNING: can't merge lr '%s.lr': %s", Meshes[i].c_str(), e.what()); } } gr.initQuadGrid(); for (i=0; i<ninst.size(); ++i) gr.makeLinks(ninst[i]); end = CTime::getLocalTime(); nlinfo("instance making and linking work time: %.3f", (double)(end-start)/1000.0); COFile output; /* * This way, at the end of the build process, * the rbank should be 5 bytes only and lr should be saved as well next to the rbank */ if (Merge) { serialAndSave(gr, OutputPath+MergeOutputPrefix+".gr"); rb.saveShortBank(OutputPath, MergeOutputPrefix, true); // save 5 bytes rbank and lr as well // serialAndSave(rb, OutputPath+MergeOutputPrefix+".rbank"); } else { serialAndSave(gr, OutputPath+OutputPrefix+".gr"); rb.saveShortBank(OutputPath, OutputPrefix, true); // save 5 bytes rbank and lr as well // serialAndSave(rb, OutputPath+OutputPrefix+".rbank"); } gr.check(); /* UGlobalPosition gpos; gpos = gr.retrievePosition(CVector(18630, -24604, 0)); const CLocalRetriever &lr = gr.getRetriever(gr.getInstance(gpos.InstanceId).getRetrieverId()); lr.dumpSurface(gpos.LocalPosition.Surface, gr.getInstance(gpos.InstanceId).getOrigin()); */ } void createRetriever(vector<CVector> &translation) { uint i; translation.resize(Meshes.size()); for (i=0; i<Meshes.size(); ++i) { CLocalRetriever lr; CCollisionMeshBuild cmb; string meshName = Meshes[i]; nlinfo("compute retriever %s", meshName.c_str()); try { openAndSerial(cmb, MeshPath+meshName+".cmb"); { vector<bool> usedMaterials; uint j; uint maxMat = 0; for (j=0; j<cmb.Faces.size(); ++j) if (cmb.Faces[j].Material > (sint)maxMat) maxMat = cmb.Faces[j].Material; usedMaterials.resize(maxMat+1); for (j=0; j<usedMaterials.size(); ++j) usedMaterials[j] = false; for (j=0; j<cmb.Faces.size(); ++j) usedMaterials[cmb.Faces[j].Material] = true; for (j=0; j<usedMaterials.size(); ++j) if (usedMaterials[j]) nlinfo("Material %d used", j); } computeRetriever(cmb, lr, translation[i], true); /* // TEMP uint tt; for (tt=0; tt<lr.getSurfaces().size(); ++tt) lr.dumpSurface(tt); // */ // Compute an identifier name string indentifier = meshName; string::size_type sharpPos = indentifier.rfind ('#'); if (sharpPos != string::npos) indentifier = indentifier.substr (0, sharpPos); lr.setIdentifier(indentifier); // Save the lr file serialAndSave(lr, OutputPath+meshName+".lr"); } catch (const Exception &e) { nlwarning("WARNING: can compute lr '%s.lr': %s", meshName.c_str(), e.what()); } } } // pacs test void serialGPos(UGlobalPosition &gp, NLMISC::IStream &f) { f.serial(gp.InstanceId, gp.LocalPosition.Surface, gp.LocalPosition.Estimation); } struct CGlobalPositionCompare { UGlobalPosition ClientPosition, RetrievedPosition; bool Compare; void serial(NLMISC::IStream &f) { serialGPos(ClientPosition, f); serialGPos(RetrievedPosition, f); f.serial(Compare); } }; vector<CGlobalPositionCompare> StoredPosition; void loadAndDumpPositions() { CIFile f; f.open("backup.position"); f.serialCont(StoredPosition); f.close(); uint i; for (i=0; i<StoredPosition.size(); ++i) { CGlobalPositionCompare &c = StoredPosition[i]; nlinfo("cmp=%s cl(%4d,%4d,%.8f,%.8f,%.8f) gr(%4d,%4d,%.8f,%.8f,%.8f)", c.Compare ? "true" : "false", c.ClientPosition.InstanceId, c.ClientPosition.LocalPosition.Surface, c.ClientPosition.LocalPosition.Estimation.x, c.ClientPosition.LocalPosition.Estimation.y, c.ClientPosition.LocalPosition.Estimation.z, c.RetrievedPosition.InstanceId, c.RetrievedPosition.LocalPosition.Surface, c.RetrievedPosition.LocalPosition.Estimation.x, c.RetrievedPosition.LocalPosition.Estimation.y, c.RetrievedPosition.LocalPosition.Estimation.z); } } // /* int main(int argc, char **argv) { CRetrieverBank bank; CIFile f("R:/code/ryzom/data/3d/continents/matis/pacs/matis.rbank"); f.serial(bank); bank.saveShortBank("R:/code/ryzom/data/3d/continents/matis/pacs", "matis"); } */ int main(int argc, char **argv) { vector<CVector> translation; TTime start, end; createDebug (); ErrorLog->removeDisplayer("DEFAULT_MBD"); initConfig(); start = CTime::getLocalTime(); createRetriever(translation); // translation[0] = CVector(-4670.0f, 3579.0f, 0.0f); makeGlobalRetriever(translation); end = CTime::getLocalTime(); nlinfo("%.3f seconds work", (double)(end-start)/1000.0); uint i; for (i=0; i<translation.size(); ++i) nlinfo("CVector\ttranslation_%d = CVector(%.1ff, %.1ff, %.1ff);", i, translation[i].x, translation[i].y, translation[i].z); return 0; }