Skip to content

Commit

Permalink
fix: SOH issue (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikpil committed Jan 24, 2024
1 parent 6573a56 commit 07adaaf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 30 deletions.
4 changes: 4 additions & 0 deletions src/DotRecast.Core/Buffers/RcRentedArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public T this[int index]
}
}

public T[] AsRentedArray()
{
return _array;
}

public void Dispose()
{
Expand Down
3 changes: 2 additions & 1 deletion src/DotRecast.Detour.Crowd/DtObstacleAvoidanceQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ 3. This notice may not be removed or altered from any source distribution.

using System;
using DotRecast.Core;
using DotRecast.Core.Buffers;
using DotRecast.Core.Numerics;


Expand Down Expand Up @@ -402,7 +403,7 @@ public int SampleVelocityAdaptive(RcVec3f pos, float rad, float vmax, RcVec3f ve
debug.Reset();

// Build sampling pattern aligned to desired velocity.
float[] pat = new float[(DT_MAX_PATTERN_DIVS * DT_MAX_PATTERN_RINGS + 1) * 2];
using var pat = RcRentedArray.RentDisposableArray<float>((DT_MAX_PATTERN_DIVS * DT_MAX_PATTERN_RINGS + 1) * 2);
int npat = 0;

int ndivs = m_params.adaptiveDivs;
Expand Down
63 changes: 34 additions & 29 deletions src/DotRecast.Detour/DtNavMeshQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ 3. This notice may not be removed or altered from any source distribution.
using System;
using System.Collections.Generic;
using DotRecast.Core;
using DotRecast.Core.Buffers;
using DotRecast.Core.Collections;
using DotRecast.Core.Numerics;

Expand All @@ -34,13 +35,15 @@ public class DtNavMeshQuery
protected readonly DtNodePool m_nodePool;
protected readonly DtNodeQueue m_openList;
protected DtQueryData m_query;
protected readonly DtNodePool m_tinyNodePool;

/// < Sliced query state.
public DtNavMeshQuery(DtNavMesh nav)
{
m_nav = nav;
m_nodePool = new DtNodePool();
m_openList = new DtNodeQueue();
m_tinyNodePool = new DtNodePool();
}

/// Returns random location on navmesh.
Expand Down Expand Up @@ -454,16 +457,16 @@ public DtStatus ClosestPointOnPolyBoundary(long refs, RcVec3f pos, out RcVec3f c
}

// Collect vertices.
float[] verts = new float[m_nav.GetMaxVertsPerPoly() * 3];
float[] edged = new float[m_nav.GetMaxVertsPerPoly()];
float[] edget = new float[m_nav.GetMaxVertsPerPoly()];
using var verts = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);
using var edged = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly());
using var edget = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly());
int nv = poly.vertCount;
for (int i = 0; i < nv; ++i)
{
RcArrays.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
RcArrays.Copy(tile.data.verts, poly.verts[i] * 3, verts.AsRentedArray(), i * 3, 3);
}

if (DtUtils.DistancePtPolyEdgesSqr(pos, verts, nv, edged, edget))
if (DtUtils.DistancePtPolyEdgesSqr(pos, verts.AsRentedArray(), nv, edged.AsRentedArray(), edget.AsRentedArray()))
{
closest = pos;
}
Expand All @@ -483,7 +486,7 @@ public DtStatus ClosestPointOnPolyBoundary(long refs, RcVec3f pos, out RcVec3f c

int va = imin * 3;
int vb = ((imin + 1) % nv) * 3;
closest = RcVecUtils.Lerp(verts, va, vb, edget[imin]);
closest = RcVecUtils.Lerp(verts.AsRentedArray(), va, vb, edget[imin]);
}

return DtStatus.DT_SUCCESS;
Expand Down Expand Up @@ -1783,7 +1786,9 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
resultPos = RcVec3f.Zero;

if (null != visited)
{
visited.Clear();
}

// Validate input
if (!m_nav.IsValidPolyRef(startRef) || !startPos.IsFinite()
Expand All @@ -1792,9 +1797,9 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
}

DtNodePool tinyNodePool = new DtNodePool();
m_tinyNodePool.Clear();

DtNode startNode = tinyNodePool.GetNode(startRef);
DtNode startNode = m_tinyNodePool.GetNode(startRef);
startNode.pidx = 0;
startNode.cost = 0;
startNode.total = 0;
Expand All @@ -1812,7 +1817,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
var searchPos = RcVec3f.Lerp(startPos, endPos, 0.5f);
float searchRadSqr = RcMath.Sqr(RcVec3f.Distance(startPos, endPos) / 2.0f + 0.001f);

float[] verts = new float[m_nav.GetMaxVertsPerPoly() * 3];
using var verts = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);

