diff --git a/RecastDemo/Include/InputGeom.h b/RecastDemo/Include/InputGeom.h index 34630e02..3c7b9015 100644 --- a/RecastDemo/Include/InputGeom.h +++ b/RecastDemo/Include/InputGeom.h @@ -70,8 +70,19 @@ struct BuildSettings class InputGeom { +public: + std::string filename; + + // Mesh data + std::vector verts; + std::vector tris; + std::vector normals; + + int getVertCount() const { return static_cast(verts.size()) / 3; } + int getTriCount() const { return static_cast(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; } diff --git a/RecastDemo/Include/MeshLoaderObj.h b/RecastDemo/Include/MeshLoaderObj.h index 2d388d5f..313a6a71 100644 --- a/RecastDemo/Include/MeshLoaderObj.h +++ b/RecastDemo/Include/MeshLoaderObj.h @@ -18,25 +18,6 @@ #pragma once -#include #include -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(verts.size()) / 3; } - [[nodiscard]] int getTriCount() const { return static_cast(tris.size()) / 3; } - [[nodiscard]] const std::string& getFileName() const { return filename; } - -private: - std::string filename; - - std::vector verts; - std::vector tris; - std::vector normals; -}; +void parseObjModel(char* buf, size_t bufLen, std::vector& verts, std::vector& tris, std::vector& normals); diff --git a/RecastDemo/Source/InputGeom.cpp b/RecastDemo/Source/InputGeom.cpp index af837dfe..d318453b 100644 --- a/RecastDemo/Source/InputGeom.cpp +++ b/RecastDemo/Source/InputGeom.cpp @@ -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) { diff --git a/RecastDemo/Source/MeshLoaderObj.cpp b/RecastDemo/Source/MeshLoaderObj.cpp index f704045d..4fdfb7ce 100644 --- a/RecastDemo/Source/MeshLoaderObj.cpp +++ b/RecastDemo/Source/MeshLoaderObj.cpp @@ -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& verts, std::vector& tris, std::vector& 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(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(tris.size()); i += 3) { const float* vertex0 = &verts[tris[i + 0] * 3]; diff --git a/RecastDemo/Source/Sample.cpp b/RecastDemo/Source/Sample.cpp index f914ec2a..46739379 100644 --- a/RecastDemo/Source/Sample.cpp +++ b/RecastDemo/Source/Sample.cpp @@ -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 diff --git a/RecastDemo/Source/Sample_SoloMesh.cpp b/RecastDemo/Source/Sample_SoloMesh.cpp index 73319f63..f6e91815 100644 --- a/RecastDemo/Source/Sample_SoloMesh.cpp +++ b/RecastDemo/Source/Sample_SoloMesh.cpp @@ -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(inputGeometry->verts.size()) / 3, + inputGeometry->tris.data(), + inputGeometry->normals.data(), + static_cast(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(inputGeometry->verts.size()) / 3; + const int* tris = inputGeometry->tris.data(); + const int numTris = static_cast(inputGeometry->tris.size()) / 3; // // Step 1. Initialize build config. diff --git a/RecastDemo/Source/Sample_TempObstacles.cpp b/RecastDemo/Source/Sample_TempObstacles.cpp index a0bfc074..5046eb6a 100644 --- a/RecastDemo/Source/Sample_TempObstacles.cpp +++ b/RecastDemo/Source/Sample_TempObstacles.cpp @@ -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; diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index 9163953b..01e8118d 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -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 diff --git a/RecastDemo/Source/main.cpp b/RecastDemo/Source/main.cpp index 5426273b..801f8c7e 100644 --- a/RecastDemo/Source/main.cpp +++ b/RecastDemo/Source/main.cpp @@ -604,8 +604,8 @@ int main(int /*argc*/, char** /*argv*/) text, 64, "Verts: %.1fk Tris: %.1fk", - static_cast(app.inputGeometry->getMesh()->getVertCount()) / 1000.0f, - static_cast(app.inputGeometry->getMesh()->getTriCount()) / 1000.0f); + static_cast(app.inputGeometry->getVertCount()) / 1000.0f, + static_cast(app.inputGeometry->getTriCount()) / 1000.0f); imguiValue(text); } imguiSeparator();