do not return duplicate values from spatial hash
parent
4fda9a2ce5
commit
8aa64fc664
|
@ -19,6 +19,7 @@ namespace MoonWorks.Collision
|
||||||
public int MinY { get; private set; } = 0;
|
public int MinY { get; private set; } = 0;
|
||||||
public int MaxY { get; private set; } = 0;
|
public int MaxY { get; private set; } = 0;
|
||||||
|
|
||||||
|
private Queue<HashSet<T>> hashSetPool = new Queue<HashSet<T>>();
|
||||||
|
|
||||||
public SpatialHash2D(int cellSize)
|
public SpatialHash2D(int cellSize)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +69,8 @@ namespace MoonWorks.Collision
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(T id, IHasAABB2D shape, Transform2D transform2D)
|
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(T id, IHasAABB2D shape, Transform2D transform2D)
|
||||||
{
|
{
|
||||||
|
var returned = AcquireHashSet();
|
||||||
|
|
||||||
var box = shape.TransformedAABB(transform2D);
|
var box = shape.TransformedAABB(transform2D);
|
||||||
var (minX, minY) = Hash(box.Min);
|
var (minX, minY) = Hash(box.Min);
|
||||||
var (maxX, maxY) = Hash(box.Max);
|
var (maxX, maxY) = Hash(box.Max);
|
||||||
|
@ -85,10 +88,13 @@ namespace MoonWorks.Collision
|
||||||
if (hashDictionary.ContainsKey(key))
|
if (hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
foreach (var t in hashDictionary[key])
|
foreach (var t in hashDictionary[key])
|
||||||
|
{
|
||||||
|
if (!returned.Contains(t))
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform) = IDLookup[t];
|
var (otherShape, otherTransform) = IDLookup[t];
|
||||||
if (!id.Equals(t) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
|
if (!id.Equals(t) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
|
||||||
{
|
{
|
||||||
|
returned.Add(t);
|
||||||
yield return (t, otherShape, otherTransform);
|
yield return (t, otherShape, otherTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +103,9 @@ namespace MoonWorks.Collision
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeHashSet(returned);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves objects based on a pre-transformed AABB.
|
/// Retrieves objects based on a pre-transformed AABB.
|
||||||
|
@ -105,6 +114,8 @@ namespace MoonWorks.Collision
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(AABB2D aabb)
|
public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(AABB2D aabb)
|
||||||
{
|
{
|
||||||
|
var returned = AcquireHashSet();
|
||||||
|
|
||||||
var (minX, minY) = Hash(aabb.Min);
|
var (minX, minY) = Hash(aabb.Min);
|
||||||
var (maxX, maxY) = Hash(aabb.Max);
|
var (maxX, maxY) = Hash(aabb.Max);
|
||||||
|
|
||||||
|
@ -121,6 +132,8 @@ namespace MoonWorks.Collision
|
||||||
if (hashDictionary.ContainsKey(key))
|
if (hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
foreach (var t in hashDictionary[key])
|
foreach (var t in hashDictionary[key])
|
||||||
|
{
|
||||||
|
if (!returned.Contains(t))
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform) = IDLookup[t];
|
var (otherShape, otherTransform) = IDLookup[t];
|
||||||
if (AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
|
if (AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
|
||||||
|
@ -133,6 +146,9 @@ namespace MoonWorks.Collision
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeHashSet(returned);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes everything that has been inserted into the SpatialHash.
|
/// Removes everything that has been inserted into the SpatialHash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -150,5 +166,22 @@ namespace MoonWorks.Collision
|
||||||
{
|
{
|
||||||
return ((long) left << 32) | ((uint) right);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue