400 lines
8.7 KiB
C++
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;
|
|
}
|
|
|
|
|
|
|