Compare commits

..

7 Commits

5 changed files with 59 additions and 34 deletions

View File

@ -43,6 +43,11 @@ namespace DotRecast.Core.Buffers
return _array; return _array;
} }
public Span<T> AsSpan()
{
return new Span<T>(_array, 0, Length);
}
public void Dispose() public void Dispose()
{ {

View File

@ -45,5 +45,11 @@ namespace DotRecast.Core.Collections
(list[k], list[n]) = (list[n], list[k]); (list[k], list[n]) = (list[n], list[k]);
} }
} }
public static void AddRange<T>(this IList<T> list, Span<T> span)
{
foreach (var i in span)
list.Add(i);
}
} }
} }

View File

@ -33,7 +33,7 @@ namespace DotRecast.Detour.Crowd
private RcVec3f m_pos; private RcVec3f m_pos;
private RcVec3f m_target; private RcVec3f m_target;
private List<long> m_path; private List<long> m_path = new List<long>();
private int m_npath; private int m_npath;
private int m_maxPath; private int m_maxPath;
@ -89,7 +89,8 @@ namespace DotRecast.Detour.Crowd
/// @return True if the initialization succeeded. /// @return True if the initialization succeeded.
public bool Init(int maxPath) public bool Init(int maxPath)
{ {
m_path = new List<long>(maxPath); if (m_path.Capacity < maxPath)
m_path.Capacity = maxPath;
m_npath = 0; m_npath = 0;
m_maxPath = maxPath; m_maxPath = maxPath;
return true; return true;
@ -218,7 +219,7 @@ namespace DotRecast.Detour.Crowd
{ {
if (res.Count > 1 && t > 0.99f) if (res.Count > 1 && t > 0.99f)
{ {
m_npath = DtPathUtils.MergeCorridorStartShortcut(ref m_path, m_npath, m_maxPath, res, res.Count); m_npath = DtPathUtils.MergeCorridorStartShortcut(m_path, m_npath, m_maxPath, res, res.Count);
} }
} }
} }
@ -250,7 +251,7 @@ namespace DotRecast.Detour.Crowd
if (status.Succeeded() && res.Count > 0) if (status.Succeeded() && res.Count > 0)
{ {
m_npath = DtPathUtils.MergeCorridorStartShortcut(ref m_path, m_npath, m_maxPath, res, res.Count); m_npath = DtPathUtils.MergeCorridorStartShortcut(m_path, m_npath, m_maxPath, res, res.Count);
return true; return true;
} }
@ -276,7 +277,7 @@ namespace DotRecast.Detour.Crowd
} }
// Prune path // Prune path
m_path = m_path.GetRange(npos, m_npath - npos); m_path.RemoveRange(0, npos);
m_npath -= npos; m_npath -= npos;
refs[0] = prevRef; refs[0] = prevRef;
@ -322,7 +323,7 @@ namespace DotRecast.Detour.Crowd
var status = navquery.MoveAlongSurface(m_path[0], m_pos, npos, filter, out var result, visited, out var nvisited, MAX_VISITED); var status = navquery.MoveAlongSurface(m_path[0], m_pos, npos, filter, out var result, visited, out var nvisited, MAX_VISITED);
if (status.Succeeded()) if (status.Succeeded())
{ {
m_npath = DtPathUtils.MergeCorridorStartMoved(ref m_path, m_npath, m_maxPath, visited, nvisited); m_npath = DtPathUtils.MergeCorridorStartMoved(m_path, m_npath, m_maxPath, visited, nvisited);
// Adjust the position to stay on top of the navmesh. // Adjust the position to stay on top of the navmesh.
m_pos = result; m_pos = result;
@ -366,7 +367,7 @@ namespace DotRecast.Detour.Crowd
var status = navquery.MoveAlongSurface(m_path[^1], m_target, npos, filter, out var result, visited, out nvisited, MAX_VISITED); var status = navquery.MoveAlongSurface(m_path[^1], m_target, npos, filter, out var result, visited, out nvisited, MAX_VISITED);
if (status.Succeeded()) if (status.Succeeded())
{ {
m_npath = DtPathUtils.MergeCorridorEndMoved(ref m_path, m_npath, m_maxPath, visited, nvisited); m_npath = DtPathUtils.MergeCorridorEndMoved(m_path, m_npath, m_maxPath, visited, nvisited);
// TODO: should we do that? // TODO: should we do that?
// Adjust the position to stay on top of the navmesh. // Adjust the position to stay on top of the navmesh.
@ -394,7 +395,11 @@ namespace DotRecast.Detour.Crowd
public void SetCorridor(RcVec3f target, List<long> path) public void SetCorridor(RcVec3f target, List<long> path)
{ {
m_target = target; m_target = target;
m_path = new List<long>(path); if(path != m_path)
{
m_path.Clear();
m_path.AddRange(path);
}
m_npath = path.Count; m_npath = path.Count;
} }
@ -444,7 +449,7 @@ namespace DotRecast.Detour.Crowd
else if (n < m_npath) else if (n < m_npath)
{ {
// The path is partially usable. // The path is partially usable.
m_path = m_path.GetRange(0, n); m_path.RemoveRange(n, m_path.Count - n);
m_npath = n; m_npath = n;
} }

View File

@ -20,7 +20,10 @@ freely, subject to the following restrictions:
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Core.Buffers;
using DotRecast.Core.Collections;
using DotRecast.Core.Numerics; using DotRecast.Core.Numerics;
using CollectionExtensions = DotRecast.Core.Collections.CollectionExtensions;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {
@ -148,7 +151,7 @@ namespace DotRecast.Detour
return npath; return npath;
} }
public static int MergeCorridorStartMoved(ref List<long> path, int npath, int maxPath, Span<long> visited, int nvisited) public static int MergeCorridorStartMoved(List<long> path, int npath, int maxPath, Span<long> visited, int nvisited)
{ {
int furthestPath = -1; int furthestPath = -1;
int furthestVisited = -1; int furthestVisited = -1;
@ -180,22 +183,23 @@ namespace DotRecast.Detour
} }
// Concatenate paths. // Concatenate paths.
var endIndex = nvisited - 1;
var length1 = endIndex - furthestVisited;
var length2 = npath - furthestPath;
using var result = RcRentedArray.Rent<long>(length1 + length2);
// Adjust beginning of the buffer to include the visited. // Adjust beginning of the buffer to include the visited.
List<long> result = new List<long>();
// Store visited // Store visited
for (int i = nvisited - 1; i > furthestVisited; --i) for (int i = 0; i < length1; ++i)
{ result[i] = visited[endIndex - i];
result.Add(visited[i]);
}
result.AddRange(path.GetRange(furthestPath, npath - furthestPath)); path.CopyTo(furthestPath, result.AsArray(), length1, length2);
path = result; path.Clear();
return result.Count; CollectionExtensions.AddRange(path, result.AsSpan());
return result.Length;
} }
public static int MergeCorridorEndMoved(ref List<long> path, int npath, int maxPath, Span<long> visited, int nvisited) public static int MergeCorridorEndMoved(List<long> path, int npath, int maxPath, Span<long> visited, int nvisited)
{ {
int furthestPath = -1; int furthestPath = -1;
int furthestVisited = -1; int furthestVisited = -1;
@ -227,17 +231,18 @@ namespace DotRecast.Detour
} }
// Concatenate paths. // Concatenate paths.
List<long> result = path.GetRange(0, furthestPath); var length1 = furthestPath;
foreach (var v in visited.Slice(furthestVisited, nvisited - furthestVisited)) var length2 = nvisited - furthestVisited;
{ using var result = RcRentedArray.Rent<long>(length1 + length2);
result.Add(v); path.CopyTo(0, result.AsArray(), 0, length1);
} visited.Slice(furthestVisited, nvisited - furthestVisited).CopyTo(result.AsSpan().Slice(length1, length2));
path = result; path.Clear();
return result.Count; CollectionExtensions.AddRange(path, result.AsSpan());
return path.Count;
} }
public static int MergeCorridorStartShortcut(ref List<long> path, int npath, int maxPath, List<long> visited, int nvisited) public static int MergeCorridorStartShortcut(List<long> path, int npath, int maxPath, List<long> visited, int nvisited)
{ {
int furthestPath = -1; int furthestPath = -1;
int furthestVisited = -1; int furthestVisited = -1;
@ -271,11 +276,15 @@ namespace DotRecast.Detour
// Concatenate paths. // Concatenate paths.
// Adjust beginning of the buffer to include the visited. // Adjust beginning of the buffer to include the visited.
List<long> result = visited.GetRange(0, furthestVisited); var length1 = furthestVisited;
result.AddRange(path.GetRange(furthestPath, npath - furthestPath)); var length2 = npath - furthestPath;
using var result = RcRentedArray.Rent<long>(length1 + length2);
visited.CopyTo(0, result.AsArray(), 0, length1);
path.CopyTo(furthestPath, result.AsArray(), length1, length2);
path = result; path.Clear();
return result.Count; CollectionExtensions.AddRange(path, result.AsSpan());
return path.Count;
} }
} }
} }

View File

@ -98,7 +98,7 @@ namespace DotRecast.Recast.Toolset.Tools
iterPos = result; iterPos = result;
pathIterPolyCount = DtPathUtils.MergeCorridorStartMoved(ref pathIterPolys, pathIterPolyCount, MAX_POLYS, visited, nvisited); pathIterPolyCount = DtPathUtils.MergeCorridorStartMoved(pathIterPolys, pathIterPolyCount, MAX_POLYS, visited, nvisited);
pathIterPolyCount = DtPathUtils.FixupShortcuts(ref pathIterPolys, pathIterPolyCount, navQuery); pathIterPolyCount = DtPathUtils.FixupShortcuts(ref pathIterPolys, pathIterPolyCount, navQuery);
var status = navQuery.GetPolyHeight(pathIterPolys[0], result, out var h); var status = navQuery.GetPolyHeight(pathIterPolys[0], result, out var h);