forked from MoonsideGames/MoonTools.Bonk
commit
d9084257b1
|
@ -6,6 +6,9 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Axis-aligned bounding box.
|
||||||
|
/// </summary>
|
||||||
public struct AABB
|
public struct AABB
|
||||||
{
|
{
|
||||||
public float MinX { get; private set; }
|
public float MinX { get; private set; }
|
||||||
|
|
|
@ -4,6 +4,10 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to quickly check if two shapes are potentially overlapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type that will be used to uniquely identify shape-transform pairs.</typeparam>
|
||||||
public class SpatialHash<T> where T : IEquatable<T>
|
public class SpatialHash<T> where T : IEquatable<T>
|
||||||
{
|
{
|
||||||
private readonly int cellSize;
|
private readonly int cellSize;
|
||||||
|
@ -21,6 +25,12 @@ namespace MoonTools.Core.Bonk
|
||||||
return ((int)Math.Floor(x / cellSize), (int)Math.Floor(y / cellSize));
|
return ((int)Math.Floor(x / cellSize), (int)Math.Floor(y / cellSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inserts an element into the SpatialHash.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">A unique ID for the shape-transform pair.</param>
|
||||||
|
/// <param name="shape"></param>
|
||||||
|
/// <param name="transform2D"></param>
|
||||||
public void Insert(T id, IShape2D shape, Transform2D transform2D)
|
public void Insert(T id, IShape2D shape, Transform2D transform2D)
|
||||||
{
|
{
|
||||||
var box = shape.AABB(transform2D);
|
var box = shape.AABB(transform2D);
|
||||||
|
@ -47,6 +57,9 @@ namespace MoonTools.Core.Bonk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID.
|
||||||
|
/// </summary>
|
||||||
public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D transform2D)
|
public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D transform2D)
|
||||||
{
|
{
|
||||||
var box = shape.AABB(transform2D);
|
var box = shape.AABB(transform2D);
|
||||||
|
@ -69,6 +82,9 @@ namespace MoonTools.Core.Bonk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes everything that has been inserted into the SpatialHash.
|
||||||
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (var innerDict in hashDictionary.Values)
|
foreach (var innerDict in hashDictionary.Values)
|
||||||
|
|
|
@ -6,10 +6,19 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
public interface IShape2D : IEquatable<IShape2D>
|
public interface IShape2D : IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
// A Support function for a Minkowski sum.
|
/// <summary>
|
||||||
// A Support function gives the point on the edge of a shape based on a direction.
|
/// A Minkowski support function. Gives the farthest point on the edge of a shape along the given direction.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">A normalized Vector2.</param>
|
||||||
|
/// <param name="transform">A Transform for transforming the shape vertices.</param>
|
||||||
|
/// <returns>The farthest point on the edge of the shape along the given direction.</returns>
|
||||||
Vector2 Support(Vector2 direction, Transform2D transform);
|
Vector2 Support(Vector2 direction, Transform2D transform);
|
||||||
|
|
||||||
|
/// <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>
|
||||||
AABB AABB(Transform2D transform);
|
AABB AABB(Transform2D transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A Minkowski difference between two shapes.
|
||||||
|
/// </summary>
|
||||||
public struct MinkowskiDifference : IEquatable<MinkowskiDifference>
|
public struct MinkowskiDifference : IEquatable<MinkowskiDifference>
|
||||||
{
|
{
|
||||||
private IShape2D shapeA;
|
private IShape2D shapeA;
|
||||||
|
|
|
@ -19,7 +19,11 @@ namespace MoonTools.Core.Bonk
|
||||||
|
|
||||||
public static class EPA2D
|
public static class EPA2D
|
||||||
{
|
{
|
||||||
// vector returned gives direction from A to B
|
/// <summary>
|
||||||
|
/// Returns a minimum separating vector in the direction from A to B.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="simplex">A simplex returned by the GJK algorithm.</param>
|
||||||
|
/// <returns></returns>
|
||||||
public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex simplex)
|
public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex simplex)
|
||||||
{
|
{
|
||||||
var simplexVertices = new PooledList<Vector2>(36, ClearMode.Always);
|
var simplexVertices = new PooledList<Vector2>(36, ClearMode.Always);
|
||||||
|
|
|
@ -6,6 +6,9 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
public static class GJK2D
|
public static class GJK2D
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the two shape-transform pairs are overlapping.
|
||||||
|
/// </summary>
|
||||||
public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
||||||
{
|
{
|
||||||
var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
|
var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
|
||||||
|
@ -29,6 +32,9 @@ namespace MoonTools.Core.Bonk
|
||||||
return (b - a) == Vector2.Zero || (axb.Y > 0 != bxc.Y > 0 ? CheckSimplex(simplex.WithDirections(b, c)) : (axc.Y > 0 != cxb.Y > 0 ? CheckSimplex(simplex.WithDirections(a, c)) : true));
|
return (b - a) == Vector2.Zero || (axb.Y > 0 != bxc.Y > 0 ? CheckSimplex(simplex.WithDirections(b, c)) : (axc.Y > 0 != cxb.Y > 0 ? CheckSimplex(simplex.WithDirections(a, c)) : true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests if the two shape-transform pairs are overlapping, and returns a simplex that can be used by the EPA algorithm to determine a miminum separating vector.
|
||||||
|
/// </summary>
|
||||||
public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
|
||||||
{
|
{
|
||||||
var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
|
var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
|
||||||
|
|
|
@ -4,6 +4,9 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A Circle is a shape defined by a radius.
|
||||||
|
/// </summary>
|
||||||
public struct Circle : IShape2D, IEquatable<IShape2D>
|
public struct Circle : IShape2D, IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
public int Radius { get; private set; }
|
public int Radius { get; private set; }
|
||||||
|
|
|
@ -5,6 +5,9 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A line is a shape defined by exactly two points in space.
|
||||||
|
/// </summary>
|
||||||
public struct Line : IShape2D, IEquatable<IShape2D>
|
public struct Line : IShape2D, IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
private Position2D v0;
|
private Position2D v0;
|
||||||
|
|
|
@ -4,6 +4,9 @@ using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A Shape defined by an arbitrary collection of vertices. WARNING: Polygon must use an Array internally and therefore will create GC pressure.
|
||||||
|
/// </summary>
|
||||||
public struct Polygon : IShape2D, IEquatable<IShape2D>
|
public struct Polygon : IShape2D, IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
public Position2D[] Vertices { get; private set; }
|
public Position2D[] Vertices { get; private set; }
|
||||||
|
@ -48,7 +51,7 @@ namespace MoonTools.Core.Bonk
|
||||||
|
|
||||||
for (int i = 0; i < Vertices.Length; i++)
|
for (int i = 0; i < Vertices.Length; i++)
|
||||||
{
|
{
|
||||||
if (Vertices[i].ToVector2() != otherPolygon.Vertices[i].ToVector2()) { return false;}
|
if (Vertices[i].ToVector2() != otherPolygon.Vertices[i].ToVector2()) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -7,6 +7,9 @@ using MoreLinq;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A rectangle is a shape defined by a minimum and maximum X value and a minimum and maximum Y value.
|
||||||
|
/// </summary>
|
||||||
public struct Rectangle : IShape2D, IEquatable<IShape2D>
|
public struct Rectangle : IShape2D, IEquatable<IShape2D>
|
||||||
{
|
{
|
||||||
public int MinX { get; }
|
public int MinX { get; }
|
||||||
|
|
|
@ -5,6 +5,9 @@ using MoonTools.Core.Bonk.Extensions;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A simplex is a shape used to calculate overlap. It is defined by a Minkowski difference and two direction vectors.
|
||||||
|
/// </summary>
|
||||||
public struct Simplex : IShape2D
|
public struct Simplex : IShape2D
|
||||||
{
|
{
|
||||||
MinkowskiDifference minkowskiDifference;
|
MinkowskiDifference minkowskiDifference;
|
||||||
|
|
Loading…
Reference in New Issue