do not return duplicate values from spatial hash

pull/17/head
cosmonaut 2022-03-19 10:48:23 -07:00
parent 4fda9a2ce5
commit 8aa64fc664
1 changed files with 39 additions and 6 deletions

View File

@ -19,6 +19,7 @@ namespace MoonWorks.Collision
public int MinY { get; private set; } = 0;
public int MaxY { get; private set; } = 0;
private Queue<HashSet<T>> hashSetPool = new Queue<HashSet<T>>();
public SpatialHash2D(int cellSize)
{
@ -68,6 +69,8 @@ namespace MoonWorks.Collision
/// </summary>
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(T id, IHasAABB2D shape, Transform2D transform2D)
{
var returned = AcquireHashSet();
var box = shape.TransformedAABB(transform2D);
var (minX, minY) = Hash(box.Min);
var (maxX, maxY) = Hash(box.Max);
@ -86,15 +89,21 @@ namespace MoonWorks.Collision
{
foreach (var t in hashDictionary[key])
{
var (otherShape, otherTransform) = IDLookup[t];
if (!id.Equals(t) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
if (!returned.Contains(t))
{
yield return (t, otherShape, otherTransform);
var (otherShape, otherTransform) = IDLookup[t];
if (!id.Equals(t) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
{
returned.Add(t);
yield return (t, otherShape, otherTransform);
}
}
}
}
}
}
FreeHashSet(returned);
}
@ -105,6 +114,8 @@ namespace MoonWorks.Collision
/// <returns></returns>
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(AABB2D aabb)
{
var returned = AcquireHashSet();
var (minX, minY) = Hash(aabb.Min);
var (maxX, maxY) = Hash(aabb.Max);
@ -122,15 +133,20 @@ namespace MoonWorks.Collision
{
foreach (var t in hashDictionary[key])
{
var (otherShape, otherTransform) = IDLookup[t];
if (AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
if (!returned.Contains(t))
{
yield return (t, otherShape, otherTransform);
var (otherShape, otherTransform) = IDLookup[t];
if (AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
{
yield return (t, otherShape, otherTransform);
}
}
}
}
}
}
FreeHashSet(returned);
}
/// <summary>
@ -150,5 +166,22 @@ namespace MoonWorks.Collision
{
return ((long) left << 32) | ((uint) right);
}
private HashSet<T> AcquireHashSet()
{
if (hashSetPool.Count == 0)
{
hashSetPool.Enqueue(new HashSet<T>());
}
var hashSet = hashSetPool.Dequeue();
hashSet.Clear();
return hashSet;
}
private void FreeHashSet(HashSet<T> hashSet)
{
hashSetPool.Enqueue(hashSet);
}
}
}