More polygons flags. Added filter for Detour queries.

This commit is contained in:
Mikko Mononen 2010-01-19 15:13:33 +00:00
parent fe1a62db22
commit e973b71d4b
8 changed files with 965 additions and 250 deletions

View File

@ -28,19 +28,39 @@ static const int DT_VERTS_PER_POLYGON = 6;
static const int DT_NAVMESH_MAGIC = 'DNAV'; static const int DT_NAVMESH_MAGIC = 'DNAV';
static const int DT_NAVMESH_VERSION = 2; static const int DT_NAVMESH_VERSION = 2;
static const unsigned char DT_POLY_OFFMESH_CONNECTION = 1;
static const unsigned short DT_EXT_LINK = 0x8000; static const unsigned short DT_EXT_LINK = 0x8000;
// Flags returned by findStraightPath().
enum dtStraightPathFlags
{
DT_STRAIGHTPATH_START = 0x01, // The vertex is the start position.
DT_STRAIGHTPATH_END = 0x02, // The vertex is the end position.
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, // The vertex is start of an off-mesh link.
};
// Flags describing polygon properties.
enum dtPolyFlags
{
DT_POLY_GROUND = 0x01, // Regular ground polygons.
DT_POLY_OFFMESH_CONNECTION = 0x02, // Off-mesh connections.
};
struct 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.
};
// Structure describing the navigation polygon data. // Structure describing the navigation polygon data.
struct dtPoly struct dtPoly
{ {
unsigned short verts[DT_VERTS_PER_POLYGON]; // Indices to vertices of the poly. unsigned short verts[DT_VERTS_PER_POLYGON]; // Indices to vertices of the poly.
unsigned short neis[DT_VERTS_PER_POLYGON]; // Refs to neighbours of the poly. unsigned short neis[DT_VERTS_PER_POLYGON]; // Refs to neighbours of the poly.
unsigned short linkBase; // Base index to header 'links' array. unsigned short linkBase; // Base index to header 'links' array.
unsigned short flags; // Flags (see dtPolyFlags).
unsigned char linkCount; // Number of links for unsigned char linkCount; // Number of links for
unsigned char vertCount; // Number of vertices. unsigned char vertCount; // Number of vertices.
unsigned char flags; // Flags.
}; };
// Stucture describing polygon detail triangles. // Stucture describing polygon detail triangles.
@ -118,13 +138,6 @@ struct dtMeshTile
dtMeshTile* next; // Next free tile or, next tile in spatial grid. dtMeshTile* next; // Next free tile or, next tile in spatial grid.
}; };
// Flags returned by findStraightPath().
enum dtStraightPathFlags
{
DT_STRAIGHTPATH_START = 0x01, // The vertex is the start position.
DT_STRAIGHTPATH_END = 0x02, // The vertex is the end position.
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, // The vertex is start of an off-mesh link.
};
class dtNavMesh class dtNavMesh
{ {
@ -206,16 +219,17 @@ public:
// extents - (in) The extents of the search box. // extents - (in) The extents of the search box.
// nearestPt - (out, opt) The nearest point on found polygon, null if not needed. // nearestPt - (out, opt) The nearest point on found polygon, null if not needed.
// Returns: Reference identifier for the polygon, or 0 if no polygons found. // Returns: Reference identifier for the polygon, or 0 if no polygons found.
dtPolyRef findNearestPoly(const float* center, const float* extents, float* nearestPt); dtPolyRef findNearestPoly(const float* center, const float* extents, dtQueryFilter* filter, float* nearestPt);
// Returns polygons which touch the query box. // Returns polygons which touch the query box.
// Params: // Params:
// center - (in) the center of the search box. // center - (in) the center of the search box.
// extents - (in) the extents of the search box. // extents - (in) the extents of the search box.
// flags - (int)
// polys - (out) array holding the search result. // polys - (out) array holding the search result.
// maxPolys - (in) The max number of polygons the polys array can hold. // maxPolys - (in) The max number of polygons the polys array can hold.
// Returns: Number of polygons in search result array. // Returns: Number of polygons in search result array.
int queryPolygons(const float* center, const float* extents, int queryPolygons(const float* center, const float* extents, dtQueryFilter* filter,
dtPolyRef* polys, const int maxPolys); dtPolyRef* polys, const int maxPolys);
// Finds path from start polygon to end polygon. // Finds path from start polygon to end polygon.
@ -229,6 +243,7 @@ public:
// Returns: Number of polygons in search result array. // Returns: Number of polygons in search result array.
int findPath(dtPolyRef startRef, dtPolyRef endRef, int findPath(dtPolyRef startRef, dtPolyRef endRef,
const float* startPos, const float* endPos, const float* startPos, const float* endPos,
dtQueryFilter* filter,
dtPolyRef* path, const int maxPathSize); dtPolyRef* path, const int maxPathSize);
// Finds a straight path from start to end locations within the corridor // Finds a straight path from start to end locations within the corridor
@ -266,7 +281,7 @@ public:
// hitNormal - (out) normal of the nearest hit. // hitNormal - (out) normal of the nearest hit.
// endRef - (out) ref to the last polygon which was processed. // endRef - (out) ref to the last polygon which was processed.
// Returns: Number of polygons in path or 0 if failed. // Returns: Number of polygons in path or 0 if failed.
int raycast(dtPolyRef startRef, const float* startPos, const float* endPos, int raycast(dtPolyRef startRef, const float* startPos, const float* endPos, dtQueryFilter* filter,
float& t, float* hitNormal, dtPolyRef* path, const int pathSize); float& t, float* hitNormal, dtPolyRef* path, const int pathSize);
// Returns distance to nearest wall from the specified location. // Returns distance to nearest wall from the specified location.
@ -278,7 +293,7 @@ public:
// hitNormal - (out) normal of the nearest hit. // hitNormal - (out) normal of the nearest hit.
// Returns: Distance to nearest wall from the test location. // Returns: Distance to nearest wall from the test location.
float findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius, float findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius,
float* hitPos, float* hitNormal); dtQueryFilter* filter, float* hitPos, float* hitNormal);
// Finds polygons found along the navigation graph which touch the specified circle. // Finds polygons found along the navigation graph which touch the specified circle.
// Params: // Params:
@ -290,7 +305,7 @@ public:
// resultCost - (out, opt) search cost at each result polygon. // resultCost - (out, opt) search cost at each result polygon.
// maxResult - (int) maximum capacity of search results. // maxResult - (int) maximum capacity of search results.
// Returns: Number of results. // Returns: Number of results.
int findPolysAround(dtPolyRef centerRef, const float* centerPos, float radius, int findPolysAround(dtPolyRef centerRef, const float* centerPos, float radius, dtQueryFilter* filter,
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
const int maxResult); const int maxResult);
@ -371,9 +386,9 @@ private:
// Removes external links at specified side. // Removes external links at specified side.
void removeExtLinks(dtMeshTile* tile, int side); void removeExtLinks(dtMeshTile* tile, int side);
// Queries polygons within a tile. // Queries polygons within a tile.
int queryTilePolygons(dtMeshTile* tile, const float* qmin, const float* qmax, int queryTilePolygons(dtMeshTile* tile, const float* qmin, const float* qmax, dtQueryFilter* filter,
dtPolyRef* polys, const int maxPolys); dtPolyRef* polys, const int maxPolys);
unsigned short getPolyFlags(dtPolyRef ref);
float getCost(dtPolyRef prev, dtPolyRef from, dtPolyRef to) const; float getCost(dtPolyRef prev, dtPolyRef from, dtPolyRef to) const;
float getFirstCost(const float* pos, dtPolyRef from, dtPolyRef to) const; float getFirstCost(const float* pos, dtPolyRef from, dtPolyRef to) const;
float getLastCost(dtPolyRef from, dtPolyRef to, const float* pos) const; float getLastCost(dtPolyRef from, dtPolyRef to, const float* pos) const;
@ -381,7 +396,7 @@ private:
// Returns portal points between two polygons. // Returns portal points between two polygons.
bool getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right, bool getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right,
unsigned char& fromFlags, unsigned char& toFlags) const; unsigned short& fromFlags, unsigned short& toFlags) const;
// Returns edge mid point between two polygons. // Returns edge mid point between two polygons.
bool getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const; bool getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const;

