khanat-opennel-code/code/nel/tools/pacs/build_indoor_rbank/main.cpp

400 lines
8.7 KiB
C++

// 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;
}