Skip to content

Commit 11637f4

Browse files
committed
fix: SOH issue (#41)
1 parent f3eab3e commit 11637f4

File tree

3 files changed

+40
-30
lines changed

3 files changed

+40
-30
lines changed

src/DotRecast.Core/Buffers/RcRentedArray.cs

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public T this[int index]
4646
}
4747
}
4848

49+
public T[] AsRentedArray()
50+
{
51+
return _array;
52+
}
4953

5054
public void Dispose()
5155
{

src/DotRecast.Detour.Crowd/DtObstacleAvoidanceQuery.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ 3. This notice may not be removed or altered from any source distribution.
2020

2121
using System;
2222
using DotRecast.Core;
23+
using DotRecast.Core.Buffers;
2324
using DotRecast.Core.Numerics;
2425

2526

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

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

408409
int ndivs = m_params.adaptiveDivs;

src/DotRecast.Detour/DtNavMeshQuery.cs

+34-29
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ 3. This notice may not be removed or altered from any source distribution.
2121
using System;
2222
using System.Collections.Generic;
2323
using DotRecast.Core;
24+
using DotRecast.Core.Buffers;
2425
using DotRecast.Core.Collections;
2526
using DotRecast.Core.Numerics;
2627

@@ -34,13 +35,15 @@ public class DtNavMeshQuery
3435
protected readonly DtNodePool m_nodePool;
3536
protected readonly DtNodeQueue m_openList;
3637
protected DtQueryData m_query;
38+
protected readonly DtNodePool m_tinyNodePool;
3739

3840
/// < Sliced query state.
3941
public DtNavMeshQuery(DtNavMesh nav)
4042
{
4143
m_nav = nav;
4244
m_nodePool = new DtNodePool();
4345
m_openList = new DtNodeQueue();
46+
m_tinyNodePool = new DtNodePool();
4447
}
4548

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

456459
// Collect vertices.
457-
float[] verts = new float[m_nav.GetMaxVertsPerPoly() * 3];
458-
float[] edged = new float[m_nav.GetMaxVertsPerPoly()];
459-
float[] edget = new float[m_nav.GetMaxVertsPerPoly()];
460+
using var verts = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);
461+
using var edged = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly());
462+
using var edget = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly());
460463
int nv = poly.vertCount;
461464
for (int i = 0; i < nv; ++i)
462465
{
463-
RcArrays.Copy(tile.data.verts, poly.verts[i] * 3, verts, i * 3, 3);
466+
RcArrays.Copy(tile.data.verts, poly.verts[i] * 3, verts.AsRentedArray(), i * 3, 3);
464467
}
465468

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

484487
int va = imin * 3;
485488
int vb = ((imin + 1) % nv) * 3;
486-
closest = RcVecUtils.Lerp(verts, va, vb, edget[imin]);
489+
closest = RcVecUtils.Lerp(verts.AsRentedArray(), va, vb, edget[imin]);
487490
}
488491

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

17851788
if (null != visited)
1789+
{
17861790
visited.Clear();
1791+
}
17871792

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

1795-
DtNodePool tinyNodePool = new DtNodePool();
1800+
m_tinyNodePool.Clear();
17961801

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

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

