forked from mirror/DotRecast
change ClosestPointOnPolyBoundary
This commit is contained in:
parent
0971bf2c3c
commit
8a5614eca4
|
@ -515,7 +515,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TrimInvalidPath(long safeRef, float[] safePos, DtNavMeshQuery navquery, IDtQueryFilter filter)
|
public bool TrimInvalidPath(long safeRef, float[] safePos, DtNavMeshQuery navquery, IDtQueryFilter filter)
|
||||||
{
|
{
|
||||||
// Keep valid path as far as possible.
|
// Keep valid path as far as possible.
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -524,7 +524,12 @@ namespace DotRecast.Detour.Crowd
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0)
|
if (m_path.Count == n)
|
||||||
|
{
|
||||||
|
// All valid, no need to fix.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (n == 0)
|
||||||
{
|
{
|
||||||
// The first polyref is bad, use current safe values.
|
// The first polyref is bad, use current safe values.
|
||||||
m_pos.Set(safePos);
|
m_pos.Set(safePos);
|
||||||
|
@ -533,16 +538,13 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
else if (n < m_path.Count)
|
else if (n < m_path.Count)
|
||||||
{
|
{
|
||||||
m_path = m_path.GetRange(0, n);
|
|
||||||
// The path is partially usable.
|
// The path is partially usable.
|
||||||
|
m_path = m_path.GetRange(0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp target pos to last poly
|
// Clamp target pos to last poly
|
||||||
var result = navquery.ClosestPointOnPolyBoundary(m_path[m_path.Count - 1], m_target);
|
navquery.ClosestPointOnPolyBoundary(m_path[m_path.Count - 1], m_target, out m_target);
|
||||||
if (result.Succeeded())
|
return true;
|
||||||
{
|
|
||||||
m_target = result.result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -448,35 +448,31 @@ namespace DotRecast.Detour
|
||||||
///
|
///
|
||||||
/// Much faster than ClosestPointOnPoly().
|
/// Much faster than ClosestPointOnPoly().
|
||||||
///
|
///
|
||||||
/// If the provided position lies within the polygon's xz-bounds (above or below),
|
/// If the provided position lies within the polygon's xz-bounds (above or below),
|
||||||
/// then @p pos and @p closest will be equal.
|
/// then @p pos and @p closest will be equal.
|
||||||
///
|
///
|
||||||
/// The height of @p closest will be the polygon boundary. The height detail is not used.
|
/// The height of @p closest will be the polygon boundary. The height detail is not used.
|
||||||
///
|
///
|
||||||
/// @p pos does not have to be within the bounds of the polybon or the navigation mesh.
|
/// @p pos does not have to be within the bounds of the polybon or the navigation mesh.
|
||||||
///
|
///
|
||||||
/// Returns a point on the boundary closest to the source point if the source point is outside the
|
/// Returns a point on the boundary closest to the source point if the source point is outside the
|
||||||
/// polygon's xz-bounds.
|
/// polygon's xz-bounds.
|
||||||
/// @param[in] ref The reference id to the polygon.
|
/// @param[in] ref The reference id to the polygon.
|
||||||
/// @param[in] pos The position to check. [(x, y, z)]
|
/// @param[in] pos The position to check. [(x, y, z)]
|
||||||
/// @param[out] closest The closest point. [(x, y, z)]
|
/// @param[out] closest The closest point. [(x, y, z)]
|
||||||
/// @returns The status flags for the query.
|
/// @returns The status flags for the query.
|
||||||
public Result<RcVec3f> ClosestPointOnPolyBoundary(long refs, RcVec3f pos)
|
public DtStatus ClosestPointOnPolyBoundary(long refs, RcVec3f pos, out RcVec3f closest)
|
||||||
{
|
{
|
||||||
|
closest = pos;
|
||||||
var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
|
var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
|
||||||
if (status.Failed())
|
if (status.Failed())
|
||||||
{
|
{
|
||||||
return Results.Of<RcVec3f>(status, "");
|
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile == null)
|
if (tile == null || !RcVec3f.IsFinite(pos))
|
||||||
{
|
{
|
||||||
return Results.InvalidParam<RcVec3f>("Invalid tile");
|
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||||
}
|
|
||||||
|
|
||||||
if (!RcVec3f.IsFinite(pos))
|
|
||||||
{
|
|
||||||
return Results.InvalidParam<RcVec3f>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect vertices.
|
// Collect vertices.
|
||||||
|
@ -489,7 +485,6 @@ namespace DotRecast.Detour
|
||||||
Array.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
|
Array.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
RcVec3f closest;
|
|
||||||
if (DetourCommon.DistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
|
if (DetourCommon.DistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
|
||||||
{
|
{
|
||||||
closest = pos;
|
closest = pos;
|
||||||
|
@ -513,7 +508,7 @@ namespace DotRecast.Detour
|
||||||
closest = RcVec3f.Lerp(verts, va, vb, edget[imin]);
|
closest = RcVec3f.Lerp(verts, va, vb, edget[imin]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Results.Success(closest);
|
return DtStatus.DT_SUCCSESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
@ -1545,20 +1540,18 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should this be callers responsibility?
|
// TODO: Should this be callers responsibility?
|
||||||
Result<RcVec3f> closestStartPosRes = ClosestPointOnPolyBoundary(path[0], startPos);
|
var closestStartPosRes = ClosestPointOnPolyBoundary(path[0], startPos, out var closestStartPos);
|
||||||
if (closestStartPosRes.Failed())
|
if (closestStartPosRes.Failed())
|
||||||
{
|
{
|
||||||
return Results.InvalidParam<List<StraightPathItem>>("Cannot find start position");
|
return Results.InvalidParam<List<StraightPathItem>>("Cannot find start position");
|
||||||
}
|
}
|
||||||
|
|
||||||
var closestStartPos = closestStartPosRes.result;
|
var closestEndPosRes = ClosestPointOnPolyBoundary(path[path.Count - 1], endPos, out var closestEndPos);
|
||||||
var closestEndPosRes = ClosestPointOnPolyBoundary(path[path.Count - 1], endPos);
|
|
||||||
if (closestEndPosRes.Failed())
|
if (closestEndPosRes.Failed())
|
||||||
{
|
{
|
||||||
return Results.InvalidParam<List<StraightPathItem>>("Cannot find end position");
|
return Results.InvalidParam<List<StraightPathItem>>("Cannot find end position");
|
||||||
}
|
}
|
||||||
|
|
||||||
var closestEndPos = closestEndPosRes.result;
|
|
||||||
// Add start point.
|
// Add start point.
|
||||||
DtStatus stat = AppendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], straightPath, maxStraightPath);
|
DtStatus stat = AppendVertex(closestStartPos, DT_STRAIGHTPATH_START, path[0], straightPath, maxStraightPath);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
|
@ -1592,18 +1585,17 @@ namespace DotRecast.Detour
|
||||||
int fromType; // // fromType is ignored.
|
int fromType; // // fromType is ignored.
|
||||||
|
|
||||||
// Next portal.
|
// Next portal.
|
||||||
var portalPoints = GetPortalPoints(path[i], path[i + 1], out left, out right, out fromType, out toType);
|
var ppStatus = GetPortalPoints(path[i], path[i + 1], out left, out right, out fromType, out toType);
|
||||||
if (portalPoints.Failed())
|
if (ppStatus.Failed())
|
||||||
{
|
{
|
||||||
// Failed to get portal points, in practice this means that path[i+1] is invalid polygon.
|
// Failed to get portal points, in practice this means that path[i+1] is invalid polygon.
|
||||||
// Clamp the end point to path[i], and return the path so far.
|
// Clamp the end point to path[i], and return the path so far.
|
||||||
closestEndPosRes = ClosestPointOnPolyBoundary(path[i], endPos);
|
var cpStatus = ClosestPointOnPolyBoundary(path[i], endPos, out closestEndPos);
|
||||||
if (closestEndPosRes.Failed())
|
if (cpStatus.Failed())
|
||||||
{
|
{
|
||||||
return Results.InvalidParam<List<StraightPathItem>>();
|
return Results.InvalidParam<List<StraightPathItem>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
closestEndPos = closestEndPosRes.result;
|
|
||||||
// Append portals along the current straight path segment.
|
// Append portals along the current straight path segment.
|
||||||
if ((options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
if ((options & (DT_STRAIGHTPATH_AREA_CROSSINGS | DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue