Changed dtQueryFilter to contain the flags check and cost calculation, can customized. Fix for issue 47 and issue 103.

This commit is contained in:
Mikko Mononen 2010-08-20 09:30:37 +00:00
parent 8215cd48d1
commit 0e4aa30e85
19 changed files with 2458 additions and 13396 deletions

View File

@ -29,6 +29,7 @@ enum DrawNavMeshFlags
void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh& mesh, unsigned char flags);
void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMeshQuery& query, unsigned char flags);
void duDebugDrawNavMeshNodes(struct duDebugDraw* dd, const dtNavMeshQuery& query);
void duDebugDrawNavMeshBVTree(struct duDebugDraw* dd, const dtNavMesh& mesh);
void duDebugDrawNavMeshPortals(struct duDebugDraw* dd, const dtNavMesh& mesh);
void duDebugDrawNavMeshPoly(struct duDebugDraw* dd, const dtNavMesh& mesh, dtPolyRef ref, const unsigned int col);

View File

@ -21,6 +21,7 @@
#include "DetourDebugDraw.h"
#include "DetourNavMesh.h"
#include "DetourCommon.h"
#include "DetourNode.h"
static float distancePtLine2d(const float* pt, const float* p, const float* q)
@ -220,7 +221,6 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
dd->end();
}
const unsigned int vcol = duRGBA(0,0,0,196);
dd->begin(DU_DRAW_POINTS, 3.0f);
for (int i = 0; i < tile->header->vertCount; ++i)
@ -229,7 +229,7 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh& mesh, const dtNavMesh
dd->vertex(v[0], v[1], v[2], vcol);
}
dd->end();
dd->depthMask(true);
}
@ -257,6 +257,44 @@ void duDebugDrawNavMeshWithClosedList(struct duDebugDraw* dd, const dtNavMesh& m
}
}
void duDebugDrawNavMeshNodes(struct duDebugDraw* dd, const dtNavMeshQuery& query)
{
if (!dd) return;
const dtNodePool* pool = query.getNodePool();
if (pool)
{
const float off = 0.5f;
dd->begin(DU_DRAW_POINTS, 4.0f);
for (int i = 0; i < pool->getHashSize(); ++i)
{
for (unsigned short j = pool->getFirst(i); j != DT_NULL_IDX; j = pool->getNext(j))
{
const dtNode* node = pool->getNodeAtIdx(j+1);
if (!node) continue;
dd->vertex(node->pos[0],node->pos[1]+off,node->pos[2], duRGBA(255,192,0,255));
}
}
dd->end();
dd->begin(DU_DRAW_LINES, 2.0f);
for (int i = 0; i < pool->getHashSize(); ++i)
{
for (unsigned short j = pool->getFirst(i); j != DT_NULL_IDX; j = pool->getNext(j))
{
const dtNode* node = pool->getNodeAtIdx(j+1);
if (!node) continue;
if (!node->pidx) continue;
const dtNode* parent = pool->getNodeAtIdx(node->pidx);
if (!parent) continue;
dd->vertex(node->pos[0],node->pos[1]+off,node->pos[2], duRGBA(255,192,0,128));
dd->vertex(parent->pos[0],parent->pos[1]+off,parent->pos[2], duRGBA(255,192,0,128));
}
}
dd->end();
}
}
static void drawMeshTileBVTree(duDebugDraw* dd, const dtMeshTile* tile)
{
@ -291,28 +329,6 @@ void duDebugDrawNavMeshBVTree(duDebugDraw* dd, const dtNavMesh& mesh)
}
}
/*
static void calcRect(const float* va, const float* vb,
float* bmin, float* bmax,
int side, float padx, float pady)
{
if (side == 0 || side == 4)
{
bmin[0] = dtMin(va[2],vb[2]) + padx;
bmin[1] = dtMin(va[1],vb[1]) - pady;
bmax[0] = dtMax(va[2],vb[2]) - padx;
bmax[1] = dtMax(va[1],vb[1]) + pady;
}
else if (side == 2 || side == 6)
{
bmin[0] = dtMin(va[0],vb[0]) + padx;
bmin[1] = dtMin(va[1],vb[1]) - pady;
bmax[0] = dtMax(va[0],vb[0]) - padx;
bmax[1] = dtMax(va[1],vb[1]) + pady;
}
}
*/
static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
{
// Draw portals
@ -358,24 +374,6 @@ static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
dd->vertex(x,vb[1]-pady,vb[2], col);
dd->vertex(x,va[1]-pady,va[2], col);
/* const float zmin = dtMin(va[2], vb[2]) - padx;
const float zmax = dtMax(va[2], vb[2]) + padx;
const float ymin = dtMin(va[1], vb[1]) - pady;
const float ymax = dtMax(va[1], vb[1]) + pady;
const float x = va[0] + ((side == 0) ? -0.02f : 0.02f);
dd->vertex(x,ymin,zmin, col);
dd->vertex(x,ymin,zmax, col);
dd->vertex(x,ymin,zmax, col);
dd->vertex(x,ymax,zmax, col);
dd->vertex(x,ymax,zmax, col);
dd->vertex(x,ymax,zmin, col);
dd->vertex(x,ymax,zmin, col);
dd->vertex(x,ymin,zmin, col);*/
}
else if (side == 2 || side == 6)
{
@ -394,25 +392,6 @@ static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
dd->vertex(vb[0],vb[1]-pady,z, col);
dd->vertex(va[0],va[1]-pady,z, col);
/* const float xmin = dtMin(va[0], vb[0]) - padx;
const float xmax = dtMax(va[0], vb[0]) + padx;
const float ymin = dtMin(va[1], vb[1]) - pady;
const float ymax = dtMax(va[1], vb[1]) + pady;
const float z = va[2] + ((side == 2) ? -0.02f : 0.02f);
dd->vertex(xmin,ymin,z, col);
dd->vertex(xmax,ymin,z, col);
dd->vertex(xmax,ymin,z, col);
dd->vertex(xmax,ymax,z, col);
dd->vertex(xmax,ymax,z, col);
dd->vertex(xmin,ymax,z, col);
dd->vertex(xmin,ymax,z, col);
dd->vertex(xmin,ymin,z, col);*/
}
}

View File

@ -19,14 +19,81 @@
#ifndef DETOURNAVMESHQUERY_H
#define DETOURNAVMESHQUERY_H
#include "DetourAlloc.h"
#include "DetourNavMesh.h"
struct dtQueryFilter
// Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter.
// On certain platforms indirect or virtual function call is expensive. The default
// setting is to use non-virtual functions, the actualy implementations of the functions
// are declared as inline for maximum speed.
//#define DT_VIRTUAL_QUERYFILTER 1
// Class for polygon filtering and cost calculation during query operations.
// - It is possible to derive a custom query filter from dtQueryFilter by overriding
// the virtual functions passFilter() and getCost().
// - Both functions should be as fast as possible. Use cached local copy of data
// instead of accessing your own objects where possible.
// - You do not need to adhere to the flags and cost logic provided by the default
// implementation.
// - In order for the A* to work properly, the cost should be proportional to
// the travel distance. Using cost modifier less than 1.0 is likely to lead
// to problems during pathfinding.
class dtQueryFilter
{
dtQueryFilter() : includeFlags(0xffff), excludeFlags(0) {}
unsigned short includeFlags; // If any of the flags are set, the poly is included.
unsigned short excludeFlags; // If any of the flags are set, the poly is excluded.
float m_areaCost[DT_MAX_AREAS]; // Array storing cost per area type, used by default implementation.
unsigned short m_includeFlags; // Include poly flags, used by default implementation.
unsigned short m_excludeFlags; // Exclude poly flags, used by default implementation.
public:
dtQueryFilter();
// Returns true if the polygon is can visited.
// Params:
// ref - (in) reference to the polygon test.
// tile - (in) pointer to the tile of the polygon test.
// poly - (in) pointer to the polygon test.
#ifdef DT_VIRTUAL_QUERYFILTER
virtual bool passFilter(const dtPolyRef ref,
const dtMeshTile* tile,
const dtPoly* poly) const;
#else
bool passFilter(const dtPolyRef ref,
const dtMeshTile* tile,
const dtPoly* poly) const;
#endif
// Returns cost to travel from 'pa' to 'pb'.'
// The segment is fully contained inside 'cur'.
// 'pa' lies on the edge between 'prev' and 'cur',
// 'pb' lies on the edge between 'cur' and 'next'.
// Params:
// pa - (in) segment start position.
// pb - (in) segment end position.
// prevRef, prevTile, prevPoly - (in) data describing the previous polygon, can be null.
// curRef, curTile, curPoly - (in) data describing the current polygon.
// nextRef, nextTile, nextPoly - (in) data describing the next polygon, can be null.
#ifdef DT_VIRTUAL_QUERYFILTER
virtual float getCost(const float* pa, const float* pb,
const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly,
const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly,
const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const;
#else
float getCost(const float* pa, const float* pb,
const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly,
const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly,
const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const;
#endif
// Getters and setters for the default implementation data.
inline float getAreaCost(const int i) const { return m_areaCost[i]; }
inline void setAreaCost(const int i, const float cost) { m_areaCost[i] = cost; }
inline unsigned short getIncludeFlags() const { return m_includeFlags; }
inline void setIncludeFlags(const unsigned short flags) { m_includeFlags = flags; }
inline unsigned short getExcludeFlags() const { return m_excludeFlags; }
inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; }
};
enum dtQueryState
@ -47,18 +114,18 @@ public:
// nav - (in) pointer to navigation mesh data.
// maxNodes - (in) Maximum number of search nodes to use (max 65536).
// Returns: True if succeed, else false.
bool init(dtNavMesh* nav, const int maxNodes);
bool init(class dtNavMesh* nav, const int maxNodes);
// Sets the pathfinding cost of the specified area.
// Params:
// area - (in) area ID (0-63).
// cost - (int) travel cost of the area.
void setAreaCost(const int area, float cost);
// void setAreaCost(const int area, float cost);
// Returns the pathfinding cost of the specified area.
// Params:
// area - (in) area ID (0-63).
float getAreaCost(const int area) const;
// float getAreaCost(const int area) const;
// Finds the nearest navigation polygon around the center location.
// Params:
@ -101,8 +168,10 @@ public:
dtPolyRef* path, const int maxPathSize) const;
// Intializes sliced path find query.
// Note: calling any other dtNavMeshQuery method before calling findPathEnd()
// Note 1: calling any other dtNavMeshQuery method before calling findPathEnd()
// may results in corrupted data!
// Note 2: The pointer to filter is store, and used in subsequent
// calls to updateSlicedFindPath().
// Params:
// startRef - (in) ref to path start polygon.
// endRef - (in) ref to path end polygon.
@ -285,6 +354,8 @@ public:
// Returns true if poly reference ins in closed list.
bool isInClosedList(dtPolyRef ref) const;
class dtNodePool* getNodePool() const { return m_nodePool; }
private:
// Returns neighbour tile based on side.
@ -312,7 +383,7 @@ private:
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
float* mid) const;
dtNavMesh* m_nav; // Pointer to navmesh data.
class dtNavMesh* m_nav; // Pointer to navmesh data.
struct dtQueryData
{
@ -321,12 +392,10 @@ private:
float lastBestNodeCost;
dtPolyRef startRef, endRef;
float startPos[3], endPos[3];
dtQueryFilter filter;
const dtQueryFilter* filter;
};
dtQueryData m_query; // Sliced query state.
float m_areaCost[DT_MAX_AREAS]; // Cost per area.
class dtNodePool* m_tinyNodePool; // Pointer to small node pool.
class dtNodePool* m_nodePool; // Pointer to node pool.
class dtNodeQueue* m_openList; // Pointer to open list queue.

