|
3 | 3 |
|
4 | 4 | using System; |
5 | 5 | using System.Collections.Generic; |
| 6 | +using System.Linq; |
6 | 7 | using System.Runtime.InteropServices; |
7 | 8 | using DotRecast.Core.Numerics; |
8 | 9 | using DotRecast.Detour; |
@@ -79,14 +80,32 @@ public void DoPathFindQuery(PathFindQuery query, ref PathFindResult result) |
79 | 80 | return; |
80 | 81 |
|
81 | 82 | long[] polys = new long[query.MaxPathPoints]; |
82 | | - status = navQuery.FindPath(startPoly, endPoly, startPoint, endPoint, filter, polys, out var pathCount, query.MaxPathPoints); |
83 | | - if (status.Failed() || status.IsPartial()) |
84 | | - return; |
| 83 | + navQuery.FindPath(startPoly, endPoly, startPoint, endPoint, filter, polys, out var pathCount, polys.Length); |
85 | 84 |
|
86 | | - var pathPointsSpan = CollectionsMarshal.AsSpan(result.PathPoints); |
87 | | - status = navQuery.FindStraightPath(startPoint, endPoint, polys, polys.Length, pathPointsSpan, out var straightPathCount, query.MaxPathPoints, 0); |
88 | | - if (status.Failed()) |
| 85 | + if (0 >= pathCount) |
| 86 | + { |
89 | 87 | return; |
| 88 | + } |
| 89 | + |
| 90 | + // In case of partial path, make sure the end point is clamped to the last polygon. |
| 91 | + var endPosition = new RcVec3f(endPoint.X, endPoint.Y, endPoint.Z); |
| 92 | + if (polys[pathCount - 1] != endPoly) |
| 93 | + { |
| 94 | + status = navQuery.ClosestPointOnPoly(polys[pathCount - 1], endPoint, out var closest, out var _); |
| 95 | + if (status.Succeeded()) |
| 96 | + { |
| 97 | + endPosition = closest; |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + // Due to Dotrecast using Spans, we need to allocate the array with the max size possible then resize it later to remove empty entries. |
| 102 | + // TODO: By default we allocate 1024 points which is way more than enough for most cases and should maybe be defaulted to a smaller value in the future. |
| 103 | + result.PathPoints = new DtStraightPath[query.MaxPathPoints]; |
| 104 | + navQuery.FindStraightPath(startPoint, endPosition, polys, pathCount, result.PathPoints, out var straightPathCount, query.MaxPathPoints, 0); |
| 105 | + |
| 106 | + // cut out the empty entries |
| 107 | + Array.Resize(ref result.PathPoints, straightPathCount); |
| 108 | + |
90 | 109 | result.PathFound = true; |
91 | 110 | } |
92 | 111 |
|
|
0 commit comments