From aaaca914a62177276691a63cbf6cc33a0c954185 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 8 Jul 2024 12:29:44 +0200 Subject: [PATCH] Recast: union poly groups connected through off-mesh connections Poly groups connected though off-mesh connections should be unioned. Confirmed working during in-editor tests. --- .../Detour/Source/DetourNavMeshBuilder.cpp | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp index 145763fe..8c2b6a88 100644 --- a/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp +++ b/src/thirdparty/recast/Detour/Source/DetourNavMeshBuilder.cpp @@ -381,6 +381,49 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) } } + // Third pass to handle off-mesh connections. + // note(amos): this has to happen after the first and second pass as these + // are for grouping directly connected polygons together, else groups linked + // through off-mesh connections will be merged into a single group! + // + // todo(amos): should off-mesh links be marked reachable for all traverse + // anim types? Research needed on Titanfall 2. For now, mark connected + // poly groups with off-mesh connections reachable. + for (int i = 0; i < nav->getMaxTiles(); ++i) + { + dtMeshTile* tile = nav->getTile(i); + if (!tile || !tile->header || !tile->dataSize) continue; + const int pcount = tile->header->polyCount; + for (int j = 0; j < pcount; j++) + { + dtPoly& poly = tile->polys[j]; + + if (poly.getType() != DT_POLYTYPE_OFFMESH_CONNECTION) + continue; + + unsigned int plink = poly.firstLink; + unsigned short firstGroupId = DT_NULL_POLY_GROUP; + + while (plink != DT_NULL_LINK) + { + const dtLink l = tile->links[plink]; + const dtMeshTile* t; + const dtPoly* p; + nav->getTileAndPolyByRefUnsafe(l.ref, &t, &p); + + if (p->groupId != DT_NULL_POLY_GROUP) + { + if (firstGroupId == DT_NULL_POLY_GROUP) + firstGroupId = p->groupId; + else + disjoint.setUnion(firstGroupId, p->groupId); + } + + plink = l.next; + } + } + } + // Gather all unique polygroups and map them to a contiguous range. std::map groupMap; unsigned short numPolyGroups = DT_FIRST_USABLE_POLY_GROUP; // Anything <= DT_STRAY_POLY_GROUP is reserved! @@ -398,7 +441,7 @@ bool dtCreateDisjointPolyGroups(dtNavMesh* nav, dtDisjointSet& disjoint) } } - // Third pass to apply the new mapping to all polys. + // Fourth pass to apply the new mapping to all polys. for (int i = 0; i < nav->getMaxTiles(); ++i) { dtMeshTile* tile = nav->getTile(i);