mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 11:52:32 +01:00
Tools: Made more updates to the MeshExtractor
This commit is contained in:
@@ -4,17 +4,19 @@
|
||||
#include "MapChunk.h"
|
||||
#include "DoodadHandler.h"
|
||||
#include "WorldModelHandler.h"
|
||||
#include "LiquidHandler.h"
|
||||
|
||||
class ADT
|
||||
{
|
||||
public:
|
||||
ADT();
|
||||
~ADT() { delete[] MapChunks; delete ObjectData; delete Data; }
|
||||
ADT(std::string file);
|
||||
~ADT();
|
||||
|
||||
void Read();
|
||||
|
||||
ChunkedData* ObjectData;
|
||||
ChunkedData* Data;
|
||||
// This here is not a pointer, is an array of objects ( made this way to allow the dynamic allocation )
|
||||
MapChunk* MapChunks;
|
||||
std::vector<MapChunk*> MapChunks;
|
||||
MHDR Header;
|
||||
// Can we dispose of this?
|
||||
bool HasObjectData;
|
||||
|
||||
@@ -1 +1,95 @@
|
||||
#include "LiquidHandler.h"
|
||||
#include "LiquidHandler.h"
|
||||
#include "Utils.h"
|
||||
|
||||
LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt)
|
||||
{
|
||||
HandleNewLiquid();
|
||||
}
|
||||
|
||||
void LiquidHandler::HandleNewLiquid()
|
||||
{
|
||||
Chunk* chunk = Source->Data->GetChunkByName("MH2O");
|
||||
if (!chunk)
|
||||
return;
|
||||
|
||||
Vertices.reserve(1000);
|
||||
Triangles.reserve(1000);
|
||||
|
||||
FILE* stream = chunk->GetStream();
|
||||
H2OHeader header[256];
|
||||
MCNKData.reserve(256);
|
||||
for (int i = 0; i < 256; i++)
|
||||
header[i] = H2OHeader::Read(stream);
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
H2OHeader h = header[i];
|
||||
if (h.LayerCount == 0)
|
||||
continue;
|
||||
fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET);
|
||||
H2OInformation information = H2OInformation::Read(stream);
|
||||
|
||||
float** heights = new float*[9];
|
||||
for (int i = 0; i < 9; ++i)
|
||||
heights[i] = new float[9];
|
||||
|
||||
H2ORenderMask renderMask;
|
||||
if (information.LiquidType != 2)
|
||||
{
|
||||
fseek(stream, chunk->Offset + h.OffsetRender, SEEK_SET);
|
||||
renderMask = H2ORenderMask::Read(stream);
|
||||
if ((Utils::IsAllZero(renderMask.Mask, 8) || (information.Width == 8 && information.Height == 8)) && information.OffsetMask2)
|
||||
{
|
||||
fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET);
|
||||
uint32 size = ceil(information.Width * information.Height / 8.0f);
|
||||
uint8* altMask = new uint8[size];
|
||||
fread(altMax, sizeof(uint8), size, stream);
|
||||
|
||||
for (int mi = 0; mi < size; mi++)
|
||||
renderMask.Mask[mi + information.OffsetY] |= altMask[mi];
|
||||
delete[] altMask;
|
||||
}
|
||||
fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET);
|
||||
|
||||
for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++)
|
||||
for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++)
|
||||
fread(&heights[x][y], sizeof(float), 1, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fill with ocean data
|
||||
for (uint32 i = 0; i < 8; ++i)
|
||||
renderMask.Mask[i] = 0xFF;
|
||||
|
||||
for (uint32 y = 0; y < 9; ++y)
|
||||
for (uint32 x = 0; x < 9; ++x)
|
||||
heights[x][y] = information.HeightLevel1;
|
||||
}
|
||||
|
||||
MCNKData.push_back(MCNKLiquidData(heights, renderMask));
|
||||
|
||||
for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++)
|
||||
{
|
||||
for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++)
|
||||
{
|
||||
if (!renderMask.ShouldRender(x, y))
|
||||
continue;
|
||||
|
||||
MapChunk* mapChunk = Source->MapChunks[i];
|
||||
Vector3 location = mapChunk->Header.Position;
|
||||
location.y = location.y - (x * Constants::UnitSize);
|
||||
location.x = location.x - (y * Constants::UnitSize);
|
||||
location.z = heights[x][y];
|
||||
|
||||
uint32 vertOffset = Vertices.size();
|
||||
Vertices.push_back(location);
|
||||
Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z));
|
||||
Vertices.push_back(new Vector3(location.x, location.y - Constants::UnitSize, location.z));
|
||||
Vertices.push_back(new Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z));
|
||||
|
||||
Triangles.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset+2, vertOffset + 1));
|
||||
Triangles.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
class LiquidHandler
|
||||
{
|
||||
public:
|
||||
LiquidHandler(ADT* adt);
|
||||
ADT* Source;
|
||||
std::vector<Vector3> Vertices;
|
||||
std::vector<Triangle<uint32> > Triangles;
|
||||
std::vector<MCNKLiquidData> MCNKData;
|
||||
private:
|
||||
void HandleNewLiquid();
|
||||
};
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "MapChunk.h"
|
||||
#include "ADT.h"
|
||||
|
||||
MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : adt(_adt), Source(chunk), Vertices(NULL)
|
||||
MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk), Vertices(NULL)
|
||||
{
|
||||
FILE* stream = chunk->GetStream();
|
||||
Header.Read(stream);
|
||||
@@ -26,14 +26,14 @@ void MapChunk::GenerateTriangles()
|
||||
uint32 center = (17 * y) + 9 + x;
|
||||
|
||||
uint8 triangleType = Constants::TRIANGLE_TYPE_TERRAIN;
|
||||
if (ADT.LiquidHandler && ADT.LiquidHandler.MCNKData)
|
||||
if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty())
|
||||
{
|
||||
var data = ADT.LiquidHandler.MCNKData[Index];
|
||||
MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index];
|
||||
uint32 maxHeight = std::max(
|
||||
std::max(
|
||||
std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z),
|
||||
Vertices[bottomRight].z), Vertices[center].z);
|
||||
if (data && data->IsWater(x, y, maxHeight))
|
||||
if (data.IsWater(x, y, maxHeight))
|
||||
triangleType = Constants::TRIANGLE_TYPE_WATER;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
void GenerateTriangles();
|
||||
void GenerateVertices(FILE* stream);
|
||||
static bool HasHole(uint32 map, int x, int y);
|
||||
ADT* adt;
|
||||
ADT* Adt;
|
||||
Chunk* Source;
|
||||
MapChunkHeader Header;
|
||||
Vector3* Vertices;
|
||||
|
||||
@@ -161,3 +161,14 @@ float Utils::Distance( float x, float y )
|
||||
{
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr )
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = str.find(oldStr, pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(pos, oldStr.length(), newStr);
|
||||
pos += newStr.length();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ struct Vector3
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
Vector3 operator+(Vector3 right, Vector3 left)
|
||||
Vector3 operator +(Vector3 const& other)
|
||||
{
|
||||
return Vector3(right.x+left.x, right.y+left.y, right.z+left.z);
|
||||
return Vector3(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
static Vector3 Read(FILE* file);
|
||||
};
|
||||
@@ -380,7 +380,7 @@ public:
|
||||
return RenderFlags[x][y] != 0x0F;
|
||||
}
|
||||
|
||||
public static LiquidData Read(FILE* stream, LiquidHeader header)
|
||||
static LiquidData Read(FILE* stream, LiquidHeader header)
|
||||
{
|
||||
LiquidData ret;
|
||||
ret.HeightMap = new float*[header.CountXVertices];
|
||||
@@ -440,14 +440,15 @@ class MCNKLiquidData
|
||||
{
|
||||
public:
|
||||
MCNKLiquidData() {}
|
||||
MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {}
|
||||
const float MaxStandableHeight = 1.5f;
|
||||
|
||||
float** Heights;
|
||||
H2ORenderMask* Mask;
|
||||
H2ORenderMask Mask;
|
||||
|
||||
bool IsWater(int x, int y, float height)
|
||||
{
|
||||
if (!Heights || !Mask)
|
||||
if (!Heights)
|
||||
return false;
|
||||
if (!Mask->ShouldRender(x, y))
|
||||
return false;
|
||||
@@ -458,6 +459,56 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class H2OHeader
|
||||
{
|
||||
public:
|
||||
H2OHeader() {}
|
||||
uint32 OffsetInformation;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
class H2OInformation
|
||||
{
|
||||
public:
|
||||
H2OInformation() {}
|
||||
uint16 LiquidType;
|
||||
uint16 Flags;
|
||||
float HeightLevel1;
|
||||
float HeightLevel2;
|
||||
uint8 OffsetX;
|
||||
uint8 OffsetY;
|
||||
uint8 Width;
|
||||
uint8 Height;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// Dummy class to act as an interface.
|
||||
class IDefinition
|
||||
{
|
||||
@@ -493,5 +544,15 @@ public:
|
||||
static std::string GetPathBase(std::string path);
|
||||
static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y);
|
||||
static float Distance(float x, float y);
|
||||
template<typename T>
|
||||
static bool IsAllZero(T* arr, uint32 size)
|
||||
{
|
||||
for (uint32 i = 0; i < size; ++i)
|
||||
if (arr[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
static std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr );
|
||||
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user