diff --git a/Bonk/NarrowPhase/NarrowPhase.cs b/Bonk/NarrowPhase/NarrowPhase.cs
index 7cb65ca..4e7fc9a 100644
--- a/Bonk/NarrowPhase/NarrowPhase.cs
+++ b/Bonk/NarrowPhase/NarrowPhase.cs
@@ -65,11 +65,23 @@ namespace MoonTools.Core.Bonk
{
return TestRectangleOverlap(rectangleA, transformA, rectangleB, transformB);
}
+ else if (shapeA is Point && shapeB is Rectangle && transformB.Rotation == 0)
+ {
+ return TestPointRectangleOverlap((Point)shapeA, transformA, (Rectangle)shapeB, transformB);
+ }
+ else if (shapeA is Rectangle && shapeB is Point && transformA.Rotation == 0)
+ {
+ return TestPointRectangleOverlap((Point)shapeB, transformB, (Rectangle)shapeA, transformA);
+ }
+ else if (shapeA is Circle circleA && shapeB is Circle circleB && transformA.Scale.X == transformA.Scale.Y && transformB.Scale.X == transformB.Scale.Y)
+ {
+ return TestCircleOverlap(circleA, transformA, circleB, transformB);
+ }
return FindCollisionSimplex(shapeA, transformA, shapeB, transformB).Item1;
}
///
- /// Fast path for overlapping rectangles. If the transforms have non-zero rotation this will be inaccurate.
+ /// Fast path for axis-aligned rectangles. If the transforms have non-zero rotation this will be inaccurate.
///
///
///
@@ -84,6 +96,44 @@ namespace MoonTools.Core.Bonk
return firstAABB.Left <= secondAABB.Right && firstAABB.Right >= secondAABB.Left && firstAABB.Top <= secondAABB.Bottom && firstAABB.Bottom >= secondAABB.Top;
}
+ ///
+ /// Fast path for overlapping point and axis-aligned rectangle. The rectangle transform must have non-zero rotation.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool TestPointRectangleOverlap(Point point, Transform2D pointTransform, Rectangle rectangle, Transform2D rectangleTransform)
+ {
+ var transformedPoint = pointTransform.Position;
+ var AABB = rectangle.TransformedAABB(rectangleTransform);
+
+ return transformedPoint.X >= AABB.Left && transformedPoint.X <= AABB.Right && transformedPoint.Y <= AABB.Bottom && transformedPoint.Y >= AABB.Top;
+ }
+
+ ///
+ /// Fast path for overlapping circles. The circles must have uniform scaling.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static bool TestCircleOverlap(Circle circleA, Transform2D transformA, Circle circleB, Transform2D transformB)
+ {
+ var radiusA = circleA.Radius * transformA.Scale.X;
+ var radiusB = circleB.Radius * transformB.Scale.Y;
+
+ var centerA = transformA.Position;
+ var centerB = transformB.Position;
+
+ var distanceSquared = (centerA - centerB).LengthSquared();
+ var radiusSumSquared = (radiusA + radiusB) * (radiusA + radiusB);
+
+ return distanceSquared <= radiusSumSquared;
+ }
+
///
/// 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.
///
diff --git a/Bonk/Shapes/Point.cs b/Bonk/Shapes/Point.cs
index eca1eee..79f8ee3 100644
--- a/Bonk/Shapes/Point.cs
+++ b/Bonk/Shapes/Point.cs
@@ -6,21 +6,9 @@ namespace MoonTools.Core.Bonk
{
public struct Point : IShape2D, IEquatable
{
- private Position2D _position;
+ private Position2D Position { get; }
public AABB AABB { get; }
- public Point(Position2D position)
- {
- _position = position;
- AABB = new AABB(position, position);
- }
-
- public Point(int x, int y)
- {
- _position = new Position2D(x, y);
- AABB = new AABB(x, y, x, y);
- }
-
public AABB TransformedAABB(Transform2D transform)
{
return AABB.Transformed(AABB, transform);
@@ -28,7 +16,7 @@ namespace MoonTools.Core.Bonk
public Vector2 Support(Vector2 direction, Transform2D transform)
{
- return Vector2.Transform(_position.ToVector2(), transform.TransformMatrix);
+ return Vector2.Transform(Position.ToVector2(), transform.TransformMatrix);
}
public override bool Equals(object obj)
@@ -43,22 +31,22 @@ namespace MoonTools.Core.Bonk
public bool Equals(Point other)
{
- return _position == other._position;
+ return Position == other.Position;
}
public override int GetHashCode()
{
- return HashCode.Combine(_position);
+ return HashCode.Combine(Position);
}
public static bool operator ==(Point a, Point b)
{
- return a.Equals(b);
+ return true;
}
public static bool operator !=(Point a, Point b)
{
- return !(a == b);
+ return false;
}
}
}
diff --git a/Test/Equality.cs b/Test/Equality.cs
index 15fe666..bf303dd 100644
--- a/Test/Equality.cs
+++ b/Test/Equality.cs
@@ -15,36 +15,27 @@ namespace Tests
[Test]
public void PointEqual()
{
- var a = new Point(1, 1);
- var b = new Point(1, 1);
+ var a = new Point();
+ var b = new Point();
a.Equals(b).Should().BeTrue();
}
- [Test]
- public void PointNotEqual()
- {
- var a = new Point(1, 1);
- var b = new Point(-1, 1);
-
- a.Equals(b).Should().BeFalse();
- }
-
[Test]
public void PointEqualOperator()
{
- var a = new Point(1, 1);
- var b = new Point(1, 1);
+ var a = new Point();
+ var b = new Point();
(a == b).Should().BeTrue();
}
[Test]
public void PointNotEqualOperator()
{
- var a = new Point(1, 1);
- var b = new Point(-1, 1);
+ var a = new Point();
+ var b = new Point();
- (a != b).Should().BeTrue();
+ (a != b).Should().BeFalse();
}
}
diff --git a/Test/GJK2DTest.cs b/Test/GJK2DTest.cs
index ef83851..540d08b 100644
--- a/Test/GJK2DTest.cs
+++ b/Test/GJK2DTest.cs
@@ -12,8 +12,8 @@ namespace Tests
[Test]
public void PointLineOverlapping()
{
- var point = new Point(-3, -3);
- var pointTransform = new Transform2D(new Position2D(4, 4));
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(1, 1));
var line = new Line(new Position2D(-2, -2), new Position2D(2, 2));
NarrowPhase.TestCollision(point, pointTransform, line, Transform2D.DefaultTransform).Should().BeTrue();
@@ -22,10 +22,11 @@ namespace Tests
[Test]
public void PointLineNotOverlapping()
{
- var point = new Point(1, 1);
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(1, 1));
var line = new Line(new Position2D(-3, -2), new Position2D(-9, -5));
- NarrowPhase.TestCollision(point, Transform2D.DefaultTransform, line, Transform2D.DefaultTransform).Should().BeFalse();
+ NarrowPhase.TestCollision(point, pointTransform, line, Transform2D.DefaultTransform).Should().BeFalse();
}
[Test]
@@ -43,7 +44,7 @@ namespace Tests
[Test]
public void PointCircleNotOverlapping()
{
- var point = new Point(0, 0);
+ var point = new Point();
var pointTransform = new Transform2D(new Position2D(3, 0));
var circle = new Circle(1);
@@ -53,7 +54,7 @@ namespace Tests
[Test]
public void PointRectangleOverlapping()
{
- var point = new Point(1, 1);
+ var point = new Point();
var rectangle = new Rectangle(-2, -2, 2, 2);
NarrowPhase.TestCollision(point, Transform2D.DefaultTransform, rectangle, Transform2D.DefaultTransform).Should().BeTrue();
@@ -62,16 +63,18 @@ namespace Tests
[Test]
public void PointRectangleNotOverlapping()
{
- var point = new Point(5, 5);
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(5, 5));
var rectangle = new Rectangle(-2, -2, 2, 2);
- NarrowPhase.TestCollision(point, Transform2D.DefaultTransform, rectangle, Transform2D.DefaultTransform).Should().BeFalse();
+ NarrowPhase.TestCollision(point, pointTransform, rectangle, Transform2D.DefaultTransform).Should().BeFalse();
}
[Test]
public void PointPolygonOverlapping()
{
- var point = new Point(1, 1);
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(1, 1));
var polygon = new Polygon(ImmutableArray.Create(
new Position2D(-2, -2),
new Position2D(-3, 2),
@@ -79,13 +82,14 @@ namespace Tests
new Position2D(3, -2)
));
- NarrowPhase.TestCollision(point, Transform2D.DefaultTransform, polygon, Transform2D.DefaultTransform).Should().BeTrue();
+ NarrowPhase.TestCollision(point, pointTransform, polygon, Transform2D.DefaultTransform).Should().BeTrue();
}
[Test]
public void PointPolygonNotOverlapping()
{
- var point = new Point(5, 5);
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(5, 5));
var polygon = new Polygon(ImmutableArray.Create(
new Position2D(-2, -2),
new Position2D(-3, 2),
@@ -93,7 +97,7 @@ namespace Tests
new Position2D(3, -2)
));
- NarrowPhase.TestCollision(point, Transform2D.DefaultTransform, polygon, Transform2D.DefaultTransform).Should().BeFalse();
+ NarrowPhase.TestCollision(point, pointTransform, polygon, Transform2D.DefaultTransform).Should().BeFalse();
}
[Test]
diff --git a/Test/SpatialHashTest.cs b/Test/SpatialHashTest.cs
index 6e9661c..2d4b153 100644
--- a/Test/SpatialHashTest.cs
+++ b/Test/SpatialHashTest.cs
@@ -1,4 +1,4 @@
-using FluentAssertions;
+using FluentAssertions;
using NUnit.Framework;
using MoonTools.Core.Structs;
using MoonTools.Core.Bonk;
@@ -34,8 +34,8 @@ namespace Tests
var line = new Line(new Position2D(20, -4), new Position2D(22, -12));
var lineTransform = new Transform2D(new Vector2(0, 0));
- var point = new Point(8, 8);
- var pointTransform = Transform2D.DefaultTransform;
+ var point = new Point();
+ var pointTransform = new Transform2D(new Position2D(8, 8));
spatialHash.Insert(0, rectA, rectATransform);
spatialHash.Insert(1, rectB, rectBTransform);
@@ -98,4 +98,4 @@ namespace Tests
spatialHash.Retrieve(0, rectA, rectATransform).Should().HaveCount(0);
}
}
-}
\ No newline at end of file
+}