Tools/MeshExtractor:
* Fixed some crashes * Added multithreading support, default to 4 threads. * Added some command line arguments
This commit is contained in:
@@ -29,14 +29,7 @@ ADT::~ADT()
|
|||||||
|
|
||||||
void ADT::Read()
|
void ADT::Read()
|
||||||
{
|
{
|
||||||
Chunk* mhdr = Data->GetChunkByName("MHDR");
|
Header.Read(Data->GetChunkByName("MHDR")->GetStream());
|
||||||
if (!mhdr)
|
|
||||||
{
|
|
||||||
delete Data;
|
|
||||||
Data = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Header.Read(mhdr->GetStream());
|
|
||||||
MapChunks.reserve(16 * 16);
|
MapChunks.reserve(16 * 16);
|
||||||
int mapChunkIndex = 0;
|
int mapChunkIndex = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "ace/Synch.h"
|
||||||
|
|
||||||
class WorldModelRoot;
|
class WorldModelRoot;
|
||||||
class Model;
|
class Model;
|
||||||
@@ -20,6 +21,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (_items.size() > FlushLimit)
|
if (_items.size() > FlushLimit)
|
||||||
Clear();
|
Clear();
|
||||||
|
ACE_GUARD(ACE_Thread_Mutex, g, mutex);
|
||||||
_items[key] = val;
|
_items[key] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ public:
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::map<K, T*> _items;
|
std::map<K, T*> _items;
|
||||||
|
ACE_Thread_Mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CacheClass
|
class CacheClass
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "WDT.h"
|
#include "WDT.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "DetourNavMesh.h"
|
#include "DetourNavMesh.h"
|
||||||
|
#include "Cache.h"
|
||||||
#include "ace/Task.h"
|
#include "ace/Task.h"
|
||||||
|
|
||||||
class BuilderThread : public ACE_Task<ACE_MT_SYNCH>
|
class BuilderThread : public ACE_Task<ACE_MT_SYNCH>
|
||||||
@@ -17,7 +18,7 @@ public:
|
|||||||
int svc()
|
int svc()
|
||||||
{
|
{
|
||||||
Free = false;
|
Free = false;
|
||||||
printf("[%02i,%02i] Building tile", X, Y);
|
printf("[%02i,%02i] Building tile\n", X, Y);
|
||||||
TileBuilder builder(Continent, X, Y, MapId);
|
TileBuilder builder(Continent, X, Y, MapId);
|
||||||
char buff[100];
|
char buff[100];
|
||||||
sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y);
|
sprintf(buff, "%03u%02u%02u.mmtile", MapId, X, Y);
|
||||||
@@ -63,14 +64,11 @@ void ContinentBuilder::Build()
|
|||||||
fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap);
|
fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap);
|
||||||
fclose(mmap);
|
fclose(mmap);
|
||||||
std::vector<BuilderThread*> Threads;
|
std::vector<BuilderThread*> Threads;
|
||||||
/*for (uint32 i = 0; i < 1; ++i)
|
for (uint32 i = 0; i < NumberOfThreads; ++i)
|
||||||
Threads.push_back(new BuilderThread());*/
|
Threads.push_back(new BuilderThread());
|
||||||
for (std::vector<TilePos>::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr)
|
for (std::vector<TilePos>::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr)
|
||||||
{
|
{
|
||||||
BuilderThread th;
|
bool next = false;
|
||||||
th.SetData(itr->X, itr->Y, MapId, Continent);
|
|
||||||
th.svc();
|
|
||||||
/*bool next = false;
|
|
||||||
while (!next)
|
while (!next)
|
||||||
{
|
{
|
||||||
for (std::vector<BuilderThread*>::iterator _th = Threads.begin(); _th != Threads.end(); ++_th)
|
for (std::vector<BuilderThread*>::iterator _th = Threads.begin(); _th != Threads.end(); ++_th)
|
||||||
@@ -85,13 +83,14 @@ void ContinentBuilder::Build()
|
|||||||
}
|
}
|
||||||
// Wait for 20 seconds
|
// Wait for 20 seconds
|
||||||
ACE_OS::sleep(ACE_Time_Value (0, 20000));
|
ACE_OS::sleep(ACE_Time_Value (0, 20000));
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Cache->Clear();
|
||||||
|
|
||||||
/*// Free memory
|
// Free memory
|
||||||
for (std::vector<BuilderThread*>::iterator _th = Threads.begin(); _th != Threads.end(); ++_th)
|
for (std::vector<BuilderThread*>::iterator _th = Threads.begin(); _th != Threads.end(); ++_th)
|
||||||
{
|
{
|
||||||
(*_th)->wait();
|
(*_th)->wait();
|
||||||
delete *_th;
|
delete *_th;
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,12 @@
|
|||||||
class ContinentBuilder
|
class ContinentBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt) : MapId(mapId), Continent(continent), TileMap(wdt) {}
|
ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {}
|
||||||
void Build();
|
void Build();
|
||||||
private:
|
private:
|
||||||
std::string Continent;
|
std::string Continent;
|
||||||
WDT* TileMap;
|
WDT* TileMap;
|
||||||
uint32 MapId;
|
uint32 MapId;
|
||||||
|
uint32 NumberOfThreads;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -25,7 +25,11 @@ void LiquidHandler::HandleNewLiquid()
|
|||||||
{
|
{
|
||||||
H2OHeader h = header[i];
|
H2OHeader h = header[i];
|
||||||
if (h.LayerCount == 0)
|
if (h.LayerCount == 0)
|
||||||
|
{
|
||||||
|
// Need to fill in missing data with dummies.
|
||||||
|
MCNKData.push_back(MCNKLiquidData(NULL, H2ORenderMask()));
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET);
|
fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET);
|
||||||
H2OInformation information = H2OInformation::Read(stream);
|
H2OInformation information = H2OInformation::Read(stream);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "DBC.h"
|
#include "DBC.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include "ace/Synch.h"
|
||||||
|
|
||||||
char* MPQManager::Files[] = {
|
char* MPQManager::Files[] = {
|
||||||
"common.MPQ",
|
"common.MPQ",
|
||||||
"common-2.MPQ",
|
"common-2.MPQ",
|
||||||
@@ -27,12 +29,6 @@ void MPQManager::Initialize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPQManager::LoadMaps()
|
|
||||||
{
|
|
||||||
DBC* file = GetDBC("Map");
|
|
||||||
printf("NAME %s\n", file->GetRecordById(608)->GetString(1).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MPQManager::InitializeDBC()
|
void MPQManager::InitializeDBC()
|
||||||
{
|
{
|
||||||
CurLocale = 0;
|
CurLocale = 0;
|
||||||
@@ -54,6 +50,7 @@ void MPQManager::InitializeDBC()
|
|||||||
|
|
||||||
FILE* MPQManager::GetFile( std::string path )
|
FILE* MPQManager::GetFile( std::string path )
|
||||||
{
|
{
|
||||||
|
ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL);
|
||||||
MPQFile file(path.c_str());
|
MPQFile file(path.c_str());
|
||||||
if (file.isEof())
|
if (file.isEof())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define MPQ_MANAGER_H
|
#define MPQ_MANAGER_H
|
||||||
|
|
||||||
#include "MPQ.h"
|
#include "MPQ.h"
|
||||||
|
#include "ace/Synch.h"
|
||||||
|
|
||||||
class DBC;
|
class DBC;
|
||||||
class MPQManager
|
class MPQManager
|
||||||
@@ -11,7 +12,6 @@ public:
|
|||||||
~MPQManager() {}
|
~MPQManager() {}
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void LoadMaps();
|
|
||||||
FILE* GetFile(std::string path);
|
FILE* GetFile(std::string path);
|
||||||
DBC* GetDBC(std::string name);
|
DBC* GetDBC(std::string name);
|
||||||
|
|
||||||
@@ -22,6 +22,8 @@ public:
|
|||||||
static char* Languages[];
|
static char* Languages[];
|
||||||
protected:
|
protected:
|
||||||
void InitializeDBC();
|
void InitializeDBC();
|
||||||
|
private:
|
||||||
|
ACE_Thread_Mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MPQManager* MPQHandler;
|
extern MPQManager* MPQHandler;
|
||||||
|
|||||||
@@ -4,42 +4,73 @@
|
|||||||
#include "Cache.h"
|
#include "Cache.h"
|
||||||
#include "DBC.h"
|
#include "DBC.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "LoginDatabase.h"
|
#include "LoginDatabase.h"
|
||||||
|
#include "Util.h"
|
||||||
LoginDatabaseWorkerPool LoginDatabase;
|
LoginDatabaseWorkerPool LoginDatabase;
|
||||||
|
|
||||||
MPQManager* MPQHandler;
|
MPQManager* MPQHandler;
|
||||||
CacheClass* Cache;
|
CacheClass* Cache;
|
||||||
|
|
||||||
void ExtractAllMaps(uint32 onlyMap)
|
void ExtractAllMaps(std::set<uint32>& mapIds, uint32 threads)
|
||||||
{
|
{
|
||||||
DBC* dbc = MPQHandler->GetDBC("Map");
|
DBC* dbc = MPQHandler->GetDBC("Map");
|
||||||
for (std::vector<Record*>::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr)
|
for (std::vector<Record*>::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr)
|
||||||
{
|
{
|
||||||
uint32 mapId = (*itr)->Values[0];
|
uint32 mapId = (*itr)->Values[0];
|
||||||
if (onlyMap && mapId != onlyMap)
|
|
||||||
|
// Skip this map if a list of specific maps was provided and this one is not contained in it.
|
||||||
|
if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string name = (*itr)->GetString(1);
|
std::string name = (*itr)->GetString(1);
|
||||||
WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt");
|
WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt");
|
||||||
if (!wdt.IsValid || wdt.IsGlobalModel)
|
if (!wdt.IsValid || wdt.IsGlobalModel)
|
||||||
continue;
|
continue;
|
||||||
printf("Building %s MapId %u\n", name.c_str(), mapId);
|
printf("Building %s MapId %u\n", name.c_str(), mapId);
|
||||||
ContinentBuilder builder(name, mapId, &wdt);
|
ContinentBuilder builder(name, mapId, &wdt, threads);
|
||||||
builder.Build();
|
builder.Build();
|
||||||
}
|
}
|
||||||
/*
|
}
|
||||||
WDT wdt("World\\maps\\DalaranPrison\\DalaranPrison.wdt");
|
|
||||||
if (!wdt.IsValid)
|
bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList)
|
||||||
return;
|
|
||||||
printf("Model valid!\n");
|
|
||||||
if (wdt.IsGlobalModel)
|
|
||||||
{
|
{
|
||||||
printf("Unsupported\n");
|
char* param = NULL;
|
||||||
return;
|
for (int i = 1; i < argc; ++i)
|
||||||
|
{
|
||||||
|
if (strcmp(argv[i], "--threads") == 0)
|
||||||
|
{
|
||||||
|
param = argv[++i];
|
||||||
|
if (!param)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
threads = atoi(param);
|
||||||
|
printf("Using %i threads\n", threads);
|
||||||
}
|
}
|
||||||
ContinentBuilder builder("DalaranPrison", &wdt);
|
if (strcmp(argv[i], "--maps") == 0)
|
||||||
builder.Build();
|
{
|
||||||
*/
|
param = argv[++i];
|
||||||
|
if (!param)
|
||||||
|
return false;
|
||||||
|
std::string maps = std::string(param);
|
||||||
|
Tokens tokens(maps, ',');
|
||||||
|
|
||||||
|
for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||||
|
mapList.insert(atoi(*itr));
|
||||||
|
|
||||||
|
printf("Extracting only provided list of maps (%u).\n", mapList.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintUsage()
|
||||||
|
{
|
||||||
|
printf("MeshExtractor help.\n");
|
||||||
|
printf("* Use \"--threads <number>\" to specify <number> threads, default to 4\n");
|
||||||
|
printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@@ -48,11 +79,16 @@ int main(int argc, char* argv[])
|
|||||||
Cache = new CacheClass();
|
Cache = new CacheClass();
|
||||||
MPQHandler = new MPQManager();
|
MPQHandler = new MPQManager();
|
||||||
MPQHandler->Initialize();
|
MPQHandler->Initialize();
|
||||||
MPQHandler->LoadMaps();
|
uint32 threads = 4;
|
||||||
uint32 onlyMap = 0;
|
std::set<uint32> mapIds;
|
||||||
if (argc == 2)
|
|
||||||
onlyMap = uint32(atoi(argv[1]));
|
if (!HandleArgs(argc, argv, threads, mapIds))
|
||||||
ExtractAllMaps(onlyMap);
|
{
|
||||||
|
PrintUsage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtractAllMaps(mapIds, threads);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "RecastAlloc.h"
|
#include "RecastAlloc.h"
|
||||||
#include "DetourNavMeshBuilder.h"
|
#include "DetourNavMeshBuilder.h"
|
||||||
|
|
||||||
|
#include "ace/Synch.h"
|
||||||
|
|
||||||
TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0)
|
TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0)
|
||||||
{
|
{
|
||||||
// Cell Size = TileSize / TileVoxelSize
|
// Cell Size = TileSize / TileVoxelSize
|
||||||
@@ -54,11 +56,6 @@ uint8* TileBuilder::Build()
|
|||||||
{
|
{
|
||||||
adt = new ADT(Utils::GetAdtPath(World, X, Y));
|
adt = new ADT(Utils::GetAdtPath(World, X, Y));
|
||||||
adt->Read();
|
adt->Read();
|
||||||
if (!adt->Data)
|
|
||||||
{
|
|
||||||
delete adt;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Cache->AdtCache.Insert(std::make_pair(X, Y), adt);
|
Cache->AdtCache.Insert(std::make_pair(X, Y), adt);
|
||||||
}
|
}
|
||||||
_Geometry->AddAdt(adt);
|
_Geometry->AddAdt(adt);
|
||||||
@@ -234,7 +231,6 @@ uint8* TileBuilder::Build()
|
|||||||
DataSize = navDataSize;
|
DataSize = navDataSize;
|
||||||
rcFreePolyMesh(pmesh);
|
rcFreePolyMesh(pmesh);
|
||||||
rcFreePolyMeshDetail(dmesh);
|
rcFreePolyMeshDetail(dmesh);
|
||||||
Cache->Clear();
|
|
||||||
return navData;
|
return navData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user