aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubv <s.v.h21@hotmail.com>2012-09-28 07:59:22 -0500
committerSubv <s.v.h21@hotmail.com>2012-09-28 07:59:22 -0500
commitad0cd9f40acff1ff6d7571426b4acb1ea675d7a6 (patch)
tree104616d295acf88958f174c5cafef7dfe6cbd322 /src
parent50f833a0086c9f7f80152b907c77acb19d352896 (diff)
Tools: Made more updates to the MeshExtractor
Diffstat (limited to 'src')
-rw-r--r--src/tools/mesh_extractor/ADT.h10
-rw-r--r--src/tools/mesh_extractor/LiquidHandler.cpp96
-rw-r--r--src/tools/mesh_extractor/LiquidHandler.h3
-rw-r--r--src/tools/mesh_extractor/MapChunk.cpp8
-rw-r--r--src/tools/mesh_extractor/MapChunk.h2
-rw-r--r--src/tools/mesh_extractor/Utils.cpp11
-rw-r--r--src/tools/mesh_extractor/Utils.h71
7 files changed, 186 insertions, 15 deletions
diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h
index 18b811a4e4c..43984d0902c 100644
--- a/src/tools/mesh_extractor/ADT.h
+++ b/src/tools/mesh_extractor/ADT.h
@@ -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;
diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp
index 5924c693196..3217bb2cbc6 100644
--- a/src/tools/mesh_extractor/LiquidHandler.cpp
+++ b/src/tools/mesh_extractor/LiquidHandler.cpp
@@ -1 +1,95 @@
-#include "LiquidHandler.h" \ No newline at end of file
+#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));
+ }
+ }
+ }
+}
diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h
index ba89be33e08..138b2da2ad9 100644
--- a/src/tools/mesh_extractor/LiquidHandler.h
+++ b/src/tools/mesh_extractor/LiquidHandler.h
@@ -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 \ No newline at end of file
diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp
index 95f8c2e56c0..4cb5dc04d2d 100644
--- a/src/tools/mesh_extractor/MapChunk.cpp
+++ b/src/tools/mesh_extractor/MapChunk.cpp
@@ -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;
}
diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h
index 034429a81ec..9d7b02bbfe5 100644
--- a/src/tools/mesh_extractor/MapChunk.h
+++ b/src/tools/mesh_extractor/MapChunk.h
@@ -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;
diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp
index 03473eb0794..0b92dab267f 100644
--- a/src/tools/mesh_extractor/Utils.cpp
+++ b/src/tools/mesh_extractor/Utils.cpp
@@ -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;
+}
diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h
index cda5f4c7cd8..aa73db173a7 100644
--- a/src/tools/mesh_extractor/Utils.h
+++ b/src/tools/mesh_extractor/Utils.h
@@ -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 \ No newline at end of file