Fix for U-turn path case
This commit is contained in:
parent
cbab6a3825
commit
bc964f9994
@ -101,6 +101,66 @@ static int fixupCorridor(dtPolyRef* path, const int npath, const int maxPath,
|
||||
return req+size;
|
||||
}
|
||||
|
||||
// This function checks if the path has a small U-turn, that is,
|
||||
// a polygon further in the path is adjacent to the first polygon
|
||||
// in the path. If that happens, a shortcut is taken.
|
||||
// This can happen if the target (T) location is at tile boundary,
|
||||
// and we're (S) approaching it parallel to the tile edge.
|
||||
// The choice at the vertex can be arbitrary,
|
||||
// +---+---+
|
||||
// |:::|:::|
|
||||
// +-S-+-T-+
|
||||
// |:::| | <-- the step can end up in here, resulting U-turn path.
|
||||
// +---+---+
|
||||
static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery)
|
||||
{
|
||||
if (npath < 3)
|
||||
return npath;
|
||||
|
||||
// Get connected polygons
|
||||
static const int maxNeis = 16;
|
||||
dtPolyRef neis[maxNeis];
|
||||
int nneis = 0;
|
||||
|
||||
const dtMeshTile* tile = 0;
|
||||
const dtPoly* poly = 0;
|
||||
if (dtStatusFailed(navQuery->getAttachedNavMesh()->getTileAndPolyByRef(path[0], &tile, &poly)))
|
||||
return npath;
|
||||
|
||||
for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next)
|
||||
{
|
||||
const dtLink* link = &tile->links[k];
|
||||
if (link->ref != 0)
|
||||
{
|
||||
if (nneis < maxNeis)
|
||||
neis[nneis++] = link->ref;
|
||||
}
|
||||
}
|
||||
|
||||
// If any of the neighbour polygons is within the next few polygons
|
||||
// in the path, short cut to that polygon directly.
|
||||
static const int maxLookAhead = 6;
|
||||
int cut = 0;
|
||||
for (int i = dtMin(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--) {
|
||||
for (int j = 0; j < nneis; j++)
|
||||
{
|
||||
if (path[i] == neis[j]) {
|
||||
cut = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cut > 1)
|
||||
{
|
||||
int offset = cut-1;
|
||||
npath -= offset;
|
||||
for (int i = 1; i < npath; i++)
|
||||
path[i] = path[i+offset];
|
||||
}
|
||||
|
||||
return npath;
|
||||
}
|
||||
|
||||
static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, const float* endPos,
|
||||
const float minTargetDist,
|
||||
const dtPolyRef* path, const int pathSize,
|
||||
@ -503,6 +563,8 @@ void NavMeshTesterTool::handleToggle()
|
||||
m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter,
|
||||
result, visited, &nvisited, 16);
|
||||
m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited);
|
||||
m_pathIterPolyCount = fixupShortcuts(m_pathIterPolys, m_pathIterPolyCount, m_navQuery);
|
||||
|
||||
float h = 0;
|
||||
m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h);
|
||||
result[1] = h;
|
||||
@ -698,8 +760,10 @@ void NavMeshTesterTool::recalc()
|
||||
int nvisited = 0;
|
||||
m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter,
|
||||
result, visited, &nvisited, 16);
|
||||
|
||||
|
||||
npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited);
|
||||
npolys = fixupShortcuts(polys, npolys, m_navQuery);
|
||||
|
||||
float h = 0;
|
||||
m_navQuery->getPolyHeight(polys[0], result, &h);
|
||||
result[1] = h;
|
||||
|
Loading…
x
Reference in New Issue
Block a user