Tools/MeshExtractor:

* Fixed some crashes
* Added multithreading support, default to 4 threads.
* Added some command line arguments
This commit is contained in:
Subv
2012-09-29 12:49:14 -05:00
parent 3bea28e62c
commit 1a7f0658b2
9 changed files with 82 additions and 51 deletions
+1 -8
View File
@@ -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
View File
@@ -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
+9 -10
View File
@@ -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(&params, sizeof(dtNavMeshParams), 1, mmap); fwrite(&params, 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;
}*/ }
} }
+2 -1
View File
@@ -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
View File
@@ -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;
+3 -1
View File
@@ -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;
+55 -19
View File
@@ -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"); char* param = NULL;
if (wdt.IsGlobalModel) for (int i = 1; i < argc; ++i)
{ {
printf("Unsupported\n"); if (strcmp(argv[i], "--threads") == 0)
return; {
param = argv[++i];
if (!param)
return false;
threads = atoi(param);
printf("Using %i threads\n", threads);
}
if (strcmp(argv[i], "--maps") == 0)
{
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());
}
} }
ContinentBuilder builder("DalaranPrison", &wdt); return true;
builder.Build(); }
*/
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;
} }
+2 -6
View File
@@ -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;
} }