forked from mirror/DotRecast
Changed to limit neighbor search to a maximum count and use array for memory efficiency in `DtCrowd.AddNeighbour()`
This commit is contained in:
parent
76e5ade4d1
commit
9ebaa3fc65
|
@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()`
|
- Changed `new float[]` to `stackalloc float[]` in `DtConvexConvexIntersections.Intersect()`
|
||||||
- Changed agents management from list to dictionary in `DtCrowd`
|
- Changed agents management from list to dictionary in `DtCrowd`
|
||||||
- Changed to efficiently stack nearby DtCrowdAgents in `DtCrowd.GetNeighbours()`
|
- Changed to efficiently stack nearby DtCrowdAgents in `DtCrowd.GetNeighbours()`
|
||||||
|
- Changed to limit neighbor search to a maximum count and use array for memory efficiency in `DtCrowd.AddNeighbour()`
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Removed RcMeshDetails.VdistSq2(float[], float[])
|
- Removed RcMeshDetails.VdistSq2(float[], float[])
|
||||||
|
|
|
@ -20,7 +20,7 @@ freely, subject to the following restrictions:
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Diagnostics;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
using DotRecast.Core.Collections;
|
using DotRecast.Core.Collections;
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
|
@ -258,6 +258,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
ag.topologyOptTime = 0;
|
ag.topologyOptTime = 0;
|
||||||
ag.targetReplanTime = 0;
|
ag.targetReplanTime = 0;
|
||||||
|
ag.nneis = 0;
|
||||||
|
|
||||||
ag.dvel = RcVec3f.Zero;
|
ag.dvel = RcVec3f.Zero;
|
||||||
ag.nvel = RcVec3f.Zero;
|
ag.nvel = RcVec3f.Zero;
|
||||||
|
@ -897,14 +898,56 @@ namespace DotRecast.Detour.Crowd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query neighbour agents
|
// Query neighbour agents
|
||||||
GetNeighbours(ag.npos, ag.option.height, ag.option.collisionQueryRange, ag, ref ag.neis, _grid);
|
ag.nneis = GetNeighbours(ag.npos, ag.option.height, ag.option.collisionQueryRange, ag, ag.neis, DtCrowdConst.DT_CROWDAGENT_MAX_NEIGHBOURS, _grid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int AddNeighbour(DtCrowdAgent idx, float dist, Span<DtCrowdNeighbour> neis, int nneis, int maxNeis)
|
||||||
private int GetNeighbours(RcVec3f pos, float height, float range, DtCrowdAgent skip, ref List<DtCrowdNeighbour> result, DtProximityGrid grid)
|
|
||||||
{
|
{
|
||||||
result.Clear();
|
// Insert neighbour based on the distance.
|
||||||
|
int nei = 0;
|
||||||
|
if (0 == nneis)
|
||||||
|
{
|
||||||
|
nei = nneis;
|
||||||
|
}
|
||||||
|
else if (dist >= neis[nneis - 1].dist)
|
||||||
|
{
|
||||||
|
if (nneis >= maxNeis)
|
||||||
|
return nneis;
|
||||||
|
nei = nneis;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nneis; ++i)
|
||||||
|
{
|
||||||
|
if (dist <= neis[i].dist)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tgt = i + 1;
|
||||||
|
int n = Math.Min(nneis - i, maxNeis - tgt);
|
||||||
|
|
||||||
|
Debug.Assert(tgt + n <= maxNeis);
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
RcSpans.Move(neis, i, tgt, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
nei = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
neis[nei] = new DtCrowdNeighbour(idx, dist);
|
||||||
|
|
||||||
|
return Math.Min(nneis + 1, maxNeis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetNeighbours(RcVec3f pos, float height, float range, DtCrowdAgent skip, DtCrowdNeighbour[] result, int maxResult, DtProximityGrid grid)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
const int MAX_NEIS = 32;
|
const int MAX_NEIS = 32;
|
||||||
Span<int> ids = stackalloc int[MAX_NEIS];
|
Span<int> ids = stackalloc int[MAX_NEIS];
|
||||||
|
@ -934,11 +977,10 @@ namespace DotRecast.Detour.Crowd
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Add(new DtCrowdNeighbour(ag, distSqr));
|
n = AddNeighbour(ag, distSqr, result, n, maxResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Sort((o1, o2) => o1.dist.CompareTo(o2.dist));
|
return n;
|
||||||
return result.Count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindCorners(IList<DtCrowdAgent> agents, DtCrowdAgentDebugInfo debug)
|
private void FindCorners(IList<DtCrowdAgent> agents, DtCrowdAgentDebugInfo debug)
|
||||||
|
@ -1028,7 +1070,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
ag.state = DtCrowdAgentState.DT_CROWDAGENT_STATE_OFFMESH;
|
ag.state = DtCrowdAgentState.DT_CROWDAGENT_STATE_OFFMESH;
|
||||||
ag.ncorners = 0;
|
ag.ncorners = 0;
|
||||||
ag.neis.Clear();
|
ag.nneis = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1093,7 +1135,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
float w = 0;
|
float w = 0;
|
||||||
RcVec3f disp = new RcVec3f();
|
RcVec3f disp = new RcVec3f();
|
||||||
|
|
||||||
for (int j = 0; j < ag.neis.Count; ++j)
|
for (int j = 0; j < ag.nneis; ++j)
|
||||||
{
|
{
|
||||||
DtCrowdAgent nei = ag.neis[j].agent;
|
DtCrowdAgent nei = ag.neis[j].agent;
|
||||||
|
|
||||||
|
@ -1155,7 +1197,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
_obstacleQuery.Reset();
|
_obstacleQuery.Reset();
|
||||||
|
|
||||||
// Add neighbours as obstacles.
|
// Add neighbours as obstacles.
|
||||||
for (int j = 0; j < ag.neis.Count; ++j)
|
for (int j = 0; j < ag.nneis; ++j)
|
||||||
{
|
{
|
||||||
DtCrowdAgent nei = ag.neis[j].agent;
|
DtCrowdAgent nei = ag.neis[j].agent;
|
||||||
_obstacleQuery.AddCircle(nei.npos, nei.option.radius, nei.vel, nei.dvel);
|
_obstacleQuery.AddCircle(nei.npos, nei.option.radius, nei.vel, nei.dvel);
|
||||||
|
@ -1243,7 +1285,7 @@ namespace DotRecast.Detour.Crowd
|
||||||
|
|
||||||
float w = 0;
|
float w = 0;
|
||||||
|
|
||||||
for (int j = 0; j < ag.neis.Count; ++j)
|
for (int j = 0; j < ag.nneis; ++j)
|
||||||
{
|
{
|
||||||
DtCrowdAgent nei = ag.neis[j].agent;
|
DtCrowdAgent nei = ag.neis[j].agent;
|
||||||
long idx1 = nei.idx;
|
long idx1 = nei.idx;
|
||||||
|
|
|
@ -37,16 +37,19 @@ namespace DotRecast.Detour.Crowd
|
||||||
public bool partial;
|
public bool partial;
|
||||||
|
|
||||||
/// The path corridor the agent is using.
|
/// The path corridor the agent is using.
|
||||||
public DtPathCorridor corridor;
|
public readonly DtPathCorridor corridor;
|
||||||
|
|
||||||
/// The local boundary data for the agent.
|
/// The local boundary data for the agent.
|
||||||
public DtLocalBoundary boundary;
|
public readonly DtLocalBoundary boundary;
|
||||||
|
|
||||||
/// Time since the agent's path corridor was optimized.
|
/// Time since the agent's path corridor was optimized.
|
||||||
public float topologyOptTime;
|
public float topologyOptTime;
|
||||||
|
|
||||||
/// The known neighbors of the agent.
|
/// The known neighbors of the agent.
|
||||||
public List<DtCrowdNeighbour> neis = new List<DtCrowdNeighbour>();
|
public readonly DtCrowdNeighbour[] neis = new DtCrowdNeighbour[DtCrowdConst.DT_CROWDAGENT_MAX_NEIGHBOURS];
|
||||||
|
|
||||||
|
/// The number of neighbors.
|
||||||
|
public int nneis;
|
||||||
|
|
||||||
/// The desired speed.
|
/// The desired speed.
|
||||||
public float desiredSpeed;
|
public float desiredSpeed;
|
||||||
|
|
|
@ -325,7 +325,7 @@ public class CrowdSampleTool : ISampleTool
|
||||||
2.0f);
|
2.0f);
|
||||||
|
|
||||||
dd.Begin(LINES, 2.0f);
|
dd.Begin(LINES, 2.0f);
|
||||||
for (int j = 0; j < ag.neis.Count; ++j)
|
for (int j = 0; j < ag.nneis; ++j)
|
||||||
{
|
{
|
||||||
DtCrowdAgent nei = ag.neis[j].agent;
|
DtCrowdAgent nei = ag.neis[j].agent;
|
||||||
if (nei != null)
|
if (nei != null)
|
||||||
|
|
Loading…
Reference in New Issue