Compare commits

...

2 Commits

Author SHA1 Message Date
wrenge 7de4b51135 Merge branch 'risky_optimizations' 2024-11-13 16:19:06 +03:00
wrenge 4824f29db7 Non alloc raycast 2024-11-13 15:51:02 +03:00
2 changed files with 21 additions and 7 deletions

View File

@ -23,6 +23,7 @@ using System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Core.Buffers; using DotRecast.Core.Buffers;
using DotRecast.Core.Numerics; using DotRecast.Core.Numerics;
using CollectionExtensions = DotRecast.Core.Collections.CollectionExtensions;
namespace DotRecast.Detour namespace DotRecast.Detour
{ {
@ -33,6 +34,8 @@ namespace DotRecast.Detour
/// @ingroup detour /// @ingroup detour
public class DtNavMeshQuery public class DtNavMeshQuery
{ {
public const int MAX_PATH_LENGTH = 256;
protected readonly DtNavMesh m_nav; //< Pointer to navmesh data. protected readonly DtNavMesh m_nav; //< Pointer to navmesh data.
protected DtQueryData m_query; //< Sliced query state. protected DtQueryData m_query; //< Sliced query state.
@ -882,7 +885,8 @@ namespace DotRecast.Detour
float lastBestNodeCost = startNode.total; float lastBestNodeCost = startNode.total;
DtRaycastHit rayHit = new DtRaycastHit(); DtRaycastHit rayHit = new DtRaycastHit();
rayHit.path = new List<long>(); using var pathRent = RcRentedArray.Rent<long>(MAX_PATH_LENGTH);
rayHit.path = pathRent.AsArray();
while (!m_openList.IsEmpty()) while (!m_openList.IsEmpty())
{ {
// Remove node from open list and put it in closed list. // Remove node from open list and put it in closed list.
@ -1171,7 +1175,8 @@ namespace DotRecast.Detour
} }
var rayHit = new DtRaycastHit(); var rayHit = new DtRaycastHit();
rayHit.path = new List<long>(); using var pathRent = RcRentedArray.Rent<long>(MAX_PATH_LENGTH);
rayHit.path = pathRent.AsArray();
int iter = 0; int iter = 0;
while (iter < maxIter && !m_openList.IsEmpty()) while (iter < maxIter && !m_openList.IsEmpty())
@ -2263,13 +2268,15 @@ namespace DotRecast.Detour
out float t, out RcVec3f hitNormal, ref List<long> path) out float t, out RcVec3f hitNormal, ref List<long> path)
{ {
DtRaycastHit hit = new DtRaycastHit(); DtRaycastHit hit = new DtRaycastHit();
hit.path = path; using var pathRent = RcRentedArray.Rent<long>(MAX_PATH_LENGTH);
hit.path = pathRent.AsArray();
DtStatus status = Raycast(startRef, startPos, endPos, filter, 0, ref hit, 0); DtStatus status = Raycast(startRef, startPos, endPos, filter, 0, ref hit, 0);
t = hit.t; t = hit.t;
hitNormal = hit.hitNormal; hitNormal = hit.hitNormal;
path = hit.path; path.Clear();
CollectionExtensions.AddRange(path, new Span<long>(hit.path, 0, hit.pathCount));
return status; return status;
} }
@ -2335,7 +2342,7 @@ namespace DotRecast.Detour
} }
hit.t = 0; hit.t = 0;
hit.path.Clear(); hit.pathCount = 0;
hit.pathCost = 0; hit.pathCost = 0;
Span<RcVec3f> verts = stackalloc RcVec3f[m_nav.GetMaxVertsPerPoly() + 1]; Span<RcVec3f> verts = stackalloc RcVec3f[m_nav.GetMaxVertsPerPoly() + 1];
@ -2388,7 +2395,7 @@ namespace DotRecast.Detour
} }
// Store visited polygons. // Store visited polygons.
hit.path.Add(curRef); hit.AddPathNode(curRef);
// Ray end is completely inside the polygon. // Ray end is completely inside the polygon.
if (segMax == -1) if (segMax == -1)

View File

@ -38,9 +38,16 @@ namespace DotRecast.Detour
public int hitEdgeIndex; public int hitEdgeIndex;
/// Pointer to an array of reference ids of the visited polygons. [opt] /// Pointer to an array of reference ids of the visited polygons. [opt]
public List<long> path; public long[] path;
public int pathCount;
/// The cost of the path until hit. /// The cost of the path until hit.
public float pathCost; public float pathCost;
public void AddPathNode(long nodeRef)
{
path[pathCount++] = nodeRef;
}
} }
} }