From b41141018e9be3c28cdbc74d1fc7e3b8ec876c6d Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 3 Nov 2024 02:04:27 +0100 Subject: [PATCH] Recast: run the full compass rose during traverse linkage Go over each neighboring tile starting with the tile facing the edge normal, and then its oposite, and perform the same alternation on the next tiles. This link pattern gives the best and most consistent results by trying to link all sides equally. In order to guarantee maximum coverage, the link count multiplication has been increased from 8 to 32 per detail mesh bound as this new approach is creating an incredible amount of new links. Some of the links will end up not being used, but these will be removed during the prune stage. --- .../recast/Detour/Source/DetourNavMesh.cpp | 31 ++++++++++++++++--- .../Detour/Source/DetourNavMeshBuilder.cpp | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp index 2a596ce1..46744097 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMesh.cpp @@ -878,11 +878,33 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver int nneis = 0; - if (params.linkToNeighbor) // Retrieve the neighboring tiles on the side of our base poly edge. + if (params.linkToNeighbor) // Retrieve the neighboring tiles. { - nneis = getNeighbourTilesAt(baseHeader->x, baseHeader->y, baseSide, neis, MAX_NEIS); + // Start with the tile our edge is facing first, as this has the highest + // chance for the best connection. + nneis = getNeighbourTilesAt(baseHeader->x, baseHeader->y, baseSide, neis, nneis); + bool getOpposite = true; - // No neighbors, nothing to link to on this side. + // Get the other tiles starting from the opposite of the base side in the + // compass rose, and alternate between the next side and its opposite. It + // is possible we don't end up linking to these if we happen to run out + // of links on the base tile. + for (int n = 1; n < 8; ++n, getOpposite ^= true) + { + const int side = getOpposite + ? rdOppositeTile(baseSide+n) + : rdWrapTileSide(baseSide+n); + + rdAssert(side != baseSide); + const int numSlotsLeft = MAX_NEIS-nneis; + + if (!numSlotsLeft) + break; + + nneis += getNeighbourTilesAt(baseHeader->x, baseHeader->y, side, &neis[nneis], numSlotsLeft); + } + + // No neighbors, nothing to link to. if (!nneis) continue; } @@ -1030,9 +1052,10 @@ dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraver const float* const lowerEdgeNorm = basePolyHigher ? landEdgeNorm : baseEdgeNorm; const float* const higherEdgeNorm = basePolyHigher ? baseEdgeNorm : landEdgeNorm; + const float walkableHeight = basePolyHigher ? baseHeader->walkableHeight : landHeader->walkableHeight; const float walkableRadius = basePolyHigher ? baseHeader->walkableRadius : landHeader->walkableRadius; - if (!params.traverseLinkInLOS(params.userData, lowerEdgeMid, higherEdgeMid, lowerEdgeNorm, higherEdgeNorm, walkableRadius, slopeAngle)) + if (!params.traverseLinkInLOS(params.userData, lowerEdgeMid, higherEdgeMid, lowerEdgeNorm, higherEdgeNorm, walkableHeight, walkableRadius, slopeAngle)) continue; const unsigned char landSide = params.linkToNeighbor diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 29cca6b1..489e4c0e 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -909,7 +909,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, detailBoundCount += (numDetailBounds-numPolyBounds); } - const int maxLinkCount = edgeCount + detailBoundCount*4 + portalCount*2 + baseOffMeshConLinkCount*3 + landOffMeshConLinkCount; + const int maxLinkCount = edgeCount + detailBoundCount*32 + portalCount*2 + baseOffMeshConLinkCount*3 + landOffMeshConLinkCount; // Find unique detail vertices. int uniqueDetailVertCount = 0;