From 086489a00089545a6ee76aaec082cac15e9504b0 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 25 Jul 2022 16:39:07 +0200 Subject: [PATCH] AIN/NavMesh debug draw improvements * Move AIN/NavMesh debug draw to ai_utility_shared.cpp. * Use shift index + range for AIN debug draw. * Added cvar for determining max distance between camera and tile (anything outside this range doesn't get draw). --- r5dev/engine/debugoverlay.cpp | 312 +------------------- r5dev/game/shared/ai_utility_shared.cpp | 371 ++++++++++++++++++++++++ r5dev/game/shared/ai_utility_shared.h | 10 + r5dev/tier1/IConVar.cpp | 9 +- r5dev/tier1/cvar.cpp | 3 +- r5dev/tier1/cvar.h | 3 +- r5dev/vproj/gamesdk.vcxproj | 2 + r5dev/vproj/gamesdk.vcxproj.filters | 6 + 8 files changed, 401 insertions(+), 315 deletions(-) create mode 100644 r5dev/game/shared/ai_utility_shared.cpp create mode 100644 r5dev/game/shared/ai_utility_shared.h diff --git a/r5dev/engine/debugoverlay.cpp b/r5dev/engine/debugoverlay.cpp index a84788ab..419171f5 100644 --- a/r5dev/engine/debugoverlay.cpp +++ b/r5dev/engine/debugoverlay.cpp @@ -15,12 +15,9 @@ #include "engine/debugoverlay.h" #include "materialsystem/cmaterialsystem.h" #include "mathlib/mathlib.h" -#ifndef CLIENT_DLL -#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 +#if not defined (DEDICATED) && not defined (CLIENT_DLL) +#include "game/shared/ai_utility_shared.h" +#endif // !DEDICATED && !CLIENT_DLL //------------------------------------------------------------------------------ @@ -242,309 +239,6 @@ void DrawOverlay(OverlayBase_t* pOverlay) } #ifndef CLIENT_DLL -//------------------------------------------------------------------------------ -// Purpose : draw AIN script nodes -//------------------------------------------------------------------------------ -void DrawAIScriptNodes() -{ - if (*g_pAINetwork) - { - OverlayBox_t::Transforms vTransforms; - - for (int i = ai_script_nodes_draw_index->GetInt(); i < (*g_pAINetwork)->GetNumScriptNodes(); i++) - { - vTransforms.xmm[0] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.x - 50.f, 0.0f, 0.0f, 1.0f); - vTransforms.xmm[1] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.y - 50.f, 0.0f, 1.0f, 0.0f); - vTransforms.xmm[2] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.z - 50.f, 1.0f, 0.0f, 0.0f); - - v_RenderBox(vTransforms, {0, 0, 0}, {100, 100, 100}, Color(0, 255, 0, 255), r_debug_overlay_zbuffer->GetBool()); - - if (i > 0) - { - v_RenderLine((*g_pAINetwork)->m_ScriptNode[i - 1].m_vOrigin, (*g_pAINetwork)->m_ScriptNode[i].m_vOrigin, Color(255, 0, 0, 255), r_debug_overlay_zbuffer->GetBool()); - } - } - } -} - -//------------------------------------------------------------------------------ -// Purpose : draw NavMesh BVTree -//------------------------------------------------------------------------------ -void DrawNavMeshBVTree() -{ - const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); - if (!mesh) - return; - - OverlayBox_t::Transforms vTransforms; - for (int i = navmesh_draw_bvtree->GetInt(); i < mesh->getTileCount(); ++i) - { - if (navmesh_debug_tile_range->GetBool()) - if (i > navmesh_debug_tile_range->GetInt()) - break; - - const dtMeshTile* tile = &mesh->m_tiles[i]; - if (!tile->header) - continue; - - const float cs = 1.0f / tile->header->bvQuantFactor; - for (int j = 0; j < tile->header->bvNodeCount; ++j) - { - const dtBVNode* node = &tile->bvTree[j]; - if (node->i < 0) // Leaf indices are positive. - continue; - - vTransforms.xmm[0] = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f); - vTransforms.xmm[1] = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f); - vTransforms.xmm[2] = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f); - - const Vector3D vMins( - tile->header->bmin[0] + node->bmin[0] * cs, - tile->header->bmin[1] + node->bmin[1] * cs, - tile->header->bmin[2] + node->bmin[2] * cs); - const Vector3D vMaxs( - tile->header->bmin[0] + node->bmax[0] * cs, - tile->header->bmin[1] + node->bmax[1] * cs, - tile->header->bmin[2] + node->bmax[2] * cs); - - v_RenderBox(vTransforms, vMins, vMaxs, Color(255, 255, 255, 255), r_debug_overlay_zbuffer->GetBool()); - } - } -} - -//------------------------------------------------------------------------------ -// Purpose : draw NavMesh portals -//------------------------------------------------------------------------------ -static void DrawNavMeshPortals() -{ - const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); - if (!mesh) - return; - - OverlayBox_t::Transforms vTransforms; - for (int i = navmesh_draw_portal->GetInt(); i < mesh->getTileCount(); ++i) - { - if (navmesh_debug_tile_range->GetBool()) - if (i > navmesh_debug_tile_range->GetInt()) - break; - - const dtMeshTile* tile = &mesh->m_tiles[i]; - if (!tile->header) - continue; - - // Draw portals - const float padx = 0.04f; - const float padz = tile->header->walkableClimb; - - for (int side = 0; side < 8; ++side) - { - unsigned short m = DT_EXT_LINK | static_cast(side); - for (int i = 0; i < tile->header->polyCount; ++i) - { - const dtPoly* poly = &tile->polys[i]; - - // Create new links. - const int nv = poly->vertCount; - for (int j = 0; j < nv; ++j) - { - // Skip edges which do not point to the right side. - if (poly->neis[j] != m) - continue; - - // Create new links - const float* va = &tile->verts[poly->verts[j] * 3]; - const float* vb = &tile->verts[poly->verts[(j + 1) % nv] * 3]; - - if (side == 0 || side == 4) - { - Color col = side == 0 ? Color(188, 0, 0, 255) : Color(188, 0, 188, 255); - const float x = va[0] + ((side == 0) ? -padx : padx); - - v_RenderLine(Vector3D(x, va[1], va[2] - padz), Vector3D(x, va[1], va[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(x, va[1], va[2] + padz), Vector3D(x, vb[1], vb[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(x, vb[1], vb[2] + padz), Vector3D(x, vb[1], vb[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(x, vb[1], vb[2] - padz), Vector3D(x, va[1], va[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); - } - else if (side == 2 || side == 6) - { - Color col = side == 2 ? Color(0, 188, 0, 255) : Color(0, 188, 188, 255); - const float y = va[1] + ((side == 2) ? -padx : padx); - - v_RenderLine(Vector3D(va[0], y, va[2] - padz), Vector3D(va[0], y, va[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(va[0], y, va[2] + padz), Vector3D(vb[0], y, vb[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(vb[0], y, vb[2] + padz), Vector3D(vb[0], y, vb[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(Vector3D(vb[0], y, vb[2] - padz), Vector3D(va[0], y, va[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); - } - } - } - } - } -} - -//------------------------------------------------------------------------------ -// Purpose : draw NavMesh polys -//------------------------------------------------------------------------------ -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) - { - if (navmesh_debug_tile_range->GetBool()) - if (i > navmesh_debug_tile_range->GetInt()) - break; - - 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 col{ 110, 200, 220, 255 }; - const unsigned int ip = (unsigned int)(poly - tile->polys); - - if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) - { - const dtOffMeshConnection* con = &tile->offMeshCons[ip - tile->header->offMeshBase]; - v_RenderLine(Vector3D(con->pos[0], con->pos[1], con->pos[2]), Vector3D(con->pos[3], con->pos[4], con->pos[5]), Color(188, 0, 188, 255), r_debug_overlay_zbuffer->GetBool()); - } - 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], col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(tris[1], tris[2], col, r_debug_overlay_zbuffer->GetBool()); - v_RenderLine(tris[2], tris[0], col, r_debug_overlay_zbuffer->GetBool()); - } - } - } - } -} - -//------------------------------------------------------------------------------ -// Purpose : draw NavMesh poly boundaries -//------------------------------------------------------------------------------ -void DrawNavMeshPolyBoundaries() -{ - static const float thr = 0.01f * 0.01f; - Color col{20, 140, 255, 255}; - - 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) - { - if (navmesh_debug_tile_range->GetBool()) - if (i > navmesh_debug_tile_range->GetInt()) - break; - - 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) - { - if (navmesh_draw_poly_bounds_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) - col = Color(255, 255, 255, 48); - else - col = Color(0, 0, 0, 48); - } - else - col = 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]), col, r_debug_overlay_zbuffer->GetBool()); - } - } - } - } - } - } -} #endif // !CLIENT_DLL //------------------------------------------------------------------------------ diff --git a/r5dev/game/shared/ai_utility_shared.cpp b/r5dev/game/shared/ai_utility_shared.cpp new file mode 100644 index 00000000..e04d9ab8 --- /dev/null +++ b/r5dev/game/shared/ai_utility_shared.cpp @@ -0,0 +1,371 @@ +//=============================================================================// +// +// Purpose: Shared AI utility. +// +//=============================================================================// +// ai_utility_shared.cpp: requires server.dll and client.dll! +// +///////////////////////////////////////////////////////////////////////////////// + +#include "core/stdafx.h" +#include "tier1/cvar.h" +#include "mathlib/color.h" +#include "mathlib/vector.h" +#include "engine/debugoverlay.h" +#include "game/shared/ai_utility_shared.h" +#include "game/server/ai_utility.h" +#include "game/server/ai_network.h" +#include "game/server/ai_networkmanager.h" +#include "game/client/view.h" +#include "thirdparty/recast/detour/include/detourcommon.h" + +//------------------------------------------------------------------------------ +// Purpose : draw AIN script nodes +//------------------------------------------------------------------------------ +void DrawAIScriptNodes() +{ + if (*g_pAINetwork) + { + OverlayBox_t::Transforms vTransforms; + + for (int i = ai_script_nodes_draw->GetInt(); i < (*g_pAINetwork)->GetNumScriptNodes(); i++) + { + if (ai_script_nodes_draw_range->GetBool()) + { + if (i > ai_script_nodes_draw_range->GetInt()) + break; + } + + vTransforms.xmm[0] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.x - 50.f, 0.0f, 0.0f, 1.0f); + vTransforms.xmm[1] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.y - 50.f, 0.0f, 1.0f, 0.0f); + vTransforms.xmm[2] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.z - 50.f, 1.0f, 0.0f, 0.0f); + + v_RenderBox(vTransforms, { 0, 0, 0 }, { 100, 100, 100 }, Color(0, 255, 0, 255), r_debug_overlay_zbuffer->GetBool()); + + if (i > 0) + v_RenderLine((*g_pAINetwork)->m_ScriptNode[i - 1].m_vOrigin, (*g_pAINetwork)->m_ScriptNode[i].m_vOrigin, Color(255, 0, 0, 255), r_debug_overlay_zbuffer->GetBool()); + } + } +} + +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh BVTree +//------------------------------------------------------------------------------ +void DrawNavMeshBVTree() +{ + const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); + if (!mesh) + return; + + OverlayBox_t::Transforms vTransforms; + for (int i = navmesh_draw_bvtree->GetInt(); i < mesh->getTileCount(); ++i) + { + if (navmesh_debug_tile_range->GetBool()) + { + if (i > navmesh_debug_tile_range->GetInt()) + break; + } + + const dtMeshTile* tile = &mesh->m_tiles[i]; + if (!tile->header) + continue; + + if (navmesh_debug_camera_range->GetBool()) + { + const Vector3D vCamera = MainViewOrigin(); + + if (vCamera.DistTo(Vector3D(tile->header->bmin[0], tile->header->bmin[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat() || + vCamera.DistTo(Vector3D(tile->header->bmax[0], tile->header->bmax[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat()) + continue; + } + + const float cs = 1.0f / tile->header->bvQuantFactor; + for (int j = 0; j < tile->header->bvNodeCount; ++j) + { + const dtBVNode* node = &tile->bvTree[j]; + if (node->i < 0) // Leaf indices are positive. + continue; + + vTransforms.xmm[0] = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f); + vTransforms.xmm[1] = _mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f); + vTransforms.xmm[2] = _mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f); + + const Vector3D vMins( + tile->header->bmin[0] + node->bmin[0] * cs, + tile->header->bmin[1] + node->bmin[1] * cs, + tile->header->bmin[2] + node->bmin[2] * cs); + const Vector3D vMaxs( + tile->header->bmin[0] + node->bmax[0] * cs, + tile->header->bmin[1] + node->bmax[1] * cs, + tile->header->bmin[2] + node->bmax[2] * cs); + + v_RenderBox(vTransforms, vMins, vMaxs, Color(255, 255, 255, 255), r_debug_overlay_zbuffer->GetBool()); + } + } +} + +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh portals +//------------------------------------------------------------------------------ +void DrawNavMeshPortals() +{ + const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); + if (!mesh) + return; + + OverlayBox_t::Transforms vTransforms; + for (int i = navmesh_draw_portal->GetInt(); i < mesh->getTileCount(); ++i) + { + if (navmesh_debug_tile_range->GetBool()) + { + if (i > navmesh_debug_tile_range->GetInt()) + break; + } + + const dtMeshTile* tile = &mesh->m_tiles[i]; + if (!tile->header) + continue; + + if (navmesh_debug_camera_range->GetBool()) + { + const Vector3D vCamera = MainViewOrigin(); + + if (vCamera.DistTo(Vector3D(tile->header->bmin[0], tile->header->bmin[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat() || + vCamera.DistTo(Vector3D(tile->header->bmax[0], tile->header->bmax[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat()) + continue; + } + + // Draw portals + const float padx = 0.04f; + const float padz = tile->header->walkableClimb; + + for (int side = 0; side < 8; ++side) + { + unsigned short m = DT_EXT_LINK | static_cast(side); + for (int i = 0; i < tile->header->polyCount; ++i) + { + const dtPoly* poly = &tile->polys[i]; + + // Create new links. + const int nv = poly->vertCount; + for (int j = 0; j < nv; ++j) + { + // Skip edges which do not point to the right side. + if (poly->neis[j] != m) + continue; + + // Create new links + const float* va = &tile->verts[poly->verts[j] * 3]; + const float* vb = &tile->verts[poly->verts[(j + 1) % nv] * 3]; + + if (side == 0 || side == 4) + { + Color col = side == 0 ? Color(188, 0, 0, 255) : Color(188, 0, 188, 255); + const float x = va[0] + ((side == 0) ? -padx : padx); + + v_RenderLine(Vector3D(x, va[1], va[2] - padz), Vector3D(x, va[1], va[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(x, va[1], va[2] + padz), Vector3D(x, vb[1], vb[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(x, vb[1], vb[2] + padz), Vector3D(x, vb[1], vb[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(x, vb[1], vb[2] - padz), Vector3D(x, va[1], va[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); + } + else if (side == 2 || side == 6) + { + Color col = side == 2 ? Color(0, 188, 0, 255) : Color(0, 188, 188, 255); + const float y = va[1] + ((side == 2) ? -padx : padx); + + v_RenderLine(Vector3D(va[0], y, va[2] - padz), Vector3D(va[0], y, va[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(va[0], y, va[2] + padz), Vector3D(vb[0], y, vb[2] + padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(vb[0], y, vb[2] + padz), Vector3D(vb[0], y, vb[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(Vector3D(vb[0], y, vb[2] - padz), Vector3D(va[0], y, va[2] - padz), col, r_debug_overlay_zbuffer->GetBool()); + } + } + } + } + } +} + +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh polys +//------------------------------------------------------------------------------ +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) + { + if (navmesh_debug_tile_range->GetBool()) + { + if (i > navmesh_debug_tile_range->GetInt()) + break; + } + + const dtMeshTile* tile = &mesh->m_tiles[i]; + if (!tile->header) + continue; + + if (navmesh_debug_camera_range->GetBool()) + { + const Vector3D vCamera = MainViewOrigin(); + + if (vCamera.DistTo(Vector3D(tile->header->bmin[0], tile->header->bmin[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat() || + vCamera.DistTo(Vector3D(tile->header->bmax[0], tile->header->bmax[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat()) + continue; + } + + for (int j = 0; j < tile->header->polyCount; j++) + { + const dtPoly* poly = &tile->polys[j]; + + Color col{ 110, 200, 220, 255 }; + const unsigned int ip = (unsigned int)(poly - tile->polys); + + if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION) + { + const dtOffMeshConnection* con = &tile->offMeshCons[ip - tile->header->offMeshBase]; + v_RenderLine(Vector3D(con->pos[0], con->pos[1], con->pos[2]), Vector3D(con->pos[3], con->pos[4], con->pos[5]), Color(188, 0, 188, 255), r_debug_overlay_zbuffer->GetBool()); + } + 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], col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(tris[1], tris[2], col, r_debug_overlay_zbuffer->GetBool()); + v_RenderLine(tris[2], tris[0], col, r_debug_overlay_zbuffer->GetBool()); + } + } + } + } +} + +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh poly boundaries +//------------------------------------------------------------------------------ +void DrawNavMeshPolyBoundaries() +{ + static const float thr = 0.01f * 0.01f; + Color col{ 20, 140, 255, 255 }; + + 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) + { + if (navmesh_debug_tile_range->GetBool()) + { + if (i > navmesh_debug_tile_range->GetInt()) + break; + } + + const dtMeshTile* tile = &mesh->m_tiles[i]; + if (!tile->header) + continue; + + if (navmesh_debug_camera_range->GetBool()) + { + const Vector3D vCamera = MainViewOrigin(); + + if (vCamera.DistTo(Vector3D(tile->header->bmin[0], tile->header->bmin[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat() || + vCamera.DistTo(Vector3D(tile->header->bmax[0], tile->header->bmax[1], vCamera.z)) > navmesh_debug_camera_range->GetFloat()) + 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) + { + if (navmesh_draw_poly_bounds_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) + col = Color(255, 255, 255, 48); + else + col = Color(0, 0, 0, 48); + } + else + col = 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]), col, r_debug_overlay_zbuffer->GetBool()); + } + } + } + } + } + } +} diff --git a/r5dev/game/shared/ai_utility_shared.h b/r5dev/game/shared/ai_utility_shared.h new file mode 100644 index 00000000..9c91930d --- /dev/null +++ b/r5dev/game/shared/ai_utility_shared.h @@ -0,0 +1,10 @@ +#ifndef AI_UTILITY_SHARED_H +#define AI_UTILITY_SHARED_H + +void DrawAIScriptNodes(); +void DrawNavMeshBVTree(); +void DrawNavMeshPortals(); +void DrawNavMeshPolys(); +void DrawNavMeshPolyBoundaries(); + +#endif // AI_UTILITY_SHARED_H diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 3391fe99..6e5965b4 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -70,11 +70,12 @@ void ConVar::Init(void) const #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); + ai_script_nodes_draw_range = new ConVar("ai_script_nodes_draw_range", "0", FCVAR_DEVELOPMENTONLY, "AIN debug draw script nodes ranging from shift index to this cvar.", 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 debug draw hull index.", true, 0.f, true, 4.f, nullptr, "0 = small, 1 = med_short, 2 = medium, 3 = large, 4 = extra large"); - navmesh_debug_tile_range = new ConVar("navmesh_debug_tile_range" , "0" , FCVAR_DEVELOPMENTONLY, "NavMesh debug draw tiles ranging from shift index to this cvar.", true, 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 debug draw hull index.", true, 0.f, true, 4.f, nullptr, "0 = small, 1 = med_short, 2 = medium, 3 = large, 4 = extra large"); + navmesh_debug_tile_range = new ConVar("navmesh_debug_tile_range" , "0" , FCVAR_DEVELOPMENTONLY, "NavMesh debug draw tiles ranging from shift index to this cvar.", true, 0.f, false, 0.f, nullptr, nullptr); + navmesh_debug_camera_range = new ConVar("navmesh_debug_camera_range" , "2000" , FCVAR_DEVELOPMENTONLY, "Only debug draw tiles within this distance from camera origin.", true, 0.f, false, 0.f, nullptr, nullptr); #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"); diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index 6e3d91c7..13e4cc6f 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -46,11 +46,12 @@ ConVar* stream_overlay_mode = nullptr; ConVar* ai_ainDumpOnLoad = nullptr; ConVar* ai_ainDebugConnect = nullptr; ConVar* ai_script_nodes_draw = nullptr; -ConVar* ai_script_nodes_draw_index = nullptr; +ConVar* ai_script_nodes_draw_range = nullptr; ConVar* navmesh_always_reachable = nullptr; ConVar* navmesh_debug_type = nullptr; ConVar* navmesh_debug_tile_range = nullptr; +ConVar* navmesh_debug_camera_range = nullptr; #ifndef DEDICATED ConVar* navmesh_draw_bvtree = nullptr; ConVar* navmesh_draw_portal = nullptr; diff --git a/r5dev/tier1/cvar.h b/r5dev/tier1/cvar.h index 832b84b5..db41b847 100644 --- a/r5dev/tier1/cvar.h +++ b/r5dev/tier1/cvar.h @@ -46,11 +46,12 @@ extern ConVar* stream_overlay_mode; extern ConVar* ai_ainDumpOnLoad; extern ConVar* ai_ainDebugConnect; extern ConVar* ai_script_nodes_draw; -extern ConVar* ai_script_nodes_draw_index; +extern ConVar* ai_script_nodes_draw_range; extern ConVar* navmesh_always_reachable; extern ConVar* navmesh_debug_type; extern ConVar* navmesh_debug_tile_range; +extern ConVar* navmesh_debug_camera_range; #ifndef DEDICATED extern ConVar* navmesh_draw_bvtree; extern ConVar* navmesh_draw_portal; diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index 7e5c74e8..fbafbebb 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -60,6 +60,7 @@ + @@ -214,6 +215,7 @@ + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index 7117e3a7..3dff4ff2 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -597,6 +597,9 @@ sdk\game\client + + sdk\game\shared + @@ -1730,6 +1733,9 @@ sdk\game\client + + sdk\game\shared +