add Update and Remove to SpatialHash2D

main
cosmonaut 2022-04-20 10:57:16 -07:00
parent dccd81e029
commit 985e096a7b
2 changed files with 53 additions and 34 deletions

View File

@ -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)

View File

@ -44,11 +44,8 @@ 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++)
{
var key = MakeLong(i, j);
if (!hashDictionary.ContainsKey(key)) if (!hashDictionary.ContainsKey(key))
{ {
hashDictionary.Add(key, new HashSet<T>()); hashDictionary.Add(key, new HashSet<T>());
@ -57,7 +54,6 @@ namespace MoonWorks.Collision
hashDictionary[key].Add(id); hashDictionary[key].Add(id);
IDLookup[id] = (shape, transform2D, collisionGroups); IDLookup[id] = (shape, transform2D, collisionGroups);
} }
}
MinX = System.Math.Min(MinX, minHash.Item1); MinX = System.Math.Min(MinX, minHash.Item1);
MinY = System.Math.Min(MinY, minHash.Item2); MinY = System.Math.Min(MinY, minHash.Item2);
@ -81,11 +77,8 @@ 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++)
{
var key = MakeLong(i, j);
if (hashDictionary.ContainsKey(key)) if (hashDictionary.ContainsKey(key))
{ {
foreach (var t in hashDictionary[key]) foreach (var t in hashDictionary[key])
@ -102,7 +95,6 @@ namespace MoonWorks.Collision
} }
} }
} }
}
FreeHashSet(returned); FreeHashSet(returned);
} }
@ -125,11 +117,8 @@ 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++)
{
var key = MakeLong(i, j);
if (hashDictionary.ContainsKey(key)) if (hashDictionary.ContainsKey(key))
{ {
foreach (var t in hashDictionary[key]) foreach (var t in hashDictionary[key])
@ -145,17 +134,36 @@ 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)