- use "cylinder distance" for nearest point in polygon
- added option for findStraightPath() to append vertices at get edge crossings - added scale parameter for .obj loader
This commit is contained in:
parent
a02cc64e4b
commit
de6fd8c3ef
@ -376,6 +376,10 @@ bool dtIntersectSegmentPoly2D(const float* p0, const float* p1,
|
|||||||
float& tmin, float& tmax,
|
float& tmin, float& tmax,
|
||||||
int& segMin, int& segMax);
|
int& segMin, int& segMax);
|
||||||
|
|
||||||
|
bool dtIntersectSegSeg2D(const float* ap, const float* aq,
|
||||||
|
const float* bp, const float* bq,
|
||||||
|
float& s, float& t);
|
||||||
|
|
||||||
/// Determines if the specified point is inside the convex polygon on the xz-plane.
|
/// Determines if the specified point is inside the convex polygon on the xz-plane.
|
||||||
/// @param[in] pt The point to check. [(x, y, z)]
|
/// @param[in] pt The point to check. [(x, y, z)]
|
||||||
/// @param[in] verts The polygon vertices. [(x, y, z) * @p nverts]
|
/// @param[in] verts The polygon vertices. [(x, y, z) * @p nverts]
|
||||||
|
@ -87,6 +87,13 @@ enum dtStraightPathFlags
|
|||||||
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is the start of an off-mesh connection.
|
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is the start of an off-mesh connection.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Options for dtNavMeshQuery::findStraightPath.
|
||||||
|
enum dtStraightPathOptions
|
||||||
|
{
|
||||||
|
DT_STRAIGHTPATH_AREA_CROSSINGS = 0x01, ///< Add a vertex at every polygon edge crossing where area changes.
|
||||||
|
DT_STRAIGHTPATH_ALL_CROSSINGS = 0x02, ///< Add a vertex at every polygon edge crossing.
|
||||||
|
};
|
||||||
|
|
||||||
/// Flags representing the type of a navigation mesh polygon.
|
/// Flags representing the type of a navigation mesh polygon.
|
||||||
enum dtPolyTypes
|
enum dtPolyTypes
|
||||||
{
|
{
|
||||||
|
@ -158,11 +158,12 @@ public:
|
|||||||
/// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt]
|
/// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt]
|
||||||
/// @param[out] straightPathCount The number of points in the straight path.
|
/// @param[out] straightPathCount The number of points in the straight path.
|
||||||
/// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0]
|
/// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0]
|
||||||
|
/// @param[in] options Query options. (see: #dtStraightPathOptions)
|
||||||
/// @returns The status flags for the query.
|
/// @returns The status flags for the query.
|
||||||
dtStatus findStraightPath(const float* startPos, const float* endPos,
|
dtStatus findStraightPath(const float* startPos, const float* endPos,
|
||||||
const dtPolyRef* path, const int pathSize,
|
const dtPolyRef* path, const int pathSize,
|
||||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
int* straightPathCount, const int maxStraightPath) const;
|
int* straightPathCount, const int maxStraightPath, const int options = 0) const;
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
/// @name Sliced Pathfinding Functions
|
/// @name Sliced Pathfinding Functions
|
||||||
@ -446,6 +447,16 @@ private:
|
|||||||
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
|
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
|
||||||
float* mid) const;
|
float* mid) const;
|
||||||
|
|
||||||
|
// Appends vertex to a straight path
|
||||||
|
dtStatus appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref,
|
||||||
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
|
int* straightPathCount, const int maxStraightPath) const;
|
||||||
|
|
||||||
|
// Appends intermediate portal points to a straight path.
|
||||||
|
dtStatus appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path,
|
||||||
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
|
int* straightPathCount, const int maxStraightPath, const int options) const;
|
||||||
|
|
||||||
const dtNavMesh* m_nav; ///< Pointer to navmesh data.
|
const dtNavMesh* m_nav; ///< Pointer to navmesh data.
|
||||||
|
|
||||||
struct dtQueryData
|
struct dtQueryData
|
||||||
|
@ -374,3 +374,20 @@ void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas,
|
|||||||
out[2] = a*pa[2] + b*pb[2] + c*pc[2];
|
out[2] = a*pa[2] + b*pb[2] + c*pc[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float vperpXZ(const float* a, const float* b) { return a[0]*b[2] - a[2]*b[0]; }
|
||||||
|
|
||||||
|
bool dtIntersectSegSeg2D(const float* ap, const float* aq,
|
||||||
|
const float* bp, const float* bq,
|
||||||
|
float& s, float& t)
|
||||||
|
{
|
||||||
|
float u[3], v[3], w[3];
|
||||||
|
dtVsub(u,aq,ap);
|
||||||
|
dtVsub(v,bq,bp);
|
||||||
|
dtVsub(w,ap,bp);
|
||||||
|
float d = vperpXZ(u,v);
|
||||||
|
if (fabsf(d) < 1e-6f) return false;
|
||||||
|
s = vperpXZ(v,w) / d;
|
||||||
|
t = vperpXZ(u,w) / d;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -616,10 +616,48 @@ void dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip
|
|||||||
const float* pos, float* closest) const
|
const float* pos, float* closest) const
|
||||||
{
|
{
|
||||||
const dtPoly* poly = &tile->polys[ip];
|
const dtPoly* poly = &tile->polys[ip];
|
||||||
|
// Off-mesh connections don't have detail polygons.
|
||||||
|
if (poly->getType() == DT_POLYTYPE_OFFMESH_CONNECTION)
|
||||||
|
{
|
||||||
|
const float* v0 = &tile->verts[poly->verts[0]*3];
|
||||||
|
const float* v1 = &tile->verts[poly->verts[1]*3];
|
||||||
|
const float d0 = dtVdist(pos, v0);
|
||||||
|
const float d1 = dtVdist(pos, v1);
|
||||||
|
const float u = d0 / (d0+d1);
|
||||||
|
dtVlerp(closest, v0, v1, u);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float closestDistSqr = FLT_MAX;
|
|
||||||
const dtPolyDetail* pd = &tile->detailMeshes[ip];
|
const dtPolyDetail* pd = &tile->detailMeshes[ip];
|
||||||
|
|
||||||
|
// Clamp point to be inside the polygon.
|
||||||
|
float verts[DT_VERTS_PER_POLYGON*3];
|
||||||
|
float edged[DT_VERTS_PER_POLYGON];
|
||||||
|
float edget[DT_VERTS_PER_POLYGON];
|
||||||
|
const int nv = poly->vertCount;
|
||||||
|
for (int i = 0; i < nv; ++i)
|
||||||
|
dtVcopy(&verts[i*3], &tile->verts[poly->verts[i]*3]);
|
||||||
|
|
||||||
|
dtVcopy(closest, pos);
|
||||||
|
if (!dtDistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
|
||||||
|
{
|
||||||
|
// Point is outside the polygon, dtClamp to nearest edge.
|
||||||
|
float dmin = FLT_MAX;
|
||||||
|
int imin = -1;
|
||||||
|
for (int i = 0; i < nv; ++i)
|
||||||
|
{
|
||||||
|
if (edged[i] < dmin)
|
||||||
|
{
|
||||||
|
dmin = edged[i];
|
||||||
|
imin = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const float* va = &verts[imin*3];
|
||||||
|
const float* vb = &verts[((imin+1)%nv)*3];
|
||||||
|
dtVlerp(closest, va, vb, edget[imin]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find height at the location.
|
||||||
for (int j = 0; j < pd->triCount; ++j)
|
for (int j = 0; j < pd->triCount; ++j)
|
||||||
{
|
{
|
||||||
const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4];
|
const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4];
|
||||||
@ -631,13 +669,11 @@ void dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip
|
|||||||
else
|
else
|
||||||
v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3];
|
v[k] = &tile->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3];
|
||||||
}
|
}
|
||||||
float pt[3];
|
float h;
|
||||||
dtClosestPtPointTriangle(pt, pos, v[0], v[1], v[2]);
|
if (dtClosestHeightPointTriangle(pos, v[0], v[1], v[2], h))
|
||||||
float d = dtVdistSqr(pos, pt);
|
|
||||||
if (d < closestDistSqr)
|
|
||||||
{
|
{
|
||||||
dtVcopy(closest, pt);
|
closest[1] = h;
|
||||||
closestDistSqr = d;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,9 +534,6 @@ void dtNavMeshQuery::closestPointOnPolyInTile(const dtMeshTile* tile, const dtPo
|
|||||||
const unsigned int ip = (unsigned int)(poly - tile->polys);
|
const unsigned int ip = (unsigned int)(poly - tile->polys);
|
||||||
const dtPolyDetail* pd = &tile->detailMeshes[ip];
|
const dtPolyDetail* pd = &tile->detailMeshes[ip];
|
||||||
|
|
||||||
// TODO: The commented out version finds 'cylinder distance' instead of 'sphere distance' to the navmesh.
|
|
||||||
// Test and enable.
|
|
||||||
/*
|
|
||||||
// Clamp point to be inside the polygon.
|
// Clamp point to be inside the polygon.
|
||||||
float verts[DT_VERTS_PER_POLYGON*3];
|
float verts[DT_VERTS_PER_POLYGON*3];
|
||||||
float edged[DT_VERTS_PER_POLYGON];
|
float edged[DT_VERTS_PER_POLYGON];
|
||||||
@ -583,8 +580,8 @@ void dtNavMeshQuery::closestPointOnPolyInTile(const dtMeshTile* tile, const dtPo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
float closestDistSqr = FLT_MAX;
|
/* float closestDistSqr = FLT_MAX;
|
||||||
for (int j = 0; j < pd->triCount; ++j)
|
for (int j = 0; j < pd->triCount; ++j)
|
||||||
{
|
{
|
||||||
const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4];
|
const unsigned char* t = &tile->detailTris[(pd->triBase+j)*4];
|
||||||
@ -606,7 +603,7 @@ void dtNavMeshQuery::closestPointOnPolyInTile(const dtMeshTile* tile, const dtPo
|
|||||||
dtVcopy(closest, pt);
|
dtVcopy(closest, pt);
|
||||||
closestDistSqr = d;
|
closestDistSqr = d;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
@ -1543,6 +1540,87 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing
|
|||||||
return DT_SUCCESS | details;
|
return DT_SUCCESS | details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dtStatus dtNavMeshQuery::appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref,
|
||||||
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
|
int* straightPathCount, const int maxStraightPath) const
|
||||||
|
{
|
||||||
|
if ((*straightPathCount) > 0 && dtVequal(&straightPath[((*straightPathCount)-1)*3], pos))
|
||||||
|
{
|
||||||
|
// The vertices are equal, update flags and poly.
|
||||||
|
if (straightPathFlags)
|
||||||
|
straightPathFlags[(*straightPathCount)-1] = flags;
|
||||||
|
if (straightPathRefs)
|
||||||
|
straightPathRefs[(*straightPathCount)-1] = ref;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Append new vertex.
|
||||||
|
dtVcopy(&straightPath[(*straightPathCount)*3], pos);
|
||||||
|
if (straightPathFlags)
|
||||||
|
straightPathFlags[(*straightPathCount)] = flags;
|
||||||
|
if (straightPathRefs)
|
||||||
|
straightPathRefs[(*straightPathCount)] = ref;
|
||||||
|
(*straightPathCount)++;
|
||||||
|
// If reached end of path or there is no space to append more vertices, return.
|
||||||
|
if (flags == DT_STRAIGHTPATH_END || (*straightPathCount) >= maxStraightPath)
|
||||||
|
{
|
||||||
|
return DT_SUCCESS | (((*straightPathCount) >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DT_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
dtStatus dtNavMeshQuery::appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path,
|
||||||
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
|
int* straightPathCount, const int maxStraightPath, const int options) const
|
||||||
|
{
|
||||||
|
const float* startPos = &straightPath[(*straightPathCount-1)*3];
|
||||||
|
// Append or update last vertex
|
||||||
|
dtStatus stat = 0;
|
||||||
|
for (int i = startIdx; i < endIdx; i++)
|
||||||
|
{
|
||||||
|
// Calculate portal
|
||||||
|
const dtPolyRef from = path[i];
|
||||||
|
const dtMeshTile* fromTile = 0;
|
||||||
|
const dtPoly* fromPoly = 0;
|
||||||
|
if (dtStatusFailed(m_nav->getTileAndPolyByRef(from, &fromTile, &fromPoly)))
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
const dtPolyRef to = path[i+1];
|
||||||
|
const dtMeshTile* toTile = 0;
|
||||||
|
const dtPoly* toPoly = 0;
|
||||||
|
if (dtStatusFailed(m_nav->getTileAndPolyByRef(to, &toTile, &toPoly)))
|
||||||
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
float left[3], right[3];
|
||||||
|
if (dtStatusFailed(getPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, left, right)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (options & DT_STRAIGHTPATH_AREA_CROSSINGS)
|
||||||
|
{
|
||||||
|
// Skip intersection if only area crossings are requested.
|
||||||
|
if (fromPoly->getArea() == toPoly->getArea())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append intersection
|
||||||
|
float s,t;
|
||||||
|
if (dtIntersectSegSeg2D(startPos, endPos, left, right, s, t))
|
||||||
|
{
|
||||||
|
float pt[3];
|
||||||
|
dtVlerp(pt, left,right, t);
|
||||||
|
|
||||||
|
stat = appendVertex(pt, 0, path[i+1],
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath);
|
||||||
|
if (stat != DT_IN_PROGRESS)
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DT_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// This method peforms what is often called 'string pulling'.
|
/// This method peforms what is often called 'string pulling'.
|
||||||
@ -1563,7 +1641,7 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing
|
|||||||
dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos,
|
dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos,
|
||||||
const dtPolyRef* path, const int pathSize,
|
const dtPolyRef* path, const int pathSize,
|
||||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||||
int* straightPathCount, const int maxStraightPath) const
|
int* straightPathCount, const int maxStraightPath, const int options) const
|
||||||
{
|
{
|
||||||
dtAssert(m_nav);
|
dtAssert(m_nav);
|
||||||
|
|
||||||
@ -1575,30 +1653,24 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
if (!path[0])
|
if (!path[0])
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
int n = 0;
|
dtStatus stat = 0;
|
||||||
|
|
||||||
// TODO: Should this be callers responsibility?
|
// TODO: Should this be callers responsibility?
|
||||||
float closestStartPos[3];
|
float closestStartPos[3];
|
||||||
if (dtStatusFailed(closestPointOnPolyBoundary(path[0], startPos, closestStartPos)))
|
if (dtStatusFailed(closestPointOnPolyBoundary(path[0], startPos, closestStartPos)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
// Add start point.
|
|
||||||
dtVcopy(&straightPath[n*3], closestStartPos);
|
|
||||||
if (straightPathFlags)
|
|
||||||
straightPathFlags[n] = DT_STRAIGHTPATH_START;
|
|
||||||
if (straightPathRefs)
|
|
||||||
straightPathRefs[n] = path[0];
|
|
||||||
n++;
|
|
||||||
if (n >= maxStraightPath)
|
|
||||||
{
|
|
||||||
*straightPathCount = n;
|
|
||||||
return DT_SUCCESS | DT_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
float closestEndPos[3];
|
float closestEndPos[3];
|
||||||
if (dtStatusFailed(closestPointOnPolyBoundary(path[pathSize-1], endPos, closestEndPos)))
|
if (dtStatusFailed(closestPointOnPolyBoundary(path[pathSize-1], endPos, closestEndPos)))
|
||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
|
|
||||||
|
// Add start point.
|
||||||
|
stat = appendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0],
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath);
|
||||||
|
if (stat != DT_IN_PROGRESS)
|
||||||
|
return stat;
|
||||||
|
|
||||||
if (pathSize > 1)
|
if (pathSize > 1)
|
||||||
{
|
{
|
||||||
float portalApex[3], portalLeft[3], portalRight[3];
|
float portalApex[3], portalLeft[3], portalRight[3];
|
||||||
@ -1634,16 +1706,19 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
return DT_FAILURE | DT_INVALID_PARAM;
|
return DT_FAILURE | DT_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dtVcopy(&straightPath[n*3], closestEndPos);
|
// Apeend portals along the current straight path segment.
|
||||||
if (straightPathFlags)
|
if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||||
straightPathFlags[n] = 0;
|
{
|
||||||
if (straightPathRefs)
|
stat = appendPortals(apexIndex, i, closestEndPos, path,
|
||||||
straightPathRefs[n] = path[i];
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
n++;
|
straightPathCount, maxStraightPath, options);
|
||||||
|
}
|
||||||
|
|
||||||
*straightPathCount = n;
|
stat = appendVertex(closestEndPos, 0, path[i],
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath);
|
||||||
|
|
||||||
return DT_SUCCESS | DT_PARTIAL_RESULT | ((n >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
return DT_SUCCESS | DT_PARTIAL_RESULT | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If starting really close the portal, advance.
|
// If starting really close the portal, advance.
|
||||||
@ -1675,6 +1750,16 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Append portals along the current straight path segment.
|
||||||
|
if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||||
|
{
|
||||||
|
stat = appendPortals(apexIndex, leftIndex, portalLeft, path,
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath, options);
|
||||||
|
if (stat != DT_IN_PROGRESS)
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
dtVcopy(portalApex, portalLeft);
|
dtVcopy(portalApex, portalLeft);
|
||||||
apexIndex = leftIndex;
|
apexIndex = leftIndex;
|
||||||
|
|
||||||
@ -1685,30 +1770,12 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION;
|
flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION;
|
||||||
dtPolyRef ref = leftPolyRef;
|
dtPolyRef ref = leftPolyRef;
|
||||||
|
|
||||||
if (!dtVequal(&straightPath[(n-1)*3], portalApex))
|
// Append or update vertex
|
||||||
{
|
stat = appendVertex(portalApex, flags, ref,
|
||||||
// Append new vertex.
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
dtVcopy(&straightPath[n*3], portalApex);
|
straightPathCount, maxStraightPath);
|
||||||
if (straightPathFlags)
|
if (stat != DT_IN_PROGRESS)
|
||||||
straightPathFlags[n] = flags;
|
return stat;
|
||||||
if (straightPathRefs)
|
|
||||||
straightPathRefs[n] = ref;
|
|
||||||
n++;
|
|
||||||
// If reached end of path or there is no space to append more vertices, return.
|
|
||||||
if (flags == DT_STRAIGHTPATH_END || n >= maxStraightPath)
|
|
||||||
{
|
|
||||||
*straightPathCount = n;
|
|
||||||
return DT_SUCCESS | ((n >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The vertices are equal, update flags and poly.
|
|
||||||
if (straightPathFlags)
|
|
||||||
straightPathFlags[n-1] = flags;
|
|
||||||
if (straightPathRefs)
|
|
||||||
straightPathRefs[n-1] = ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
dtVcopy(portalLeft, portalApex);
|
dtVcopy(portalLeft, portalApex);
|
||||||
dtVcopy(portalRight, portalApex);
|
dtVcopy(portalRight, portalApex);
|
||||||
@ -1734,6 +1801,16 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Append portals along the current straight path segment.
|
||||||
|
if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||||
|
{
|
||||||
|
stat = appendPortals(apexIndex, rightIndex, portalRight, path,
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath, options);
|
||||||
|
if (stat != DT_IN_PROGRESS)
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
dtVcopy(portalApex, portalRight);
|
dtVcopy(portalApex, portalRight);
|
||||||
apexIndex = rightIndex;
|
apexIndex = rightIndex;
|
||||||
|
|
||||||
@ -1744,30 +1821,12 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION;
|
flags = DT_STRAIGHTPATH_OFFMESH_CONNECTION;
|
||||||
dtPolyRef ref = rightPolyRef;
|
dtPolyRef ref = rightPolyRef;
|
||||||
|
|
||||||
if (!dtVequal(&straightPath[(n-1)*3], portalApex))
|
// Append or update vertex
|
||||||
{
|
stat = appendVertex(portalApex, flags, ref,
|
||||||
// Append new vertex.
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
dtVcopy(&straightPath[n*3], portalApex);
|
straightPathCount, maxStraightPath);
|
||||||
if (straightPathFlags)
|
if (stat != DT_IN_PROGRESS)
|
||||||
straightPathFlags[n] = flags;
|
return stat;
|
||||||
if (straightPathRefs)
|
|
||||||
straightPathRefs[n] = ref;
|
|
||||||
n++;
|
|
||||||
// If reached end of path or there is no space to append more vertices, return.
|
|
||||||
if (flags == DT_STRAIGHTPATH_END || n >= maxStraightPath)
|
|
||||||
{
|
|
||||||
*straightPathCount = n;
|
|
||||||
return DT_SUCCESS | ((n >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The vertices are equal, update flags and poly.
|
|
||||||
if (straightPathFlags)
|
|
||||||
straightPathFlags[n-1] = flags;
|
|
||||||
if (straightPathRefs)
|
|
||||||
straightPathRefs[n-1] = ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
dtVcopy(portalLeft, portalApex);
|
dtVcopy(portalLeft, portalApex);
|
||||||
dtVcopy(portalRight, portalApex);
|
dtVcopy(portalRight, portalApex);
|
||||||
@ -1781,26 +1840,23 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the point already exists, remove it and add reappend the actual end location.
|
// Append portals along the current straight path segment.
|
||||||
if (n > 0 && dtVequal(&straightPath[(n-1)*3], closestEndPos))
|
if (options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||||
n--;
|
|
||||||
|
|
||||||
// Add end point.
|
|
||||||
if (n < maxStraightPath)
|
|
||||||
{
|
{
|
||||||
dtVcopy(&straightPath[n*3], closestEndPos);
|
stat = appendPortals(apexIndex, pathSize-1, closestEndPos, path,
|
||||||
if (straightPathFlags)
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
straightPathFlags[n] = DT_STRAIGHTPATH_END;
|
straightPathCount, maxStraightPath, options);
|
||||||
if (straightPathRefs)
|
if (stat != DT_IN_PROGRESS)
|
||||||
straightPathRefs[n] = 0;
|
return stat;
|
||||||
n++;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*straightPathCount = n;
|
stat = appendVertex(closestEndPos, DT_STRAIGHTPATH_END, 0,
|
||||||
|
straightPath, straightPathFlags, straightPathRefs,
|
||||||
|
straightPathCount, maxStraightPath);
|
||||||
|
|
||||||
return DT_SUCCESS | ((n >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
return DT_SUCCESS | ((*straightPathCount >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -40,7 +40,7 @@ private:
|
|||||||
void addTriangle(int a, int b, int c, int& cap);
|
void addTriangle(int a, int b, int c, int& cap);
|
||||||
|
|
||||||
char m_filename[260];
|
char m_filename[260];
|
||||||
|
float m_scale;
|
||||||
float* m_verts;
|
float* m_verts;
|
||||||
int* m_tris;
|
int* m_tris;
|
||||||
float* m_normals;
|
float* m_normals;
|
||||||
|
@ -48,6 +48,8 @@ class NavMeshTesterTool : public SampleTool
|
|||||||
|
|
||||||
ToolMode m_toolMode;
|
ToolMode m_toolMode;
|
||||||
|
|
||||||
|
int m_straightPathOptions;
|
||||||
|
|
||||||
static const int MAX_POLYS = 256;
|
static const int MAX_POLYS = 256;
|
||||||
static const int MAX_SMOOTH = 2048;
|
static const int MAX_SMOOTH = 2048;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
rcMeshLoaderObj::rcMeshLoaderObj() :
|
rcMeshLoaderObj::rcMeshLoaderObj() :
|
||||||
|
m_scale(1.0f),
|
||||||
m_verts(0),
|
m_verts(0),
|
||||||
m_tris(0),
|
m_tris(0),
|
||||||
m_normals(0),
|
m_normals(0),
|
||||||
@ -51,9 +52,9 @@ void rcMeshLoaderObj::addVertex(float x, float y, float z, int& cap)
|
|||||||
m_verts = nv;
|
m_verts = nv;
|
||||||
}
|
}
|
||||||
float* dst = &m_verts[m_vertCount*3];
|
float* dst = &m_verts[m_vertCount*3];
|
||||||
*dst++ = x;
|
*dst++ = x*m_scale;
|
||||||
*dst++ = y;
|
*dst++ = y*m_scale;
|
||||||
*dst++ = z;
|
*dst++ = z*m_scale;
|
||||||
m_vertCount++;
|
m_vertCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ NavMeshTesterTool::NavMeshTesterTool() :
|
|||||||
m_navQuery(0),
|
m_navQuery(0),
|
||||||
m_pathFindStatus(DT_FAILURE),
|
m_pathFindStatus(DT_FAILURE),
|
||||||
m_toolMode(TOOLMODE_PATHFIND_FOLLOW),
|
m_toolMode(TOOLMODE_PATHFIND_FOLLOW),
|
||||||
|
m_straightPathOptions(0),
|
||||||
m_startRef(0),
|
m_startRef(0),
|
||||||
m_endRef(0),
|
m_endRef(0),
|
||||||
m_npolys(0),
|
m_npolys(0),
|
||||||
@ -218,6 +219,28 @@ void NavMeshTesterTool::handleMenu()
|
|||||||
m_toolMode = TOOLMODE_PATHFIND_STRAIGHT;
|
m_toolMode = TOOLMODE_PATHFIND_STRAIGHT;
|
||||||
recalc();
|
recalc();
|
||||||
}
|
}
|
||||||
|
if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||||
|
{
|
||||||
|
imguiIndent();
|
||||||
|
imguiLabel("Vertices at crossings");
|
||||||
|
if (imguiCheck("None", m_straightPathOptions == 0))
|
||||||
|
{
|
||||||
|
m_straightPathOptions = 0;
|
||||||
|
recalc();
|
||||||
|
}
|
||||||
|
if (imguiCheck("Area", m_straightPathOptions == DT_STRAIGHTPATH_AREA_CROSSINGS))
|
||||||
|
{
|
||||||
|
m_straightPathOptions = DT_STRAIGHTPATH_AREA_CROSSINGS;
|
||||||
|
recalc();
|
||||||
|
}
|
||||||
|
if (imguiCheck("All", m_straightPathOptions == DT_STRAIGHTPATH_ALL_CROSSINGS))
|
||||||
|
{
|
||||||
|
m_straightPathOptions = DT_STRAIGHTPATH_ALL_CROSSINGS;
|
||||||
|
recalc();
|
||||||
|
}
|
||||||
|
|
||||||
|
imguiUnindent();
|
||||||
|
}
|
||||||
if (imguiCheck("Pathfind Sliced", m_toolMode == TOOLMODE_PATHFIND_SLICED))
|
if (imguiCheck("Pathfind Sliced", m_toolMode == TOOLMODE_PATHFIND_SLICED))
|
||||||
{
|
{
|
||||||
m_toolMode = TOOLMODE_PATHFIND_SLICED;
|
m_toolMode = TOOLMODE_PATHFIND_SLICED;
|
||||||
@ -772,7 +795,7 @@ void NavMeshTesterTool::recalc()
|
|||||||
|
|
||||||
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
|
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
|
||||||
m_straightPath, m_straightPathFlags,
|
m_straightPath, m_straightPathFlags,
|
||||||
m_straightPathPolys, &m_nstraightPath, MAX_POLYS);
|
m_straightPathPolys, &m_nstraightPath, MAX_POLYS, m_straightPathOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1033,7 +1056,8 @@ void NavMeshTesterTool::handleRender()
|
|||||||
dd.depthMask(true);
|
dd.depthMask(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT || m_toolMode == TOOLMODE_PATHFIND_SLICED)
|
else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT ||
|
||||||
|
m_toolMode == TOOLMODE_PATHFIND_SLICED)
|
||||||
{
|
{
|
||||||
duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol);
|
duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_startRef, startCol);
|
||||||
duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_endRef, endCol);
|
duDebugDrawNavMeshPoly(&dd, *m_navMesh, m_endRef, endCol);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user