forked from bit/DotRecastNetSim
crowd performance
This commit is contained in:
parent
cd39cbbd36
commit
d3d966cccc
|
@ -869,7 +869,7 @@ namespace DotRecast.Detour.Crowd
|
|||
{
|
||||
Vector3f p = ag.npos;
|
||||
float r = ag.option.radius;
|
||||
m_grid.addItem(ag, p.x - r, p.z - r, p.x + r, p.z + r);
|
||||
m_grid.AddItem(ag, p.x - r, p.z - r, p.x + r, p.z + r);
|
||||
}
|
||||
|
||||
_telemetry.stop("buildProximityGrid");
|
||||
|
@ -901,12 +901,12 @@ namespace DotRecast.Detour.Crowd
|
|||
|
||||
_telemetry.stop("buildNeighbours");
|
||||
}
|
||||
|
||||
|
||||
private List<CrowdNeighbour> getNeighbours(Vector3f pos, float height, float range, CrowdAgent skip, ProximityGrid grid)
|
||||
{
|
||||
List<CrowdNeighbour> result = new List<CrowdNeighbour>();
|
||||
HashSet<CrowdAgent> proxAgents = grid.queryItems(pos.x - range, pos.z - range, pos.x + range, pos.z + range);
|
||||
|
||||
HashSet<CrowdAgent> proxAgents = grid.QueryItems(pos.x - range, pos.z - range, pos.x + range, pos.z + range);
|
||||
foreach (CrowdAgent ag in proxAgents)
|
||||
{
|
||||
if (ag == skip)
|
||||
|
@ -1392,4 +1392,4 @@ namespace DotRecast.Detour.Crowd
|
|||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,44 +20,60 @@ freely, subject to the following restrictions:
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Linq;
|
||||
|
||||
namespace DotRecast.Detour.Crowd
|
||||
{
|
||||
public class ProximityGrid
|
||||
{
|
||||
private readonly float m_cellSize;
|
||||
private readonly float m_invCellSize;
|
||||
private readonly Dictionary<ItemKey, List<CrowdAgent>> items;
|
||||
private readonly float _cellSize;
|
||||
private readonly float _invCellSize;
|
||||
private readonly Dictionary<long, List<CrowdAgent>> _items;
|
||||
|
||||
public ProximityGrid(float m_cellSize)
|
||||
public ProximityGrid(float cellSize)
|
||||
{
|
||||
this.m_cellSize = m_cellSize;
|
||||
m_invCellSize = 1.0f / m_cellSize;
|
||||
items = new Dictionary<ItemKey, List<CrowdAgent>>();
|
||||
_cellSize = cellSize;
|
||||
_invCellSize = 1.0f / cellSize;
|
||||
_items = new Dictionary<long, List<CrowdAgent>>();
|
||||
}
|
||||
|
||||
void clear()
|
||||
public static long CombineKey(int x, int y)
|
||||
{
|
||||
items.Clear();
|
||||
uint ux = (uint)x;
|
||||
uint uy = (uint)y;
|
||||
return ((long)ux << 32) | uy;
|
||||
}
|
||||
|
||||
public void addItem(CrowdAgent agent, float minx, float miny, float maxx, float maxy)
|
||||
public static void DecomposeKey(long key, out int x, out int y)
|
||||
{
|
||||
int iminx = (int)Math.Floor(minx * m_invCellSize);
|
||||
int iminy = (int)Math.Floor(miny * m_invCellSize);
|
||||
int imaxx = (int)Math.Floor(maxx * m_invCellSize);
|
||||
int imaxy = (int)Math.Floor(maxy * m_invCellSize);
|
||||
uint ux = (uint)(key >> 32);
|
||||
uint uy = (uint)key;
|
||||
x = (int)ux;
|
||||
y = (int)uy;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
public void AddItem(CrowdAgent agent, float minx, float miny, float maxx, float maxy)
|
||||
{
|
||||
int iminx = (int)Math.Floor(minx * _invCellSize);
|
||||
int iminy = (int)Math.Floor(miny * _invCellSize);
|
||||
int imaxx = (int)Math.Floor(maxx * _invCellSize);
|
||||
int imaxy = (int)Math.Floor(maxy * _invCellSize);
|
||||
|
||||
for (int y = iminy; y <= imaxy; ++y)
|
||||
{
|
||||
for (int x = iminx; x <= imaxx; ++x)
|
||||
{
|
||||
ItemKey key = new ItemKey(x, y);
|
||||
if (!items.TryGetValue(key, out var ids))
|
||||
long key = CombineKey(x, y);
|
||||
if (!_items.TryGetValue(key, out var ids))
|
||||
{
|
||||
ids = new List<CrowdAgent>();
|
||||
items.Add(key, ids);
|
||||
_items.Add(key, ids);
|
||||
}
|
||||
|
||||
ids.Add(agent);
|
||||
|
@ -65,20 +81,20 @@ namespace DotRecast.Detour.Crowd
|
|||
}
|
||||
}
|
||||
|
||||
public HashSet<CrowdAgent> queryItems(float minx, float miny, float maxx, float maxy)
|
||||
public HashSet<CrowdAgent> QueryItems(float minx, float miny, float maxx, float maxy)
|
||||
{
|
||||
int iminx = (int)Math.Floor(minx * m_invCellSize);
|
||||
int iminy = (int)Math.Floor(miny * m_invCellSize);
|
||||
int imaxx = (int)Math.Floor(maxx * m_invCellSize);
|
||||
int imaxy = (int)Math.Floor(maxy * m_invCellSize);
|
||||
int iminx = (int)Math.Floor(minx * _invCellSize);
|
||||
int iminy = (int)Math.Floor(miny * _invCellSize);
|
||||
int imaxx = (int)Math.Floor(maxx * _invCellSize);
|
||||
int imaxy = (int)Math.Floor(maxy * _invCellSize);
|
||||
|
||||
HashSet<CrowdAgent> result = new HashSet<CrowdAgent>();
|
||||
for (int y = iminy; y <= imaxy; ++y)
|
||||
{
|
||||
for (int x = iminx; x <= imaxx; ++x)
|
||||
{
|
||||
ItemKey key = new ItemKey(x, y);
|
||||
if (items.TryGetValue(key, out var ids))
|
||||
long key = CombineKey(x, y);
|
||||
if (_items.TryGetValue(key, out var ids))
|
||||
{
|
||||
result.UnionWith(ids);
|
||||
}
|
||||
|
@ -88,59 +104,16 @@ namespace DotRecast.Detour.Crowd
|
|||
return result;
|
||||
}
|
||||
|
||||
public List<int[]> getItemCounts()
|
||||
public IEnumerable<(long, int)> GetItemCounts()
|
||||
{
|
||||
return items
|
||||
return _items
|
||||
.Where(e => e.Value.Count > 0)
|
||||
.Select(e => new int[] { e.Key.x, e.Key.y, e.Value.Count })
|
||||
.ToList();
|
||||
.Select(e => (e.Key, e.Value.Count));
|
||||
}
|
||||
|
||||
public float getCellSize()
|
||||
public float GetCellSize()
|
||||
{
|
||||
return m_cellSize;
|
||||
return _cellSize;
|
||||
}
|
||||
|
||||
private class ItemKey
|
||||
{
|
||||
public readonly int x;
|
||||
public readonly int y;
|
||||
|
||||
public ItemKey(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
if (GetType() != obj.GetType())
|
||||
return false;
|
||||
|
||||
ItemKey other = (ItemKey)obj;
|
||||
if (x != other.x)
|
||||
return false;
|
||||
|
||||
if (y != other.y)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -408,12 +408,10 @@ public class CrowdTool : Tool
|
|||
|
||||
dd.begin(QUADS);
|
||||
ProximityGrid grid = crowd.getGrid();
|
||||
float cs = grid.getCellSize();
|
||||
foreach (int[] ic in grid.getItemCounts())
|
||||
float cs = grid.GetCellSize();
|
||||
foreach (var (combinedKey, count) in grid.GetItemCounts())
|
||||
{
|
||||
int x = ic[0];
|
||||
int y = ic[1];
|
||||
int count = ic[2];
|
||||
ProximityGrid.DecomposeKey(combinedKey, out var x, out var y);
|
||||
if (count != 0)
|
||||
{
|
||||
int col = duRGBA(128, 0, 0, Math.Min(count * 40, 255));
|
||||
|
@ -838,4 +836,4 @@ public class CrowdTool : Tool
|
|||
{
|
||||
return "Crowd";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue