Add NavMesh poly bounds debug overlay

This commit is contained in:
Kawe Mazidjatari 2022-07-21 02:21:59 +02:00
parent e21ae20f4a
commit c850d52d1b
7 changed files with 130 additions and 34 deletions

View File

@ -19,6 +19,7 @@
#include "game/server/ai_utility.h"
#include "game/server/ai_network.h"
#include "game/server/ai_networkmanager.h"
#include "thirdparty/recast/detour/include/detourcommon.h"
#endif // !CLIENT_DLL
@ -382,6 +383,100 @@ static void DrawNavMeshPortals()
#endif // !CLIENT_DLL
}
static void DrawNavMeshPolyBoundaries()
{
#ifndef CLIENT_DLL
static const float thr = 0.01f * 0.01f;
Color col{0, 140, 240, 255};
//dd->begin(DU_DRAW_LINES, linew);
const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt());
if (!mesh)
return;
OverlayBox_t::Transforms vTransforms;
for (int i = navmesh_draw_poly_bounds->GetInt(); i < mesh->getTileCount(); ++i)
{
const dtMeshTile* tile = &mesh->m_tiles[i];
if (!tile->header)
continue;
for (int i = 0; i < tile->header->polyCount; ++i)
{
const dtPoly* p = &tile->polys[i];
if (p->getType() == DT_POLYTYPE_OFFMESH_CONNECTION)
continue;
const dtPolyDetail* pd = &tile->detailMeshes[i];
for (int j = 0, nj = (int)p->vertCount; j < nj; ++j)
{
Color c = col;
if (navmesh_draw_poly_inner->GetBool())
{
if (p->neis[j] == 0)
continue;
if (p->neis[j] & DT_EXT_LINK)
{
bool con = false;
for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = tile->links[k].next)
{
if (tile->links[k].edge == j)
{
con = true;
break;
}
}
if (con)
c = Color(255, 255, 255, 48);
else
c = Color(0, 0, 0, 48);
}
else
c = Color(0, 48, 64, 32);
}
else
{
if (p->neis[j] != 0) continue;
}
const float* v0 = &tile->verts[p->verts[j] * 3];
const float* v1 = &tile->verts[p->verts[(j + 1) % nj] * 3];
// Draw detail mesh edges which align with the actual poly edge.
// This is really slow.
for (int k = 0; k < pd->triCount; ++k)
{
const unsigned char* t = &tile->detailTris[(pd->triBase + k) * 4];
const float* tv[3];
for (int m = 0; m < 3; ++m)
{
if (t[m] < p->vertCount)
tv[m] = &tile->verts[p->verts[t[m]] * 3];
else
tv[m] = &tile->detailVerts[(pd->vertBase + (t[m] - p->vertCount)) * 3];
}
for (int m = 0, n = 2; m < 3; n = m++)
{
if ((dtGetDetailTriEdgeFlags(t[3], n) & DT_DETAIL_EDGE_BOUNDARY) == 0)
continue;
if (distancePtLine2d(tv[n], v0, v1) < thr &&
distancePtLine2d(tv[m], v0, v1) < thr)
{
v_RenderLine(Vector3D(tv[n][0], tv[n][1], tv[n][2]), Vector3D(tv[m][0], tv[m][1], tv[m][2]), c, r_debug_overlay_zbuffer->GetBool());
}
}
}
}
}
}
#endif // !CLIENT_DLL
}
//------------------------------------------------------------------------------
// Purpose : overlay drawing entrypoint
// Input : bDraw -
@ -389,24 +484,18 @@ static void DrawNavMeshPortals()
void DrawAllOverlays(bool bDraw)
{
if (!enable_debug_overlays->GetBool())
{
return;
}
if (ai_script_nodes_draw->GetBool())
{
DrawAIScriptNodes();
}
if (navmesh_draw_bvtree->GetInt() > -1)
{
DrawNavMeshBVTree();
}
if (navmesh_draw_portal->GetInt() > -1)
{
DrawNavMeshPortals();
}
EnterCriticalSection(&*s_OverlayMutex);
if (ai_script_nodes_draw->GetBool())
DrawAIScriptNodes();
if (navmesh_draw_bvtree->GetInt() > -1)
DrawNavMeshBVTree();
if (navmesh_draw_portal->GetInt() > -1)
DrawNavMeshPortals();
if (navmesh_draw_poly_bounds->GetInt() > -1)
DrawNavMeshPolyBoundaries();
OverlayBase_t* pCurrOverlay = *s_pOverlays; // rdi
OverlayBase_t* pPrevOverlay = nullptr; // rsi
OverlayBase_t* pNextOverlay = nullptr; // rbx

View File

@ -22,21 +22,6 @@
#include "Detour/Include/DetourCommon.h"
#include "Detour/Include/DetourNode.h"
static float distancePtLine2d(const float* pt, const float* p, const float* q)
{
float pqx = q[0] - p[0];
float pqz = q[2] - p[2];
float dx = pt[0] - p[0];
float dz = pt[2] - p[2];
float d = pqx*pqx + pqz*pqz;
float t = pqx*dx + pqz*dz;
if (d != 0) t /= d;
dx = p[0] + t*pqx - pt[0];
dz = p[2] + t*pqz - pt[2];
return dx*dx + dz*dz;
}
static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshTile* tile,
const unsigned int col, const float linew,
bool inner)

