forked from mirror/DotRecast
Changed `List<DtStraightPath>` to `Span<DtStraightPath>` for enhanced memory efficiency
This commit is contained in:
parent
5b6905bd8f
commit
99224251dc
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Changed `DtTileCacheLayerHeaderReader` to a static class
|
- Changed `DtTileCacheLayerHeaderReader` to a static class
|
||||||
- Changed `Dictionary<int, List<DtMeshTile>>` to `DtMeshTile[]` to optimize memory usage
|
- Changed `Dictionary<int, List<DtMeshTile>>` to `DtMeshTile[]` to optimize memory usage
|
||||||
- Changed `MAX_STEER_POINTS` from class constant to local.
|
- Changed `MAX_STEER_POINTS` from class constant to local.
|
||||||
|
- Changed `List<DtStraightPath>` to `Span<DtStraightPath>` for enhanced memory efficiency
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Nothing
|
- Nothing
|
||||||
|
|
|
@ -944,13 +944,13 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find corners for steering
|
// Find corners for steering
|
||||||
ag.corridor.FindCorners(ref ag.corners, DtCrowdConst.DT_CROWDAGENT_MAX_CORNERS, _navQuery, _filters[ag.option.queryFilterType]);
|
ag.ncorners = ag.corridor.FindCorners(ag.corners, DtCrowdConst.DT_CROWDAGENT_MAX_CORNERS, _navQuery, _filters[ag.option.queryFilterType]);
|
||||||
|
|
||||||
// Check to see if the corner after the next corner is directly visible,
|
// Check to see if the corner after the next corner is directly visible,
|
||||||
// and short cut to there.
|
// and short cut to there.
|
||||||
if ((ag.option.updateFlags & DtCrowdAgentUpdateFlags.DT_CROWD_OPTIMIZE_VIS) != 0 && ag.corners.Count > 0)
|
if ((ag.option.updateFlags & DtCrowdAgentUpdateFlags.DT_CROWD_OPTIMIZE_VIS) != 0 && ag.ncorners > 0)
|
||||||
{
|
{
|
||||||
RcVec3f target = ag.corners[Math.Min(1, ag.corners.Count - 1)].pos;
|
RcVec3f target = ag.corners[Math.Min(1, ag.ncorners - 1)].pos;
|
||||||
ag.corridor.OptimizePathVisibility(target, ag.option.pathOptimizationRange, _navQuery,
|
ag.corridor.OptimizePathVisibility(target, ag.option.pathOptimizationRange, _navQuery,
|
||||||
_filters[ag.option.queryFilterType]);
|
_filters[ag.option.queryFilterType]);
|
||||||
|
|
||||||
|
@ -1000,7 +1000,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
// Adjust the path over the off-mesh connection.
|
// Adjust the path over the off-mesh connection.
|
||||||
long[] refs = new long[2];
|
long[] refs = new long[2];
|
||||||
if (ag.corridor.MoveOverOffmeshConnection(ag.corners[ag.corners.Count - 1].refs, refs, ref anim.startPos,
|
if (ag.corridor.MoveOverOffmeshConnection(ag.corners[ag.ncorners - 1].refs, refs, ref anim.startPos,
|
||||||
ref anim.endPos, _navQuery))
|
ref anim.endPos, _navQuery))
|
||||||
{
|
{
|
||||||
anim.initPos = ag.npos;
|
anim.initPos = ag.npos;
|
||||||
|
@ -1010,7 +1010,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
anim.tmax = (RcVecUtils.Dist2D(anim.startPos, anim.endPos) / ag.option.maxSpeed) * 0.5f;
|
anim.tmax = (RcVecUtils.Dist2D(anim.startPos, anim.endPos) / ag.option.maxSpeed) * 0.5f;
|
||||||
|
|
||||||
ag.state = DtCrowdAgentState.DT_CROWDAGENT_STATE_OFFMESH;
|
ag.state = DtCrowdAgentState.DT_CROWDAGENT_STATE_OFFMESH;
|
||||||
ag.corners.Clear();
|
ag.ncorners = 0;
|
||||||
ag.neis.Clear();
|
ag.neis.Clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
public DtCrowdAgentParams option;
|
public DtCrowdAgentParams option;
|
||||||
|
|
||||||
/// The local path corridor corners for the agent.
|
/// The local path corridor corners for the agent.
|
||||||
public List<DtStraightPath> corners = new List<DtStraightPath>();
|
public DtStraightPath[] corners = new DtStraightPath[DtCrowdConst.DT_CROWDAGENT_MAX_CORNERS];
|
||||||
|
|
||||||
|
/// The number of corners.
|
||||||
|
public int ncorners;
|
||||||
|
|
||||||
public DtMoveRequestState targetState; // < State of the movement request.
|
public DtMoveRequestState targetState; // < State of the movement request.
|
||||||
public long targetRef; // < Target polyref of the movement request.
|
public long targetRef; // < Target polyref of the movement request.
|
||||||
|
@ -100,16 +103,16 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
public bool OverOffmeshConnection(float radius)
|
public bool OverOffmeshConnection(float radius)
|
||||||
{
|
{
|
||||||
if (0 == corners.Count)
|
if (0 == ncorners)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool offMeshConnection = ((corners[corners.Count - 1].flags
|
bool offMeshConnection = ((corners[ncorners - 1].flags
|
||||||
& DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
& DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
||||||
? true
|
? true
|
||||||
: false;
|
: false;
|
||||||
if (offMeshConnection)
|
if (offMeshConnection)
|
||||||
{
|
{
|
||||||
float distSq = RcVecUtils.Dist2DSqr(npos, corners[corners.Count - 1].pos);
|
float distSq = RcVecUtils.Dist2DSqr(npos, corners[ncorners - 1].pos);
|
||||||
if (distSq < radius * radius)
|
if (distSq < radius * radius)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -119,12 +122,12 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
public float GetDistanceToGoal(float range)
|
public float GetDistanceToGoal(float range)
|
||||||
{
|
{
|
||||||
if (0 == corners.Count)
|
if (0 == ncorners)
|
||||||
return range;
|
return range;
|
||||||
|
|
||||||
bool endOfPath = ((corners[corners.Count - 1].flags & DtStraightPathFlags.DT_STRAIGHTPATH_END) != 0) ? true : false;
|
bool endOfPath = ((corners[ncorners - 1].flags & DtStraightPathFlags.DT_STRAIGHTPATH_END) != 0) ? true : false;
|
||||||
if (endOfPath)
|
if (endOfPath)
|
||||||
return Math.Min(RcVecUtils.Dist2D(npos, corners[corners.Count - 1].pos), range);
|
return Math.Min(RcVecUtils.Dist2D(npos, corners[ncorners - 1].pos), range);
|
||||||
|
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
@ -132,10 +135,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
public RcVec3f CalcSmoothSteerDirection()
|
public RcVec3f CalcSmoothSteerDirection()
|
||||||
{
|
{
|
||||||
RcVec3f dir = new RcVec3f();
|
RcVec3f dir = new RcVec3f();
|
||||||
if (0 < corners.Count)
|
if (0 < ncorners)
|
||||||
{
|
{
|
||||||
int ip0 = 0;
|
int ip0 = 0;
|
||||||
int ip1 = Math.Min(1, corners.Count - 1);
|
int ip1 = Math.Min(1, ncorners - 1);
|
||||||
var p0 = corners[ip0].pos;
|
var p0 = corners[ip0].pos;
|
||||||
var p1 = corners[ip1].pos;
|
var p1 = corners[ip1].pos;
|
||||||
|
|
||||||
|
@ -161,7 +164,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
public RcVec3f CalcStraightSteerDirection()
|
public RcVec3f CalcStraightSteerDirection()
|
||||||
{
|
{
|
||||||
RcVec3f dir = new RcVec3f();
|
RcVec3f dir = new RcVec3f();
|
||||||
if (0 < corners.Count)
|
if (0 < ncorners)
|
||||||
{
|
{
|
||||||
dir = RcVec3f.Subtract(corners[0].pos, npos);
|
dir = RcVec3f.Subtract(corners[0].pos, npos);
|
||||||
dir.Y = 0;
|
dir.Y = 0;
|
||||||
|
|
|
@ -133,42 +133,42 @@ namespace DotRecast.Detour.Crowd
|
||||||
/// @param[in] navquery The query object used to build the corridor.
|
/// @param[in] navquery The query object used to build the corridor.
|
||||||
/// @param[in] filter The filter to apply to the operation.
|
/// @param[in] filter The filter to apply to the operation.
|
||||||
/// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners]
|
/// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners]
|
||||||
public int FindCorners(ref List<DtStraightPath> corners, int maxCorners, DtNavMeshQuery navquery, IDtQueryFilter filter)
|
public int FindCorners(Span<DtStraightPath> corners, int maxCorners, DtNavMeshQuery navquery, IDtQueryFilter filter)
|
||||||
{
|
{
|
||||||
const float MIN_TARGET_DIST = 0.01f;
|
const float MIN_TARGET_DIST = 0.01f;
|
||||||
|
|
||||||
var result = navquery.FindStraightPath(m_pos, m_target, m_path, m_npath, ref corners, maxCorners, 0);
|
int ncorners = 0;
|
||||||
if (result.Succeeded())
|
navquery.FindStraightPath(m_pos, m_target, m_path, m_npath, corners, out ncorners, maxCorners, 0);
|
||||||
{
|
|
||||||
// Prune points in the beginning of the path which are too close.
|
// Prune points in the beginning of the path which are too close.
|
||||||
int start = 0;
|
while (0 < ncorners)
|
||||||
foreach (DtStraightPath spi in corners)
|
|
||||||
{
|
{
|
||||||
if ((spi.flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0
|
if ((corners[0].flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ||
|
||||||
|| RcVecUtils.Dist2DSqr(spi.pos, m_pos) > RcMath.Sqr(MIN_TARGET_DIST))
|
RcVecUtils.Dist2DSqr(corners[0].pos, m_pos) > RcMath.Sqr(MIN_TARGET_DIST))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
start++;
|
ncorners--;
|
||||||
|
if (0 < ncorners)
|
||||||
|
{
|
||||||
|
RcSpans.Move(corners, 1, 0, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int end = corners.Count;
|
|
||||||
// Prune points after an off-mesh connection.
|
// Prune points after an off-mesh connection.
|
||||||
for (int i = start; i < corners.Count; i++)
|
for (int i = 0; i < ncorners; ++i)
|
||||||
{
|
{
|
||||||
DtStraightPath spi = corners[i];
|
if ((corners[i].flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
||||||
if ((spi.flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
|
||||||
{
|
{
|
||||||
end = i + 1;
|
ncorners = i + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
corners = corners.GetRange(start, end - start);
|
|
||||||
}
|
|
||||||
|
|
||||||
return corners.Count;
|
return ncorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,9 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using DotRecast.Core.Collections;
|
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Detour
|
namespace DotRecast.Detour
|
||||||
|
@ -1485,24 +1483,27 @@ namespace DotRecast.Detour
|
||||||
return DtStatus.DT_SUCCESS | details;
|
return DtStatus.DT_SUCCESS | details;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DtStatus AppendVertex(RcVec3f pos, int flags, long refs, ref List<DtStraightPath> straightPath,
|
protected DtStatus AppendVertex(RcVec3f pos, int flags, long refs, Span<DtStraightPath> straightPath, ref int straightPathCount, int maxStraightPath)
|
||||||
int maxStraightPath)
|
|
||||||
{
|
{
|
||||||
if (straightPath.Count > 0 && DtUtils.VEqual(straightPath[straightPath.Count - 1].pos, pos))
|
if (straightPathCount > 0 && DtUtils.VEqual(straightPath[straightPathCount - 1].pos, pos))
|
||||||
{
|
{
|
||||||
// The vertices are equal, update flags and poly.
|
// The vertices are equal, update flags and poly.
|
||||||
straightPath[straightPath.Count - 1] = new DtStraightPath(straightPath[straightPath.Count - 1].pos, flags, refs);
|
straightPath[straightPathCount - 1] = new DtStraightPath(straightPath[straightPathCount - 1].pos, flags, refs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (straightPath.Count < maxStraightPath)
|
|
||||||
{
|
{
|
||||||
// Append new vertex.
|
// Append new vertex.
|
||||||
straightPath.Add(new DtStraightPath(pos, flags, refs));
|
straightPath[straightPathCount] = new DtStraightPath(pos, flags, refs);
|
||||||
|
straightPathCount++;
|
||||||
|
|
||||||
|
// If there is no space to append more vertices, return.
|
||||||
|
if (straightPathCount >= maxStraightPath)
|
||||||
|
{
|
||||||
|
return DtStatus.DT_SUCCESS | DtStatus.DT_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If reached end of path or there is no space to append more vertices, return.
|
// If reached end of path, return.
|
||||||
if (flags == DtStraightPathFlags.DT_STRAIGHTPATH_END || straightPath.Count >= maxStraightPath)
|
if (flags == DtStraightPathFlags.DT_STRAIGHTPATH_END)
|
||||||
{
|
{
|
||||||
return DtStatus.DT_SUCCESS;
|
return DtStatus.DT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1512,9 +1513,9 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DtStatus AppendPortals(int startIdx, int endIdx, RcVec3f endPos, List<long> path,
|
protected DtStatus AppendPortals(int startIdx, int endIdx, RcVec3f endPos, List<long> path,
|
||||||
ref List<DtStraightPath> straightPath, int maxStraightPath, int options)
|
Span<DtStraightPath> straightPath, ref int straightPathCount, int maxStraightPath, int options)
|
||||||
{
|
{
|
||||||
var startPos = straightPath[straightPath.Count - 1].pos;
|
var startPos = straightPath[straightPathCount - 1].pos;
|
||||||
// Append or update last vertex
|
// Append or update last vertex
|
||||||
DtStatus stat;
|
DtStatus stat;
|
||||||
for (int i = startIdx; i < endIdx; i++)
|
for (int i = startIdx; i < endIdx; i++)
|
||||||
|
@ -1553,7 +1554,7 @@ namespace DotRecast.Detour
|
||||||
if (DtUtils.IntersectSegSeg2D(startPos, endPos, left, right, out var _, out var t))
|
if (DtUtils.IntersectSegSeg2D(startPos, endPos, left, right, out var _, out var t))
|
||||||
{
|
{
|
||||||
var pt = RcVec3f.Lerp(left, right, t);
|
var pt = RcVec3f.Lerp(left, right, t);
|
||||||
stat = AppendVertex(pt, 0, path[i + 1], ref straightPath, maxStraightPath);
|
stat = AppendVertex(pt, 0, path[i + 1], straightPath, ref straightPathCount, maxStraightPath);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1590,17 +1591,22 @@ namespace DotRecast.Detour
|
||||||
/// @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)
|
/// @param[in] options Query options. (see: #dtStraightPathOptions)
|
||||||
/// @returns The status flags for the query.
|
/// @returns The status flags for the query.
|
||||||
public virtual DtStatus FindStraightPath(RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
|
public virtual DtStatus FindStraightPath(RcVec3f startPos, RcVec3f endPos,
|
||||||
ref List<DtStraightPath> straightPath,
|
List<long> path, int pathSize,
|
||||||
int maxStraightPath, int options)
|
Span<DtStraightPath> straightPath, out int straightPathCount, int maxStraightPath,
|
||||||
|
int options)
|
||||||
{
|
{
|
||||||
if (!startPos.IsFinite() || !endPos.IsFinite() || null == straightPath
|
straightPathCount = 0;
|
||||||
|| null == path || pathSize <= 0 || path[0] == 0 || maxStraightPath <= 0)
|
|
||||||
|
if (!startPos.IsFinite() || !endPos.IsFinite() ||
|
||||||
|
null == straightPath ||
|
||||||
|
null == path || pathSize <= 0 || path[0] == 0
|
||||||
|
|| maxStraightPath <= 0)
|
||||||
{
|
{
|
||||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
straightPath.Clear();
|
DtStatus stat = DtStatus.DT_STATUS_NOTHING;
|
||||||
|
|
||||||
// TODO: Should this be callers responsibility?
|
// TODO: Should this be callers responsibility?
|
||||||
var closestStartPosRes = ClosestPointOnPolyBoundary(path[0], startPos, out var closestStartPos);
|
var closestStartPosRes = ClosestPointOnPolyBoundary(path[0], startPos, out var closestStartPos);
|
||||||
|
@ -1616,7 +1622,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add start point.
|
// Add start point.
|
||||||
DtStatus stat = AppendVertex(closestStartPos, DtStraightPathFlags.DT_STRAIGHTPATH_START, path[0], ref straightPath, maxStraightPath);
|
stat = AppendVertex(closestStartPos, DtStraightPathFlags.DT_STRAIGHTPATH_START, path[0], straightPath, ref straightPathCount, maxStraightPath);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1663,13 +1669,13 @@ namespace DotRecast.Detour
|
||||||
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
||||||
{
|
{
|
||||||
// Ignore status return value as we're just about to return anyway.
|
// Ignore status return value as we're just about to return anyway.
|
||||||
AppendPortals(apexIndex, i, closestEndPos, path, ref straightPath, maxStraightPath, options);
|
AppendPortals(apexIndex, i, closestEndPos, path, straightPath, ref straightPathCount, maxStraightPath, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore status return value as we're just about to return anyway.
|
// Ignore status return value as we're just about to return anyway.
|
||||||
AppendVertex(closestEndPos, 0, path[i], ref straightPath, maxStraightPath);
|
AppendVertex(closestEndPos, 0, path[i], straightPath, ref straightPathCount, maxStraightPath);
|
||||||
|
|
||||||
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM | (straightPath.Count >= maxStraightPath ? DtStatus.DT_BUFFER_TOO_SMALL : DtStatus.DT_STATUS_NOTHING);
|
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM | (straightPathCount >= maxStraightPath ? DtStatus.DT_BUFFER_TOO_SMALL : DtStatus.DT_STATUS_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If starting really close the portal, advance.
|
// If starting really close the portal, advance.
|
||||||
|
@ -1705,7 +1711,7 @@ namespace DotRecast.Detour
|
||||||
// Append portals along the current straight path segment.
|
// Append portals along the current straight path segment.
|
||||||
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
||||||
{
|
{
|
||||||
stat = AppendPortals(apexIndex, leftIndex, portalLeft, path, ref straightPath, maxStraightPath, options);
|
stat = AppendPortals(apexIndex, leftIndex, portalLeft, path, straightPath, ref straightPathCount, maxStraightPath, options);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1728,7 +1734,7 @@ namespace DotRecast.Detour
|
||||||
long refs = leftPolyRef;
|
long refs = leftPolyRef;
|
||||||
|
|
||||||
// Append or update vertex
|
// Append or update vertex
|
||||||
stat = AppendVertex(portalApex, flags, refs, ref straightPath, maxStraightPath);
|
stat = AppendVertex(portalApex, flags, refs, straightPath, ref straightPathCount, maxStraightPath);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1761,7 +1767,7 @@ namespace DotRecast.Detour
|
||||||
// Append portals along the current straight path segment.
|
// Append portals along the current straight path segment.
|
||||||
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
||||||
{
|
{
|
||||||
stat = AppendPortals(apexIndex, rightIndex, portalRight, path, ref straightPath, maxStraightPath, options);
|
stat = AppendPortals(apexIndex, rightIndex, portalRight, path, straightPath, ref straightPathCount, maxStraightPath, options);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1784,7 +1790,7 @@ namespace DotRecast.Detour
|
||||||
long refs = rightPolyRef;
|
long refs = rightPolyRef;
|
||||||
|
|
||||||
// Append or update vertex
|
// Append or update vertex
|
||||||
stat = AppendVertex(portalApex, flags, refs, ref straightPath, maxStraightPath);
|
stat = AppendVertex(portalApex, flags, refs, straightPath, ref straightPathCount, maxStraightPath);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1806,7 +1812,7 @@ namespace DotRecast.Detour
|
||||||
// Append portals along the current straight path segment.
|
// Append portals along the current straight path segment.
|
||||||
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
if ((options & (DtStraightPathOptions.DT_STRAIGHTPATH_AREA_CROSSINGS | DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS)) != 0)
|
||||||
{
|
{
|
||||||
stat = AppendPortals(apexIndex, pathSize - 1, closestEndPos, path, ref straightPath, maxStraightPath, options);
|
stat = AppendPortals(apexIndex, pathSize - 1, closestEndPos, path, straightPath, ref straightPathCount, maxStraightPath, options);
|
||||||
if (!stat.InProgress())
|
if (!stat.InProgress())
|
||||||
{
|
{
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -1815,8 +1821,8 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore status return value as we're just about to return anyway.
|
// Ignore status return value as we're just about to return anyway.
|
||||||
AppendVertex(closestEndPos, DtStraightPathFlags.DT_STRAIGHTPATH_END, 0, ref straightPath, maxStraightPath);
|
AppendVertex(closestEndPos, DtStraightPathFlags.DT_STRAIGHTPATH_END, 0, straightPath, ref straightPathCount, maxStraightPath);
|
||||||
return DtStatus.DT_SUCCESS | (straightPath.Count >= maxStraightPath ? DtStatus.DT_BUFFER_TOO_SMALL : DtStatus.DT_STATUS_NOTHING);
|
return DtStatus.DT_SUCCESS | (straightPathCount >= maxStraightPath ? DtStatus.DT_BUFFER_TOO_SMALL : DtStatus.DT_STATUS_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
|
namespace DotRecast.Detour
|
||||||
|
{
|
||||||
|
public class DtNavMeshQueryMock : DtNavMeshQuery
|
||||||
|
{
|
||||||
|
private readonly DtStraightPath[] _straightPath;
|
||||||
|
private readonly DtStatus _status;
|
||||||
|
|
||||||
|
public DtNavMeshQueryMock(DtStraightPath[] straightPath, DtStatus status)
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
_straightPath = straightPath;
|
||||||
|
_status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DtStatus FindStraightPath(RcVec3f startPos, RcVec3f endPos,
|
||||||
|
List<long> path, int pathSize,
|
||||||
|
Span<DtStraightPath> straightPath, out int straightPathCount, int maxStraightPath,
|
||||||
|
int options)
|
||||||
|
{
|
||||||
|
straightPathCount = 0;
|
||||||
|
for (int i = 0; i < _straightPath.Length && i < maxStraightPath; ++i)
|
||||||
|
{
|
||||||
|
straightPath[i] = _straightPath[i];
|
||||||
|
straightPathCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,8 +40,8 @@ namespace DotRecast.Detour
|
||||||
steerPosRef = 0;
|
steerPosRef = 0;
|
||||||
|
|
||||||
// Find steer target.
|
// Find steer target.
|
||||||
var straightPath = new List<DtStraightPath>(MAX_STEER_POINTS);
|
Span<DtStraightPath> straightPath = stackalloc DtStraightPath[MAX_STEER_POINTS];
|
||||||
var result = navQuery.FindStraightPath(startPos, endPos, path, pathSize, ref straightPath, MAX_STEER_POINTS, 0);
|
var result = navQuery.FindStraightPath(startPos, endPos, path, pathSize, straightPath, out var nsteerPath, MAX_STEER_POINTS, 0);
|
||||||
if (result.Failed())
|
if (result.Failed())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -49,7 +49,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
// Find vertex far enough to steer to.
|
// Find vertex far enough to steer to.
|
||||||
int ns = 0;
|
int ns = 0;
|
||||||
while (ns < straightPath.Count)
|
while (ns < nsteerPath)
|
||||||
{
|
{
|
||||||
// Stop at Off-Mesh link or when point is further than slop away.
|
// Stop at Off-Mesh link or when point is further than slop away.
|
||||||
if (((straightPath[ns].flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
if (((straightPath[ns].flags & DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
||||||
|
@ -59,7 +59,7 @@ namespace DotRecast.Detour
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failed to find good point to steer to.
|
// Failed to find good point to steer to.
|
||||||
if (ns >= straightPath.Count)
|
if (ns >= nsteerPath)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
steerPos = straightPath[ns].pos;
|
steerPos = straightPath[ns].pos;
|
||||||
|
|
|
@ -251,10 +251,10 @@ public class CrowdSampleTool : ISampleTool
|
||||||
|
|
||||||
if (_showCorners)
|
if (_showCorners)
|
||||||
{
|
{
|
||||||
if (0 < ag.corners.Count)
|
if (0 < ag.ncorners)
|
||||||
{
|
{
|
||||||
dd.Begin(LINES, 2.0f);
|
dd.Begin(LINES, 2.0f);
|
||||||
for (int j = 0; j < ag.corners.Count; ++j)
|
for (int j = 0; j < ag.ncorners; ++j)
|
||||||
{
|
{
|
||||||
RcVec3f va = j == 0 ? pos : ag.corners[j - 1].pos;
|
RcVec3f va = j == 0 ? pos : ag.corners[j - 1].pos;
|
||||||
RcVec3f vb = ag.corners[j].pos;
|
RcVec3f vb = ag.corners[j].pos;
|
||||||
|
@ -262,10 +262,10 @@ public class CrowdSampleTool : ISampleTool
|
||||||
dd.Vertex(vb.X, vb.Y + radius, vb.Z, DuRGBA(128, 0, 0, 192));
|
dd.Vertex(vb.X, vb.Y + radius, vb.Z, DuRGBA(128, 0, 0, 192));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ag.corners[ag.corners.Count - 1].flags
|
if ((ag.corners[ag.ncorners - 1].flags
|
||||||
& DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
& DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
|
||||||
{
|
{
|
||||||
RcVec3f v = ag.corners[ag.corners.Count - 1].pos;
|
RcVec3f v = ag.corners[ag.ncorners - 1].pos;
|
||||||
dd.Vertex(v.X, v.Y, v.Z, DuRGBA(192, 0, 0, 192));
|
dd.Vertex(v.X, v.Y, v.Z, DuRGBA(192, 0, 0, 192));
|
||||||
dd.Vertex(v.X, v.Y + radius * 2, v.Z, DuRGBA(192, 0, 0, 192));
|
dd.Vertex(v.X, v.Y + radius * 2, v.Z, DuRGBA(192, 0, 0, 192));
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
private bool m_hitResult;
|
private bool m_hitResult;
|
||||||
|
|
||||||
private float m_distanceToWall;
|
private float m_distanceToWall;
|
||||||
private List<DtStraightPath> m_straightPath;
|
private DtStraightPath[] m_straightPath;
|
||||||
|
private int m_straightPathCount;
|
||||||
private List<long> m_polys;
|
private List<long> m_polys;
|
||||||
private List<long> m_parent;
|
private List<long> m_parent;
|
||||||
private float m_neighbourhoodRadius;
|
private float m_neighbourhoodRadius;
|
||||||
|
@ -77,6 +78,8 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED,
|
SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED,
|
||||||
new float[] { 1f, 1f, 1f, 1f, 2f, 1.5f }
|
new float[] { 1f, 1f, 1f, 1f, 2f, 1.5f }
|
||||||
);
|
);
|
||||||
|
m_straightPath = new DtStraightPath[MAX_POLYS];
|
||||||
|
m_straightPathCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Layout()
|
public void Layout()
|
||||||
|
@ -284,7 +287,7 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
int spathCol = DuRGBA(64, 16, 0, 220);
|
int spathCol = DuRGBA(64, 16, 0, 220);
|
||||||
int offMeshCol = DuRGBA(128, 96, 0, 220);
|
int offMeshCol = DuRGBA(128, 96, 0, 220);
|
||||||
dd.Begin(LINES, 2.0f);
|
dd.Begin(LINES, 2.0f);
|
||||||
for (int i = 0; i < m_straightPath.Count - 1; ++i)
|
for (int i = 0; i < m_straightPathCount - 1; ++i)
|
||||||
{
|
{
|
||||||
DtStraightPath straightPathItem = m_straightPath[i];
|
DtStraightPath straightPathItem = m_straightPath[i];
|
||||||
DtStraightPath straightPathItem2 = m_straightPath[i + 1];
|
DtStraightPath straightPathItem2 = m_straightPath[i + 1];
|
||||||
|
@ -304,7 +307,7 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
|
|
||||||
dd.End();
|
dd.End();
|
||||||
dd.Begin(POINTS, 6.0f);
|
dd.Begin(POINTS, 6.0f);
|
||||||
for (int i = 0; i < m_straightPath.Count; ++i)
|
for (int i = 0; i < m_straightPathCount; ++i)
|
||||||
{
|
{
|
||||||
DtStraightPath straightPathItem = m_straightPath[i];
|
DtStraightPath straightPathItem = m_straightPath[i];
|
||||||
int col;
|
int col;
|
||||||
|
@ -349,7 +352,7 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
dd.DepthMask(false);
|
dd.DepthMask(false);
|
||||||
int spathCol = m_hitResult ? DuRGBA(64, 16, 0, 220) : DuRGBA(240, 240, 240, 220);
|
int spathCol = m_hitResult ? DuRGBA(64, 16, 0, 220) : DuRGBA(240, 240, 240, 220);
|
||||||
dd.Begin(LINES, 2.0f);
|
dd.Begin(LINES, 2.0f);
|
||||||
for (int i = 0; i < m_straightPath.Count - 1; ++i)
|
for (int i = 0; i < m_straightPathCount - 1; ++i)
|
||||||
{
|
{
|
||||||
DtStraightPath straightPathItem = m_straightPath[i];
|
DtStraightPath straightPathItem = m_straightPath[i];
|
||||||
DtStraightPath straightPathItem2 = m_straightPath[i + 1];
|
DtStraightPath straightPathItem2 = m_straightPath[i + 1];
|
||||||
|
@ -359,7 +362,7 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
|
|
||||||
dd.End();
|
dd.End();
|
||||||
dd.Begin(POINTS, 4.0f);
|
dd.Begin(POINTS, 4.0f);
|
||||||
for (int i = 0; i < m_straightPath.Count; ++i)
|
for (int i = 0; i < m_straightPathCount; ++i)
|
||||||
{
|
{
|
||||||
DtStraightPath straightPathItem = m_straightPath[i];
|
DtStraightPath straightPathItem = m_straightPath[i];
|
||||||
dd.Vertex(straightPathItem.pos.X, straightPathItem.pos.Y + 0.4f, straightPathItem.pos.Z, spathCol);
|
dd.Vertex(straightPathItem.pos.X, straightPathItem.pos.Y + 0.4f, straightPathItem.pos.Z, spathCol);
|
||||||
|
@ -666,18 +669,18 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
else if (_mode == RcTestNavmeshToolMode.PATHFIND_STRAIGHT)
|
else if (_mode == RcTestNavmeshToolMode.PATHFIND_STRAIGHT)
|
||||||
{
|
{
|
||||||
_tool.FindStraightPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, _enableRaycast,
|
_tool.FindStraightPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, _enableRaycast,
|
||||||
ref m_polys, ref m_straightPath, _straightPathOption);
|
ref m_polys, m_straightPath, out m_straightPathCount, MAX_POLYS, _straightPathOption);
|
||||||
}
|
}
|
||||||
else if (_mode == RcTestNavmeshToolMode.PATHFIND_SLICED)
|
else if (_mode == RcTestNavmeshToolMode.PATHFIND_SLICED)
|
||||||
{
|
{
|
||||||
m_polys?.Clear();
|
m_polys?.Clear();
|
||||||
m_straightPath?.Clear();
|
m_straightPathCount = 0;
|
||||||
m_pathFindStatus = _tool.InitSlicedFindPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, _enableRaycast);
|
m_pathFindStatus = _tool.InitSlicedFindPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, _enableRaycast);
|
||||||
}
|
}
|
||||||
else if (_mode == RcTestNavmeshToolMode.RAYCAST)
|
else if (_mode == RcTestNavmeshToolMode.RAYCAST)
|
||||||
{
|
{
|
||||||
_tool.Raycast(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter,
|
_tool.Raycast(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter,
|
||||||
ref m_polys, ref m_straightPath, ref m_hitPos, ref m_hitNormal, ref m_hitResult);
|
ref m_polys, m_straightPath, out m_straightPathCount, MAX_POLYS, ref m_hitPos, ref m_hitNormal, ref m_hitResult);
|
||||||
}
|
}
|
||||||
else if (_mode == RcTestNavmeshToolMode.DISTANCE_TO_WALL)
|
else if (_mode == RcTestNavmeshToolMode.DISTANCE_TO_WALL)
|
||||||
{
|
{
|
||||||
|
@ -712,7 +715,7 @@ public class TestNavmeshSampleTool : ISampleTool
|
||||||
|
|
||||||
if (m_pathFindStatus.InProgress())
|
if (m_pathFindStatus.InProgress())
|
||||||
{
|
{
|
||||||
m_pathFindStatus = _tool.UpdateSlicedFindPath(navQuery, 1, m_endRef, m_spos, m_epos, ref m_polys, ref m_straightPath);
|
m_pathFindStatus = _tool.UpdateSlicedFindPath(navQuery, 1, m_endRef, m_spos, m_epos, ref m_polys, m_straightPath, out m_straightPathCount, MAX_POLYS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
public const int MAX_POLYS = 256;
|
public const int MAX_POLYS = 256;
|
||||||
public const int MAX_SMOOTH = 2048;
|
public const int MAX_SMOOTH = 2048;
|
||||||
|
|
||||||
|
|
||||||
public RcTestNavMeshTool()
|
public RcTestNavMeshTool()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -172,15 +171,15 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtStatus FindStraightPath(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
|
public DtStatus FindStraightPath(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
|
||||||
ref List<long> polys, ref List<DtStraightPath> straightPath, int straightPathOptions)
|
ref List<long> polys, Span<DtStraightPath> straightPath, out int straightPathCount, int maxStraightPath, int straightPathOptions)
|
||||||
{
|
{
|
||||||
|
straightPathCount = 0;
|
||||||
if (startRef == 0 || endRef == 0)
|
if (startRef == 0 || endRef == 0)
|
||||||
{
|
{
|
||||||
return DtStatus.DT_FAILURE;
|
return DtStatus.DT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
polys ??= new List<long>();
|
polys ??= new List<long>();
|
||||||
straightPath ??= new List<DtStraightPath>();
|
|
||||||
|
|
||||||
polys.Clear();
|
polys.Clear();
|
||||||
straightPath.Clear();
|
straightPath.Clear();
|
||||||
|
@ -202,7 +201,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
navQuery.FindStraightPath(startPt, epos, polys, polys.Count, ref straightPath, MAX_POLYS, straightPathOptions);
|
navQuery.FindStraightPath(startPt, epos, polys, polys.Count, straightPath, out straightPathCount, maxStraightPath, straightPathOptions);
|
||||||
|
|
||||||
return DtStatus.DT_SUCCESS;
|
return DtStatus.DT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -221,8 +220,9 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtStatus UpdateSlicedFindPath(DtNavMeshQuery navQuery, int maxIter, long endRef, RcVec3f startPos, RcVec3f endPos,
|
public DtStatus UpdateSlicedFindPath(DtNavMeshQuery navQuery, int maxIter, long endRef, RcVec3f startPos, RcVec3f endPos,
|
||||||
ref List<long> path, ref List<DtStraightPath> straightPath)
|
ref List<long> path, Span<DtStraightPath> straightPath, out int straightPathCount, int maxStraightPath)
|
||||||
{
|
{
|
||||||
|
straightPathCount = 0;
|
||||||
var status = navQuery.UpdateSlicedFindPath(maxIter, out _);
|
var status = navQuery.UpdateSlicedFindPath(maxIter, out _);
|
||||||
|
|
||||||
if (!status.Succeeded())
|
if (!status.Succeeded())
|
||||||
|
@ -232,7 +232,6 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
|
|
||||||
navQuery.FinalizeSlicedFindPath(ref path);
|
navQuery.FinalizeSlicedFindPath(ref path);
|
||||||
|
|
||||||
straightPath?.Clear();
|
|
||||||
if (path != null)
|
if (path != null)
|
||||||
{
|
{
|
||||||
// In case of partial path, make sure the end point is clamped to the last polygon.
|
// In case of partial path, make sure the end point is clamped to the last polygon.
|
||||||
|
@ -246,8 +245,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
straightPath = new List<DtStraightPath>(MAX_POLYS);
|
navQuery.FindStraightPath(startPos, epos, path, path.Count, straightPath, out straightPathCount, maxStraightPath, DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS);
|
||||||
navQuery.FindStraightPath(startPos, epos, path, path.Count, ref straightPath, MAX_POLYS, DtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DtStatus.DT_SUCCESS;
|
return DtStatus.DT_SUCCESS;
|
||||||
|
@ -255,13 +253,12 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
|
|
||||||
|
|
||||||
public DtStatus Raycast(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter,
|
public DtStatus Raycast(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter,
|
||||||
ref List<long> polys, ref List<DtStraightPath> straightPath, ref RcVec3f hitPos, ref RcVec3f hitNormal, ref bool hitResult)
|
ref List<long> polys, Span<DtStraightPath> straightPath, out int straightPathCount, int maxStraightPath, ref RcVec3f hitPos, ref RcVec3f hitNormal, ref bool hitResult)
|
||||||
{
|
{
|
||||||
|
straightPathCount = 0;
|
||||||
if (startRef == 0 || endRef == 0)
|
if (startRef == 0 || endRef == 0)
|
||||||
{
|
{
|
||||||
polys?.Clear();
|
polys?.Clear();
|
||||||
straightPath?.Clear();
|
|
||||||
|
|
||||||
return DtStatus.DT_FAILURE;
|
return DtStatus.DT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,10 +296,8 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
straightPath ??= new List<DtStraightPath>();
|
straightPath[straightPathCount++] = new DtStraightPath(startPos, 0, 0);
|
||||||
straightPath.Clear();
|
straightPath[straightPathCount++] = new DtStraightPath(hitPos, 0, 0);
|
||||||
straightPath.Add(new DtStraightPath(startPos, 0, 0));
|
|
||||||
straightPath.Add(new DtStraightPath(hitPos, 0, 0));
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,13 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Crowd.Test;
|
namespace DotRecast.Detour.Crowd.Test;
|
||||||
|
|
||||||
|
|
||||||
public class DtPathCorridorTest
|
public class DtPathCorridorTest
|
||||||
{
|
{
|
||||||
private readonly DtPathCorridor corridor = new DtPathCorridor();
|
private readonly DtPathCorridor corridor = new DtPathCorridor();
|
||||||
|
@ -41,63 +39,35 @@ public class DtPathCorridorTest
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldKeepOriginalPathInFindCornersWhenNothingCanBePruned()
|
public void ShouldKeepOriginalPathInFindCornersWhenNothingCanBePruned()
|
||||||
{
|
{
|
||||||
List<DtStraightPath> straightPath = new();
|
var straightPath = new DtStraightPath[4];
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(11, 20, 30.00001f), 0, 0));
|
straightPath[0] = new DtStraightPath(new RcVec3f(11, 20, 30.00001f), 0, 0);
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(12, 20, 30.00002f), 0, 0));
|
straightPath[1] = new DtStraightPath(new RcVec3f(12, 20, 30.00002f), 0, 0);
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0));
|
straightPath[2] = new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0);
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0));
|
straightPath[3] = new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0);
|
||||||
var mockQuery = new Mock<DtNavMeshQuery>(It.IsAny<DtNavMesh>());
|
var query = new DtNavMeshQueryMock(straightPath, DtStatus.DT_SUCCESS);
|
||||||
mockQuery.Setup(q => q.FindStraightPath(
|
|
||||||
It.IsAny<RcVec3f>(),
|
|
||||||
It.IsAny<RcVec3f>(),
|
|
||||||
It.IsAny<List<long>>(),
|
|
||||||
It.IsAny<int>(),
|
|
||||||
ref It.Ref<List<DtStraightPath>>.IsAny,
|
|
||||||
It.IsAny<int>(),
|
|
||||||
It.IsAny<int>())
|
|
||||||
)
|
|
||||||
.Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
|
|
||||||
ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) =>
|
|
||||||
{
|
|
||||||
refStraightPath = straightPath;
|
|
||||||
})
|
|
||||||
.Returns(() => DtStatus.DT_SUCCESS);
|
|
||||||
|
|
||||||
var path = new List<DtStraightPath>();
|
Span<DtStraightPath> path = stackalloc DtStraightPath[8];
|
||||||
corridor.FindCorners(ref path, int.MaxValue, mockQuery.Object, filter);
|
var npath = corridor.FindCorners(path, 8, query, filter);
|
||||||
Assert.That(path.Count, Is.EqualTo(4));
|
Assert.That(npath, Is.EqualTo(4));
|
||||||
Assert.That(path, Is.EqualTo(straightPath));
|
Assert.That(path.Slice(0, npath).ToArray(), Is.EqualTo(straightPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldPrunePathInFindCorners()
|
public void ShouldPrunePathInFindCorners()
|
||||||
{
|
{
|
||||||
List<DtStraightPath> straightPath = new();
|
DtStraightPath[] straightPath = new DtStraightPath[5];
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(10, 20, 30.00001f), 0, 0)); // too close
|
straightPath[0] = (new DtStraightPath(new RcVec3f(10, 20, 30.00001f), 0, 0)); // too close
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(10, 20, 30.00002f), 0, 0)); // too close
|
straightPath[1] = (new DtStraightPath(new RcVec3f(10, 20, 30.00002f), 0, 0)); // too close
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0));
|
straightPath[2] = (new DtStraightPath(new RcVec3f(11f, 21, 32f), 0, 0));
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(12f, 22, 33f), DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
straightPath[3] = (new DtStraightPath(new RcVec3f(12f, 22, 33f), DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
||||||
straightPath.Add(new DtStraightPath(new RcVec3f(11f, 21, 32f), DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
straightPath[4] = (new DtStraightPath(new RcVec3f(11f, 21, 32f), DtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION, 0)); // offmesh
|
||||||
|
|
||||||
var mockQuery = new Mock<DtNavMeshQuery>(It.IsAny<DtNavMesh>());
|
var query = new DtNavMeshQueryMock(straightPath, DtStatus.DT_SUCCESS);
|
||||||
mockQuery.Setup(q => q.FindStraightPath(
|
|
||||||
It.IsAny<RcVec3f>(),
|
|
||||||
It.IsAny<RcVec3f>(),
|
|
||||||
It.IsAny<List<long>>(),
|
|
||||||
It.IsAny<int>(),
|
|
||||||
ref It.Ref<List<DtStraightPath>>.IsAny,
|
|
||||||
It.IsAny<int>(),
|
|
||||||
It.IsAny<int>())
|
|
||||||
).Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
|
|
||||||
ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) =>
|
|
||||||
{
|
|
||||||
refStraightPath = straightPath;
|
|
||||||
})
|
|
||||||
.Returns(() => DtStatus.DT_SUCCESS);
|
|
||||||
|
|
||||||
var path = new List<DtStraightPath>();
|
Span<DtStraightPath> path = stackalloc DtStraightPath[8];
|
||||||
corridor.FindCorners(ref path, int.MaxValue, mockQuery.Object, filter);
|
int npath = corridor.FindCorners(path, 8, query, filter);
|
||||||
Assert.That(path.Count, Is.EqualTo(2));
|
Assert.That(npath, Is.EqualTo(2));
|
||||||
Assert.That(path, Is.EqualTo(new List<DtStraightPath> { straightPath[2], straightPath[3] }));
|
Assert.That(path.Slice(0, npath).ToArray(), Is.EqualTo(new DtStraightPath[] { straightPath[2], straightPath[3] }));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,13 +16,13 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Test;
|
namespace DotRecast.Detour.Test;
|
||||||
|
|
||||||
|
|
||||||
public class FindPathTest : AbstractDetourTest
|
public class FindPathTest : AbstractDetourTest
|
||||||
{
|
{
|
||||||
private static readonly DtStatus[] STATUSES =
|
private static readonly DtStatus[] STATUSES =
|
||||||
|
@ -184,6 +184,7 @@ public class FindPathTest : AbstractDetourTest
|
||||||
{
|
{
|
||||||
IDtQueryFilter filter = new DtQueryDefaultFilter();
|
IDtQueryFilter filter = new DtQueryDefaultFilter();
|
||||||
var path = new List<long>();
|
var path = new List<long>();
|
||||||
|
Span<DtStraightPath> straightPath = stackalloc DtStraightPath[256];
|
||||||
for (int i = 0; i < STRAIGHT_PATHS.Length; i++)
|
for (int i = 0; i < STRAIGHT_PATHS.Length; i++)
|
||||||
{
|
{
|
||||||
// startRefs.Length; i++) {
|
// startRefs.Length; i++) {
|
||||||
|
@ -192,9 +193,8 @@ public class FindPathTest : AbstractDetourTest
|
||||||
var startPos = startPoss[i];
|
var startPos = startPoss[i];
|
||||||
var endPos = endPoss[i];
|
var endPos = endPoss[i];
|
||||||
var status = query.FindPath(startRef, endRef, startPos, endPos, filter, ref path, DtFindPathOption.NoOption);
|
var status = query.FindPath(startRef, endRef, startPos, endPos, filter, ref path, DtFindPathOption.NoOption);
|
||||||
var straightPath = new List<DtStraightPath>();
|
query.FindStraightPath(startPos, endPos, path, path.Count, straightPath, out var nstraightPath, 256, 0);
|
||||||
query.FindStraightPath(startPos, endPos, path, path.Count, ref straightPath, int.MaxValue, 0);
|
Assert.That(nstraightPath, Is.EqualTo(STRAIGHT_PATHS[i].Length));
|
||||||
Assert.That(straightPath.Count, Is.EqualTo(STRAIGHT_PATHS[i].Length));
|
|
||||||
for (int j = 0; j < STRAIGHT_PATHS[i].Length; j++)
|
for (int j = 0; j < STRAIGHT_PATHS[i].Length; j++)
|
||||||
{
|
{
|
||||||
Assert.That(straightPath[j].refs, Is.EqualTo(STRAIGHT_PATHS[i][j].refs));
|
Assert.That(straightPath[j].refs, Is.EqualTo(STRAIGHT_PATHS[i][j].refs));
|
||||||
|
|
|
@ -18,6 +18,7 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
|
@ -29,7 +30,6 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.TileCache.Test;
|
namespace DotRecast.Detour.TileCache.Test;
|
||||||
|
|
||||||
|
|
||||||
public class TileCacheFindPathTest : AbstractTileCacheTest
|
public class TileCacheFindPathTest : AbstractTileCacheTest
|
||||||
{
|
{
|
||||||
private readonly RcVec3f start = new RcVec3f(39.44734f, 9.998177f, -0.784811f);
|
private readonly RcVec3f start = new RcVec3f(39.44734f, 9.998177f, -0.784811f);
|
||||||
|
@ -56,11 +56,11 @@ public class TileCacheFindPathTest : AbstractTileCacheTest
|
||||||
|
|
||||||
var path = new List<long>();
|
var path = new List<long>();
|
||||||
var status = query.FindPath(startRef, endRef, startPos, endPos, filter, ref path, DtFindPathOption.NoOption);
|
var status = query.FindPath(startRef, endRef, startPos, endPos, filter, ref path, DtFindPathOption.NoOption);
|
||||||
int maxStraightPath = 256;
|
const int maxStraightPath = 256;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
|
|
||||||
var pathStr = new List<DtStraightPath>();
|
Span<DtStraightPath> pathStr = stackalloc DtStraightPath[maxStraightPath];
|
||||||
query.FindStraightPath(startPos, endPos, path, path.Count, ref pathStr, maxStraightPath, options);
|
query.FindStraightPath(startPos, endPos, path, path.Count, pathStr, out var npathStr, maxStraightPath, options);
|
||||||
Assert.That(pathStr.Count, Is.EqualTo(8));
|
Assert.That(npathStr, Is.EqualTo(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue