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:
Subv
2012-10-03 18:02:18 -05:00
parent fa57ecddac
commit e32ddea96a
17 changed files with 264 additions and 75 deletions

View File

@@ -48,7 +48,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint )
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)
return i;
return -1;
@@ -56,7 +56,7 @@ int ChunkedData::GetFirstIndex( 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)
return Chunks[i];
return NULL;

View File

@@ -29,6 +29,17 @@ public:
POLY_FLAG_SWIM = 2,
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 MaxXY;
static const float ChunkSize;

View File

@@ -13,8 +13,9 @@ private:
int X, Y, MapId;
std::string Continent;
bool debug;
dtNavMeshParams Params;
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; }
int svc()
@@ -32,7 +33,7 @@ public:
Free = true;
return 0;
}
uint8* nav = builder.Build(debug);
uint8* nav = builder.Build(debug, Params);
if (nav)
{
f = fopen(buff, "wb");
@@ -101,14 +102,17 @@ void ContinentBuilder::Build(bool debug)
dtNavMeshParams params;
params.maxPolys = 32768;
params.maxTiles = TileMap->TileTable.size();
rcVcopy(params.orig, bmin);
params.tileHeight = 533.33333f;
params.tileWidth = 533.33333f;
// rcVcopy(params.orig, bmin);
params.orig[0] = Constants::Origin[0];
params.orig[1] = 0;
params.orig[2] = Constants::Origin[2];
params.tileHeight = Constants::TileSize;
params.tileWidth = Constants::TileSize;
fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
fclose(mmap);
std::vector<BuilderThread*> Threads;
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);
for (std::vector<TilePos>::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr)
{

View File

@@ -31,7 +31,7 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks )
{
int32 index;
fread(&index, sizeof(int32), 1, stream);
if (index < 0 || index >= _definitions->size())
if (index < 0 || uint32(index) >= _definitions->size())
continue;
DoodadDefinition doodad = (*_definitions)[index];
if (_drawn.find(doodad.UniqueId) != _drawn.end())

View File

@@ -34,10 +34,10 @@ void LiquidHandler::HandleNewLiquid()
H2OInformation information = H2OInformation::Read(stream);
float** heights = new float*[9];
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++i)
{
heights[i] = new float[9];
memset(heights[i], 0, sizeof(float) * 9);
heights[j] = new float[9];
memset(heights[j], 0, sizeof(float) * 9);
}
H2ORenderMask renderMask;
@@ -52,7 +52,7 @@ void LiquidHandler::HandleNewLiquid()
uint8* altMask = new uint8[size];
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];
delete[] altMask;
}

View File

@@ -31,6 +31,7 @@ MPQArchive::MPQArchive(const char* filename)
break;
}
}
GetFileListTo(Files);
}
void MPQArchive::close()

View File

@@ -16,6 +16,8 @@ class MPQArchive
public:
mpq_archive_s *mpq_a;
vector<string> Files;
MPQArchive(const char* filename);
void close();

View File

@@ -15,7 +15,7 @@ char* MPQManager::Files[] = {
"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()
{
@@ -31,21 +31,38 @@ void MPQManager::Initialize()
void MPQManager::InitializeDBC()
{
CurLocale = 0;
BaseLocale = -1;
std::string fileName;
uint32 size = sizeof(Languages) / sizeof(char*);
MPQArchive* _baseLocale = NULL;
for (uint32 i = 0; i < size; ++i)
{
fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ";
FILE* file = fopen(fileName.c_str(), "rb");
std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ";
FILE* file = fopen(_fileName.c_str(), "rb");
if (file)
{
CurLocale = i;
break;
if (BaseLocale == -1)
{
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()));
printf("Using locale: %s\n", Languages[CurLocale]);
Archives.push_front(_baseLocale);
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 )
@@ -62,3 +79,31 @@ DBC* MPQManager::GetDBC( std::string name )
std::string path = "DBFilesClient\\" + name + ".dbc";
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;
}

View File

@@ -13,10 +13,14 @@ public:
void Initialize();
FILE* GetFile(std::string path);
FILE* GetFileFrom(std::string path, MPQArchive* file);
DBC* GetDBC(std::string name);
std::vector<std::string> GetAllFiles(std::string extension);
std::deque<MPQArchive*> Archives;
uint32 CurLocale;
int32 BaseLocale;
std::set<uint32> AvailableLocales;
std::map<uint32, MPQArchive*> LocaleFiles;
static char* Files[];
static char* Languages[];

View File

@@ -3,6 +3,7 @@
#include "ContinentBuilder.h"
#include "Cache.h"
#include "DBC.h"
#include "Constants.h"
#include <set>
@@ -14,7 +15,7 @@ LoginDatabaseWorkerPool LoginDatabase;
MPQManager* MPQHandler;
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");
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;
extractFlags = 0;
for (int i = 1; i < argc; ++i)
{
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);
printf("Using %i threads\n", threads);
}
if (strcmp(argv[i], "--maps") == 0)
else if (strcmp(argv[i], "--maps") == 0)
{
param = argv[++i];
if (!param)
@@ -62,13 +99,32 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapLis
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];
if (!param)
return false;
debugOutput = atoi(param);
printf("Output will contain debug information (.obj files)\n");
if (debugOutput)
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;
@@ -77,9 +133,17 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapLis
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");
printf("* Use \"--debug 1\" to generate debug information of the tiles.\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 \"--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[])
@@ -88,16 +152,21 @@ int main(int argc, char* argv[])
Cache = new CacheClass();
MPQHandler = new MPQManager();
MPQHandler->Initialize();
uint32 threads = 4;
uint32 threads = 4, extractFlags = 0;
std::set<uint32> mapIds;
bool debug = false;
if (!HandleArgs(argc, argv, threads, mapIds, debug))
if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags))
{
PrintUsage();
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;
}

