aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/mesh_extractor/ContinentBuilder.cpp59
-rw-r--r--src/tools/mesh_extractor/MeshExtractor.cpp62
-rw-r--r--src/tools/mesh_extractor/TileBuilder.cpp46
-rw-r--r--src/tools/mesh_extractor/TileBuilder.h7
-rw-r--r--src/tools/mesh_extractor/Utils.cpp20
-rw-r--r--src/tools/mesh_extractor/Utils.h6
-rw-r--r--src/tools/mesh_extractor/WorldModelHandler.cpp35
-rw-r--r--src/tools/mesh_extractor/WorldModelHandler.h2
8 files changed, 163 insertions, 74 deletions
diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp
index 7708aa36617..6449f8c1443 100644
--- a/src/tools/mesh_extractor/ContinentBuilder.cpp
+++ b/src/tools/mesh_extractor/ContinentBuilder.cpp
@@ -6,6 +6,7 @@
#include "Cache.h"
#include "ace/Task.h"
#include "Recast.h"
+#include "DetourCommon.h"
class BuilderThread : public ACE_Task_Base
{
@@ -52,7 +53,7 @@ public:
return 0;
}
- uint8* nav = builder.BuildInstance(Params, Model, *Definition);
+ uint8* nav = builder.BuildInstance(Params);
if (nav)
{
f = fopen(buff, "wb");
@@ -155,26 +156,58 @@ void ContinentBuilder::Build()
CalculateTileBounds();
dtNavMeshParams params;
- params.maxPolys = 1 << STATIC_POLY_BITS;
- params.maxTiles = TileMap->TileTable.size();
- rcVcopy(params.orig, bmin);
- params.tileHeight = Constants::TileSize;
- params.tileWidth = Constants::TileSize;
- fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
- fclose(mmap);
+
std::vector<BuilderThread*> Threads;
if (TileMap->IsGlobalModel)
{
printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId);
- BuilderThread* thread = new BuilderThread(this, params);
- Threads.push_back(thread);
- thread->SetData(65, 65, MapId, Continent, true, TileMap->Model, &TileMap->ModelDefinition);
- thread->activate();
- thread->wait();
+
+ TileBuilder* builder = new TileBuilder(this, Continent, 0, 0, MapId);
+ builder->AddGeometry(TileMap->Model, TileMap->ModelDefinition);
+ builder->SetCoords(0, 0);
+ uint8* nav = builder->BuildInstance(params);
+ if (nav)
+ {
+ // Set some params for the navmesh
+ dtMeshHeader* header = (dtMeshHeader*)nav;
+ dtVcopy(params.orig, header->bmin);
+ params.tileWidth = header->bmax[0] - header->bmin[0];
+ params.tileHeight = header->bmax[2] - header->bmin[2];
+ params.maxTiles = 1;
+ params.maxPolys = header->polyCount;
+ fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
+ fclose(mmap);
+
+ char buff[100];
+ sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, 0, 0);
+ FILE* 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;
+ }
+
+ MmapTileHeader mheader;
+ mheader.size = builder->DataSize;
+ fwrite(&mheader, sizeof(MmapTileHeader), 1, f);
+ fwrite(nav, sizeof(unsigned char), builder->DataSize, f);
+ fclose(f);
+ }
+
+ dtFree(nav);
+ delete builder;
}
else
{
+ params.maxPolys = 1 << STATIC_POLY_BITS;
+ params.maxTiles = TileMap->TileTable.size();
+ rcVcopy(params.orig, bmin);
+ params.tileHeight = Constants::TileSize;
+ params.tileWidth = Constants::TileSize;
+ fwrite(&params, sizeof(dtNavMeshParams), 1, mmap);
+ fclose(mmap);
+
for (uint32 i = 0; i < NumberOfThreads; ++i)
Threads.push_back(new BuilderThread(this, params));
printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads);
diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp
index 4a312640395..7653faae2ab 100644
--- a/src/tools/mesh_extractor/MeshExtractor.cpp
+++ b/src/tools/mesh_extractor/MeshExtractor.cpp
@@ -328,6 +328,8 @@ void PrintUsage()
void LoadTile(dtNavMesh*& navMesh, const char* tile)
{
FILE* f = fopen(tile, "rb");
+ if (!f)
+ return;
MmapTileHeader header;
if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1)
@@ -376,37 +378,37 @@ int main(int argc, char* argv[])
if (extractFlags & Constants::EXTRACT_FLAG_TEST)
{
- float start[] = { 0.0f, 0.0f, 0.0f };
- float end[] = { 0.0f, 0.0f, 0.0f };
+ float start[] = { -230.133f, 191.085f, -24.9191f };
+ float end[] = { -396.309f, 150.828f, 7.82184f };
//
float m_spos[3];
- m_spos[0] = -1.0f * start[1];
+ m_spos[0] = -start[1];
m_spos[1] = start[2];
- m_spos[2] = -1.0f * start[0];
+ m_spos[2] = -start[0];
//
float m_epos[3];
- m_epos[0] = -1.0f * end[1];
+ m_epos[0] = -end[1];
m_epos[1] = end[2];
- m_epos[2] = -1.0f * end[0];
+ m_epos[2] = -end[0];
//
dtQueryFilter m_filter;
- m_filter.setIncludeFlags(0xffff);
- m_filter.setExcludeFlags(0);
+ m_filter.setIncludeFlags(Constants::POLY_AREA_ROAD | Constants::POLY_AREA_TERRAIN);
+ m_filter.setExcludeFlags(Constants::POLY_AREA_WATER);
//
float m_polyPickExt[3];
- m_polyPickExt[0] = 2;
- m_polyPickExt[1] = 4;
- m_polyPickExt[2] = 2;
+ m_polyPickExt[0] = 2.5f;
+ m_polyPickExt[1] = 2.5f;
+ m_polyPickExt[2] = 2.5f;
//
dtPolyRef m_startRef;
dtPolyRef m_endRef;
- FILE* mmap = fopen(".mmap", "rb");
+ FILE* mmap = fopen("mmaps/389.mmap", "rb");
dtNavMeshParams params;
int count = fread(&params, sizeof(dtNavMeshParams), 1, mmap);
fclose(mmap);
@@ -420,13 +422,16 @@ int main(int argc, char* argv[])
dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery();
navMesh->init(&params);
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
- LoadTile(navMesh, ".mmtile");
-
+ for (int i = 0; i <= 32; ++i)
+ {
+ for (int j = 0; j <= 32; ++j)
+ {
+ char buff[100];
+ sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j);
+ LoadTile(navMesh, buff);
+ }
+ }
+
navMeshQuery->init(navMesh, 2048);
float nearestPt[3];
@@ -440,7 +445,24 @@ int main(int argc, char* argv[])
return 0;
}
- printf("Found!");
+ int hops;
+ dtPolyRef* hopBuffer = new dtPolyRef[8192];
+ dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192);
+
+ int resultHopCount;
+ float* straightPath = new float[2048*3];
+ unsigned char* pathFlags = new unsigned char[2048];
+ dtPolyRef* pathRefs = new dtPolyRef[2048];
+
+ status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048);
+ std::vector<Vector3> FinalPath;
+ FinalPath.reserve(resultHopCount);
+ for (uint32 i = 0; i < resultHopCount; ++i)
+ {
+ Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2]));
+ FinalPath.push_back(finalV);
+ printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z);
+ }
}
return 0;
diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp
index 857cf7f16d8..aa09b21cd73 100644
--- a/src/tools/mesh_extractor/TileBuilder.cpp
+++ b/src/tools/mesh_extractor/TileBuilder.cpp
@@ -14,7 +14,7 @@
#include <ace/Synch.h>
TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) :
- World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder)
+ World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder), pmesh(NULL), dmesh(NULL)
{
/*
Test, non-working values
@@ -90,12 +90,12 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara
bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1));
}
-uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def )
+void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def)
{
_Geometry = new Geometry();
_Geometry->Transform = true;
- WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root);
+ WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root, false);
if (Constants::Debug)
{
@@ -114,26 +114,35 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
}
fclose(debug);
}
+}
+
+void TileBuilder::SetCoords(int x, int y)
+{
+ X = x;
+ Y = y;
+}
- float* bmin, *bmax;
+void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax)
+{
_Geometry->CalculateBoundingBox(bmin, bmax);
rcVcopy(InstanceConfig.bmax, bmax);
rcVcopy(InstanceConfig.bmin, bmin);
+ if (pmesh && dmesh)
+ return;
+
uint32 numVerts = _Geometry->Vertices.size();
uint32 numTris = _Geometry->Triangles.size();
float* vertices;
int* triangles;
uint8* areas;
_Geometry->GetRawData(vertices, triangles, areas);
- _Geometry->Vertices.clear();
- _Geometry->Triangles.clear();
// this sets the dimensions of the heightfield - should maybe happen before border padding
rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height);
rcHeightfield* hf = rcAllocHeightfield();
rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch);
-
+
rcClearUnwalkableTriangles(Context, InstanceConfig.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas);
rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, InstanceConfig.walkableClimb);
@@ -151,10 +160,10 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
rcContourSet* contours = rcAllocContourSet();
rcBuildContours(Context, *chf, InstanceConfig.maxSimplificationError, InstanceConfig.maxEdgeLen, *contours);
- rcPolyMesh* pmesh = rcAllocPolyMesh();
+ pmesh = rcAllocPolyMesh();
rcBuildPolyMesh(Context, *contours, InstanceConfig.maxVertsPerPoly, *pmesh);
- rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail();
+ dmesh = rcAllocPolyMeshDetail();
rcBuildPolyMeshDetail(Context, *pmesh, *chf, InstanceConfig.detailSampleDist, InstanceConfig.detailSampleMaxError, *dmesh);
// Set flags according to area types (e.g. Swim for Water)
@@ -165,6 +174,13 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
else if (pmesh->areas[i] == Constants::POLY_AREA_WATER)
pmesh->flags[i] = Constants::POLY_FLAG_SWIM;
}
+}
+
+uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams )
+{
+ float* bmin = NULL, *bmax = NULL;
+
+ PrepareInstanceMesh(bmin, bmax);
dtNavMeshCreateParams params;
memset(&params, 0, sizeof(params));
@@ -190,9 +206,10 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch;
params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch;
params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs;
- params.tileX = 0;
- params.tileY = 0;
+ params.tileX = X;
+ params.tileY = Y;
params.tileLayer = 0;
+ params.buildBvTree = true;
rcVcopy(params.bmax, bmax);
rcVcopy(params.bmin, bmin);
@@ -208,9 +225,6 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
// keep in mind that we do output those into debug info
// drop tiles with only exact count - some tiles may have geometry while having less tiles
printf("No polygons to build on tile, skipping.\n");
- delete areas;
- delete triangles;
- delete vertices;
return NULL;
}
@@ -219,10 +233,6 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo
printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", pmesh->nverts, pmesh->npolys, dmesh->ntris);
bool result = dtCreateNavMeshData(&params, &navData, &navDataSize);
- delete areas;
- delete triangles;
- delete vertices;
-
if (result)
{
printf("NavMesh created, size %i!\n", navDataSize);
diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h
index 814f989486e..ca84387a6d9 100644
--- a/src/tools/mesh_extractor/TileBuilder.h
+++ b/src/tools/mesh_extractor/TileBuilder.h
@@ -17,7 +17,10 @@ public:
void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams);
uint8* Build(dtNavMeshParams& navMeshParams);
- uint8* BuildInstance(dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def);
+ uint8* BuildInstance(dtNavMeshParams& navMeshParams);
+ void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def);
+ void SetCoords(int x, int y);
+ void PrepareInstanceMesh(float*& bmin, float*& bmax);
std::string World;
int X;
int Y;
@@ -28,5 +31,7 @@ public:
Geometry* _Geometry;
uint32 DataSize;
ContinentBuilder* cBuilder;
+ rcPolyMesh* pmesh;
+ rcPolyMeshDetail* dmesh;
};
#endif \ No newline at end of file
diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp
index 10e0bdc0d04..e7ffc0ed919 100644
--- a/src/tools/mesh_extractor/Utils.cpp
+++ b/src/tools/mesh_extractor/Utils.cpp
@@ -87,7 +87,7 @@ std::string Utils::FixModelPath(const std::string& path )
return Utils::GetPathBase(path) + ".M2";
}
-Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec)
+Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate)
{
// Sources of information:
/// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715
@@ -99,15 +99,21 @@ Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec)
Vector3 ret = Utils::VectorTransform(vec, rot);
// And finally scale and translate it to our origin
- return (ret * def.Scale()) + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y);
+ ret = ret * def.Scale();
+ if (translate)
+ ret = ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y);
+ return ret;
}
-Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec )
+Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate )
{
G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW);
Vector3 ret = Utils::VectorTransform(vec, G3D::Matrix4(quat.toRotationMatrix()));
- return (ret * (inst.Scale / 1024.0f)) + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y);
+ ret = ret * (inst.Scale / 1024.0f);
+ if (translate)
+ ret = ret + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y);
+ return ret;
}
float Utils::ToRadians( float degrees )
@@ -138,11 +144,11 @@ Vector3 Vector3::Read( FILE* file )
return ret;
}
-Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/)
+Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int x, int y, bool translate)
{
if (Utils::Distance(height, 0.0f) > 0.5f)
basePosition.z = 0.0f;
- return Utils::TransformDoodadVertex(def, basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height));
+ return Utils::TransformDoodadVertex(def, basePosition + Vector3(x * Constants::UnitSize, y * Constants::UnitSize, height), translate);
}
float Utils::Distance( float x, float y )
@@ -189,7 +195,7 @@ void Utils::SaveToDisk( FILE* stream, const std::string& path )
Vector3 Utils::ToWoWCoords(const Vector3& vec )
{
- return Vector3(-vec.z, vec.x, vec.y);
+ return Vector3(-vec.z, -vec.x, vec.y);
}
std::string Utils::GetExtension( std::string path )
diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h
index a307dd4f695..d6bb421a633 100644
--- a/src/tools/mesh_extractor/Utils.h
+++ b/src/tools/mesh_extractor/Utils.h
@@ -367,7 +367,7 @@ public:
}
static float ToRadians(float degrees);
static std::string GetPathBase(const std::string& path);
- static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/);
+ static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/, bool translate = true);
static float Distance(float x, float y);
template<typename T>
static bool IsAllZero(T* arr, uint32 size)
@@ -383,8 +383,8 @@ public:
static Vector3 ToWoWCoords(const Vector3& vec );
static std::string GetExtension( std::string path );
static char* GetPlainName(const char* FileName);
- static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec);
+ static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true);
static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false );
- static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec );
+ static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true );
};
#endif
diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp
index 24f63dc1e33..3565a1d6af0 100644
--- a/src/tools/mesh_extractor/WorldModelHandler.cpp
+++ b/src/tools/mesh_extractor/WorldModelHandler.cpp
@@ -79,13 +79,17 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk )
fseek(stream, mcnk->Source->Offset, SEEK_SET);
}
-void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root )
+void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate )
{
for (std::vector<WorldModelGroup>::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group)
{
uint32 vertOffset = verts.size();
for (std::vector<Vector3>::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2)
- verts.push_back(Utils::TransformDoodadVertex(def, *itr2)); // Transform the vertex to world space
+ {
+ Vector3 v = Utils::TransformDoodadVertex(def, *itr2, translate);
+ // If translate is false, then we were called directly from the TileBuilder to add data to it's _Geometry member, hence, we have to manually convert the vertices to Recast format.
+ verts.push_back(translate ? v : Utils::ToRecast(v)); // Transform the vertex to world space
+ }
for (uint32 i = 0; i < group->Triangles.size(); ++i)
{
@@ -122,7 +126,10 @@ void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::v
continue;
int vertOffset = verts.size();
for (std::vector<Vector3>::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2)
- verts.push_back(Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2)));
+ {
+ Vector3 v = Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2, false), translate);
+ verts.push_back(translate ? v : Utils::ToRecast(v));
+ }
for (std::vector<Triangle<uint16> >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2)
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset));
}
@@ -144,14 +151,20 @@ void WorldModelHandler::InsertModelGeometry( std::vector<Vector3>& verts, std::v
continue;
uint32 vertOffset = verts.size();
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x][y], x, y));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x + 1][y], x + 1, y));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x][y + 1], x, y + 1));
- verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
- liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1));
+
+ Vector3 v1 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x][y], x, y, translate);
+ Vector3 v2 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x + 1][y], x + 1, y, translate);
+ Vector3 v3 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x][y + 1], x, y + 1, translate);
+ Vector3 v4 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation,
+ liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1, translate);
+
+ verts.push_back(translate ? v1 : Utils::ToRecast(v1));
+ verts.push_back(translate ? v2 : Utils::ToRecast(v2));
+ verts.push_back(translate ? v3 : Utils::ToRecast(v3));
+ verts.push_back(translate ? v4 : Utils::ToRecast(v4));
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1));
tris.push_back(Triangle<uint32>(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1));
diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h
index 0611a02f764..87a5ad62938 100644
--- a/src/tools/mesh_extractor/WorldModelHandler.h
+++ b/src/tools/mesh_extractor/WorldModelHandler.h
@@ -34,7 +34,7 @@ public:
std::vector<Vector3> Vertices;
std::vector<Triangle<uint32> > Triangles;
bool IsSane() { return _definitions && _paths; }
- static void InsertModelGeometry(std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root);
+ static void InsertModelGeometry(std::vector<Vector3>& verts, std::vector<Triangle<uint32> >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate = true);
protected:
void ProcessInternal(MapChunk* data);
private: