reorganization + AABB test when retrieving from spatial hash

generics
Evan Hemsley 2020-01-01 19:24:42 -08:00
parent f62c855c37
commit 097790a41f
6 changed files with 89 additions and 52 deletions

View File

@ -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; } }
public float Top { get { return Min.Y; } }
/// <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);

View File

@ -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);
}
}
}
}

View File

@ -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)
{

View File

@ -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];
}

View File

@ -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)