Skip to content

Connect tile polygons from different layers#1

Open
elsid wants to merge 1 commit into
OpenMW:openmw-fixesfrom
elsid:layered_navmesh
Open

Connect tile polygons from different layers#1
elsid wants to merge 1 commit into
OpenMW:openmw-fixesfrom
elsid:layered_navmesh

Conversation

@elsid
Copy link
Copy Markdown

@elsid elsid commented May 24, 2026

Fixes recastnavigation#818.

Root cause: The connectExtLinks function (which links tiles at the same x,y position but different layers) only processes DT_EXT_LINK edges - edges where the polygon mesh touches the tile boundary. For the slope geometry in the test, the walkable area never reaches the tile boundary (it's eroded away), so no DT_EXT_LINK edges exist. As a result, layers -1 and 0 had no connections, causing findPath to return DT_PARTIAL_RESULT.

Fix: Added a new connectLayerLinks(tile, target) function in DetourNavMesh.cpp that connects same-position tiles (different layers) by finding xz-overlapping polygons:

  • For each ground polygon in tile, compute its centroid
  • Query findNearestPolyInTile in target with that centroid
  • If the nearest polygon in target contains the centroid in xz (dxz < 1e-3) and the height difference is within walkableClimb, create a link with side=0xff (layer-to-layer connection)

This is called bidirectionally (connectLayerLinks(tile, neis[j]) and connectLayerLinks(neis[j], tile)) from the same place existing layer connection code runs in addTile.

Root cause: The connectExtLinks function (which links tiles at the same
x,y position but different layers) only processes DT_EXT_LINK edges -
edges where the polygon mesh touches the tile boundary. For the slope
geometry in the test, the walkable area never reaches the tile boundary
(it's eroded away), so no DT_EXT_LINK edges exist. As a result, layers
-1 and 0 had no connections, causing findPath to return
DT_PARTIAL_RESULT.

Fix: Added a new connectLayerLinks(tile, target) function in
DetourNavMesh.cpp that connects same-position tiles (different layers)
by finding xz-overlapping polygons:

* For each ground polygon in tile, compute its centroid.
* Query findNearestPolyInTile in target with that centroid.
* If the nearest polygon in target contains the centroid in xz (dxz <
  1e-3) and the height difference is within walkableClimb, create a link
  with side=0xff (layer-to-layer connection).

This is called bidirectionally (connectLayerLinks(tile, neis[j]) and
connectLayerLinks(neis[j], tile)) from the same place existing layer
connection code runs in addTile.
@elsid elsid force-pushed the layered_navmesh branch from 8473e87 to 2dc2803 Compare May 25, 2026 00:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant