Detour: Fixed open list bug in pathfinder, nodes were never marked as closed!

Detour: Made the cost function to use polygon edge midpoints instead of polygon centroids.
This commit is contained in:
Mikko Mononen 2009-07-16 11:15:21 +00:00
parent 6fc3d5c58e
commit e1d7b3e1f5
8 changed files with 1861 additions and 2561 deletions

View File

@ -98,6 +98,7 @@ public:
// maxPathSize - (in) The max number of polygons the path array can hold.
// Returns: Number of polygons in search result array.
int findPath(dtStatPolyRef startRef, dtStatPolyRef endRef,
const float* startPos, const float* endPos,
dtStatPolyRef* path, const int maxPathSize);
// Finds a straight path from start to end locations within the corridor
@ -183,12 +184,16 @@ public:
private:
float getCost(dtStatPolyRef prev, dtStatPolyRef from, dtStatPolyRef to) const;
float getHeuristic(dtStatPolyRef from, dtStatPolyRef to) const;
float getFirstCost(const float* pos, dtStatPolyRef from, dtStatPolyRef to) const;
float getLastCost(dtStatPolyRef from, dtStatPolyRef to, const float* pos) const;
float getHeuristic(const float* from, const float* to) const;
// Copies the locations of vertices of a polygon to an array.
int getPolyVerts(dtStatPolyRef ref, float* verts) const;
// Returns portal points between two polygons.
bool getPortalPoints(dtStatPolyRef from, dtStatPolyRef to, float* left, float* right) const;
// Returns edge mid point between two polygons.
bool getEdgeMidPoint(dtStatPolyRef from, dtStatPolyRef to, float* mid) const;
unsigned char* m_data;
int m_dataSize;

View File

@ -175,6 +175,7 @@ public:
// maxPathSize - (in) The max number of polygons the path array can hold.
// Returns: Number of polygons in search result array.
int findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
const float* startPos, const float* endPos,
dtTilePolyRef* path, const int maxPathSize);
// Finds a straight path from start to end locations within the corridor
@ -264,12 +265,16 @@ private:
// Queries polygons within a tile.
int queryTilePolygons(dtTile* tile, const float* qmin, const float* qmax,
dtTilePolyRef* polys, const int maxPolys);
// Returns travel cost between two polygons.
float getCost(dtTilePolyRef prev, dtTilePolyRef from, dtTilePolyRef to) const;
// returns A* heuristics between two polygons.
float getHeuristic(dtTilePolyRef from, dtTilePolyRef to) const;
float getFirstCost(const float* pos, dtTilePolyRef from, dtTilePolyRef to) const;
float getLastCost(dtTilePolyRef from, dtTilePolyRef to, const float* pos) const;
float getHeuristic(const float* from, const float* to) const;
// Returns portal points between two polygons.
bool getPortalPoints(dtTilePolyRef from, dtTilePolyRef to, float* left, float* right) const;
// Returns edge mid point between two polygons.
bool getEdgeMidPoint(dtTilePolyRef from, dtTilePolyRef to, float* mid) const;
float m_orig[3];
float m_tileSize;

View File

