getPolyWallSegments can return both walls and portals. Added userData pointer to dtCrowdAgent.
This commit is contained in:
parent
1080b6c249
commit
fdb4ad30f7
@ -304,14 +304,18 @@ public:
|
|||||||
int* resultCount, const int maxResult) const;
|
int* resultCount, const int maxResult) const;
|
||||||
|
|
||||||
// Returns wall segments of specified polygon.
|
// Returns wall segments of specified polygon.
|
||||||
|
// If 'segmentRefs' is specified, both the wall and portal segments are returned.
|
||||||
|
// Wall segments will have null (0) polyref, and portal segments store the polygon they lead to.
|
||||||
// Params:
|
// Params:
|
||||||
// ref - (in) ref to the polygon.
|
// ref - (in) ref to the polygon.
|
||||||
// filter - (in) path polygon filter.
|
// filter - (in) path polygon filter.
|
||||||
// segments[6*maxSegments] - (out) wall segments (2 endpoints per segment).
|
// segmentVerts[6*maxSegments] - (out) wall segments (2 endpoints per segment).
|
||||||
|
// segmentRefs[maxSegments] - (out,opt) reference to a neighbour.
|
||||||
// segmentCount - (out) number of wall segments.
|
// segmentCount - (out) number of wall segments.
|
||||||
// maxSegments - (in) max number of segments that can be stored in 'segments'.
|
// maxSegments - (in) max number of segments that can be stored in 'segments'.
|
||||||
dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
|
dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
|
||||||
float* segments, int* segmentCount, const int maxSegments) const;
|
float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount,
|
||||||
|
const int maxSegments) const;
|
||||||
|
|
||||||
// Returns closest point on navigation polygon.
|
// Returns closest point on navigation polygon.
|
||||||
// Uses detail polygons to find the closest point to the navigation polygon surface.
|
// Uses detail polygons to find the closest point to the navigation polygon surface.
|
||||||
|
@ -2353,11 +2353,12 @@ dtStatus dtNavMeshQuery::findLocalNeighbourhood(dtPolyRef startRef, const float*
|
|||||||
|
|
||||||
struct dtSegInterval
|
struct dtSegInterval
|
||||||
{
|
{
|
||||||
|
dtPolyRef ref;
|
||||||
short tmin, tmax;
|
short tmin, tmax;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void insertInterval(dtSegInterval* ints, int& nints, const int maxInts,
|
static void insertInterval(dtSegInterval* ints, int& nints, const int maxInts,
|
||||||
const short tmin, const short tmax)
|
const short tmin, const short tmax, const dtPolyRef ref)
|
||||||
{
|
{
|
||||||
if (nints+1 > maxInts) return;
|
if (nints+1 > maxInts) return;
|
||||||
// Find insertion point.
|
// Find insertion point.
|
||||||
@ -2372,13 +2373,15 @@ static void insertInterval(dtSegInterval* ints, int& nints, const int maxInts,
|
|||||||
if (nints-idx)
|
if (nints-idx)
|
||||||
memmove(ints+idx+1, ints+idx, sizeof(dtSegInterval)*(nints-idx));
|
memmove(ints+idx+1, ints+idx, sizeof(dtSegInterval)*(nints-idx));
|
||||||
// Store
|
// Store
|
||||||
|
ints[idx].ref = ref;
|
||||||
ints[idx].tmin = tmin;
|
ints[idx].tmin = tmin;
|
||||||
ints[idx].tmax = tmax;
|
ints[idx].tmax = tmax;
|
||||||
nints++;
|
nints++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
|
dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
|
||||||
float* segments, int* segmentCount, const int maxSegments) const
|
float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount,
|
||||||
|
const int maxSegments) const
|
||||||
{
|
{
|
||||||
dtAssert(m_nav);
|
dtAssert(m_nav);
|
||||||
|
|
||||||
@ -2394,6 +2397,8 @@ dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter*
|
|||||||
dtSegInterval ints[MAX_INTERVAL];
|
dtSegInterval ints[MAX_INTERVAL];
|
||||||
int nints;
|
int nints;
|
||||||
|
|
||||||
|
const bool storePortals = segmentRefs != 0;
|
||||||
|
|
||||||
dtStatus status = DT_SUCCESS;
|
dtStatus status = DT_SUCCESS;
|
||||||
|
|
||||||
for (int i = 0, j = (int)poly->vertCount-1; i < (int)poly->vertCount; j = i++)
|
for (int i = 0, j = (int)poly->vertCount-1; i < (int)poly->vertCount; j = i++)
|
||||||
@ -2415,58 +2420,91 @@ dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter*
|
|||||||
m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly);
|
m_nav->getTileAndPolyByRefUnsafe(link->ref, &neiTile, &neiPoly);
|
||||||
if (filter->passFilter(link->ref, neiTile, neiPoly))
|
if (filter->passFilter(link->ref, neiTile, neiPoly))
|
||||||
{
|
{
|
||||||
insertInterval(ints, nints, MAX_INTERVAL, link->bmin, link->bmax);
|
insertInterval(ints, nints, MAX_INTERVAL, link->bmin, link->bmax, link->ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (poly->neis[j])
|
else
|
||||||
{
|
{
|
||||||
// Internal edge
|
// Internal edge
|
||||||
const unsigned int idx = (unsigned int)(poly->neis[j]-1);
|
dtPolyRef ref = 0;
|
||||||
const dtPolyRef ref = m_nav->getPolyRefBase(tile) | idx;
|
if (poly->neis[j])
|
||||||
if (filter->passFilter(ref, tile, &tile->polys[idx]))
|
{
|
||||||
|
const unsigned int idx = (unsigned int)(poly->neis[j]-1);
|
||||||
|
ref = m_nav->getPolyRefBase(tile) | idx;
|
||||||
|
if (!filter->passFilter(ref, tile, &tile->polys[idx]))
|
||||||
|
ref = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the edge leads to another polygon and portals are not stored, skip.
|
||||||
|
if (ref != 0 && !storePortals)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (n < maxSegments)
|
||||||
|
{
|
||||||
|
const float* vj = &tile->verts[poly->verts[j]*3];
|
||||||
|
const float* vi = &tile->verts[poly->verts[i]*3];
|
||||||
|
float* seg = &segmentVerts[n*6];
|
||||||
|
dtVcopy(seg+0, vj);
|
||||||
|
dtVcopy(seg+3, vi);
|
||||||
|
if (segmentRefs)
|
||||||
|
segmentRefs[n] = ref;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status |= DT_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add sentinels
|
// Add sentinels
|
||||||
insertInterval(ints, nints, MAX_INTERVAL, -1, 0);
|
insertInterval(ints, nints, MAX_INTERVAL, -1, 0, 0);
|
||||||
insertInterval(ints, nints, MAX_INTERVAL, 255, 256);
|
insertInterval(ints, nints, MAX_INTERVAL, 255, 256, 0);
|
||||||
|
|
||||||
// Store segment.
|
// Store segments.
|
||||||
const float* vj = &tile->verts[poly->verts[j]*3];
|
const float* vj = &tile->verts[poly->verts[j]*3];
|
||||||
const float* vi = &tile->verts[poly->verts[i]*3];
|
const float* vi = &tile->verts[poly->verts[i]*3];
|
||||||
for (int k = 1; k < nints; ++k)
|
for (int k = 1; k < nints; ++k)
|
||||||
{
|
{
|
||||||
// Find the space inbetween the opening areas.
|
// Portal segment.
|
||||||
const int imin = ints[k-1].tmax;
|
if (storePortals && ints[k].ref)
|
||||||
const int imax = ints[k].tmin;
|
|
||||||
if (imin == imax) continue;
|
|
||||||
if (imin == 0 && imax == 255)
|
|
||||||
{
|
{
|
||||||
|
const float tmin = ints[k].tmin/255.0f;
|
||||||
|
const float tmax = ints[k].tmax/255.0f;
|
||||||
if (n < maxSegments)
|
if (n < maxSegments)
|
||||||
{
|
{
|
||||||
float* seg = &segments[n*6];
|
float* seg = &segmentVerts[n*6];
|
||||||
|
dtVlerp(seg+0, vj,vi, tmin);
|
||||||
|
dtVlerp(seg+3, vj,vi, tmax);
|
||||||
|
if (segmentRefs)
|
||||||
|
segmentRefs[n] = ints[k].ref;
|
||||||
n++;
|
n++;
|
||||||
dtVcopy(seg+0, vj);
|
|
||||||
dtVcopy(seg+3, vi);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status |= DT_BUFFER_TOO_SMALL;
|
status |= DT_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Wall segment.
|
||||||
|
const int imin = ints[k-1].tmax;
|
||||||
|
const int imax = ints[k].tmin;
|
||||||
|
if (imin != imax)
|
||||||
{
|
{
|
||||||
const float tmin = imin/255.0f;
|
const float tmin = imin/255.0f;
|
||||||
const float tmax = imax/255.0f;
|
const float tmax = imax/255.0f;
|
||||||
if (n < maxSegments)
|
if (n < maxSegments)
|
||||||
{
|
{
|
||||||
float* seg = &segments[n*6];
|
float* seg = &segmentVerts[n*6];
|
||||||
n++;
|
|
||||||
dtVlerp(seg+0, vj,vi, tmin);
|
dtVlerp(seg+0, vj,vi, tmin);
|
||||||
dtVlerp(seg+3, vj,vi, tmax);
|
dtVlerp(seg+3, vj,vi, tmax);
|
||||||
|
if (segmentRefs)
|
||||||
|
segmentRefs[n] = 0;
|
||||||
|
n++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -106,7 +106,7 @@ void dtLocalBoundary::update(dtPolyRef ref, const float* pos, const float collis
|
|||||||
int nsegs = 0;
|
int nsegs = 0;
|
||||||
for (int j = 0; j < nlocals; ++j)
|
for (int j = 0; j < nlocals; ++j)
|
||||||
{
|
{
|
||||||
navquery->getPolyWallSegments(locals[j], filter, segs, &nsegs, MAX_SEGS_PER_POLY);
|
navquery->getPolyWallSegments(locals[j], filter, segs, 0, &nsegs, MAX_SEGS_PER_POLY);
|
||||||
for (int k = 0; k < nsegs; ++k)
|
for (int k = 0; k < nsegs; ++k)
|
||||||
{
|
{
|
||||||
const float* s = &segs[k*6];
|
const float* s = &segs[k*6];
|
||||||
|
Binary file not shown.
@ -1127,10 +1127,12 @@ void NavMeshTesterTool::handleRender()
|
|||||||
dd.depthMask(true);
|
dd.depthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int MAX_SEGS = DT_VERTS_PER_POLYGON*2;
|
static const int MAX_SEGS = DT_VERTS_PER_POLYGON*4;
|
||||||
float segs[MAX_SEGS*6];
|
float segs[MAX_SEGS*6];
|
||||||
|
dtPolyRef refs[MAX_SEGS];
|
||||||
|
memset(refs, 0, sizeof(dtPolyRef)*MAX_SEGS);
|
||||||
int nsegs = 0;
|
int nsegs = 0;
|
||||||
m_navQuery->getPolyWallSegments(m_polys[i], &m_filter, segs, &nsegs, MAX_SEGS);
|
m_navQuery->getPolyWallSegments(m_polys[i], &m_filter, segs, refs, &nsegs, MAX_SEGS);
|
||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||||
for (int j = 0; j < nsegs; ++j)
|
for (int j = 0; j < nsegs; ++j)
|
||||||
{
|
{
|
||||||
@ -1152,15 +1154,24 @@ void NavMeshTesterTool::handleRender()
|
|||||||
dtVmad(p1, p0, norm, agentRadius*0.5f);
|
dtVmad(p1, p0, norm, agentRadius*0.5f);
|
||||||
|
|
||||||
// Skip backfacing segments.
|
// Skip backfacing segments.
|
||||||
unsigned int col = duRGBA(255,255,255,192);
|
if (refs[j])
|
||||||
if (dtTriArea2D(m_spos, s, s+3) < 0.0f)
|
{
|
||||||
col = duRGBA(255,255,255,64);
|
unsigned int col = duRGBA(255,255,255,32);
|
||||||
|
dd.vertex(s[0],s[1]+agentClimb,s[2],col);
|
||||||
|
dd.vertex(s[3],s[4]+agentClimb,s[5],col);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int col = duRGBA(192,32,16,192);
|
||||||
|
if (dtTriArea2D(m_spos, s, s+3) < 0.0f)
|
||||||
|
col = duRGBA(96,32,16,192);
|
||||||
|
|
||||||
dd.vertex(p0[0],p0[1]+agentClimb,p0[2],duRGBA(0,0,0,128));
|
dd.vertex(p0[0],p0[1]+agentClimb,p0[2],col);
|
||||||
dd.vertex(p1[0],p1[1]+agentClimb,p1[2],duRGBA(0,0,0,128));
|
dd.vertex(p1[0],p1[1]+agentClimb,p1[2],col);
|
||||||
|
|
||||||
dd.vertex(s[0],s[1]+agentClimb,s[2],col);
|
dd.vertex(s[0],s[1]+agentClimb,s[2],col);
|
||||||
dd.vertex(s[3],s[4]+agentClimb,s[5],col);
|
dd.vertex(s[3],s[4]+agentClimb,s[5],col);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dd.end();
|
dd.end();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user