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>
|
||||
public struct AABB : IEquatable<AABB>
|
||||
{
|
||||
/// <summary>
|
||||
/// The top-left position of the AABB.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Vector2 Min { get; private set; }
|
||||
/// <summary>
|
||||
/// The bottom-right position of the AABB.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Vector2 Max { get; private set; }
|
||||
|
||||
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 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; } }
|
||||
/// <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 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)
|
||||
{
|
||||
var center = (aabb.Min + aabb.Max) / 2f;
|
||||
|
@ -55,6 +77,12 @@ namespace MoonTools.Core.Bonk
|
|||
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)
|
||||
{
|
||||
var minX = float.MaxValue;
|
||||
|
@ -85,6 +113,11 @@ namespace MoonTools.Core.Bonk
|
|||
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)
|
||||
{
|
||||
return obj is AABB aabb && Equals(aabb);
|
||||
|
|
|
@ -73,7 +73,10 @@ namespace MoonTools.Core.Bonk
|
|||
foreach (var t in hashDictionary[key])
|
||||
{
|
||||
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 System.Numerics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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
|
||||
{
|
||||
private enum PolygonWinding
|
||||
|
@ -57,7 +12,7 @@ namespace MoonTools.Core.Bonk
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if the two shape-transform pairs are overlapping.
|
||||
/// Tests if two shape-transform pairs are overlapping. Automatically detects fast-path optimizations.
|
||||
/// </summary>
|
||||
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>
|
||||
{
|
||||
private Position2D Position { get; }
|
||||
public AABB AABB { get; }
|
||||
|
||||
public AABB TransformedAABB(Transform2D transform)
|
||||
|
@ -16,7 +15,7 @@ namespace MoonTools.Core.Bonk
|
|||
|
||||
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)
|
||||
|
@ -31,12 +30,12 @@ namespace MoonTools.Core.Bonk
|
|||
|
||||
public bool Equals(Point other)
|
||||
{
|
||||
return Position == other.Position;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool operator ==(Point a, Point b)
|
||||
|
|
Loading…
Reference in New Issue