mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 10:05:32 +01:00
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 )
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¶ms, 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)
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ MPQArchive::MPQArchive(const char* filename)
|
||||
break;
|
||||
}
|
||||
}
|
||||
GetFileListTo(Files);
|
||||
}
|
||||
|
||||
void MPQArchive::close()
|
||||
|
||||
@@ -16,6 +16,8 @@ class MPQArchive
|
||||
|
||||
public:
|
||||
mpq_archive_s *mpq_a;
|
||||
|
||||
vector<string> Files;
|
||||
|
||||
MPQArchive(const char* filename);
|
||||
void close();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user