mirror of
https://github.com/recastnavigation/recastnavigation.git
synced 2026-10-02 15:05:40 +00:00
Remove MeshLoaderObj class. Replace with parseObjModel function
This commit is contained in:
@@ -70,8 +70,19 @@ struct BuildSettings
|
||||
|
||||
class InputGeom
|
||||
{
|
||||
public:
|
||||
std::string filename;
|
||||
|
||||
// Mesh data
|
||||
std::vector<float> verts;
|
||||
std::vector<int> tris;
|
||||
std::vector<float> normals;
|
||||
|
||||
int getVertCount() const { return static_cast<int>(verts.size()) / 3; }
|
||||
int getTriCount() const { return static_cast<int>(tris.size()) / 3; }
|
||||
|
||||
private:
|
||||
ChunkyTriMesh* chunkyMesh = nullptr;
|
||||
MeshLoaderObj* meshLoader = nullptr;
|
||||
float meshBMin[3] = {};
|
||||
float meshBMax[3] = {};
|
||||
BuildSettings buildSettings;
|
||||
@@ -105,7 +116,6 @@ public:
|
||||
~InputGeom()
|
||||
{
|
||||
delete chunkyMesh;
|
||||
delete meshLoader;
|
||||
}
|
||||
InputGeom(const InputGeom&) = delete;
|
||||
InputGeom& operator=(const InputGeom&) = delete;
|
||||
@@ -116,7 +126,6 @@ public:
|
||||
bool saveGeomSet(const BuildSettings* settings);
|
||||
|
||||
/// Method to return static mesh data.
|
||||
const MeshLoaderObj* getMesh() const { return meshLoader; }
|
||||
const float* getMeshBoundsMin() const { return meshBMin; }
|
||||
const float* getMeshBoundsMax() const { return meshBMax; }
|
||||
const float* getNavMeshBoundsMin() const { return hasBuildSettings ? buildSettings.navMeshBMin : meshBMin; }
|
||||
|
||||
@@ -18,25 +18,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class MeshLoaderObj
|
||||
{
|
||||
public:
|
||||
void load(char* buf, size_t bufLen);
|
||||
|
||||
[[nodiscard]] const float* getVerts() const { return verts.data(); }
|
||||
[[nodiscard]] const float* getNormals() const { return normals.data(); }
|
||||
[[nodiscard]] const int* getTris() const { return tris.data(); }
|
||||
[[nodiscard]] int getVertCount() const { return static_cast<int>(verts.size()) / 3; }
|
||||
[[nodiscard]] int getTriCount() const { return static_cast<int>(tris.size()) / 3; }
|
||||
[[nodiscard]] const std::string& getFileName() const { return filename; }
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
|
||||
std::vector<float> verts;
|
||||
std::vector<int> tris;
|
||||
std::vector<float> normals;
|
||||
};
|
||||
void parseObjModel(char* buf, size_t bufLen, std::vector<float>& verts, std::vector<int>& tris, std::vector<float>& normals);
|
||||
|
||||
@@ -143,21 +143,16 @@ bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
|
||||
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath.c_str());
|
||||
return false;
|
||||
}
|
||||
filename = filepath;
|
||||
|
||||
if (meshLoader)
|
||||
{
|
||||
delete chunkyMesh;
|
||||
chunkyMesh = nullptr;
|
||||
delete meshLoader;
|
||||
meshLoader = nullptr;
|
||||
}
|
||||
delete chunkyMesh;
|
||||
chunkyMesh = nullptr;
|
||||
offMeshConCount = 0;
|
||||
volumeCount = 0;
|
||||
|
||||
meshLoader = new MeshLoaderObj;
|
||||
meshLoader->load(buffer, bufferLen);
|
||||
parseObjModel(buffer, bufferLen, verts, tris, normals);
|
||||
|
||||
rcCalcBounds(meshLoader->getVerts(), meshLoader->getVertCount(), meshBMin, meshBMax);
|
||||
rcCalcBounds(verts.data(), getVertCount(), meshBMin, meshBMax);
|
||||
|
||||
chunkyMesh = new ChunkyTriMesh;
|
||||
if (!chunkyMesh)
|
||||
@@ -165,7 +160,7 @@ bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath)
|
||||
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'm_chunkyMesh'.");
|
||||
return false;
|
||||
}
|
||||
if (!chunkyMesh->TryPartitionMesh(meshLoader->getVerts(), meshLoader->getTris(), meshLoader->getTriCount(), 256))
|
||||
if (!chunkyMesh->TryPartitionMesh(verts.data(), tris.data(), getTriCount(), 256))
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Failed to build chunky mesh.");
|
||||
return false;
|
||||
@@ -224,9 +219,6 @@ bool InputGeom::loadGeomSet(rcContext* ctx, char* buffer, size_t bufferLen)
|
||||
offMeshConCount = 0;
|
||||
volumeCount = 0;
|
||||
|
||||
delete meshLoader;
|
||||
meshLoader = nullptr;
|
||||
|
||||
char* src = buffer;
|
||||
char* srcEnd = buffer + bufferLen;
|
||||
char row[512];
|
||||
@@ -355,13 +347,13 @@ bool InputGeom::load(rcContext* ctx, const std::string& filepath)
|
||||
|
||||
bool InputGeom::saveGeomSet(const BuildSettings* settings)
|
||||
{
|
||||
if (!meshLoader)
|
||||
if (verts.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Change extension
|
||||
std::string filepath = meshLoader->getFileName();
|
||||
std::string filepath = filename;
|
||||
size_t extPos = filepath.find_last_of('.');
|
||||
if (extPos != std::string::npos)
|
||||
{
|
||||
@@ -376,7 +368,7 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings)
|
||||
}
|
||||
|
||||
// Store mesh filename.
|
||||
fprintf(fp, "f %s\n", meshLoader->getFileName().c_str());
|
||||
fprintf(fp, "f %s\n", filename.c_str());
|
||||
|
||||
// Store settings if any
|
||||
if (settings)
|
||||
@@ -502,7 +494,6 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
|
||||
|
||||
tmin = 1.0f;
|
||||
bool hit = false;
|
||||
const float* verts = meshLoader->getVerts();
|
||||
|
||||
for (int i = 0; i < ncid; ++i)
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ int readFace(char* row, int* data, int maxDataLen, int vertCount)
|
||||
}
|
||||
}
|
||||
|
||||
void MeshLoaderObj::load(char* buf, size_t bufLen)
|
||||
void parseObjModel(char* buf, size_t bufLen, std::vector<float>& verts, std::vector<int>& tris, std::vector<float>& normals)
|
||||
{
|
||||
char* src = buf;
|
||||
char* srcEnd = buf + bufLen;
|
||||
@@ -133,13 +133,14 @@ void MeshLoaderObj::load(char* buf, size_t bufLen)
|
||||
if (row[0] == 'f')
|
||||
{
|
||||
// Face
|
||||
numVertices = readFace(row + 1, face, sizeof(face) / sizeof(face[0]), getVertCount());
|
||||
const int vertCount = static_cast<int>(verts.size()) / 3;
|
||||
numVertices = readFace(row + 1, face, sizeof(face) / sizeof(face[0]), vertCount);
|
||||
for (int i = 2; i < numVertices; ++i)
|
||||
{
|
||||
const int a = face[0];
|
||||
const int b = face[i - 1];
|
||||
const int c = face[i];
|
||||
if (a < 0 || a >= getVertCount() || b < 0 || b >= getVertCount() || c < 0 || c >= getVertCount())
|
||||
if (a < 0 || a >= vertCount || b < 0 || b >= vertCount || c < 0 || c >= vertCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -151,8 +152,8 @@ void MeshLoaderObj::load(char* buf, size_t bufLen)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate normals.
|
||||
normals.resize(getTriCount() * 3);
|
||||
// Calculate face normals.
|
||||
normals.resize(tris.size());
|
||||
for (int i = 0; i < static_cast<int>(tris.size()); i += 3)
|
||||
{
|
||||
const float* vertex0 = &verts[tris[i + 0] * 3];
|
||||
|
||||
@@ -124,11 +124,11 @@ void Sample::handleRender()
|
||||
// Draw mesh
|
||||
duDebugDrawTriMesh(
|
||||
&debugDraw,
|
||||
inputGeometry->getMesh()->getVerts(),
|
||||
inputGeometry->getMesh()->getVertCount(),
|
||||
inputGeometry->getMesh()->getTris(),
|
||||
inputGeometry->getMesh()->getNormals(),
|
||||
inputGeometry->getMesh()->getTriCount(),
|
||||
inputGeometry->verts.data(),
|
||||
inputGeometry->getVertCount(),
|
||||
inputGeometry->tris.data(),
|
||||
inputGeometry->normals.data(),
|
||||
inputGeometry->getTriCount(),
|
||||
0,
|
||||
1.0f);
|
||||
// Draw bounds
|
||||
|
||||
@@ -148,7 +148,7 @@ void Sample_SoloMesh::handleDebugMode()
|
||||
|
||||
void Sample_SoloMesh::handleRender()
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh())
|
||||
if (!inputGeometry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -161,9 +161,15 @@ void Sample_SoloMesh::handleRender()
|
||||
if (currentDrawMode != DrawMode::NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&debugDraw, inputGeometry->getMesh()->getVerts(), inputGeometry->getMesh()->getVertCount(),
|
||||
inputGeometry->getMesh()->getTris(), inputGeometry->getMesh()->getNormals(), inputGeometry->getMesh()->getTriCount(),
|
||||
agentMaxSlope, texScale);
|
||||
duDebugDrawTriMeshSlope(
|
||||
&debugDraw,
|
||||
inputGeometry->verts.data(),
|
||||
static_cast<int>(inputGeometry->verts.size()) / 3,
|
||||
inputGeometry->tris.data(),
|
||||
inputGeometry->normals.data(),
|
||||
static_cast<int>(inputGeometry->tris.size()) / 3,
|
||||
agentMaxSlope,
|
||||
texScale);
|
||||
inputGeometry->drawOffMeshConnections(&debugDraw);
|
||||
}
|
||||
|
||||
@@ -304,7 +310,7 @@ void Sample_SoloMesh::handleMeshChanged(InputGeom* geom)
|
||||
|
||||
bool Sample_SoloMesh::handleBuild()
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh())
|
||||
if (!inputGeometry || inputGeometry->verts.empty())
|
||||
{
|
||||
buildContext->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
|
||||
return false;
|
||||
@@ -314,10 +320,10 @@ bool Sample_SoloMesh::handleBuild()
|
||||
|
||||
const float* boundsMin = inputGeometry->getNavMeshBoundsMin();
|
||||
const float* boundsMax = inputGeometry->getNavMeshBoundsMax();
|
||||
const float* verts = inputGeometry->getMesh()->getVerts();
|
||||
const int numVerts = inputGeometry->getMesh()->getVertCount();
|
||||
const int* tris = inputGeometry->getMesh()->getTris();
|
||||
const int numTris = inputGeometry->getMesh()->getTriCount();
|
||||
const float* verts = inputGeometry->verts.data();
|
||||
const int numVerts = static_cast<int>(inputGeometry->verts.size()) / 3;
|
||||
const int* tris = inputGeometry->tris.data();
|
||||
const int numTris = static_cast<int>(inputGeometry->tris.size()) / 3;
|
||||
|
||||
//
|
||||
// Step 1. Initialize build config.
|
||||
|
||||
@@ -256,7 +256,7 @@ struct RasterizationContext
|
||||
|
||||
int Sample_TempObstacles::rasterizeTileLayers(const int tileX, const int tileY, const rcConfig& cfg, TileCacheData* tiles, const int maxTiles)
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh() || !inputGeometry->getChunkyMesh())
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0 || !inputGeometry->getChunkyMesh())
|
||||
{
|
||||
buildContext->log(RC_LOG_ERROR, "buildTile: Input mesh is not specified.");
|
||||
return 0;
|
||||
@@ -265,8 +265,8 @@ int Sample_TempObstacles::rasterizeTileLayers(const int tileX, const int tileY,
|
||||
FastLZCompressor comp;
|
||||
RasterizationContext rasterContext;
|
||||
|
||||
const float* verts = inputGeometry->getMesh()->getVerts();
|
||||
const int nverts = inputGeometry->getMesh()->getVertCount();
|
||||
const float* verts = inputGeometry->verts.data();
|
||||
const int nverts = inputGeometry->getVertCount();
|
||||
const ChunkyTriMesh* chunkyMesh = inputGeometry->getChunkyMesh();
|
||||
|
||||
// Tile bounds.
|
||||
@@ -1016,7 +1016,7 @@ void Sample_TempObstacles::handleDebugMode()
|
||||
|
||||
void Sample_TempObstacles::handleRender()
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh()) { return; }
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0) { return; }
|
||||
|
||||
const float texScale = 1.0f / (cellSize * 10.0f);
|
||||
|
||||
@@ -1024,9 +1024,15 @@ void Sample_TempObstacles::handleRender()
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&debugDraw, inputGeometry->getMesh()->getVerts(), inputGeometry->getMesh()->getVertCount(),
|
||||
inputGeometry->getMesh()->getTris(), inputGeometry->getMesh()->getNormals(), inputGeometry->getMesh()->getTriCount(),
|
||||
agentMaxSlope, texScale);
|
||||
duDebugDrawTriMeshSlope(
|
||||
&debugDraw,
|
||||
inputGeometry->verts.data(),
|
||||
inputGeometry->getVertCount(),
|
||||
inputGeometry->tris.data(),
|
||||
inputGeometry->normals.data(),
|
||||
inputGeometry->getTriCount(),
|
||||
agentMaxSlope,
|
||||
texScale);
|
||||
inputGeometry->drawOffMeshConnections(&debugDraw);
|
||||
}
|
||||
|
||||
@@ -1199,7 +1205,7 @@ bool Sample_TempObstacles::handleBuild()
|
||||
{
|
||||
dtStatus status;
|
||||
|
||||
if (!inputGeometry || !inputGeometry->getMesh())
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0)
|
||||
{
|
||||
buildContext->log(RC_LOG_ERROR, "buildTiledNavigation: No vertices and triangles.");
|
||||
return false;
|
||||
|
||||
@@ -354,7 +354,7 @@ void Sample_TileMesh::handleDebugMode()
|
||||
|
||||
void Sample_TileMesh::handleRender()
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh())
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -367,11 +367,11 @@ void Sample_TileMesh::handleRender()
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(
|
||||
&debugDraw,
|
||||
inputGeometry->getMesh()->getVerts(),
|
||||
inputGeometry->getMesh()->getVertCount(),
|
||||
inputGeometry->getMesh()->getTris(),
|
||||
inputGeometry->getMesh()->getNormals(),
|
||||
inputGeometry->getMesh()->getTriCount(),
|
||||
inputGeometry->verts.data(),
|
||||
inputGeometry->getVertCount(),
|
||||
inputGeometry->tris.data(),
|
||||
inputGeometry->normals.data(),
|
||||
inputGeometry->getTriCount(),
|
||||
agentMaxSlope,
|
||||
texScale);
|
||||
inputGeometry->drawOffMeshConnections(&debugDraw);
|
||||
@@ -581,7 +581,7 @@ void Sample_TileMesh::handleMeshChanged(InputGeom* geom)
|
||||
|
||||
bool Sample_TileMesh::handleBuild()
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh())
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0)
|
||||
{
|
||||
buildContext->log(RC_LOG_ERROR, "buildTiledNavigation: No vertices and triangles.");
|
||||
return false;
|
||||
@@ -828,7 +828,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(
|
||||
const float* boundsMax,
|
||||
int& outDataSize)
|
||||
{
|
||||
if (!inputGeometry || !inputGeometry->getMesh() || !inputGeometry->getChunkyMesh())
|
||||
if (!inputGeometry || inputGeometry->getVertCount() == 0 || !inputGeometry->getChunkyMesh())
|
||||
{
|
||||
buildContext->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
|
||||
return 0;
|
||||
@@ -839,9 +839,9 @@ unsigned char* Sample_TileMesh::buildTileMesh(
|
||||
|
||||
cleanup();
|
||||
|
||||
const float* verts = inputGeometry->getMesh()->getVerts();
|
||||
const int numVerts = inputGeometry->getMesh()->getVertCount();
|
||||
const int numTris = inputGeometry->getMesh()->getTriCount();
|
||||
const float* verts = inputGeometry->verts.data();
|
||||
const int numVerts = inputGeometry->getVertCount();
|
||||
const int numTris = inputGeometry->getTriCount();
|
||||
const ChunkyTriMesh* chunkyMesh = inputGeometry->getChunkyMesh();
|
||||
|
||||
// Init build configuration from GUI
|
||||
|
||||
@@ -604,8 +604,8 @@ int main(int /*argc*/, char** /*argv*/)
|
||||
text,
|
||||
64,
|
||||
"Verts: %.1fk Tris: %.1fk",
|
||||
static_cast<float>(app.inputGeometry->getMesh()->getVertCount()) / 1000.0f,
|
||||
static_cast<float>(app.inputGeometry->getMesh()->getTriCount()) / 1000.0f);
|
||||
static_cast<float>(app.inputGeometry->getVertCount()) / 1000.0f,
|
||||
static_cast<float>(app.inputGeometry->getTriCount()) / 1000.0f);
|
||||
imguiValue(text);
|
||||
}
|
||||
imguiSeparator();
|
||||
|
||||
Reference in New Issue
Block a user