mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 01:15:35 +01:00
Tools/MeshExtractor:
* Added the option to output debug information on ADTs. * Tweaked rcConfig options and fixed some mistakes about it. * Generate 64 tiles per ADT, this should give us a more accurate mesh on large maps. * Speedup compilation time by moving function bodies from Utils.h to Utils.cpp
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
#include "DoodadHandler.h"
|
||||
#include "LiquidHandler.h"
|
||||
#include "WorldModelHandler.h"
|
||||
#include "Cache.h"
|
||||
|
||||
ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), HasObjectData(false)
|
||||
{
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
#include "ace/Task.h"
|
||||
#include "Recast.h"
|
||||
|
||||
class BuilderThread : public ACE_Task<ACE_MT_SYNCH>
|
||||
class BuilderThread : public ACE_Task_Base
|
||||
{
|
||||
private:
|
||||
int X, Y, MapId;
|
||||
std::string Continent;
|
||||
bool debug;
|
||||
public:
|
||||
BuilderThread() : Free(true) {}
|
||||
BuilderThread(bool deb) : Free(true), debug(deb) {}
|
||||
void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; }
|
||||
|
||||
int svc()
|
||||
@@ -22,23 +23,23 @@ public:
|
||||
printf("[%02i,%02i] Building tile\n", X, Y);
|
||||
TileBuilder builder(Continent, X, Y, MapId);
|
||||
char buff[100];
|
||||
sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, X, Y);
|
||||
sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X);
|
||||
FILE* f = fopen(buff, "r");
|
||||
if (f) // Check if file already exists.
|
||||
{
|
||||
printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y);
|
||||
fclose(f);
|
||||
Free = true;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
uint8* nav = builder.Build();
|
||||
uint8* nav = builder.Build(debug);
|
||||
if (nav)
|
||||
{
|
||||
f = fopen(buff, "wb");
|
||||
if (!f)
|
||||
{
|
||||
printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
MmapTileHeader header;
|
||||
header.size = builder.DataSize;
|
||||
@@ -73,7 +74,7 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa
|
||||
bmin[2] = bmax[2] - Constants::TileSize;
|
||||
}
|
||||
|
||||
void ContinentBuilder::Build()
|
||||
void ContinentBuilder::Build(bool debug)
|
||||
{
|
||||
char buff[50];
|
||||
sprintf(buff, "mmaps/%03u.mmap", MapId);
|
||||
@@ -107,7 +108,7 @@ void ContinentBuilder::Build()
|
||||
fclose(mmap);
|
||||
std::vector<BuilderThread*> Threads;
|
||||
for (uint32 i = 0; i < NumberOfThreads; ++i)
|
||||
Threads.push_back(new BuilderThread());
|
||||
Threads.push_back(new BuilderThread(debug));
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ class ContinentBuilder
|
||||
{
|
||||
public:
|
||||
ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {}
|
||||
void Build();
|
||||
void Build(bool debug);
|
||||
private:
|
||||
std::string Continent;
|
||||
WDT* TileMap;
|
||||
|
||||
@@ -14,7 +14,7 @@ LoginDatabaseWorkerPool LoginDatabase;
|
||||
MPQManager* MPQHandler;
|
||||
CacheClass* Cache;
|
||||
|
||||
void ExtractAllMaps(std::set<uint32>& mapIds, uint32 threads)
|
||||
void ExtractAllMaps(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)
|
||||
@@ -31,11 +31,11 @@ void ExtractAllMaps(std::set<uint32>& mapIds, uint32 threads)
|
||||
continue;
|
||||
printf("Building %s MapId %u\n", name.c_str(), mapId);
|
||||
ContinentBuilder builder(name, mapId, &wdt, threads);
|
||||
builder.Build();
|
||||
builder.Build(debug);
|
||||
}
|
||||
}
|
||||
|
||||
bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList)
|
||||
bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList, bool& debugOutput)
|
||||
{
|
||||
char* param = NULL;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
@@ -62,6 +62,14 @@ 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)
|
||||
{
|
||||
param = argv[++i];
|
||||
if (!param)
|
||||
return false;
|
||||
debugOutput = atoi(param);
|
||||
printf("Output will contain debug information (.obj files)\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -71,6 +79,7 @@ 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");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
@@ -81,14 +90,14 @@ int main(int argc, char* argv[])
|
||||
MPQHandler->Initialize();
|
||||
uint32 threads = 4;
|
||||
std::set<uint32> mapIds;
|
||||
bool debug = false;
|
||||
|
||||
if (!HandleArgs(argc, argv, threads, mapIds))
|
||||
if (!HandleArgs(argc, argv, threads, mapIds, debug))
|
||||
{
|
||||
PrintUsage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
ExtractAllMaps(mapIds, threads);
|
||||
ExtractAllMaps(mapIds, threads, debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,20 +17,22 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome
|
||||
// 1800 = TileVoxelSize
|
||||
Config.cs = Constants::TileSize / 1800;
|
||||
// Cell Height
|
||||
Config.ch = 0.3f;
|
||||
// Min Region Area = 6^2
|
||||
Config.minRegionArea = 36;
|
||||
// Merge Region Area = 12^2
|
||||
Config.mergeRegionArea = 144;
|
||||
Config.ch = 0.4f;
|
||||
// Min Region Area = 20^2
|
||||
Config.minRegionArea = 20*20;
|
||||
// Merge Region Area = 40^2
|
||||
Config.mergeRegionArea = 40*40;
|
||||
Config.tileSize = Constants::TileSize / 4;
|
||||
Config.walkableSlopeAngle = 50.0f;
|
||||
Config.detailSampleDist = 3.0f;
|
||||
Config.detailSampleMaxError = 1.25f;
|
||||
Config.walkableClimb = 1.0f / Config.ch;
|
||||
Config.walkableHeight = 2.1f / Config.ch;
|
||||
Config.walkableRadius = 0.6f / Config.cs;
|
||||
Config.walkableHeight = 1.652778f / Config.ch;
|
||||
Config.walkableRadius = 0.2951389f / Config.cs;
|
||||
Config.maxEdgeLen = Config.walkableRadius * 8;
|
||||
Config.borderSize = Config.walkableRadius + 8;
|
||||
Config.width = 1800;
|
||||
Config.borderSize = Config.walkableRadius + 4;
|
||||
Config.width = 1800 + Config.borderSize * 2;
|
||||
Config.height = 1800 + Config.borderSize * 2;
|
||||
Config.maxVertsPerPoly = 6;
|
||||
Config.maxSimplificationError = 1.3f;
|
||||
|
||||
@@ -47,7 +49,7 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax )
|
||||
bmax[2] = Constants::Origin[2] + (Constants::TileSize * (Y + 1));
|
||||
}
|
||||
|
||||
uint8* TileBuilder::Build()
|
||||
uint8* TileBuilder::Build(bool dbg)
|
||||
{
|
||||
_Geometry = new Geometry();
|
||||
_Geometry->Transform = true;
|
||||
@@ -65,9 +67,9 @@ uint8* TileBuilder::Build()
|
||||
_Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]);
|
||||
|
||||
// again, we load everything - wasteful but who cares
|
||||
for (int ty = Y - 1; ty <= Y + 1; ty++)
|
||||
for (int ty = Y - 4; ty <= Y + 4; ty++)
|
||||
{
|
||||
for (int tx = X - 1; tx <= X + 1; tx++)
|
||||
for (int tx = X - 4; tx <= X + 4; tx++)
|
||||
{
|
||||
// don't load main tile again
|
||||
if (tx == X && ty == Y)
|
||||
@@ -85,6 +87,19 @@ uint8* TileBuilder::Build()
|
||||
delete _adt;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbg)
|
||||
{
|
||||
char buff[100];
|
||||
sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X);
|
||||
FILE* debug = fopen(buff, "wb");
|
||||
for (int i = 0; i < _Geometry->Vertices.size(); ++i)
|
||||
fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z);
|
||||
for (int i = 0; i < _Geometry->Triangles.size(); ++i)
|
||||
fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1);
|
||||
fclose(debug);
|
||||
}
|
||||
|
||||
uint32 numVerts = _Geometry->Vertices.size();
|
||||
uint32 numTris = _Geometry->Triangles.size();
|
||||
float* vertices;
|
||||
@@ -100,8 +115,7 @@ uint8* TileBuilder::Build()
|
||||
bbMax[0] += Config.borderSize * Config.cs;
|
||||
|
||||
rcHeightfield* hf = rcAllocHeightfield();
|
||||
int width = Config.width + (Config.borderSize * 2);
|
||||
rcCreateHeightfield(Context, *hf, width, width, bbMin, bbMax, Config.cs, Config.ch);
|
||||
rcCreateHeightfield(Context, *hf, Config.width, Config.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);
|
||||
|
||||
@@ -208,14 +222,14 @@ uint8* TileBuilder::Build()
|
||||
params.walkableRadius = Config.walkableRadius;
|
||||
params.tileX = X;
|
||||
params.tileY = Y;
|
||||
params.tileSize = Config.width;
|
||||
params.tileSize = 1800;
|
||||
|
||||
// Offmesh-connection settings
|
||||
params.offMeshConCount = 0; // none for now
|
||||
|
||||
int navDataSize;
|
||||
uint8* navData;
|
||||
printf("[%02i,%02i] Creating the navmesh!\n", X, Y);
|
||||
printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris);
|
||||
bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize);
|
||||
|
||||
// Free some memory
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
~TileBuilder();
|
||||
|
||||
void CalculateTileBounds(float*& bmin, float*& bmax);
|
||||
uint8* Build();
|
||||
uint8* Build(bool dbg);
|
||||
|
||||
std::string World;
|
||||
int X;
|
||||
|
||||
@@ -180,3 +180,253 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD
|
||||
|
||||
return scale * rotation * quatRotation ** translation * rootTransformation;
|
||||
}
|
||||
|
||||
void MapChunkHeader::Read(FILE* stream)
|
||||
{
|
||||
fread(&Flags, sizeof(uint32), 1, stream);
|
||||
fread(&IndexX, sizeof(uint32), 1, stream);
|
||||
fread(&IndexY, sizeof(uint32), 1, stream);
|
||||
fread(&Layers, sizeof(uint32), 1, stream);
|
||||
fread(&DoodadRefs, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCVT, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCNR, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCLY, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCRF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCAL, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCAL, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCSH, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCSH, sizeof(uint32), 1, stream);
|
||||
fread(&AreaId, sizeof(uint32), 1, stream);
|
||||
fread(&MapObjectRefs, sizeof(uint32), 1, stream);
|
||||
fread(&Holes, sizeof(uint32), 1, stream);
|
||||
LowQualityTextureMap = new uint32[4];
|
||||
fread(LowQualityTextureMap, sizeof(uint32), 4, stream);
|
||||
fread(&PredTex, sizeof(uint32), 1, stream);
|
||||
fread(&NumberEffectDoodad, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCSE, sizeof(uint32), 1, stream);
|
||||
fread(&SoundEmitters, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCLQ, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCLQ, sizeof(uint32), 1, stream);
|
||||
Position = Vector3::Read(stream);
|
||||
fread(&OffsetMCCV, sizeof(uint32), 1, stream);
|
||||
}
|
||||
|
||||
void MHDR::Read(FILE* stream)
|
||||
{
|
||||
fread(&Flags, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCIN, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMTEX, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMMDX, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMMID, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMWMO, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMWID, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMDDF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMODF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMFBO, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMH2O, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMTFX, sizeof(uint32), 1, stream);
|
||||
}
|
||||
|
||||
void ModelHeader::Read(FILE* stream)
|
||||
{
|
||||
fread(&Magic, sizeof(char), 4, stream);
|
||||
Magic[4] = '\0'; // null-terminate it.
|
||||
fread(&Version, sizeof(uint32), 1, stream);
|
||||
fread(&LengthModelName, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetName, sizeof(uint32), 1, stream);
|
||||
fread(&ModelFlags, sizeof(uint32), 1, stream);
|
||||
fread(&CountGlobalSequences, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream);
|
||||
fread(&CountAnimations, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetAnimations, sizeof(uint32), 1, stream);
|
||||
fread(&CountAnimationLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountBones, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBones, sizeof(uint32), 1, stream);
|
||||
fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountVertices, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetVertices, sizeof(uint32), 1, stream);
|
||||
fread(&CountViews, sizeof(uint32), 1, stream);
|
||||
fread(&CountColors, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetColors, sizeof(uint32), 1, stream);
|
||||
fread(&CountTextures, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTextures, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&CountRenderFlags, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetRenderFlags, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexUnits, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexUnits, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountColors, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetColors, sizeof(uint32), 1, stream);
|
||||
fread(&CountTextures, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTextures, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexReplace, sizeof(uint32), 1, stream);
|
||||
VertexBox[0] = Vector3::Read(stream);
|
||||
VertexBox[1] = Vector3::Read(stream);
|
||||
fread(&VertexRadius, sizeof(float), 1, stream);
|
||||
BoundingBox[0] = Vector3::Read(stream);
|
||||
BoundingBox[1] = Vector3::Read(stream);
|
||||
fread(&BoundingRadius, sizeof(float), 1, stream);
|
||||
fread(&CountBoundingTriangles, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoundingVertices, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoundingNormals, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream);
|
||||
}
|
||||
|
||||
WorldModelHeader WorldModelHeader::Read(FILE* stream)
|
||||
{
|
||||
WorldModelHeader ret;
|
||||
fread(&ret.CountMaterials, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountGroups, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountPortals, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountLights, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountModels, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountDoodads, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountSets, sizeof(uint32), 1, stream);
|
||||
fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream);
|
||||
fread(&ret.WmoId, sizeof(uint32), 1, stream);
|
||||
ret.BoundingBox[0] = Vector3::Read(stream);
|
||||
ret.BoundingBox[1] = Vector3::Read(stream);
|
||||
fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DoodadInstance DoodadInstance::Read(FILE* stream)
|
||||
{
|
||||
DoodadInstance ret;
|
||||
fread(&ret.FileOffset, sizeof(uint32), 1, stream);
|
||||
ret.Position = Vector3::Read(stream);
|
||||
fread(&ret.QuatW, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatX, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatY, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatZ, sizeof(float), 1, stream);
|
||||
fread(&ret.Scale, sizeof(float), 1, stream);
|
||||
fread(&ret.LightColor, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DoodadSet DoodadSet::Read(FILE* stream)
|
||||
{
|
||||
DoodadSet ret;
|
||||
char name[21];
|
||||
fread(&name, sizeof(char), 20, stream);
|
||||
name[20] = '\0';
|
||||
ret.Name = name;
|
||||
fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountInstances, sizeof(uint32), 1, stream);
|
||||
fread(&ret.UnknownZero, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LiquidHeader LiquidHeader::Read(FILE* stream)
|
||||
{
|
||||
LiquidHeader ret;
|
||||
fread(&ret.CountXVertices, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountYVertices, sizeof(uint32), 1, stream);
|
||||
fread(&ret.Width, sizeof(uint32), 1, stream);
|
||||
fread(&ret.Height, sizeof(uint32), 1, stream);
|
||||
ret.BaseLocation = Vector3::Read(stream);
|
||||
fread(&ret.MaterialId, sizeof(uint16), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header)
|
||||
{
|
||||
LiquidData ret;
|
||||
ret.HeightMap = new float*[header.CountXVertices];
|
||||
for (uint32 i = 0; i < header.CountXVertices; ++i)
|
||||
ret.HeightMap[i] = new float[header.CountYVertices];
|
||||
|
||||
ret.RenderFlags = new uint8*[header.Width];
|
||||
for (uint32 i = 0; i < header.Width; ++i)
|
||||
ret.RenderFlags[i] = new uint8[header.Height];
|
||||
|
||||
for (uint32 y = 0; y < header.CountYVertices; y++)
|
||||
{
|
||||
for (uint32 x = 0; x < header.CountXVertices; x++)
|
||||
{
|
||||
uint32 discard;
|
||||
fread(&discard, sizeof(uint32), 1, stream);
|
||||
float tmp;
|
||||
fread(&tmp, sizeof(float), 1, stream);
|
||||
ret.HeightMap[x][y] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 y = 0; y < header.Height; y++)
|
||||
{
|
||||
for (uint32 x = 0; x < header.Width; x++)
|
||||
{
|
||||
uint8 tmp;
|
||||
fread(&tmp, sizeof(uint8), 1, stream);
|
||||
ret.RenderFlags[x][y] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
H2ORenderMask H2ORenderMask::Read(FILE* stream)
|
||||
{
|
||||
H2ORenderMask ret;
|
||||
fread(&ret.Mask, sizeof(uint8), 8, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool MCNKLiquidData::IsWater(int x, int y, float height)
|
||||
{
|
||||
if (!Heights)
|
||||
return false;
|
||||
if (!Mask.ShouldRender(x, y))
|
||||
return false;
|
||||
float diff = Heights[x][y] - height;
|
||||
if (diff > Constants::MaxStandableHeight)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
H2OHeader H2OHeader::Read(FILE* stream)
|
||||
{
|
||||
H2OHeader ret;
|
||||
fread(&ret.OffsetInformation, sizeof(uint32), 1, stream);
|
||||
fread(&ret.LayerCount, sizeof(uint32), 1, stream);
|
||||
fread(&ret.OffsetRender, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
H2OInformation H2OInformation::Read(FILE* stream)
|
||||
{
|
||||
H2OInformation ret;
|
||||
fread(&ret.LiquidType, sizeof(uint16), 1, stream);
|
||||
fread(&ret.Flags, sizeof(uint16), 1, stream);
|
||||
fread(&ret.HeightLevel1, sizeof(float), 1, stream);
|
||||
fread(&ret.HeightLevel2, sizeof(float), 1, stream);
|
||||
fread(&ret.OffsetX, sizeof(uint8), 1, stream);
|
||||
fread(&ret.OffsetY, sizeof(uint8), 1, stream);
|
||||
fread(&ret.Width, sizeof(uint8), 1, stream);
|
||||
fread(&ret.Height, sizeof(uint8), 1, stream);
|
||||
fread(&ret.OffsetMask2, sizeof(uint32), 1, stream);
|
||||
fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -77,35 +77,7 @@ public:
|
||||
Vector3 Position;
|
||||
uint32 OffsetMCCV;
|
||||
|
||||
void Read(FILE* stream)
|
||||
{
|
||||
fread(&Flags, sizeof(uint32), 1, stream);
|
||||
fread(&IndexX, sizeof(uint32), 1, stream);
|
||||
fread(&IndexY, sizeof(uint32), 1, stream);
|
||||
fread(&Layers, sizeof(uint32), 1, stream);
|
||||
fread(&DoodadRefs, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCVT, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCNR, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCLY, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCRF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCAL, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCAL, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCSH, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCSH, sizeof(uint32), 1, stream);
|
||||
fread(&AreaId, sizeof(uint32), 1, stream);
|
||||
fread(&MapObjectRefs, sizeof(uint32), 1, stream);
|
||||
fread(&Holes, sizeof(uint32), 1, stream);
|
||||
LowQualityTextureMap = new uint32[4];
|
||||
fread(LowQualityTextureMap, sizeof(uint32), 4, stream);
|
||||
fread(&PredTex, sizeof(uint32), 1, stream);
|
||||
fread(&NumberEffectDoodad, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCSE, sizeof(uint32), 1, stream);
|
||||
fread(&SoundEmitters, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCLQ, sizeof(uint32), 1, stream);
|
||||
fread(&SizeMCLQ, sizeof(uint32), 1, stream);
|
||||
Position = Vector3::Read(stream);
|
||||
fread(&OffsetMCCV, sizeof(uint32), 1, stream);
|
||||
}
|
||||
void Read(FILE* stream);
|
||||
};
|
||||
|
||||
class MHDR
|
||||
@@ -125,21 +97,7 @@ public:
|
||||
uint32 OffsetMH2O;
|
||||
uint32 OffsetMTFX;
|
||||
|
||||
void Read(FILE* stream)
|
||||
{
|
||||
fread(&Flags, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMCIN, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMTEX, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMMDX, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMMID, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMWMO, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMWID, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMDDF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMODF, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMFBO, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMH2O, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetMTFX, sizeof(uint32), 1, stream);
|
||||
}
|
||||
void Read(FILE* stream);
|
||||
};
|
||||
|
||||
class ModelHeader
|
||||
@@ -196,72 +154,7 @@ public:
|
||||
uint32 CountBoundingNormals;
|
||||
uint32 OffsetBoundingNormals;
|
||||
|
||||
void Read(FILE* stream)
|
||||
{
|
||||
fread(&Magic, sizeof(char), 4, stream);
|
||||
Magic[4] = '\0'; // null-terminate it.
|
||||
fread(&Version, sizeof(uint32), 1, stream);
|
||||
fread(&LengthModelName, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetName, sizeof(uint32), 1, stream);
|
||||
fread(&ModelFlags, sizeof(uint32), 1, stream);
|
||||
fread(&CountGlobalSequences, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream);
|
||||
fread(&CountAnimations, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetAnimations, sizeof(uint32), 1, stream);
|
||||
fread(&CountAnimationLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountBones, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBones, sizeof(uint32), 1, stream);
|
||||
fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountVertices, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetVertices, sizeof(uint32), 1, stream);
|
||||
fread(&CountViews, sizeof(uint32), 1, stream);
|
||||
fread(&CountColors, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetColors, sizeof(uint32), 1, stream);
|
||||
fread(&CountTextures, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTextures, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&CountRenderFlags, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetRenderFlags, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoneLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexUnits, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexUnits, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimLookup, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream);
|
||||
fread(&CountColors, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetColors, sizeof(uint32), 1, stream);
|
||||
fread(&CountTextures, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTextures, sizeof(uint32), 1, stream);
|
||||
fread(&CountTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTransparency, sizeof(uint32), 1, stream);
|
||||
fread(&CountUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetUvAnimation, sizeof(uint32), 1, stream);
|
||||
fread(&CountTexReplace, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetTexReplace, sizeof(uint32), 1, stream);
|
||||
VertexBox[0] = Vector3::Read(stream);
|
||||
VertexBox[1] = Vector3::Read(stream);
|
||||
fread(&VertexRadius, sizeof(float), 1, stream);
|
||||
BoundingBox[0] = Vector3::Read(stream);
|
||||
BoundingBox[1] = Vector3::Read(stream);
|
||||
fread(&BoundingRadius, sizeof(float), 1, stream);
|
||||
fread(&CountBoundingTriangles, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoundingVertices, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream);
|
||||
fread(&CountBoundingNormals, sizeof(uint32), 1, stream);
|
||||
fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream);
|
||||
}
|
||||
void Read(FILE* stream);
|
||||
};
|
||||
|
||||
class WorldModelHeader
|
||||
@@ -280,23 +173,7 @@ public:
|
||||
Vector3 BoundingBox[2];
|
||||
uint32 LiquidTypeRelated;
|
||||
|
||||
static WorldModelHeader Read(FILE* stream)
|
||||
{
|
||||
WorldModelHeader ret;
|
||||
fread(&ret.CountMaterials, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountGroups, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountPortals, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountLights, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountModels, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountDoodads, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountSets, sizeof(uint32), 1, stream);
|
||||
fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream);
|
||||
fread(&ret.WmoId, sizeof(uint32), 1, stream);
|
||||
ret.BoundingBox[0] = Vector3::Read(stream);
|
||||
ret.BoundingBox[1] = Vector3::Read(stream);
|
||||
fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static WorldModelHeader Read(FILE* stream);
|
||||
};
|
||||
|
||||
class DoodadInstance
|
||||
@@ -313,19 +190,7 @@ public:
|
||||
float Scale;
|
||||
uint32 LightColor;
|
||||
|
||||
static DoodadInstance Read(FILE* stream)
|
||||
{
|
||||
DoodadInstance ret;
|
||||
fread(&ret.FileOffset, sizeof(uint32), 1, stream);
|
||||
ret.Position = Vector3::Read(stream);
|
||||
fread(&ret.QuatW, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatX, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatY, sizeof(float), 1, stream);
|
||||
fread(&ret.QuatZ, sizeof(float), 1, stream);
|
||||
fread(&ret.Scale, sizeof(float), 1, stream);
|
||||
fread(&ret.LightColor, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static DoodadInstance Read(FILE* stream);
|
||||
};
|
||||
|
||||
class DoodadSet
|
||||
@@ -337,18 +202,7 @@ public:
|
||||
uint32 CountInstances;
|
||||
uint32 UnknownZero;
|
||||
|
||||
static DoodadSet Read(FILE* stream)
|
||||
{
|
||||
DoodadSet ret;
|
||||
char name[21];
|
||||
fread(&name, sizeof(char), 20, stream);
|
||||
name[20] = '\0';
|
||||
ret.Name = name;
|
||||
fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountInstances, sizeof(uint32), 1, stream);
|
||||
fread(&ret.UnknownZero, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static DoodadSet Read(FILE* stream);
|
||||
};
|
||||
|
||||
class LiquidHeader
|
||||
@@ -362,17 +216,7 @@ public:
|
||||
Vector3 BaseLocation;
|
||||
uint16 MaterialId;
|
||||
|
||||
static LiquidHeader Read(FILE* stream)
|
||||
{
|
||||
LiquidHeader ret;
|
||||
fread(&ret.CountXVertices, sizeof(uint32), 1, stream);
|
||||
fread(&ret.CountYVertices, sizeof(uint32), 1, stream);
|
||||
fread(&ret.Width, sizeof(uint32), 1, stream);
|
||||
fread(&ret.Height, sizeof(uint32), 1, stream);
|
||||
ret.BaseLocation = Vector3::Read(stream);
|
||||
fread(&ret.MaterialId, sizeof(uint16), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static LiquidHeader Read(FILE* stream);
|
||||
};
|
||||
|
||||
class LiquidData
|
||||
@@ -387,41 +231,7 @@ public:
|
||||
return RenderFlags[x][y] != 0x0F;
|
||||
}
|
||||
|
||||
static LiquidData Read(FILE* stream, LiquidHeader header)
|
||||
{
|
||||
LiquidData ret;
|
||||
ret.HeightMap = new float*[header.CountXVertices];
|
||||
for (uint32 i = 0; i < header.CountXVertices; ++i)
|
||||
ret.HeightMap[i] = new float[header.CountYVertices];
|
||||
|
||||
ret.RenderFlags = new uint8*[header.Width];
|
||||
for (uint32 i = 0; i < header.Width; ++i)
|
||||
ret.RenderFlags[i] = new uint8[header.Height];
|
||||
|
||||
for (uint32 y = 0; y < header.CountYVertices; y++)
|
||||
{
|
||||
for (uint32 x = 0; x < header.CountXVertices; x++)
|
||||
{
|
||||
uint32 discard;
|
||||
fread(&discard, sizeof(uint32), 1, stream);
|
||||
float tmp;
|
||||
fread(&tmp, sizeof(float), 1, stream);
|
||||
ret.HeightMap[x][y] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 y = 0; y < header.Height; y++)
|
||||
{
|
||||
for (uint32 x = 0; x < header.Width; x++)
|
||||
{
|
||||
uint8 tmp;
|
||||
fread(&tmp, sizeof(uint8), 1, stream);
|
||||
ret.RenderFlags[x][y] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
static LiquidData Read(FILE* stream, LiquidHeader& header);
|
||||
};
|
||||
|
||||
class H2ORenderMask
|
||||
@@ -435,12 +245,7 @@ public:
|
||||
return (Mask[y] >> x & 1) != 0;
|
||||
}
|
||||
|
||||
static H2ORenderMask Read(FILE* stream)
|
||||
{
|
||||
H2ORenderMask ret;
|
||||
fread(&ret.Mask, sizeof(uint8), 8, stream);
|
||||
return ret;
|
||||
}
|
||||
static H2ORenderMask Read(FILE* stream);
|
||||
};
|
||||
|
||||
class MCNKLiquidData
|
||||
@@ -452,17 +257,7 @@ public:
|
||||
float** Heights;
|
||||
H2ORenderMask Mask;
|
||||
|
||||
bool IsWater(int x, int y, float height)
|
||||
{
|
||||
if (!Heights)
|
||||
return false;
|
||||
if (!Mask.ShouldRender(x, y))
|
||||
return false;
|
||||
float diff = Heights[x][y] - height;
|
||||
if (diff > Constants::MaxStandableHeight)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool IsWater(int x, int y, float height);
|
||||
};
|
||||
|
||||
class H2OHeader
|
||||
@@ -473,14 +268,7 @@ public:
|
||||
uint32 LayerCount;
|
||||
uint32 OffsetRender;
|
||||
|
||||
static H2OHeader Read(FILE* stream)
|
||||
{
|
||||
H2OHeader ret;
|
||||
fread(&ret.OffsetInformation, sizeof(uint32), 1, stream);
|
||||
fread(&ret.LayerCount, sizeof(uint32), 1, stream);
|
||||
fread(&ret.OffsetRender, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static H2OHeader Read(FILE* stream);
|
||||
};
|
||||
|
||||
class H2OInformation
|
||||
@@ -498,21 +286,7 @@ public:
|
||||
uint32 OffsetMask2;
|
||||
uint32 OffsetHeightmap;
|
||||
|
||||
static H2OInformation Read(FILE* stream)
|
||||
{
|
||||
H2OInformation ret;
|
||||
fread(&ret.LiquidType, sizeof(uint16), 1, stream);
|
||||
fread(&ret.Flags, sizeof(uint16), 1, stream);
|
||||
fread(&ret.HeightLevel1, sizeof(float), 1, stream);
|
||||
fread(&ret.HeightLevel2, sizeof(float), 1, stream);
|
||||
fread(&ret.OffsetX, sizeof(uint8), 1, stream);
|
||||
fread(&ret.OffsetY, sizeof(uint8), 1, stream);
|
||||
fread(&ret.Width, sizeof(uint8), 1, stream);
|
||||
fread(&ret.Height, sizeof(uint8), 1, stream);
|
||||
fread(&ret.OffsetMask2, sizeof(uint32), 1, stream);
|
||||
fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream);
|
||||
return ret;
|
||||
}
|
||||
static H2OInformation Read(FILE* stream);
|
||||
};
|
||||
|
||||
// Dummy class to act as an interface.
|
||||
|
||||
Reference in New Issue
Block a user