18171822
while (0 < stack.Count)
18181823
{
@@ -1829,11 +1834,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
18291834
int nverts = curPoly.vertCount;
18301835
for (int i = 0; i < nverts; ++i)
18311836
{
1832-
RcArrays.Copy(curTile.data.verts, curPoly.verts[i] * 3, verts, i * 3, 3);
1837+
RcArrays.Copy(curTile.data.verts, curPoly.verts[i] * 3, verts.AsRentedArray(), i * 3, 3);
18331838
}
18341839

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

18511856
if ((curPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
18521857
{
@@ -1886,11 +1891,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
18861891
// Wall edge, calc distance.
18871892
int vj = j * 3;
18881893
int vi = i * 3;
1889-
var distSqr = DtUtils.DistancePtSegSqr2D(endPos, verts, vj, vi, out var tseg);
1894+
var distSqr = DtUtils.DistancePtSegSqr2D(endPos, verts.AsRentedArray(), vj, vi, out var tseg);
18901895
if (distSqr < bestDist)
18911896
{
18921897
// Update nearest distance.
1893-
bestPos = RcVecUtils.Lerp(verts, vj, vi, tseg);
1898+
bestPos = RcVecUtils.Lerp(verts.AsRentedArray(), vj, vi, tseg);
18941899
bestDist = distSqr;
18951900
bestNode = curNode;
18961901
}
@@ -1899,7 +1904,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
18991904
{
19001905
for (int k = 0; k < nneis; ++k)
19011906
{
1902-
DtNode neighbourNode = tinyNodePool.GetNode(neis[k]);
1907+
DtNode neighbourNode = m_tinyNodePool.GetNode(neis[k]);
19031908
// Skip if already visited.
19041909
if ((neighbourNode.flags & DtNodeFlags.DT_NODE_CLOSED) != 0)
19051910
{
@@ -1910,14 +1915,14 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
19101915
// TODO: Maybe should use GetPortalPoints(), but this one is way faster.
19111916
int vj = j * 3;
19121917
int vi = i * 3;
1913-
var distSqr = DtUtils.DistancePtSegSqr2D(searchPos, verts, vj, vi, out var _);
1918+
var distSqr = DtUtils.DistancePtSegSqr2D(searchPos, verts.AsRentedArray(), vj, vi, out var _);
19141919
if (distSqr > searchRadSqr)
19151920
{
19161921
continue;
19171922
}
19181923

19191924
// Mark as the node as visited and push to queue.
1920-
neighbourNode.pidx = tinyNodePool.GetNodeIdx(curNode);
1925+
neighbourNode.pidx = m_tinyNodePool.GetNodeIdx(curNode);
19211926
neighbourNode.flags |= DtNodeFlags.DT_NODE_CLOSED;
19221927
stack.AddLast(neighbourNode);
19231928
}
@@ -1932,8 +1937,8 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
19321937
DtNode node = bestNode;
19331938
do
19341939
{
1935-
DtNode next = tinyNodePool.GetNodeAtIdx(node.pidx);
1936-
node.pidx = tinyNodePool.GetNodeIdx(prev);
1940+
DtNode next = m_tinyNodePool.GetNodeAtIdx(node.pidx);
1941+
node.pidx = m_tinyNodePool.GetNodeIdx(prev);
19371942
prev = node;
19381943
node = next;
19391944
} while (node != null);
@@ -1943,7 +1948,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
19431948
do
19441949
{
19451950
visited.Add(node.id);
1946-
node = tinyNodePool.GetNodeAtIdx(node.pidx);
1951+
node = m_tinyNodePool.GetNodeAtIdx(node.pidx);
19471952
} while (node != null);
19481953
}
19491954

@@ -2794,9 +2799,9 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
27942799
resultRef.Clear();
27952800
resultParent.Clear();
27962801

2797-
DtNodePool tinyNodePool = new DtNodePool();
2802+
m_tinyNodePool.Clear();
27982803

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

28092814
float radiusSqr = RcMath.Sqr(radius);
28102815

2811-
float[] pa = new float[m_nav.GetMaxVertsPerPoly() * 3];
2812-
float[] pb = new float[m_nav.GetMaxVertsPerPoly() * 3];
2816+
using var pa = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);
2817+
using var pb = RcRentedArray.RentDisposableArray<float>(m_nav.GetMaxVertsPerPoly() * 3);
28132818

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

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

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

28792884
// Collect vertices of the neighbour poly.
28802885
int npa = neighbourPoly.vertCount;
28812886
for (int k = 0; k < npa; ++k)
28822887
{
2883-
RcArrays.Copy(neighbourTile.data.verts, neighbourPoly.verts[k] * 3, pa, k * 3, 3);
2888+
RcArrays.Copy(neighbourTile.data.verts, neighbourPoly.verts[k] * 3, pa.AsRentedArray(), k * 3, 3);
28842889
}
28852890

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

2917-
if (DtUtils.OverlapPolyPoly2D(pa, npa, pb, npb))
2922+
if (DtUtils.OverlapPolyPoly2D(pa.AsRentedArray(), npa, pb.AsRentedArray(), npb))
29182923
{
29192924
overlap = true;
29202925
break;

0 commit comments

Comments
 (0)