forked from MoonsideGames/MoonTools.Bonk
reorganization + AABB test when retrieving from spatial hash
parent
f62c855c37
commit
097790a41f
33
Bonk/AABB.cs
33
Bonk/AABB.cs
|
@ -10,7 +10,15 @@ namespace MoonTools.Core.Bonk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct AABB : IEquatable<AABB>
|
public struct AABB : IEquatable<AABB>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The top-left position of the AABB.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
public Vector2 Min { get; private set; }
|
public Vector2 Min { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The bottom-right position of the AABB.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
public Vector2 Max { get; private set; }
|
public Vector2 Max { get; private set; }
|
||||||
|
|
||||||
public float Width { get { return Max.X - Min.X; } }
|
public float Width { get { return Max.X - Min.X; } }
|
||||||
|
@ -18,7 +26,15 @@ namespace MoonTools.Core.Bonk
|
||||||
|
|
||||||
public float Right { get { return Max.X; } }
|
public float Right { get { return Max.X; } }
|
||||||
public float Left { get { return Min.X; } }
|
public float Left { get { return Min.X; } }
|
||||||
|
/// <summary>
|
||||||
|
/// The top of the AABB. Assumes a downward-aligned Y axis, so this value will be smaller than Bottom.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
public float Top { get { return Min.Y; } }
|
public float Top { get { return Min.Y; } }
|
||||||
|
/// <summary>
|
||||||
|
/// The bottom of the AABB. Assumes a downward-aligned Y axis, so this value will be larger than Top.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
public float Bottom { get { return Max.Y; } }
|
public float Bottom { get { return Max.Y; } }
|
||||||
|
|
||||||
public AABB(float minX, float minY, float maxX, float maxY)
|
public AABB(float minX, float minY, float maxX, float maxY)
|
||||||
|
@ -44,6 +60,12 @@ namespace MoonTools.Core.Bonk
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Efficiently transforms the AABB by a Transform2D.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aabb"></param>
|
||||||
|
/// <param name="transform"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static AABB Transformed(AABB aabb, Transform2D transform)
|
public static AABB Transformed(AABB aabb, Transform2D transform)
|
||||||
{
|
{
|
||||||
var center = (aabb.Min + aabb.Max) / 2f;
|
var center = (aabb.Min + aabb.Max) / 2f;
|
||||||
|
@ -55,6 +77,12 @@ namespace MoonTools.Core.Bonk
|
||||||
return new AABB(newCenter - newExtent, newCenter + newExtent);
|
return new AABB(newCenter - newExtent, newCenter + newExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vertices"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static AABB FromVertices(IEnumerable<Position2D> vertices)
|
public static AABB FromVertices(IEnumerable<Position2D> vertices)
|
||||||
{
|
{
|
||||||
var minX = float.MaxValue;
|
var minX = float.MaxValue;
|
||||||
|
@ -85,6 +113,11 @@ namespace MoonTools.Core.Bonk
|
||||||
return new AABB(minX, minY, maxX, maxY);
|
return new AABB(minX, minY, maxX, maxY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TestOverlap(AABB a, AABB b)
|
||||||
|
{
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
return obj is AABB aabb && Equals(aabb);
|
return obj is AABB aabb && Equals(aabb);
|
||||||
|
|
|
@ -73,7 +73,10 @@ namespace MoonTools.Core.Bonk
|
||||||
foreach (var t in hashDictionary[key])
|
foreach (var t in hashDictionary[key])
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform) = IDLookup[t];
|
var (otherShape, otherTransform) = IDLookup[t];
|
||||||
if (!id.Equals(t)) { yield return (t, otherShape, otherTransform); }
|
if (!id.Equals(t) && AABB.TestOverlap(shape.TransformedAABB(transform2D), otherShape.TransformedAABB(otherTransform)))
|
||||||
|
{
|
||||||
|
yield return (t, otherShape, otherTransform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,8 @@
|
||||||
using MoonTools.Core.Structs;
|
using MoonTools.Core.Structs;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
internal unsafe struct SimplexVertexBuffer
|
|
||||||
{
|
|
||||||
private const int Size = 35;
|
|
||||||
|
|
||||||
public int Length { get; private set; }
|
|
||||||
|
|
||||||
public SimplexVertexBuffer(IEnumerable<Position2D> positions)
|
|
||||||
{
|
|
||||||
var i = 0;
|
|
||||||
foreach (var position in positions)
|
|
||||||
{
|
|
||||||
if (i == Size) { break; }
|
|
||||||
var vertex = position.ToVector2();
|
|
||||||
_simplexXBuffer[i] = vertex.X;
|
|
||||||
_simplexYBuffer[i] = vertex.Y;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
Length = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 this[int key]
|
|
||||||
{
|
|
||||||
get => new Vector2(_simplexXBuffer[key], _simplexYBuffer[key]);
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
_simplexXBuffer[key] = value.X;
|
|
||||||
_simplexYBuffer[key] = value.Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Insert(int index, Vector2 value)
|
|
||||||
{
|
|
||||||
for (var i = Length; i > index; i--)
|
|
||||||
{
|
|
||||||
this[i] = this[i - 1];
|
|
||||||
}
|
|
||||||
this[index] = value;
|
|
||||||
Length++;
|
|
||||||
}
|
|
||||||
|
|
||||||
private fixed float _simplexXBuffer[Size];
|
|
||||||
private fixed float _simplexYBuffer[Size];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class NarrowPhase
|
public static class NarrowPhase
|
||||||
{
|
{
|
||||||
private enum PolygonWinding
|
private enum PolygonWinding
|
||||||
|
@ -57,7 +12,7 @@ namespace MoonTools.Core.Bonk
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests if the two shape-transform pairs are overlapping.
|
/// Tests if two shape-transform pairs are overlapping. Automatically detects fast-path optimizations.
|
||||||
/// </summary>
|
/// </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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
|
using MoonTools.Core.Structs;
|
||||||
|
|
||||||
|
internal unsafe struct SimplexVertexBuffer
|
||||||
|
{
|
||||||
|
private const int Size = 35;
|
||||||
|
|
||||||
|
public int Length { get; private set; }
|
||||||
|
|
||||||
|
public SimplexVertexBuffer(IEnumerable<Position2D> positions)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
foreach (var position in positions)
|
||||||
|
{
|
||||||
|
if (i == Size) { break; }
|
||||||
|
var vertex = position.ToVector2();
|
||||||
|
_simplexXBuffer[i] = vertex.X;
|
||||||
|
_simplexYBuffer[i] = vertex.Y;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
Length = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 this[int key]
|
||||||
|
{
|
||||||
|
get => new Vector2(_simplexXBuffer[key], _simplexYBuffer[key]);
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_simplexXBuffer[key] = value.X;
|
||||||
|
_simplexYBuffer[key] = value.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Insert(int index, Vector2 value)
|
||||||
|
{
|
||||||
|
for (var i = Length; i > index; i--)
|
||||||
|
{
|
||||||
|
this[i] = this[i - 1];
|
||||||
|
}
|
||||||
|
this[index] = value;
|
||||||
|
Length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fixed float _simplexXBuffer[Size];
|
||||||
|
private fixed float _simplexYBuffer[Size];
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
public struct Point : IShape2D, IEquatable<Point>
|
public struct Point : IShape2D, IEquatable<Point>
|
||||||
{
|
{
|
||||||
private Position2D Position { get; }
|
|
||||||
public AABB AABB { get; }
|
public AABB AABB { get; }
|
||||||
|
|
||||||
public AABB TransformedAABB(Transform2D transform)
|
public AABB TransformedAABB(Transform2D transform)
|
||||||
|
@ -16,7 +15,7 @@ namespace MoonTools.Core.Bonk
|
||||||
|
|
||||||
public Vector2 Support(Vector2 direction, Transform2D transform)
|
public Vector2 Support(Vector2 direction, Transform2D transform)
|
||||||
{
|
{
|
||||||
return Vector2.Transform(Position.ToVector2(), transform.TransformMatrix);
|
return Vector2.Transform(Vector2.Zero, transform.TransformMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
|
@ -31,12 +30,12 @@ namespace MoonTools.Core.Bonk
|
||||||
|
|
||||||
public bool Equals(Point other)
|
public bool Equals(Point other)
|
||||||
{
|
{
|
||||||
return Position == other.Position;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return HashCode.Combine(Position);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(Point a, Point b)
|
public static bool operator ==(Point a, Point b)
|
||||||
|
|
Loading…
Reference in New Issue