diff options
author | Subv <s.v.h21@hotmail.com> | 2012-09-28 07:59:22 -0500 |
---|---|---|
committer | Subv <s.v.h21@hotmail.com> | 2012-09-28 07:59:22 -0500 |
commit | ad0cd9f40acff1ff6d7571426b4acb1ea675d7a6 (patch) | |
tree | 104616d295acf88958f174c5cafef7dfe6cbd322 /src | |
parent | 50f833a0086c9f7f80152b907c77acb19d352896 (diff) |
Tools: Made more updates to the MeshExtractor
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/mesh_extractor/ADT.h | 10 | ||||
-rw-r--r-- | src/tools/mesh_extractor/LiquidHandler.cpp | 96 | ||||
-rw-r--r-- | src/tools/mesh_extractor/LiquidHandler.h | 3 | ||||
-rw-r--r-- | src/tools/mesh_extractor/MapChunk.cpp | 8 | ||||
-rw-r--r-- | src/tools/mesh_extractor/MapChunk.h | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.cpp | 11 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.h | 71 |
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 |