forked from MoonsideGames/MoonWorks
add Update and Remove to SpatialHash2D
parent
dccd81e029
commit
985e096a7b
|
@ -142,7 +142,7 @@ namespace MoonWorks.Collision
|
||||||
|
|
||||||
public static bool TestOverlap(AABB2D a, AABB2D b)
|
public static bool TestOverlap(AABB2D a, AABB2D b)
|
||||||
{
|
{
|
||||||
return a.Left <= b.Right && a.Right >= b.Left && a.Top <= b.Bottom && a.Bottom >= b.Top;
|
return a.Left < b.Right && a.Right > b.Left && a.Top < b.Bottom && a.Bottom > b.Top;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
|
|
|
@ -44,19 +44,15 @@ namespace MoonWorks.Collision
|
||||||
var minHash = Hash(box.Min);
|
var minHash = Hash(box.Min);
|
||||||
var maxHash = Hash(box.Max);
|
var maxHash = Hash(box.Max);
|
||||||
|
|
||||||
for (var i = minHash.Item1; i <= maxHash.Item1; i++)
|
foreach (var key in Keys(minHash.Item1, minHash.Item2, maxHash.Item1, maxHash.Item2))
|
||||||
{
|
{
|
||||||
for (var j = minHash.Item2; j <= maxHash.Item2; j++)
|
if (!hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
var key = MakeLong(i, j);
|
hashDictionary.Add(key, new HashSet<T>());
|
||||||
if (!hashDictionary.ContainsKey(key))
|
|
||||||
{
|
|
||||||
hashDictionary.Add(key, new HashSet<T>());
|
|
||||||
}
|
|
||||||
|
|
||||||
hashDictionary[key].Add(id);
|
|
||||||
IDLookup[id] = (shape, transform2D, collisionGroups);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hashDictionary[key].Add(id);
|
||||||
|
IDLookup[id] = (shape, transform2D, collisionGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
MinX = System.Math.Min(MinX, minHash.Item1);
|
MinX = System.Math.Min(MinX, minHash.Item1);
|
||||||
|
@ -81,23 +77,19 @@ namespace MoonWorks.Collision
|
||||||
if (minY < MinY) { minY = MinY; }
|
if (minY < MinY) { minY = MinY; }
|
||||||
if (maxY > MaxY) { maxY = MaxY; }
|
if (maxY > MaxY) { maxY = MaxY; }
|
||||||
|
|
||||||
for (var i = minX; i <= maxX; i++)
|
foreach (var key in Keys(minX, minY, maxX, maxY))
|
||||||
{
|
{
|
||||||
for (var j = minY; j <= maxY; j++)
|
if (hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
var key = MakeLong(i, j);
|
foreach (var t in hashDictionary[key])
|
||||||
if (hashDictionary.ContainsKey(key))
|
|
||||||
{
|
{
|
||||||
foreach (var t in hashDictionary[key])
|
if (!returned.Contains(t))
|
||||||
{
|
{
|
||||||
if (!returned.Contains(t))
|
var (otherShape, otherTransform, collisionGroups) = IDLookup[t];
|
||||||
|
if (!id.Equals(t) && ((collisionGroups & collisionMask) > 0) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform, collisionGroups) = IDLookup[t];
|
returned.Add(t);
|
||||||
if (!id.Equals(t) && ((collisionGroups & collisionMask) > 0) && AABB2D.TestOverlap(box, otherShape.TransformedAABB(otherTransform)))
|
yield return (t, otherShape, otherTransform, collisionGroups);
|
||||||
{
|
|
||||||
returned.Add(t);
|
|
||||||
yield return (t, otherShape, otherTransform, collisionGroups);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,22 +117,18 @@ namespace MoonWorks.Collision
|
||||||
if (minY < MinY) { minY = MinY; }
|
if (minY < MinY) { minY = MinY; }
|
||||||
if (maxY > MaxY) { maxY = MaxY; }
|
if (maxY > MaxY) { maxY = MaxY; }
|
||||||
|
|
||||||
for (var i = minX; i <= maxX; i++)
|
foreach (var key in Keys(minX, minY, maxX, maxY))
|
||||||
{
|
{
|
||||||
for (var j = minY; j <= maxY; j++)
|
if (hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
var key = MakeLong(i, j);
|
foreach (var t in hashDictionary[key])
|
||||||
if (hashDictionary.ContainsKey(key))
|
|
||||||
{
|
{
|
||||||
foreach (var t in hashDictionary[key])
|
if (!returned.Contains(t))
|
||||||
{
|
{
|
||||||
if (!returned.Contains(t))
|
var (otherShape, otherTransform, collisionGroups) = IDLookup[t];
|
||||||
|
if (((collisionGroups & collisionMask) > 0) && AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform, collisionGroups) = IDLookup[t];
|
yield return (t, otherShape, otherTransform, collisionGroups);
|
||||||
if (((collisionGroups & collisionMask) > 0) && AABB2D.TestOverlap(aabb, otherShape.TransformedAABB(otherTransform)))
|
|
||||||
{
|
|
||||||
yield return (t, otherShape, otherTransform, collisionGroups);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,12 +138,32 @@ namespace MoonWorks.Collision
|
||||||
FreeHashSet(returned);
|
FreeHashSet(returned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Update(T id, ICollidable shape, Transform2D transform2D, uint collisionGroups = uint.MaxValue)
|
||||||
|
{
|
||||||
|
Remove(id);
|
||||||
|
Insert(id, shape, transform2D, collisionGroups);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a specific ID from the SpatialHash.
|
/// Removes a specific ID from the SpatialHash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Remove(T id)
|
public void Remove(T id)
|
||||||
{
|
{
|
||||||
|
var (shape, transform, collisionGroups) = IDLookup[id];
|
||||||
|
|
||||||
|
var box = shape.TransformedAABB(transform);
|
||||||
|
var minHash = Hash(box.Min);
|
||||||
|
var maxHash = Hash(box.Max);
|
||||||
|
|
||||||
|
foreach (var key in Keys(minHash.Item1, minHash.Item2, maxHash.Item1, maxHash.Item2))
|
||||||
|
{
|
||||||
|
if (hashDictionary.ContainsKey(key))
|
||||||
|
{
|
||||||
|
hashDictionary[key].Remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IDLookup.Remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -176,6 +184,17 @@ namespace MoonWorks.Collision
|
||||||
return ((long) left << 32) | ((uint) right);
|
return ((long) left << 32) | ((uint) right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<long> Keys(int minX, int minY, int maxX, int maxY)
|
||||||
|
{
|
||||||
|
for (var i = minX; i <= maxX; i++)
|
||||||
|
{
|
||||||
|
for (var j = minY; j <= maxY; j++)
|
||||||
|
{
|
||||||
|
yield return MakeLong(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private HashSet<T> AcquireHashSet()
|
private HashSet<T> AcquireHashSet()
|
||||||
{
|
{
|
||||||
if (hashSetPool.Count == 0)
|
if (hashSetPool.Count == 0)
|
||||||
|
|
Loading…
Reference in New Issue