Recast: combine off-mesh link basing and land connection logic

Combine the 2 to avoid an extra loop. Also break out of tile grid loop as soon as a link has been established to save even more processing time.
This commit is contained in:
Kawe Mazidjatari 2024-09-18 17:28:10 +02:00
parent 8eaa349dbc
commit d5fa52499c
4 changed files with 39 additions and 62 deletions

View File

@ -850,12 +850,8 @@ void Editor::connectOffMeshLinks()
const dtTileRef targetRef = m_navMesh->getTileRef(target);
// Base off-mesh connections to their starting polygons
// and connect connections inside the tile.
m_navMesh->baseOffMeshLinks(targetRef);
// Connect off-mesh polygons to outer tiles.
m_navMesh->connectExtOffMeshLinks(targetRef);
// Connect off-mesh polygons to inner and outer tiles.
m_navMesh->connectOffMeshLinks(targetRef);
}
}

View File

@ -700,10 +700,7 @@ void Editor_TileMesh::buildTile(const float* pos)
failure = true;
}
else if (header->offMeshConCount)
{
m_navMesh->baseOffMeshLinks(tileRef);
m_navMesh->connectExtOffMeshLinks(tileRef);
}
m_navMesh->connectOffMeshLinks(tileRef);
if (!failure)
{
@ -731,7 +728,7 @@ void Editor_TileMesh::buildTile(const float* pos)
getTilePos(&con->pos[3], landTx, landTy);
if (landTx == tx && landTy == ty)
m_navMesh->connectExtOffMeshLinks(targetRef);
m_navMesh->connectOffMeshLinks(targetRef);
}
}

View File

@ -950,9 +950,7 @@ public:
/// Builds external polygon links for a tile.
dtStatus connectTraverseLinks(const dtTileRef tileRef, const dtTraverseLinkConnectParams& params);
/// Builds external polygon links for a tile.
dtStatus connectExtOffMeshLinks(const dtTileRef tileRef);
/// Builds internal polygons links for a tile.
dtStatus baseOffMeshLinks(const dtTileRef tileRef);
dtStatus connectOffMeshLinks(const dtTileRef tileRef);
dtPolyRef clampOffMeshVertToPoly(const dtOffMeshConnection* con, dtMeshTile* conTile, const dtMeshTile* lookupTile, const bool start);

View File

