mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: fix bugs causing mesh links to leak when removing and readding tiles
Rework the way traverse links are tracked and how the traverse table gets recreated when a tile gets removed/added. We would rebuild the entire traverse network and thus leak links since we also cleared the map that tracks the connections.
This commit is contained in:
parent
794f619d84
commit
d81f6a24aa
@ -783,6 +783,8 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
return;
|
||||
|
||||
const dtMeshHeader* baseHeader = baseTile->header;
|
||||
const dtPolyRef basePolyRefBase = m_navMesh->getPolyRefBase(baseTile);
|
||||
|
||||
bool firstBaseTileLinkUsed = false;
|
||||
|
||||
for (int i = 0; i < baseHeader->polyCount; ++i)
|
||||
@ -847,6 +849,8 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
continue;
|
||||
|
||||
const dtMeshHeader* landHeader = landTile->header;
|
||||
const dtPolyRef landPolyRefBase = m_navMesh->getPolyRefBase(landTile);
|
||||
|
||||
bool firstLandTileLinkUsed = false;
|
||||
|
||||
for (int l = 0; l < landHeader->polyCount; ++l)
|
||||
@ -942,7 +946,10 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
continue;
|
||||
}
|
||||
|
||||
const TraverseLinkPolyPair linkedPolyPair(basePoly, landPoly);
|
||||
const dtPolyRef basePolyRef = basePolyRefBase | i;
|
||||
const dtPolyRef landPolyRef = landPolyRefBase | l;
|
||||
|
||||
const TraverseLinkPolyPair linkedPolyPair(basePolyRef, landPolyRef);
|
||||
auto linkedIt = m_traverseLinkPolyMap.find(linkedPolyPair);
|
||||
|
||||
bool traverseLinkFound = false;
|
||||
@ -992,7 +999,7 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
|
||||
dtLink* const forwardLink = &baseTile->links[forwardIdx];
|
||||
|
||||
forwardLink->ref = m_navMesh->getPolyRefBase(landTile) | (dtPolyRef)l;
|
||||
forwardLink->ref = landPolyRef;
|
||||
forwardLink->edge = (unsigned char)j;
|
||||
forwardLink->side = landSide;
|
||||
forwardLink->bmin = 0;
|
||||
@ -1005,7 +1012,7 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
|
||||
dtLink* const reverseLink = &landTile->links[reverseIdx];
|
||||
|
||||
reverseLink->ref = m_navMesh->getPolyRefBase(baseTile) | (dtPolyRef)i;
|
||||
reverseLink->ref = basePolyRef;
|
||||
reverseLink->edge = (unsigned char)m;
|
||||
reverseLink->side = baseSide;
|
||||
reverseLink->bmin = 0;
|
||||
@ -1030,6 +1037,8 @@ void Editor::connectTileTraverseLinks(dtMeshTile* const baseTile, const bool lin
|
||||
bool Editor::createTraverseLinks()
|
||||
{
|
||||
rdAssert(m_navMesh);
|
||||
m_traverseLinkPolyMap.clear();
|
||||
|
||||
const int maxTiles = m_navMesh->getMaxTiles();
|
||||
|
||||
// First pass to connect edges between external tiles together.
|
||||
@ -1052,7 +1061,6 @@ bool Editor::createTraverseLinks()
|
||||
connectTileTraverseLinks(baseTile, false);
|
||||
}
|
||||
|
||||
m_traverseLinkPolyMap.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -243,8 +243,6 @@ public:
|
||||
m_editor->removeTile(m_hitPos);
|
||||
else
|
||||
m_editor->buildTile(m_hitPos);
|
||||
|
||||
m_editor->buildStaticPathingData();
|
||||
}
|
||||
else if (m_cursorMode == TT_CURSOR_MODE_DEBUG)
|
||||
{
|
||||
@ -727,6 +725,18 @@ void Editor_TileMesh::buildTile(const float* pos)
|
||||
m_navMesh->connectExtOffMeshLinks(targetRef);
|
||||
}
|
||||
}
|
||||
|
||||
dtMeshTile* tile = (dtMeshTile*)m_navMesh->getTileByRef(tileRef);
|
||||
|
||||
// Reconnect the traverse links.
|
||||
connectTileTraverseLinks(tile, true);
|
||||
connectTileTraverseLinks(tile, false);
|
||||
|
||||
dtTraverseTableCreateParams params;
|
||||
createTraverseTableParams(¶ms);
|
||||
|
||||
dtCreateDisjointPolyGroups(¶ms);
|
||||
updateStaticPathingData(¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,7 +778,34 @@ void Editor_TileMesh::removeTile(const float* pos)
|
||||
getTileExtents(tx, ty, m_lastBuiltTileBmin, m_lastBuiltTileBmax);
|
||||
|
||||
m_tileCol = duRGBA(255,0,0,180);
|
||||
m_navMesh->removeTile(m_navMesh->getTileRefAt(tx,ty,0),0,0);
|
||||
const dtTileRef tileRef = m_navMesh->getTileRefAt(tx,ty, 0);
|
||||
|
||||
if (dtStatusSucceed(m_navMesh->removeTile(tileRef, 0, 0)))
|
||||
{
|
||||
// Update traverse link map so the next time we rebuild this
|
||||
// tile, the polygon pairs will be marked as available.
|
||||
const unsigned int tileId = m_navMesh->decodePolyIdTile(tileRef);
|
||||
|
||||
for (auto it = m_traverseLinkPolyMap.cbegin(); it != m_traverseLinkPolyMap.cend();)
|
||||
{
|
||||
const TraverseLinkPolyPair& pair = it->first;
|
||||
|
||||
if (m_navMesh->decodePolyIdTile(pair.poly1) == tileId ||
|
||||
m_navMesh->decodePolyIdTile(pair.poly2) == tileId)
|
||||
{
|
||||
it = m_traverseLinkPolyMap.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
dtTraverseTableCreateParams params;
|
||||
createTraverseTableParams(¶ms);
|
||||
|
||||
dtCreateDisjointPolyGroups(¶ms);
|
||||
updateStaticPathingData(¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor_TileMesh::buildAllTiles()
|
||||
@ -837,6 +874,8 @@ void Editor_TileMesh::removeAllTiles()
|
||||
for (int y = 0; y < th; ++y)
|
||||
for (int x = 0; x < tw; ++x)
|
||||
m_navMesh->removeTile(m_navMesh->getTileRefAt(x,y,0),0,0);
|
||||
|
||||
m_traverseLinkPolyMap.clear();
|
||||
}
|
||||
|
||||
void Editor_TileMesh::buildAllHulls()
|
||||
|
@ -194,7 +194,7 @@ enum EditorPolyFlags
|
||||
|
||||
struct TraverseLinkPolyPair
|
||||
{
|
||||
TraverseLinkPolyPair(const dtPoly* p1, const dtPoly* p2)
|
||||
TraverseLinkPolyPair(dtPolyRef p1, dtPolyRef p2)
|
||||
{
|
||||
if (p1 > p2)
|
||||
rdSwap(p1, p2);
|
||||
@ -213,8 +213,8 @@ struct TraverseLinkPolyPair
|
||||
return poly2 < other.poly2;
|
||||
}
|
||||
|
||||
const dtPoly* poly1;
|
||||
const dtPoly* poly2;
|
||||
dtPolyRef poly1;
|
||||
dtPolyRef poly2;
|
||||
};
|
||||
|
||||
class EditorDebugDraw : public DebugDrawGL
|
||||
|
@ -316,6 +316,15 @@ bool dtCreateDisjointPolyGroups(const dtTraverseTableCreateParams* params)
|
||||
while (plink != DT_NULL_LINK)
|
||||
{
|
||||
const dtLink l = tile->links[plink];
|
||||
|
||||
// Polygons linked with traverse links are not necessarily on
|
||||
// the same group, these should be skipped.
|
||||
if (l.traverseType != DT_NULL_TRAVERSE_TYPE)
|
||||
{
|
||||
plink = l.next;
|
||||
continue;
|
||||
}
|
||||
|
||||
const dtMeshTile* t;
|
||||
const dtPoly* p;
|
||||
nav->getTileAndPolyByRefUnsafe(l.ref, &t, &p);
|
||||
|
Loading…
x
Reference in New Issue
Block a user