From 0b688c6807c94009ca223ce8c6f6220c1d3a97a1 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:48:39 +0200 Subject: [PATCH] Recast: implement neighbor extending logic in traverse link algorithm Allow the user to specify how far to extend from the current tile towards the direction of the traverse link, this is useful when navmeshes with smaller tiles are generated as the neighbor lookup boundary for these are essentially bound to the tile size, thus smaller tiles will result in smaller links unless we extend to further neighbors. --- src/naveditor/Editor.cpp | 26 ++++++++++++++++++++++++-- src/naveditor/include/Editor.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index 42a9884e..c28230fb 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -270,6 +270,7 @@ void Editor::resetCommonSettings() m_agentMaxSlope = 45.573f; m_traverseRayExtraOffset = 0.0f; + m_maxTraverseNeighbors = 4; m_regionMinSize = 8; m_regionMergeSize = 20; @@ -561,6 +562,7 @@ void Editor::handleCommonSettings() if (ImGui::SliderFloat("Extra Offset", &m_traverseRayExtraOffset, 0, 128)) m_traverseLinkParams.extraOffset = m_traverseRayExtraOffset; + ImGui::SliderInt("Neighbors", &m_maxTraverseNeighbors, 0, 32); ImGui::Separator(); } @@ -792,13 +794,27 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin rdVsad(basePolyEdgeMid, basePolySpos, basePolyEpos, 0.5f); unsigned char baseSide = rdClassifyPointInsideBounds(basePolyEdgeMid, baseHeader->bmin, baseHeader->bmax); + const int MAX_NEIS = 32; // Max neighbors + const int numLookupNeighbors = rdMin(m_maxTraverseNeighbors, MAX_NEIS); dtMeshTile* neis[MAX_NEIS]; - int nneis; + int nneis = 0; if (linkToNeighbor) // Retrieve the neighboring tiles on the side of our base poly edge. - nneis = m_navMesh->getNeighbourTilesAt(baseHeader->x, baseHeader->y, baseSide, neis, MAX_NEIS); + { + const dtMeshHeader* neiTileHeader = baseHeader; + + // Extend towards the furthest neighbor specified or possible. + for (int k = 0; k < numLookupNeighbors; k++) + { + if (!m_navMesh->getNeighbourTilesAt(neiTileHeader->x, neiTileHeader->y, baseSide, &neis[k], 1)) + break; + + neiTileHeader = neis[k]->header; + nneis++; + } + } else { // Internal links. @@ -806,6 +822,12 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin neis[0] = baseTile; } + // note(amos): we run the loop in reverse here as we want to link + // edges to the furthest neighbor tiles first, this yields better + // results as when we start from closest first (which will have a + // bunch more edges eligible for linking) we would probably burn + // through all available links by the time we reach the furthest + // neighbor tile. for (int k = nneis-1; k >= 0; --k) { dtMeshTile* landTile = neis[k]; diff --git a/src/naveditor/include/Editor.h b/src/naveditor/include/Editor.h index b05c0793..491e94b0 100644 --- a/src/naveditor/include/Editor.h +++ b/src/naveditor/include/Editor.h @@ -277,6 +277,7 @@ protected: float m_agentMaxClimb; float m_agentMaxSlope; float m_traverseRayExtraOffset; + int m_maxTraverseNeighbors; int m_regionMinSize; int m_regionMergeSize; int m_edgeMaxLen;