@ -577,7 +577,7 @@ static bool connectOffMeshLink(dtMeshTile* tile, dtPoly* fromPoly, const dtPolyR
return true;
}
dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef)
dtStatus dtNavMesh::connectOffMeshLinks(const dtTileRef tileRef)
{
const int tileIndex = (int)decodePolyIdTile((dtPolyRef)tileRef);
if (tileIndex >= m_maxTiles)
@ -594,6 +594,28 @@ dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef)
dtOffMeshConnection* con = &tile->offMeshCons[i];
dtPoly* conPoly = &tile->polys[con->poly];
const dtPolyRef basePolyRef = clampOffMeshVertToPoly(con, tile, tile, true);
if (!basePolyRef)
continue;
const unsigned char traverseType = con->getTraverseType();
const bool invertVertLookup = con->getVertLookupOrder();
// Start end-point is always connect back to off-mesh connection.
const unsigned short basePolyIdx = (unsigned short)decodePolyIdPoly(basePolyRef);
dtPoly* basePoly = &tile->polys[basePolyIdx];
const dtPolyRef conPolyRef = base | (dtPolyRef)(con->poly);
if (!connectOffMeshLink(tile, basePoly, conPolyRef, 0xff, 0xff, traverseType,
invertVertLookup ? DT_OFFMESH_CON_TRAVERSE_ON_VERT : DT_OFFMESH_CON_TRAVERSE_ON_POLY))
return DT_FAILURE | DT_OUT_OF_MEMORY;
// Link off-mesh connection to target poly.
if (!connectOffMeshLink(tile, conPoly, basePolyRef, 0xff, 0, DT_NULL_TRAVERSE_TYPE, 0))
return DT_FAILURE | DT_OUT_OF_MEMORY;
// connect to land points.
const float halfExtents[3] = { con->rad, con->rad, header->walkableClimb };
float bmin[3], bmax[3];
@ -608,19 +630,15 @@ dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef)
static const int MAX_NEIS = 32;
dtMeshTile* neis[MAX_NEIS];
const dtPolyRef conPolyRef = base | (dtPolyRef)(con->poly);
const unsigned char side = rdClassifyPointOutsideBounds(&con->pos[3], header->bmin, header->bmax);
const unsigned char oppositeSide = (side == 0xff) ? 0xff : (unsigned char)rdOppositeTile(side);
const unsigned char traverseType = con->getTraverseType();
const bool invertVertLookup = con->getVertLookupOrder();
#if DT_NAVMESH_SET_VERSION >= 7
// NOTE: need to remove the vert lookup inversion flag from here as the
// engine uses this value directly to index into the activity array.
con->setTraverseType(traverseType, 0);
#endif
bool breakOut = false;
for (int y = miny; y <= maxy; ++y)
{
@ -653,8 +671,18 @@ dtStatus dtNavMesh::connectExtOffMeshLinks(const dtTileRef tileRef)
invertVertLookup ? DT_OFFMESH_CON_TRAVERSE_ON_POLY : DT_OFFMESH_CON_TRAVERSE_ON_VERT))
return DT_FAILURE | DT_OUT_OF_MEMORY;
}
// Off-mesh links have been established, break out entirely.
breakOut = true;
break;
}
if (breakOut)
break;
}
if (breakOut)
break;
}
}
@ -701,48 +729,6 @@ void dtNavMesh::connectIntLinks(dtMeshTile* tile)
}
}
dtStatus dtNavMesh::baseOffMeshLinks(const dtTileRef tileRef)
{
const int tileIndex = (int)decodePolyIdTile((dtPolyRef)tileRef);
if (tileIndex >= m_maxTiles)
return DT_FAILURE | DT_OUT_OF_MEMORY;
dtMeshTile* tile = &m_tiles[tileIndex];
const dtMeshHeader* header = tile->header;
dtPolyRef base = getPolyRefBase(tile);
for (int i = 0; i < header->offMeshConCount; ++i)
{
// Base off-mesh connection start points.
dtOffMeshConnection* con = &tile->offMeshCons[i];
dtPoly* conPoly = &tile->polys[con->poly];
const dtPolyRef basePolyRef = clampOffMeshVertToPoly(con, tile, tile, true);
if (!basePolyRef)
continue;
const unsigned char traverseType = con->getTraverseType();
const bool invertVertLookup = con->getVertLookupOrder();
// Link off-mesh connection to target poly.
if (!connectOffMeshLink(tile, conPoly, basePolyRef, 0xff, 0, DT_NULL_TRAVERSE_TYPE, 0))
return DT_FAILURE | DT_OUT_OF_MEMORY;
// Start end-point is always connect back to off-mesh connection.
const unsigned short basePolyIdx = (unsigned short)decodePolyIdPoly(basePolyRef);
dtPoly* basePoly = &tile->polys[basePolyIdx];
const dtPolyRef conPolyRef = base | (dtPolyRef)(con->poly);
if (!connectOffMeshLink(tile, basePoly, conPolyRef, 0xff, 0xff, traverseType,
invertVertLookup ? DT_OFFMESH_CON_TRAVERSE_ON_VERT : DT_OFFMESH_CON_TRAVERSE_ON_POLY))
return DT_FAILURE | DT_OUT_OF_MEMORY;
}
return DT_SUCCESS;
}
dtStatus dtNavMesh::connectTraverseLinks(const dtTileRef tileRef, const dtTraverseLinkConnectParams& params)
{
const int tileIndex = (int)decodePolyIdTile((dtPolyRef)tileRef);