Tools/MeshExtractor:
* Added the capability of extracting DBCs. * Fixed most compile warnings * Some work on the navigation mesh generation process (still not ready)
This commit is contained in:
@@ -48,7 +48,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint )
|
|||||||
|
|
||||||
int ChunkedData::GetFirstIndex( std::string name )
|
int ChunkedData::GetFirstIndex( std::string name )
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Chunks.size(); ++i)
|
for (uint32 i = 0; i < Chunks.size(); ++i)
|
||||||
if (Chunks[i]->Name == name)
|
if (Chunks[i]->Name == name)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -56,7 +56,7 @@ int ChunkedData::GetFirstIndex( std::string name )
|
|||||||
|
|
||||||
Chunk* ChunkedData::GetChunkByName( std::string name )
|
Chunk* ChunkedData::GetChunkByName( std::string name )
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Chunks.size(); ++i)
|
for (uint32 i = 0; i < Chunks.size(); ++i)
|
||||||
if (Chunks[i]->Name == name)
|
if (Chunks[i]->Name == name)
|
||||||
return Chunks[i];
|
return Chunks[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -29,6 +29,17 @@ public:
|
|||||||
POLY_FLAG_SWIM = 2,
|
POLY_FLAG_SWIM = 2,
|
||||||
POLY_FLAG_FLIGHTMASTER = 4
|
POLY_FLAG_FLIGHTMASTER = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ExtractFlags
|
||||||
|
{
|
||||||
|
EXTRACT_FLAG_DBC = 1,
|
||||||
|
EXTRACT_FLAG_MAPS = 2,
|
||||||
|
EXTRACT_FLAG_VMAPS = 4,
|
||||||
|
EXTRACT_FLAG_GOB_MODELS = 8,
|
||||||
|
EXTRACT_FLAG_MMAPS = 16,
|
||||||
|
EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS
|
||||||
|
};
|
||||||
|
|
||||||
static const float TileSize;
|
static const float TileSize;
|
||||||
static const float MaxXY;
|
static const float MaxXY;
|
||||||
static const float ChunkSize;
|
static const float ChunkSize;
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ private:
|
|||||||
int X, Y, MapId;
|
int X, Y, MapId;
|
||||||
std::string Continent;
|
std::string Continent;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
dtNavMeshParams Params;
|
||||||
public:
|
public:
|
||||||
BuilderThread(bool deb) : Free(true), debug(deb) {}
|
BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {}
|
||||||
void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; }
|
void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; }
|
||||||
|
|
||||||
int svc()
|
int svc()
|
||||||
@@ -32,7 +33,7 @@ public:
|
|||||||
Free = true;
|
Free = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint8* nav = builder.Build(debug);
|
uint8* nav = builder.Build(debug, Params);
|
||||||
if (nav)
|
if (nav)
|
||||||
{
|
{
|
||||||
f = fopen(buff, "wb");
|
f = fopen(buff, "wb");
|
||||||
@@ -101,14 +102,17 @@ void ContinentBuilder::Build(bool debug)
|
|||||||
dtNavMeshParams params;
|
dtNavMeshParams params;
|
||||||
params.maxPolys = 32768;
|
params.maxPolys = 32768;
|
||||||
params.maxTiles = TileMap->TileTable.size();
|
params.maxTiles = TileMap->TileTable.size();
|
||||||
rcVcopy(params.orig, bmin);
|
// rcVcopy(params.orig, bmin);
|
||||||
params.tileHeight = 533.33333f;
|
params.orig[0] = Constants::Origin[0];
|
||||||
params.tileWidth = 533.33333f;
|
params.orig[1] = 0;
|
||||||
|
params.orig[2] = Constants::Origin[2];
|
||||||
|
params.tileHeight = Constants::TileSize;
|
||||||
|
params.tileWidth = Constants::TileSize;
|
||||||
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 < NumberOfThreads; ++i)
|
for (uint32 i = 0; i < NumberOfThreads; ++i)
|
||||||
Threads.push_back(new BuilderThread(debug));
|
Threads.push_back(new BuilderThread(debug, params));
|
||||||
printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads);
|
printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads);
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks )
|
|||||||
{
|
{
|
||||||
int32 index;
|
int32 index;
|
||||||
fread(&index, sizeof(int32), 1, stream);
|
fread(&index, sizeof(int32), 1, stream);
|
||||||
if (index < 0 || index >= _definitions->size())
|
if (index < 0 || uint32(index) >= _definitions->size())
|
||||||
continue;
|
continue;
|
||||||
DoodadDefinition doodad = (*_definitions)[index];
|
DoodadDefinition doodad = (*_definitions)[index];
|
||||||
if (_drawn.find(doodad.UniqueId) != _drawn.end())
|
if (_drawn.find(doodad.UniqueId) != _drawn.end())
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ void LiquidHandler::HandleNewLiquid()
|
|||||||
H2OInformation information = H2OInformation::Read(stream);
|
H2OInformation information = H2OInformation::Read(stream);
|
||||||
|
|
||||||
float** heights = new float*[9];
|
float** heights = new float*[9];
|
||||||
for (int i = 0; i < 9; ++i)
|
for (int j = 0; j < 9; ++i)
|
||||||
{
|
{
|
||||||
heights[i] = new float[9];
|
heights[j] = new float[9];
|
||||||
memset(heights[i], 0, sizeof(float) * 9);
|
memset(heights[j], 0, sizeof(float) * 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
H2ORenderMask renderMask;
|
H2ORenderMask renderMask;
|
||||||
@@ -52,7 +52,7 @@ void LiquidHandler::HandleNewLiquid()
|
|||||||
uint8* altMask = new uint8[size];
|
uint8* altMask = new uint8[size];
|
||||||
fread(altMask, sizeof(uint8), size, stream);
|
fread(altMask, sizeof(uint8), size, stream);
|
||||||
|
|
||||||
for (int mi = 0; mi < size; mi++)
|
for (uint32 mi = 0; mi < size; mi++)
|
||||||
renderMask.Mask[mi + information.OffsetY] |= altMask[mi];
|
renderMask.Mask[mi + information.OffsetY] |= altMask[mi];
|
||||||
delete[] altMask;
|
delete[] altMask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ MPQArchive::MPQArchive(const char* filename)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GetFileListTo(Files);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MPQArchive::close()
|
void MPQArchive::close()
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ class MPQArchive
|
|||||||
public:
|
public:
|
||||||
mpq_archive_s *mpq_a;
|
mpq_archive_s *mpq_a;
|
||||||
|
|
||||||
|
vector<string> Files;
|
||||||
|
|
||||||
MPQArchive(const char* filename);
|
MPQArchive(const char* filename);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ char* MPQManager::Files[] = {
|
|||||||
"patch-3.MPQ"
|
"patch-3.MPQ"
|
||||||
};
|
};
|
||||||
|
|
||||||
char* MPQManager::Languages[] = { "esES", "enUS", "enGB", "esMX", "deDE" };
|
char* MPQManager::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
|
||||||
|
|
||||||
void MPQManager::Initialize()
|
void MPQManager::Initialize()
|
||||||
{
|
{
|
||||||
@@ -31,21 +31,38 @@ void MPQManager::Initialize()
|
|||||||
|
|
||||||
void MPQManager::InitializeDBC()
|
void MPQManager::InitializeDBC()
|
||||||
{
|
{
|
||||||
CurLocale = 0;
|
BaseLocale = -1;
|
||||||
std::string fileName;
|
std::string fileName;
|
||||||
uint32 size = sizeof(Languages) / sizeof(char*);
|
uint32 size = sizeof(Languages) / sizeof(char*);
|
||||||
|
MPQArchive* _baseLocale = NULL;
|
||||||
for (uint32 i = 0; i < size; ++i)
|
for (uint32 i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ";
|
std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ";
|
||||||
FILE* file = fopen(fileName.c_str(), "rb");
|
FILE* file = fopen(_fileName.c_str(), "rb");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
CurLocale = i;
|
if (BaseLocale == -1)
|
||||||
break;
|
{
|
||||||
|
BaseLocale = i;
|
||||||
|
_baseLocale = new MPQArchive(_fileName.c_str());
|
||||||
|
fileName = _fileName;
|
||||||
|
LocaleFiles[i] = _baseLocale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LocaleFiles[i] = new MPQArchive(_fileName.c_str());
|
||||||
|
|
||||||
|
AvailableLocales.insert(i);
|
||||||
|
printf("Detected locale: %s\n", Languages[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Archives.push_front(new MPQArchive(fileName.c_str()));
|
Archives.push_front(_baseLocale);
|
||||||
printf("Using locale: %s\n", Languages[CurLocale]);
|
if (BaseLocale == -1)
|
||||||
|
{
|
||||||
|
printf("No locale data detected\n");
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Using default locale: %s\n", Languages[BaseLocale]);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* MPQManager::GetFile( std::string path )
|
FILE* MPQManager::GetFile( std::string path )
|
||||||
@@ -62,3 +79,31 @@ DBC* MPQManager::GetDBC( std::string name )
|
|||||||
std::string path = "DBFilesClient\\" + name + ".dbc";
|
std::string path = "DBFilesClient\\" + name + ".dbc";
|
||||||
return new DBC(GetFile(path));
|
return new DBC(GetFile(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE* MPQManager::GetFileFrom( std::string path, MPQArchive* file )
|
||||||
|
{
|
||||||
|
ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL);
|
||||||
|
mpq_archive* mpq_a = file->mpq_a;
|
||||||
|
|
||||||
|
uint32_t filenum;
|
||||||
|
if(libmpq__file_number(mpq_a, path.c_str(), &filenum))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
libmpq__off_t transferred;
|
||||||
|
libmpq__off_t size = 0;
|
||||||
|
libmpq__file_unpacked_size(mpq_a, filenum, &size);
|
||||||
|
|
||||||
|
// HACK: in patch.mpq some files don't want to open and give 1 for filesize
|
||||||
|
if (size <= 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uint8* buffer = new uint8[size];
|
||||||
|
|
||||||
|
//libmpq_file_getdata
|
||||||
|
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
|
||||||
|
|
||||||
|
// Pack the return into a FILE stream
|
||||||
|
FILE* ret = tmpfile();
|
||||||
|
fwrite(buffer, sizeof(uint8), size, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ public:
|
|||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
FILE* GetFile(std::string path);
|
FILE* GetFile(std::string path);
|
||||||
|
FILE* GetFileFrom(std::string path, MPQArchive* file);
|
||||||
DBC* GetDBC(std::string name);
|
DBC* GetDBC(std::string name);
|
||||||
|
std::vector<std::string> GetAllFiles(std::string extension);
|
||||||
|
|
||||||
std::deque<MPQArchive*> Archives;
|
std::deque<MPQArchive*> Archives;
|
||||||
uint32 CurLocale;
|
int32 BaseLocale;
|
||||||
|
std::set<uint32> AvailableLocales;
|
||||||
|
std::map<uint32, MPQArchive*> LocaleFiles;
|
||||||
|
|
||||||
static char* Files[];
|
static char* Files[];
|
||||||
static char* Languages[];
|
static char* Languages[];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "ContinentBuilder.h"
|
#include "ContinentBuilder.h"
|
||||||
#include "Cache.h"
|
#include "Cache.h"
|
||||||
#include "DBC.h"
|
#include "DBC.h"
|
||||||
|
#include "Constants.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ LoginDatabaseWorkerPool LoginDatabase;
|
|||||||
MPQManager* MPQHandler;
|
MPQManager* MPQHandler;
|
||||||
CacheClass* Cache;
|
CacheClass* Cache;
|
||||||
|
|
||||||
void ExtractAllMaps(std::set<uint32>& mapIds, uint32 threads, bool debug)
|
void ExtractMMaps(std::set<uint32>& mapIds, uint32 threads, bool debug)
|
||||||
{
|
{
|
||||||
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)
|
||||||
@@ -35,9 +36,45 @@ void ExtractAllMaps(std::set<uint32>& mapIds, uint32 threads, bool debug)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList, bool& debugOutput)
|
void ExtractDBCs()
|
||||||
|
{
|
||||||
|
printf("Extracting DBCs\n");
|
||||||
|
// Create the filesystem structure
|
||||||
|
std::string baseDBCPath = "dbc/";
|
||||||
|
Utils::CreateDir(baseDBCPath);
|
||||||
|
|
||||||
|
// Populate list of DBC files
|
||||||
|
std::set<std::string> DBCFiles;
|
||||||
|
for (std::vector<std::string>::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr)
|
||||||
|
if (itr->rfind(".dbc") == itr->length() - strlen(".dbc"))
|
||||||
|
DBCFiles.insert(*itr);
|
||||||
|
|
||||||
|
// Iterate over all available locales
|
||||||
|
for (std::set<uint32>::iterator itr = MPQHandler->AvailableLocales.begin(); itr != MPQHandler->AvailableLocales.end(); ++itr)
|
||||||
|
{
|
||||||
|
printf("Extracting DBCs for locale %s\n", MPQManager::Languages[*itr]);
|
||||||
|
std::string path = baseDBCPath;
|
||||||
|
if (*itr != MPQHandler->BaseLocale)
|
||||||
|
{
|
||||||
|
path += std::string(MPQManager::Languages[*itr]) + "/";
|
||||||
|
Utils::CreateDir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt";
|
||||||
|
// Extract the component file
|
||||||
|
Utils::SaveToDisk(MPQHandler->GetFile(component), path + component);
|
||||||
|
// Extract the DBC files for the given locale
|
||||||
|
for (std::set<std::string>::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2)
|
||||||
|
Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + strlen("DBFilesClient\\")));
|
||||||
|
}
|
||||||
|
printf("DBC extraction finished!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList, bool& debugOutput, uint32& extractFlags)
|
||||||
{
|
{
|
||||||
char* param = NULL;
|
char* param = NULL;
|
||||||
|
extractFlags = 0;
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
if (strcmp(argv[i], "--threads") == 0)
|
if (strcmp(argv[i], "--threads") == 0)
|
||||||
@@ -49,7 +86,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapLis
|
|||||||
threads = atoi(param);
|
threads = atoi(param);
|
||||||
printf("Using %i threads\n", threads);
|
printf("Using %i threads\n", threads);
|
||||||
}
|
}
|
||||||
if (strcmp(argv[i], "--maps") == 0)
|
else if (strcmp(argv[i], "--maps") == 0)
|
||||||
{
|
{
|
||||||
param = argv[++i];
|
param = argv[++i];
|
||||||
if (!param)
|
if (!param)
|
||||||
@@ -62,14 +99,33 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapLis
|
|||||||
|
|
||||||
printf("Extracting only provided list of maps (%u).\n", mapList.size());
|
printf("Extracting only provided list of maps (%u).\n", mapList.size());
|
||||||
}
|
}
|
||||||
if (strcmp(argv[i], "--debug") == 0)
|
else if (strcmp(argv[i], "--debug") == 0)
|
||||||
{
|
{
|
||||||
param = argv[++i];
|
param = argv[++i];
|
||||||
if (!param)
|
if (!param)
|
||||||
return false;
|
return false;
|
||||||
debugOutput = atoi(param);
|
debugOutput = atoi(param);
|
||||||
|
if (debugOutput)
|
||||||
printf("Output will contain debug information (.obj files)\n");
|
printf("Output will contain debug information (.obj files)\n");
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[i], "--extract") == 0)
|
||||||
|
{
|
||||||
|
param = argv[++i];
|
||||||
|
if (!param)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
extractFlags = atoi(param);
|
||||||
|
|
||||||
|
if (!(extractFlags & Constants::EXTRACT_FLAG_ALLOWED)) // Tried to use an invalid flag
|
||||||
|
return false;
|
||||||
|
|
||||||
|
printf("Detected flags: \n");
|
||||||
|
printf("* Extract DBCs: %s\n", (extractFlags & Constants::EXTRACT_FLAG_DBC) ? "Yes" : "No");
|
||||||
|
printf("* Extract Maps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MAPS) ? "Yes" : "No");
|
||||||
|
printf("* Extract VMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_VMAPS) ? "Yes" : "No");
|
||||||
|
printf("* Extract GameObject Models: %s\n", (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ? "Yes" : "No");
|
||||||
|
printf("* Extract MMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ? "Yes" : "No");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -77,9 +133,17 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapLis
|
|||||||
void PrintUsage()
|
void PrintUsage()
|
||||||
{
|
{
|
||||||
printf("MeshExtractor help.\n");
|
printf("MeshExtractor help.\n");
|
||||||
printf("* Use \"--threads <number>\" to specify <number> threads, default to 4\n");
|
printf("* Use \"--threads <number>\" to specify <number> threads, default to 4 (Only available when extracting MMaps)\n");
|
||||||
printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified ( do not use spaces )\n");
|
printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified (Do not use spaces)\n");
|
||||||
printf("* Use \"--debug 1\" to generate debug information of the tiles.\n");
|
printf("* Use \"--debug 1\" to generate debug information of the tiles (Only available when extracting MMaps)\n");
|
||||||
|
printf("* Use \"--extract X\" to extract the data specified by the flag X (Note: You can combine the flags with the bitwise OR operator |). Available flags are: \n");
|
||||||
|
{
|
||||||
|
printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC);
|
||||||
|
printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS);
|
||||||
|
printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS);
|
||||||
|
printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS);
|
||||||
|
printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@@ -88,16 +152,21 @@ int main(int argc, char* argv[])
|
|||||||
Cache = new CacheClass();
|
Cache = new CacheClass();
|
||||||
MPQHandler = new MPQManager();
|
MPQHandler = new MPQManager();
|
||||||
MPQHandler->Initialize();
|
MPQHandler->Initialize();
|
||||||
uint32 threads = 4;
|
uint32 threads = 4, extractFlags = 0;
|
||||||
std::set<uint32> mapIds;
|
std::set<uint32> mapIds;
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
|
|
||||||
if (!HandleArgs(argc, argv, threads, mapIds, debug))
|
if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags))
|
||||||
{
|
{
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtractAllMaps(mapIds, threads, debug);
|
if (extractFlags & Constants::EXTRACT_FLAG_DBC)
|
||||||
|
ExtractDBCs();
|
||||||
|
|
||||||
|
if (extractFlags & Constants::EXTRACT_FLAG_MMAPS)
|
||||||
|
ExtractMMaps(mapIds, threads, debug);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,9 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome
|
|||||||
Config.walkableSlopeAngle = 50.0f;
|
Config.walkableSlopeAngle = 50.0f;
|
||||||
Config.detailSampleDist = 3.0f;
|
Config.detailSampleDist = 3.0f;
|
||||||
Config.detailSampleMaxError = 1.25f;
|
Config.detailSampleMaxError = 1.25f;
|
||||||
Config.walkableClimb = 1.0f / Config.ch;
|
Config.walkableClimb = floorf(1.0f / Config.ch);
|
||||||
Config.walkableHeight = 1.652778f / Config.ch;
|
Config.walkableHeight = ceilf(1.652778f / Config.ch);
|
||||||
Config.walkableRadius = 0.2951389f / Config.cs;
|
Config.walkableRadius = ceilf(0.2951389f / Config.cs);
|
||||||
Config.maxEdgeLen = Config.walkableRadius * 8;
|
Config.maxEdgeLen = Config.walkableRadius * 8;
|
||||||
Config.borderSize = Config.walkableRadius + 4;
|
Config.borderSize = Config.walkableRadius + 4;
|
||||||
Config.width = 1800 + Config.borderSize * 2;
|
Config.width = 1800 + Config.borderSize * 2;
|
||||||
@@ -39,17 +39,17 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome
|
|||||||
Context = new rcContext;
|
Context = new rcContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax )
|
void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams )
|
||||||
{
|
{
|
||||||
bmin = new float[3];
|
bmin = new float[3];
|
||||||
bmax = new float[3];
|
bmax = new float[3];
|
||||||
bmin[0] = Constants::Origin[0] + (Constants::TileSize * X);
|
bmin[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * X);
|
||||||
bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y);
|
bmin[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * Y);
|
||||||
bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1));
|
bmax[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * (X + 1));
|
||||||
bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1));
|
bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* TileBuilder::Build(bool dbg)
|
uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams)
|
||||||
{
|
{
|
||||||
_Geometry = new Geometry();
|
_Geometry = new Geometry();
|
||||||
_Geometry->Transform = true;
|
_Geometry->Transform = true;
|
||||||
@@ -61,15 +61,10 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty())
|
if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
float* bbMin;
|
|
||||||
float* bbMax;
|
|
||||||
CalculateTileBounds(bbMin, bbMax);
|
|
||||||
_Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]);
|
|
||||||
|
|
||||||
// again, we load everything - wasteful but who cares
|
// again, we load everything - wasteful but who cares
|
||||||
for (int ty = Y - 4; ty <= Y + 4; ty++)
|
for (int ty = Y - 2; ty <= Y + 2; ty++)
|
||||||
{
|
{
|
||||||
for (int tx = X - 4; tx <= X + 4; tx++)
|
for (int tx = X - 2; tx <= X + 2; tx++)
|
||||||
{
|
{
|
||||||
// don't load main tile again
|
// don't load main tile again
|
||||||
if (tx == X && ty == Y)
|
if (tx == X && ty == Y)
|
||||||
@@ -109,13 +104,23 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
_Geometry->Vertices.clear();
|
_Geometry->Vertices.clear();
|
||||||
_Geometry->Triangles.clear();
|
_Geometry->Triangles.clear();
|
||||||
|
|
||||||
bbMin[0] -= Config.borderSize * Config.cs;
|
float bbMin[3];
|
||||||
|
float bbMax[3];
|
||||||
|
// CalculateTileBounds(bbMin, bbMax, navMeshParams);
|
||||||
|
rcCalcBounds(vertices, numVerts, bbMin, bbMax);
|
||||||
|
// _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]);
|
||||||
|
|
||||||
|
/*bbMin[0] -= Config.borderSize * Config.cs;
|
||||||
bbMin[2] -= Config.borderSize * Config.cs;
|
bbMin[2] -= Config.borderSize * Config.cs;
|
||||||
bbMax[0] += Config.borderSize * Config.cs;
|
bbMax[0] += Config.borderSize * Config.cs;
|
||||||
bbMax[0] += Config.borderSize * Config.cs;
|
bbMax[0] += Config.borderSize * Config.cs;*/
|
||||||
|
|
||||||
|
|
||||||
rcHeightfield* hf = rcAllocHeightfield();
|
rcHeightfield* hf = rcAllocHeightfield();
|
||||||
rcCreateHeightfield(Context, *hf, Config.width, Config.height, bbMin, bbMax, Config.cs, Config.ch);
|
int height, width;
|
||||||
|
rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height);
|
||||||
|
printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width);
|
||||||
|
rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch);
|
||||||
rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
|
rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
|
||||||
rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb);
|
rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb);
|
||||||
|
|
||||||
@@ -168,29 +173,31 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
rcFreeCompactHeightfield(chf);
|
rcFreeCompactHeightfield(chf);
|
||||||
rcFreeContourSet(cset);
|
rcFreeContourSet(cset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removed with RecastNavigation v292
|
||||||
// Remove padding from the polymesh data. (Remove this odditity)
|
// Remove padding from the polymesh data. (Remove this odditity)
|
||||||
for (int i = 0; i < pmesh->nverts; ++i)
|
for (int i = 0; i < pmesh->nverts; ++i)
|
||||||
{
|
{
|
||||||
unsigned short* v = &pmesh->verts[i * 3];
|
unsigned short* v = &pmesh->verts[i * 3];
|
||||||
v[0] -= (unsigned short)Config.borderSize;
|
v[0] -= (unsigned short)Config.borderSize;
|
||||||
v[2] -= (unsigned short)Config.borderSize;
|
v[2] -= (unsigned short)Config.borderSize;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Set flags according to area types (e.g. Swim for Water)
|
// Set flags according to area types (e.g. Swim for Water)
|
||||||
for (int i = 0; i < pmesh->npolys; i++)
|
for (int i = 0; i < pmesh->npolys; i++)
|
||||||
{
|
{
|
||||||
if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN)
|
if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN)
|
||||||
pmesh->flags[i] = Constants::POLY_FLAG_WALK;
|
pmesh->flags[i] = Constants::POLY_FLAG_WALK;
|
||||||
else if (pmesh->areas[i] == (int)Constants::POLY_AREA_WATER)
|
else if (pmesh->areas[i] == Constants::POLY_AREA_WATER)
|
||||||
pmesh->flags[i] = Constants::POLY_FLAG_SWIM;
|
pmesh->flags[i] = Constants::POLY_FLAG_SWIM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get original bounds
|
// get original bounds
|
||||||
float* tilebMin;
|
/*float* tilebMin;
|
||||||
float* tilebMax;
|
float* tilebMax;
|
||||||
CalculateTileBounds(tilebMin, tilebMax);
|
CalculateTileBounds(tilebMin, tilebMax, navMeshParams);
|
||||||
tilebMin[1] = bbMin[1];
|
tilebMin[1] = bbMin[1];
|
||||||
tilebMax[1] = bbMax[1];
|
tilebMax[1] = bbMax[1];*/
|
||||||
|
|
||||||
dtNavMeshCreateParams params;
|
dtNavMeshCreateParams params;
|
||||||
// PolyMesh data
|
// PolyMesh data
|
||||||
@@ -208,12 +215,14 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
params.detailTris = dmesh->tris;
|
params.detailTris = dmesh->tris;
|
||||||
params.detailTriCount = dmesh->ntris;
|
params.detailTriCount = dmesh->ntris;
|
||||||
// Copy bounding box
|
// Copy bounding box
|
||||||
params.bmin[0] = tilebMin[0];
|
/*params.bmin[0] = tilebMin[0];
|
||||||
params.bmin[1] = tilebMin[1];
|
params.bmin[1] = tilebMin[1];
|
||||||
params.bmin[2] = tilebMin[2];
|
params.bmin[2] = tilebMin[2];
|
||||||
params.bmax[0] = tilebMax[0];
|
params.bmax[0] = tilebMax[0];
|
||||||
params.bmax[1] = tilebMax[1];
|
params.bmax[1] = tilebMax[1];
|
||||||
params.bmax[2] = tilebMax[2];
|
params.bmax[2] = tilebMax[2];*/
|
||||||
|
rcVcopy(params.bmin, pmesh->bmin);
|
||||||
|
rcVcopy(params.bmax, pmesh->bmax);
|
||||||
// General settings
|
// General settings
|
||||||
params.ch = Config.ch;
|
params.ch = Config.ch;
|
||||||
params.cs = Config.cs;
|
params.cs = Config.cs;
|
||||||
@@ -222,7 +231,11 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
params.walkableRadius = Config.walkableRadius;
|
params.walkableRadius = Config.walkableRadius;
|
||||||
params.tileX = X;
|
params.tileX = X;
|
||||||
params.tileY = Y;
|
params.tileY = Y;
|
||||||
params.tileSize = 1800;
|
int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize;
|
||||||
|
int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize;
|
||||||
|
printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]);
|
||||||
|
params.buildBvTree = true;
|
||||||
|
params.tileLayer = 0;
|
||||||
|
|
||||||
// Offmesh-connection settings
|
// Offmesh-connection settings
|
||||||
params.offMeshConCount = 0; // none for now
|
params.offMeshConCount = 0; // none for now
|
||||||
@@ -235,13 +248,13 @@ uint8* TileBuilder::Build(bool dbg)
|
|||||||
// Free some memory
|
// Free some memory
|
||||||
rcFreePolyMesh(pmesh);
|
rcFreePolyMesh(pmesh);
|
||||||
rcFreePolyMeshDetail(dmesh);
|
rcFreePolyMeshDetail(dmesh);
|
||||||
delete tilebMax;
|
//delete tilebMax;
|
||||||
delete tilebMin;
|
//delete tilebMin;
|
||||||
delete areas;
|
delete areas;
|
||||||
delete triangles;
|
delete triangles;
|
||||||
delete vertices;
|
delete vertices;
|
||||||
delete bbMax;
|
//delete bbMax;
|
||||||
delete bbMin;
|
//delete bbMin;
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ public:
|
|||||||
TileBuilder(std::string world, int x, int y, uint32 mapId);
|
TileBuilder(std::string world, int x, int y, uint32 mapId);
|
||||||
~TileBuilder();
|
~TileBuilder();
|
||||||
|
|
||||||
void CalculateTileBounds(float*& bmin, float*& bmax);
|
void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams);
|
||||||
uint8* Build(bool dbg);
|
uint8* Build(bool dbg, dtNavMeshParams& navMeshParams);
|
||||||
|
|
||||||
std::string World;
|
std::string World;
|
||||||
int X;
|
int X;
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
#include "G3D/Matrix4.h"
|
#include "G3D/Matrix4.h"
|
||||||
#include "G3D/Quat.h"
|
#include "G3D/Quat.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "direct.h"
|
||||||
|
#else
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
const float Constants::TileSize = 533.0f + (1/3.0f);
|
const float Constants::TileSize = 533.0f + (1/3.0f);
|
||||||
const float Constants::MaxXY = 32.0f * Constants::TileSize;
|
const float Constants::MaxXY = 32.0f * Constants::TileSize;
|
||||||
const float Constants::ChunkSize = Constants::TileSize / 16.0f;
|
const float Constants::ChunkSize = Constants::TileSize / 16.0f;
|
||||||
@@ -13,6 +20,15 @@ const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }
|
|||||||
const float Constants::PI = 3.1415926f;
|
const float Constants::PI = 3.1415926f;
|
||||||
const float Constants::MaxStandableHeight = 1.5f;
|
const float Constants::MaxStandableHeight = 1.5f;
|
||||||
|
|
||||||
|
void Utils::CreateDir( const std::string& Path )
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
_mkdir( Path.c_str());
|
||||||
|
#else
|
||||||
|
mkdir( Path.c_str(), 0777 );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Utils::Reverse(char word[])
|
void Utils::Reverse(char word[])
|
||||||
{
|
{
|
||||||
int len = strlen(word);
|
int len = strlen(word);
|
||||||
@@ -181,6 +197,28 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD
|
|||||||
return scale * rotation * quatRotation ** translation * rootTransformation;
|
return scale * rotation * quatRotation ** translation * rootTransformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::SaveToDisk( FILE* stream, std::string path )
|
||||||
|
{
|
||||||
|
FILE* disk = fopen(path.c_str(), "wb");
|
||||||
|
if (!disk)
|
||||||
|
{
|
||||||
|
printf("Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 size = Utils::Size(stream);
|
||||||
|
uint8* data = new uint8[size];
|
||||||
|
// Read the data to an array
|
||||||
|
fread(data, 1, size, stream);
|
||||||
|
// And write it in the file
|
||||||
|
fwrite(data, 1, size, disk);
|
||||||
|
|
||||||
|
// Close the filestream
|
||||||
|
fclose(disk);
|
||||||
|
// Free the used memory
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
void MapChunkHeader::Read(FILE* stream)
|
void MapChunkHeader::Read(FILE* stream)
|
||||||
{
|
{
|
||||||
fread(&Flags, sizeof(uint32), 1, stream);
|
fread(&Flags, sizeof(uint32), 1, stream);
|
||||||
|
|||||||
@@ -349,5 +349,7 @@ public:
|
|||||||
}
|
}
|
||||||
static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr );
|
static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr );
|
||||||
static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root );
|
static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root );
|
||||||
|
static void CreateDir( const std::string& Path );
|
||||||
|
static void SaveToDisk(FILE* stream, std::string path);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -36,7 +36,7 @@ void WorldModelGroup::ReadNormals()
|
|||||||
ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count");
|
ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count");
|
||||||
Normals.reserve(normalCount);
|
Normals.reserve(normalCount);
|
||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
for (int i = 0; i < normalCount; i++)
|
for (uint32 i = 0; i < normalCount; i++)
|
||||||
Normals[i] = Vector3::Read(stream);
|
Normals[i] = Vector3::Read(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ void WorldModelGroup::ReadVertices()
|
|||||||
uint32 verticeCount = chunk->Length / 12;
|
uint32 verticeCount = chunk->Length / 12;
|
||||||
Vertices.reserve(verticeCount);
|
Vertices.reserve(verticeCount);
|
||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
for (int i = 0; i < verticeCount; i++)
|
for (uint32 i = 0; i < verticeCount; i++)
|
||||||
Vertices.push_back(Vector3::Read(stream));
|
Vertices.push_back(Vector3::Read(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ void WorldModelGroup::ReadTriangles()
|
|||||||
ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()");
|
ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()");
|
||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
Triangles.reserve(triangleCount);
|
Triangles.reserve(triangleCount);
|
||||||
for (int i = 0; i < triangleCount; i++)
|
for (uint32 i = 0; i < triangleCount; i++)
|
||||||
{
|
{
|
||||||
uint16 v0;
|
uint16 v0;
|
||||||
uint16 v1;
|
uint16 v1;
|
||||||
@@ -97,7 +97,7 @@ void WorldModelGroup::ReadMaterials()
|
|||||||
uint32 triangleCount = chunk->Length / 2;
|
uint32 triangleCount = chunk->Length / 2;
|
||||||
TriangleFlags.reserve(triangleCount);
|
TriangleFlags.reserve(triangleCount);
|
||||||
TriangleMaterials.reserve(triangleCount);
|
TriangleMaterials.reserve(triangleCount);
|
||||||
for (int i = 0; i < triangleCount; i++)
|
for (uint32 i = 0; i < triangleCount; i++)
|
||||||
{
|
{
|
||||||
uint8 tmp;
|
uint8 tmp;
|
||||||
fread(&tmp, sizeof(uint8), 1, stream);
|
fread(&tmp, sizeof(uint8), 1, stream);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks )
|
|||||||
int32 index;
|
int32 index;
|
||||||
fread(&index, sizeof(int32), 1, stream);
|
fread(&index, sizeof(int32), 1, stream);
|
||||||
|
|
||||||
if (index < 0 || index >= _definitions->size())
|
if (index < 0 || uint32(index) >= _definitions->size())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
WorldModelDefinition wmo = (*_definitions)[index];
|
WorldModelDefinition wmo = (*_definitions)[index];
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ void WorldModelRoot::ReadGroups()
|
|||||||
{
|
{
|
||||||
std::string pathBase = Utils::GetPathBase(Path);
|
std::string pathBase = Utils::GetPathBase(Path);
|
||||||
Groups.reserve(Header.CountGroups);
|
Groups.reserve(Header.CountGroups);
|
||||||
for (int i = 0; i < Header.CountGroups; i++)
|
for (uint32 i = 0; i < Header.CountGroups; i++)
|
||||||
{
|
{
|
||||||
char name[200];
|
char name[200];
|
||||||
sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i);
|
sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i);
|
||||||
@@ -35,7 +35,7 @@ void WorldModelRoot::ReadDoodadSets()
|
|||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets");
|
ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets");
|
||||||
DoodadSets.reserve(Header.CountSets);
|
DoodadSets.reserve(Header.CountSets);
|
||||||
for (int i = 0; i < Header.CountSets; i++)
|
for (uint32 i = 0; i < Header.CountSets; i++)
|
||||||
DoodadSets.push_back(DoodadSet::Read(stream));
|
DoodadSets.push_back(DoodadSet::Read(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ void WorldModelRoot::ReadDoodadInstances()
|
|||||||
const uint32 instanceSize = 40;
|
const uint32 instanceSize = 40;
|
||||||
uint32 countInstances = chunk->Length / instanceSize;
|
uint32 countInstances = chunk->Length / instanceSize;
|
||||||
DoodadInstances.reserve(countInstances);
|
DoodadInstances.reserve(countInstances);
|
||||||
for (int i = 0; i < countInstances; i++)
|
for (uint32 i = 0; i < countInstances; i++)
|
||||||
{
|
{
|
||||||
FILE* stream = chunk->GetStream();
|
FILE* stream = chunk->GetStream();
|
||||||
fseek(stream, instanceSize * i, SEEK_CUR);
|
fseek(stream, instanceSize * i, SEEK_CUR);
|
||||||
|
|||||||
Reference in New Issue
Block a user