Recast: only link 2 polygons with the same traverse type once

Major improvement to generated navmesh, avoids duplicated links.
This commit is contained in:
Kawe Mazidjatari 2024-08-20 22:22:43 +02:00
parent afbcd4d91b
commit 1024f50c0c
2 changed files with 43 additions and 4 deletions

View File

@ -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;
}

View File

@ -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<TraverseLinkPolyPair, unsigned int> m_traverseLinkPolyMap;
EditorDebugDraw m_dd;
unsigned int m_navMeshDrawFlags;