Recast: add traverse links debug drawing

Originally taken from https://github.com/ASpoonPlaysGames/r2recast, slightly modified to use the new constants added in commit 78a632eec85ca5406adb03617084746b446b0044, and now renders white crosses if reverse links are set.
This commit is contained in:
Kawe Mazidjatari 2024-07-18 14:22:14 +02:00
parent 78a632eec8
commit 12f39f1c44
5 changed files with 89 additions and 10 deletions

View File

@ -72,7 +72,8 @@ Editor::Editor() :
m_loadedNavMeshType(NAVMESH_SMALL),
m_navmeshName(NavMesh_GetNameForType(NAVMESH_SMALL)),
m_tool(0),
m_ctx(0)
m_ctx(0),
m_traverseLinkDrawTypes(-1)
{
resetCommonSettings();
m_navQuery = dtAllocNavMeshQuery();
@ -500,6 +501,18 @@ void Editor::renderDetourDebugMenu()
if (ImGui::Checkbox("Transparency", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_ALPHA);
isEnabled = (getNavMeshDrawFlags() & DU_DRAWNAVMESH_TRAVERSE_LINKS);
if (ImGui::Checkbox("Traverse Links", &isEnabled))
toggleNavMeshDrawFlag(DU_DRAWNAVMESH_TRAVERSE_LINKS);
if (isEnabled)
{
ImGui::PushItemWidth(190);
ImGui::SliderInt("Traverse Type", &m_traverseLinkDrawTypes, -1, 31);
ImGui::PopItemWidth();
}
}
// NOTE: the climb height should never equal or exceed the agent's height, see https://groups.google.com/g/recastnavigation/c/L5rBamxcOBk/m/5xGLj6YP25kJ

View File

@ -307,7 +307,7 @@ void Editor_StaticTileMeshCommon::renderTileMeshData()
{
if (m_tileMeshDrawFlags & TM_DRAWFLAGS_NAVMESH)
{
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, detourDrawOffset, m_navMeshDrawFlags);
duDebugDrawNavMeshWithClosedList(&m_dd, *m_navMesh, *m_navQuery, detourDrawOffset, m_navMeshDrawFlags, m_traverseLinkDrawTypes);
duDebugDrawNavMeshPolysWithFlags(&m_dd, *m_navMesh, EDITOR_POLYFLAGS_DISABLED, detourDrawOffset, detourDrawFlags, duRGBA(0, 0, 0, 128));
}
}

View File

@ -115,7 +115,6 @@ protected:
class dtNavMeshQuery* m_navQuery;
class dtCrowd* m_crowd;
unsigned int m_navMeshDrawFlags;
bool m_filterLowHangingObstacles;
bool m_filterLedgeSpans;
bool m_filterWalkableLowHeightSpans;
@ -149,6 +148,8 @@ protected:
BuildContext* m_ctx;
EditorDebugDraw m_dd;
unsigned int m_navMeshDrawFlags;
int m_traverseLinkDrawTypes;
float m_recastDrawOffset[3];
float m_detourDrawOffset[3];

View File

@ -38,10 +38,11 @@ enum DrawNavMeshFlags
DU_DRAWNAVMESH_POLYGROUPS = 1 << 10, // Render poly group by color.
DU_DRAWNAVMESH_DEPTH_MASK = 1 << 11, // Use depth mask.
DU_DRAWNAVMESH_ALPHA = 1 << 12, // Use transparency.
DU_DRAWNAVMESH_TRAVERSE_LINKS = 1 << 13, // Render traverse links.
};
void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh& mesh, const float* offset, unsigned int flags);
void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, const float* offset, unsigned int flags);
void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh& mesh, const float* offset, unsigned int flags, const int linkTypes = -1);
void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, const float* offset, unsigned int flags, const int linkTypes = -1);
void duDebugDrawNavMeshNodes(struct duDebugDraw* dd, const dtNavMeshQuery& query, const float* offset);
void duDebugDrawNavMeshBVTree(struct duDebugDraw* dd, const dtNavMesh& mesh, const float* offset);
void duDebugDrawNavMeshPortals(struct duDebugDraw* dd, const dtNavMesh& mesh, const float* offset);