while (0 < stack.Count)
{
Expand All @@ -1829,11 +1834,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
int nverts = curPoly.vertCount;
for (int i = 0; i < nverts; ++i)
{
RcArrays.Copy(curTile.data.verts, curPoly.verts[i] * 3, verts, i * 3, 3);
RcArrays.Copy(curTile.data.verts, curPoly.verts[i] * 3, verts.AsRentedArray(), i * 3, 3);
}

// If target is inside the poly, stop search.
if (DtUtils.PointInPolygon(endPos, verts, nverts))
if (DtUtils.PointInPolygon(endPos, verts.AsRentedArray(), nverts))
{
bestNode = curNode;
bestPos = endPos;
Expand All @@ -1846,7 +1851,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
// Find links to neighbours.
int MAX_NEIS = 8;
int nneis = 0;
long[] neis = new long[MAX_NEIS];
using var neis = RcRentedArray.RentDisposableArray<long>(MAX_NEIS);

if ((curPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
{
Expand Down Expand Up @@ -1886,11 +1891,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
// Wall edge, calc distance.
int vj = j * 3;
int vi = i * 3;
var distSqr = DtUtils.DistancePtSegSqr2D(endPos, verts, vj, vi, out var tseg);
var distSqr = DtUtils.DistancePtSegSqr2D(endPos, verts.AsRentedArray(), vj, vi, out var tseg);
if (distSqr < bestDist)
{
// Update nearest distance.
bestPos = RcVecUtils.Lerp(verts, vj, vi, tseg);
bestPos = RcVecUtils.Lerp(verts.AsRentedArray(), vj, vi, tseg);
bestDist = distSqr;
bestNode = curNode;
}
Expand All @@ -1899,7 +1904,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
{
for (int k = 0; k < nneis; ++k)
{
DtNode neighbourNode = tinyNodePool.GetNode(neis[k]);
DtNode neighbourNode = m_tinyNodePool.GetNode(neis[k]);
// Skip if already visited.
if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
{
Expand All @@ -1910,14 +1915,14 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
// TODO: Maybe should use GetPortalPoints(), but this one is way faster.
int vj = j * 3;
int vi = i * 3;
var distSqr = DtUtils.DistancePtSegSqr2D(searchPos, verts, vj, vi, out var _);
var distSqr = DtUtils.DistancePtSegSqr2D(searchPos, verts.AsRentedArray(), vj, vi, out var _);
if (distSqr > searchRadSqr)
{
continue;
}

// Mark as the node as visited and push to queue.
neighbourNode.pidx = tinyNodePool.GetNodeIdx(curNode);
neighbourNode.pidx = m_tinyNodePool.GetNodeIdx(curNode);
neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED;
stack.AddLast(neighbourNode);
}
Expand All @@ -1932,8 +1937,8 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
DtNode node = bestNode;
do
{
DtNode next = tinyNodePool.GetNodeAtIdx(node.pidx);
node.pidx = tinyNodePool.GetNodeIdx(prev);
DtNode next = m_tinyNodePool.GetNodeAtIdx(node.pidx);
node.pidx = m_tinyNodePool.GetNodeIdx(prev);
prev = node;
node = next;
} while (node != null);
Expand All @@ -1943,7 +1948,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
do
{
visited.Add(node.id);
node = tinyNodePool.GetNodeAtIdx(node.pidx);
node = m_tinyNodePool.GetNodeAtIdx(node.pidx);
} while (node != null);
}

Expand Down Expand Up @@ -2794,9 +2799,9 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
resultRef.Clear();
resultParent.Clear();

DtNodePool tinyNodePool = new DtNodePool();
m_tinyNodePool.Clear();

DtNode startNode = tinyNodePool.GetNode(startRef);
DtNode startNode = m_tinyNodePool.GetNode(startRef);
startNode.pidx = 0;
startNode.id = startRef;
startNode.flags = DtNodeFlags.DT_NODE_CLOSED;
Expand All @@ -2808,8 +2813,8 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r

float radiusSqr = RcMath.Sqr(radius);

float[] pa = new float[m_nav.GetMaxVertsPerPoly() * 3];
float[] pb = new float[m_nav.GetMaxVertsPerPoly() * 3];
using var pa = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);
using var pb = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);

while (0 < stack.Count)
{
Expand All @@ -2832,7 +2837,7 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
continue;
}

DtNode neighbourNode = tinyNodePool.GetNode(neighbourRef);
DtNode neighbourNode = m_tinyNodePool.GetNode(neighbourRef);
// Skip visited.
if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
{
Expand Down Expand Up @@ -2872,15 +2877,15 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
// Mark node visited, this is done before the overlap test so that
// we will not visit the poly again if the test fails.
neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED;
neighbourNode.pidx = tinyNodePool.GetNodeIdx(curNode);
neighbourNode.pidx = m_tinyNodePool.GetNodeIdx(curNode);

// Check that the polygon does not collide with existing polygons.

// Collect vertices of the neighbour poly.
int npa = neighbourPoly.vertCount;
for (int k = 0; k < npa; ++k)
{
RcArrays.Copy(neighbourTile.data.verts, neighbourPoly.verts[k] * 3, pa, k * 3, 3);
RcArrays.Copy(neighbourTile.data.verts, neighbourPoly.verts[k] * 3, pa.AsRentedArray(), k * 3, 3);
}

bool overlap = false;
Expand Down Expand Up @@ -2911,10 +2916,10 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
int npb = pastPoly.vertCount;
for (int k = 0; k < npb; ++k)
{
RcArrays.Copy(pastTile.data.verts, pastPoly.verts[k] * 3, pb, k * 3, 3);
RcArrays.Copy(pastTile.data.verts, pastPoly.verts[k] * 3, pb.AsRentedArray(), k * 3, 3);
}

if (DtUtils.OverlapPolyPoly2D(pa, npa, pb, npb))
if (DtUtils.OverlapPolyPoly2D(pa.AsRentedArray(), npa, pb.AsRentedArray(), npb))
{
overlap = true;
break;
Expand Down

0 comments on commit 07adaaf

Please sign in to comment.