From 83ab1c87ff11e7820f3f414e13b2ba70baaa0f57 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 22 Aug 2024 23:48:16 +0200 Subject: [PATCH] Recast: small debug draw refactor Move all render logic to separate functions and add flag to disable/enable the rendering of the poly faces. --- src/naveditor/Editor.cpp | 9 +- .../DebugUtils/Include/DetourDebugDraw.h | 17 +- .../DebugUtils/Source/DetourDebugDraw.cpp | 250 ++++++++++-------- 3 files changed, 150 insertions(+), 126 deletions(-) diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index e4e1c397..cef64185 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -130,7 +130,7 @@ Editor::Editor() : m_crowd(0), m_navMeshDrawFlags( DU_DRAWNAVMESH_OFFMESHCONS|DU_DRAWNAVMESH_WITH_CLOSED_LIST| - DU_DRAWNAVMESH_POLY_BOUNDS_OUTER|DU_DRAWNAVMESH_ALPHA), + DU_DRAWNAVMESH_POLY_FACES|DU_DRAWNAVMESH_POLY_BOUNDS_OUTER|DU_DRAWNAVMESH_ALPHA), m_filterLowHangingObstacles(true), m_filterLedgeSpans(true), m_filterWalkableLowHeightSpans(true), @@ -1234,9 +1234,14 @@ void Editor::renderDetourDebugMenu() toggleNavMeshDrawFlag(DU_DRAWNAVMESH_TILE_CELLS); #endif + isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLY_FACES); + + if (ImGui::Checkbox("Poly Faces", &isEnabled)) + toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLY_FACES); + isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLY_VERTS); - if (ImGui::Checkbox("Vertex Points", &isEnabled)) + if (ImGui::Checkbox("Poly Verts", &isEnabled)) toggleNavMeshDrawFlag(DU_DRAWNAVMESH_POLY_VERTS); isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_POLY_BOUNDS_INNER); diff --git a/src/thirdparty/recast/DebugUtils/Include/DetourDebugDraw.h b/src/thirdparty/recast/DebugUtils/Include/DetourDebugDraw.h index d0dfab90..90abf14e 100644 --- a/src/thirdparty/recast/DebugUtils/Include/DetourDebugDraw.h +++ b/src/thirdparty/recast/DebugUtils/Include/DetourDebugDraw.h @@ -34,14 +34,15 @@ enum DrawNavMeshFlags DU_DRAWNAVMESH_TILE_BOUNDS = 1 << 6, // Render tile boundaries. DU_DRAWNAVMESH_TILE_CELLS = 1 << 7, // Render tile cells. DU_DRAWNAVMESH_POLY_VERTS = 1 << 8, // Render vertex points. - DU_DRAWNAVMESH_POLY_BOUNDS_INNER = 1 << 9, // Render inner poly boundaries. - DU_DRAWNAVMESH_POLY_BOUNDS_OUTER = 1 << 10, // Render outer poly boundaries. - DU_DRAWNAVMESH_POLY_CENTERS = 1 << 11, // Render poly centers. - DU_DRAWNAVMESH_POLY_GROUPS = 1 << 12, // Render poly group by color. - DU_DRAWNAVMESH_LEDGE_SPANS = 1 << 13, // Render ledge spans. - DU_DRAWNAVMESH_DEPTH_MASK = 1 << 14, // Use depth mask. - DU_DRAWNAVMESH_ALPHA = 1 << 15, // Use transparency. - DU_DRAWNAVMESH_TRAVERSE_LINKS = 1 << 16, // Render traverse links. + DU_DRAWNAVMESH_POLY_FACES = 1 << 9, // Render poly faces. + DU_DRAWNAVMESH_POLY_BOUNDS_INNER = 1 << 10, // Render inner poly boundaries. + DU_DRAWNAVMESH_POLY_BOUNDS_OUTER = 1 << 11, // Render outer poly boundaries. + DU_DRAWNAVMESH_POLY_CENTERS = 1 << 12, // Render poly centers. + DU_DRAWNAVMESH_POLY_GROUPS = 1 << 13, // Render poly group by color. + DU_DRAWNAVMESH_LEDGE_SPANS = 1 << 14, // Render ledge spans. + DU_DRAWNAVMESH_DEPTH_MASK = 1 << 15, // Use depth mask. + DU_DRAWNAVMESH_ALPHA = 1 << 16, // Use transparency. + DU_DRAWNAVMESH_TRAVERSE_LINKS = 1 << 17, // Render traverse links. }; struct duDrawTraverseLinkParams diff --git a/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp b/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp index 88900863..05435ac3 100644 --- a/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp +++ b/src/thirdparty/recast/DebugUtils/Source/DetourDebugDraw.cpp @@ -22,6 +22,20 @@ #include "Detour/Include/DetourNode.h" #include "Shared/Include/SharedCommon.h" +static void drawPolyVerts(duDebugDraw* dd, const dtMeshTile* tile, const float* offset) +{ + const dtMeshHeader* header = tile->header; + const unsigned int vcol = duRGBA(0, 0, 0, 220); + + dd->begin(DU_DRAW_POINTS, 4.0f, offset); + for (int i = 0; i < header->vertCount; ++i) + { + const float* v = &tile->verts[i * 3]; + dd->vertex(v[0], v[1], v[2], vcol); + } + dd->end(); +} + static unsigned int getPolySurfaceColor(const dtPoly* poly, duDebugDraw* dd, const unsigned int alpha) { return poly->groupId == DT_UNLINKED_POLY_GROUP @@ -29,6 +43,51 @@ static unsigned int getPolySurfaceColor(const dtPoly* poly, duDebugDraw* dd, con : duTransCol(dd->areaToCol(poly->getArea()), alpha); } +static void drawPolyFaces(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query, const dtMeshTile* tile, const float* offset, unsigned int flags) +{ + const dtMeshHeader* header = tile->header; + const dtPolyRef base = mesh.getPolyRefBase(tile); + + // If the "Alpha" flag isn't set, force the colour to be opaque instead of semi-transparent. + const int tileAlpha = flags & DU_DRAWNAVMESH_ALPHA ? 170 : 255; + + dd->begin(DU_DRAW_TRIS, 1.0f, offset); + for (int i = 0; i < header->polyCount; ++i) + { + const dtPoly* p = &tile->polys[i]; + if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. + continue; + + const dtPolyDetail* pd = &tile->detailMeshes[i]; + + unsigned int col; + if (query && query->isInClosedList(base | (dtPolyRef)i)) + col = duRGBA(255,196,0,64); + else + { + if (flags & DU_DRAWNAVMESH_TILE_COLORS) + col = duIntToCol(mesh.decodePolyIdTile(base), tileAlpha); + else if (flags & DU_DRAWNAVMESH_POLY_GROUPS) + col = duIntToCol(p->groupId, tileAlpha); + else + col = getPolySurfaceColor(p, dd, tileAlpha); + } + + for (int j = 0; j < pd->triCount; ++j) + { + const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < p->vertCount) + dd->vertex(&tile->verts[p->verts[t[k]]*3], col); + else + dd->vertex(&tile->detailVerts[(pd->vertBase+t[k]-p->vertCount)*3], col); + } + } + } + dd->end(); +} + static unsigned int getPolyBoundaryColor(const dtPoly* poly, const bool inner) { return poly->groupId == DT_UNLINKED_POLY_GROUP @@ -36,15 +95,6 @@ static unsigned int getPolyBoundaryColor(const dtPoly* poly, const bool inner) : inner ? duRGBA(0,24,32,32) : duRGBA(0,24,32,220); } -static void drawOffMeshConnectionRefPosition(duDebugDraw* dd, const dtOffMeshConnection* con) -{ - float refPosDir[3]; - dtCalcOffMeshRefPos(con->refPos, con->refYaw, DT_OFFMESH_CON_REFPOS_OFFSET, refPosDir); - - duAppendArrow(dd, con->refPos[0], con->refPos[1], con->refPos[2], - refPosDir[0], refPosDir[1], refPosDir[2], 0.f, 10.f, duRGBA(255,255,0,255)); -} - static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile, const float linew, const float* offset, const int flags, bool inner) { @@ -200,8 +250,7 @@ static void drawTraverseLinks(duDebugDraw* dd, const dtNavMesh& mesh, const dtNa const dtPoly* endPoly; const dtMeshTile* endTile; - if (dtStatusFailed(mesh.getTileAndPolyByRef(link->ref, &endTile, &endPoly))) - continue; + mesh.getTileAndPolyByRefUnsafe(link->ref, &endTile, &endPoly); if (endPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. continue; @@ -292,54 +341,97 @@ static void drawTileBounds(duDebugDraw* dd, const dtMeshTile* tile, const float* duDebugDrawBoxWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f,offset); } -static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query, - const dtMeshTile* tile, const float* offset, unsigned int flags, const duDrawTraverseLinkParams& traverseLinkParams) +static void drawOffMeshConnectionRefPosition(duDebugDraw* dd, const dtOffMeshConnection* con) { - // If the "Alpha" flag isn't set, force the colour to be opaque instead of semi-transparent. - const int tileAlpha = flags & DU_DRAWNAVMESH_ALPHA ? 170 : 255; - const bool depthTest = flags & DU_DRAWNAVMESH_DEPTH_MASK; + float refPosDir[3]; + dtCalcOffMeshRefPos(con->refPos, con->refYaw, DT_OFFMESH_CON_REFPOS_OFFSET, refPosDir); - dtPolyRef base = mesh.getPolyRefBase(tile); + duAppendArrow(dd, con->refPos[0], con->refPos[1], con->refPos[2], + refPosDir[0], refPosDir[1], refPosDir[2], 0.f, 10.f, duRGBA(255,255,0,255)); +} + +static void drawOffMeshLinks(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query, + const dtMeshTile* tile, const float* offset) +{ const dtMeshHeader* header = tile->header; + const dtPolyRef base = mesh.getPolyRefBase(tile); - dd->depthMask(depthTest); - - dd->begin(DU_DRAW_TRIS, 1.0f, offset); + dd->begin(DU_DRAW_LINES, 2.0f, offset); for (int i = 0; i < header->polyCount; ++i) { const dtPoly* p = &tile->polys[i]; - if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links. + if (p->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) // Skip regular polys. continue; - - const dtPolyDetail* pd = &tile->detailMeshes[i]; + + const dtOffMeshConnection* con = &tile->offMeshCons[i - header->offMeshBase]; unsigned int col; if (query && query->isInClosedList(base | (dtPolyRef)i)) - col = duRGBA(255,196,0,64); + col = duRGBA(255,196,0,220); else + col = duDarkenCol(duTransCol(dd->areaToCol(p->getArea()), 220)); + + const float* va = &tile->verts[p->verts[0]*3]; + const float* vb = &tile->verts[p->verts[1]*3]; + + // Check to see if start and end end-points have links. + bool startSet = false; + bool endSet = false; + for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) { - if (flags & DU_DRAWNAVMESH_TILE_COLORS) - col = duIntToCol(mesh.decodePolyIdTile(base), tileAlpha); - else if (flags & DU_DRAWNAVMESH_POLY_GROUPS) - col = duIntToCol(p->groupId, tileAlpha); - else - col = getPolySurfaceColor(p, dd, tileAlpha); + const dtLink& link = tile->links[k]; + + if (link.edge == 0) + startSet = true; + if (link.edge == 1) + endSet = true; } - for (int j = 0; j < pd->triCount; ++j) - { - const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4]; - for (int k = 0; k < 3; ++k) - { - if (t[k] < p->vertCount) - dd->vertex(&tile->verts[p->verts[t[k]]*3], col); - else - dd->vertex(&tile->detailVerts[(pd->vertBase+t[k]-p->vertCount)*3], col); - } - } + // End points and their on-mesh locations. + dd->vertex(va[0],va[1],va[2], col); + dd->vertex(con->pos[0],con->pos[1],con->pos[2], col); + duAppendCircle(dd, con->pos[0],con->pos[1],con->pos[2]+5.0f, con->rad, duRGBA(220,32,16,196)); + + if (startSet) + duAppendCross(dd, con->pos[0],con->pos[1],con->pos[2]+5.0f, con->rad, duRGBA(220,220,16,196)); + + dd->vertex(vb[0],vb[1],vb[2], col); + dd->vertex(con->pos[3],con->pos[4],con->pos[5], col); + duAppendCircle(dd, con->pos[3],con->pos[4],con->pos[5]+5.0f, con->rad, duRGBA(32,220,16,196)); + + if (endSet) + duAppendCross(dd, con->pos[3],con->pos[4],con->pos[5]+5.0f, con->rad, duRGBA(220,220,16,196)); + + // End point vertices. + dd->vertex(con->pos[0],con->pos[1],con->pos[2], duRGBA(0,48,64,196)); + dd->vertex(con->pos[0],con->pos[1],con->pos[2]+10.0f, duRGBA(0,48,64,196)); + + dd->vertex(con->pos[3],con->pos[4],con->pos[5], duRGBA(0,48,64,196)); + dd->vertex(con->pos[3],con->pos[4],con->pos[5]+10.0f, duRGBA(0,48,64,196)); + + // Connection arc. + duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, + (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, 30.0f, col); + + // Reference positions. + drawOffMeshConnectionRefPosition(dd, con); } dd->end(); +} + +static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query, + const dtMeshTile* tile, const float* offset, unsigned int flags, const duDrawTraverseLinkParams& traverseLinkParams) +{ + const bool depthTest = flags & DU_DRAWNAVMESH_DEPTH_MASK; + + dd->depthMask(depthTest); + if (flags & DU_DRAWNAVMESH_POLY_VERTS) + drawPolyVerts(dd, tile, offset); + + if (flags & DU_DRAWNAVMESH_POLY_FACES) + drawPolyFaces(dd, mesh, query, tile, offset, flags); + // Draw inner poly boundaries if (flags & DU_DRAWNAVMESH_POLY_BOUNDS_INNER) drawPolyBoundaries(dd, tile, 1.5f, offset, flags, true); @@ -362,81 +454,7 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh drawTileBounds(dd, tile, offset); if (flags & DU_DRAWNAVMESH_OFFMESHCONS) - { - dd->begin(DU_DRAW_LINES, 2.0f, offset); - for (int i = 0; i < header->polyCount; ++i) - { - const dtPoly* p = &tile->polys[i]; - if (p->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) // Skip regular polys. - continue; - - const dtOffMeshConnection* con = &tile->offMeshCons[i - header->offMeshBase]; - - unsigned int col; - if (query && query->isInClosedList(base | (dtPolyRef)i)) - col = duRGBA(255, 196, 0, 220); - else - col = duDarkenCol(duTransCol(dd->areaToCol(p->getArea()), 220)); - - const float* va = &tile->verts[p->verts[0]*3]; - const float* vb = &tile->verts[p->verts[1]*3]; - - // Check to see if start and end end-points have links. - bool startSet = false; - bool endSet = false; - for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = tile->links[k].next) - { - const dtLink& link = tile->links[k]; - - if (link.edge == 0) - startSet = true; - if (link.edge == 1) - endSet = true; - } - - // End points and their on-mesh locations. - dd->vertex(va[0],va[1],va[2], col); - dd->vertex(con->pos[0],con->pos[1],con->pos[2], col); - duAppendCircle(dd, con->pos[0],con->pos[1],con->pos[2]+5.0f, con->rad, duRGBA(220,32,16,196)); - - if (startSet) - duAppendCross(dd, con->pos[0],con->pos[1],con->pos[2]+5.0f, con->rad, duRGBA(220,220,16,196)); - - dd->vertex(vb[0],vb[1],vb[2], col); - dd->vertex(con->pos[3],con->pos[4],con->pos[5], col); - duAppendCircle(dd, con->pos[3],con->pos[4],con->pos[5]+5.0f, con->rad, duRGBA(32,220,16,196)); - - if (endSet) - duAppendCross(dd, con->pos[3],con->pos[4],con->pos[5]+5.0f, con->rad, duRGBA(220,220,16,196)); - - // End point vertices. - dd->vertex(con->pos[0],con->pos[1],con->pos[2], duRGBA(0,48,64,196)); - dd->vertex(con->pos[0],con->pos[1],con->pos[2]+10.0f, duRGBA(0,48,64,196)); - - dd->vertex(con->pos[3],con->pos[4],con->pos[5], duRGBA(0,48,64,196)); - dd->vertex(con->pos[3],con->pos[4],con->pos[5]+10.0f, duRGBA(0,48,64,196)); - - // Connection arc. - duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f, - (con->flags & DT_OFFMESH_CON_BIDIR) ? 30.0f : 0.0f, 30.0f, col); - - // Reference positions. - drawOffMeshConnectionRefPosition(dd, con); - } - dd->end(); - } - - if (flags & DU_DRAWNAVMESH_POLY_VERTS) - { - const unsigned int vcol = duRGBA(0,0,0,220); - dd->begin(DU_DRAW_POINTS, 4.0f, offset); - for (int i = 0; i < header->vertCount; ++i) - { - const float* v = &tile->verts[i*3]; - dd->vertex(v[0], v[1], v[2], vcol); - } - dd->end(); - } + drawOffMeshLinks(dd, mesh, query, tile, offset); if (!depthTest) dd->depthMask(true);