View File

@ -133,8 +133,69 @@ static void drawPolyCenters(duDebugDraw* dd, const dtMeshTile* tile, const unsig
}
}
static void drawTraverseLinks(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query,
const dtMeshTile* tile, const float* offset, const int drawLinkType)
{
for (int i = 0; i < tile->header->polyCount; ++i)
{
const dtPoly* startPoly = &tile->polys[i];
if (startPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links.
continue;
// Iterate through links in the poly.
for (int j = startPoly->firstLink; j != -1; j = tile->links[j].next)
{
const dtLink* link = &tile->links[j];
// Skip "normal" links (non-jumping ones).
if (link->jumpType == DT_NULL_TRAVERSE_TYPE || tile->links[i].ref == 0)
continue;
// Filter, drawLinkType -1 means draw all
if (drawLinkType != -1 && link->jumpType != drawLinkType)
continue;
const dtPoly* endPoly;
const dtMeshTile* endTile;
if (dtStatusFailed(mesh.getTileAndPolyByRef(link->ref, &endTile, &endPoly)))
continue;
if (endPoly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) // Skip off-mesh links.
continue;
float startPos[3];
float endPos[3];
query->getEdgeMidPoint(mesh.getPolyRefBase(tile) | (dtPolyRef)i, link->ref, startPos);
query->getEdgeMidPoint(link->ref, mesh.getPolyRefBase(tile) | (dtPolyRef)i, endPos);
// Unique color for each type.
const int col = duIntToCol(link->jumpType, 180);
dd->begin(DU_DRAW_LINES, 2.0f, offset);
dd->vertex(startPos, col);
dd->vertex(endPos, col);
const bool hasReverseLink = link->reverseLinkIndex != DT_NULL_TRAVERSE_REVERSE_LINK;
if (hasReverseLink)
{
// If the reverse link is set, render white crosses to confirm
// the links are set properly.
duAppendCross(dd, startPos[0], startPos[1], startPos[2], 10.f, duRGBA(255,255,255,180));
duAppendCross(dd, endPos[0], endPos[1], endPos[2], 10.f, duRGBA(255,255,255,180));
}
dd->end();
}
}
}
static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery* query,
const dtMeshTile* tile, const float* offset, unsigned int flags)
const dtMeshTile* tile, const float* offset, unsigned int flags, const int linkTypes)
{
// 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;
@ -192,6 +253,9 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
if (flags & DU_DRAWNAVMESH_POLYCENTERS)
drawPolyCenters(dd, tile, duRGBA(255, 255, 255, 100), 1.0f, offset);
if (flags & DU_DRAWNAVMESH_TRAVERSE_LINKS)
drawTraverseLinks(dd, mesh, query, tile, offset, linkTypes);
if (flags & DU_DRAWNAVMESH_OFFMESHCONS)
{
dd->begin(DU_DRAW_LINES, 2.0f, offset);
@ -272,7 +336,7 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
dd->depthMask(true);
}
void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh& mesh, const float* offset, unsigned int flags)
void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh& mesh, const float* offset, unsigned int flags, const int linkTypes)
{
if (!dd) return;
@ -280,11 +344,11 @@ void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh& mesh, const float* off
{
const dtMeshTile* tile = mesh.getTile(i);
if (!tile->header) continue;
drawMeshTile(dd, mesh, 0, tile, offset, flags);
drawMeshTile(dd, mesh, 0, tile, offset, flags, linkTypes);
}
}
void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, const float* offset, unsigned int flags)
void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, const float* offset, unsigned int flags, const int linkTypes)
{
if (!dd) return;
@ -294,7 +358,7 @@ void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& m
{
const dtMeshTile* tile = mesh.getTile(i);
if (!tile->header) continue;
drawMeshTile(dd, mesh, q, tile, offset, flags);
drawMeshTile(dd, mesh, q, tile, offset, flags, linkTypes);
}
if (flags & DU_DRAWNAVMESH_BVTREE)