@@ -21,6 +21,7 @@ 3. This notice may not be removed or altered from any source distribution.
21
21
using System ;
22
22
using System . Collections . Generic ;
23
23
using DotRecast . Core ;
24
+ using DotRecast . Core . Buffers ;
24
25
using DotRecast . Core . Collections ;
25
26
using DotRecast . Core . Numerics ;
26
27
@@ -34,13 +35,15 @@ public class DtNavMeshQuery
34
35
protected readonly DtNodePool m_nodePool ;
35
36
protected readonly DtNodeQueue m_openList ;
36
37
protected DtQueryData m_query ;
38
+ protected readonly DtNodePool m_tinyNodePool ;
37
39
38
40
/// < Sliced query state.
39
41
public DtNavMeshQuery ( DtNavMesh nav )
40
42
{
41
43
m_nav = nav ;
42
44
m_nodePool = new DtNodePool ( ) ;
43
45
m_openList = new DtNodeQueue ( ) ;
46
+ m_tinyNodePool = new DtNodePool ( ) ;
44
47
}
45
48
46
49
/// Returns random location on navmesh.
@@ -454,16 +457,16 @@ public DtStatus ClosestPointOnPolyBoundary(long refs, RcVec3f pos, out RcVec3f c
454
457
}
455
458
456
459
// 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 ( ) ) ;
460
463
int nv = poly . vertCount ;
461
464
for ( int i = 0 ; i < nv ; ++ i )
462
465
{
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 ) ;
464
467
}
465
468
466
- if ( DtUtils . DistancePtPolyEdgesSqr ( pos , verts , nv , edged , edget ) )
469
+ if ( DtUtils . DistancePtPolyEdgesSqr ( pos , verts . AsRentedArray ( ) , nv , edged . AsRentedArray ( ) , edget . AsRentedArray ( ) ) )
467
470
{
468
471
closest = pos ;
469
472
}
@@ -483,7 +486,7 @@ public DtStatus ClosestPointOnPolyBoundary(long refs, RcVec3f pos, out RcVec3f c
483
486
484
487
int va = imin * 3 ;
485
488
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 ] ) ;
487
490
}
488
491
489
492
return DtStatus . DT_SUCCESS ;
@@ -1783,7 +1786,9 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1783
1786
resultPos = RcVec3f . Zero ;
1784
1787
1785
1788
if ( null != visited )
1789
+ {
1786
1790
visited . Clear ( ) ;
1791
+ }
1787
1792
1788
1793
// Validate input
1789
1794
if ( ! m_nav . IsValidPolyRef ( startRef ) || ! startPos . IsFinite ( )
@@ -1792,9 +1797,9 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1792
1797
return DtStatus . DT_FAILURE | DtStatus . DT_INVALID_PARAM ;
1793
1798
}
1794
1799
1795
- DtNodePool tinyNodePool = new DtNodePool ( ) ;
1800
+ m_tinyNodePool . Clear ( ) ;
1796
1801
1797
- DtNode startNode = tinyNodePool . GetNode ( startRef ) ;
1802
+ DtNode startNode = m_tinyNodePool . GetNode ( startRef ) ;
1798
1803
startNode . pidx = 0 ;
1799
1804
startNode . cost = 0 ;
1800
1805
startNode . total = 0 ;
@@ -1812,7 +1817,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1812
1817
var searchPos = RcVec3f . Lerp ( startPos , endPos , 0.5f ) ;
1813
1818
float searchRadSqr = RcMath . Sqr ( RcVec3f . Distance ( startPos , endPos ) / 2.0f + 0.001f ) ;
1814
1819
1815
- float [ ] verts = new float [ m_nav . GetMaxVertsPerPoly ( ) * 3 ] ;
1820
+ using var verts = RcRentedArray . RentDisposableArray < float > ( m_nav . GetMaxVertsPerPoly ( ) * 3 ) ;
1816
1821
1817
1822
while ( 0 < stack . Count )
1818
1823
{
@@ -1829,11 +1834,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1829
1834
int nverts = curPoly . vertCount ;
1830
1835
for ( int i = 0 ; i < nverts ; ++ i )
1831
1836
{
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 ) ;
1833
1838
}
1834
1839
1835
1840
// If target is inside the poly, stop search.
1836
- if ( DtUtils . PointInPolygon ( endPos , verts , nverts ) )
1841
+ if ( DtUtils . PointInPolygon ( endPos , verts . AsRentedArray ( ) , nverts ) )
1837
1842
{
1838
1843
bestNode = curNode ;
1839
1844
bestPos = endPos ;
@@ -1846,7 +1851,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1846
1851
// Find links to neighbours.
1847
1852
int MAX_NEIS = 8 ;
1848
1853
int nneis = 0 ;
1849
- long [ ] neis = new long [ MAX_NEIS ] ;
1854
+ using var neis = RcRentedArray . RentDisposableArray < long > ( MAX_NEIS ) ;
1850
1855
1851
1856
if ( ( curPoly . neis [ j ] & DtNavMesh . DT_EXT_LINK ) != 0 )
1852
1857
{
@@ -1886,11 +1891,11 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1886
1891
// Wall edge, calc distance.
1887
1892
int vj = j * 3 ;
1888
1893
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 ) ;
1890
1895
if ( distSqr < bestDist )
1891
1896
{
1892
1897
// Update nearest distance.
1893
- bestPos = RcVecUtils . Lerp ( verts , vj , vi , tseg ) ;
1898
+ bestPos = RcVecUtils . Lerp ( verts . AsRentedArray ( ) , vj , vi , tseg ) ;
1894
1899
bestDist = distSqr ;
1895
1900
bestNode = curNode ;
1896
1901
}
@@ -1899,7 +1904,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1899
1904
{
1900
1905
for ( int k = 0 ; k < nneis ; ++ k )
1901
1906
{
1902
- DtNode neighbourNode = tinyNodePool . GetNode ( neis [ k ] ) ;
1907
+ DtNode neighbourNode = m_tinyNodePool . GetNode ( neis [ k ] ) ;
1903
1908
// Skip if already visited.
1904
1909
if ( ( neighbourNode . flags & DtNodeFlags . DT_NODE_CLOSED ) != 0 )
1905
1910
{
@@ -1910,14 +1915,14 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1910
1915
// TODO: Maybe should use GetPortalPoints(), but this one is way faster.
1911
1916
int vj = j * 3 ;
1912
1917
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 _ ) ;
1914
1919
if ( distSqr > searchRadSqr )
1915
1920
{
1916
1921
continue ;
1917
1922
}
1918
1923
1919
1924
// Mark as the node as visited and push to queue.
1920
- neighbourNode . pidx = tinyNodePool . GetNodeIdx ( curNode ) ;
1925
+ neighbourNode . pidx = m_tinyNodePool . GetNodeIdx ( curNode ) ;
1921
1926
neighbourNode . flags |= DtNodeFlags . DT_NODE_CLOSED ;
1922
1927
stack . AddLast ( neighbourNode ) ;
1923
1928
}
@@ -1932,8 +1937,8 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1932
1937
DtNode node = bestNode ;
1933
1938
do
1934
1939
{
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 ) ;
1937
1942
prev = node ;
1938
1943
node = next ;
1939
1944
} while ( node != null ) ;
@@ -1943,7 +1948,7 @@ public DtStatus MoveAlongSurface(long startRef, RcVec3f startPos, RcVec3f endPos
1943
1948
do
1944
1949
{
1945
1950
visited . Add ( node . id ) ;
1946
- node = tinyNodePool . GetNodeAtIdx ( node . pidx ) ;
1951
+ node = m_tinyNodePool . GetNodeAtIdx ( node . pidx ) ;
1947
1952
} while ( node != null ) ;
1948
1953
}
1949
1954
@@ -2794,9 +2799,9 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
2794
2799
resultRef . Clear ( ) ;
2795
2800
resultParent . Clear ( ) ;
2796
2801
2797
- DtNodePool tinyNodePool = new DtNodePool ( ) ;
2802
+ m_tinyNodePool . Clear ( ) ;
2798
2803
2799
- DtNode startNode = tinyNodePool . GetNode ( startRef ) ;
2804
+ DtNode startNode = m_tinyNodePool . GetNode ( startRef ) ;
2800
2805
startNode . pidx = 0 ;
2801
2806
startNode . id = startRef ;
2802
2807
startNode . flags = DtNodeFlags . DT_NODE_CLOSED ;
@@ -2808,8 +2813,8 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
2808
2813
2809
2814
float radiusSqr = RcMath . Sqr ( radius ) ;
2810
2815
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 ) ;
2813
2818
2814
2819
while ( 0 < stack . Count )
2815
2820
{
@@ -2832,7 +2837,7 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
2832
2837
continue ;
2833
2838
}
2834
2839
2835
- DtNode neighbourNode = tinyNodePool . GetNode ( neighbourRef ) ;
2840
+ DtNode neighbourNode = m_tinyNodePool . GetNode ( neighbourRef ) ;
2836
2841
// Skip visited.
2837
2842
if ( ( neighbourNode . flags & DtNodeFlags . DT_NODE_CLOSED ) != 0 )
2838
2843
{
@@ -2872,15 +2877,15 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
2872
2877
// Mark node visited, this is done before the overlap test so that
2873
2878
// we will not visit the poly again if the test fails.
2874
2879
neighbourNode . flags |= DtNodeFlags . DT_NODE_CLOSED ;
2875
- neighbourNode . pidx = tinyNodePool . GetNodeIdx ( curNode ) ;
2880
+ neighbourNode . pidx = m_tinyNodePool . GetNodeIdx ( curNode ) ;
2876
2881
2877
2882
// Check that the polygon does not collide with existing polygons.
2878
2883
2879
2884
// Collect vertices of the neighbour poly.
2880
2885
int npa = neighbourPoly . vertCount ;
2881
2886
for ( int k = 0 ; k < npa ; ++ k )
2882
2887
{
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 ) ;
2884
2889
}
2885
2890
2886
2891
bool overlap = false ;
@@ -2911,10 +2916,10 @@ public DtStatus FindLocalNeighbourhood(long startRef, RcVec3f centerPos, float r
2911
2916
int npb = pastPoly . vertCount ;
2912
2917
for ( int k = 0 ; k < npb ; ++ k )
2913
2918
{
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 ) ;
2915
2920
}
2916
2921
2917
- if ( DtUtils . OverlapPolyPoly2D ( pa , npa , pb , npb ) )
2922
+ if ( DtUtils . OverlapPolyPoly2D ( pa . AsRentedArray ( ) , npa , pb . AsRentedArray ( ) , npb ) )
2918
2923
{
2919
2924
overlap = true ;
2920
2925
break ;
0 commit comments