From 9758f988ec54df229ba82562b547ef5721245af9 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 21 Jul 2022 14:48:50 +0200 Subject: [PATCH] Add NavMesh poly debug overlay Can be toggled and shifted through tiles using 'navmesh_draw_polys'. --- r5dev/engine/debugoverlay.cpp | 88 +++++++++++++++++++++++++++++++---- r5dev/tier1/IConVar.cpp | 11 +++-- r5dev/tier1/cvar.cpp | 3 ++ r5dev/tier1/cvar.h | 6 ++- 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/r5dev/engine/debugoverlay.cpp b/r5dev/engine/debugoverlay.cpp index 67b5e5ca..cf5d6142 100644 --- a/r5dev/engine/debugoverlay.cpp +++ b/r5dev/engine/debugoverlay.cpp @@ -241,12 +241,12 @@ void DrawOverlay(OverlayBase_t* pOverlay) LeaveCriticalSection(&*s_OverlayMutex); } +#ifndef CLIENT_DLL //------------------------------------------------------------------------------ // Purpose : draw AIN script nodes //------------------------------------------------------------------------------ void DrawAIScriptNodes() { -#ifndef CLIENT_DLL if (*g_pAINetwork) { OverlayBox_t::Transforms vTransforms; @@ -270,7 +270,6 @@ void DrawAIScriptNodes() } } } -#endif // !CLIENT_DLL } //------------------------------------------------------------------------------ @@ -278,7 +277,6 @@ void DrawAIScriptNodes() //------------------------------------------------------------------------------ void DrawNavMeshBVTree() { -#ifndef CLIENT_DLL const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); if (!mesh) return; @@ -313,7 +311,6 @@ void DrawNavMeshBVTree() v_RenderBox(vTransforms, vMins, vMaxs, Color(255, 255, 255, 255), r_debug_overlay_zbuffer->GetBool()); } } -#endif // !CLIENT_DLL } //------------------------------------------------------------------------------ @@ -321,7 +318,6 @@ void DrawNavMeshBVTree() //------------------------------------------------------------------------------ static void DrawNavMeshPortals() { -#ifndef CLIENT_DLL const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); if (!mesh) return; @@ -380,14 +376,83 @@ static void DrawNavMeshPortals() } } } -#endif // !CLIENT_DLL +} + +void DrawNavMeshPolys() +{ + const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); + if (!mesh) + return; + + OverlayBox_t::Transforms vTransforms; + for (int i = navmesh_draw_polys->GetInt(); i < mesh->getTileCount(); ++i) + { + const dtMeshTile* tile = &mesh->m_tiles[i]; + if (!tile->header) + continue; + + + for (int j = 0; j < tile->header->polyCount; j++) + { + const dtPoly* poly = &tile->polys[j]; + + + Color c{ 0, 140, 240, 255 }; + const unsigned int ip = (unsigned int)(poly - tile->polys); + + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + //dtOffMeshConnection* con = &tile->offMeshCons[ip - tile->header->offMeshBase]; + + //dd->begin(DU_DRAW_LINES, 2.0f); + + //// 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 & 1) ? 0.6f : 0.0f, 0.6f, c); + + //dd->end(); + } + else + { + const dtPolyDetail* pd = &tile->detailMeshes[ip]; + + //dd->begin(DU_DRAW_TRIS); + for (int k = 0; k < pd->triCount; ++k) + { + Vector3D tris[3]; + const unsigned char* t = &tile->detailTris[(pd->triBase + k) * 4]; + for (int e = 0; e < 3; ++e) + { + if (t[e] < poly->vertCount) + { + float* verts = &tile->verts[poly->verts[t[e]] * 3]; + tris[e].x = verts[0]; + tris[e].y = verts[1]; + tris[e].z = verts[2]; + } + else + { + float* verts = &tile->detailVerts[(pd->vertBase + t[e] - poly->vertCount) * 3]; + tris[e].x = verts[0]; + tris[e].y = verts[1]; + tris[e].z = verts[2]; + } + } + + v_RenderLine(tris[0], tris[1], c, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(tris[1], tris[2], c, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(tris[2], tris[0], c, r_debug_overlay_zbuffer->GetBool()); + } + } + + } + } } static void DrawNavMeshPolyBoundaries() { -#ifndef CLIENT_DLL static const float thr = 0.01f * 0.01f; - Color col{0, 140, 240, 255}; + Color col{20, 210, 255, 255}; //dd->begin(DU_DRAW_LINES, linew); @@ -474,8 +539,8 @@ static void DrawNavMeshPolyBoundaries() } } } -#endif // !CLIENT_DLL } +#endif // !CLIENT_DLL //------------------------------------------------------------------------------ // Purpose : overlay drawing entrypoint @@ -486,15 +551,18 @@ void DrawAllOverlays(bool bDraw) if (!enable_debug_overlays->GetBool()) return; EnterCriticalSection(&*s_OverlayMutex); - +#ifndef CLIENT_DLL if (ai_script_nodes_draw->GetBool()) DrawAIScriptNodes(); if (navmesh_draw_bvtree->GetInt() > -1) DrawNavMeshBVTree(); if (navmesh_draw_portal->GetInt() > -1) DrawNavMeshPortals(); + if (navmesh_draw_polys->GetInt() > -1) + DrawNavMeshPolys(); if (navmesh_draw_poly_bounds->GetInt() > -1) DrawNavMeshPolyBoundaries(); +#endif // !CLIENT_DLL OverlayBase_t* pCurrOverlay = *s_pOverlays; // rdi OverlayBase_t* pPrevOverlay = nullptr; // rsi diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index e2eda1f6..3b89e1f3 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -61,22 +61,26 @@ void ConVar::Init(void) const r_drawWorldMeshesDepthAtTheEnd = new ConVar("r_drawWorldMeshesDepthAtTheEnd", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT, "Render world meshes (depth at the end).", false, 0.f, false, 0.f, nullptr, nullptr); //------------------------------------------------------------------------- // SERVER | +#ifndef CLIENT_DLL ai_ainDumpOnLoad = new ConVar("ai_ainDumpOnLoad" , "0", FCVAR_DEVELOPMENTONLY, "Dumps AIN data from node graphs loaded from the disk on load.", false, 0.f, false, 0.f, nullptr, nullptr); 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"); +#ifndef DEDICATED 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_polys = new ConVar("navmesh_draw_polys" , "-1", FCVAR_DEVELOPMENTONLY, "Draws the polys 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"); - +#endif // !DEDICATED 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); sv_pylonRefreshInterval = new ConVar("sv_pylonRefreshInterval" , "5.0", FCVAR_RELEASE, "Pylon server host request post update interval (seconds).", true, 2.f, true, 8.f, nullptr, nullptr); sv_banlistRefreshInterval = new ConVar("sv_banlistRefreshInterval", "1.0", FCVAR_RELEASE, "Banlist refresh interval (seconds).", true, 1.f, false, 0.f, nullptr, nullptr); sv_statusRefreshInterval = new ConVar("sv_statusRefreshInterval" , "0.5", FCVAR_RELEASE, "Server status bar update interval (seconds).", false, 0.f, false, 0.f, nullptr, nullptr); +#endif // !CLIENT_DLL #ifdef DEDICATED sv_rcon_debug = new ConVar("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); sv_rcon_banpenalty = new ConVar("sv_rcon_banpenalty" , "10", FCVAR_RELEASE, "Number of minutes to ban users who fail rcon authentication.", false, 0.f, false, 0.f, nullptr, nullptr); @@ -180,13 +184,16 @@ void ConVar::Init(void) const //----------------------------------------------------------------------------- void ConVar::InitShipped(void) const { +#ifndef CLIENT_DLL ai_script_nodes_draw = g_pCVar->FindVar("ai_script_nodes_draw"); +#endif // !CLIENT_DLL single_frame_shutdown_for_reload = g_pCVar->FindVar("single_frame_shutdown_for_reload"); enable_debug_overlays = g_pCVar->FindVar("enable_debug_overlays"); model_defaultFadeDistScale = g_pCVar->FindVar("model_defaultFadeDistScale"); model_defaultFadeDistMin = g_pCVar->FindVar("model_defaultFadeDistMin"); staticProp_no_fade_scalar = g_pCVar->FindVar("staticProp_no_fade_scalar"); staticProp_gather_size_weight = g_pCVar->FindVar("staticProp_gather_size_weight"); + stream_overlay = g_pCVar->FindVar("stream_overlay"); old_gather_props = g_pCVar->FindVar("old_gather_props"); mp_gamemode = g_pCVar->FindVar("mp_gamemode"); hostname = g_pCVar->FindVar("hostname"); @@ -195,8 +202,6 @@ void ConVar::InitShipped(void) const host_hasIrreversibleShutdown = g_pCVar->FindVar("host_hasIrreversibleShutdown"); net_usesocketsforloopback = g_pCVar->FindVar("net_usesocketsforloopback"); - stream_overlay = g_pCVar->FindVar("stream_overlay"); - mp_gamemode->SetCallback(&MP_GameMode_Changed_f); } diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index 2d1fdaac..042c43bf 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -49,10 +49,13 @@ ConVar* ai_script_nodes_draw_index = nullptr; ConVar* navmesh_always_reachable = nullptr; ConVar* navmesh_debug_type = nullptr; +#ifndef DEDICATED ConVar* navmesh_draw_bvtree = nullptr; ConVar* navmesh_draw_portal = nullptr; +ConVar* navmesh_draw_polys = nullptr; ConVar* navmesh_draw_poly_bounds = nullptr; ConVar* navmesh_draw_poly_inner = nullptr; +#endif // !DEDICATED ConVar* sv_showconnecting = nullptr; ConVar* sv_pylonVisibility = nullptr; diff --git a/r5dev/tier1/cvar.h b/r5dev/tier1/cvar.h index 3b62b3db..59a0af1b 100644 --- a/r5dev/tier1/cvar.h +++ b/r5dev/tier1/cvar.h @@ -41,6 +41,7 @@ extern ConVar* r_drawWorldMeshesDepthAtTheEnd; extern ConVar* stream_overlay; //------------------------------------------------------------------------- // SERVER | +#ifndef CLIENT_DLL extern ConVar* ai_ainDumpOnLoad; extern ConVar* ai_ainDebugConnect; extern ConVar* ai_script_nodes_draw; @@ -48,11 +49,13 @@ extern ConVar* ai_script_nodes_draw_index; extern ConVar* navmesh_always_reachable; extern ConVar* navmesh_debug_type; +#ifndef DEDICATED extern ConVar* navmesh_draw_bvtree; extern ConVar* navmesh_draw_portal; +extern ConVar* navmesh_draw_polys; extern ConVar* navmesh_draw_poly_bounds; extern ConVar* navmesh_draw_poly_inner; - +#endif // DEDICATED extern ConVar* sv_showconnecting; extern ConVar* sv_pylonVisibility; extern ConVar* sv_pylonRefreshInterval; @@ -66,6 +69,7 @@ extern ConVar* sv_rcon_maxignores; extern ConVar* sv_rcon_maxsockets; extern ConVar* sv_rcon_whitelist_address; #endif // DEDICATED +#endif // CLIENT_DLL //------------------------------------------------------------------------- // CLIENT | #ifndef DEDICATED