forked from MoonsideGames/MoonWorks
change collision API to support multi shapes
parent
65568ea234
commit
dccd81e029
|
@ -77,6 +77,33 @@ namespace MoonWorks.Collision
|
||||||
return new AABB2D(newCenter - newExtent, newCenter + newExtent);
|
return new AABB2D(newCenter - newExtent, newCenter + newExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AABB2D Compose(AABB2D aabb)
|
||||||
|
{
|
||||||
|
float left = Left;
|
||||||
|
float top = Top;
|
||||||
|
float right = Right;
|
||||||
|
float bottom = Bottom;
|
||||||
|
|
||||||
|
if (aabb.Left < left)
|
||||||
|
{
|
||||||
|
left = aabb.Left;
|
||||||
|
}
|
||||||
|
if (aabb.Right > right)
|
||||||
|
{
|
||||||
|
right = aabb.Right;
|
||||||
|
}
|
||||||
|
if (aabb.Top < top)
|
||||||
|
{
|
||||||
|
top = aabb.Top;
|
||||||
|
}
|
||||||
|
if (aabb.Bottom > bottom)
|
||||||
|
{
|
||||||
|
bottom = aabb.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AABB2D(left, top, right, bottom);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an AABB for an arbitrary collection of positions.
|
/// Creates an AABB for an arbitrary collection of positions.
|
||||||
/// This is less efficient than defining a custom AABB method for most shapes, so avoid using this if possible.
|
/// This is less efficient than defining a custom AABB method for most shapes, so avoid using this if possible.
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MoonWorks.Math;
|
||||||
|
|
||||||
|
namespace MoonWorks.Collision
|
||||||
|
{
|
||||||
|
public interface ICollidable
|
||||||
|
{
|
||||||
|
IEnumerable<IShape2D> Shapes { get; }
|
||||||
|
AABB2D AABB { get; }
|
||||||
|
AABB2D TransformedAABB(Transform2D transform);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
using MoonWorks.Math;
|
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
|
||||||
{
|
|
||||||
public interface IHasAABB2D
|
|
||||||
{
|
|
||||||
AABB2D AABB { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a bounding box based on the shape.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="transform">A Transform for transforming the shape vertices.</param>
|
|
||||||
/// <returns>Returns a bounding box based on the shape.</returns>
|
|
||||||
AABB2D TransformedAABB(Transform2D transform);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
namespace MoonWorks.Collision
|
||||||
{
|
{
|
||||||
public interface IShape2D : IHasAABB2D, System.IEquatable<IShape2D>
|
public interface IShape2D : ICollidable, System.IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Minkowski support function. Gives the farthest point on the edge of a shape along the given direction.
|
/// A Minkowski support function. Gives the farthest point on the edge of a shape along the given direction.
|
||||||
|
|
|
@ -11,6 +11,22 @@ namespace MoonWorks.Collision
|
||||||
public int Index;
|
public int Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TestCollision(ICollidable collidableA, Transform2D transformA, ICollidable collidableB, Transform2D transformB)
|
||||||
|
{
|
||||||
|
foreach (var shapeA in collidableA.Shapes)
|
||||||
|
{
|
||||||
|
foreach (var shapeB in collidableB.Shapes)
|
||||||
|
{
|
||||||
|
if (TestCollision(shapeA, transformA, shapeB, transformB))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
||||||
{
|
{
|
||||||
// If we can use a fast path check, let's do that!
|
// If we can use a fast path check, let's do that!
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
namespace MoonWorks.Collision
|
||||||
|
@ -9,6 +10,13 @@ namespace MoonWorks.Collision
|
||||||
{
|
{
|
||||||
public int Radius { get; }
|
public int Radius { get; }
|
||||||
public AABB2D AABB { get; }
|
public AABB2D AABB { get; }
|
||||||
|
public IEnumerable<IShape2D> Shapes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
yield return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Circle(int radius)
|
public Circle(int radius)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
namespace MoonWorks.Collision
|
||||||
|
@ -12,7 +13,15 @@ namespace MoonWorks.Collision
|
||||||
|
|
||||||
public AABB2D AABB { get; }
|
public AABB2D AABB { get; }
|
||||||
|
|
||||||
public Line(Vector2 start, Vector2 end)
|
public IEnumerable<IShape2D> Shapes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
yield return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line(Vector2 start, Vector2 end)
|
||||||
{
|
{
|
||||||
Start = start;
|
Start = start;
|
||||||
End = end;
|
End = end;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
namespace MoonWorks.Collision
|
||||||
|
@ -9,6 +10,13 @@ namespace MoonWorks.Collision
|
||||||
public struct Point : IShape2D, System.IEquatable<Point>
|
public struct Point : IShape2D, System.IEquatable<Point>
|
||||||
{
|
{
|
||||||
public AABB2D AABB { get; }
|
public AABB2D AABB { get; }
|
||||||
|
public IEnumerable<IShape2D> Shapes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
yield return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AABB2D TransformedAABB(Transform2D transform)
|
public AABB2D TransformedAABB(Transform2D transform)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using MoonWorks.Math;
|
using MoonWorks.Math;
|
||||||
|
|
||||||
namespace MoonWorks.Collision
|
namespace MoonWorks.Collision
|
||||||
|
@ -15,12 +16,20 @@ namespace MoonWorks.Collision
|
||||||
public int Left { get; }
|
public int Left { get; }
|
||||||
public int Top { get; }
|
public int Top { get; }
|
||||||
public int Bottom { get; }
|
public int Bottom { get; }
|
||||||
public Vector2 BottomLeft { get; }
|
public Vector2 TopLeft { get; }
|
||||||
public Vector2 TopRight { get; }
|
public Vector2 BottomRight { get; }
|
||||||
|
|
||||||
public Vector2 Min { get; }
|
public Vector2 Min { get; }
|
||||||
public Vector2 Max { get; }
|
public Vector2 Max { get; }
|
||||||
|
|
||||||
|
public IEnumerable<IShape2D> Shapes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
yield return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Rectangle(int left, int top, int width, int height)
|
public Rectangle(int left, int top, int width, int height)
|
||||||
{
|
{
|
||||||
Width = width;
|
Width = width;
|
||||||
|
@ -30,8 +39,8 @@ namespace MoonWorks.Collision
|
||||||
Top = top;
|
Top = top;
|
||||||
Bottom = top + height;
|
Bottom = top + height;
|
||||||
AABB = new AABB2D(left, top, Right, Bottom);
|
AABB = new AABB2D(left, top, Right, Bottom);
|
||||||
BottomLeft = new Vector2(Left, Bottom);
|
TopLeft = new Vector2(Left, Top);
|
||||||
TopRight = new Vector2(Top, Right);
|
BottomRight = new Vector2(Right, Bottom);
|
||||||
Min = AABB.Min;
|
Min = AABB.Min;
|
||||||
Max = AABB.Max;
|
Max = AABB.Max;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace MoonWorks.Collision
|
||||||
private readonly int cellSize;
|
private readonly int cellSize;
|
||||||
|
|
||||||
private readonly Dictionary<long, HashSet<T>> hashDictionary = new Dictionary<long, HashSet<T>>();
|
private readonly Dictionary<long, HashSet<T>> hashDictionary = new Dictionary<long, HashSet<T>>();
|
||||||
private readonly Dictionary<T, (IHasAABB2D, Transform2D, uint)> IDLookup = new Dictionary<T, (IHasAABB2D, Transform2D, uint)>();
|
private readonly Dictionary<T, (ICollidable, Transform2D, uint)> IDLookup = new Dictionary<T, (ICollidable, Transform2D, uint)>();
|
||||||
|
|
||||||
public int MinX { get; private set; } = 0;
|
public int MinX { get; private set; } = 0;
|
||||||
public int MaxX { get; private set; } = 0;
|
public int MaxX { get; private set; } = 0;
|
||||||
|
@ -38,7 +38,7 @@ namespace MoonWorks.Collision
|
||||||
/// <param name="shape"></param>
|
/// <param name="shape"></param>
|
||||||
/// <param name="transform2D"></param>
|
/// <param name="transform2D"></param>
|
||||||
/// <param name="collisionGroups">A bitmask value specifying the groups this object belongs to.</param>
|
/// <param name="collisionGroups">A bitmask value specifying the groups this object belongs to.</param>
|
||||||
public void Insert(T id, IHasAABB2D shape, Transform2D transform2D, uint collisionGroups = uint.MaxValue)
|
public void Insert(T id, ICollidable shape, Transform2D transform2D, uint collisionGroups = uint.MaxValue)
|
||||||
{
|
{
|
||||||
var box = shape.TransformedAABB(transform2D);
|
var box = shape.TransformedAABB(transform2D);
|
||||||
var minHash = Hash(box.Min);
|
var minHash = Hash(box.Min);
|
||||||
|
@ -68,7 +68,7 @@ namespace MoonWorks.Collision
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID.
|
/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<(T, IHasAABB2D, Transform2D, uint)> Retrieve(T id, IHasAABB2D shape, Transform2D transform2D, uint collisionMask = uint.MaxValue)
|
public IEnumerable<(T, ICollidable, Transform2D, uint)> Retrieve(T id, ICollidable shape, Transform2D transform2D, uint collisionMask = uint.MaxValue)
|
||||||
{
|
{
|
||||||
var returned = AcquireHashSet();
|
var returned = AcquireHashSet();
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ namespace MoonWorks.Collision
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="aabb">A transformed AABB.</param>
|
/// <param name="aabb">A transformed AABB.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<(T, IHasAABB2D, Transform2D, uint)> Retrieve(AABB2D aabb, uint collisionMask = uint.MaxValue)
|
public IEnumerable<(T, ICollidable, Transform2D, uint)> Retrieve(AABB2D aabb, uint collisionMask = uint.MaxValue)
|
||||||
{
|
{
|
||||||
var returned = AcquireHashSet();
|
var returned = AcquireHashSet();
|
||||||
|
|
||||||
|
@ -150,6 +150,14 @@ namespace MoonWorks.Collision
|
||||||
FreeHashSet(returned);
|
FreeHashSet(returned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a specific ID from the SpatialHash.
|
||||||
|
/// </summary>
|
||||||
|
public void Remove(T id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes everything that has been inserted into the SpatialHash.
|
/// Removes everything that has been inserted into the SpatialHash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue