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.
This commit is contained in:
Kawe Mazidjatari 2024-07-08 12:29:44 +02:00
parent 6a9599ca2e
commit aaaca914a6

View File

@ -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<unsigned short, unsigned short> 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);