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;
|
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,
|
static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, const float* endPos,
|
||||||
const float minTargetDist,
|
const float minTargetDist,
|
||||||
const dtPolyRef* path, const int pathSize,
|
const dtPolyRef* path, const int pathSize,
|
||||||
@ -503,6 +563,8 @@ void NavMeshTesterTool::handleToggle()
|
|||||||
m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter,
|
m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter,
|
||||||
result, visited, &nvisited, 16);
|
result, visited, &nvisited, 16);
|
||||||
m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited);
|
m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited);
|
||||||
|
m_pathIterPolyCount = fixupShortcuts(m_pathIterPolys, m_pathIterPolyCount, m_navQuery);
|
||||||
|
|
||||||
float h = 0;
|
float h = 0;
|
||||||
m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h);
|
m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h);
|
||||||
result[1] = h;
|
result[1] = h;
|
||||||
@ -700,6 +762,8 @@ void NavMeshTesterTool::recalc()
|
|||||||
result, visited, &nvisited, 16);
|
result, visited, &nvisited, 16);
|
||||||
|
|
||||||
npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited);
|
npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited);
|
||||||
|
npolys = fixupShortcuts(polys, npolys, m_navQuery);
|
||||||
|
|
||||||
float h = 0;
|
float h = 0;
|
||||||
m_navQuery->getPolyHeight(polys[0], result, &h);
|
m_navQuery->getPolyHeight(polys[0], result, &h);
|
||||||
result[1] = h;
|
result[1] = h;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user