Recast: properly handle off-mesh linked polygon reachability

Handle it in the same loop as standard traverse links, off-mesh links also have a link determining its traverse type after it has been reverse engineered and fixed. The output and behavior is now correct.
This commit is contained in:
Kawe Mazidjatari 2024-08-28 14:55:16 +02:00
parent 4dfdbaee17
commit 0bfd44abba
2 changed files with 0 additions and 61 deletions

View File

@ -1200,11 +1200,6 @@ bool Editor::updateStaticPathingData(const dtTraverseTableCreateParams* params)
static bool animTypeSupportsTraverseLink(const dtTraverseTableCreateParams* params, const dtLink* link, const int tableIndex)
{
// TODO: always link off-mesh connected polygon islands together?
// Research needed.
if (link->reverseLink == DT_NULL_TRAVERSE_REVERSE_LINK)
return true;
const NavMeshType_e navMeshType = (NavMeshType_e)params->navMeshType;
// Only the _small NavMesh has more than 1 table.

View File

@ -378,51 +378,6 @@ static void unionTraverseLinkedPolyGroups(const dtTraverseTableCreateParams* par
dtNavMesh* nav = params->nav;
dtDisjointSet& set = params->sets[tableIndex];
// Fifth 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!
// This also has to happen after the remap as otherwise this information
// will be lost!
//
// 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 if (params->canTraverse(params, &l, tableIndex))
set.setUnion(firstGroupId, p->groupId);
}
plink = l.next;
}
}
}
// Sixth pass to handle traverse linked poly's.
for (int i = 0; i < nav->getMaxTiles(); ++i)
{
@ -433,25 +388,14 @@ static void unionTraverseLinkedPolyGroups(const dtTraverseTableCreateParams* par
{
dtPoly& poly = tile->polys[j];
if (poly.getType() == DT_POLYTYPE_OFFMESH_CONNECTION)
continue;
for (int k = poly.firstLink; k != DT_NULL_LINK; k = tile->links[k].next)
{
const dtLink* link = &tile->links[k];
// Skip normal and off-mesh links.
if (link->traverseType == DT_NULL_TRAVERSE_TYPE ||
(link->traverseType & DT_OFFMESH_CON_TRAVERSE_ON_VERT) ||
(link->traverseType & DT_OFFMESH_CON_TRAVERSE_ON_POLY))
continue;
const dtMeshTile* landTile;
const dtPoly* landPoly;
nav->getTileAndPolyByRefUnsafe(link->ref, &landTile, &landPoly);
rdAssert(landPoly->getType() != DT_POLYTYPE_OFFMESH_CONNECTION);
rdAssert(landPoly->groupId != DT_UNLINKED_POLY_GROUP);
if (poly.groupId != landPoly->groupId && params->canTraverse(params, link, tableIndex))