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);
|
||||
}
|
||||
|
||||
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>
|
||||
/// 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.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
public interface IShape2D : IHasAABB2D, System.IEquatable<IShape2D>
|
||||
public interface IShape2D : ICollidable, System.IEquatable<IShape2D>
|
||||
{
|
||||
/// <summary>
|
||||
/// 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 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)
|
||||
{
|
||||
// If we can use a fast path check, let's do that!
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using MoonWorks.Math;
|
||||
|
||||
namespace MoonWorks.Collision
|
||||
|
@ -9,6 +10,13 @@ namespace MoonWorks.Collision
|
|||
{
|
||||
public int Radius { get; }
|
||||
public AABB2D AABB { get; }
|
||||
public IEnumerable<IShape2D> Shapes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Circle(int radius)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using MoonWorks.Math;
|
||||
|
||||
namespace MoonWorks.Collision
|
||||
|
@ -12,6 +13,14 @@ namespace MoonWorks.Collision
|
|||
|
||||
public AABB2D AABB { get; }
|
||||
|
||||
public IEnumerable<IShape2D> Shapes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Line(Vector2 start, Vector2 end)
|
||||
{
|
||||
Start = start;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using MoonWorks.Math;
|
||||
|
||||
namespace MoonWorks.Collision
|
||||
|
@ -9,6 +10,13 @@ namespace MoonWorks.Collision
|
|||
public struct Point : IShape2D, System.IEquatable<Point>
|
||||
{
|
||||
public AABB2D AABB { get; }
|
||||
public IEnumerable<IShape2D> Shapes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
}
|
||||
}
|
||||
|
||||
public AABB2D TransformedAABB(Transform2D transform)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using MoonWorks.Math;
|
||||
|
||||
namespace MoonWorks.Collision
|
||||
|
@ -15,12 +16,20 @@ namespace MoonWorks.Collision
|
|||
public int Left { get; }
|
||||
public int Top { get; }
|
||||
public int Bottom { get; }
|
||||
public Vector2 BottomLeft { get; }
|
||||
public Vector2 TopRight { get; }
|
||||
public Vector2 TopLeft { get; }
|
||||
public Vector2 BottomRight { get; }
|
||||
|
||||
public Vector2 Min { get; }
|
||||
public Vector2 Max { get; }
|
||||
|
||||
public IEnumerable<IShape2D> Shapes
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle(int left, int top, int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
|
@ -30,8 +39,8 @@ namespace MoonWorks.Collision
|
|||
Top = top;
|
||||
Bottom = top + height;
|
||||
AABB = new AABB2D(left, top, Right, Bottom);
|
||||
BottomLeft = new Vector2(Left, Bottom);
|
||||
TopRight = new Vector2(Top, Right);
|
||||
TopLeft = new Vector2(Left, Top);
|
||||
BottomRight = new Vector2(Right, Bottom);
|
||||
Min = AABB.Min;
|
||||
Max = AABB.Max;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace MoonWorks.Collision
|
|||
private readonly int cellSize;
|
||||
|
||||
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 MaxX { get; private set; } = 0;
|
||||
|
@ -38,7 +38,7 @@ namespace MoonWorks.Collision
|
|||
/// <param name="shape"></param>
|
||||
/// <param name="transform2D"></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 minHash = Hash(box.Min);
|
||||
|
@ -68,7 +68,7 @@ namespace MoonWorks.Collision
|
|||
/// <summary>
|
||||
/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID.
|
||||
/// </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();
|
||||
|
||||
|
@ -113,7 +113,7 @@ namespace MoonWorks.Collision
|
|||
/// </summary>
|
||||
/// <param name="aabb">A transformed AABB.</param>
|
||||
/// <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();
|
||||
|
||||
|
@ -150,6 +150,14 @@ namespace MoonWorks.Collision
|
|||
FreeHashSet(returned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a specific ID from the SpatialHash.
|
||||
/// </summary>
|
||||
public void Remove(T id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes everything that has been inserted into the SpatialHash.
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in New Issue