View File

@@ -26,9 +26,9 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome
Config.walkableSlopeAngle = 50.0f;
Config.detailSampleDist = 3.0f;
Config.detailSampleMaxError = 1.25f;
Config.walkableClimb = 1.0f / Config.ch;
Config.walkableHeight = 1.652778f / Config.ch;
Config.walkableRadius = 0.2951389f / Config.cs;
Config.walkableClimb = floorf(1.0f / Config.ch);
Config.walkableHeight = ceilf(1.652778f / Config.ch);
Config.walkableRadius = ceilf(0.2951389f / Config.cs);
Config.maxEdgeLen = Config.walkableRadius * 8;
Config.borderSize = Config.walkableRadius + 4;
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;
}
void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax )
void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams )
{
bmin = new float[3];
bmax = new float[3];
bmin[0] = Constants::Origin[0] + (Constants::TileSize * X);
bmin[2] = Constants::Origin[2] + (Constants::TileSize * Y);
bmax[0] = Constants::Origin[0] + (Constants::TileSize * (X + 1));
bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1));
bmin[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * X);
bmin[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * Y);
bmax[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * (X + 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->Transform = true;
@@ -61,15 +61,10 @@ uint8* TileBuilder::Build(bool dbg)
if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty())
return NULL;
float* bbMin;
float* bbMax;
CalculateTileBounds(bbMin, bbMax);
_Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]);
// 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
if (tx == X && ty == Y)
@@ -109,13 +104,23 @@ uint8* TileBuilder::Build(bool dbg)
_Geometry->Vertices.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;
bbMax[0] += Config.borderSize * Config.cs;
bbMax[0] += Config.borderSize * Config.cs;
bbMax[0] += Config.borderSize * Config.cs;*/
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);
rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb);
@@ -168,29 +173,31 @@ uint8* TileBuilder::Build(bool dbg)
rcFreeCompactHeightfield(chf);
rcFreeContourSet(cset);
/*
* Removed with RecastNavigation v292
// Remove padding from the polymesh data. (Remove this odditity)
for (int i = 0; i < pmesh->nverts; ++i)
{
unsigned short* v = &pmesh->verts[i * 3];
v[0] -= (unsigned short)Config.borderSize;
v[2] -= (unsigned short)Config.borderSize;
}
}*/
// Set flags according to area types (e.g. Swim for Water)
for (int i = 0; i < pmesh->npolys; i++)
{
if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN)
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;
}
// get original bounds
float* tilebMin;
/*float* tilebMin;
float* tilebMax;
CalculateTileBounds(tilebMin, tilebMax);
CalculateTileBounds(tilebMin, tilebMax, navMeshParams);
tilebMin[1] = bbMin[1];
tilebMax[1] = bbMax[1];
tilebMax[1] = bbMax[1];*/
dtNavMeshCreateParams params;
// PolyMesh data
@@ -208,12 +215,14 @@ uint8* TileBuilder::Build(bool dbg)
params.detailTris = dmesh->tris;
params.detailTriCount = dmesh->ntris;
// Copy bounding box
params.bmin[0] = tilebMin[0];
/*params.bmin[0] = tilebMin[0];
params.bmin[1] = tilebMin[1];
params.bmin[2] = tilebMin[2];
params.bmax[0] = tilebMax[0];
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
params.ch = Config.ch;
params.cs = Config.cs;
@@ -222,7 +231,11 @@ uint8* TileBuilder::Build(bool dbg)
params.walkableRadius = Config.walkableRadius;
params.tileX = X;
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
params.offMeshConCount = 0; // none for now
@@ -235,13 +248,13 @@ uint8* TileBuilder::Build(bool dbg)
// Free some memory
rcFreePolyMesh(pmesh);
rcFreePolyMeshDetail(dmesh);
delete tilebMax;
delete tilebMin;
//delete tilebMax;
//delete tilebMin;
delete areas;
delete triangles;
delete vertices;
delete bbMax;
delete bbMin;
//delete bbMax;
//delete bbMin;
if (result)
{

View File

@@ -13,8 +13,8 @@ public:
TileBuilder(std::string world, int x, int y, uint32 mapId);
~TileBuilder();
void CalculateTileBounds(float*& bmin, float*& bmax);
uint8* Build(bool dbg);
void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams);
uint8* Build(bool dbg, dtNavMeshParams& navMeshParams);
std::string World;
int X;

View File

@@ -5,6 +5,13 @@
#include "G3D/Matrix4.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::MaxXY = 32.0f * Constants::TileSize;
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::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[])
{
int len = strlen(word);
@@ -181,6 +197,28 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD
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)
{
fread(&Flags, sizeof(uint32), 1, stream);

View File

@@ -349,5 +349,7 @@ public:
}
static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr );
static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root );
static void CreateDir( const std::string& Path );
static void SaveToDisk(FILE* stream, std::string path);
};
#endif

View File

@@ -36,7 +36,7 @@ void WorldModelGroup::ReadNormals()
ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count");
Normals.reserve(normalCount);
FILE* stream = chunk->GetStream();
for (int i = 0; i < normalCount; i++)
for (uint32 i = 0; i < normalCount; i++)
Normals[i] = Vector3::Read(stream);
}
@@ -61,7 +61,7 @@ void WorldModelGroup::ReadVertices()
uint32 verticeCount = chunk->Length / 12;
Vertices.reserve(verticeCount);
FILE* stream = chunk->GetStream();
for (int i = 0; i < verticeCount; i++)
for (uint32 i = 0; i < verticeCount; i++)
Vertices.push_back(Vector3::Read(stream));
}
@@ -75,7 +75,7 @@ void WorldModelGroup::ReadTriangles()
ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()");
FILE* stream = chunk->GetStream();
Triangles.reserve(triangleCount);
for (int i = 0; i < triangleCount; i++)
for (uint32 i = 0; i < triangleCount; i++)
{
uint16 v0;
uint16 v1;
@@ -97,7 +97,7 @@ void WorldModelGroup::ReadMaterials()
uint32 triangleCount = chunk->Length / 2;
TriangleFlags.reserve(triangleCount);
TriangleMaterials.reserve(triangleCount);
for (int i = 0; i < triangleCount; i++)
for (uint32 i = 0; i < triangleCount; i++)
{
uint8 tmp;
fread(&tmp, sizeof(uint8), 1, stream);

View File

@@ -46,7 +46,7 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks )
int32 index;
fread(&index, sizeof(int32), 1, stream);
if (index < 0 || index >= _definitions->size())
if (index < 0 || uint32(index) >= _definitions->size())
continue;
WorldModelDefinition wmo = (*_definitions)[index];

View File

@@ -16,7 +16,7 @@ void WorldModelRoot::ReadGroups()
{
std::string pathBase = Utils::GetPathBase(Path);
Groups.reserve(Header.CountGroups);
for (int i = 0; i < Header.CountGroups; i++)
for (uint32 i = 0; i < Header.CountGroups; i++)
{
char name[200];
sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i);
@@ -35,7 +35,7 @@ void WorldModelRoot::ReadDoodadSets()
FILE* stream = chunk->GetStream();
ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == 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));
}
@@ -49,7 +49,7 @@ void WorldModelRoot::ReadDoodadInstances()
const uint32 instanceSize = 40;
uint32 countInstances = chunk->Length / instanceSize;
DoodadInstances.reserve(countInstances);
for (int i = 0; i < countInstances; i++)
for (uint32 i = 0; i < countInstances; i++)
{
FILE* stream = chunk->GetStream();
fseek(stream, instanceSize * i, SEEK_CUR);