View File

@ -74,6 +74,11 @@ inline int computeTileHash(int x, int y, const int mask)
return (int)(n & mask); return (int)(n & mask);
} }
inline bool passFilter(dtQueryFilter* filter, unsigned short flags)
{
return (flags & filter->includeFlags) != 0 && (flags & filter->excludeFlags) == 0;
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -361,6 +366,7 @@ void dtNavMesh::buildIntLinks(dtMeshTile* tile)
{ {
dtOffMeshConnection* con = &h->offMeshCons[i]; dtOffMeshConnection* con = &h->offMeshCons[i];
dtPoly* poly = &h->polys[con->poly]; dtPoly* poly = &h->polys[con->poly];
dtQueryFilter defaultFilter;
con->ref[0] = 0; con->ref[0] = 0;
con->ref[1] = 0; con->ref[1] = 0;
@ -371,7 +377,7 @@ void dtNavMesh::buildIntLinks(dtMeshTile* tile)
// Find polygon to connect to. // Find polygon to connect to.
const float* p = &con->pos[j*3]; const float* p = &con->pos[j*3];
float nearestPt[3]; float nearestPt[3];
dtPolyRef ref = findNearestPoly(p, ext, nearestPt); dtPolyRef ref = findNearestPoly(p, ext, &defaultFilter, nearestPt);
// findNearestPoly may return too optimistic results, further check to make sure. // findNearestPoly may return too optimistic results, further check to make sure.
if (sqr(nearestPt[0]-p[0])+sqr(nearestPt[2]-p[2]) > sqr(con->rad)) if (sqr(nearestPt[0]-p[0])+sqr(nearestPt[2]-p[2]) > sqr(con->rad))
continue; continue;
@ -847,11 +853,11 @@ bool dtNavMesh::getPolyHeight(dtPolyRef ref, const float* pos, float* height) co
} }
dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents, float* nearestPt) dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents, dtQueryFilter* filter, float* nearestPt)
{ {
// Get nearby polygons from proximity grid. // Get nearby polygons from proximity grid.
dtPolyRef polys[128]; dtPolyRef polys[128];
int polyCount = queryPolygons(center, extents, polys, 128); int polyCount = queryPolygons(center, extents, filter, polys, 128);
// Find nearest polygon amongst the nearby polygons. // Find nearest polygon amongst the nearby polygons.
dtPolyRef nearest = 0; dtPolyRef nearest = 0;
@ -875,8 +881,8 @@ dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents,
return nearest; return nearest;
} }
int dtNavMesh::queryTilePolygons(dtMeshTile* tile, int dtNavMesh::queryTilePolygons(dtMeshTile* tile, const float* qmin, const float* qmax,
const float* qmin, const float* qmax, dtQueryFilter* filter,
dtPolyRef* polys, const int maxPolys) dtPolyRef* polys, const int maxPolys)
{ {
const dtMeshHeader* header = tile->header; const dtMeshHeader* header = tile->header;
@ -912,8 +918,11 @@ int dtNavMesh::queryTilePolygons(dtMeshTile* tile,
if (isLeafNode && overlap) if (isLeafNode && overlap)
{ {
if (n < maxPolys) if (passFilter(filter, header->polys[node->i].flags))
polys[n++] = base | (dtPolyRef)node->i; {
if (n < maxPolys)
polys[n++] = base | (dtPolyRef)node->i;
}
} }
if (overlap || isLeafNode) if (overlap || isLeafNode)
@ -948,15 +957,18 @@ int dtNavMesh::queryTilePolygons(dtMeshTile* tile,
} }
if (overlapBoxes(qmin,qmax, bmin,bmax)) if (overlapBoxes(qmin,qmax, bmin,bmax))
{ {
if (n < maxPolys) if (passFilter(filter, p->flags))
polys[n++] = base | (dtPolyRef)i; {
if (n < maxPolys)
polys[n++] = base | (dtPolyRef)i;
}
} }
} }
return n; return n;
} }
} }
int dtNavMesh::queryPolygons(const float* center, const float* extents, int dtNavMesh::queryPolygons(const float* center, const float* extents, dtQueryFilter* filter,
dtPolyRef* polys, const int maxPolys) dtPolyRef* polys, const int maxPolys)
{ {
float bmin[3], bmax[3]; float bmin[3], bmax[3];
@ -982,7 +994,7 @@ int dtNavMesh::queryPolygons(const float* center, const float* extents,
{ {
dtMeshTile* tile = getTileAt(x,y); dtMeshTile* tile = getTileAt(x,y);
if (!tile) continue; if (!tile) continue;
n += queryTilePolygons(tile, bmin, bmax, polys+n, maxPolys-n); n += queryTilePolygons(tile, bmin, bmax, filter, polys+n, maxPolys-n);
if (n >= maxPolys) return n; if (n >= maxPolys) return n;
} }
} }
@ -991,8 +1003,9 @@ int dtNavMesh::queryPolygons(const float* center, const float* extents,
} }
int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef, int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef,
const float* startPos, const float* endPos, const float* startPos, const float* endPos,
dtPolyRef* path, const int maxPathSize) dtQueryFilter* filter,
dtPolyRef* path, const int maxPathSize)
{ {
if (!startRef || !endRef) if (!startRef || !endRef)
return 0; return 0;
@ -1053,6 +1066,10 @@ int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef,
if (bestNode->pidx && m_nodePool->getNodeAtIdx(bestNode->pidx)->id == neighbour) if (bestNode->pidx && m_nodePool->getNodeAtIdx(bestNode->pidx)->id == neighbour)
continue; continue;
// TODO: Avoid digging the polygon (done in getEdgeMidPoint too).
if (!passFilter(filter, getPolyFlags(neighbour)))
continue;
dtNode* parent = bestNode; dtNode* parent = bestNode;
dtNode newNode; dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(parent); newNode.pidx = m_nodePool->getNodeIdx(parent);
@ -1064,7 +1081,9 @@ int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef,
vcopy(p0, startPos); vcopy(p0, startPos);
else else
getEdgeMidPoint(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, p0); getEdgeMidPoint(m_nodePool->getNodeAtIdx(parent->pidx)->id, parent->id, p0);
getEdgeMidPoint(parent->id, newNode.id, p1); getEdgeMidPoint(parent->id, newNode.id, p1);
newNode.cost = parent->cost + vdist(p0,p1); newNode.cost = parent->cost + vdist(p0,p1);
// Special case for last node. // Special case for last node.
if (newNode.id == endRef) if (newNode.id == endRef)
@ -1174,8 +1193,8 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
int leftIndex = 0; int leftIndex = 0;
int rightIndex = 0; int rightIndex = 0;
unsigned char leftPolyFlags = 0; unsigned short leftPolyFlags = 0;
unsigned char rightPolyFlags = 0; unsigned short rightPolyFlags = 0;
dtPolyRef leftPolyRef = path[0]; dtPolyRef leftPolyRef = path[0];
dtPolyRef rightPolyRef = path[0]; dtPolyRef rightPolyRef = path[0];
@ -1183,7 +1202,7 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
for (int i = 0; i < pathSize; ++i) for (int i = 0; i < pathSize; ++i)
{ {
float left[3], right[3]; float left[3], right[3];
unsigned char fromFlags, toFlags; unsigned short fromFlags, toFlags;
if (i+1 < pathSize) if (i+1 < pathSize)
{ {
@ -1382,7 +1401,7 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
if (n+1 < pathSize) if (n+1 < pathSize)
{ {
float left[3], right[3]; float left[3], right[3];
unsigned char fromFlags, toFlags; unsigned short fromFlags, toFlags;
if (!getPortalPoints(path[n], path[n+1], left, right, fromFlags, toFlags)) if (!getPortalPoints(path[n], path[n+1], left, right, fromFlags, toFlags))
return n; return n;
vcopy(resultPos, endPos); vcopy(resultPos, endPos);
@ -1426,7 +1445,7 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
if (n+1 >= pathSize) if (n+1 >= pathSize)
return n; return n;
float left[3], right[3]; float left[3], right[3];
unsigned char fromFlags, toFlags; unsigned short fromFlags, toFlags;
if (!getPortalPoints(path[n], path[n+1], left, right, fromFlags, toFlags)) if (!getPortalPoints(path[n], path[n+1], left, right, fromFlags, toFlags))
return n; return n;
// If the clamped point is close to the next portal edge, advance to next poly. // If the clamped point is close to the next portal edge, advance to next poly.
@ -1443,7 +1462,7 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
// Returns portal points between two polygons. // Returns portal points between two polygons.
bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right, bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right,
unsigned char& fromFlags, unsigned char& toFlags) const unsigned short& fromFlags, unsigned short& toFlags) const
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
dtDecodePolyId(from, salt, it, ip); dtDecodePolyId(from, salt, it, ip);
@ -1526,7 +1545,7 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
bool dtNavMesh::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const bool dtNavMesh::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const
{ {
float left[3], right[3]; float left[3], right[3];
unsigned char fromFlags, toFlags; unsigned short fromFlags, toFlags;
if (!getPortalPoints(from, to, left,right, fromFlags, toFlags)) return false; if (!getPortalPoints(from, to, left,right, fromFlags, toFlags)) return false;
mid[0] = (left[0]+right[0])*0.5f; mid[0] = (left[0]+right[0])*0.5f;
mid[1] = (left[1]+right[1])*0.5f; mid[1] = (left[1]+right[1])*0.5f;
@ -1534,7 +1553,19 @@ bool dtNavMesh::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const
return true; return true;
} }
int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float* endPos, unsigned short dtNavMesh::getPolyFlags(dtPolyRef ref)
{
unsigned int salt, it, ip;
dtDecodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return 0;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0;
const dtMeshHeader* header = m_tiles[it].header;
const dtPoly* poly = &header->polys[ip];
return poly->flags;
}
int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float* endPos, dtQueryFilter* filter,
float& t, float* hitNormal, dtPolyRef* path, const int pathSize) float& t, float* hitNormal, dtPolyRef* path, const int pathSize)
{ {
t = 0; t = 0;
@ -1638,7 +1669,7 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
} }
} }
if (!nextRef) if (!nextRef || !passFilter(filter, getPolyFlags(nextRef)))
{ {
// No neighbour, we hit a wall. // No neighbour, we hit a wall.
@ -1664,7 +1695,7 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
return n; return n;
} }
int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, float radius, int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, float radius, dtQueryFilter* filter,
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
const int maxResult) const int maxResult)
{ {
@ -1727,6 +1758,9 @@ int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, floa
// If the circle is not touching the next polygon, skip it. // If the circle is not touching the next polygon, skip it.
if (distSqr > radiusSqr) if (distSqr > radiusSqr)
continue; continue;
if (!passFilter(filter, getPolyFlags(neighbour)))
continue;
dtNode* parent = bestNode; dtNode* parent = bestNode;
dtNode newNode; dtNode newNode;
@ -1780,8 +1814,8 @@ int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, floa
return n; return n;
} }
float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius, float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius, dtQueryFilter* filter,
float* hitPos, float* hitNormal) float* hitPos, float* hitNormal)
{ {
if (!centerRef) return 0; if (!centerRef) return 0;
if (!getPolyByRef(centerRef)) return 0; if (!getPolyByRef(centerRef)) return 0;
@ -1822,7 +1856,7 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
for (int i = 0; i < poly->linkCount; ++i) for (int i = 0; i < poly->linkCount; ++i)
{ {
const dtLink* link = &header->links[poly->linkBase+i]; const dtLink* link = &header->links[poly->linkBase+i];
if (link->edge == j && link->ref != 0) if (link->edge == j && link->ref != 0 && passFilter(filter, getPolyFlags(link->ref)))
{ {
solid = false; solid = false;
break; break;
@ -1830,7 +1864,7 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
} }
if (!solid) continue; if (!solid) continue;
} }
else if (poly->neis[j]) else if (poly->neis[j] && passFilter(filter, getPolyFlags(poly->neis[j])))
{ {
// Internal edge // Internal edge
continue; continue;
@ -1874,6 +1908,9 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
if (distSqr > radiusSqr) if (distSqr > radiusSqr)
continue; continue;
if (!passFilter(filter, getPolyFlags(neighbour)))
continue;
dtNode* parent = bestNode; dtNode* parent = bestNode;
dtNode newNode; dtNode newNode;
newNode.pidx = m_nodePool->getNodeIdx(parent); newNode.pidx = m_nodePool->getNodeIdx(parent);

View File

@ -486,6 +486,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
{ {
dtPoly* p = &navPolys[i]; dtPoly* p = &navPolys[i];
p->vertCount = 0; p->vertCount = 0;
p->flags = DT_POLY_GROUND;
for (int j = 0; j < nvp; ++j) for (int j = 0; j < nvp; ++j)
{ {
if (src[j] == 0xffff) break; if (src[j] == 0xffff) break;

File diff suppressed because it is too large Load Diff

View File

@ -281,14 +281,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>11</integer> <integer>13</integer>
<integer>3</integer> <integer>12</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 45}, {282, 643}}</string> <string>{{0, 41}, {282, 643}}</string>
</dict> </dict>
<key>PBXTopSmartGroupGIDs</key> <key>PBXTopSmartGroupGIDs</key>
<array/> <array/>
@ -323,7 +323,7 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>DetourDebugDraw.cpp</string> <string>DetourNavMesh.h</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
<dict> <dict>
<key>Split0</key> <key>Split0</key>
@ -331,11 +331,11 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string> <string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>DetourDebugDraw.cpp</string> <string>DetourNavMesh.h</string>
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>6BCF34AF1105F8DB009445BF</string> <string>6BCF34F411060322009445BF</string>
<key>history</key> <key>history</key>
<array> <array>
<string>6B57D358108C66B200DDD053</string> <string>6B57D358108C66B200DDD053</string>
@ -360,7 +360,6 @@
<string>6BB3605210FE5CBD00A9B4B8</string> <string>6BB3605210FE5CBD00A9B4B8</string>
<string>6BB3606210FE5E8F00A9B4B8</string> <string>6BB3606210FE5E8F00A9B4B8</string>
<string>6B69736710FFBDCA00984788</string> <string>6B69736710FFBDCA00984788</string>
<string>6B69736810FFBDCA00984788</string>
<string>6B69739F10FFCA4500984788</string> <string>6B69739F10FFCA4500984788</string>
<string>6BCF325E1104CFE7009445BF</string> <string>6BCF325E1104CFE7009445BF</string>
<string>6BCF325F1104CFE7009445BF</string> <string>6BCF325F1104CFE7009445BF</string>
@ -379,15 +378,16 @@
<string>6BCF343A1105ECAB009445BF</string> <string>6BCF343A1105ECAB009445BF</string>
<string>6BCF34441105ECEB009445BF</string> <string>6BCF34441105ECEB009445BF</string>
<string>6BCF34691105EF2D009445BF</string> <string>6BCF34691105EF2D009445BF</string>
<string>6BCF347A1105F519009445BF</string>
<string>6BCF347B1105F519009445BF</string>
<string>6BCF34831105F555009445BF</string> <string>6BCF34831105F555009445BF</string>
<string>6BCF34901105F821009445BF</string> <string>6BCF34901105F821009445BF</string>
<string>6BCF34911105F821009445BF</string> <string>6BCF34911105F821009445BF</string>
<string>6BCF34A41105F894009445BF</string> <string>6BCF34A41105F894009445BF</string>
<string>6BCF34A51105F894009445BF</string> <string>6BCF34B01105FA03009445BF</string>
<string>6BCF34AC1105F8DB009445BF</string> <string>6BCF34B11105FA03009445BF</string>
<string>6BCF34AD1105F8DB009445BF</string> <string>6BCF34E2110602BB009445BF</string>
<string>6BCF34E3110602BB009445BF</string>
<string>6BCF34F111060322009445BF</string>
<string>6BCF34F211060322009445BF</string>
</array> </array>
<key>prevStack</key> <key>prevStack</key>
<array> <array>
@ -605,6 +605,40 @@
<string>6BCF34A81105F894009445BF</string> <string>6BCF34A81105F894009445BF</string>
<string>6BCF34A91105F894009445BF</string> <string>6BCF34A91105F894009445BF</string>
<string>6BCF34AE1105F8DB009445BF</string> <string>6BCF34AE1105F8DB009445BF</string>
<string>6BCF34B31105FA03009445BF</string>
<string>6BCF34B41105FA03009445BF</string>
<string>6BCF34B51105FA03009445BF</string>
<string>6BCF34BE1105FD0F009445BF</string>
<string>6BCF34BF1105FD0F009445BF</string>
<string>6BCF34C01105FD0F009445BF</string>
<string>6BCF34C11105FD0F009445BF</string>
<string>6BCF34C21105FD0F009445BF</string>
<string>6BCF34C31105FD0F009445BF</string>
<string>6BCF34C41105FD0F009445BF</string>
<string>6BCF34C51105FD0F009445BF</string>
<string>6BCF34C61105FD0F009445BF</string>
<string>6BCF34C71105FD0F009445BF</string>
<string>6BCF34C81105FD0F009445BF</string>
<string>6BCF34C91105FD0F009445BF</string>
<string>6BCF34CA1105FD0F009445BF</string>
<string>6BCF34CB1105FD0F009445BF</string>
<string>6BCF34CC1105FD0F009445BF</string>
<string>6BCF34D01105FF32009445BF</string>
<string>6BCF34D11105FF32009445BF</string>
<string>6BCF34D21105FF32009445BF</string>
<string>6BCF34D31105FF32009445BF</string>
<string>6BCF34E5110602BB009445BF</string>
<string>6BCF34E6110602BB009445BF</string>
<string>6BCF34E7110602BB009445BF</string>
<string>6BCF34E8110602BB009445BF</string>
<string>6BCF34E9110602BB009445BF</string>
<string>6BCF34EA110602BB009445BF</string>
<string>6BCF34EB110602BB009445BF</string>
<string>6BCF34EC110602BB009445BF</string>
<string>6BCF34ED110602BB009445BF</string>
<string>6BCF34EE110602BB009445BF</string>
<string>6BCF34EF110602BB009445BF</string>
<string>6BCF34F311060322009445BF</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -618,18 +652,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {952, 562}}</string> <string>{{0, 0}, {952, 547}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string> <string>11 76 1256 702 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXNavigatorGroup</string> <string>PBXNavigatorGroup</string>
<key>Proportion</key> <key>Proportion</key>
<string>562pt</string> <string>547pt</string>
</dict> </dict>
<dict> <dict>
<key>Proportion</key> <key>Proportion</key>
<string>94pt</string> <string>109pt</string>
<key>Tabs</key> <key>Tabs</key>
<array> <array>
<dict> <dict>
@ -697,7 +731,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {952, 67}}</string> <string>{{10, 27}, {952, 82}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string> <string>11 76 1256 702 0 0 1280 778 </string>
</dict> </dict>

View File

@ -31,6 +31,8 @@ class NavMeshTesterTool : public SampleTool
float m_agentHeight; float m_agentHeight;
float m_agentClimb; float m_agentClimb;
dtQueryFilter m_filter;
enum ToolMode enum ToolMode
{ {
TOOLMODE_PATHFIND, TOOLMODE_PATHFIND,

View File

@ -59,6 +59,9 @@ NavMeshTesterTool::NavMeshTesterTool() :
m_sposSet(false), m_sposSet(false),
m_eposSet(false) m_eposSet(false)
{ {
m_filter.includeFlags = DT_POLY_GROUND | DT_POLY_OFFMESH_CONNECTION;
m_filter.excludeFlags = 0;
m_polyPickExt[0] = 2; m_polyPickExt[0] = 2;
m_polyPickExt[1] = 4; m_polyPickExt[1] = 4;
m_polyPickExt[2] = 2; m_polyPickExt[2] = 2;
@ -117,6 +120,34 @@ void NavMeshTesterTool::handleMenu()
recalc(); recalc();
} }
imguiSeparator();
imguiLabel("Include Flags");
if (imguiCheck("Ground", m_filter.includeFlags & DT_POLY_GROUND))
{
m_filter.includeFlags ^= DT_POLY_GROUND;
recalc();
}
if (imguiCheck("Off-Mesh Connections", m_filter.includeFlags & DT_POLY_OFFMESH_CONNECTION))
{
m_filter.includeFlags ^= DT_POLY_OFFMESH_CONNECTION;
recalc();
}
imguiLabel("Exclude Flags");
if (imguiCheck("Ground", m_filter.excludeFlags & DT_POLY_GROUND))
{
m_filter.excludeFlags ^= DT_POLY_GROUND;
recalc();
}
if (imguiCheck("Off-Mesh Connections", m_filter.excludeFlags & DT_POLY_OFFMESH_CONNECTION))
{
m_filter.excludeFlags ^= DT_POLY_OFFMESH_CONNECTION;
recalc();
}
if (m_toolMode == TOOLMODE_PATHFIND) if (m_toolMode == TOOLMODE_PATHFIND)
{ {
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST; unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
@ -203,12 +234,12 @@ void NavMeshTesterTool::recalc()
return; return;
if (m_sposSet) if (m_sposSet)
m_startRef = m_navMesh->findNearestPoly(m_spos, m_polyPickExt, 0); m_startRef = m_navMesh->findNearestPoly(m_spos, m_polyPickExt, &m_filter, 0);
else else
m_startRef = 0; m_startRef = 0;
if (m_eposSet) if (m_eposSet)
m_endRef = m_navMesh->findNearestPoly(m_epos, m_polyPickExt, 0); m_endRef = m_navMesh->findNearestPoly(m_epos, m_polyPickExt, &m_filter, 0);
else else
m_endRef = 0; m_endRef = 0;
@ -216,7 +247,7 @@ void NavMeshTesterTool::recalc()
{ {
if (m_sposSet && m_eposSet && m_startRef && m_endRef) if (m_sposSet && m_eposSet && m_startRef && m_endRef)
{ {
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, m_polys, MAX_POLYS); m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
m_nstraightPath = 0; m_nstraightPath = 0;
m_nsmoothPath = 0; m_nsmoothPath = 0;
@ -224,7 +255,8 @@ void NavMeshTesterTool::recalc()
if (m_npolys) if (m_npolys)
{ {
m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys, m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys,
m_straightPath, m_straightPathFlags, m_straightPathPolys, MAX_POLYS); m_straightPath, m_straightPathFlags,
m_straightPathPolys, MAX_POLYS);
// Iterate over the path to find smooth path on the detail mesh surface. // Iterate over the path to find smooth path on the detail mesh surface.
@ -364,7 +396,7 @@ void NavMeshTesterTool::recalc()
m_straightPath[1] = m_spos[1]; m_straightPath[1] = m_spos[1];
m_straightPath[2] = m_spos[2]; m_straightPath[2] = m_spos[2];
vcopy(m_hitPos, m_epos); vcopy(m_hitPos, m_epos);
m_npolys = m_navMesh->raycast(m_startRef, m_spos, m_epos, t, m_hitNormal, m_polys, MAX_POLYS); m_npolys = m_navMesh->raycast(m_startRef, m_spos, m_epos, &m_filter, t, m_hitNormal, m_polys, MAX_POLYS);
if (m_npolys && t < 1) if (m_npolys && t < 1)
{ {
m_hitPos[0] = m_spos[0] + (m_epos[0] - m_spos[0]) * t; m_hitPos[0] = m_spos[0] + (m_epos[0] - m_spos[0]) * t;
@ -378,7 +410,7 @@ void NavMeshTesterTool::recalc()
{ {
m_distanceToWall = 0; m_distanceToWall = 0;
if (m_sposSet && m_startRef) if (m_sposSet && m_startRef)
m_distanceToWall = m_navMesh->findDistanceToWall(m_startRef, m_spos, 100.0f, m_hitPos, m_hitNormal); m_distanceToWall = m_navMesh->findDistanceToWall(m_startRef, m_spos, 100.0f, &m_filter, m_hitPos, m_hitNormal);
} }
else if (m_toolMode == TOOLMODE_FIND_POLYS_AROUND) else if (m_toolMode == TOOLMODE_FIND_POLYS_AROUND)
{ {
@ -387,7 +419,7 @@ void NavMeshTesterTool::recalc()
const float dx = m_epos[0] - m_spos[0]; const float dx = m_epos[0] - m_spos[0];
const float dz = m_epos[2] - m_spos[2]; const float dz = m_epos[2] - m_spos[2];
float dist = sqrtf(dx*dx + dz*dz); float dist = sqrtf(dx*dx + dz*dz);
m_npolys = m_navMesh->findPolysAround(m_startRef, m_spos, dist, m_polys, m_parent, 0, MAX_POLYS); m_npolys = m_navMesh->findPolysAround(m_startRef, m_spos, dist, &m_filter, m_polys, m_parent, 0, MAX_POLYS);
} }
} }
} }