View File

@ -25,8 +25,11 @@ enum dtNodeFlags
DT_NODE_CLOSED = 0x02,
};
static const unsigned short DT_NULL_IDX = 0xffff;
struct dtNode
{
float pos[3];
float cost;
float total;
unsigned int id;
@ -55,6 +58,12 @@ public:
if (!idx) return 0;
return &m_nodes[idx-1];
}
inline const dtNode* getNodeAtIdx(unsigned int idx) const
{
if (!idx) return 0;
return &m_nodes[idx-1];
}
inline int getMemUsed() const
{
@ -66,6 +75,10 @@ public:
inline int getMaxNodes() const { return m_maxNodes; }
inline int getHashSize() const { return m_hashSize; }
inline unsigned short getFirst(int bucket) const { return m_first[bucket]; }
inline unsigned short getNext(int i) const { return m_next[i]; }
private:
inline unsigned int hashint(unsigned int a) const
{

View File

@ -19,8 +19,8 @@
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdio.h>
#include "DetourNavMeshQuery.h"
#include "DetourNavMesh.h"
#include "DetourNode.h"
#include "DetourCommon.h"
#include "DetourAlloc.h"
@ -28,8 +28,48 @@
#include <new>
// Search heuristic scale.
static const float H_SCALE = 0.999f;
dtQueryFilter::dtQueryFilter() :
m_includeFlags(0xffff),
m_excludeFlags(0)
{
for (int i = 0; i < DT_MAX_AREAS; ++i)
m_areaCost[i] = 1.0f;
}
#ifdef DT_VIRTUAL_QUERYFILTER
bool dtQueryFilter::passFilter(const dtPolyRef /*ref*/,
const dtMeshTile* /*tile*/,
const dtPoly* poly) const
{
return (poly->flags & includeFlags) != 0 && (poly->flags & excludeFlags) == 0;
}
float dtQueryFilter::getCost(const float* pa, const float* pb,
const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/,
const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly,
const dtPolyRef /*nextRef*/, const dtMeshTile* /*nextTile*/, const dtPoly* /*nextPoly*/) const
{
return dtVdist(pa, pb) * areaCost[curPoly->area];
}
#else
inline bool dtQueryFilter::passFilter(const dtPolyRef /*ref*/,
const dtMeshTile* /*tile*/,
const dtPoly* poly) const
{
return (poly->flags & m_includeFlags) != 0 && (poly->flags & m_excludeFlags) == 0;
}
inline float dtQueryFilter::getCost(const float* pa, const float* pb,
const dtPolyRef /*prevRef*/, const dtMeshTile* /*prevTile*/, const dtPoly* /*prevPoly*/,
const dtPolyRef /*curRef*/, const dtMeshTile* /*curTile*/, const dtPoly* curPoly,
const dtPolyRef /*nextRef*/, const dtMeshTile* /*nextTile*/, const dtPoly* /*nextPoly*/) const
{
return dtVdist(pa, pb) * m_areaCost[curPoly->area];
}
#endif
static const float H_SCALE = 0.999f; // Search heuristic scale.
inline int opposite(int side) { return (side+4) & 0x7; }
@ -43,11 +83,6 @@ inline bool overlapBoxes(const float* amin, const float* amax,
return overlap;
}
inline bool passFilter(const dtQueryFilter* filter, unsigned short flags)
{
return (flags & filter->includeFlags) != 0 && (flags & filter->excludeFlags) == 0;
}
dtNavMeshQuery* dtAllocNavMeshQuery()
{
return new(dtAlloc(sizeof(dtNavMeshQuery), DT_ALLOC_PERM)) dtNavMeshQuery;
@ -66,8 +101,6 @@ dtNavMeshQuery::dtNavMeshQuery() :
m_nodePool(0),
m_openList(0)
{
for (int i = 0; i < DT_MAX_AREAS; ++i)
m_areaCost[i] = 1.0f;
memset(&m_query, 0, sizeof(dtQueryData));
}
@ -276,6 +309,7 @@ bool dtNavMeshQuery::getPolyHeight(dtPolyRef ref, const float* pos, float* heigh
return false;
}
/*
void dtNavMeshQuery::setAreaCost(const int area, float cost)
{
if (area >= 0 && area < DT_MAX_AREAS)
@ -288,6 +322,7 @@ float dtNavMeshQuery::getAreaCost(const int area) const
return m_areaCost[area];
return -1;
}
*/
dtPolyRef dtNavMeshQuery::findNearestPoly(const float* center, const float* extents,
const dtQueryFilter* filter, float* nearestPt) const
@ -398,10 +433,11 @@ int dtNavMeshQuery::queryPolygonsInTile(const dtMeshTile* tile, const float* qmi
if (isLeafNode && overlap)
{
if (passFilter(filter, tile->polys[node->i].flags))
dtPolyRef ref = base | (dtPolyRef)node->i;
if (filter->passFilter(ref, tile, &tile->polys[node->i]))
{
if (n < maxPolys)
polys[n++] = base | (dtPolyRef)node->i;
polys[n++] = ref;
}
}
@ -436,10 +472,11 @@ int dtNavMeshQuery::queryPolygonsInTile(const dtMeshTile* tile, const float* qmi
}
if (overlapBoxes(qmin,qmax, bmin,bmax))
{
if (passFilter(filter, p->flags))
const dtPolyRef ref = base | (dtPolyRef)i;
if (filter->passFilter(ref, tile, p))
{
if (n < maxPolys)
polys[n++] = base | (dtPolyRef)i;
polys[n++] = ref;
}
}
}
@ -505,6 +542,7 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
m_openList->clear();
dtNode* startNode = m_nodePool->getNode(startRef);
dtVcopy(startNode->pos, startPos);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = dtVdist(startPos, endPos) * H_SCALE;
@ -517,8 +555,8 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
while (!m_openList->empty())
{
dtNode* bestNode = m_openList->pop();
// Remove node from open list and put it in closed list.
dtNode* bestNode = m_openList->pop();
bestNode->flags &= ~DT_NODE_OPEN;
bestNode->flags |= DT_NODE_CLOSED;
@ -529,8 +567,6 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
break;
}
float previousEdgeMidPoint[3];
// Get current poly and tile.
// The API input has been cheked already, skip checking internal data.
const dtPolyRef bestRef = bestNode->id;
@ -545,15 +581,7 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
if (bestNode->pidx)
parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id;
if (parentRef)
{
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
getEdgeMidPoint(parentRef, parentPoly, parentTile,
bestRef, bestPoly, bestTile, previousEdgeMidPoint);
}
else
{
dtVcopy(previousEdgeMidPoint, startPos);
}
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
{
@ -569,74 +597,85 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
const dtPoly* neighbourPoly = 0;
m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly);
if (!passFilter(filter, neighbourPoly->flags))
if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
dtNode* neighbourNode = m_nodePool->getNode(neighbourRef);
if (!neighbourNode)
continue;
dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(bestNode);
newNode.id = neighbourRef;
// Calculate cost.
float edgeMidPoint[3];
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile, edgeMidPoint);
// If the node is visited the first time, calculate node position.
if (neighbourNode->flags == 0)
{
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile,
neighbourNode->pos);
}
// Calculate cost and heuristic.
float cost = 0;
float heuristic = 0;
// Special case for last node.
float h = 0;
if (neighbourRef == endRef)
{
// Cost
newNode.cost = bestNode->cost +
dtVdist(previousEdgeMidPoint,edgeMidPoint) * m_areaCost[bestPoly->area] +
dtVdist(edgeMidPoint, endPos) * m_areaCost[neighbourPoly->area];
// Heuristic
h = 0;
const float curCost = filter->getCost(bestNode->pos, neighbourNode->pos,
parentRef, parentTile, parentPoly,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly);
const float endCost = filter->getCost(neighbourNode->pos, endPos,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly,
0, 0, 0);
cost = bestNode->cost + curCost + endCost;
heuristic = 0;
}
else
{
// Cost
newNode.cost = bestNode->cost +
dtVdist(previousEdgeMidPoint,edgeMidPoint) * m_areaCost[bestPoly->area];
// Heuristic
h = dtVdist(edgeMidPoint,endPos)*H_SCALE;
const float curCost = filter->getCost(bestNode->pos, neighbourNode->pos,
parentRef, parentTile, parentPoly,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly);
cost = bestNode->cost + curCost;
heuristic = dtVdist(neighbourNode->pos, endPos)*H_SCALE;
}
newNode.total = newNode.cost + h;
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
continue;
const float total = cost + heuristic;
// The node is already in open list and the new result is worse, skip.
if ((actualNode->flags & DT_NODE_OPEN) && newNode.total >= actualNode->total)
if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total)
continue;
// The node is already visited and process, and the new result is worse, skip.
if ((actualNode->flags & DT_NODE_CLOSED) && newNode.total >= actualNode->total)
if ((neighbourNode->flags & DT_NODE_CLOSED) && total >= neighbourNode->total)
continue;
// Add or update the node.
actualNode->flags &= ~DT_NODE_CLOSED;
actualNode->pidx = newNode.pidx;
actualNode->cost = newNode.cost;
actualNode->total = newNode.total;
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->id = neighbourRef;
neighbourNode->flags &= ~DT_NODE_CLOSED;
neighbourNode->cost = cost;
neighbourNode->total = total;
// Update nearest node to target so far.
if (h < lastBestNodeCost)
{
lastBestNodeCost = h;
lastBestNode = actualNode;
}
if (actualNode->flags & DT_NODE_OPEN)
if (neighbourNode->flags & DT_NODE_OPEN)
{
// Already in open, update node location.
m_openList->modify(actualNode);
m_openList->modify(neighbourNode);
}
else
{
// Put the node in open list.
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
neighbourNode->flags |= DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
// Update nearest node to target so far.
if (heuristic < lastBestNodeCost)
{
lastBestNodeCost = heuristic;
lastBestNode = neighbourNode;
}
}
}
@ -666,8 +705,6 @@ int dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef,
return n;
}
dtQueryState dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef,
const float* startPos, const float* endPos,
const dtQueryFilter* filter)
@ -683,7 +720,7 @@ dtQueryState dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef en
m_query.endRef = endRef;
dtVcopy(m_query.startPos, startPos);
dtVcopy(m_query.endPos, endPos);
m_query.filter = *filter;
m_query.filter = filter;
if (!startRef || !endRef)
return DT_QUERY_FAILED;
@ -702,6 +739,7 @@ dtQueryState dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef en
m_openList->clear();
dtNode* startNode = m_nodePool->getNode(startRef);
dtVcopy(startNode->pos, startPos);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = dtVdist(startPos, endPos) * H_SCALE;
@ -733,8 +771,8 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
{
iter++;
dtNode* bestNode = m_openList->pop();
// Remove node from open list and put it in closed list.
dtNode* bestNode = m_openList->pop();
bestNode->flags &= ~DT_NODE_OPEN;
bestNode->flags |= DT_NODE_CLOSED;
@ -746,9 +784,8 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
return m_query.state;
}
float previousEdgeMidPoint[3];
// Get current poly and tile.
// The API input has been cheked already, skip checking internal data.
const dtPolyRef bestRef = bestNode->id;
const dtMeshTile* bestTile = 0;
const dtPoly* bestPoly = 0;
@ -763,12 +800,8 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
dtPolyRef parentRef = 0;
const dtMeshTile* parentTile = 0;
const dtPoly* parentPoly = 0;
dtNode* parentNode = 0;
if (bestNode->pidx)
{
parentNode = m_nodePool->getNodeAtIdx(bestNode->pidx);
parentRef = parentNode->id;
}
parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id;
if (parentRef)
{
if (!m_nav->getTileAndPolyByRef(parentRef, &parentTile, &parentPoly))
@ -777,12 +810,6 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
m_query.state = DT_QUERY_FAILED;
return m_query.state;
}
getEdgeMidPoint(parentRef, parentPoly, parentTile,
bestRef, bestPoly, bestTile, previousEdgeMidPoint);
}
else
{
dtVcopy(previousEdgeMidPoint, m_query.startPos);
}
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
@ -799,74 +826,85 @@ dtQueryState dtNavMeshQuery::updateSlicedFindPath(const int maxIter)
const dtPoly* neighbourPoly = 0;
m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly);
if (!passFilter(&m_query.filter, neighbourPoly->flags))
if (!m_query.filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(bestNode);
newNode.id = neighbourRef;
dtNode* neighbourNode = m_nodePool->getNode(neighbourRef);
if (!neighbourNode)
continue;
// Calculate cost.
float edgeMidPoint[3];
// If the node is visited the first time, calculate node position.
if (neighbourNode->flags == 0)
{
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile,
neighbourNode->pos);
}
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile, edgeMidPoint);
// Calculate cost and heuristic.
float cost = 0;
float heuristic = 0;
// Special case for last node.
float h = 0;
if (neighbourRef == m_query.endRef)
{
// Cost
newNode.cost = bestNode->cost +
dtVdist(previousEdgeMidPoint,edgeMidPoint) * m_areaCost[bestPoly->area] +
dtVdist(edgeMidPoint, m_query.endPos) * m_areaCost[neighbourPoly->area];
// Heuristic
h = 0;
const float curCost = m_query.filter->getCost(bestNode->pos, neighbourNode->pos,
parentRef, parentTile, parentPoly,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly);
const float endCost = m_query.filter->getCost(neighbourNode->pos, m_query.endPos,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly,
0, 0, 0);
cost = bestNode->cost + curCost + endCost;
heuristic = 0;
}
else
{
// Cost
newNode.cost = bestNode->cost +
dtVdist(previousEdgeMidPoint,edgeMidPoint) * m_areaCost[bestPoly->area];
// Heuristic
h = dtVdist(edgeMidPoint, m_query.endPos)*H_SCALE;
const float curCost = m_query.filter->getCost(bestNode->pos, neighbourNode->pos,
parentRef, parentTile, parentPoly,
bestRef, bestTile, bestPoly,
neighbourRef, neighbourTile, neighbourPoly);
cost = bestNode->cost + curCost;
heuristic = dtVdist(neighbourNode->pos, m_query.endPos)*H_SCALE;
}
newNode.total = newNode.cost + h;
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
continue;
const float total = cost + heuristic;
// The node is already in open list and the new result is worse, skip.
if ((actualNode->flags & DT_NODE_OPEN) && newNode.total >= actualNode->total)
if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total)
continue;
// The node is already visited and process, and the new result is worse, skip.
if ((actualNode->flags & DT_NODE_CLOSED) && newNode.total >= actualNode->total)
if ((neighbourNode->flags & DT_NODE_CLOSED) && total >= neighbourNode->total)
continue;
// Add or update the node.
actualNode->flags &= ~DT_NODE_CLOSED;
actualNode->pidx = newNode.pidx;
actualNode->cost = newNode.cost;
actualNode->total = newNode.total;
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->id = neighbourRef;
neighbourNode->flags &= ~DT_NODE_CLOSED;
neighbourNode->cost = cost;
neighbourNode->total = total;
// Update nearest node to target so far.
if (h < m_query.lastBestNodeCost)
{
m_query.lastBestNodeCost = h;
m_query.lastBestNode = actualNode;
}
if (actualNode->flags & DT_NODE_OPEN)
if (neighbourNode->flags & DT_NODE_OPEN)
{
// Already in open, update node location.
m_openList->modify(actualNode);
m_openList->modify(neighbourNode);
}
else
{
// Put the node in open list.
actualNode->flags |= DT_NODE_OPEN;
m_openList->push(actualNode);
neighbourNode->flags |= DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
// Update nearest node to target so far.
if (heuristic < m_query.lastBestNodeCost)
{
m_query.lastBestNodeCost = heuristic;
m_query.lastBestNode = neighbourNode;
}
}
}
@ -1221,18 +1259,29 @@ int dtNavMeshQuery::moveAlongSurface(dtPolyRef startRef, const float* startPos,
const dtLink* link = &curTile->links[k];
if (link->edge == j)
{
if (link->ref != 0 && passFilter(filter, m_nav->getPolyFlags(link->ref)))
if (link->ref != 0)
{
if (nneis < MAX_NEIS)
neis[nneis++] = link->ref;
const dtMeshTile* neiTile = 0;
const dtPoly* neiPoly = 0;
m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly);
if (filter->passFilter(link->ref, neiTile, neiPoly))
{
if (nneis < MAX_NEIS)
neis[nneis++] = link->ref;
}
}
}
}
}
else if (curPoly->neis[j] && passFilter(filter, curTile->polys[curPoly->neis[j]-1].flags))
else if (curPoly->neis[j])
{
// Internal edge, encode id.
neis[nneis++] = m_nav->getPolyRefBase(curTile) | (unsigned int)(curPoly->neis[j]-1);
const unsigned int idx = (unsigned int)(curPoly->neis[j]-1);
const dtPolyRef ref = m_nav->getPolyRefBase(curTile) | idx;
if (filter->passFilter(ref, curTile, &curTile->polys[idx]))
{
// Internal edge, encode id.
neis[nneis++] = ref;
}
}
if (!nneis)
@ -1512,7 +1561,7 @@ int dtNavMeshQuery::raycast(dtPolyRef centerRef, const float* startPos, const fl
continue;
// Skip links based on filter.
if (!passFilter(filter, nextPoly->flags))
if (!filter->passFilter(link->ref, nextTile, nextPoly))
continue;
// If the link is internal, just return the ref.
@ -1615,6 +1664,7 @@ int dtNavMeshQuery::findPolysAroundCircle(dtPolyRef centerRef, const float* cent
m_openList->clear();
dtNode* startNode = m_nodePool->getNode(centerRef);
dtVcopy(startNode->pos, centerPos);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = 0;
@ -1639,8 +1689,8 @@ int dtNavMeshQuery::findPolysAroundCircle(dtPolyRef centerRef, const float* cent
while (!m_openList->empty())
{
dtNode* bestNode = m_openList->pop();
float previousEdgeMidPoint[3];
bestNode->flags &= ~DT_NODE_OPEN;
bestNode->flags |= DT_NODE_CLOSED;
// Get poly and tile.
// The API input has been cheked already, skip checking internal data.
@ -1656,16 +1706,7 @@ int dtNavMeshQuery::findPolysAroundCircle(dtPolyRef centerRef, const float* cent
if (bestNode->pidx)
parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id;
if (parentRef)
{
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
getEdgeMidPoint(parentRef, parentPoly, parentTile,
bestRef, bestPoly, bestTile, previousEdgeMidPoint);
}
else
{
dtVcopy(previousEdgeMidPoint, centerPos);
}
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
{
@ -1681,7 +1722,7 @@ int dtNavMeshQuery::findPolysAroundCircle(dtPolyRef centerRef, const float* cent
m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly);
// Do not advance if the polygon is excluded by the filter.
if (!passFilter(filter, neighbourPoly->flags))
if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
// Find edge and calc distance to the edge.
@ -1695,46 +1736,46 @@ int dtNavMeshQuery::findPolysAroundCircle(dtPolyRef centerRef, const float* cent
if (distSqr > radiusSqr)
continue;
dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(bestNode);
newNode.id = neighbourRef;
// Cost
float edgeMidPoint[3];
dtVlerp(edgeMidPoint, va, vb, 0.5f);
newNode.total = bestNode->total + dtVdist(previousEdgeMidPoint, edgeMidPoint);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
dtNode* neighbourNode = m_nodePool->getNode(neighbourRef);
if (!neighbourNode)
continue;
if (neighbourNode->flags & DT_NODE_CLOSED)
continue;
if (!((actualNode->flags & DT_NODE_OPEN) && newNode.total > actualNode->total) &&
!((actualNode->flags & DT_NODE_CLOSED) && newNode.total > actualNode->total))
// Cost
if (neighbourNode->flags == 0)
dtVlerp(neighbourNode->pos, va, vb, 0.5f);
const float total = bestNode->total + dtVdist(bestNode->pos, neighbourNode->pos);
// The node is already in open list and the new result is worse, skip.
if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total)
continue;
neighbourNode->id = neighbourRef;
neighbourNode->flags &= ~DT_NODE_CLOSED;
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->total = total;
if (neighbourNode->flags & DT_NODE_OPEN)
{
actualNode->flags &= ~DT_NODE_CLOSED;
actualNode->pidx = newNode.pidx;
actualNode->total = newNode.total;
if (actualNode->flags & DT_NODE_OPEN)
m_openList->modify(neighbourNode);
}
else
{
if (n < maxResult)
{
m_openList->modify(actualNode);
}
else
{
if (n < maxResult)
{
if (resultRef)
resultRef[n] = actualNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(actualNode->pidx)->id;
if (resultCost)
resultCost[n] = actualNode->total;
++n;
}
actualNode->flags = DT_NODE_OPEN;
m_openList->push(actualNode);
if (resultRef)
resultRef[n] = neighbourNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(neighbourNode->pidx)->id;
if (resultCost)
resultCost[n] = neighbourNode->total;
++n;
}
neighbourNode->flags = DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
}
}
@ -1758,7 +1799,13 @@ int dtNavMeshQuery::findPolysAroundShape(dtPolyRef centerRef, const float* verts
m_nodePool->clear();
m_openList->clear();
float centerPos[3] = {0,0,0};
for (int i = 0; i < nverts; ++i)
dtVadd(centerPos,centerPos,&verts[i*3]);
dtVscale(centerPos,centerPos,1.0f/nverts);
dtNode* startNode = m_nodePool->getNode(centerRef);
dtVcopy(startNode->pos, centerPos);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = 0;
@ -1778,16 +1825,11 @@ int dtNavMeshQuery::findPolysAroundShape(dtPolyRef centerRef, const float* verts
++n;
}
float centerPos[3] = {0,0,0};
for (int i = 0; i < nverts; ++i)
dtVadd(centerPos,centerPos,&verts[i*3]);
dtVscale(centerPos,centerPos,1.0f/nverts);
while (!m_openList->empty())
{
dtNode* bestNode = m_openList->pop();
float previousEdgeMidPoint[3];
bestNode->flags &= ~DT_NODE_OPEN;
bestNode->flags |= DT_NODE_CLOSED;
// Get poly and tile.
// The API input has been cheked already, skip checking internal data.
@ -1803,15 +1845,7 @@ int dtNavMeshQuery::findPolysAroundShape(dtPolyRef centerRef, const float* verts
if (bestNode->pidx)
parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id;
if (parentRef)
{
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
getEdgeMidPoint(parentRef, parentPoly, parentTile,
bestRef, bestPoly, bestTile, previousEdgeMidPoint);
}
else
{
dtVcopy(previousEdgeMidPoint, centerPos);
}
for (unsigned int i = bestPoly->firstLink; i != DT_NULL_LINK; i = bestTile->links[i].next)
{
@ -1827,7 +1861,7 @@ int dtNavMeshQuery::findPolysAroundShape(dtPolyRef centerRef, const float* verts
m_nav->getTileAndPolyByRefUnsafe(neighbourRef, &neighbourTile, &neighbourPoly);
// Do not advance if the polygon is excluded by the filter.
if (!passFilter(filter, neighbourPoly->flags))
if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
// Find edge and calc distance to the edge.
@ -1843,46 +1877,46 @@ int dtNavMeshQuery::findPolysAroundShape(dtPolyRef centerRef, const float* verts
if (tmin > 1.0f || tmax < 0.0f)
continue;
dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(bestNode);
newNode.id = neighbourRef;
// Cost
float edgeMidPoint[3];
dtVlerp(edgeMidPoint, va, vb, 0.5f);
newNode.total = bestNode->total + dtVdist(previousEdgeMidPoint, edgeMidPoint);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
dtNode* neighbourNode = m_nodePool->getNode(neighbourRef);
if (!neighbourNode)
continue;
if (!((actualNode->flags & DT_NODE_OPEN) && newNode.total > actualNode->total) &&
!((actualNode->flags & DT_NODE_CLOSED) && newNode.total > actualNode->total))
if (neighbourNode->flags & DT_NODE_CLOSED)
continue;
// Cost
if (neighbourNode->flags == 0)
dtVlerp(neighbourNode->pos, va, vb, 0.5f);
const float total = bestNode->total + dtVdist(bestNode->pos, neighbourNode->pos);
// The node is already in open list and the new result is worse, skip.
if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total)
continue;
neighbourNode->id = neighbourRef;
neighbourNode->flags &= ~DT_NODE_CLOSED;
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->total = total;
if (neighbourNode->flags & DT_NODE_OPEN)
{
actualNode->flags &= ~DT_NODE_CLOSED;
actualNode->pidx = newNode.pidx;
actualNode->total = newNode.total;
if (actualNode->flags & DT_NODE_OPEN)
m_openList->modify(neighbourNode);
}
else
{
if (n < maxResult)
{
m_openList->modify(actualNode);
}
else
{
if (n < maxResult)
{
if (resultRef)
resultRef[n] = actualNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(actualNode->pidx)->id;
if (resultCost)
resultCost[n] = actualNode->total;
++n;
}
actualNode->flags = DT_NODE_OPEN;
m_openList->push(actualNode);
if (resultRef)
resultRef[n] = neighbourNode->id;
if (resultParent)
resultParent[n] = m_nodePool->getNodeAtIdx(neighbourNode->pidx)->id;
if (resultCost)
resultCost[n] = neighbourNode->total;
++n;
}
neighbourNode->flags = DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
}
}
@ -1969,7 +2003,7 @@ int dtNavMeshQuery::findLocalNeighbourhood(dtPolyRef centerRef, const float* cen
continue;
// Do not advance if the polygon is excluded by the filter.
if (!passFilter(filter, neighbourPoly->flags))
if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
// Find edge and calc distance to the edge.
@ -2104,17 +2138,26 @@ int dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filt
const dtLink* link = &tile->links[k];
if (link->edge == j)
{
if (link->ref != 0 && passFilter(filter, m_nav->getPolyFlags(link->ref)))
if (link->ref != 0)
{
insertInterval(ints, nints, MAX_INTERVAL, link->bmin, link->bmax);
const dtMeshTile* neiTile = 0;
const dtPoly* neiPoly = 0;
m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly);
if (filter->passFilter(link->ref, neiTile, neiPoly))
{
insertInterval(ints, nints, MAX_INTERVAL, link->bmin, link->bmax);
}
}
}
}
}
else if (poly->neis[j] && passFilter(filter, tile->polys[poly->neis[j]-1].flags))
else if (poly->neis[j])
{
// Internal edge
continue;
const unsigned int idx = (unsigned int)(poly->neis[j]-1);
const dtPolyRef ref = m_nav->getPolyRefBase(tile) | idx;
if (filter->passFilter(ref, tile, &tile->polys[idx]))
continue;
}
// Add sentinels
@ -2173,6 +2216,7 @@ float dtNavMeshQuery::findDistanceToWall(dtPolyRef centerRef, const float* cente
m_openList->clear();
dtNode* startNode = m_nodePool->getNode(centerRef);
dtVcopy(startNode->pos, centerPos);
startNode->pidx = 0;
startNode->cost = 0;
startNode->total = 0;
@ -2185,8 +2229,8 @@ float dtNavMeshQuery::findDistanceToWall(dtPolyRef centerRef, const float* cente
while (!m_openList->empty())
{
dtNode* bestNode = m_openList->pop();
float previousEdgeMidPoint[3];
bestNode->flags &= ~DT_NODE_OPEN;
bestNode->flags |= DT_NODE_CLOSED;
// Get poly and tile.
// The API input has been cheked already, skip checking internal data.
@ -2202,15 +2246,7 @@ float dtNavMeshQuery::findDistanceToWall(dtPolyRef centerRef, const float* cente
if (bestNode->pidx)
parentRef = m_nodePool->getNodeAtIdx(bestNode->pidx)->id;
if (parentRef)
{
m_nav->getTileAndPolyByRefUnsafe(parentRef, &parentTile, &parentPoly);
getEdgeMidPoint(parentRef, parentPoly, parentTile,
bestRef, bestPoly, bestTile, previousEdgeMidPoint);
}
else
{
dtVcopy(previousEdgeMidPoint, centerPos);
}
// Hit test walls.
for (int i = 0, j = (int)bestPoly->vertCount-1; i < (int)bestPoly->vertCount; j = i++)
@ -2225,17 +2261,26 @@ float dtNavMeshQuery::findDistanceToWall(dtPolyRef centerRef, const float* cente
const dtLink* link = &bestTile->links[k];
if (link->edge == j)
{
if (link->ref != 0 && passFilter(filter, m_nav->getPolyFlags(link->ref)))
solid = false;
if (link->ref != 0)
{
const dtMeshTile* neiTile = 0;
const dtPoly* neiPoly = 0;
m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly);
if (filter->passFilter(link->ref, neiTile, neiPoly))
solid = false;
}
break;
}
}
if (!solid) continue;
}
else if (bestPoly->neis[j] && passFilter(filter, bestTile->polys[bestPoly->neis[j]-1].flags))
else if (bestPoly->neis[j])
{
// Internal edge
continue;
const unsigned int idx = (unsigned int)(bestPoly->neis[j]-1);
const dtPolyRef ref = m_nav->getPolyRefBase(bestTile) | idx;
if (filter->passFilter(ref, bestTile, &bestTile->polys[idx]))
continue;
}
// Calc distance to the edge.
@ -2283,40 +2328,42 @@ float dtNavMeshQuery::findDistanceToWall(dtPolyRef centerRef, const float* cente
if (distSqr > radiusSqr)
continue;
if (!passFilter(filter, neighbourPoly->flags))
if (!filter->passFilter(neighbourRef, neighbourTile, neighbourPoly))
continue;
dtNode* neighbourNode = m_nodePool->getNode(neighbourRef);
if (!neighbourNode)
continue;
dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(bestNode);
newNode.id = neighbourRef;
if (neighbourNode->flags & DT_NODE_CLOSED)
continue;
// Cost
float edgeMidPoint[3];
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile, edgeMidPoint);
if (neighbourNode->flags == 0)
{
getEdgeMidPoint(bestRef, bestPoly, bestTile,
neighbourRef, neighbourPoly, neighbourTile, neighbourNode->pos);
}
newNode.total = bestNode->total + dtVdist(previousEdgeMidPoint, edgeMidPoint);
const float total = bestNode->total + dtVdist(bestNode->pos, neighbourNode->pos);
dtNode* actualNode = m_nodePool->getNode(newNode.id);
if (!actualNode)
// The node is already in open list and the new result is worse, skip.
if ((neighbourNode->flags & DT_NODE_OPEN) && total >= neighbourNode->total)
continue;
if (!((actualNode->flags & DT_NODE_OPEN) && newNode.total > actualNode->total) &&
!((actualNode->flags & DT_NODE_CLOSED) && newNode.total > actualNode->total))
{
actualNode->flags &= ~DT_NODE_CLOSED;
actualNode->pidx = newNode.pidx;
actualNode->total = newNode.total;
neighbourNode->id = neighbourRef;
neighbourNode->flags &= ~DT_NODE_CLOSED;
neighbourNode->pidx = m_nodePool->getNodeIdx(bestNode);
neighbourNode->total = total;
if (actualNode->flags & DT_NODE_OPEN)
{
m_openList->modify(actualNode);
}
else
{
actualNode->flags = DT_NODE_OPEN;
m_openList->push(actualNode);
}
if (neighbourNode->flags & DT_NODE_OPEN)
{
m_openList->modify(neighbourNode);
}
else
{
neighbourNode->flags |= DT_NODE_OPEN;
m_openList->push(neighbourNode);
}
}
}

View File

@ -21,8 +21,6 @@
#include "DetourAssert.h"
#include <string.h>
static const unsigned short DT_NULL_IDX = 0xffff;
//////////////////////////////////////////////////////////////////////////////////////////
dtNodePool::dtNodePool(int maxNodes, int hashSize) :
m_nodes(0),

File diff suppressed because it is too large Load Diff

View File

@ -283,14 +283,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>42</integer>
<integer>38</integer>
<integer>17</integer>
<integer>11</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 440}, {264, 660}}</string>
<string>{{0, 0}, {264, 660}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -325,7 +325,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>Sample_SoloMeshSimple.cpp</string>
<string>DetourNavMeshQuery.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -333,11 +333,11 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>Sample_SoloMeshSimple.cpp</string>
<string>DetourNavMeshQuery.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6BAF45C2121D2F68008CFCDF</string>
<string>6B1C8DAF121E821F0048697F</string>
<key>history</key>
<array>
<string>6BBB4AA5115B4F3400CF791D</string>
@ -360,42 +360,22 @@
<string>6BAF3E781212869F008CFCDF</string>
<string>6BAF404F12140B4E008CFCDF</string>
<string>6BAF405112140B4E008CFCDF</string>
<string>6BAF409312142142008CFCDF</string>
<string>6BAF409512142142008CFCDF</string>
<string>6BAF40F412197F3D008CFCDF</string>
<string>6BAF419E12198419008CFCDF</string>
<string>6BAF4250121AD7D7008CFCDF</string>
<string>6BAF4267121AD99B008CFCDF</string>
<string>6BAF4269121AD99B008CFCDF</string>
<string>6BAF427E121ADD46008CFCDF</string>
<string>6BAF427F121ADD46008CFCDF</string>
<string>6BAF4280121ADD46008CFCDF</string>
<string>6BAF42A6121AEFD9008CFCDF</string>
<string>6BAF42E2121AF3B8008CFCDF</string>
<string>6BAF4321121AF998008CFCDF</string>
<string>6BAF4322121AF998008CFCDF</string>
<string>6BAF437D121C1F3D008CFCDF</string>
<string>6BAF43FB121C241D008CFCDF</string>
<string>6BAF43FE121C241D008CFCDF</string>
<string>6BAF43FF121C241D008CFCDF</string>
<string>6BAF4421121C25E3008CFCDF</string>
<string>6BAF4422121C25E3008CFCDF</string>
<string>6BAF4446121C40AC008CFCDF</string>
<string>6BAF446C121C4895008CFCDF</string>
<string>6BAF446E121C4895008CFCDF</string>
<string>6BAF44D9121C4DFC008CFCDF</string>
<string>6BAF44DE121C54D4008CFCDF</string>
<string>6BAF4520121D1723008CFCDF</string>
<string>6BAF4521121D1723008CFCDF</string>
<string>6BAF4522121D1723008CFCDF</string>
<string>6BAF4523121D1723008CFCDF</string>
<string>6BAF4524121D1723008CFCDF</string>
<string>6BAF4525121D1723008CFCDF</string>
<string>6BAF4527121D1723008CFCDF</string>
<string>6BAF452A121D1723008CFCDF</string>
<string>6BAF452B121D1723008CFCDF</string>
<string>6BAF4562121D1849008CFCDF</string>
<string>6BAF4564121D1849008CFCDF</string>
<string>6BAF457C121D19CB008CFCDF</string>
<string>6BAF457D121D19CB008CFCDF</string>
<string>6BAF457E121D19CB008CFCDF</string>
@ -403,21 +383,37 @@
<string>6BAF4580121D19CB008CFCDF</string>
<string>6BAF4581121D19CB008CFCDF</string>
<string>6BAF4582121D19CB008CFCDF</string>
<string>6BAF4592121D1B18008CFCDF</string>
<string>6BAF4593121D1B18008CFCDF</string>
<string>6BAF459B121D1C15008CFCDF</string>
<string>6BAF45A6121D1C49008CFCDF</string>
<string>6BAF45AA121D2C03008CFCDF</string>
<string>6BAF45AB121D2C03008CFCDF</string>
<string>6BAF45AC121D2C03008CFCDF</string>
<string>6BAF45B7121D2F37008CFCDF</string>
<string>6BAF45B8121D2F37008CFCDF</string>
<string>6BAF45C0121D2F57008CFCDF</string>
</array>
<key>nextStack</key>
<array>
<string>6BAF4490121C4895008CFCDF</string>
<string>6BAF4491121C4895008CFCDF</string>
<string>6BAF45E4121D7277008CFCDF</string>
<string>6BAF4604121D7388008CFCDF</string>
<string>6BAF4605121D7388008CFCDF</string>
<string>6BAF4607121D7388008CFCDF</string>
<string>6BAF461E121D746C008CFCDF</string>
<string>6BAF4637121D74D3008CFCDF</string>
<string>6BAF46A0121D8B41008CFCDF</string>
<string>6BAF46A1121D8B41008CFCDF</string>
<string>6BAF46A2121D8B41008CFCDF</string>
<string>6BAF46A3121D8B41008CFCDF</string>
<string>6BAF46D3121D8FF1008CFCDF</string>
<string>6BAF4739121D9FBE008CFCDF</string>
<string>6BAF473A121D9FBE008CFCDF</string>
<string>6BAF4747121D9FED008CFCDF</string>
<string>6BAF475A121DA31D008CFCDF</string>
<string>6BAF475B121DA31D008CFCDF</string>
<string>6BAF475C121DA31D008CFCDF</string>
<string>6BAF475D121DA31D008CFCDF</string>
<string>6BAF475E121DA31D008CFCDF</string>
<string>6BAF475F121DA31D008CFCDF</string>
<string>6BAF4760121DA31D008CFCDF</string>
<string>6BAF4778121DCAF9008CFCDF</string>
<string>6BAF478E121DD150008CFCDF</string>
<string>6B1C8D82121E80950048697F</string>
<string>6B1C8DA2121E813D0048697F</string>
<string>6B1C8DA3121E813D0048697F</string>
<string>6B1C8DAD121E821F0048697F</string>
<string>6B1C8DA8121E81C40048697F</string>
</array>
<key>prevStack</key>
<array>
@ -445,9 +441,6 @@
<string>6BF5F2ED11748884000502A6</string>
<string>6BF5F2EE11748884000502A6</string>
<string>6BF5F33911759C3C000502A6</string>
<string>6B4215D1118066FE006C347B</string>
<string>6B98458E11E6039A00FA177B</string>
<string>6B98465211E6F9B400FA177B</string>
<string>6B98465411E6F9B400FA177B</string>
<string>6B98466011E6F9B400FA177B</string>
<string>6B98471011E734A100FA177B</string>
@ -470,358 +463,55 @@
<string>6BBB4AF7115B4F3400CF791D</string>
<string>6BAF405912140B4E008CFCDF</string>
<string>6BAF40A612142254008CFCDF</string>
<string>6BAF410112197F3D008CFCDF</string>
<string>6BAF411712197F3D008CFCDF</string>
<string>6BAF411F12197F3D008CFCDF</string>
<string>6BAF412F12197F3D008CFCDF</string>
<string>6BAF414812197F3D008CFCDF</string>
<string>6BAF414A12197F3D008CFCDF</string>
<string>6BAF414C12197F3D008CFCDF</string>
<string>6BAF414D12197F3D008CFCDF</string>
<string>6BAF415312197F3D008CFCDF</string>
<string>6BAF415412197F3D008CFCDF</string>
<string>6BAF41781219811E008CFCDF</string>
<string>6BAF417A1219811E008CFCDF</string>
<string>6BAF417B1219811E008CFCDF</string>
<string>6BAF417C1219811E008CFCDF</string>
<string>6BAF417E1219811E008CFCDF</string>
<string>6BAF417F1219811E008CFCDF</string>
<string>6BAF41801219811E008CFCDF</string>
<string>6BAF41811219811E008CFCDF</string>
<string>6BAF41821219811E008CFCDF</string>
<string>6BAF41831219811E008CFCDF</string>
<string>6BAF41841219811E008CFCDF</string>
<string>6BAF41861219811E008CFCDF</string>
<string>6BAF41871219811E008CFCDF</string>
<string>6BAF41AE12198419008CFCDF</string>
<string>6BAF41B012198419008CFCDF</string>
<string>6BAF41B212198419008CFCDF</string>
<string>6BAF41B412198419008CFCDF</string>
<string>6BAF41B612198419008CFCDF</string>
<string>6BAF41B712198419008CFCDF</string>
<string>6BAF41B912198419008CFCDF</string>
<string>6BAF41BC12198419008CFCDF</string>
<string>6BAF41BD12198419008CFCDF</string>
<string>6BAF41BE12198419008CFCDF</string>
<string>6BAF41BF12198419008CFCDF</string>
<string>6BAF41C012198419008CFCDF</string>
<string>6BAF41C112198419008CFCDF</string>
<string>6BAF41C212198419008CFCDF</string>
<string>6BAF41C412198419008CFCDF</string>
<string>6BAF41C512198419008CFCDF</string>
<string>6BAF41C712198419008CFCDF</string>
<string>6BAF41C812198419008CFCDF</string>
<string>6BAF41C912198419008CFCDF</string>
<string>6BAF41CB12198419008CFCDF</string>
<string>6BAF41CC12198419008CFCDF</string>
<string>6BAF41D3121A5AEE008CFCDF</string>
<string>6BAF41DA121A5D13008CFCDF</string>
<string>6BAF41DB121A5D13008CFCDF</string>
<string>6BAF41E9121ACD06008CFCDF</string>
<string>6BAF4223121ACE5E008CFCDF</string>
<string>6BAF4243121AD679008CFCDF</string>
<string>6BAF4245121AD679008CFCDF</string>
<string>6BAF4254121AD7D7008CFCDF</string>
<string>6BAF4255121AD7D7008CFCDF</string>
<string>6BAF4256121AD7D7008CFCDF</string>
<string>6BAF4257121AD7D7008CFCDF</string>
<string>6BAF426B121AD99B008CFCDF</string>
<string>6BAF426D121AD99B008CFCDF</string>
<string>6BAF426F121AD99B008CFCDF</string>
<string>6BAF4270121AD99B008CFCDF</string>
<string>6BAF4272121AD99B008CFCDF</string>
<string>6BAF4283121ADD46008CFCDF</string>
<string>6BAF4284121ADD46008CFCDF</string>
<string>6BAF4285121ADD46008CFCDF</string>
<string>6BAF4288121ADD46008CFCDF</string>
<string>6BAF4289121ADD46008CFCDF</string>
<string>6BAF4290121AEBDF008CFCDF</string>
<string>6BAF4291121AEBDF008CFCDF</string>
<string>6BAF4293121AEBDF008CFCDF</string>
<string>6BAF4298121AEC2A008CFCDF</string>
<string>6BAF429D121AED31008CFCDF</string>
<string>6BAF429F121AED31008CFCDF</string>
<string>6BAF42A1121AED31008CFCDF</string>
<string>6BAF42A3121AED31008CFCDF</string>
<string>6BAF42A9121AEFD9008CFCDF</string>
<string>6BAF42B5121AF141008CFCDF</string>
<string>6BAF42B6121AF141008CFCDF</string>
<string>6BAF42B7121AF141008CFCDF</string>
<string>6BAF42B8121AF141008CFCDF</string>
<string>6BAF42B9121AF141008CFCDF</string>
<string>6BAF42BA121AF141008CFCDF</string>
<string>6BAF42BB121AF141008CFCDF</string>
<string>6BAF42BC121AF141008CFCDF</string>
<string>6BAF42BD121AF141008CFCDF</string>
<string>6BAF42BE121AF141008CFCDF</string>
<string>6BAF42BF121AF141008CFCDF</string>
<string>6BAF42C0121AF141008CFCDF</string>
<string>6BAF42C7121AF27C008CFCDF</string>
<string>6BAF42C8121AF27C008CFCDF</string>
<string>6BAF42C9121AF27C008CFCDF</string>
<string>6BAF42CA121AF27C008CFCDF</string>
<string>6BAF42CB121AF27C008CFCDF</string>
<string>6BAF42CC121AF27C008CFCDF</string>
<string>6BAF42CD121AF27C008CFCDF</string>
<string>6BAF42CE121AF27C008CFCDF</string>
<string>6BAF42CF121AF27C008CFCDF</string>
<string>6BBB4AD3115B4F3400CF791D</string>
<string>6BAF42E4121AF3B8008CFCDF</string>
<string>6BAF42E5121AF3B8008CFCDF</string>
<string>6BAF42E6121AF3B8008CFCDF</string>
<string>6BAF42E7121AF3B8008CFCDF</string>
<string>6BAF42E8121AF3B8008CFCDF</string>
<string>6BAF42FC121AF514008CFCDF</string>
<string>6BAF42FD121AF514008CFCDF</string>
<string>6BAF42FE121AF514008CFCDF</string>
<string>6BAF42FF121AF514008CFCDF</string>
<string>6BAF4300121AF514008CFCDF</string>
<string>6BAF4301121AF514008CFCDF</string>
<string>6BAF4302121AF514008CFCDF</string>
<string>6BAF4303121AF514008CFCDF</string>
<string>6BAF4304121AF514008CFCDF</string>
<string>6BAF4309121AF6E0008CFCDF</string>
<string>6BAF430E121AF7CD008CFCDF</string>
<string>6BAF430F121AF7CD008CFCDF</string>
<string>6BAF4310121AF7CD008CFCDF</string>
<string>6BAF4311121AF7CD008CFCDF</string>
<string>6BAF4312121AF7CD008CFCDF</string>
<string>6BAF4313121AF7CD008CFCDF</string>
<string>6BAF4314121AF7CD008CFCDF</string>
<string>6BAF4327121AF998008CFCDF</string>
<string>6BAF4328121AF998008CFCDF</string>
<string>6BAF4329121AF998008CFCDF</string>
<string>6BAF432A121AF998008CFCDF</string>
<string>6BAF432B121AF998008CFCDF</string>
<string>6BAF432C121AF998008CFCDF</string>
<string>6BAF432D121AF998008CFCDF</string>
<string>6BAF432E121AF998008CFCDF</string>
<string>6BAF432F121AF998008CFCDF</string>
<string>6BAF4330121AF998008CFCDF</string>
<string>6BAF4331121AF998008CFCDF</string>
<string>6BAF4332121AF998008CFCDF</string>
<string>6BAF4333121AF998008CFCDF</string>
<string>6BAF4334121AF998008CFCDF</string>
<string>6BAF4335121AF998008CFCDF</string>
<string>6BAF4336121AF998008CFCDF</string>
<string>6BAF4337121AF998008CFCDF</string>
<string>6BAF4338121AF998008CFCDF</string>
<string>6BAF4339121AF998008CFCDF</string>
<string>6BAF433A121AF998008CFCDF</string>
<string>6BAF433B121AF998008CFCDF</string>
<string>6BAF433C121AF998008CFCDF</string>
<string>6BAF433D121AF998008CFCDF</string>
<string>6BAF433E121AF998008CFCDF</string>
<string>6BAF433F121AF998008CFCDF</string>
<string>6BAF4340121AF998008CFCDF</string>
<string>6BAF4341121AF998008CFCDF</string>
<string>6BAF4348121AFD0B008CFCDF</string>
<string>6BAF438B121C1F3D008CFCDF</string>
<string>6BAF438C121C1F3D008CFCDF</string>
<string>6BAF438D121C1F3D008CFCDF</string>
<string>6BAF4390121C1F3D008CFCDF</string>
<string>6BAF4395121C1F3D008CFCDF</string>
<string>6BAF4396121C1F3D008CFCDF</string>
<string>6BAF4399121C1F3D008CFCDF</string>
<string>6BAF439A121C1F3D008CFCDF</string>
<string>6BAF439C121C1F3D008CFCDF</string>
<string>6BAF439D121C1F3D008CFCDF</string>
<string>6BAF439E121C1F3D008CFCDF</string>
<string>6BAF43A1121C1F3D008CFCDF</string>
<string>6BAF43A2121C1F3D008CFCDF</string>
<string>6BAF43A3121C1F3D008CFCDF</string>
<string>6BAF43A4121C1F3D008CFCDF</string>
<string>6BAF43A6121C1F3D008CFCDF</string>
<string>6BAF43B2121C1F3D008CFCDF</string>
<string>6BAF43B3121C1F3D008CFCDF</string>
<string>6BAF43B4121C1F3D008CFCDF</string>
<string>6BAF43B5121C1F3D008CFCDF</string>
<string>6BAF43B7121C1F3D008CFCDF</string>
<string>6BAF43B8121C1F3D008CFCDF</string>
<string>6BAF43B9121C1F3D008CFCDF</string>
<string>6BAF43BB121C1F3D008CFCDF</string>
<string>6BAF43BC121C1F3D008CFCDF</string>
<string>6BAF43BD121C1F3D008CFCDF</string>
<string>6BAF43BE121C1F3D008CFCDF</string>
<string>6BAF43BF121C1F3D008CFCDF</string>
<string>6BAF43C0121C1F3D008CFCDF</string>
<string>6BAF43C2121C1F3D008CFCDF</string>
<string>6BAF43D1121C2164008CFCDF</string>
<string>6BAF43D2121C2164008CFCDF</string>
<string>6BAF43D3121C2164008CFCDF</string>
<string>6BAF43D4121C2164008CFCDF</string>
<string>6BAF43D5121C2164008CFCDF</string>
<string>6BAF43D6121C2164008CFCDF</string>
<string>6BAF43D7121C2164008CFCDF</string>
<string>6BAF43E3121C225B008CFCDF</string>
<string>6BAF43E4121C225B008CFCDF</string>
<string>6BAF43E5121C225B008CFCDF</string>
<string>6BAF4404121C241D008CFCDF</string>
<string>6BAF4406121C241D008CFCDF</string>
<string>6BAF4408121C241D008CFCDF</string>
<string>6BAF4409121C241D008CFCDF</string>
<string>6BAF440A121C241D008CFCDF</string>
<string>6BAF440B121C241D008CFCDF</string>
<string>6BAF440C121C241D008CFCDF</string>
<string>6BAF440D121C241D008CFCDF</string>
<string>6BAF440E121C241D008CFCDF</string>
<string>6BAF440F121C241D008CFCDF</string>
<string>6BAF4411121C241D008CFCDF</string>
<string>6BAF4412121C241D008CFCDF</string>
<string>6BAF4413121C241D008CFCDF</string>
<string>6BAF4414121C241D008CFCDF</string>
<string>6BAF4415121C241D008CFCDF</string>
<string>6BAF4428121C25E3008CFCDF</string>
<string>6BAF4429121C25E3008CFCDF</string>
<string>6BAF442A121C25E3008CFCDF</string>
<string>6BAF442C121C25E3008CFCDF</string>
<string>6BAF4436121C2A3F008CFCDF</string>
<string>6BAF443D121C2E5D008CFCDF</string>
<string>6BAF444F121C40AC008CFCDF</string>
<string>6BAF4450121C40AC008CFCDF</string>
<string>6BAF4451121C40AC008CFCDF</string>
<string>6BAF4452121C40AC008CFCDF</string>
<string>6BAF4453121C40AC008CFCDF</string>
<string>6BAF4455121C40AC008CFCDF</string>
<string>6BAF4456121C40AC008CFCDF</string>
<string>6BAF4457121C40AC008CFCDF</string>
<string>6BAF4458121C40AC008CFCDF</string>
<string>6BAF4459121C40AC008CFCDF</string>
<string>6BAF445A121C40AC008CFCDF</string>
<string>6BAF445B121C40AC008CFCDF</string>
<string>6BAF445C121C40AC008CFCDF</string>
<string>6BAF445D121C40AC008CFCDF</string>
<string>6BAF445E121C40AC008CFCDF</string>
<string>6BAF445F121C40AC008CFCDF</string>
<string>6BAF4478121C4895008CFCDF</string>
<string>6BAF4479121C4895008CFCDF</string>
<string>6BAF447A121C4895008CFCDF</string>
<string>6BAF447B121C4895008CFCDF</string>
<string>6BAF447C121C4895008CFCDF</string>
<string>6BAF447D121C4895008CFCDF</string>
<string>6BAF447E121C4895008CFCDF</string>
<string>6BAF447F121C4895008CFCDF</string>
<string>6BAF4480121C4895008CFCDF</string>
<string>6BAF4481121C4895008CFCDF</string>
<string>6BAF4482121C4895008CFCDF</string>
<string>6BAF4483121C4895008CFCDF</string>
<string>6BAF4485121C4895008CFCDF</string>
<string>6BAF4486121C4895008CFCDF</string>
<string>6BAF4487121C4895008CFCDF</string>
<string>6BAF4489121C4895008CFCDF</string>
<string>6BAF448B121C4895008CFCDF</string>
<string>6BAF448C121C4895008CFCDF</string>
<string>6BAF448E121C4895008CFCDF</string>
<string>6BAF448F121C4895008CFCDF</string>
<string>6B98477411E7406900FA177B</string>
<string>6BAF3861120A8A8E008CFCDF</string>
<string>6BAF410212197F3D008CFCDF</string>
<string>6BAF44A1121C4A43008CFCDF</string>
<string>6BAF44AD121C4BD8008CFCDF</string>
<string>6BAF44BF121C4D30008CFCDF</string>
<string>6BAF44C0121C4D30008CFCDF</string>
<string>6BAF44C1121C4D30008CFCDF</string>
<string>6BAF44C9121C4D65008CFCDF</string>
<string>6BAF44CA121C4D65008CFCDF</string>
<string>6BAF44D3121C4DB4008CFCDF</string>
<string>6BAF44DB121C4DFC008CFCDF</string>
<string>6BAF44E3121C54D4008CFCDF</string>
<string>6BAF44E4121C54D4008CFCDF</string>
<string>6BAF44E5121C54D4008CFCDF</string>
<string>6BAF44E6121C54D4008CFCDF</string>
<string>6BAF44E7121C54D4008CFCDF</string>
<string>6BAF44E8121C54D4008CFCDF</string>
<string>6BAF44E9121C54D4008CFCDF</string>
<string>6BAF44EB121C54D4008CFCDF</string>
<string>6BAF44ED121C54D4008CFCDF</string>
<string>6BAF44F2121C55F4008CFCDF</string>
<string>6BAF44FA121C5713008CFCDF</string>
<string>6BAF44FB121C5713008CFCDF</string>
<string>6BAF44FC121C5713008CFCDF</string>
<string>6BAF44FD121C5713008CFCDF</string>
<string>6BAF4505121C57D5008CFCDF</string>
<string>6BAF4506121C57D5008CFCDF</string>
<string>6BAF450C121C5810008CFCDF</string>
<string>6BAF450D121C5810008CFCDF</string>
<string>6BAF4512121C5874008CFCDF</string>
<string>6BAF4513121C5874008CFCDF</string>
<string>6BAF4536121D1723008CFCDF</string>
<string>6BAF4537121D1723008CFCDF</string>
<string>6BAF4538121D1723008CFCDF</string>
<string>6BAF4539121D1723008CFCDF</string>
<string>6BAF453A121D1723008CFCDF</string>
<string>6BAF453B121D1723008CFCDF</string>
<string>6BAF453C121D1723008CFCDF</string>
<string>6BAF453D121D1723008CFCDF</string>
<string>6BAF453E121D1723008CFCDF</string>
<string>6BAF453F121D1723008CFCDF</string>
<string>6BAF4540121D1723008CFCDF</string>
<string>6BAF4541121D1723008CFCDF</string>
<string>6BAF4542121D1723008CFCDF</string>
<string>6BAF4543121D1723008CFCDF</string>
<string>6BAF4544121D1723008CFCDF</string>
<string>6BAF4545121D1723008CFCDF</string>
<string>6BAF4546121D1723008CFCDF</string>
<string>6BAF4547121D1723008CFCDF</string>
<string>6BAF4548121D1723008CFCDF</string>
<string>6BAF4549121D1723008CFCDF</string>
<string>6BAF454A121D1723008CFCDF</string>
<string>6BAF454B121D1723008CFCDF</string>
<string>6BAF454C121D1723008CFCDF</string>
<string>6BAF454D121D1723008CFCDF</string>
<string>6BAF454E121D1723008CFCDF</string>
<string>6BAF454F121D1723008CFCDF</string>
<string>6BAF4550121D1723008CFCDF</string>
<string>6BAF4551121D1723008CFCDF</string>
<string>6BAF4552121D1723008CFCDF</string>
<string>6BAF4553121D1723008CFCDF</string>
<string>6BAF4554121D1723008CFCDF</string>
<string>6BAF4555121D1723008CFCDF</string>
<string>6BAF4556121D1723008CFCDF</string>
<string>6BAF4557121D1723008CFCDF</string>
<string>6BAF4558121D1723008CFCDF</string>
<string>6BAF4559121D1723008CFCDF</string>
<string>6BAF455A121D1723008CFCDF</string>
<string>6BAF455B121D1723008CFCDF</string>
<string>6BAF455C121D1723008CFCDF</string>
<string>6BAF455D121D1723008CFCDF</string>
<string>6BAF455E121D1723008CFCDF</string>
<string>6BAF455F121D1723008CFCDF</string>
<string>6BAF4568121D1849008CFCDF</string>
<string>6BAF4569121D1849008CFCDF</string>
<string>6BAF456A121D1849008CFCDF</string>
<string>6BAF456B121D1849008CFCDF</string>
<string>6BAF456C121D1849008CFCDF</string>
<string>6BAF456D121D1849008CFCDF</string>
<string>6BAF456E121D1849008CFCDF</string>
<string>6BAF4575121D18A5008CFCDF</string>
<string>6BAF4576121D18A5008CFCDF</string>
<string>6BAF4577121D18A5008CFCDF</string>
<string>6BAF4578121D18A5008CFCDF</string>
<string>6BAF4584121D19CB008CFCDF</string>
<string>6BAF4585121D19CB008CFCDF</string>
<string>6BAF4586121D19CB008CFCDF</string>
<string>6BAF4587121D19CB008CFCDF</string>
<string>6BAF4588121D19CB008CFCDF</string>
<string>6BAF4589121D19CB008CFCDF</string>
<string>6BAF458A121D19CB008CFCDF</string>
<string>6BAF458B121D19CB008CFCDF</string>
<string>6BAF458F121D1A1C008CFCDF</string>
<string>6BAF4596121D1B18008CFCDF</string>
<string>6BAF4597121D1B18008CFCDF</string>
<string>6BAF4598121D1B18008CFCDF</string>
<string>6BAF4599121D1B18008CFCDF</string>
<string>6BAF459E121D1C15008CFCDF</string>
<string>6BAF459F121D1C15008CFCDF</string>
<string>6BAF45A0121D1C15008CFCDF</string>
<string>6BAF45A1121D1C15008CFCDF</string>
<string>6BAF45A8121D1C49008CFCDF</string>
<string>6BAF45AE121D2C03008CFCDF</string>
<string>6BAF45AF121D2C03008CFCDF</string>
<string>6BAF45B0121D2C03008CFCDF</string>
<string>6BAF45B1121D2C03008CFCDF</string>
<string>6BAF45BA121D2F37008CFCDF</string>
<string>6BAF45BB121D2F37008CFCDF</string>
<string>6BAF45E9121D7277008CFCDF</string>
<string>6BAF4455121C40AC008CFCDF</string>
<string>6BAF447E121C4895008CFCDF</string>
<string>6BAF473D121D9FBE008CFCDF</string>
<string>6BAF4749121D9FED008CFCDF</string>
<string>6BAF4762121DA31D008CFCDF</string>
<string>6BAF4767121DA31D008CFCDF</string>
<string>6BAF4768121DA31D008CFCDF</string>
<string>6BAF4797121DD34D008CFCDF</string>
<string>6B1C8D84121E80950048697F</string>
<string>6B1C8D85121E80950048697F</string>
<string>6B1C8D86121E80950048697F</string>
<string>6B1C8D87121E80950048697F</string>
<string>6B1C8D88121E80950048697F</string>
<string>6B1C8D89121E80950048697F</string>
<string>6B1C8D8A121E80950048697F</string>
<string>6B1C8D8B121E80950048697F</string>
<string>6B1C8D8C121E80950048697F</string>
<string>6B1C8D8D121E80950048697F</string>
<string>6B1C8D8E121E80950048697F</string>
<string>6B1C8D8F121E80950048697F</string>
<string>6B1C8D90121E80950048697F</string>
<string>6B1C8D91121E80950048697F</string>
<string>6B1C8D92121E80950048697F</string>
<string>6B1C8D93121E80950048697F</string>
<string>6B1C8D94121E80950048697F</string>
<string>6B1C8D95121E80950048697F</string>
<string>6B1C8D96121E80950048697F</string>
<string>6B1C8DA5121E813D0048697F</string>
<string>6B1C8DA6121E813D0048697F</string>
<string>6B1C8DAA121E81C40048697F</string>
<string>6B1C8DAE121E821F0048697F</string>
</array>
</dict>
<key>SplitCount</key>
@ -835,18 +525,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {994, 575}}</string>
<string>{{0, 0}, {994, 606}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1280 719 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>575pt</string>
<string>606pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>98pt</string>
<string>67pt</string>
<key>Tabs</key>
<array>
<dict>
@ -860,7 +550,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {994, 43}}</string>
<string>{{10, 27}, {994, 66}}</string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@ -914,7 +604,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {994, 71}}</string>
<string>{{10, 27}, {994, 40}}</string>
<key>RubberWindowFrame</key>
<string>0 59 1280 719 0 0 1280 778 </string>
</dict>
@ -944,11 +634,11 @@
</array>
<key>TableOfContents</key>
<array>
<string>6BAF40D412193E84008CFCDF</string>
<string>6B1C8D9A121E809F0048697F</string>
<string>1CA23ED40692098700951B8B</string>
<string>6BAF40D512193E84008CFCDF</string>
<string>6B1C8D9B121E809F0048697F</string>
<string>6B8632A30F78115100E2684A</string>
<string>6BAF40D612193E84008CFCDF</string>
<string>6B1C8D9C121E809F0048697F</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
@ -999,12 +689,12 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {1280, 311}}</string>
<string>{{0, 0}, {1280, 411}}</string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>311pt</string>
<string>411pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -1023,8 +713,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {577, 89}}</string>
<string>{{577, 0}, {703, 89}}</string>
<string>{{0, 0}, {577, 109}}</string>
<string>{{577, 0}, {703, 109}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@ -1039,8 +729,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {1280, 89}}</string>
<string>{{0, 89}, {1280, 273}}</string>
<string>{{0, 0}, {1280, 109}}</string>
<string>{{0, 109}, {1280, 153}}</string>
</array>
</dict>
</dict>
@ -1060,7 +750,7 @@
<key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>Frame</key>
<string>{{0, 316}, {1280, 362}}</string>
<string>{{0, 416}, {1280, 262}}</string>
<key>PBXDebugSessionStackFrameViewKey</key>
<dict>
<key>DebugVariablesTableConfiguration</key>
@ -1073,13 +763,13 @@
<real>410</real>
</array>
<key>Frame</key>
<string>{{577, 0}, {703, 89}}</string>
<string>{{577, 0}, {703, 109}}</string>
</dict>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Proportion</key>
<string>362pt</string>
<string>262pt</string>
</dict>
</array>
<key>Name</key>
@ -1097,13 +787,13 @@
</array>
<key>TableOfContents</key>
<array>
<string>6BAF41891219811E008CFCDF</string>
<string>6B1C8D9D121E809F0048697F</string>
<string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string>
<string>6BAF418A1219811E008CFCDF</string>
<string>6BAF418B1219811E008CFCDF</string>
<string>6BAF418C1219811E008CFCDF</string>
<string>6BAF418D1219811E008CFCDF</string>
<string>6B1C8D9E121E809F0048697F</string>
<string>6B1C8D9F121E809F0048697F</string>
<string>6B1C8DA0121E809F0048697F</string>
<string>6B1C8DA1121E809F0048697F</string>
<string>6B8632A30F78115100E2684A</string>
</array>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
@ -1136,8 +826,6 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>6BAF42D9121AF2AF008CFCDF</string>
<string>6BAF42DA121AF2AF008CFCDF</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array>
<key>WindowString</key>

View File

@ -42,6 +42,7 @@ protected:
DRAWMODE_NAVMESH,
DRAWMODE_NAVMESH_TRANS,
DRAWMODE_NAVMESH_BVTREE,
DRAWMODE_NAVMESH_NODES,
DRAWMODE_NAVMESH_INVIS,
DRAWMODE_MESH,
DRAWMODE_VOXELS,

View File

@ -80,6 +80,7 @@ protected:
DRAWMODE_NAVMESH,
DRAWMODE_NAVMESH_TRANS,
DRAWMODE_NAVMESH_BVTREE,
DRAWMODE_NAVMESH_NODES,
DRAWMODE_NAVMESH_INVIS,
DRAWMODE_MESH,
DRAWMODE_VOXELS,

View File

@ -45,6 +45,7 @@ protected:
DRAWMODE_NAVMESH,
DRAWMODE_NAVMESH_TRANS,
DRAWMODE_NAVMESH_BVTREE,
DRAWMODE_NAVMESH_NODES,
DRAWMODE_NAVMESH_PORTALS,
DRAWMODE_NAVMESH_INVIS,
DRAWMODE_MESH,

View File

@ -51,7 +51,7 @@ void imguiSeparatorLine();
bool imguiButton(const char* text, bool enabled = true);
bool imguiItem(const char* text, bool enabled = true);
bool imguiCheck(const char* text, bool checked, bool enabled = true);
bool imguiCollapse(const char* text, bool checked, bool enabled = true);
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled = true);
void imguiLabel(const char* text);
void imguiValue(const char* text);
bool imguiSlider(const char* text, float* val, float vmin, float vmax, float vinc, bool enabled = true);

View File

@ -1046,7 +1046,7 @@ void CrowdTool::handleMenu()
imguiSeparator();
imguiSeparator();
if (imguiCollapse("Options", m_expandOptions))
if (imguiCollapse("Options", 0, m_expandOptions))
m_expandOptions = !m_expandOptions;
if (m_expandOptions)
@ -1061,7 +1061,7 @@ void CrowdTool::handleMenu()
imguiUnindent();
}
if (imguiCollapse("Debug Draw", m_expandDebugDraw))
if (imguiCollapse("Debug Draw", 0, m_expandDebugDraw))
m_expandDebugDraw = !m_expandDebugDraw;
if (m_expandDebugDraw)

View File

@ -158,8 +158,8 @@ NavMeshTesterTool::NavMeshTesterTool() :
m_pathIterNum(0),
m_steerPointCount(0)
{
m_filter.includeFlags = SAMPLE_POLYFLAGS_ALL;
m_filter.excludeFlags = 0;
m_filter.setIncludeFlags(SAMPLE_POLYFLAGS_ALL);
m_filter.setExcludeFlags(0);
m_polyPickExt[0] = 2;
m_polyPickExt[1] = 4;
@ -189,12 +189,19 @@ void NavMeshTesterTool::init(Sample* sample)
if (m_navQuery)
{
// Change costs.
m_navQuery->setAreaCost(SAMPLE_POLYAREA_GROUND, 1.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_GROUND, 1.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_WATER, 10.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_ROAD, 1.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_DOOR, 1.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_GRASS, 2.0f);
m_filter.setAreaCost(SAMPLE_POLYAREA_JUMP, 1.5f);
/* m_navQuery->setAreaCost(SAMPLE_POLYAREA_GROUND, 1.0f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_WATER, 10.0f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_ROAD, 1.0f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_DOOR, 1.0f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_GRASS, 2.0f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_JUMP, 1.5f);
m_navQuery->setAreaCost(SAMPLE_POLYAREA_JUMP, 1.5f);*/
}
if (m_toolMode == TOOLMODE_PATHFIND_FOLLOW ||
@ -270,24 +277,24 @@ void NavMeshTesterTool::handleMenu()
imguiLabel("Include Flags");
imguiIndent();
if (imguiCheck("Walk", (m_filter.includeFlags & SAMPLE_POLYFLAGS_WALK) != 0))
if (imguiCheck("Walk", (m_filter.getIncludeFlags() & SAMPLE_POLYFLAGS_WALK) != 0))
{
m_filter.includeFlags ^= SAMPLE_POLYFLAGS_WALK;
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ SAMPLE_POLYFLAGS_WALK);
recalc();
}
if (imguiCheck("Swim", (m_filter.includeFlags & SAMPLE_POLYFLAGS_SWIM) != 0))
if (imguiCheck("Swim", (m_filter.getIncludeFlags() & SAMPLE_POLYFLAGS_SWIM) != 0))
{
m_filter.includeFlags ^= SAMPLE_POLYFLAGS_SWIM;
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ SAMPLE_POLYFLAGS_SWIM);
recalc();
}
if (imguiCheck("Door", (m_filter.includeFlags & SAMPLE_POLYFLAGS_DOOR) != 0))
if (imguiCheck("Door", (m_filter.getIncludeFlags() & SAMPLE_POLYFLAGS_DOOR) != 0))
{
m_filter.includeFlags ^= SAMPLE_POLYFLAGS_DOOR;
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ SAMPLE_POLYFLAGS_DOOR);
recalc();
}
if (imguiCheck("Jump", (m_filter.includeFlags & SAMPLE_POLYFLAGS_JUMP) != 0))
if (imguiCheck("Jump", (m_filter.getIncludeFlags() & SAMPLE_POLYFLAGS_JUMP) != 0))
{
m_filter.includeFlags ^= SAMPLE_POLYFLAGS_JUMP;
m_filter.setIncludeFlags(m_filter.getIncludeFlags() ^ SAMPLE_POLYFLAGS_JUMP);
recalc();
}
imguiUnindent();
@ -296,24 +303,24 @@ void NavMeshTesterTool::handleMenu()
imguiLabel("Exclude Flags");
imguiIndent();
if (imguiCheck("Walk", (m_filter.excludeFlags & SAMPLE_POLYFLAGS_WALK) != 0))
if (imguiCheck("Walk", (m_filter.getExcludeFlags() & SAMPLE_POLYFLAGS_WALK) != 0))
{
m_filter.excludeFlags ^= SAMPLE_POLYFLAGS_WALK;
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ SAMPLE_POLYFLAGS_WALK);
recalc();
}
if (imguiCheck("Swim", (m_filter.excludeFlags & SAMPLE_POLYFLAGS_SWIM) != 0))
if (imguiCheck("Swim", (m_filter.getExcludeFlags() & SAMPLE_POLYFLAGS_SWIM) != 0))
{
m_filter.excludeFlags ^= SAMPLE_POLYFLAGS_SWIM;
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ SAMPLE_POLYFLAGS_SWIM);
recalc();
}
if (imguiCheck("Door", (m_filter.excludeFlags & SAMPLE_POLYFLAGS_DOOR) != 0))
if (imguiCheck("Door", (m_filter.getExcludeFlags() & SAMPLE_POLYFLAGS_DOOR) != 0))
{
m_filter.excludeFlags ^= SAMPLE_POLYFLAGS_DOOR;
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ SAMPLE_POLYFLAGS_DOOR);
recalc();
}
if (imguiCheck("Jump", (m_filter.excludeFlags & SAMPLE_POLYFLAGS_JUMP) != 0))
if (imguiCheck("Jump", (m_filter.getExcludeFlags() & SAMPLE_POLYFLAGS_JUMP) != 0))
{
m_filter.excludeFlags ^= SAMPLE_POLYFLAGS_JUMP;
m_filter.setExcludeFlags(m_filter.getExcludeFlags() ^ SAMPLE_POLYFLAGS_JUMP);
recalc();
}
imguiUnindent();
@ -568,7 +575,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("pi %f %f %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2],
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
@ -710,7 +717,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("ps %f %f %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2],
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
m_nstraightPath = 0;
@ -740,7 +747,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("ps %f %f %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2],
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = 0;
m_nstraightPath = 0;
@ -761,7 +768,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("rc %f %f %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2],
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
float t = 0;
m_npolys = 0;
@ -801,7 +808,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("dw %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], 100.0f,
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_distanceToWall = m_navQuery->findDistanceToWall(m_startRef, m_spos, 100.0f, &m_filter, m_hitPos, m_hitNormal);
}
@ -816,7 +823,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("fpc %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], dist,
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = m_navQuery->findPolysAroundCircle(m_startRef, m_spos, dist, &m_filter,
m_polys, m_parent, 0, MAX_POLYS);
@ -853,7 +860,7 @@ void NavMeshTesterTool::recalc()
m_queryPoly[3],m_queryPoly[4],m_queryPoly[5],
m_queryPoly[6],m_queryPoly[7],m_queryPoly[8],
m_queryPoly[9],m_queryPoly[10],m_queryPoly[11],
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = m_navQuery->findPolysAroundShape(m_startRef, m_queryPoly, 4, &m_filter,
m_polys, m_parent, 0, MAX_POLYS);
@ -866,7 +873,7 @@ void NavMeshTesterTool::recalc()
#ifdef DUMP_REQS
printf("fln %f %f %f %f 0x%x 0x%x\n",
m_spos[0],m_spos[1],m_spos[2], m_neighbourhoodRadius,
m_filter.includeFlags, m_filter.excludeFlags);
m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif
m_npolys = m_navQuery->findLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, &m_filter,
m_polys, m_parent, MAX_POLYS);

View File

@ -139,6 +139,7 @@ void Sample_SoloMeshSimple::handleDebugMode()
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
valid[DRAWMODE_MESH] = true;
valid[DRAWMODE_VOXELS] = m_solid != 0;
@ -172,6 +173,8 @@ void Sample_SoloMeshSimple::handleDebugMode()
m_drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
m_drawMode = DRAWMODE_NAVMESH_NODES;
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
m_drawMode = DRAWMODE_VOXELS;
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
@ -236,16 +239,19 @@ void Sample_SoloMeshSimple::handleRender()
const float* bmax = m_geom->getMeshBoundsMax();
duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
if (m_navMesh &&
if (m_navMesh && m_navQuery &&
(m_drawMode == DRAWMODE_NAVMESH ||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
{
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
duDebugDrawNavMeshNodes(&dd, *m_navQuery);
}
glDepthMask(GL_TRUE);

View File

@ -267,6 +267,7 @@ void Sample_SoloMeshTiled::handleDebugMode()
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
valid[DRAWMODE_MESH] = true;
valid[DRAWMODE_VOXELS] = hasSolid;
@ -300,6 +301,8 @@ void Sample_SoloMeshTiled::handleDebugMode()
m_drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
m_drawMode = DRAWMODE_NAVMESH_NODES;
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
m_drawMode = DRAWMODE_VOXELS;
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
@ -372,16 +375,19 @@ void Sample_SoloMeshTiled::handleRender()
const float s = m_tileSize*m_cellSize;
duDebugDrawGridXZ(&dd, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f);
if (m_navMesh &&
if (m_navMesh && m_navQuery &&
(m_drawMode == DRAWMODE_NAVMESH ||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
{
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
duDebugDrawNavMeshNodes(&dd, *m_navQuery);
}
glDepthMask(GL_TRUE);

View File

@ -443,6 +443,7 @@ void Sample_TileMesh::handleDebugMode()
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
valid[DRAWMODE_NAVMESH_PORTALS] = m_navMesh != 0;
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
valid[DRAWMODE_MESH] = true;
@ -477,6 +478,8 @@ void Sample_TileMesh::handleDebugMode()
m_drawMode = DRAWMODE_NAVMESH_TRANS;
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
m_drawMode = DRAWMODE_NAVMESH_NODES;
if (imguiCheck("Navmesh Portals", m_drawMode == DRAWMODE_NAVMESH_PORTALS, valid[DRAWMODE_NAVMESH_PORTALS]))
m_drawMode = DRAWMODE_NAVMESH_PORTALS;
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
@ -563,10 +566,11 @@ void Sample_TileMesh::handleRender()
duDebugDrawNavMeshPortals(&dd, *m_navMesh);
}*/
if (m_navMesh &&
if (m_navMesh && m_navQuery &&
(m_drawMode == DRAWMODE_NAVMESH ||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
m_drawMode == DRAWMODE_NAVMESH_PORTALS ||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
{
@ -576,6 +580,8 @@ void Sample_TileMesh::handleRender()
duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
if (m_drawMode == DRAWMODE_NAVMESH_PORTALS)
duDebugDrawNavMeshPortals(&dd, *m_navMesh);
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
duDebugDrawNavMeshNodes(&dd, *m_navQuery);
}

View File

@ -179,8 +179,8 @@ void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery*
iter->nstraight = 0;
dtQueryFilter filter;
filter.includeFlags = (unsigned short)iter->includeFlags;
filter.excludeFlags = (unsigned short)iter->excludeFlags;
filter.setIncludeFlags((unsigned short)iter->includeFlags);
filter.setExcludeFlags((unsigned short)iter->excludeFlags);
// Find start points
rcTimeVal findNearestPolyStart = ctx->getTime();
@ -224,7 +224,19 @@ void TestCase::doTests(rcBuildContext* ctx, dtNavMesh* navmesh, dtNavMeshQuery*
iter->straight = new float[iter->nstraight*3];
memcpy(iter->straight, straight, sizeof(float)*3*iter->nstraight);
}
}
printf("Test Results:\n");
int n = 0;
for (Test* iter = m_tests; iter; iter = iter->next)
{
rcTimeVal total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
printf(" - Path %02d: %.4f ms\n", n, (float)total/1000.0f);
printf(" - poly: %.4f ms\n", (float)iter->findNearestPolyTime/1000.0f);
printf(" - path: %.4f ms\n", (float)iter->findPathTime/1000.0f);
printf(" - straight: %.4f ms\n", (float)iter->findStraightPathTime/1000.0f);
n++;
}
}
@ -264,7 +276,7 @@ void TestCase::handleRender()
bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
char text[64];
char text[64], subtext[64];
int n = 0;
static const float LABEL_DIST = 1.0f;
@ -310,27 +322,26 @@ bool TestCase::handleRenderOverlay(double* proj, double* model, int* view)
n = 0;
for (Test* iter = m_tests; iter; iter = iter->next)
{
snprintf(text, 64, "Path %d\n", n);
rcTimeVal total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
snprintf(subtext, 64, "%.4f ms", (float)total/1000.0f);
snprintf(text, 64, "Path %d", n);
if (imguiCollapse(text, iter->expand))
if (imguiCollapse(text, subtext, iter->expand))
iter->expand = !iter->expand;
if (iter->expand)
{
snprintf(text, 64, "Poly: %.4f ms\n", (float)iter->findNearestPolyTime/1000.0f);
snprintf(text, 64, "Poly: %.4f ms", (float)iter->findNearestPolyTime/1000.0f);
imguiValue(text);
snprintf(text, 64, "Path: %.4f ms\n", (float)iter->findPathTime/1000.0f);
snprintf(text, 64, "Path: %.4f ms", (float)iter->findPathTime/1000.0f);
imguiValue(text);
snprintf(text, 64, "Straight: %.4f ms\n", (float)iter->findStraightPathTime/1000.0f);
snprintf(text, 64, "Straight: %.4f ms", (float)iter->findStraightPathTime/1000.0f);
imguiValue(text);
imguiSeparator();
}
rcTimeVal total = iter->findNearestPolyTime + iter->findPathTime + iter->findStraightPathTime;
snprintf(text, 64, "Total: %.4f ms\n", (float)total/1000.0f);
imguiValue(text);
// imguiDrawText(10, 700-n*20, IMGUI_ALIGN_LEFT, text, imguiRGBA(255,255,255,220));
n++;
}

View File

@ -490,7 +490,7 @@ bool imguiCheck(const char* text, bool checked, bool enabled)
return res;
}
bool imguiCollapse(const char* text, bool checked, bool enabled)
bool imguiCollapse(const char* text, const char* subtext, bool checked, bool enabled)
{
g_state.widgetId++;
unsigned int id = (g_state.areaId<<16) | g_state.widgetId;
@ -516,7 +516,10 @@ bool imguiCollapse(const char* text, bool checked, bool enabled)
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, isHot(id) ? imguiRGBA(255,196,0,255) : imguiRGBA(255,255,255,200));
else
addGfxCmdText(x+BUTTON_HEIGHT, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, text, imguiRGBA(128,128,128,200));
if (subtext)
addGfxCmdText(x+w-BUTTON_HEIGHT/2, y+BUTTON_HEIGHT/2-TEXT_HEIGHT/2, IMGUI_ALIGN_RIGHT, subtext, imguiRGBA(255,255,255,128));
return res;
}