Remove MeshLoaderObj class. Replace with parseObjModel function

This commit is contained in:
Graham Pentheny
2025-07-07 00:54:57 -04:00
parent c1674f805d
commit d1e513aeaf
9 changed files with 75 additions and 81 deletions

View File

@@ -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; }

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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];

View File

@@ -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

View File

@@ -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.

View File

@@ -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;

View File

@@ -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

View File

@@ -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();