View File

@ -405,6 +405,8 @@ bool dtIntersectSegSeg2D(const float* ap, const float* aq,
const float* bp, const float* bq,
float& s, float& t);
float distancePtLine2d(const float* pt, const float* p, const float* q);
/// Determines if the specified point is inside the convex polygon on the xz-plane.
/// @param[in] pt The point to check. [(x, y, z)]
/// @param[in] verts The polygon vertices. [(x, y, z) * @p nverts]

View File

@ -385,3 +385,17 @@ bool dtIntersectSegSeg2D(const float* ap, const float* aq,
return true;
}
float distancePtLine2d(const float* pt, const float* p, const float* q)
{
float pqx = q[0] - p[0];
float pqz = q[2] - p[2];
float dx = pt[0] - p[0];
float dz = pt[2] - p[2];
float d = pqx * pqx + pqz * pqz;
float t = pqx * dx + pqz * dz;
if (d != 0) t /= d;
dx = p[0] + t * pqx - pt[0];
dz = p[2] + t * pqz - pt[2];
return dx * dx + dz * dz;
}

View File

@ -65,10 +65,12 @@ void ConVar::Init(void) const
ai_ainDebugConnect = new ConVar("ai_ainDebugConnect" , "0", FCVAR_DEVELOPMENTONLY, "Debug AIN node connections.", false, 0.f, false, 0.f, nullptr, nullptr);
ai_script_nodes_draw_index = new ConVar("ai_script_nodes_draw_index", "0", FCVAR_DEVELOPMENTONLY, "Start index for drawing script nodes.", false, 0.f, false, 0.f, nullptr, nullptr);
navmesh_always_reachable = new ConVar("navmesh_always_reachable" , "0", FCVAR_DEVELOPMENTONLY, "Marks goal poly from agent poly as reachable regardless of table data ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
navmesh_debug_type = new ConVar("navmesh_debug_type" , "0", FCVAR_DEVELOPMENTONLY, "NavMesh hull index for debug draw.", true, 0.f, true, 4.f, nullptr, "0 = small, 1 = med_short, 2 = medium, 3 = large, 4 = extra large");
navmesh_draw_bvtree = new ConVar("navmesh_draw_bvtree" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the BVTree of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
navmesh_draw_portal = new ConVar("navmesh_draw_portal" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the portal of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
navmesh_always_reachable = new ConVar("navmesh_always_reachable" , "0" , FCVAR_DEVELOPMENTONLY, "Marks goal poly from agent poly as reachable regardless of table data ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
navmesh_debug_type = new ConVar("navmesh_debug_type" , "0" , FCVAR_DEVELOPMENTONLY, "NavMesh hull index for debug draw.", true, 0.f, true, 4.f, nullptr, "0 = small, 1 = med_short, 2 = medium, 3 = large, 4 = extra large");
navmesh_draw_bvtree = new ConVar("navmesh_draw_bvtree" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the BVTree of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
navmesh_draw_portal = new ConVar("navmesh_draw_portal" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the portal of the NavMesh tiles.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
navmesh_draw_poly_bounds = new ConVar("navmesh_draw_poly_bounds" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the bounds of the NavMesh polys.", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
navmesh_draw_poly_inner = new ConVar("navmesh_draw_poly_inner" , "0" , FCVAR_DEVELOPMENTONLY, "Draws the inner bounds of the NavMesh polys (requires navmesh_draw_poly_bounds).", false, 0.f, false, 0.f, nullptr, "Index: > 0 && < mesh->m_tileCount");
sv_showconnecting = new ConVar("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr);
sv_pylonVisibility = new ConVar("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visiblity to the Pylon master server, 0 = Offline, 1 = Hidden, 2 = Public.", false, 0.f, false, 0.f, nullptr, nullptr);

View File

@ -51,6 +51,8 @@ ConVar* navmesh_always_reachable = nullptr;
ConVar* navmesh_debug_type = nullptr;
ConVar* navmesh_draw_bvtree = nullptr;
ConVar* navmesh_draw_portal = nullptr;
ConVar* navmesh_draw_poly_bounds = nullptr;
ConVar* navmesh_draw_poly_inner = nullptr;
ConVar* sv_showconnecting = nullptr;
ConVar* sv_pylonVisibility = nullptr;

View File

@ -50,6 +50,8 @@ extern ConVar* navmesh_always_reachable;
extern ConVar* navmesh_debug_type;
extern ConVar* navmesh_draw_bvtree;
extern ConVar* navmesh_draw_portal;
extern ConVar* navmesh_draw_poly_bounds;
extern ConVar* navmesh_draw_poly_inner;
extern ConVar* sv_showconnecting;
extern ConVar* sv_pylonVisibility;