diff --git a/src/Collision/SpatialHash2D.cs b/src/Collision/SpatialHash2D.cs index 9a1237c..4943387 100644 --- a/src/Collision/SpatialHash2D.cs +++ b/src/Collision/SpatialHash2D.cs @@ -19,6 +19,7 @@ namespace MoonWorks.Collision public int MinY { get; private set; } = 0; public int MaxY { get; private set; } = 0; + private Queue> hashSetPool = new Queue>(); public SpatialHash2D(int cellSize) { @@ -68,6 +69,8 @@ namespace MoonWorks.Collision /// 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 /// 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); } /// @@ -150,5 +166,22 @@ namespace MoonWorks.Collision { return ((long) left << 32) | ((uint) right); } + + private HashSet AcquireHashSet() + { + if (hashSetPool.Count == 0) + { + hashSetPool.Enqueue(new HashSet()); + } + + var hashSet = hashSetPool.Dequeue(); + hashSet.Clear(); + return hashSet; + } + + private void FreeHashSet(HashSet hashSet) + { + hashSetPool.Enqueue(hashSet); + } } }