mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
Tools/MeshExtractor: Fixed mmap extracting for instance maps and fixed a number of issues.
ToDo: Cleanup the code a bit. WILL NOT CURRENTLY WORK WITH TrinityCore, if you want to test it, use the --extract 32 flag of MeshExtractor.
This commit is contained in:
@@ -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(¶ms, 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(¶ms, 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(¶ms, 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);
|
||||
|
||||
@@ -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(¶ms, sizeof(dtNavMeshParams), 1, mmap);
|
||||
fclose(mmap);
|
||||
@@ -420,13 +422,16 @@ int main(int argc, char* argv[])
|
||||
dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery();
|
||||
|
||||
navMesh->init(¶ms);
|
||||
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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
float* bmin, *bmax;
|
||||
void TileBuilder::SetCoords(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
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(¶ms, 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(¶ms, &navData, &navDataSize);
|
||||
|
||||
delete areas;
|
||||
delete triangles;
|
||||
delete vertices;
|
||||
|
||||
if (result)
|
||||
{
|
||||
printf("NavMesh created, size %i!\n", navDataSize);
|
||||
|
||||
@@ -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
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user