From d0c4c0497dbabc1e6c83c77fa5857112f2f706f6 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 20 Sep 2024 00:10:03 +0200 Subject: [PATCH] Recast: allow ability to mark AABB box area on NavMesh Very useful utility when automating the creation of geometry bounding boxes to be used to mark and flag certain polygons on the navmesh (e.g. a door or hazard area through bounding boxes from a mesh or box-shaped trigger). --- src/naveditor/Editor_Common.cpp | 2 + src/naveditor/Editor_TileMesh.cpp | 11 ++++- src/naveditor/InputGeom.cpp | 78 ++++++++++++++++++++++++++++--- src/naveditor/include/InputGeom.h | 2 + 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/naveditor/Editor_Common.cpp b/src/naveditor/Editor_Common.cpp index 902ceb2b..b8edd49f 100644 --- a/src/naveditor/Editor_Common.cpp +++ b/src/naveditor/Editor_Common.cpp @@ -381,6 +381,7 @@ void Editor_StaticTileMeshCommon::renderTileMeshData() } // TODO: also add flags for this + m_geom->drawBoxVolumes(&m_dd, recastDrawOffset); m_geom->drawConvexVolumes(&m_dd, recastDrawOffset); // NOTE: commented out because this already gets rendered when the off-mesh @@ -577,6 +578,7 @@ void Editor_DynamicTileMeshCommon::renderTileMeshData() } // TODO: also add flags for this + m_geom->drawBoxVolumes(&m_dd, recastDrawOffset); m_geom->drawConvexVolumes(&m_dd, recastDrawOffset); // NOTE: commented out because this already gets rendered when the off-mesh diff --git a/src/naveditor/Editor_TileMesh.cpp b/src/naveditor/Editor_TileMesh.cpp index 83a6f809..563758a6 100644 --- a/src/naveditor/Editor_TileMesh.cpp +++ b/src/naveditor/Editor_TileMesh.cpp @@ -1104,8 +1104,15 @@ unsigned char* Editor_TileMesh::buildTileMesh(const int tx, const int ty, const // (Optional) Mark areas. const ConvexVolume* vols = m_geom->getConvexVolumes(); - for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i) - rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned short)vols[i].flags, (unsigned char)vols[i].area, *m_chf); + for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i) + { + const ConvexVolume& vol = vols[i]; + + if (vol.bbox) + rcMarkBoxArea(m_ctx, &vol.verts[0], &vol.verts[3], vol.flags, vol.area, *m_chf); + else + rcMarkConvexPolyArea(m_ctx, vol.verts, vol.nverts, vol.hmin, vol.hmax, vol.flags, vol.area, *m_chf); + } // Partition the heightfield so that we can use simple algorithm later to triangulate the walkable areas. diff --git a/src/naveditor/InputGeom.cpp b/src/naveditor/InputGeom.cpp index 6190eaaa..82d33fa1 100644 --- a/src/naveditor/InputGeom.cpp +++ b/src/naveditor/InputGeom.cpp @@ -306,6 +306,20 @@ bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath) m_offMeshConCount++; } } + else if (row[0] == 'b') + { + // Box volumes + if (m_volumeCount < MAX_VOLUMES) + { + ConvexVolume* vol = &m_volumes[m_volumeCount++]; + + sscanf(row+1, "%hu %hhu %f %f %f %f %f %f", &vol->flags, &vol->area, + &vol->verts[0], &vol->verts[1], &vol->verts[2], + &vol->verts[3], &vol->verts[4], &vol->verts[5]); + + vol->bbox = true; + } + } else if (row[0] == 'v') { // Convex volumes @@ -319,6 +333,8 @@ bool InputGeom::loadGeomSet(rcContext* ctx, const std::string& filepath) src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char)); sscanf(row, "%f %f %f", &vol->verts[i*3+0], &vol->verts[i*3+1], &vol->verts[i*3+2]); } + + vol->bbox = false; } } else if (row[0] == 's') @@ -453,9 +469,18 @@ bool InputGeom::saveGeomSet(const BuildSettings* settings) for (int i = 0; i < m_volumeCount; ++i) { ConvexVolume* vol = &m_volumes[i]; - fprintf(fp, "v %d %hu %hhu %f %f\n", vol->nverts, vol->flags, vol->area, vol->hmin, vol->hmax); - for (int j = 0; j < vol->nverts; ++j) - fprintf(fp, "%f %f %f\n", vol->verts[j*3+0], vol->verts[j*3+1], vol->verts[j*3+2]); + if (vol->bbox) + { + fprintf(fp, "b %hu %hhu %f %f %f %f %f %f\n", vol->flags, vol->area, + vol->verts[0], vol->verts[1], vol->verts[2], + vol->verts[3], vol->verts[4], vol->verts[5]); + } + else + { + fprintf(fp, "v %d %hu %hhu %f %f\n", vol->nverts, vol->flags, vol->area, vol->hmin, vol->hmax); + for (int j = 0; j < vol->nverts; ++j) + fprintf(fp, "%f %f %f\n", vol->verts[j*3+0], vol->verts[j*3+1], vol->verts[j*3+2]); + } } fclose(fp); @@ -688,15 +713,48 @@ void InputGeom::deleteConvexVolume(int i) m_volumes[i] = m_volumes[m_volumeCount]; } +void InputGeom::drawBoxVolumes(struct duDebugDraw* dd, const float* offset, bool /*hilight*/) +{ + for (int i = 0; i < m_volumeCount; ++i) + { + const ConvexVolume* vol = &m_volumes[i]; + + if (!vol->bbox) + continue; + + const unsigned int faceCol = vol->area == RC_NULL_AREA + ? duRGBA(255, 0, 0, 128) // Use red for visibility (null acts as deletion). + : duTransCol(dd->areaToCol(vol->area), 64); + + unsigned int fcol[6] = { faceCol, 0, faceCol, faceCol, faceCol, faceCol }; + + duDebugDrawBox(dd, + vol->verts[0],vol->verts[1],vol->verts[2], + vol->verts[3],vol->verts[4],vol->verts[5], + fcol, offset); + + const unsigned int wireCol = vol->area == RC_NULL_AREA + ? duRGBA(255, 0, 0, 220) + : duTransCol(dd->areaToCol(vol->area), 220); + + duDebugDrawBoxWire(dd, + vol->verts[0],vol->verts[1],vol->verts[2], + vol->verts[3],vol->verts[4],vol->verts[5], + wireCol, 2.0f, offset); + } +} + void InputGeom::drawConvexVolumes(struct duDebugDraw* dd, const float* offset, bool /*hilight*/) { - dd->depthMask(false); - dd->begin(DU_DRAW_TRIS, 1.0f, offset); for (int i = 0; i < m_volumeCount; ++i) { const ConvexVolume* vol = &m_volumes[i]; + + if (vol->bbox) + continue; + unsigned int col; if (vol->area == RC_NULL_AREA) @@ -729,6 +787,10 @@ void InputGeom::drawConvexVolumes(struct duDebugDraw* dd, const float* offset, b for (int i = 0; i < m_volumeCount; ++i) { const ConvexVolume* vol = &m_volumes[i]; + + if (vol->bbox) + continue; + unsigned int col; if (vol->area == RC_NULL_AREA) @@ -754,6 +816,10 @@ void InputGeom::drawConvexVolumes(struct duDebugDraw* dd, const float* offset, b for (int i = 0; i < m_volumeCount; ++i) { const ConvexVolume* vol = &m_volumes[i]; + + if (vol->bbox) + continue; + unsigned int col; if (vol->area == RC_NULL_AREA) @@ -769,6 +835,4 @@ void InputGeom::drawConvexVolumes(struct duDebugDraw* dd, const float* offset, b } } dd->end(); - - dd->depthMask(true); } diff --git a/src/naveditor/include/InputGeom.h b/src/naveditor/include/InputGeom.h index 63aeaa40..f3f45bf6 100644 --- a/src/naveditor/include/InputGeom.h +++ b/src/naveditor/include/InputGeom.h @@ -30,6 +30,7 @@ struct ConvexVolume int nverts; unsigned short flags; unsigned char area; + bool bbox; }; struct BuildSettings @@ -163,6 +164,7 @@ public: void addConvexVolume(const float* verts, const int nverts, const float minh, const float maxh, unsigned short flags, unsigned char area); void deleteConvexVolume(int i); + void drawBoxVolumes(struct duDebugDraw* dd, const float* offset, bool hilight = false); void drawConvexVolumes(struct duDebugDraw* dd, const float* offset, bool hilight = false); ///@}