diff --git a/RecastDemo/Include/InputGeom.h b/RecastDemo/Include/InputGeom.h index 5a22cbbd..3b5f7da9 100644 --- a/RecastDemo/Include/InputGeom.h +++ b/RecastDemo/Include/InputGeom.h @@ -21,7 +21,7 @@ #include #include -struct ChunkyTriMesh; +struct PartitionedMesh; class rcContext; struct duDebugDraw; @@ -88,7 +88,7 @@ public: std::string filename; Mesh mesh; - ChunkyTriMesh* chunkyMesh = nullptr; + PartitionedMesh* partitionedMesh = nullptr; float meshBoundsMin[3] = {}; float meshBoundsMax[3] = {}; diff --git a/RecastDemo/Include/ChunkyTriMesh.h b/RecastDemo/Include/PartitionedMesh.h similarity index 80% rename from RecastDemo/Include/ChunkyTriMesh.h rename to RecastDemo/Include/PartitionedMesh.h index 751e6091..3b3e3731 100644 --- a/RecastDemo/Include/ChunkyTriMesh.h +++ b/RecastDemo/Include/PartitionedMesh.h @@ -20,27 +20,31 @@ #include -/// A partitioned triangle mesh (AABB tree), where each node contains at max trisPerChunk triangles. -struct ChunkyTriMesh +/// A spatially-partitioned mesh (k/d tree), +/// where each node contains at max trisPerChunk triangles. +struct PartitionedMesh { struct Node { + // xy bounds float bmin[2]; float bmax[2]; + int triIndex; int numTris; }; std::vector nodes{}; int nnodes = 0; + std::vector tris{}; int maxTrisPerChunk = 0; void PartitionMesh(const float* verts, const int* tris, int ntris, int trisPerChunk); /// Finds the chunk indices that overlap the input rectangle. - int GetChunksOverlappingRect(float bmin[2], float bmax[2], int* ids, int maxIds) const; + int GetNodesOverlappingRect(float bmin[2], float bmax[2], int* ids, int maxIds) const; /// Returns the chunk indices which overlap the input segment. - int GetChunksOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, int maxIds) const; + int GetNodesOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, int maxIds) const; }; diff --git a/RecastDemo/Source/InputGeom.cpp b/RecastDemo/Source/InputGeom.cpp index 0e48b0c1..2ef5da15 100644 --- a/RecastDemo/Source/InputGeom.cpp +++ b/RecastDemo/Source/InputGeom.cpp @@ -18,7 +18,7 @@ #include "InputGeom.h" -#include "ChunkyTriMesh.h" +#include "PartitionedMesh.h" #include "DebugDraw.h" #include "MeshLoaderObj.h" #include "Recast.h" @@ -138,7 +138,7 @@ char* parseRow(char* buf, char* bufEnd, char* row, int len) InputGeom::~InputGeom() { - delete chunkyMesh; + delete partitionedMesh; } bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath) @@ -166,9 +166,9 @@ bool InputGeom::loadMesh(rcContext* ctx, const std::string& filepath) parseObjData(buffer, bufferLen, mesh.verts, mesh.tris, mesh.normals); rcCalcBounds(mesh.verts.data(), mesh.getVertCount(), meshBoundsMin, meshBoundsMax); - delete chunkyMesh; - chunkyMesh = new ChunkyTriMesh; - chunkyMesh->PartitionMesh(mesh.verts.data(), mesh.tris.data(), mesh.getTriCount(), 256); + delete partitionedMesh; + partitionedMesh = new PartitionedMesh; + partitionedMesh->PartitionMesh(mesh.verts.data(), mesh.tris.data(), mesh.getTriCount(), 256); return true; } @@ -489,7 +489,7 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin) float q[]{src[0] + (dst[0] - src[0]) * btmax, src[2] + (dst[2] - src[2]) * btmax}; int cid[512]; - const int ncid = chunkyMesh->GetChunksOverlappingSegment(p, q, cid, 512); + const int ncid = partitionedMesh->GetChunksOverlappingSegment(p, q, cid, 512); if (!ncid) { return false; @@ -500,8 +500,8 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin) for (int i = 0; i < ncid; ++i) { - const ChunkyTriMesh::Node& node = chunkyMesh->nodes[cid[i]]; - const int* tris = &chunkyMesh->tris[node.triIndex * 3]; + const PartitionedMesh::Node& node = partitionedMesh->nodes[cid[i]]; + const int* tris = &partitionedMesh->tris[node.triIndex * 3]; const int ntris = node.numTris; for (int j = 0; j < ntris * 3; j += 3) diff --git a/RecastDemo/Source/ChunkyTriMesh.cpp b/RecastDemo/Source/PartitionedMesh.cpp similarity index 93% rename from RecastDemo/Source/ChunkyTriMesh.cpp rename to RecastDemo/Source/PartitionedMesh.cpp index f101b2bc..90e9bba8 100644 --- a/RecastDemo/Source/ChunkyTriMesh.cpp +++ b/RecastDemo/Source/PartitionedMesh.cpp @@ -16,7 +16,7 @@ // 3. This notice may not be removed or altered from any source distribution. // -#include "ChunkyTriMesh.h" +#include "PartitionedMesh.h" #include #include @@ -69,7 +69,7 @@ void subdivide( int imax, int trisPerChunk, int& curNode, - ChunkyTriMesh::Node* nodes, + PartitionedMesh::Node* nodes, const int maxNodes, int& curTri, int* outTris, @@ -83,7 +83,7 @@ void subdivide( return; } - ChunkyTriMesh::Node& node = nodes[curNode]; + PartitionedMesh::Node& node = nodes[curNode]; curNode++; if (numTriBoundsInRange <= trisPerChunk) // Leaf @@ -179,7 +179,7 @@ bool checkOverlapSegment(const float p[2], const float q[2], const float bmin[2] } } -void ChunkyTriMesh::PartitionMesh(const float* verts, const int* tris, int numTris, int trisPerChunk) +void PartitionedMesh::PartitionMesh(const float* verts, const int* tris, int numTris, int trisPerChunk) { // Calculate the XZ bounds of every triangle. std::vector triBounds; @@ -225,7 +225,7 @@ void ChunkyTriMesh::PartitionMesh(const float* verts, const int* tris, int numTr } } -int ChunkyTriMesh::GetChunksOverlappingRect(float bmin[2], float bmax[2], int* ids, const int maxIds) const +int PartitionedMesh::GetChunksOverlappingRect(float bmin[2], float bmax[2], int* ids, const int maxIds) const { // Traverse tree int i = 0; @@ -259,7 +259,7 @@ int ChunkyTriMesh::GetChunksOverlappingRect(float bmin[2], float bmax[2], int* i return n; } -int ChunkyTriMesh::GetChunksOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, const int maxIds) const +int PartitionedMesh::GetChunksOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, const int maxIds) const { // Traverse tree int i = 0; diff --git a/RecastDemo/Source/Sample_TempObstacles.cpp b/RecastDemo/Source/Sample_TempObstacles.cpp index 974ac64a..f26a2362 100644 --- a/RecastDemo/Source/Sample_TempObstacles.cpp +++ b/RecastDemo/Source/Sample_TempObstacles.cpp @@ -16,7 +16,6 @@ // 3. This notice may not be removed or altered from any source distribution. // -#include "SDL.h" #include "SDL_opengl.h" #include @@ -27,10 +26,9 @@ #else # include #endif -#include "ChunkyTriMesh.h" +#include "PartitionedMesh.h" #include "ConvexVolumeTool.h" #include "CrowdTool.h" -#include "DetourAssert.h" #include "DetourCommon.h" #include "DetourDebugDraw.h" #include "DetourNavMesh.h" @@ -40,7 +38,6 @@ #include "NavMeshTesterTool.h" #include "OffMeshConnectionTool.h" #include "Recast.h" -#include "RecastAlloc.h" #include "RecastDebugDraw.h" #include "Sample.h" #include "Sample_TempObstacles.h" @@ -533,7 +530,7 @@ int Sample_TempObstacles::rasterizeTileLayers( TileCacheData* tiles, const int maxTiles) const { - if (!inputGeometry || inputGeometry->mesh.getVertCount() == 0 || !inputGeometry->chunkyMesh) + if (!inputGeometry || inputGeometry->mesh.getVertCount() == 0 || !inputGeometry->partitionedMesh) { buildContext->log(RC_LOG_ERROR, "buildTile: Input mesh is not specified."); return 0; @@ -544,7 +541,7 @@ int Sample_TempObstacles::rasterizeTileLayers( const float* verts = inputGeometry->mesh.verts.data(); const int nverts = inputGeometry->mesh.getVertCount(); - const ChunkyTriMesh* chunkyMesh = inputGeometry->chunkyMesh; + const PartitionedMesh* partitionedMesh = inputGeometry->partitionedMesh; // Tile bounds. const float tcs = cfg.tileSize * cfg.cs; @@ -587,10 +584,10 @@ int Sample_TempObstacles::rasterizeTileLayers( // Allocate array that can hold triangle flags. // If you have multiple meshes you need to process, allocate // and array which can hold the max number of triangles you need to process. - rasterContext.triareas = new unsigned char[chunkyMesh->maxTrisPerChunk]; + rasterContext.triareas = new unsigned char[partitionedMesh->maxTrisPerChunk]; if (!rasterContext.triareas) { - buildContext->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", chunkyMesh->maxTrisPerChunk); + buildContext->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", partitionedMesh->maxTrisPerChunk); return 0; } @@ -601,7 +598,7 @@ int Sample_TempObstacles::rasterizeTileLayers( tbmax[0] = tcfg.bmax[0]; tbmax[1] = tcfg.bmax[2]; int cid[512]; // TODO: Make grow when returning too many items. - const int ncid = chunkyMesh->GetChunksOverlappingRect(tbmin, tbmax, cid, 512); + const int ncid = partitionedMesh->GetChunksOverlappingRect(tbmin, tbmax, cid, 512); if (!ncid) { return 0; // empty @@ -609,8 +606,8 @@ int Sample_TempObstacles::rasterizeTileLayers( for (int i = 0; i < ncid; ++i) { - const ChunkyTriMesh::Node& node = chunkyMesh->nodes[cid[i]]; - const int* tris = &chunkyMesh->tris[node.triIndex * 3]; + const PartitionedMesh::Node& node = partitionedMesh->nodes[cid[i]]; + const int* tris = &partitionedMesh->tris[node.triIndex * 3]; const int ntris = node.numTris; memset(rasterContext.triareas, 0, ntris * sizeof(unsigned char)); diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index ad4647c1..3f9acd88 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -30,7 +30,7 @@ # include #endif -#include "ChunkyTriMesh.h" +#include "PartitionedMesh.h" #include "ConvexVolumeTool.h" #include "CrowdTool.h" #include "DetourDebugDraw.h" @@ -834,7 +834,7 @@ unsigned char* Sample_TileMesh::buildTileMesh( const float* boundsMax, int& outDataSize) { - if (!inputGeometry || inputGeometry->mesh.getVertCount() == 0 || !inputGeometry->chunkyMesh) + if (!inputGeometry || inputGeometry->mesh.getVertCount() == 0 || !inputGeometry->partitionedMesh) { buildContext->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified."); return 0; @@ -848,7 +848,7 @@ unsigned char* Sample_TileMesh::buildTileMesh( const float* verts = inputGeometry->mesh.verts.data(); const int numVerts = inputGeometry->mesh.getVertCount(); const int numTris = inputGeometry->mesh.getTriCount(); - const ChunkyTriMesh* chunkyMesh = inputGeometry->chunkyMesh; + const PartitionedMesh* partitionedMesh = inputGeometry->partitionedMesh; // Init build configuration from GUI memset(&config, 0, sizeof(config)); @@ -936,10 +936,10 @@ unsigned char* Sample_TileMesh::buildTileMesh( // Allocate array that can hold triangle flags. // If you have multiple meshes you need to process, allocate // and array which can hold the max number of triangles you need to process. - triareas = new unsigned char[chunkyMesh->maxTrisPerChunk]; + triareas = new unsigned char[partitionedMesh->maxTrisPerChunk]; if (!triareas) { - buildContext->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'triareas' (%d).", chunkyMesh->maxTrisPerChunk); + buildContext->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'triareas' (%d).", partitionedMesh->maxTrisPerChunk); return 0; } @@ -951,7 +951,7 @@ unsigned char* Sample_TileMesh::buildTileMesh( tileBoundsMax[1] = config.bmax[2]; int overlappingChunkIndexes[512]; // TODO: Make grow when returning too many items. const int numOverlappingChunks = - chunkyMesh->GetChunksOverlappingRect(tileBoundsMin, tileBoundsMax, overlappingChunkIndexes, 512); + partitionedMesh->GetChunksOverlappingRect(tileBoundsMin, tileBoundsMax, overlappingChunkIndexes, 512); if (!numOverlappingChunks) { return 0; @@ -961,8 +961,8 @@ unsigned char* Sample_TileMesh::buildTileMesh( for (int i = 0; i < numOverlappingChunks; ++i) { - const ChunkyTriMesh::Node& node = chunkyMesh->nodes[overlappingChunkIndexes[i]]; - const int* nodeTris = &chunkyMesh->tris[node.triIndex * 3]; + const PartitionedMesh::Node& node = partitionedMesh->nodes[overlappingChunkIndexes[i]]; + const int* nodeTris = &partitionedMesh->tris[node.triIndex * 3]; const int numNodeTris = node.numTris; tileTriCount += numNodeTris;