mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Tools/mmaps_generator: Replace G3D::Array with std::vector
This commit is contained in:
@@ -200,24 +200,24 @@ namespace MMAP
|
||||
return;
|
||||
}
|
||||
|
||||
G3D::Array<float> allVerts;
|
||||
G3D::Array<int> allTris;
|
||||
std::vector<float> allVerts;
|
||||
std::vector<int> allTris;
|
||||
|
||||
allTris.append(meshData.liquidTris);
|
||||
allVerts.append(meshData.liquidVerts);
|
||||
allTris.insert(allTris.end(), meshData.liquidTris.begin(), meshData.liquidTris.end());
|
||||
allVerts.insert(allVerts.end(), meshData.liquidVerts.begin(), meshData.liquidVerts.end());
|
||||
TerrainBuilder::copyIndices(meshData.solidTris, allTris, allVerts.size() / 3);
|
||||
allVerts.append(meshData.solidVerts);
|
||||
allVerts.insert(allVerts.end(), meshData.solidVerts.begin(), meshData.solidVerts.end());
|
||||
|
||||
float* verts = allVerts.getCArray();
|
||||
float* verts = allVerts.data();
|
||||
int vertCount = allVerts.size() / 3;
|
||||
int* tris = allTris.getCArray();
|
||||
int* tris = allTris.data();
|
||||
int triCount = allTris.size() / 3;
|
||||
|
||||
for (int i = 0; i < allVerts.size() / 3; i++)
|
||||
fprintf(objFile.get(), "v %f %f %f\n", verts[i*3], verts[i*3 + 1], verts[i*3 + 2]);
|
||||
for (std::size_t i = 0; i < allVerts.size() / 3; i++)
|
||||
fprintf(objFile.get(), "v %f %f %f\n", verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]);
|
||||
|
||||
for (int i = 0; i < allTris.size() / 3; i++)
|
||||
fprintf(objFile.get(), "f %i %i %i\n", tris[i*3] + 1, tris[i*3 + 1] + 1, tris[i*3 + 2] + 1);
|
||||
for (std::size_t i = 0; i < allTris.size() / 3; i++)
|
||||
fprintf(objFile.get(), "f %i %i %i\n", tris[i * 3] + 1, tris[i * 3 + 1] + 1, tris[i * 3 + 2] + 1);
|
||||
|
||||
TC_LOG_INFO("maps.mmapgen.debug", "[Map {:04}] [{:02},{:02}]: Writing debug output object file...", mapID, tileY, tileX);
|
||||
|
||||
|
||||
@@ -310,26 +310,20 @@ namespace MMAP
|
||||
if (fread(&indicesCount, sizeof(uint32), 1, file.get()) != 1)
|
||||
return;
|
||||
|
||||
std::unique_ptr<float[]> verts = std::make_unique<float[]>(verticesCount);
|
||||
if (fread(verts.get(), sizeof(float), verticesCount, file.get()) != verticesCount)
|
||||
return;
|
||||
|
||||
std::unique_ptr<int[]> inds = std::make_unique<int[]>(indicesCount);
|
||||
if (fread(inds.get(), sizeof(int), indicesCount, file.get()) != indicesCount)
|
||||
return;
|
||||
|
||||
MeshData data;
|
||||
|
||||
for (uint32 i = 0; i < verticesCount; ++i)
|
||||
data.solidVerts.append(verts[i]);
|
||||
data.solidVerts.resize(verticesCount);
|
||||
if (fread(data.solidVerts.data(), sizeof(float), verticesCount, file.get()) != verticesCount)
|
||||
return;
|
||||
|
||||
for (uint32 i = 0; i < indicesCount; ++i)
|
||||
data.solidTris.append(inds[i]);
|
||||
data.solidTris.resize(indicesCount);
|
||||
if (fread(data.solidTris.data(), sizeof(int), indicesCount, file.get()) != indicesCount)
|
||||
return;
|
||||
|
||||
TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris);
|
||||
// get bounds of current tile
|
||||
float bmin[3], bmax[3];
|
||||
TileBuilder::getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax);
|
||||
TileBuilder::getTileBounds(tileX, tileY, data.solidVerts.data(), data.solidVerts.size() / 3, bmin, bmax);
|
||||
|
||||
// build navmesh tile
|
||||
MapTileBuilder tileBuilder(this, m_maxWalkableAngle, m_maxWalkableAngleNotSteep,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "StringFormat.h"
|
||||
#include "Util.h"
|
||||
#include "VMapManager.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MMAP
|
||||
{
|
||||
@@ -123,8 +123,8 @@ namespace MMAP
|
||||
uint8 holes[16][16][8] = { };
|
||||
uint16 liquid_entry[16][16] = { };
|
||||
map_liquidHeaderTypeFlags liquid_flags[16][16] = { };
|
||||
G3D::Array<int> ltriangles;
|
||||
G3D::Array<int> ttriangles;
|
||||
std::vector<int> ltriangles;
|
||||
std::vector<int> ttriangles;
|
||||
|
||||
// terrain data
|
||||
if (haveTerrain)
|
||||
@@ -188,38 +188,35 @@ namespace MMAP
|
||||
}
|
||||
|
||||
int count = meshData.solidVerts.size() / 3;
|
||||
meshData.solidVerts.resize(meshData.solidVerts.size() + (V9_SIZE_SQ + V8_SIZE_SQ) * 3);
|
||||
float* solidVerts = meshData.solidVerts.data() + count * 3;
|
||||
|
||||
float xoffset = (float(tileX)-32)*GRID_SIZE;
|
||||
float yoffset = (float(tileY)-32)*GRID_SIZE;
|
||||
|
||||
float coord[3];
|
||||
|
||||
for (int i = 0; i < V9_SIZE_SQ; ++i)
|
||||
{
|
||||
getHeightCoord(i, GRID_V9, xoffset, yoffset, coord, V9);
|
||||
meshData.solidVerts.append(coord[0]);
|
||||
meshData.solidVerts.append(coord[2]);
|
||||
meshData.solidVerts.append(coord[1]);
|
||||
getHeightCoord(i, GRID_V9, xoffset, yoffset, solidVerts, V9);
|
||||
solidVerts += 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < V8_SIZE_SQ; ++i)
|
||||
{
|
||||
getHeightCoord(i, GRID_V8, xoffset, yoffset, coord, V8);
|
||||
meshData.solidVerts.append(coord[0]);
|
||||
meshData.solidVerts.append(coord[2]);
|
||||
meshData.solidVerts.append(coord[1]);
|
||||
getHeightCoord(i, GRID_V8, xoffset, yoffset, solidVerts, V8);
|
||||
solidVerts += 3;
|
||||
}
|
||||
|
||||
int indices[] = { 0, 0, 0 };
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0;
|
||||
getLoopVars(portion, loopStart, loopEnd, loopInc);
|
||||
for (int i = loopStart; i < loopEnd; i+=loopInc)
|
||||
for (int j = TOP; j <= BOTTOM; j+=1)
|
||||
{
|
||||
getHeightTriangle(i, Spot(j), indices);
|
||||
ttriangles.append(indices[2] + count);
|
||||
ttriangles.append(indices[1] + count);
|
||||
ttriangles.append(indices[0] + count);
|
||||
}
|
||||
{
|
||||
std::size_t trianglesOffset = ttriangles.size();
|
||||
ttriangles.resize(ttriangles.size() + 12);
|
||||
getHeightTriangle(i, TOP, ttriangles.data() + trianglesOffset + 0, count);
|
||||
getHeightTriangle(i, RIGHT, ttriangles.data() + trianglesOffset + 3, count);
|
||||
getHeightTriangle(i, LEFT, ttriangles.data() + trianglesOffset + 6, count);
|
||||
getHeightTriangle(i, BOTTOM, ttriangles.data() + trianglesOffset + 9, count);
|
||||
}
|
||||
}
|
||||
|
||||
// liquid data
|
||||
@@ -257,10 +254,11 @@ namespace MMAP
|
||||
}
|
||||
|
||||
int count = meshData.liquidVerts.size() / 3;
|
||||
meshData.liquidVerts.resize(meshData.liquidVerts.size() + V9_SIZE_SQ * 3);
|
||||
float* liquidVerts = meshData.liquidVerts.data();
|
||||
float xoffset = (float(tileX)-32)*GRID_SIZE;
|
||||
float yoffset = (float(tileY)-32)*GRID_SIZE;
|
||||
|
||||
float coord[3];
|
||||
int row, col;
|
||||
|
||||
// generate coordinates
|
||||
@@ -276,14 +274,13 @@ namespace MMAP
|
||||
col < lheader.offsetX || col >= lheader.offsetX + lheader.width)
|
||||
{
|
||||
// dummy vert using invalid height
|
||||
meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, INVALID_MAP_LIQ_HEIGHT, (yoffset+row*GRID_PART_SIZE)*-1);
|
||||
liquidVerts[(count + i) * 3 + 0] = (xoffset + col * GRID_PART_SIZE) * -1;
|
||||
liquidVerts[(count + i) * 3 + 1] = INVALID_MAP_LIQ_HEIGHT;
|
||||
liquidVerts[(count + i) * 3 + 2] = (yoffset + row * GRID_PART_SIZE) * -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
getLiquidCoord(i, j, xoffset, yoffset, coord, liquid_map.get());
|
||||
meshData.liquidVerts.append(coord[0]);
|
||||
meshData.liquidVerts.append(coord[2]);
|
||||
meshData.liquidVerts.append(coord[1]);
|
||||
getLiquidCoord(i, j, xoffset, yoffset, &liquidVerts[(count + i) * 3], liquid_map.get());
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -293,24 +290,22 @@ namespace MMAP
|
||||
{
|
||||
row = i / V9_SIZE;
|
||||
col = i % V9_SIZE;
|
||||
meshData.liquidVerts.append((xoffset+col*GRID_PART_SIZE)*-1, lheader.liquidLevel, (yoffset+row*GRID_PART_SIZE)*-1);
|
||||
liquidVerts[(count + i) * 3 + 0] = (xoffset + col * GRID_PART_SIZE) * -1;
|
||||
liquidVerts[(count + i) * 3 + 1] = lheader.liquidLevel;
|
||||
liquidVerts[(count + i) * 3 + 2] = (yoffset + row * GRID_PART_SIZE) * -1;
|
||||
}
|
||||
}
|
||||
|
||||
int indices[] = { 0, 0, 0 };
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0, triInc = BOTTOM-TOP;
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0;
|
||||
getLoopVars(portion, loopStart, loopEnd, loopInc);
|
||||
|
||||
// generate triangles
|
||||
for (int i = loopStart; i < loopEnd; i += loopInc)
|
||||
{
|
||||
for (int j = TOP; j <= BOTTOM; j += triInc)
|
||||
{
|
||||
getHeightTriangle(i, Spot(j), indices, true);
|
||||
ltriangles.append(indices[2] + count);
|
||||
ltriangles.append(indices[1] + count);
|
||||
ltriangles.append(indices[0] + count);
|
||||
}
|
||||
std::size_t trianglesOffset = ltriangles.size();
|
||||
ltriangles.resize(ltriangles.size() + 6);
|
||||
getHeightTriangle(i, TOP, ltriangles.data() + trianglesOffset + 0, count, true);
|
||||
getHeightTriangle(i, BOTTOM, ltriangles.data() + trianglesOffset + 3, count, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,11 +314,11 @@ namespace MMAP
|
||||
int loopStart = 0, loopEnd = 0, loopInc = 0, tTriCount = 4;
|
||||
bool useTerrain, useLiquid;
|
||||
|
||||
float* lverts = meshData.liquidVerts.getCArray();
|
||||
int* ltris = ltriangles.getCArray();
|
||||
float* lverts = meshData.liquidVerts.data();
|
||||
int* ltris = ltriangles.data();
|
||||
|
||||
float* tverts = meshData.solidVerts.getCArray();
|
||||
int* ttris = ttriangles.getCArray();
|
||||
float* tverts = meshData.solidVerts.data();
|
||||
int* ttris = ttriangles.data();
|
||||
|
||||
if ((ltriangles.size() + ttriangles.size()) == 0)
|
||||
return false;
|
||||
@@ -331,7 +326,7 @@ namespace MMAP
|
||||
// make a copy of liquid vertices
|
||||
// used to pad right-bottom frame due to lost vertex data at extraction
|
||||
std::unique_ptr<float[]> lverts_copy;
|
||||
if (meshData.liquidVerts.size())
|
||||
if (!meshData.liquidVerts.empty())
|
||||
{
|
||||
lverts_copy = std::make_unique<float[]>(meshData.liquidVerts.size());
|
||||
memcpy(lverts_copy.get(), lverts, sizeof(float)* meshData.liquidVerts.size());
|
||||
@@ -349,7 +344,7 @@ namespace MMAP
|
||||
uint8 navLiquidType = NAV_AREA_EMPTY;
|
||||
|
||||
// if there is no liquid, don't use liquid
|
||||
if (!meshData.liquidVerts.size() || !ltriangles.size())
|
||||
if (meshData.liquidVerts.empty() || ltriangles.empty())
|
||||
useLiquid = false;
|
||||
else
|
||||
{
|
||||
@@ -369,7 +364,7 @@ namespace MMAP
|
||||
}
|
||||
|
||||
// if there is no terrain, don't use terrain
|
||||
if (!ttriangles.size())
|
||||
if (ttriangles.empty())
|
||||
useTerrain = false;
|
||||
|
||||
// while extracting ADT data we are losing right-bottom vertices
|
||||
@@ -448,14 +443,12 @@ namespace MMAP
|
||||
// store the result
|
||||
if (useLiquid)
|
||||
{
|
||||
meshData.liquidType.append(navLiquidType);
|
||||
for (int k = 0; k < 3; ++k)
|
||||
meshData.liquidTris.append(ltris[k]);
|
||||
meshData.liquidTris.insert(meshData.liquidTris.end(), <ris[0], <ris[3]);
|
||||
meshData.liquidType.push_back(navLiquidType);
|
||||
}
|
||||
|
||||
if (useTerrain)
|
||||
for (int k = 0; k < 3*tTriCount/2; ++k)
|
||||
meshData.solidTris.append(ttris[k]);
|
||||
meshData.solidTris.insert(meshData.solidTris.end(), &ttris[0], &ttris[3 * tTriCount / 2]);
|
||||
|
||||
// advance to next set of triangles
|
||||
ltris += 3;
|
||||
@@ -463,88 +456,88 @@ namespace MMAP
|
||||
}
|
||||
}
|
||||
|
||||
return meshData.solidTris.size() || meshData.liquidTris.size();
|
||||
return !meshData.solidTris.empty() || !meshData.liquidTris.empty();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v)
|
||||
inline void TerrainBuilder::getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v)
|
||||
{
|
||||
// wow coords: x, y, height
|
||||
// coord is mirroed about the horizontal axes
|
||||
switch (grid)
|
||||
{
|
||||
case GRID_V9:
|
||||
coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f;
|
||||
coord[2] = v[index];
|
||||
coord[0] = (xOffset + (int)(index % V9_SIZE) * GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = v[index];
|
||||
coord[2] = (yOffset + (int)(index / (V9_SIZE)) * GRID_PART_SIZE) * -1.f;
|
||||
break;
|
||||
case GRID_V8:
|
||||
coord[0] = (xOffset + index%(V8_SIZE)*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V8_SIZE))*GRID_PART_SIZE + GRID_PART_SIZE/2.f) * -1.f;
|
||||
coord[2] = v[index];
|
||||
coord[0] = (xOffset + (int)(index % V8_SIZE) * GRID_PART_SIZE + GRID_PART_SIZE / 2.f) * -1.f;
|
||||
coord[1] = v[index];
|
||||
coord[2] = (yOffset + (int)(index / (V8_SIZE)) * GRID_PART_SIZE + GRID_PART_SIZE / 2.f) * -1.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, bool liquid/* = false*/)
|
||||
inline void TerrainBuilder::getHeightTriangle(int square, Spot triangle, int* indices, int offset, bool liquid/* = false*/)
|
||||
{
|
||||
int rowOffset = square/V8_SIZE;
|
||||
if (!liquid)
|
||||
switch (triangle)
|
||||
{
|
||||
case TOP:
|
||||
indices[0] = square+rowOffset; // 0-----1 .... 128
|
||||
indices[1] = square+1+rowOffset; // |\ T /|
|
||||
indices[2] = (V9_SIZE_SQ)+square; // | \ / |
|
||||
break; // |L 0 R| .. 127
|
||||
case LEFT: // | / \ |
|
||||
indices[0] = square+rowOffset; // |/ B \|
|
||||
indices[1] = (V9_SIZE_SQ)+square; // 129---130 ... 386
|
||||
indices[2] = square+V9_SIZE+rowOffset; // |\ /|
|
||||
break; // | \ / |
|
||||
case RIGHT: // | 128 | .. 255
|
||||
indices[0] = square+1+rowOffset; // | / \ |
|
||||
indices[1] = square+V9_SIZE+1+rowOffset; // |/ \|
|
||||
indices[2] = (V9_SIZE_SQ)+square; // 258---259 ... 515
|
||||
indices[0] = V9_SIZE_SQ + square + offset; // 0-----1 .... 128
|
||||
indices[1] = square + 1 + rowOffset + offset; // |\ T /|
|
||||
indices[2] = square + rowOffset + offset; // | \ / |
|
||||
break; // |L 0 R| .. 127
|
||||
case LEFT: // | / \ |
|
||||
indices[0] = square + V9_SIZE + rowOffset + offset; // |/ B \|
|
||||
indices[1] = V9_SIZE_SQ + square + offset; // 129---130 ... 386
|
||||
indices[2] = square + rowOffset + offset; // |\ /|
|
||||
break; // | \ / |
|
||||
case RIGHT: // | 128 | .. 255
|
||||
indices[0] = V9_SIZE_SQ + square + offset; // | / \ |
|
||||
indices[1] = square + V9_SIZE + 1 + rowOffset + offset; // |/ \|
|
||||
indices[2] = square + 1 + rowOffset + offset; // 258---259 ... 515
|
||||
break;
|
||||
case BOTTOM:
|
||||
indices[0] = (V9_SIZE_SQ)+square;
|
||||
indices[1] = square+V9_SIZE+1+rowOffset;
|
||||
indices[2] = square+V9_SIZE+rowOffset;
|
||||
indices[0] = square + V9_SIZE + rowOffset + offset;
|
||||
indices[1] = square + V9_SIZE + 1 + rowOffset + offset;
|
||||
indices[2] = V9_SIZE_SQ + square + offset;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
else
|
||||
switch (triangle)
|
||||
{ // 0-----1 .... 128
|
||||
case TOP: // |\ |
|
||||
indices[0] = square+rowOffset; // | \ T |
|
||||
indices[1] = square+1+rowOffset; // | \ |
|
||||
indices[2] = square+V9_SIZE+1+rowOffset; // | B \ |
|
||||
break; // | \|
|
||||
case BOTTOM: // 129---130 ... 386
|
||||
indices[0] = square+rowOffset; // |\ |
|
||||
indices[1] = square+V9_SIZE+1+rowOffset; // | \ |
|
||||
indices[2] = square+V9_SIZE+rowOffset; // | \ |
|
||||
break; // | \ |
|
||||
default: break; // | \|
|
||||
} // 258---259 ... 515
|
||||
{ // 0-----1 .... 128
|
||||
case TOP: // |\ |
|
||||
indices[0] = square + V9_SIZE + 1 + rowOffset + offset; // | \ T |
|
||||
indices[1] = square + 1 + rowOffset + offset; // | \ |
|
||||
indices[2] = square + rowOffset + offset; // | B \ |
|
||||
break; // | \|
|
||||
case BOTTOM: // 129---130 ... 386
|
||||
indices[0] = square + V9_SIZE + rowOffset + offset; // |\ |
|
||||
indices[1] = square + V9_SIZE + 1 + rowOffset + offset; // | \ |
|
||||
indices[2] = square + rowOffset + offset; // | \ |
|
||||
break; // | \ |
|
||||
default: break; // | \|
|
||||
} // 258---259 ... 515
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v)
|
||||
inline void TerrainBuilder::getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v)
|
||||
{
|
||||
// wow coords: x, y, height
|
||||
// coord is mirroed about the horizontal axes
|
||||
coord[0] = (xOffset + index%(V9_SIZE)*GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = (yOffset + (int)(index/(V9_SIZE))*GRID_PART_SIZE) * -1.f;
|
||||
coord[2] = v[index2];
|
||||
coord[0] = (xOffset + (int)(index % V9_SIZE) * GRID_PART_SIZE) * -1.f;
|
||||
coord[1] = v[index2];
|
||||
coord[2] = (yOffset + (int)(index / (V9_SIZE)) * GRID_PART_SIZE) * -1.f;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
bool TerrainBuilder::isHole(int square, uint8 const (&holes)[16][16][8])
|
||||
inline bool TerrainBuilder::isHole(int square, uint8 const (&holes)[16][16][8])
|
||||
{
|
||||
int row = square / 128;
|
||||
int col = square % 128;
|
||||
@@ -557,7 +550,7 @@ namespace MMAP
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
map_liquidHeaderTypeFlags TerrainBuilder::getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16])
|
||||
inline map_liquidHeaderTypeFlags TerrainBuilder::getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16])
|
||||
{
|
||||
int row = square / 128;
|
||||
int col = square % 128;
|
||||
@@ -602,36 +595,27 @@ namespace MMAP
|
||||
|
||||
// transform data
|
||||
float scale = instance.iScale;
|
||||
G3D::Matrix3 rotation = instance.GetInvRot();
|
||||
G3D::Matrix3 const& rotation = instance.GetInvRot();
|
||||
G3D::Vector3 position = instance.iPos;
|
||||
position.x -= 32 * GRID_SIZE;
|
||||
position.y -= 32 * GRID_SIZE;
|
||||
|
||||
for (std::vector<VMAP::GroupModel>::const_iterator it = groupModels.begin(); it != groupModels.end(); ++it)
|
||||
{
|
||||
std::vector<G3D::Vector3> const& tempVertices = it->GetVertices();
|
||||
std::vector<G3D::Vector3> transformedVertices;
|
||||
std::vector<VMAP::MeshTriangle> const& tempTriangles = it->GetTriangles();
|
||||
VMAP::WmoLiquid const* liquid = it->GetLiquid();
|
||||
|
||||
// first handle collision mesh
|
||||
transform(tempVertices, transformedVertices, scale, rotation, position);
|
||||
|
||||
int offset = meshData.solidVerts.size() / 3;
|
||||
|
||||
copyVertices(transformedVertices, meshData.solidVerts);
|
||||
copyIndices(tempTriangles, meshData.solidTris, offset, isM2);
|
||||
transformVertices(it->GetVertices(), meshData.solidVerts, scale, rotation, position);
|
||||
copyIndices(it->GetTriangles(), meshData.solidTris, offset, isM2);
|
||||
|
||||
// now handle liquid data
|
||||
VMAP::WmoLiquid const* liquid = it->GetLiquid();
|
||||
if (liquid && liquid->GetFlagsStorage())
|
||||
{
|
||||
std::vector<G3D::Vector3> liqVerts;
|
||||
std::vector<int> liqTris;
|
||||
uint32 tilesX, tilesY, vertsX, vertsY;
|
||||
uint32 tilesX, tilesY;
|
||||
G3D::Vector3 corner;
|
||||
liquid->getPosInfo(tilesX, tilesY, corner);
|
||||
vertsX = tilesX + 1;
|
||||
vertsY = tilesY + 1;
|
||||
uint32 vertsX = tilesX + 1;
|
||||
uint32 vertsY = tilesY + 1;
|
||||
uint8 const* flags = liquid->GetFlagsStorage();
|
||||
float const* data = liquid->GetHeightStorage();
|
||||
uint8 type = NAV_AREA_EMPTY;
|
||||
@@ -649,54 +633,56 @@ namespace MMAP
|
||||
// tile = x*tilesY+y
|
||||
// flag = y*tilesY+x
|
||||
|
||||
G3D::Vector3 vert;
|
||||
uint32 liqOffset = meshData.liquidVerts.size() / 3;
|
||||
meshData.liquidVerts.resize(meshData.liquidVerts.size() + vertsX * vertsY * 3);
|
||||
float* liquidVerts = meshData.liquidVerts.data();
|
||||
for (uint32 x = 0; x < vertsX; ++x)
|
||||
{
|
||||
for (uint32 y = 0; y < vertsY; ++y)
|
||||
{
|
||||
vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]);
|
||||
G3D::Vector3 vert = G3D::Vector3(corner.x + x * GRID_PART_SIZE, corner.y + y * GRID_PART_SIZE, data[y * vertsX + x]);
|
||||
vert = vert * rotation * scale + position;
|
||||
vert.x *= -1.f;
|
||||
vert.y *= -1.f;
|
||||
liqVerts.push_back(vert);
|
||||
liquidVerts[(liqOffset + x * vertsY + y) * 3 + 0] = vert.y;
|
||||
liquidVerts[(liqOffset + x * vertsY + y) * 3 + 1] = vert.z;
|
||||
liquidVerts[(liqOffset + x * vertsY + y) * 3 + 2] = vert.x;
|
||||
}
|
||||
}
|
||||
|
||||
int idx1, idx2, idx3, idx4;
|
||||
uint32 square;
|
||||
std::size_t liquidSquares = 0;
|
||||
for (uint32 x = 0; x < tilesX; ++x)
|
||||
{
|
||||
for (uint32 y = 0; y < tilesY; ++y)
|
||||
{
|
||||
if ((flags[x + y * tilesX] & 0x0f) != 0x0f)
|
||||
{
|
||||
square = x * tilesY + y;
|
||||
idx1 = square + x;
|
||||
idx2 = square + 1 + x;
|
||||
idx3 = square + tilesY + 1 + 1 + x;
|
||||
idx4 = square + tilesY + 1 + x;
|
||||
uint32 square = x * tilesY + y;
|
||||
int idx1 = square + x;
|
||||
int idx2 = square + 1 + x;
|
||||
int idx3 = square + tilesY + 1 + 1 + x;
|
||||
int idx4 = square + tilesY + 1 + x;
|
||||
|
||||
std::size_t liquidTriOffset = meshData.liquidTris.size();
|
||||
meshData.liquidTris.resize(liquidTriOffset + 6);
|
||||
int* liquidTris = meshData.liquidTris.data() + liquidTriOffset;
|
||||
|
||||
// top triangle
|
||||
liqTris.push_back(idx3);
|
||||
liqTris.push_back(idx2);
|
||||
liqTris.push_back(idx1);
|
||||
liquidTris[0] = idx2 + liqOffset;
|
||||
liquidTris[1] = idx1 + liqOffset;
|
||||
liquidTris[2] = idx3 + liqOffset;
|
||||
|
||||
// bottom triangle
|
||||
liqTris.push_back(idx4);
|
||||
liqTris.push_back(idx3);
|
||||
liqTris.push_back(idx1);
|
||||
liquidTris[3] = idx3 + liqOffset;
|
||||
liquidTris[4] = idx1 + liqOffset;
|
||||
liquidTris[5] = idx4 + liqOffset;
|
||||
|
||||
++liquidSquares;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 liqOffset = meshData.liquidVerts.size() / 3;
|
||||
for (uint32 i = 0; i < liqVerts.size(); ++i)
|
||||
meshData.liquidVerts.append(liqVerts[i].y, liqVerts[i].z, liqVerts[i].x);
|
||||
|
||||
for (uint32 i = 0; i < liqTris.size() / 3; ++i)
|
||||
{
|
||||
meshData.liquidTris.append(liqTris[i * 3 + 1] + liqOffset, liqTris[i * 3 + 2] + liqOffset, liqTris[i * 3] + liqOffset);
|
||||
meshData.liquidType.append(type);
|
||||
}
|
||||
meshData.liquidType.resize(meshData.liquidType.size() + liquidSquares * 2, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -705,105 +691,90 @@ namespace MMAP
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::transform(std::vector<G3D::Vector3> const& source, std::vector<G3D::Vector3>& transformedVertices, float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position)
|
||||
void TerrainBuilder::transformVertices(std::vector<G3D::Vector3> const& source, std::vector<float>& dest, float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position)
|
||||
{
|
||||
transformedVertices.reserve(transformedVertices.size() + source.size());
|
||||
for (G3D::Vector3 const& vertex : source)
|
||||
std::size_t offset = dest.size();
|
||||
dest.resize(dest.size() + source.size() * 3);
|
||||
float* d = dest.data();
|
||||
for (std::size_t i = 0; i < source.size(); ++i)
|
||||
{
|
||||
// apply tranform, then mirror along the horizontal axes
|
||||
G3D::Vector3 v(vertex * rotation * scale + position);
|
||||
G3D::Vector3 v(source[i] * rotation * scale + position);
|
||||
v.x *= -1.f;
|
||||
v.y *= -1.f;
|
||||
transformedVertices.push_back(v);
|
||||
d[offset + i * 3 + 0] = v.y;
|
||||
d[offset + i * 3 + 1] = v.z;
|
||||
d[offset + i * 3 + 2] = v.x;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyVertices(std::vector<G3D::Vector3> const& source, G3D::Array<float>& dest)
|
||||
void TerrainBuilder::copyIndices(std::vector<VMAP::MeshTriangle> const& source, std::vector<int>& dest, int offset, bool flip)
|
||||
{
|
||||
dest.reserve(dest.size() + source.size() * 3);
|
||||
for (G3D::Vector3 const& vertex : source)
|
||||
{
|
||||
dest.push_back(vertex.y);
|
||||
dest.push_back(vertex.z);
|
||||
dest.push_back(vertex.x);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyIndices(std::vector<VMAP::MeshTriangle> const& source, G3D::Array<int>& dest, int offset, bool flip)
|
||||
{
|
||||
dest.reserve(dest.size() + source.size() * 3);
|
||||
std::size_t destOffset = dest.size();
|
||||
dest.resize(dest.size() + source.size() * 3);
|
||||
int* d = dest.data();
|
||||
if (flip)
|
||||
{
|
||||
for (VMAP::MeshTriangle const& triangle : source)
|
||||
{
|
||||
dest.push_back(triangle.idx2 + offset);
|
||||
dest.push_back(triangle.idx1 + offset);
|
||||
dest.push_back(triangle.idx0 + offset);
|
||||
d[destOffset++] = triangle.idx2 + offset;
|
||||
d[destOffset++] = triangle.idx1 + offset;
|
||||
d[destOffset++] = triangle.idx0 + offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (VMAP::MeshTriangle const& triangle : source)
|
||||
{
|
||||
dest.push_back(triangle.idx0 + offset);
|
||||
dest.push_back(triangle.idx1 + offset);
|
||||
dest.push_back(triangle.idx2 + offset);
|
||||
}
|
||||
static_assert(sizeof(VMAP::MeshTriangle) == 3 * sizeof(uint32));
|
||||
std::ranges::transform(reinterpret_cast<uint32 const*>(source.data()), reinterpret_cast<uint32 const*>(source.data() + source.size()),
|
||||
dest.data() + destOffset, [&](int src) { return src + offset; });
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::copyIndices(G3D::Array<int> const& source, G3D::Array<int>& dest, int offset)
|
||||
void TerrainBuilder::copyIndices(std::vector<int> const& source, std::vector<int>& dest, int offset)
|
||||
{
|
||||
int const* src = source.getCArray();
|
||||
dest.reserve(dest.size() + source.size());
|
||||
for (int32 i = 0; i < source.size(); ++i)
|
||||
dest.append(src[i] + offset);
|
||||
std::size_t destOffset = dest.size();
|
||||
dest.resize(destOffset + source.size());
|
||||
std::ranges::transform(source, dest.data() + destOffset, [&](int src) { return src + offset; });
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
void TerrainBuilder::cleanVertices(G3D::Array<float>& verts, G3D::Array<int>& tris)
|
||||
void TerrainBuilder::cleanVertices(std::vector<float>& verts, std::vector<int>& tris)
|
||||
{
|
||||
std::map<int, int> vertMap;
|
||||
std::unordered_map<int, int> vertMap;
|
||||
vertMap.reserve(tris.size());
|
||||
|
||||
int* t = tris.getCArray();
|
||||
float* v = verts.getCArray();
|
||||
int* t = tris.data();
|
||||
float* v = verts.data();
|
||||
|
||||
G3D::Array<float> cleanVerts;
|
||||
int index, count = 0;
|
||||
std::vector<float> cleanVerts;
|
||||
cleanVerts.reserve(verts.size());
|
||||
int count = 0;
|
||||
// collect all the vertex indices from triangle
|
||||
for (int i = 0; i < tris.size(); ++i)
|
||||
for (std::size_t i = 0; i < tris.size(); ++i)
|
||||
{
|
||||
if (vertMap.find(t[i]) != vertMap.end())
|
||||
auto [vertItr, isNew] = vertMap.try_emplace(t[i], count);
|
||||
if (!isNew)
|
||||
continue;
|
||||
std::pair<int, int> val;
|
||||
val.first = t[i];
|
||||
|
||||
index = val.first;
|
||||
val.second = count;
|
||||
std::ptrdiff_t index = t[i];
|
||||
|
||||
vertMap.insert(val);
|
||||
cleanVerts.append(v[index * 3], v[index * 3 + 1], v[index * 3 + 2]);
|
||||
cleanVerts.insert(cleanVerts.end(), &v[index * 3], &v[index * 3 + 3]);
|
||||
count++;
|
||||
}
|
||||
|
||||
verts.fastClear();
|
||||
verts.append(cleanVerts);
|
||||
cleanVerts.clear();
|
||||
verts = std::move(cleanVerts);
|
||||
|
||||
// update triangles to use new indices
|
||||
for (int i = 0; i < tris.size(); ++i)
|
||||
for (std::size_t i = 0; i < tris.size(); ++i)
|
||||
{
|
||||
std::map<int, int>::iterator it;
|
||||
if ((it = vertMap.find(t[i])) == vertMap.end())
|
||||
auto it = vertMap.find(t[i]);
|
||||
if (it == vertMap.end())
|
||||
continue;
|
||||
|
||||
t[i] = (*it).second;
|
||||
t[i] = it->second;
|
||||
}
|
||||
|
||||
vertMap.clear();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
@@ -814,19 +785,19 @@ namespace MMAP
|
||||
if (mapID != offMeshConnection.MapId || tileX != offMeshConnection.TileX || tileY != offMeshConnection.TileY)
|
||||
continue;
|
||||
|
||||
meshData.offMeshConnections.append(offMeshConnection.From[1]);
|
||||
meshData.offMeshConnections.append(offMeshConnection.From[2]);
|
||||
meshData.offMeshConnections.append(offMeshConnection.From[0]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.From[1]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.From[2]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.From[0]);
|
||||
|
||||
meshData.offMeshConnections.append(offMeshConnection.To[1]);
|
||||
meshData.offMeshConnections.append(offMeshConnection.To[2]);
|
||||
meshData.offMeshConnections.append(offMeshConnection.To[0]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.To[1]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.To[2]);
|
||||
meshData.offMeshConnections.push_back(offMeshConnection.To[0]);
|
||||
|
||||
meshData.offMeshConnectionDirs.append(offMeshConnection.Bidirectional ? 1 : 0);
|
||||
meshData.offMeshConnectionRads.append(offMeshConnection.Radius); // agent size equivalent
|
||||
meshData.offMeshConnectionDirs.push_back(offMeshConnection.Bidirectional ? 1 : 0);
|
||||
meshData.offMeshConnectionRads.push_back(offMeshConnection.Radius); // agent size equivalent
|
||||
// can be used same way as polygon flags
|
||||
meshData.offMeshConnectionsAreas.append(offMeshConnection.AreaId);
|
||||
meshData.offMeshConnectionsFlags.append(offMeshConnection.Flags);
|
||||
meshData.offMeshConnectionsAreas.push_back(offMeshConnection.AreaId);
|
||||
meshData.offMeshConnectionsFlags.push_back(offMeshConnection.Flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#define _MMAP_TERRAIN_BUILDER_H
|
||||
|
||||
#include "WorldModel.h"
|
||||
|
||||
#include <G3D/Array.h>
|
||||
#include <G3D/Vector3.h>
|
||||
|
||||
namespace VMAP
|
||||
@@ -77,19 +75,19 @@ namespace MMAP
|
||||
|
||||
struct MeshData
|
||||
{
|
||||
G3D::Array<float> solidVerts;
|
||||
G3D::Array<int> solidTris;
|
||||
std::vector<float> solidVerts;
|
||||
std::vector<int> solidTris;
|
||||
|
||||
G3D::Array<float> liquidVerts;
|
||||
G3D::Array<int> liquidTris;
|
||||
G3D::Array<uint8> liquidType;
|
||||
std::vector<float> liquidVerts;
|
||||
std::vector<int> liquidTris;
|
||||
std::vector<uint8> liquidType;
|
||||
|
||||
// offmesh connection data
|
||||
G3D::Array<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection
|
||||
G3D::Array<float> offMeshConnectionRads;
|
||||
G3D::Array<unsigned char> offMeshConnectionDirs;
|
||||
G3D::Array<unsigned char> offMeshConnectionsAreas;
|
||||
G3D::Array<unsigned short> offMeshConnectionsFlags;
|
||||
std::vector<float> offMeshConnections; // [p0y,p0z,p0x,p1y,p1z,p1x] - per connection
|
||||
std::vector<float> offMeshConnectionRads;
|
||||
std::vector<unsigned char> offMeshConnectionDirs;
|
||||
std::vector<unsigned char> offMeshConnectionsAreas;
|
||||
std::vector<unsigned short> offMeshConnectionsFlags;
|
||||
};
|
||||
|
||||
class TerrainBuilder
|
||||
@@ -104,36 +102,35 @@ namespace MMAP
|
||||
bool usesLiquids() const { return !m_skipLiquid; }
|
||||
|
||||
// vert and triangle methods
|
||||
static void transform(std::vector<G3D::Vector3> const& source, std::vector<G3D::Vector3>& transformed,
|
||||
static void transformVertices(std::vector<G3D::Vector3> const& source, std::vector<float>& dest,
|
||||
float scale, G3D::Matrix3 const& rotation, G3D::Vector3 const& position);
|
||||
static void copyVertices(std::vector<G3D::Vector3> const& source, G3D::Array<float>& dest);
|
||||
static void copyIndices(std::vector<VMAP::MeshTriangle> const& source, G3D::Array<int>& dest, int offset, bool flip);
|
||||
static void copyIndices(G3D::Array<int> const& source, G3D::Array<int>& dest, int offset);
|
||||
static void cleanVertices(G3D::Array<float>& verts, G3D::Array<int>& tris);
|
||||
static void copyIndices(std::vector<VMAP::MeshTriangle> const& source, std::vector<int>& dest, int offset, bool flip);
|
||||
static void copyIndices(std::vector<int> const& source, std::vector<int>& dest, int offset);
|
||||
static void cleanVertices(std::vector<float>& verts, std::vector<int>& tris);
|
||||
private:
|
||||
/// Loads a portion of a map's terrain
|
||||
bool loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, VMAP::VMapManager* vmapManager, Spot portion);
|
||||
|
||||
/// Sets loop variables for selecting only certain parts of a map's terrain
|
||||
void getLoopVars(Spot portion, int& loopStart, int& loopEnd, int& loopInc);
|
||||
static void getLoopVars(Spot portion, int& loopStart, int& loopEnd, int& loopInc);
|
||||
|
||||
/// Controls whether liquids are loaded
|
||||
bool m_skipLiquid;
|
||||
|
||||
/// Get the vector coordinate for a specific position
|
||||
void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v);
|
||||
static void getHeightCoord(int index, Grid grid, float xOffset, float yOffset, float* coord, float* v);
|
||||
|
||||
/// Get the triangle's vector indices for a specific position
|
||||
void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false);
|
||||
static void getHeightTriangle(int square, Spot triangle, int* indices, int offset, bool liquid = false);
|
||||
|
||||
/// Determines if the specific position's triangles should be rendered
|
||||
bool isHole(int square, uint8 const (&holes)[16][16][8]);
|
||||
static bool isHole(int square, uint8 const (&holes)[16][16][8]);
|
||||
|
||||
/// Get the liquid vector coordinate for a specific position
|
||||
void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v);
|
||||
static void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v);
|
||||
|
||||
/// Get the liquid type for a specific position
|
||||
map_liquidHeaderTypeFlags getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]);
|
||||
static map_liquidHeaderTypeFlags getLiquidType(int square, map_liquidHeaderTypeFlags const (&liquid_type)[16][16]);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace MMAP
|
||||
m_terrainBuilder.loadVMap(mapID, tileY, tileX, meshData, vmapManager.get());
|
||||
|
||||
// if there is no data, give up now
|
||||
if (!meshData.solidVerts.size() && !meshData.liquidVerts.size())
|
||||
if (meshData.solidVerts.empty() && meshData.liquidVerts.empty())
|
||||
{
|
||||
OnTileDone();
|
||||
return;
|
||||
@@ -115,20 +115,21 @@ namespace MMAP
|
||||
TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris);
|
||||
TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris);
|
||||
|
||||
// gather all mesh data for final data check, and bounds calculation
|
||||
G3D::Array<float> allVerts;
|
||||
allVerts.append(meshData.liquidVerts);
|
||||
allVerts.append(meshData.solidVerts);
|
||||
|
||||
if (!allVerts.size())
|
||||
if (meshData.liquidVerts.empty() && meshData.solidVerts.empty())
|
||||
{
|
||||
OnTileDone();
|
||||
return;
|
||||
}
|
||||
|
||||
// gather all mesh data for final data check, and bounds calculation
|
||||
std::vector<float> allVerts(meshData.liquidVerts.size() + meshData.solidVerts.size());
|
||||
auto allVertsOutput = allVerts.begin();
|
||||
allVertsOutput = std::ranges::copy(meshData.liquidVerts, allVertsOutput).out;
|
||||
allVertsOutput = std::ranges::copy(meshData.solidVerts, allVertsOutput).out;
|
||||
|
||||
// get bounds of current tile
|
||||
float bmin[3], bmax[3];
|
||||
getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax);
|
||||
getTileBounds(tileX, tileY, allVerts.data(), allVerts.size() / 3, bmin, bmax);
|
||||
|
||||
if (m_offMeshConnections)
|
||||
m_terrainBuilder.loadOffMeshConnections(mapID, tileX, tileY, meshData, *m_offMeshConnections);
|
||||
@@ -150,16 +151,16 @@ namespace MMAP
|
||||
|
||||
IntermediateValues iv;
|
||||
|
||||
float* tVerts = meshData.solidVerts.getCArray();
|
||||
float* tVerts = meshData.solidVerts.data();
|
||||
int tVertCount = meshData.solidVerts.size() / 3;
|
||||
int* tTris = meshData.solidTris.getCArray();
|
||||
int* tTris = meshData.solidTris.data();
|
||||
int tTriCount = meshData.solidTris.size() / 3;
|
||||
|
||||
float* lVerts = meshData.liquidVerts.getCArray();
|
||||
float* lVerts = meshData.liquidVerts.data();
|
||||
int lVertCount = meshData.liquidVerts.size() / 3;
|
||||
int* lTris = meshData.liquidTris.getCArray();
|
||||
int* lTris = meshData.liquidTris.data();
|
||||
int lTriCount = meshData.liquidTris.size() / 3;
|
||||
uint8* lTriFlags = meshData.liquidType.getCArray();
|
||||
uint8* lTriFlags = meshData.liquidType.data();
|
||||
|
||||
const TileConfig tileConfig = TileConfig(m_bigBaseUnit);
|
||||
int TILES_PER_MAP = tileConfig.TILES_PER_MAP;
|
||||
@@ -348,12 +349,12 @@ namespace MMAP
|
||||
params.detailTris = iv.polyMeshDetail->tris;
|
||||
params.detailTriCount = iv.polyMeshDetail->ntris;
|
||||
|
||||
params.offMeshConVerts = meshData.offMeshConnections.getCArray();
|
||||
params.offMeshConVerts = meshData.offMeshConnections.data();
|
||||
params.offMeshConCount = meshData.offMeshConnections.size() / 6;
|
||||
params.offMeshConRad = meshData.offMeshConnectionRads.getCArray();
|
||||
params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray();
|
||||
params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray();
|
||||
params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray();
|
||||
params.offMeshConRad = meshData.offMeshConnectionRads.data();
|
||||
params.offMeshConDir = meshData.offMeshConnectionDirs.data();
|
||||
params.offMeshConAreas = meshData.offMeshConnectionsAreas.data();
|
||||
params.offMeshConFlags = meshData.offMeshConnectionsFlags.data();
|
||||
|
||||
params.walkableHeight = BASE_UNIT_DIM * config.walkableHeight; // agent height
|
||||
params.walkableRadius = BASE_UNIT_DIM * config.walkableRadius; // agent radius
|
||||
|
||||
Reference in New Issue
Block a user