diff --git a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs index 2e1d00c..b370fe3 100644 --- a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs +++ b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs @@ -20,6 +20,7 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; +using System.Linq; using DotRecast.Core; using DotRecast.Core.Numerics; @@ -316,7 +317,7 @@ namespace DotRecast.Detour.Crowd var status = navquery.MoveAlongSurface(m_path[0], m_pos, npos, filter, out var result, ref visited); if (status.Succeeded()) { - m_path = DtPathUtils.MergeCorridorStartMoved(m_path, m_path.Count, m_maxPath, visited); + DtPathUtils.MergeCorridorStartMoved(m_path, m_path.Count, m_maxPath, visited); // Adjust the position to stay on top of the navmesh. m_pos = result; diff --git a/src/DotRecast.Detour/DtPathUtils.cs b/src/DotRecast.Detour/DtPathUtils.cs index b9c77e1..1fe2a98 100644 --- a/src/DotRecast.Detour/DtPathUtils.cs +++ b/src/DotRecast.Detour/DtPathUtils.cs @@ -20,6 +20,7 @@ freely, subject to the following restrictions: using System; using System.Collections.Generic; +using System.Linq; using DotRecast.Core.Numerics; namespace DotRecast.Detour @@ -141,13 +142,13 @@ namespace DotRecast.Detour return path; } - public static List MergeCorridorStartMoved(List path, int npath, int maxPath, List visited) + public static int MergeCorridorStartMoved(List path, int npath, int maxPath, List visited) { int furthestPath = -1; int furthestVisited = -1; // Find furthest common polygon. - for (int i = path.Count - 1; i >= 0; --i) + for (int i = npath - 1; i >= 0; --i) { bool found = false; for (int j = visited.Count - 1; j >= 0; --j) @@ -169,22 +170,37 @@ namespace DotRecast.Detour // If no intersection found just return current path. if (furthestPath == -1 || furthestVisited == -1) { - return path; + return npath; } // Concatenate paths. // Adjust beginning of the buffer to include the visited. - List result = new List(); - - // Store visited - for (int i = visited.Count - 1; i > furthestVisited; --i) + int req = visited.Count - furthestVisited; + int orig = Math.Min(furthestPath + 1, npath); + int size = Math.Max(0, npath - orig); + if (req + size > maxPath) + size = maxPath - req; + + if (size > 0) { - result.Add(visited[i]); + //memmove(path + req, path + orig, size * sizeof(dtPolyRef)); + for (int i = 0; i < size; ++i) + { + if (path.Count <= req + i) + path.Add(0); + + path[req + i] = path[orig + i]; + } } - result.AddRange(path.GetRange(furthestPath, path.Count - furthestPath)); - return result; + // Store visited + for (int i = 0, n = Math.Min(req, maxPath); i < n; ++i) + { + path[i] = visited[(visited.Count - 1) - i]; + } + + return req + size; } public static List MergeCorridorEndMoved(List path, int npath, int maxPath, List visited) diff --git a/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs index a9c9b62..382ecaf 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcTestNavMeshTool.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using DotRecast.Core; using DotRecast.Core.Numerics; using DotRecast.Detour; @@ -92,7 +93,7 @@ namespace DotRecast.Recast.Toolset.Tools iterPos = result; - pathIterPolys = DtPathUtils.MergeCorridorStartMoved(pathIterPolys, pathIterPolys.Count, MAX_POLYS, visited); + DtPathUtils.MergeCorridorStartMoved(pathIterPolys, pathIterPolys.Count, MAX_POLYS, visited); pathIterPolys = DtPathUtils.FixupShortcuts(pathIterPolys, navQuery); var status = navQuery.GetPolyHeight(pathIterPolys[0], result, out var h); diff --git a/test/DotRecast.Detour.Crowd.Test/DtPathCorridorTest.cs b/test/DotRecast.Detour.Crowd.Test/DtPathCorridorTest.cs index 740188e..627fc66 100644 --- a/test/DotRecast.Detour.Crowd.Test/DtPathCorridorTest.cs +++ b/test/DotRecast.Detour.Crowd.Test/DtPathCorridorTest.cs @@ -47,7 +47,7 @@ public class DtPathCorridorTest const int maxPath = 0; var visited = new List(); var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(0)); + Assert.That(result, Is.EqualTo(0)); } [Test(Description = "dtMergeCorridorStartMoved")] @@ -60,7 +60,7 @@ public class DtPathCorridorTest var visited = new List(); var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(1)); + Assert.That(result, Is.EqualTo(1)); var expectedPath = new List { 1 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -76,7 +76,7 @@ public class DtPathCorridorTest var visited = new List { 1 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(0)); + Assert.That(result, Is.EqualTo(0)); } [Test(Description = "dtMergeCorridorStartMoved")] @@ -89,7 +89,7 @@ public class DtPathCorridorTest var visited = new List { 1, 2 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(1)); + Assert.That(result, Is.EqualTo(1)); var expectedPath = new List { 2, 2 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -103,7 +103,7 @@ public class DtPathCorridorTest const int maxPath = 3; var visited = new List { 1, 2, 3, 4 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(3)); + Assert.That(result, Is.EqualTo(3)); var expectedPath = new List { 4, 3, 2 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -117,7 +117,7 @@ public class DtPathCorridorTest const int maxPath = 3; var visited = new List() { 1, 2, 3, 4, 5 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(3)); + Assert.That(result, Is.EqualTo(3)); var expectedPath = new List { 5, 4, 3 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -131,7 +131,7 @@ public class DtPathCorridorTest const int maxPath = 2; var visited = new List() { 3, 4 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(2)); + Assert.That(result, Is.EqualTo(2)); var expectedPath = new List { 1, 2 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -145,7 +145,7 @@ public class DtPathCorridorTest const int maxPath = 3; var visited = new List() { 1, 3 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(3)); + Assert.That(result, Is.EqualTo(3)); var expectedPath = new List { 3, 1, 2 }; Assert.That(path, Is.EqualTo(expectedPath)); @@ -159,7 +159,7 @@ public class DtPathCorridorTest const int maxPath = 2; var visited = new List() { 1, 3 }; var result = DtPathUtils.MergeCorridorStartMoved(path, npath, maxPath, visited); - Assert.That(result.Count, Is.EqualTo(2)); + Assert.That(result, Is.EqualTo(2)); var expectedPath = new List { 3, 1 }; Assert.That(path, Is.EqualTo(expectedPath));