diff --git a/src/naveditor/Editor.cpp b/src/naveditor/Editor.cpp index 94530010..dfd44104 100644 --- a/src/naveditor/Editor.cpp +++ b/src/naveditor/Editor.cpp @@ -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; } diff --git a/src/naveditor/Editor_TileMesh.cpp b/src/naveditor/Editor_TileMesh.cpp index 7902f259..3db79c94 100644 --- a/src/naveditor/Editor_TileMesh.cpp +++ b/src/naveditor/Editor_TileMesh.cpp @@ -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() diff --git a/src/naveditor/include/Editor.h b/src/naveditor/include/Editor.h index a73a7a61..758f3c28 100644 --- a/src/naveditor/include/Editor.h +++ b/src/naveditor/include/Editor.h @@ -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 diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 6c7ba95e..90d8ad38 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -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);