From 1024f50c0c81a9f2d0f546d80050a5a96e4d2786 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:22:43 +0200 Subject: [PATCH] Recast: only link 2 polygons with the same traverse type once Major improvement to generated navmesh, avoids duplicated links. --- src/naveditor/Editor.cpp | 21 +++++++++++++++++---- src/naveditor/include/Editor.h | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index 22a43b48..42a9884e 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -762,10 +762,6 @@ static bool traverseLinkInLOS(const InputGeom* geom, const float* lowPos, const return true; } -// TODO: create lookup table and look for distance + slope to determine the -// correct jumpType. -// TODO: make sure we don't generate duplicate pairs of jump types between -// 2 polygons. void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool linkToNeighbor) { // If we link to the same tile, we need at least 2 links. @@ -919,6 +915,17 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin continue; } + const TraverseLinkPolyPair linkedPolyPair(basePoly, landPoly); + auto linkedIt = m_traverseLinkPolyMap.find(linkedPolyPair); + + bool traverseLinkFound = false; + + if (linkedIt != m_traverseLinkPolyMap.end()) + traverseLinkFound = true; + + // These 2 polygons are already linked with the same traverse type. + if (traverseLinkFound && (rdBitCellBit(traverseType) & linkedIt->second)) + continue; const bool basePolyHigher = basePolyEdgeMid[2] > landPolyEdgeMid[2]; float* const lowerEdgeMid = basePolyHigher ? landPolyEdgeMid : basePolyEdgeMid; @@ -981,6 +988,11 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin reverseLink->traverseType = (unsigned char)traverseType; reverseLink->traverseDist = quantDist; reverseLink->reverseLink = (unsigned short)forwardIdx; + + if (traverseLinkFound) + linkedIt->second |= 1 << traverseType; + else + m_traverseLinkPolyMap.emplace(linkedPolyPair, 1 << traverseType); } } } @@ -1013,6 +1025,7 @@ bool Editor::createTraverseLinks() connectTileTraverseLinks(baseTile, false); } + m_traverseLinkPolyMap.clear(); return true; } diff --git a/src/naveditor/include/Editor.h b/src/naveditor/include/Editor.h index 91d3ee67..b05c0793 100644 --- a/src/naveditor/include/Editor.h +++ b/src/naveditor/include/Editor.h @@ -192,6 +192,31 @@ enum EditorPolyFlags EDITOR_POLYFLAGS_ALL = 0xffff // All abilities. }; +struct TraverseLinkPolyPair +{ + TraverseLinkPolyPair(const dtPoly* p1, const dtPoly* p2) + { + if (p1 > p2) + rdSwap(p1, p2); + + poly1 = p1; + poly2 = p2; + } + + bool operator<(const TraverseLinkPolyPair& other) const + { + if (poly1 < other.poly1) + return true; + if (poly1 > other.poly1) + return false; + + return poly2 < other.poly2; + } + + const dtPoly* poly1; + const dtPoly* poly2; +}; + class EditorDebugDraw : public DebugDrawGL { public: @@ -274,6 +299,7 @@ protected: BuildContext* m_ctx; dtDisjointSet m_djs[DT_MAX_TRAVERSE_TABLES]; + std::map m_traverseLinkPolyMap; EditorDebugDraw m_dd; unsigned int m_navMeshDrawFlags;