@ -79,43 +79,44 @@ bool dtStatNavMesh::init(unsigned char* data, int dataSize, bool ownsData)
return true;
}
float dtStatNavMesh::getCost(dtStatPolyRef prev, dtStatPolyRef from, dtStatPolyRef to) const
{
const dtStatPoly* fromPoly = getPoly(prev ? prev-1 : from-1);
const dtStatPoly* toPoly = getPoly(to-1);
float fromPc[3], toPc[3];
calcPolyCenter(fromPc, fromPoly->v, fromPoly->nv, m_header->verts);
calcPolyCenter(toPc, toPoly->v, toPoly->nv, m_header->verts);
float dx = fromPc[0]-toPc[0];
float dy = fromPc[1]-toPc[1];
float dz = fromPc[2]-toPc[2];
return sqrtf(dx*dx + dy*dy + dz*dz);
}
float dtStatNavMesh::getHeuristic(dtStatPolyRef from, dtStatPolyRef to) const
{
const dtStatPoly* fromPoly = getPoly(from-1);
const dtStatPoly* toPoly = getPoly(to-1);
float fromPc[3], toPc[3];
calcPolyCenter(fromPc, fromPoly->v, fromPoly->nv, m_header->verts);
calcPolyCenter(toPc, toPoly->v, toPoly->nv, m_header->verts);
float dx = fromPc[0]-toPc[0];
float dy = fromPc[1]-toPc[1];
float dz = fromPc[2]-toPc[2];
return sqrtf(dx*dx + dy*dy + dz*dz) * 2.0f;
}
const dtStatPoly* dtStatNavMesh::getPolyByRef(dtStatPolyRef ref) const
{
if (!m_header || ref == 0 || (int)ref > m_header->npolys) return 0;
return &m_header->polys[ref-1];
}
float dtStatNavMesh::getCost(dtStatPolyRef prev, dtStatPolyRef from, dtStatPolyRef to) const
{
float midFrom[3], midTo[3];
if (!getEdgeMidPoint(prev,from,midFrom) || !getEdgeMidPoint(from,to,midTo))
return FLT_MAX;
return sqrtf(vdistSqr(midFrom,midTo));
}
float dtStatNavMesh::getFirstCost(const float* pos, dtStatPolyRef from, dtStatPolyRef to) const
{
float mid[3];
if (!getEdgeMidPoint(from,to,mid))
return FLT_MAX;
return sqrtf(vdistSqr(pos,mid));
}
float dtStatNavMesh::getLastCost(dtStatPolyRef from, dtStatPolyRef to, const float* pos) const
{
float mid[3];
if (!getEdgeMidPoint(from,to,mid))
return FLT_MAX;
return sqrtf(vdistSqr(mid,pos));
}
float dtStatNavMesh::getHeuristic(const float* from, const float* to) const
{
return sqrtf(vdistSqr(from,to)) * 1.1f;
}
int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef,
const float* startPos, const float* endPos,
dtStatPolyRef* path, const int maxPathSize)
{
if (!m_header) return 0;
@ -138,7 +139,7 @@ int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef,
dtNode* startNode = m_nodePool->getNode(startRef);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = getHeuristic(startRef, endRef);
startNode->total = getHeuristic(startPos, endPos);
startNode->id = startRef;
startNode->flags = DT_NODE_OPEN;
m_openList->push(startNode);
@ -170,9 +171,20 @@ int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef,
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtStatPolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
float h = getHeuristic(newNode.id, endRef);
newNode.cost = bestNode->cost + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->cost;
if (!parent->pidx)
newNode.cost += getFirstCost(startPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
// Special case for last node.
if (newNode.id == endRef)
newNode.cost += getLastCost(parent->id,newNode.id,endPos);
float ec[3];
if (!getEdgeMidPoint(parent->id,newNode.id,ec))
continue;
const float h = getHeuristic(ec, endPos);
newNode.total = newNode.cost + h;
dtNode* actualNode = m_nodePool->getNode(newNode.id);
@ -199,12 +211,13 @@ int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef,
}
else
{
actualNode->flags = DT_NODE_OPEN;
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
}
}
}
}
bestNode->flags |= DT_NODE_CLOSED;
}
// Reverse the path.
@ -555,8 +568,11 @@ float dtStatNavMesh::findDistanceToWall(dtStatPolyRef centerRef, const float* ce
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtStatPolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
newNode.total = parent->total + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->total;
if (!parent->pidx)
newNode.cost += getFirstCost(centerPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
@ -575,11 +591,12 @@ float dtStatNavMesh::findDistanceToWall(dtStatPolyRef centerRef, const float* ce
}
else
{
actualNode->flags = DT_NODE_OPEN;
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
}
}
}
bestNode->flags |= DT_NODE_CLOSED;
}
// Calc hit normal.
@ -650,8 +667,11 @@ int dtStatNavMesh::findPolysAround(dtStatPolyRef centerRef, const float* centerP
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtStatPolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
newNode.total = parent->total + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->total;
if (!parent->pidx)
newNode.cost += getFirstCost(centerPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
@ -680,12 +700,14 @@ int dtStatNavMesh::findPolysAround(dtStatPolyRef centerRef, const float* centerP
resultCost[n] = actualNode->total;
++n;
}
actualNode->flags = DT_NODE_OPEN;
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
}
}
}
}
bestNode->flags |= DT_NODE_CLOSED;
}
return n;
@ -795,6 +817,17 @@ bool dtStatNavMesh::getPortalPoints(dtStatPolyRef from, dtStatPolyRef to, float*
return false;
}
// Returns edge mid point between two polygons.
bool dtStatNavMesh::getEdgeMidPoint(dtStatPolyRef from, dtStatPolyRef to, float* mid) const
{
float left[3], right[3];
if (!getPortalPoints(from, to, left,right)) return false;
mid[0] = (left[0]+right[0])*0.5f;
mid[1] = (left[1]+right[1])*0.5f;
mid[2] = (left[2]+right[2])*0.5f;
return true;
}
bool dtStatNavMesh::isInOpenList(dtStatPolyRef ref) const
{
if (!m_nodePool) return false;

View File

@ -616,50 +616,35 @@ int dtTiledNavMesh::queryPolygons(const float* center, const float* extents,
float dtTiledNavMesh::getCost(dtTilePolyRef prev, dtTilePolyRef from, dtTilePolyRef to) const
{
unsigned int salt, it, ip;
if (prev) from = prev;
// The API input has been cheked already, skip checking internal data.
dtDecodeTileId(from, salt, it, ip);
const dtTileHeader* fromHeader = m_tiles[it].header;
const dtTilePoly* fromPoly = &fromHeader->polys[ip];
dtDecodeTileId(to, salt, it, ip);
const dtTileHeader* toHeader = m_tiles[it].header;
const dtTilePoly* toPoly = &toHeader->polys[ip];
float fromPc[3], toPc[3];
calcPolyCenter(fromPc, fromPoly->v, fromPoly->nv, fromHeader->verts);
calcPolyCenter(toPc, toPoly->v, toPoly->nv, toHeader->verts);
float dx = fromPc[0]-toPc[0];
float dy = fromPc[1]-toPc[1];
float dz = fromPc[2]-toPc[2];
return sqrtf(dx*dx + dy*dy + dz*dz);
float midFrom[3], midTo[3];
if (!getEdgeMidPoint(prev,from,midFrom) || !getEdgeMidPoint(from,to,midTo))
return FLT_MAX;
return sqrtf(vdistSqr(midFrom,midTo));
}
float dtTiledNavMesh::getHeuristic(dtTilePolyRef from, dtTilePolyRef to) const
float dtTiledNavMesh::getFirstCost(const float* pos, dtTilePolyRef from, dtTilePolyRef to) const
{
unsigned int salt, it, ip;
// The API input has been cheked already, skip checking internal data.
dtDecodeTileId(from, salt, it, ip);
const dtTileHeader* fromHeader = m_tiles[it].header;
const dtTilePoly* fromPoly = &fromHeader->polys[ip];
dtDecodeTileId(to, salt, it, ip);
const dtTileHeader* toHeader = m_tiles[it].header;
const dtTilePoly* toPoly = &toHeader->polys[ip];
float mid[3];
if (!getEdgeMidPoint(from,to,mid))
return FLT_MAX;
return sqrtf(vdistSqr(pos,mid));
}
float fromPc[3], toPc[3];
calcPolyCenter(fromPc, fromPoly->v, fromPoly->nv, fromHeader->verts);
calcPolyCenter(toPc, toPoly->v, toPoly->nv, toHeader->verts);
float dtTiledNavMesh::getLastCost(dtTilePolyRef from, dtTilePolyRef to, const float* pos) const
{
float mid[3];
if (!getEdgeMidPoint(from,to,mid))
return FLT_MAX;
return sqrtf(vdistSqr(mid,pos));
}
float dx = fromPc[0]-toPc[0];
float dy = fromPc[1]-toPc[1];
float dz = fromPc[2]-toPc[2];
return sqrtf(dx*dx + dy*dy + dz*dz) * 2.0f;
float dtTiledNavMesh::getHeuristic(const float* from, const float* to) const
{
return sqrtf(vdistSqr(from,to)) * 1.1f;
}
int dtTiledNavMesh::findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
const float* startPos, const float* endPos,
dtTilePolyRef* path, const int maxPathSize)
{
if (!startRef || !endRef)
@ -686,7 +671,7 @@ int dtTiledNavMesh::findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
dtNode* startNode = m_nodePool->getNode(startRef);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = getHeuristic(startRef, endRef);
startNode->total = getHeuristic(startPos, endPos);
startNode->id = startRef;
startNode->flags = DT_NODE_OPEN;
m_openList->push(startNode);
@ -724,9 +709,20 @@ int dtTiledNavMesh::findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtTilePolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
float h = getHeuristic(newNode.id, endRef);
newNode.cost = bestNode->cost + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->cost;
if (!parent->pidx)
newNode.cost += getFirstCost(startPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
// Special case for last node.
if (newNode.id == endRef)
newNode.cost += getLastCost(parent->id,newNode.id,endPos);
float ec[3];
if (!getEdgeMidPoint(parent->id,newNode.id,ec))
continue;
const float h = getHeuristic(ec, endPos);
newNode.total = newNode.cost + h;
dtNode* actualNode = m_nodePool->getNode(newNode.id);
@ -753,12 +749,13 @@ int dtTiledNavMesh::findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
}
else
{
actualNode->flags = DT_NODE_OPEN;
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
}
}
}
}
bestNode->flags |= DT_NODE_CLOSED;
}
// Reverse the path.
@ -991,6 +988,17 @@ bool dtTiledNavMesh::getPortalPoints(dtTilePolyRef from, dtTilePolyRef to, float
return false;
}
// Returns edge mid point between two polygons.
bool dtTiledNavMesh::getEdgeMidPoint(dtTilePolyRef from, dtTilePolyRef to, float* mid) const
{
float left[3], right[3];
if (!getPortalPoints(from, to, left,right)) return false;
mid[0] = (left[0]+right[0])*0.5f;
mid[1] = (left[1]+right[1])*0.5f;
mid[2] = (left[2]+right[2])*0.5f;
return true;
}
int dtTiledNavMesh::raycast(dtTilePolyRef centerRef, const float* startPos, const float* endPos,
float& t, dtTilePolyRef* path, const int pathSize)
{
@ -1160,8 +1168,11 @@ int dtTiledNavMesh::findPolysAround(dtTilePolyRef centerRef, const float* center
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtTilePolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
newNode.total = parent->total + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->total;
if (!parent->pidx)
newNode.cost += getFirstCost(centerPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
@ -1300,8 +1311,11 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c
newNode.pidx = m_nodePool->getNodeIdx(parent);
newNode.id = neighbour;
dtTilePolyRef prevRef = parent->pidx ? m_nodePool->getNodeAtIdx(parent->pidx)->id : 0;
newNode.total = parent->total + getCost(prevRef, parent->id, newNode.id);
newNode.cost = parent->total;
if (!parent->pidx)
newNode.cost += getFirstCost(centerPos,parent->id,newNode.id);
else
newNode.cost += getCost(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, newNode.id);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)

File diff suppressed because it is too large Load Diff

View File

@ -279,14 +279,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>27</integer>
<integer>18</integer>
<integer>7</integer>
<integer>3</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 266}, {282, 628}}</string>
<string>{{0, 2}, {282, 628}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -321,7 +321,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>RecastTimer.cpp</string>
<string>DetourTileNavMesh.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -329,11 +329,11 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>RecastTimer.cpp</string>
<string>DetourTileNavMesh.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6B92CE9D100E0763003DA304</string>
<string>6B996062100F42AF00D7BF5A</string>
<key>history</key>
<array>
<string>6B7707F00FBD90F100D21BAE</string>
@ -355,7 +355,6 @@
<string>6B024C011006098300CF7107</string>
<string>6B024C1110060C7600CF7107</string>
<string>6B1186211006945C0018F96F</string>
<string>6B1186CF100699A00018F96F</string>
<string>6B1186D1100699A00018F96F</string>
<string>6B1186E610069E200018F96F</string>
<string>6B7EBB69100721310066EF8C</string>
@ -370,34 +369,39 @@
<string>6B555F0D100B473F00247EA3</string>
<string>6B555F0E100B473F00247EA3</string>
<string>6B555F0F100B473F00247EA3</string>
<string>6B555F10100B473F00247EA3</string>
<string>6B555F42100B4C5800247EA3</string>
<string>6B555F5E100B53F500247EA3</string>
<string>6B555F8B100B577A00247EA3</string>
<string>6B555FA8100B589200247EA3</string>
<string>6B92CE68100E0577003DA304</string>
<string>6B92CE69100E0577003DA304</string>
<string>6B92CE6A100E0577003DA304</string>
<string>6B92CE6B100E0577003DA304</string>
<string>6B92CE6C100E0577003DA304</string>
<string>6B92CE6D100E0577003DA304</string>
<string>6B92CE6E100E0577003DA304</string>
<string>6B92CE6F100E0577003DA304</string>
<string>6B92CE70100E0577003DA304</string>
<string>6B92CE71100E0577003DA304</string>
<string>6B92CE72100E0577003DA304</string>
<string>6B92CE73100E0577003DA304</string>
<string>6B92CE74100E0577003DA304</string>
<string>6B92CE89100E0739003DA304</string>
<string>6B92CE8A100E0739003DA304</string>
<string>6B92CE8C100E0739003DA304</string>
<string>6B92CE9A100E0763003DA304</string>
<string>6B92CE9B100E0763003DA304</string>
<string>6B995F9F100F336B00D7BF5A</string>
<string>6B995FA2100F336B00D7BF5A</string>
<string>6B995FA4100F336B00D7BF5A</string>
<string>6B995FDE100F387200D7BF5A</string>
<string>6B995FDF100F387200D7BF5A</string>
<string>6B995FF4100F39EA00D7BF5A</string>
<string>6B996047100F41DB00D7BF5A</string>
<string>6B996049100F41DB00D7BF5A</string>
<string>6B996059100F42AF00D7BF5A</string>
<string>6B99605A100F42AF00D7BF5A</string>
<string>6B99605B100F42AF00D7BF5A</string>
<string>6B99605C100F42AF00D7BF5A</string>
<string>6B99605D100F42AF00D7BF5A</string>
</array>
<key>nextStack</key>
<array>
<string>6B996061100F42AF00D7BF5A</string>
</array>
<key>prevStack</key>
<array>
<string>6B1E02680F924A8500CC0038</string>
<string>6B1E029B0F924D8B00CC0038</string>
<string>6B1E02FC0F92563500CC0038</string>
<string>6B1E032E0F925D9100CC0038</string>
<string>6B8DB3900F9798DE007FA9E1</string>
@ -439,43 +443,32 @@
<string>6B1186311006945C0018F96F</string>
<string>6B1186401006945C0018F96F</string>
<string>6B1186411006945C0018F96F</string>
<string>6B1186581006945C0018F96F</string>
<string>6B118672100694C40018F96F</string>
<string>6B555D26100B136A00247EA3</string>
<string>6B555DC9100B236A00247EA3</string>
<string>6B555E12100B285300247EA3</string>
<string>6B555E13100B285300247EA3</string>
<string>6B555EE0100B39A600247EA3</string>
<string>6B555EF9100B42E600247EA3</string>
<string>6B555F63100B53F500247EA3</string>
<string>6B555F90100B577A00247EA3</string>
<string>6B555FB4100B595C00247EA3</string>
<string>6B92CE50100E02D3003DA304</string>
<string>6B92CE75100E0577003DA304</string>
<string>6B92CE76100E0577003DA304</string>
<string>6B92CE77100E0577003DA304</string>
<string>6B92CE78100E0577003DA304</string>
<string>6B92CE79100E0577003DA304</string>
<string>6B92CE7A100E0577003DA304</string>
<string>6B92CE7B100E0577003DA304</string>
<string>6B92CE7C100E0577003DA304</string>
<string>6B92CE7D100E0577003DA304</string>
<string>6B92CE7E100E0577003DA304</string>
<string>6B92CE7F100E0577003DA304</string>
<string>6B92CE80100E0577003DA304</string>
<string>6B92CE81100E0577003DA304</string>
<string>6B92CE82100E0577003DA304</string>
<string>6B92CE83100E0577003DA304</string>
<string>6B92CE84100E0577003DA304</string>
<string>6B92CE8E100E0739003DA304</string>
<string>6B92CE8F100E0739003DA304</string>
<string>6B92CE90100E0739003DA304</string>
<string>6B92CE91100E0739003DA304</string>
<string>6B92CE92100E0739003DA304</string>
<string>6B92CE93100E0739003DA304</string>
<string>6B92CE94100E0739003DA304</string>
<string>6B92CE95100E0739003DA304</string>
<string>6B92CE9C100E0763003DA304</string>
<string>6B995FA9100F336B00D7BF5A</string>
<string>6B995FB4100F336B00D7BF5A</string>
<string>6B995FB5100F336B00D7BF5A</string>
<string>6B995FBE100F336B00D7BF5A</string>
<string>6B995FC1100F336B00D7BF5A</string>
<string>6B995FCF100F345100D7BF5A</string>
<string>6B995FE3100F387200D7BF5A</string>
<string>6B995FE4100F387200D7BF5A</string>
<string>6B995FF7100F39EA00D7BF5A</string>
<string>6B99604D100F41DB00D7BF5A</string>
<string>6B99604E100F41DB00D7BF5A</string>
<string>6B99604F100F41DB00D7BF5A</string>
<string>6B996050100F41DB00D7BF5A</string>
<string>6B996051100F41DB00D7BF5A</string>
<string>6B996053100F41DB00D7BF5A</string>
<string>6B996055100F41DB00D7BF5A</string>
<string>6B99605E100F42AF00D7BF5A</string>
<string>6B99605F100F42AF00D7BF5A</string>
<string>6B996060100F42AF00D7BF5A</string>
</array>
</dict>
<key>SplitCount</key>
@ -489,18 +482,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {976, 449}}</string>
<string>{{0, 0}, {976, 548}}</string>
<key>RubberWindowFrame</key>
<string>0 91 1280 687 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>449pt</string>
<string>548pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>192pt</string>
<string>93pt</string>
<key>Tabs</key>
<array>
<dict>
@ -514,7 +507,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {976, 64}}</string>
<string>{{10, 27}, {976, 68}}</string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@ -568,7 +561,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {976, 165}}</string>
<string>{{10, 27}, {976, 66}}</string>
<key>RubberWindowFrame</key>
<string>0 91 1280 687 0 0 1280 778 </string>
</dict>
@ -598,11 +591,11 @@
</array>
<key>TableOfContents</key>
<array>
<string>6B92CE3F100E01F0003DA304</string>
<string>6B995F7A100F14BB00D7BF5A</string>
<string>1CA23ED40692098700951B8B</string>
<string>6B92CE40100E01F0003DA304</string>
<string>6B995F7B100F14BB00D7BF5A</string>
<string>6B8632A30F78115100E2684A</string>
<string>6B92CE41100E01F0003DA304</string>
<string>6B995F7C100F14BB00D7BF5A</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
@ -749,14 +742,14 @@
</array>
<key>TableOfContents</key>
<array>
<string>6B92CE52100E02D3003DA304</string>
<string>6B995FC4100F336D00D7BF5A</string>
<string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string>
<string>6B92CE53100E02D3003DA304</string>
<string>6B92CE54100E02D3003DA304</string>
<string>6B92CE55100E02D3003DA304</string>
<string>6B92CE56100E02D3003DA304</string>
<string>6B92CE57100E02D3003DA304</string>
<string>6B995FC5100F336D00D7BF5A</string>
<string>6B995FC6100F336D00D7BF5A</string>
<string>6B995FC7100F336D00D7BF5A</string>
<string>6B995FC8100F336D00D7BF5A</string>
<string>6B8632A30F78115100E2684A</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
@ -786,6 +779,8 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>6B996027100F3E4200D7BF5A</string>
<string>6B996028100F3E4200D7BF5A</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array>
<key>WindowString</key>

View File

@ -114,7 +114,7 @@ void Sample_StatMesh::toolRecalc()
{
if (m_sposSet && m_eposSet && m_startRef && m_endRef)
{
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_polys, MAX_POLYS);
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, m_polys, MAX_POLYS);
if (m_npolys)
m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys, m_straightPath, MAX_POLYS);
}

View File

@ -119,7 +119,7 @@ void Sample_TileMesh::toolRecalc()
{
if (m_sposSet && m_eposSet && m_startRef && m_endRef)
{
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_polys, MAX_POLYS);
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, m_polys, MAX_POLYS);
if (m_npolys)
m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys, m_straightPath, MAX_POLYS);
}