preparatory work to resolve the SOH issue during path merging.

This commit is contained in:
ikpil 2024-05-08 00:25:32 +09:00
parent 19e358bdfc
commit cfdcc1336c
8 changed files with 32 additions and 28 deletions

View File

@ -589,7 +589,7 @@ namespace DotRecast.Detour.Crowd
if (ag.targetReplan) // && npath > 10) if (ag.targetReplan) // && npath > 10)
{ {
// Try to use existing steady path during replan if possible. // Try to use existing steady path during replan if possible.
status = _navQuery.FinalizeSlicedFindPathPartial(path, ref reqPath); status = _navQuery.FinalizeSlicedFindPathPartial(path, path.Count, ref reqPath);
} }
else else
{ {

View File

@ -137,7 +137,7 @@ namespace DotRecast.Detour.Crowd
{ {
const float MIN_TARGET_DIST = 0.01f; const float MIN_TARGET_DIST = 0.01f;
var result = navquery.FindStraightPath(m_pos, m_target, m_path, ref corners, maxCorners, 0); var result = navquery.FindStraightPath(m_pos, m_target, m_path, m_npath, ref corners, maxCorners, 0);
if (result.Succeeded()) if (result.Succeeded())
{ {
// Prune points in the beginning of the path which are too close. // Prune points in the beginning of the path which are too close.
@ -246,7 +246,7 @@ namespace DotRecast.Detour.Crowd
var res = new List<long>(); var res = new List<long>();
navquery.InitSlicedFindPath(m_path[0], m_path[^1], m_pos, m_target, filter, 0); navquery.InitSlicedFindPath(m_path[0], m_path[^1], m_pos, m_target, filter, 0);
navquery.UpdateSlicedFindPath(maxIterations, out var _); navquery.UpdateSlicedFindPath(maxIterations, out var _);
var status = navquery.FinalizeSlicedFindPathPartial(m_path, ref res); var status = navquery.FinalizeSlicedFindPathPartial(m_path, m_npath, ref res);
if (status.Succeeded() && res.Count > 0) if (status.Succeeded() && res.Count > 0)
{ {

View File

@ -1363,19 +1363,21 @@ namespace DotRecast.Detour
/// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest /// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest
/// polygon on the existing path that was visited during the search. /// polygon on the existing path that was visited during the search.
/// @param[in] existing An array of polygon references for the existing path. /// @param[in] existing An array of polygon references for the existing path.
/// @param[in] existingSize The number of polygon in the @p existing array. /// @param[in] existingSize The number of polygon in the @p existing array.
/// @param[out] path An ordered list of polygon references representing the path. (Start to end.) /// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
/// [(polyRef) * @p pathCount] /// [(polyRef) * @p pathCount]
/// @param[out] pathCount The number of polygons returned in the @p path array.
/// @param[in] maxPath The max number of polygons the @p path array can hold. [Limit: >= 1]
/// @returns The status flags for the query. /// @returns The status flags for the query.
public virtual DtStatus FinalizeSlicedFindPathPartial(List<long> existing, ref List<long> path) public virtual DtStatus FinalizeSlicedFindPathPartial(List<long> existing, int existingSize, ref List<long> path)
{ {
if (null == path) if (null == path)
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
path.Clear(); path.Clear();
if (null == existing || existing.Count <= 0) if (null == existing || existingSize <= 0)
{ {
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
@ -1396,7 +1398,7 @@ namespace DotRecast.Detour
{ {
// Find furthest existing node that was visited. // Find furthest existing node that was visited.
DtNode node = null; DtNode node = null;
for (int i = existing.Count - 1; i >= 0; --i) for (int i = existingSize - 1; i >= 0; --i)
{ {
node = m_nodePool.FindNode(existing[i]); node = m_nodePool.FindNode(existing[i]);
if (node != null) if (node != null)
@ -1527,12 +1529,12 @@ 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, public virtual DtStatus FindStraightPath(RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
ref List<DtStraightPath> straightPath, ref List<DtStraightPath> straightPath,
int maxStraightPath, int options) int maxStraightPath, int options)
{ {
if (!startPos.IsFinite() || !endPos.IsFinite() || null == straightPath if (!startPos.IsFinite() || !endPos.IsFinite() || null == straightPath
|| null == path || 0 == path.Count || path[0] == 0 || maxStraightPath <= 0) || 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;
} }
@ -1546,7 +1548,7 @@ namespace DotRecast.Detour
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
var closestEndPosRes = ClosestPointOnPolyBoundary(path[path.Count - 1], endPos, out var closestEndPos); var closestEndPosRes = ClosestPointOnPolyBoundary(path[pathSize - 1], endPos, out var closestEndPos);
if (closestEndPosRes.Failed()) if (closestEndPosRes.Failed())
{ {
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
@ -1559,7 +1561,7 @@ namespace DotRecast.Detour
return stat; return stat;
} }
if (path.Count > 1) if (pathSize > 1)
{ {
RcVec3f portalApex = closestStartPos; RcVec3f portalApex = closestStartPos;
RcVec3f portalLeft = portalApex; RcVec3f portalLeft = portalApex;
@ -1574,13 +1576,13 @@ namespace DotRecast.Detour
long leftPolyRef = path[0]; long leftPolyRef = path[0];
long rightPolyRef = path[0]; long rightPolyRef = path[0];
for (int i = 0; i < path.Count; ++i) for (int i = 0; i < pathSize; ++i)
{ {
RcVec3f left; RcVec3f left;
RcVec3f right; RcVec3f right;
int toType; int toType;
if (i + 1 < path.Count) if (i + 1 < pathSize)
{ {
int fromType; // // fromType is ignored. int fromType; // // fromType is ignored.
@ -1633,7 +1635,7 @@ namespace DotRecast.Detour
if (DtUtils.VEqual(portalApex, portalRight) || DtUtils.TriArea2D(portalApex, portalLeft, right) > 0.0f) if (DtUtils.VEqual(portalApex, portalRight) || DtUtils.TriArea2D(portalApex, portalLeft, right) > 0.0f)
{ {
portalRight = right; portalRight = right;
rightPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0; rightPolyRef = (i + 1 < pathSize) ? path[i + 1] : 0;
rightPolyType = toType; rightPolyType = toType;
rightIndex = i; rightIndex = i;
} }
@ -1689,7 +1691,7 @@ namespace DotRecast.Detour
if (DtUtils.VEqual(portalApex, portalLeft) || DtUtils.TriArea2D(portalApex, portalRight, left) < 0.0f) if (DtUtils.VEqual(portalApex, portalLeft) || DtUtils.TriArea2D(portalApex, portalRight, left) < 0.0f)
{ {
portalLeft = left; portalLeft = left;
leftPolyRef = (i + 1 < path.Count) ? path[i + 1] : 0; leftPolyRef = (i + 1 < pathSize) ? path[i + 1] : 0;
leftPolyType = toType; leftPolyType = toType;
leftIndex = i; leftIndex = i;
} }
@ -1743,7 +1745,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, path.Count - 1, closestEndPos, path, ref straightPath, maxStraightPath, options); stat = AppendPortals(apexIndex, pathSize - 1, closestEndPos, path, ref straightPath, maxStraightPath, options);
if (!stat.InProgress()) if (!stat.InProgress())
{ {
return stat; return stat;

View File

@ -31,7 +31,7 @@ namespace DotRecast.Detour
public static bool GetSteerTarget(DtNavMeshQuery navQuery, RcVec3f startPos, RcVec3f endPos, public static bool GetSteerTarget(DtNavMeshQuery navQuery, RcVec3f startPos, RcVec3f endPos,
float minTargetDist, float minTargetDist,
List<long> path, List<long> path, int pathSize,
out RcVec3f steerPos, out int steerPosFlag, out long steerPosRef) out RcVec3f steerPos, out int steerPosFlag, out long steerPosRef)
{ {
steerPos = RcVec3f.Zero; steerPos = RcVec3f.Zero;
@ -40,7 +40,7 @@ namespace DotRecast.Detour
// Find steer target. // Find steer target.
var straightPath = new List<DtStraightPath>(MAX_STEER_POINTS); var straightPath = new List<DtStraightPath>(MAX_STEER_POINTS);
var result = navQuery.FindStraightPath(startPos, endPos, path, ref straightPath, MAX_STEER_POINTS, 0); var result = navQuery.FindStraightPath(startPos, endPos, path, pathSize, ref straightPath, MAX_STEER_POINTS, 0);
if (result.Failed()) if (result.Failed())
{ {
return false; return false;

View File

@ -65,7 +65,7 @@ namespace DotRecast.Recast.Toolset.Tools
{ {
// Find location to steer towards. // Find location to steer towards.
if (!DtPathUtils.GetSteerTarget(navQuery, iterPos, targetPos, SLOP, if (!DtPathUtils.GetSteerTarget(navQuery, iterPos, targetPos, SLOP,
pathIterPolys, out var steerPos, out var steerPosFlag, out var steerPosRef)) pathIterPolys, pathIterPolyCount, out var steerPos, out var steerPosFlag, out var steerPosRef))
{ {
break; break;
} }
@ -200,7 +200,7 @@ namespace DotRecast.Recast.Toolset.Tools
} }
} }
navQuery.FindStraightPath(startPt, epos, polys, ref straightPath, MAX_POLYS, straightPathOptions); navQuery.FindStraightPath(startPt, epos, polys, polys.Count, ref straightPath, MAX_POLYS, straightPathOptions);
return DtStatus.DT_SUCCESS; return DtStatus.DT_SUCCESS;
} }
@ -245,7 +245,7 @@ namespace DotRecast.Recast.Toolset.Tools
} }
straightPath = new List<DtStraightPath>(MAX_POLYS); straightPath = new List<DtStraightPath>(MAX_POLYS);
navQuery.FindStraightPath(startPos, epos, path, ref straightPath, MAX_POLYS, 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;

View File

@ -51,11 +51,12 @@ public class PathCorridorTest
It.IsAny<RcVec3f>(), It.IsAny<RcVec3f>(),
It.IsAny<RcVec3f>(), It.IsAny<RcVec3f>(),
It.IsAny<List<long>>(), It.IsAny<List<long>>(),
It.IsAny<int>(),
ref It.Ref<List<DtStraightPath>>.IsAny, ref It.Ref<List<DtStraightPath>>.IsAny,
It.IsAny<int>(), It.IsAny<int>(),
It.IsAny<int>()) It.IsAny<int>())
) )
.Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, .Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) => ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) =>
{ {
refStraightPath = straightPath; refStraightPath = straightPath;
@ -83,10 +84,11 @@ public class PathCorridorTest
It.IsAny<RcVec3f>(), It.IsAny<RcVec3f>(),
It.IsAny<RcVec3f>(), It.IsAny<RcVec3f>(),
It.IsAny<List<long>>(), It.IsAny<List<long>>(),
It.IsAny<int>(),
ref It.Ref<List<DtStraightPath>>.IsAny, ref It.Ref<List<DtStraightPath>>.IsAny,
It.IsAny<int>(), It.IsAny<int>(),
It.IsAny<int>()) It.IsAny<int>())
).Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, ).Callback((RcVec3f startPos, RcVec3f endPos, List<long> path, int pathSize,
ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) => ref List<DtStraightPath> refStraightPath, int maxStraightPath, int options) =>
{ {
refStraightPath = straightPath; refStraightPath = straightPath;

View File

@ -193,7 +193,7 @@ public class FindPathTest : AbstractDetourTest
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>(); var straightPath = new List<DtStraightPath>();
query.FindStraightPath(startPos, endPos, path, ref straightPath, int.MaxValue, 0); query.FindStraightPath(startPos, endPos, path, path.Count, ref straightPath, int.MaxValue, 0);
Assert.That(straightPath.Count, 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++)
{ {

View File

@ -60,7 +60,7 @@ public class TileCacheFindPathTest : AbstractTileCacheTest
int options = 0; int options = 0;
var pathStr = new List<DtStraightPath>(); var pathStr = new List<DtStraightPath>();
query.FindStraightPath(startPos, endPos, path, ref pathStr, maxStraightPath, options); query.FindStraightPath(startPos, endPos, path, path.Count, ref pathStr, maxStraightPath, options);
Assert.That(pathStr.Count, Is.EqualTo(8)); Assert.That(pathStr.Count, Is.EqualTo(8));
} }
} }