Missing changes from previous commit. Added dtNavMesh.findLocalNeighbourhood() and dtNavMesh.getPolyWallSegments() and test code for them.
This commit is contained in:
parent
1c4755012f
commit
81c0402116
@ -385,7 +385,7 @@ static void calcRect(const float* va, const float* vb,
|
||||
static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
|
||||
{
|
||||
// Draw portals
|
||||
const float padx = 0.01f;
|
||||
const float padx = 0.02f;
|
||||
const float pady = tile->header->walkableClimb;
|
||||
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
@ -414,7 +414,7 @@ static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
|
||||
{
|
||||
unsigned int col = side == 0 ? duRGBA(128,0,0,128) : duRGBA(128,0,128,128);
|
||||
|
||||
const float x = va[0] + ((side == 0) ? -0.02f : 0.02f);
|
||||
const float x = va[0] + ((side == 0) ? -padx : padx);
|
||||
|
||||
dd->vertex(x,va[1]-pady,va[2], col);
|
||||
dd->vertex(x,va[1]+pady,va[2], col);
|
||||
@ -450,7 +450,7 @@ static void drawMeshTilePortal(duDebugDraw* dd, const dtMeshTile* tile)
|
||||
{
|
||||
unsigned int col = side == 2 ? duRGBA(0,128,0,128) : duRGBA(0,128,128,128);
|
||||
|
||||
const float z = va[2] + ((side == 2) ? -0.02f : 0.02f);
|
||||
const float z = va[2] + ((side == 2) ? -padx : padx);
|
||||
|
||||
dd->vertex(va[0],va[1]-pady,z, col);
|
||||
dd->vertex(va[0],va[1]+pady,z, col);
|
||||
|
@ -201,6 +201,8 @@ bool dtIntersectSegmentPoly2D(const float* p0, const float* p1,
|
||||
float& tmin, float& tmax,
|
||||
int& segMin, int& segMax);
|
||||
|
||||
bool dtPointInPolygon(const float* pt, const float* verts, const int nverts);
|
||||
|
||||
bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts,
|
||||
float* ed, float* et);
|
||||
|
||||
@ -208,4 +210,7 @@ float dtDistancePtSegSqr2D(const float* pt, const float* p, const float* q, floa
|
||||
|
||||
void dtCalcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* verts);
|
||||
|
||||
bool dtOverlapPolyPoly2D(const float* polya, const int npolya,
|
||||
const float* polyb, const int npolyb);
|
||||
|
||||
#endif // DETOURCOMMON_H
|
@ -324,19 +324,24 @@ public:
|
||||
const dtPolyRef* path, const int pathSize,
|
||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||
const int maxStraightPathSize) const;
|
||||
|
||||
// Moves towards end position a long the path corridor.
|
||||
// The start location is assumed to be roughly at inside the first polygon on the path.
|
||||
// The return value can be used to advance the path pointer along the path.
|
||||
|
||||
// Moves from startPos to endPos constrained to the navmesh.
|
||||
// If the endPos is reachable, the resultPos will be endPos,
|
||||
// or else the resultPos will be the nearest point in navmesh.
|
||||
// Note: The resulting point is not projected to the ground, use getPolyHeight() to get height.
|
||||
// Note: The algorithm is optimized for small delta movement and small number of polygons.
|
||||
// Params:
|
||||
// startPos[3] - (in) current position of the agent.
|
||||
// endPos[3] - (in) new position of the agent.
|
||||
// resultPos[3] - (out) new positio after the move, constrained to be inside the path polygons.
|
||||
// path - (in) remainder of the path to follow.
|
||||
// pathSize - (in) number of polygons on the path.
|
||||
// Returns: Index to the path polygon where the result position lies.
|
||||
int moveAlongPathCorridor(const float* startPos, const float* endPos, float* resultPos,
|
||||
const dtPolyRef* path, const int pathSize) const;
|
||||
// startRef - (in) ref to the polygon where startPos lies.
|
||||
// startPos[3] - (in) start position of the mover.
|
||||
// endPos[3] - (in) desired end position of the mover.
|
||||
// filter - (in) path polygon filter.
|
||||
// resultPos[3] - (out) new position of the mover.
|
||||
// visited - (out) array of visited polygons.
|
||||
// maxVisitedSize - (in) max number of polygons in the visited array.
|
||||
// Returns: Number of entries in the visited array.
|
||||
int moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter,
|
||||
float* resultPos, dtPolyRef* visited, const int maxVisitedSize) const;
|
||||
|
||||
// Casts 'walkability' ray along the navmesh surface from startPos towards the endPos.
|
||||
// Params:
|
||||
@ -375,7 +380,7 @@ public:
|
||||
// resultCost - (out, opt) search cost at each result polygon.
|
||||
// maxResult - (int) maximum capacity of search results.
|
||||
// Returns: Number of results.
|
||||
int findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, float radius,
|
||||
int findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
|
||||
const int maxResult) const;
|
||||
@ -396,6 +401,29 @@ public:
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
|
||||
const int maxResult) const;
|
||||
|
||||
// Finds non-overlapping local neighbourhood around center location.
|
||||
// Note: The algorithm is optimized for small query radius and small number of polygons.
|
||||
// Params:
|
||||
// startRef - (in) ref to the polygon where the search starts.
|
||||
// centerPos[3] - (in) center if the query circle.
|
||||
// radius - (in) radius of the query circle.
|
||||
// filter - (in) path polygon filter.
|
||||
// resultRef - (out) refs to the polygons touched by the circle.
|
||||
// resultParent - (out, opt) parent of each result polygon.
|
||||
// maxResult - (int) maximum capacity of search results.
|
||||
// Returns: Number of results.
|
||||
int findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, const int maxResult) const;
|
||||
|
||||
// Returns wall segments of specified polygon.
|
||||
// Params:
|
||||
// ref - (in) ref to the polygon.
|
||||
// filter - (in) path polygon filter.
|
||||
// segments[DT_VERTS_PER_POLYGON*3*2] - (out) wall segments.
|
||||
// Returns: Number of wall segments.
|
||||
int getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, float* segments);
|
||||
|
||||
// Returns closest point on navigation polygon.
|
||||
// Uses detail polygons to find the closest point to the navigation polygon surface.
|
||||
// Params:
|
||||
@ -561,6 +589,7 @@ private:
|
||||
|
||||
float m_areaCost[DT_MAX_AREAS]; // Cost per area.
|
||||
|
||||
class dtNodePool* m_tinyNodePool; // Pointer to node pool.
|
||||
class dtNodePool* m_nodePool; // Pointer to node pool.
|
||||
class dtNodeQueue* m_openList; // Pointer to open list queue.
|
||||
};
|
||||
|
@ -238,6 +238,22 @@ bool dtClosestHeightPointTriangle(const float* p, const float* a, const float* b
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dtPointInPolygon(const float* pt, const float* verts, const int nverts)
|
||||
{
|
||||
// TODO: Replace pnpoly with triArea2D tests?
|
||||
int i, j;
|
||||
bool c = false;
|
||||
for (i = 0, j = nverts-1; i < nverts; j = i++)
|
||||
{
|
||||
const float* vi = &verts[i*3];
|
||||
const float* vj = &verts[j*3];
|
||||
if (((vi[2] > pt[2]) != (vj[2] > pt[2])) &&
|
||||
(pt[0] < (vj[0]-vi[0]) * (pt[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
|
||||
c = !c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts,
|
||||
float* ed, float* et)
|
||||
{
|
||||
@ -255,3 +271,59 @@ bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nve
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static void projectPoly(const float* axis, const float* poly, const int npoly,
|
||||
float& rmin, float& rmax)
|
||||
{
|
||||
rmin = rmax = dtVdot2D(axis, &poly[0]);
|
||||
for (int i = 1; i < npoly; ++i)
|
||||
{
|
||||
const float d = dtVdot2D(axis, &poly[i*3]);
|
||||
rmin = dtMin(rmin, d);
|
||||
rmax = dtMax(rmax, d);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool overlapRange(const float amin, const float amax,
|
||||
const float bmin, const float bmax,
|
||||
const float eps)
|
||||
{
|
||||
return ((amin+eps) > bmax || (amax-eps) < bmin) ? false : true;
|
||||
}
|
||||
|
||||
bool dtOverlapPolyPoly2D(const float* polya, const int npolya,
|
||||
const float* polyb, const int npolyb)
|
||||
{
|
||||
const float eps = 1e-4f;
|
||||
|
||||
for (int i = 0, j = npolya-1; i < npolya; j=i++)
|
||||
{
|
||||
const float* va = &polya[j*3];
|
||||
const float* vb = &polya[i*3];
|
||||
const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) };
|
||||
float amin,amax,bmin,bmax;
|
||||
projectPoly(n, polya, npolya, amin,amax);
|
||||
projectPoly(n, polyb, npolyb, bmin,bmax);
|
||||
if (!overlapRange(amin,amax, bmin,bmax, eps))
|
||||
{
|
||||
// Found separating axis
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0, j = npolyb-1; i < npolyb; j=i++)
|
||||
{
|
||||
const float* va = &polyb[j*3];
|
||||
const float* vb = &polyb[i*3];
|
||||
const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) };
|
||||
float amin,amax,bmin,bmax;
|
||||
projectPoly(n, polya, npolya, amin,amax);
|
||||
projectPoly(n, polyb, npolyb, bmin,bmax);
|
||||
if (!overlapRange(amin,amax, bmin,bmax, eps))
|
||||
{
|
||||
// Found separating axis
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,7 @@ dtNavMesh::dtNavMesh() :
|
||||
m_saltBits(0),
|
||||
m_tileBits(0),
|
||||
m_polyBits(0),
|
||||
m_tinyNodePool(0),
|
||||
m_nodePool(0),
|
||||
m_openList(0)
|
||||
{
|
||||
@ -198,8 +199,10 @@ dtNavMesh::~dtNavMesh()
|
||||
m_tiles[i].dataSize = 0;
|
||||
}
|
||||
}
|
||||
m_tinyNodePool->~dtNodePool();
|
||||
m_nodePool->~dtNodePool();
|
||||
m_openList->~dtNodeQueue();
|
||||
dtFree(m_tinyNodePool);
|
||||
dtFree(m_nodePool);
|
||||
dtFree(m_openList);
|
||||
dtFree(m_posLookup);
|
||||
@ -242,6 +245,13 @@ bool dtNavMesh::init(const dtNavMeshParams* params)
|
||||
if (!m_nodePool)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_tinyNodePool)
|
||||
{
|
||||
m_tinyNodePool = new (dtAlloc(sizeof(dtNodePool), DT_ALLOC_PERM)) dtNodePool(64, 32);
|
||||
if (!m_tinyNodePool)
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: check the open list size too.
|
||||
if (!m_openList)
|
||||
@ -1762,100 +1772,170 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
|
||||
return straightPathSize;
|
||||
}
|
||||
|
||||
// Moves towards end position a long the path corridor.
|
||||
// Returns: Index to the result path polygon.
|
||||
int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos, float* resultPos,
|
||||
const dtPolyRef* path, const int pathSize) const
|
||||
int dtNavMesh::moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter,
|
||||
float* resultPos, dtPolyRef* visited, const int maxVisitedSize) const
|
||||
{
|
||||
if (!pathSize)
|
||||
return 0;
|
||||
|
||||
float verts[DT_VERTS_PER_POLYGON*3];
|
||||
float edged[DT_VERTS_PER_POLYGON];
|
||||
float edget[DT_VERTS_PER_POLYGON];
|
||||
int n = 0;
|
||||
|
||||
static const float SLOP = 0.01f;
|
||||
if (!startRef) return 0;
|
||||
if (!getPolyByRef(startRef)) return 0;
|
||||
if (!m_tinyNodePool) return 0;
|
||||
|
||||
dtVcopy(resultPos, startPos);
|
||||
static const int MAX_STACK = 48;
|
||||
dtNode* stack[MAX_STACK];
|
||||
int nstack = 0;
|
||||
|
||||
while (n < pathSize)
|
||||
{
|
||||
// Get current polygon and poly vertices.
|
||||
unsigned int salt, it, ip;
|
||||
decodePolyId(path[n], salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return n;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return n;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return n;
|
||||
const dtMeshTile* tile = &m_tiles[it];
|
||||
const dtPoly* poly = &tile->polys[ip];
|
||||
m_tinyNodePool->clear();
|
||||
|
||||
dtNode* startNode = m_tinyNodePool->getNode(startRef);
|
||||
startNode->pidx = 0;
|
||||
startNode->cost = 0;
|
||||
startNode->total = 0;
|
||||
startNode->id = startRef;
|
||||
startNode->flags = DT_NODE_CLOSED;
|
||||
stack[nstack++] = startNode;
|
||||
|
||||
// In case of Off-Mesh link, just snap to the end location and advance over it.
|
||||
if (poly->type == DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||
{
|
||||
if (n+1 < pathSize)
|
||||
{
|
||||
float left[3], right[3];
|
||||
unsigned char fromType, toType;
|
||||
if (!getPortalPoints(path[n], path[n+1], left, right, fromType, toType))
|
||||
return n;
|
||||
dtVcopy(resultPos, endPos);
|
||||
}
|
||||
return n+1;
|
||||
}
|
||||
float bestPos[3];
|
||||
float bestDist = FLT_MAX;
|
||||
dtNode* bestNode = 0;
|
||||
dtVcopy(bestPos, startPos);
|
||||
|
||||
// Search constraints
|
||||
float searchPos[3], searchRadSqr;
|
||||
dtVlerp(searchPos, startPos, endPos, 0.5f);
|
||||
searchRadSqr = dtSqr(dtVdist(startPos, endPos)/2.0f + 0.001f);
|
||||
|
||||
unsigned int it, ip;
|
||||
float verts[DT_VERTS_PER_POLYGON*3];
|
||||
|
||||
while (nstack)
|
||||
{
|
||||
// Pop front.
|
||||
dtNode* curNode = stack[0];
|
||||
for (int i = 0; i < nstack-1; ++i)
|
||||
stack[i] = stack[i+1];
|
||||
nstack--;
|
||||
|
||||
// Get poly and tile.
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
const dtPolyRef curRef = curNode->id;
|
||||
it = decodePolyIdTile(curRef);
|
||||
ip = decodePolyIdPoly(curRef);
|
||||
const dtMeshTile* curTile = &m_tiles[it];
|
||||
const dtPoly* curPoly = &curTile->polys[ip];
|
||||
|
||||
// Collect vertices.
|
||||
int nv = 0;
|
||||
for (int i = 0; i < (int)poly->vertCount; ++i)
|
||||
const int nverts = curPoly->vertCount;
|
||||
for (int i = 0; i < nverts; ++i)
|
||||
dtVcopy(&verts[i*3], &curTile->verts[curPoly->verts[i]*3]);
|
||||
|
||||
// If target is inside the poly, stop search.
|
||||
if (dtPointInPolygon(endPos, verts, nverts))
|
||||
{
|
||||
dtVcopy(&verts[nv*3], &tile->verts[poly->verts[i]*3]);
|
||||
nv++;
|
||||
bestNode = curNode;
|
||||
dtVcopy(bestPos, endPos);
|
||||
break;
|
||||
}
|
||||
|
||||
const bool inside = dtDistancePtPolyEdgesSqr(endPos, verts, nv, edged, edget);
|
||||
if (inside)
|
||||
// Find wall edges and find nearest point inside the walls.
|
||||
for (int i = 0, j = (int)curPoly->vertCount-1; i < (int)curPoly->vertCount; j = i++)
|
||||
{
|
||||
// The end point is inside the current polygon.
|
||||
dtVcopy(resultPos, endPos);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Constraint the point on the polygon boundary.
|
||||
// This results sliding movement.
|
||||
float dmin = FLT_MAX;
|
||||
int imin = -1;
|
||||
for (int i = 0; i < nv; ++i)
|
||||
{
|
||||
if (edged[i] < dmin)
|
||||
// Skip non-solid edges.
|
||||
dtPolyRef neighbourRef = 0;
|
||||
if (curPoly->neis[j] & DT_EXT_LINK)
|
||||
{
|
||||
dmin = edged[i];
|
||||
imin = i;
|
||||
// Tile border.
|
||||
for (unsigned int k = curPoly->firstLink; k != DT_NULL_LINK; k = curTile->links[k].next)
|
||||
{
|
||||
const dtLink* link = &curTile->links[k];
|
||||
if (link->edge == j)
|
||||
{
|
||||
if (link->ref != 0 && passFilter(filter, getPolyFlags(link->ref)))
|
||||
neighbourRef = link->ref;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (curPoly->neis[j] && passFilter(filter, curTile->polys[curPoly->neis[j]-1].flags))
|
||||
{
|
||||
// Internal edge, encode id.
|
||||
neighbourRef = getTilePolyRefBase(curTile) | (unsigned int)(curPoly->neis[j]-1);
|
||||
}
|
||||
|
||||
if (!neighbourRef)
|
||||
{
|
||||
// Wall edge, calc distance.
|
||||
const float* vj = &verts[j*3];
|
||||
const float* vi = &verts[i*3];
|
||||
float tseg;
|
||||
const float distSqr = dtDistancePtSegSqr2D(endPos, vj, vi, tseg);
|
||||
if (distSqr < bestDist)
|
||||
{
|
||||
// Update nearest distance.
|
||||
dtVlerp(bestPos, vj,vi, tseg);
|
||||
bestDist = distSqr;
|
||||
bestNode = curNode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip if no node can be allocated.
|
||||
dtNode* neighbourNode = m_tinyNodePool->getNode(neighbourRef);
|
||||
if (!neighbourNode)
|
||||
continue;
|
||||
// Skip if already visited.
|
||||
if (neighbourNode->flags & DT_NODE_CLOSED)
|
||||
continue;
|
||||
|
||||
// Skip the link if it is too far from search constraint.
|
||||
const float* vj = &verts[j*3];
|
||||
const float* vi = &verts[i*3];
|
||||
float tseg;
|
||||
float distSqr = dtDistancePtSegSqr2D(searchPos, vj, vi, tseg);
|
||||
if (distSqr > searchRadSqr)
|
||||
continue;
|
||||
|
||||
// Mark as the node as visited and push to queue.
|
||||
if (nstack < MAX_STACK)
|
||||
{
|
||||
neighbourNode->pidx = m_tinyNodePool->getNodeIdx(curNode);
|
||||
neighbourNode->flags |= DT_NODE_CLOSED;
|
||||
stack[nstack++] = neighbourNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
const float* va = &verts[imin*3];
|
||||
const float* vb = &verts[((imin+1)%nv)*3];
|
||||
dtVlerp(resultPos, va, vb, edget[imin]);
|
||||
|
||||
// Check to see if the point is on the portal edge to the next polygon.
|
||||
if (n+1 >= pathSize)
|
||||
return n;
|
||||
// TODO: optimize
|
||||
float left[3], right[3];
|
||||
unsigned char fromType, toType;
|
||||
if (!getPortalPoints(path[n], path[n+1], left, right, fromType, toType))
|
||||
return n;
|
||||
// If the dtClamped point is close to the next portal edge, advance to next poly.
|
||||
float t;
|
||||
const float d = dtDistancePtSegSqr2D(resultPos, left, right, t);
|
||||
if (d > SLOP*SLOP)
|
||||
return n;
|
||||
// Advance to next polygon.
|
||||
n++;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
if (bestNode)
|
||||
{
|
||||
// Reverse the path.
|
||||
dtNode* prev = 0;
|
||||
dtNode* node = bestNode;
|
||||
do
|
||||
{
|
||||
dtNode* next = m_tinyNodePool->getNodeAtIdx(node->pidx);
|
||||
node->pidx = m_tinyNodePool->getNodeIdx(prev);
|
||||
prev = node;
|
||||
node = next;
|
||||
}
|
||||
while (node);
|
||||
|
||||
// Store result
|
||||
node = prev;
|
||||
do
|
||||
{
|
||||
visited[n++] = node->id;
|
||||
node = m_tinyNodePool->getNodeAtIdx(node->pidx);
|
||||
}
|
||||
while (node && n < maxVisitedSize);
|
||||
}
|
||||
|
||||
dtVcopy(resultPos, bestPos);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right,
|
||||
unsigned char& fromType, unsigned char& toType) const
|
||||
{
|
||||
@ -2198,7 +2278,8 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
return n;
|
||||
}
|
||||
|
||||
int dtNavMesh::findPolysAroundCircle(dtPolyRef centerRef, const float* centerPos, float radius, const dtQueryFilter* filter,
|
||||
int dtNavMesh::findPolysAroundCircle(dtPolyRef centerRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
|
||||
const int maxResult) const
|
||||
{
|
||||
@ -2497,6 +2578,217 @@ int dtNavMesh::findPolysAroundShape(dtPolyRef centerRef, const float* verts, con
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int dtNavMesh::findLocalNeighbourhood(dtPolyRef centerRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, const int maxResult) const
|
||||
{
|
||||
if (!centerRef) return 0;
|
||||
if (!getPolyByRef(centerRef)) return 0;
|
||||
if (!m_tinyNodePool) return 0;
|
||||
|
||||
static const int MAX_STACK = 48;
|
||||
dtNode* stack[MAX_STACK];
|
||||
int nstack = 0;
|
||||
|
||||
m_tinyNodePool->clear();
|
||||
|
||||
dtNode* startNode = m_tinyNodePool->getNode(centerRef);
|
||||
startNode->pidx = 0;
|
||||
startNode->id = centerRef;
|
||||
startNode->flags = DT_NODE_CLOSED;
|
||||
stack[nstack++] = startNode;
|
||||
|
||||
const float radiusSqr = dtSqr(radius);
|
||||
|
||||
float pa[DT_VERTS_PER_POLYGON*3];
|
||||
float pb[DT_VERTS_PER_POLYGON*3];
|
||||
unsigned int it, ip;
|
||||
|
||||
int n = 0;
|
||||
if (n < maxResult)
|
||||
{
|
||||
resultRef[n] = startNode->id;
|
||||
if (resultParent)
|
||||
resultParent[n] = 0;
|
||||
++n;
|
||||
}
|
||||
|
||||
while (nstack)
|
||||
{
|
||||
// Pop front.
|
||||
dtNode* curNode = stack[0];
|
||||
for (int i = 0; i < nstack-1; ++i)
|
||||
stack[i] = stack[i+1];
|
||||
nstack--;
|
||||
|
||||
// Get poly and tile.
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
const dtPolyRef curRef = curNode->id;
|
||||
it = decodePolyIdTile(curRef);
|
||||
ip = decodePolyIdPoly(curRef);
|
||||
const dtMeshTile* curTile = &m_tiles[it];
|
||||
const dtPoly* curPoly = &curTile->polys[ip];
|
||||
|
||||
for (unsigned int i = curPoly->firstLink; i != DT_NULL_LINK; i = curTile->links[i].next)
|
||||
{
|
||||
const dtLink* link = &curTile->links[i];
|
||||
dtPolyRef neighbourRef = link->ref;
|
||||
// Skip invalid neighbours.
|
||||
if (!neighbourRef)
|
||||
continue;
|
||||
|
||||
// Skip if cannot alloca more nodes.
|
||||
dtNode* neighbourNode = m_tinyNodePool->getNode(neighbourRef);
|
||||
if (!neighbourNode)
|
||||
continue;
|
||||
// Skip visited.
|
||||
if (neighbourNode->flags & DT_NODE_CLOSED)
|
||||
continue;
|
||||
|
||||
// Expand to neighbour
|
||||
it = decodePolyIdTile(neighbourRef);
|
||||
ip = decodePolyIdPoly(neighbourRef);
|
||||
const dtMeshTile* neighbourTile = &m_tiles[it];
|
||||
const dtPoly* neighbourPoly = &neighbourTile->polys[ip];
|
||||
|
||||
// Skip off-mesh connections.
|
||||
if (neighbourPoly->type == DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||
continue;
|
||||
|
||||
// Do not advance if the polygon is excluded by the filter.
|
||||
if (!passFilter(filter, neighbourPoly->flags))
|
||||
continue;
|
||||
|
||||
// Find edge and calc distance to the edge.
|
||||
float va[3], vb[3];
|
||||
if (!getPortalPoints(curRef, curPoly, curTile, neighbourRef, neighbourPoly, neighbourTile, va, vb))
|
||||
continue;
|
||||
|
||||
// If the circle is not touching the next polygon, skip it.
|
||||
float tseg;
|
||||
float distSqr = dtDistancePtSegSqr2D(centerPos, va, vb, tseg);
|
||||
if (distSqr > radiusSqr)
|
||||
continue;
|
||||
|
||||
// Mark node visited, this is done before the overlap test so that
|
||||
// we will not visit the poly again if the test fails.
|
||||
neighbourNode->flags |= DT_NODE_CLOSED;
|
||||
neighbourNode->pidx = m_tinyNodePool->getNodeIdx(curNode);
|
||||
|
||||
// Check that the polygon does not collide with existing polygons.
|
||||
|
||||
// Collect vertices of the neighbour poly.
|
||||
const int npa = neighbourPoly->vertCount;
|
||||
for (int k = 0; k < npa; ++k)
|
||||
dtVcopy(&pa[k*3], &neighbourTile->verts[neighbourPoly->verts[k]*3]);
|
||||
|
||||
bool overlap = false;
|
||||
for (int j = 0; j < n; ++j)
|
||||
{
|
||||
dtPolyRef pastRef = resultRef[j];
|
||||
|
||||
// Connected polys do not overlap.
|
||||
bool areConnected = false;
|
||||
for (unsigned int k = curPoly->firstLink; k != DT_NULL_LINK; k = curTile->links[k].next)
|
||||
{
|
||||
if (curTile->links[k].ref == pastRef)
|
||||
{
|
||||
areConnected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (areConnected)
|
||||
continue;
|
||||
|
||||
// Potentially overlapping.
|
||||
it = decodePolyIdTile(pastRef);
|
||||
ip = decodePolyIdPoly(pastRef);
|
||||
const dtMeshTile* pastTile = &m_tiles[it];
|
||||
const dtPoly* pastPoly = &pastTile->polys[ip];
|
||||
|
||||
// Get vertices and test overlap
|
||||
const int npb = pastPoly->vertCount;
|
||||
for (int k = 0; k < npb; ++k)
|
||||
dtVcopy(&pb[k*3], &pastTile->verts[pastPoly->verts[k]*3]);
|
||||
|
||||
if (dtOverlapPolyPoly2D(pa,npa, pb,npb))
|
||||
{
|
||||
overlap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (overlap)
|
||||
continue;
|
||||
|
||||
// This poly is fine, store and advance to the poly.
|
||||
if (n < maxResult)
|
||||
{
|
||||
resultRef[n] = neighbourRef;
|
||||
if (resultParent)
|
||||
resultParent[n] = curRef;
|
||||
++n;
|
||||
}
|
||||
|
||||
if (nstack < MAX_STACK)
|
||||
{
|
||||
stack[nstack++] = neighbourNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int dtNavMesh::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, float* segments)
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
decodePolyId(ref, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return 0;
|
||||
const dtMeshTile* tile = &m_tiles[it];
|
||||
if (tile->salt != salt || tile->header == 0) return 0;
|
||||
if (ip >= (unsigned int)tile->header->polyCount) return 0;
|
||||
const dtPoly* poly = &tile->polys[ip];
|
||||
|
||||
int n = 0;
|
||||
|
||||
for (int i = 0, j = (int)poly->vertCount-1; i < (int)poly->vertCount; j = i++)
|
||||
{
|
||||
// Skip non-solid edges.
|
||||
if (poly->neis[j] & DT_EXT_LINK)
|
||||
{
|
||||
// Tile border.
|
||||
bool solid = true;
|
||||
for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next)
|
||||
{
|
||||
const dtLink* link = &tile->links[k];
|
||||
if (link->edge == j)
|
||||
{
|
||||
if (link->ref != 0 && passFilter(filter, getPolyFlags(link->ref)))
|
||||
solid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!solid) continue;
|
||||
}
|
||||
else if (poly->neis[j] && passFilter(filter, tile->polys[poly->neis[j]-1].flags))
|
||||
{
|
||||
// Internal edge
|
||||
continue;
|
||||
}
|
||||
|
||||
// Store segment.
|
||||
const float* vj = &tile->verts[poly->verts[j]*3];
|
||||
const float* vi = &tile->verts[poly->verts[i]*3];
|
||||
float* seg = &segments[n*6];
|
||||
n++;
|
||||
dtVcopy(seg+0, vj);
|
||||
dtVcopy(seg+3, vi);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius, const dtQueryFilter* filter,
|
||||
float* hitPos, float* hitNormal) const
|
||||
{
|
||||
@ -2574,7 +2866,7 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
}
|
||||
if (!solid) continue;
|
||||
}
|
||||
else if (bestPoly->neis[j] && passFilter(filter, bestTile->polys[bestPoly->neis[j]].flags))
|
||||
else if (bestPoly->neis[j] && passFilter(filter, bestTile->polys[bestPoly->neis[j]-1].flags))
|
||||
{
|
||||
// Internal edge
|
||||
continue;
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -283,8 +283,8 @@
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>14</integer>
|
||||
<integer>11</integer>
|
||||
<integer>10</integer>
|
||||
<integer>2</integer>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
@ -337,7 +337,7 @@
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>6BAF3A3112101D4B008CFCDF</string>
|
||||
<string>6BAF3AC3121039C7008CFCDF</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>6BBB4AA1115B4F3400CF791D</string>
|
||||
@ -357,7 +357,6 @@
|
||||
<string>6BF5F31C117490A1000502A6</string>
|
||||
<string>6BF5F32E11759C3C000502A6</string>
|
||||
<string>6BF5F474117644A2000502A6</string>
|
||||
<string>6BF5F475117644A2000502A6</string>
|
||||
<string>6BF5F5041176F5F8000502A6</string>
|
||||
<string>6B4214D911803923006C347B</string>
|
||||
<string>6B2CDC911197F0720090FA4D</string>
|
||||
@ -380,7 +379,6 @@
|
||||
<string>6BF9B1F211EC43FC0043574C</string>
|
||||
<string>6BF9B20B11EC450E0043574C</string>
|
||||
<string>6BF9B21211EC49A30043574C</string>
|
||||
<string>6BF9B21311EC49A30043574C</string>
|
||||
<string>6BF9B21B11EC49F90043574C</string>
|
||||
<string>6BAF37D411FEAC16008CFCDF</string>
|
||||
<string>6BAF37F911FEB4BB008CFCDF</string>
|
||||
@ -395,20 +393,21 @@
|
||||
<string>6BAF3873120AD32F008CFCDF</string>
|
||||
<string>6BAF3874120AD32F008CFCDF</string>
|
||||
<string>6BAF3875120AD32F008CFCDF</string>
|
||||
<string>6BAF38F2120FD8CC008CFCDF</string>
|
||||
<string>6BAF390F120FEB27008CFCDF</string>
|
||||
<string>6BAF3910120FEB27008CFCDF</string>
|
||||
<string>6BAF3938120FEF30008CFCDF</string>
|
||||
<string>6BAF3971120FF609008CFCDF</string>
|
||||
<string>6BAF39D012100A22008CFCDF</string>
|
||||
<string>6BAF39D112100A22008CFCDF</string>
|
||||
<string>6BAF39D212100A22008CFCDF</string>
|
||||
<string>6BAF39DB12100D84008CFCDF</string>
|
||||
<string>6BAF39E712100DE4008CFCDF</string>
|
||||
<string>6BAF39F012100ED1008CFCDF</string>
|
||||
<string>6BAF39F112100ED1008CFCDF</string>
|
||||
<string>6BAF3A2E12101D4B008CFCDF</string>
|
||||
<string>6BAF3A2F12101D4B008CFCDF</string>
|
||||
<string>6BAF3A5F12102BB9008CFCDF</string>
|
||||
<string>6BAF3A7812103373008CFCDF</string>
|
||||
<string>6BAF3AAB1210369A008CFCDF</string>
|
||||
<string>6BAF3AB3121038F9008CFCDF</string>
|
||||
<string>6BAF3AB4121038F9008CFCDF</string>
|
||||
<string>6BAF3AB5121038F9008CFCDF</string>
|
||||
<string>6BAF3AB6121038F9008CFCDF</string>
|
||||
<string>6BAF3AC2121039C7008CFCDF</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -428,7 +427,6 @@
|
||||
<string>6BBB4AEF115B4F3400CF791D</string>
|
||||
<string>6BBB4AF0115B4F3400CF791D</string>
|
||||
<string>6BBB4AF1115B4F3400CF791D</string>
|
||||
<string>6BBB4AF4115B4F3400CF791D</string>
|
||||
<string>6BBB4AF7115B4F3400CF791D</string>
|
||||
<string>6BBB4AF8115B4F3400CF791D</string>
|
||||
<string>6BBB4AF9115B4F3400CF791D</string>
|
||||
@ -448,7 +446,6 @@
|
||||
<string>6BF5F33911759C3C000502A6</string>
|
||||
<string>6B4215D1118066FE006C347B</string>
|
||||
<string>6B4215DF1180672F006C347B</string>
|
||||
<string>6B4216881180725E006C347B</string>
|
||||
<string>6B5562681193EF2F00843384</string>
|
||||
<string>6B2CDD181197FE370090FA4D</string>
|
||||
<string>6B10005C11AD08FA0098A59A</string>
|
||||
@ -474,12 +471,9 @@
|
||||
<string>6BF9B14911EB8CF20043574C</string>
|
||||
<string>6BAF37D611FEAC16008CFCDF</string>
|
||||
<string>6BAF37FE11FEB4BB008CFCDF</string>
|
||||
<string>6BAF380211FEB4BB008CFCDF</string>
|
||||
<string>6BAF382612019EDA008CFCDF</string>
|
||||
<string>6BAF382712019EDA008CFCDF</string>
|
||||
<string>6BAF382812019EDA008CFCDF</string>
|
||||
<string>6BAF382912019EDA008CFCDF</string>
|
||||
<string>6BAF382A12019EDA008CFCDF</string>
|
||||
<string>6BAF385F120A8A8E008CFCDF</string>
|
||||
<string>6BAF3860120A8A8E008CFCDF</string>
|
||||
<string>6BAF3861120A8A8E008CFCDF</string>
|
||||
@ -507,40 +501,63 @@
|
||||
<string>6BAF3919120FEB27008CFCDF</string>
|
||||
<string>6BAF391B120FEB27008CFCDF</string>
|
||||
<string>6BAF391C120FEB27008CFCDF</string>
|
||||
<string>6BAF393B120FEF30008CFCDF</string>
|
||||
<string>6BAF393D120FEF30008CFCDF</string>
|
||||
<string>6BAF3944120FEF7A008CFCDF</string>
|
||||
<string>6BBB4AD2115B4F3400CF791D</string>
|
||||
<string>6BBB4AD4115B4F3400CF791D</string>
|
||||
<string>6BAF38431202CBF8008CFCDF</string>
|
||||
<string>6BAF395E120FF37D008CFCDF</string>
|
||||
<string>6BAF395F120FF37D008CFCDF</string>
|
||||
<string>6BAF3969120FF483008CFCDF</string>
|
||||
<string>6BAF396A120FF483008CFCDF</string>
|
||||
<string>6BAF396B120FF483008CFCDF</string>
|
||||
<string>6BAF396C120FF483008CFCDF</string>
|
||||
<string>6BAF3973120FF609008CFCDF</string>
|
||||
<string>6BAF3974120FF609008CFCDF</string>
|
||||
<string>6BAF3982120FF75F008CFCDF</string>
|
||||
<string>6BAF3983120FF75F008CFCDF</string>
|
||||
<string>6BAF398E120FF809008CFCDF</string>
|
||||
<string>6BAF3990120FF809008CFCDF</string>
|
||||
<string>6BAF3992120FF809008CFCDF</string>
|
||||
<string>6BAF39C112100714008CFCDF</string>
|
||||
<string>6BAF39CA1210074E008CFCDF</string>
|
||||
<string>6BAF39D412100A22008CFCDF</string>
|
||||
<string>6BAF39D512100A22008CFCDF</string>
|
||||
<string>6BAF39D612100A22008CFCDF</string>
|
||||
<string>6BAF39DD12100D84008CFCDF</string>
|
||||
<string>6BAF39DE12100D84008CFCDF</string>
|
||||
<string>6BAF39DF12100D84008CFCDF</string>
|
||||
<string>6BAF39E412100DA6008CFCDF</string>
|
||||
<string>6BAF39E912100DE4008CFCDF</string>
|
||||
<string>6BAF39EA12100DE4008CFCDF</string>
|
||||
<string>6BAF39F312100ED1008CFCDF</string>
|
||||
<string>6BAF39F412100ED1008CFCDF</string>
|
||||
<string>6BAF39F512100ED1008CFCDF</string>
|
||||
<string>6BAF3A3012101D4B008CFCDF</string>
|
||||
<string>6BAF3A3412102220008CFCDF</string>
|
||||
<string>6BAF3A3B1210235F008CFCDF</string>
|
||||
<string>6BAF3A3D1210235F008CFCDF</string>
|
||||
<string>6BAF3A3F1210235F008CFCDF</string>
|
||||
<string>6BAF3A46121023ED008CFCDF</string>
|
||||
<string>6BAF3A4F121028E6008CFCDF</string>
|
||||
<string>6BAF3A50121028E6008CFCDF</string>
|
||||
<string>6BAF3A51121028E6008CFCDF</string>
|
||||
<string>6BAF3A6212102BB9008CFCDF</string>
|
||||
<string>6BAF3A6312102BB9008CFCDF</string>
|
||||
<string>6BAF3A6512102BB9008CFCDF</string>
|
||||
<string>6BAF3A6612102BB9008CFCDF</string>
|
||||
<string>6BAF3A7C12103373008CFCDF</string>
|
||||
<string>6BAF3A7D12103373008CFCDF</string>
|
||||
<string>6BAF3A7E12103373008CFCDF</string>
|
||||
<string>6BAF3A7F12103373008CFCDF</string>
|
||||
<string>6BAF3A8012103373008CFCDF</string>
|
||||
<string>6BAF3A8212103373008CFCDF</string>
|
||||
<string>6BAF3A8412103373008CFCDF</string>
|
||||
<string>6BAF3A8512103373008CFCDF</string>
|
||||
<string>6BAF3A8612103373008CFCDF</string>
|
||||
<string>6BAF3A8712103373008CFCDF</string>
|
||||
<string>6BAF3A8812103373008CFCDF</string>
|
||||
<string>6BAF3A8912103373008CFCDF</string>
|
||||
<string>6BAF3A8A12103373008CFCDF</string>
|
||||
<string>6BAF3A8B12103373008CFCDF</string>
|
||||
<string>6BAF3A8C12103373008CFCDF</string>
|
||||
<string>6BAF3A8D12103373008CFCDF</string>
|
||||
<string>6BAF3A8E12103373008CFCDF</string>
|
||||
<string>6BAF3A8F12103373008CFCDF</string>
|
||||
<string>6BAF3A9012103373008CFCDF</string>
|
||||
<string>6BAF3A9112103373008CFCDF</string>
|
||||
<string>6BAF3A9212103373008CFCDF</string>
|
||||
<string>6BAF3A9312103373008CFCDF</string>
|
||||
<string>6BAF3A9512103373008CFCDF</string>
|
||||
<string>6BAF3A9612103373008CFCDF</string>
|
||||
<string>6BAF3AB7121038F9008CFCDF</string>
|
||||
<string>6BAF3AB8121038F9008CFCDF</string>
|
||||
<string>6BAF3AB9121038F9008CFCDF</string>
|
||||
<string>6BAF3ABA121038F9008CFCDF</string>
|
||||
<string>6BAF3ABB121038F9008CFCDF</string>
|
||||
<string>6BAF3ABC121038F9008CFCDF</string>
|
||||
<string>6BAF3ABD121038F9008CFCDF</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
@ -554,18 +571,18 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {887, 567}}</string>
|
||||
<string>{{0, 0}, {887, 530}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>33 87 1173 691 0 0 1280 778 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>567pt</string>
|
||||
<string>530pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>79pt</string>
|
||||
<string>116pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
@ -633,7 +650,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {887, 52}}</string>
|
||||
<string>{{10, 27}, {887, 89}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>33 87 1173 691 0 0 1280 778 </string>
|
||||
</dict>
|
||||
@ -855,6 +872,7 @@
|
||||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>6BAF3AC4121039C7008CFCDF</string>
|
||||
<string>6BAF394F120FF023008CFCDF</string>
|
||||
<string>6BAF3950120FF023008CFCDF</string>
|
||||
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
|
||||
|
@ -37,7 +37,8 @@ class NavMeshTesterTool : public SampleTool
|
||||
TOOLMODE_RAYCAST,
|
||||
TOOLMODE_DISTANCE_TO_WALL,
|
||||
TOOLMODE_FIND_POLYS_IN_CIRCLE,
|
||||
TOOLMODE_FIND_POLYS_IN_POLY,
|
||||
TOOLMODE_FIND_POLYS_IN_SHAPE,
|
||||
TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD,
|
||||
};
|
||||
|
||||
ToolMode m_toolMode;
|
||||
@ -65,6 +66,7 @@ class NavMeshTesterTool : public SampleTool
|
||||
float m_hitNormal[3];
|
||||
bool m_hitResult;
|
||||
float m_distanceToWall;
|
||||
float m_neighbourhoodRadius;
|
||||
bool m_sposSet;
|
||||
bool m_eposSet;
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "DetourCommon.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
@ -161,6 +162,8 @@ NavMeshTesterTool::NavMeshTesterTool() :
|
||||
m_polyPickExt[0] = 2;
|
||||
m_polyPickExt[1] = 4;
|
||||
m_polyPickExt[2] = 2;
|
||||
|
||||
m_neighbourhoodRadius = 2.5f;
|
||||
}
|
||||
|
||||
NavMeshTesterTool::~NavMeshTesterTool()
|
||||
@ -199,6 +202,7 @@ void NavMeshTesterTool::init(Sample* sample)
|
||||
m_sample->setNavMeshDrawFlags(flags);
|
||||
}
|
||||
|
||||
m_neighbourhoodRadius = sample->getAgentRadius() * 20.0f;
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::handleMenu()
|
||||
@ -228,9 +232,14 @@ void NavMeshTesterTool::handleMenu()
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_IN_CIRCLE;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Find Polys in Poly", m_toolMode == TOOLMODE_FIND_POLYS_IN_POLY))
|
||||
if (imguiCheck("Find Polys in Poly", m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE))
|
||||
{
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_IN_POLY;
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_IN_SHAPE;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Find Local Neighbourhood", m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD))
|
||||
{
|
||||
m_toolMode = TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD;
|
||||
recalc();
|
||||
}
|
||||
|
||||
@ -738,7 +747,7 @@ void NavMeshTesterTool::recalc()
|
||||
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_POLY)
|
||||
else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE)
|
||||
{
|
||||
if (m_sposSet && m_startRef && m_eposSet)
|
||||
{
|
||||
@ -774,6 +783,19 @@ void NavMeshTesterTool::recalc()
|
||||
m_polys, m_parent, 0, MAX_POLYS);
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD)
|
||||
{
|
||||
if (m_sposSet && m_startRef)
|
||||
{
|
||||
#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);
|
||||
#endif
|
||||
m_npolys = m_navMesh->findLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, &m_filter,
|
||||
m_polys, m_parent, MAX_POLYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center)
|
||||
@ -1000,7 +1022,7 @@ void NavMeshTesterTool::handleRender()
|
||||
dd.depthMask(true);
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_POLY)
|
||||
else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE)
|
||||
{
|
||||
for (int i = 0; i < m_npolys; ++i)
|
||||
{
|
||||
@ -1033,6 +1055,67 @@ void NavMeshTesterTool::handleRender()
|
||||
dd.end();
|
||||
dd.depthMask(true);
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD)
|
||||
{
|
||||
for (int i = 0; i < m_npolys; ++i)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_polys[i], pathCol);
|
||||
dd.depthMask(false);
|
||||
if (m_parent[i])
|
||||
{
|
||||
float p0[3], p1[3];
|
||||
dd.depthMask(false);
|
||||
getPolyCenter(m_navMesh, m_parent[i], p0);
|
||||
getPolyCenter(m_navMesh, m_polys[i], p1);
|
||||
duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0,0,0,128), 2.0f);
|
||||
dd.depthMask(true);
|
||||
}
|
||||
|
||||
float segs[DT_VERTS_PER_POLYGON*3*2];
|
||||
const int nsegs = m_navMesh->getPolyWallSegments(m_polys[i], &m_filter, segs);
|
||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int j = 0; j < nsegs; ++j)
|
||||
{
|
||||
const float* s = &segs[j*6];
|
||||
|
||||
// Skip too distant segments.
|
||||
float tseg;
|
||||
float distSqr = dtDistancePtSegSqr2D(m_spos, s, s+3, tseg);
|
||||
if (distSqr > dtSqr(m_neighbourhoodRadius))
|
||||
continue;
|
||||
|
||||
float delta[3], norm[3], p0[3], p1[3];
|
||||
rcVsub(delta, s+3,s);
|
||||
rcVmad(p0, s, delta, 0.5f);
|
||||
norm[0] = delta[2];
|
||||
norm[1] = 0;
|
||||
norm[2] = -delta[0];
|
||||
rcVnormalize(norm);
|
||||
rcVmad(p1, p0, norm, agentRadius*0.5f);
|
||||
|
||||
// Skip backfacing segments.
|
||||
unsigned int col = duRGBA(255,255,255,192);
|
||||
if (dtTriArea2D(m_spos, s, s+3) < 0.0f)
|
||||
col = duRGBA(255,255,255,64);
|
||||
|
||||
dd.vertex(p0[0],p0[1]+agentClimb,p0[2],duRGBA(0,0,0,128));
|
||||
dd.vertex(p1[0],p1[1]+agentClimb,p1[2],duRGBA(0,0,0,128));
|
||||
|
||||
dd.vertex(s[0],s[1]+agentClimb,s[2],col);
|
||||
dd.vertex(s[3],s[4]+agentClimb,s[5],col);
|
||||
}
|
||||
dd.end();
|
||||
|
||||
dd.depthMask(true);
|
||||
}
|
||||
|
||||
if (m_sposSet)
|
||||
{
|
||||
dd.depthMask(false);
|
||||
duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+agentHeight/2, m_spos[2], m_neighbourhoodRadius, duRGBA(64,16,0,220), 2.0f);
|
||||
dd.depthMask(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user