Append results correctly in Dijkstra searches (#205)

This changes the Dijkstra searches in findPolysAroundCircle and
findPolysAroundShape to append the results when we visit nodes in the
main loop. The algorithm guarantees that we will never visit them again
after this, so at this point we are guaranteed that we cannot find a
better path.

Previously results would be appended the first time we saw a polygon
which meant later improvements on the paths to those polygons would not
be reflected in the results.

Fix #204
This commit is contained in:
Jakob Botsch Nielsen 2016-05-18 19:01:41 +02:00 committed by Graham Pentheny
parent 16bea738b8
commit 12569b5cf6

View File

@ -2743,20 +2743,6 @@ dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float*
dtStatus status = DT_SUCCESS;
int n = 0;
if (n < maxResult)
{
if (resultRef)
resultRef[n] = startNode->id;
if (resultParent)
resultParent[n] = 0;
if (resultCost)
resultCost[n] = 0;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
const float radiusSqr = dtSqr(radius);
@ -2782,6 +2768,21 @@ dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float*
if (parentRef)
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
if (n < maxResult)
{
if (resultRef)
resultRef[n] = bestRef;
if (resultParent)
resultParent[n] = parentRef;
if (resultCost)
resultCost[n] = bestNode->total;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
{
const dtLink* link = &bestTile->links[i];
@ -2831,7 +2832,6 @@ dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float*
continue;
neighbourNode->id = neighbourRef;
neighbourNode->flags = (neighbourNode->flags & ~DT_NODE_CLOSED);
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->total = total;
@ -2841,20 +2841,6 @@ dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float*
}
else
{
if (n < maxResult)
{
if (resultRef)
resultRef[n] = neighbourNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(neighbourNode->pidx)->id;
if (resultCost)
resultCost[n] = neighbourNode->total;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
neighbourNode->flags = DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
@ -2923,20 +2909,6 @@ dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* v
dtStatus status = DT_SUCCESS;
int n = 0;
if (n < maxResult)
{
if (resultRef)
resultRef[n] = startNode->id;
if (resultParent)
resultParent[n] = 0;
if (resultCost)
resultCost[n] = 0;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
while (!m_openList->empty())
{
@ -2960,6 +2932,22 @@ dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* v
if (parentRef)
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
if (n < maxResult)
{
if (resultRef)
resultRef[n] = bestRef;
if (resultParent)
resultParent[n] = parentRef;
if (resultCost)
resultCost[n] = bestNode->total;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
{
const dtLink* link = &bestTile->links[i];
@ -3011,7 +2999,6 @@ dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* v
continue;
neighbourNode->id = neighbourRef;
neighbourNode->flags = (neighbourNode->flags & ~DT_NODE_CLOSED);
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->total = total;
@ -3021,20 +3008,6 @@ dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* v
}
else
{
if (n < maxResult)
{
if (resultRef)
resultRef[n] = neighbourNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(neighbourNode->pidx)->id;
if (resultCost)
resultCost[n] = neighbourNode->total;
++n;
}
else
{
status |= DT_BUFFER_TOO_SMALL;
}
neighbourNode->flags = DT_NODE_OPEN;
m_openList->push(neighbourNode);
}