diff --git a/src/DotRecast.Detour.Crowd/DtCrowd.cs b/src/DotRecast.Detour.Crowd/DtCrowd.cs index 0b7ef026..6e2bd3b6 100644 --- a/src/DotRecast.Detour.Crowd/DtCrowd.cs +++ b/src/DotRecast.Detour.Crowd/DtCrowd.cs @@ -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; @@ -894,10 +895,12 @@ private int GetNeighbours(RcVec3f pos, float height, float range, DtCrowdAgent s { result.Clear(); - var proxAgents = new HashSet(); - int nids = grid.QueryItems(pos.X - range, pos.Z - range, pos.X + range, pos.Z + range, ref proxAgents); - foreach (DtCrowdAgent ag in proxAgents) + int MAX_NEIS = 32; + using var proxAgents = RcRentedArray.RentDisposableArray(MAX_NEIS); + int nids = grid.QueryItems(pos.X - range, pos.Z - range, pos.X + range, pos.Z + range, proxAgents.AsRentedArray(), MAX_NEIS); + for (int i = 0; i < nids; ++i) { + var ag = proxAgents[i]; if (ag == skip) { continue; diff --git a/src/DotRecast.Detour.Crowd/DtProximityGrid.cs b/src/DotRecast.Detour.Crowd/DtProximityGrid.cs index d10bee06..b72a1942 100644 --- a/src/DotRecast.Detour.Crowd/DtProximityGrid.cs +++ b/src/DotRecast.Detour.Crowd/DtProximityGrid.cs @@ -84,29 +84,49 @@ public void AddItem(DtCrowdAgent agent, float minx, float miny, float maxx, floa } // 해당 셀 사이즈의 크기로 x ~ y 영역을 찾아, 군집 에이전트를 가져오는 코드 - public int QueryItems(float minx, float miny, float maxx, float maxy, ref HashSet result) + public int QueryItems(float minx, float miny, float maxx, float maxy, DtCrowdAgent[] ids, int maxIds) { int iminx = (int)MathF.Floor(minx * _invCellSize); int iminy = (int)MathF.Floor(miny * _invCellSize); int imaxx = (int)MathF.Floor(maxx * _invCellSize); int imaxy = (int)MathF.Floor(maxy * _invCellSize); + int n = 0; + for (int y = iminy; y <= imaxy; ++y) { for (int x = iminx; x <= imaxx; ++x) { long key = CombineKey(x, y); - if (_items.TryGetValue(key, out var ids)) + bool hasPool = _items.TryGetValue(key, out var pool); + if (!hasPool) + continue; + + for (int idx = 0; idx < pool.Count; ++idx) { - for (int i = 0; i < ids.Count; ++i) + var item = pool[idx]; + + // Check if the id exists already. + int end = n; + int i = 0; + while (i != end && ids[i] != item) { - result.Add(ids[i]); + ++i; + } + + // Item not found, add it. + if (i == n) + { + ids[n++] = item; + + if (n >= maxIds) + return n; } } } } - return result.Count; + return n; } public IEnumerable<(long, int)> GetItemCounts()