updating docs for Bonk 8
continuous-integration/drone/push Build is passing Details

main
Evan Hemsley 2020-07-18 13:13:59 -07:00
parent 3e74a91750
commit 52f78c5351
14 changed files with 216 additions and 120 deletions

View File

@ -8,22 +8,38 @@ weight: 6
## Properties ## Properties
##### **public Vector2 Min { get; private set; }** ##### **public Vector2 Min**
The minimum point of the AABB. The minimum point of the AABB.
##### **public Vector2 Max { get; private set; }** ##### **public Vector2 Max**
The maximum point of the AABB. The maximum point of the AABB.
##### **public float Width { get; }** ##### **public float Width**
The width of the AABB. The width of the AABB.
##### **public float Height { get; }** ##### **public float Height**
The height of the AABB. The height of the AABB.
##### **public float Right**
The right point of the AABB.
##### **public float Left**
The left point of the AABB.
##### **public float Top**
The top point of the AABB.
##### **public float Bottom**
The bottom point of the AABB.
## Methods ## Methods
##### **public static AABB FromVertices(IEnumerable<Position2D> vertices)** ##### **public static AABB FromVertices(IEnumerable<Position2D> vertices)**
@ -33,3 +49,7 @@ Can be used to generate an AABB from an arbitrary collection of vertices. It is
##### **public static AABB Transformed(AABB aabb, Transform2D transform)** ##### **public static AABB Transformed(AABB aabb, Transform2D transform)**
Efficiently transforms an AABB. Used internally by SpatialHash to quickly transform a shape's AABB. Efficiently transforms an AABB. Used internally by SpatialHash to quickly transform a shape's AABB.
##### **public static bool TestOverlap(AABB a, AABB b)**
Efficiently checks if two AABBs overlap.

View File

@ -1,31 +0,0 @@
---
title: "EPA2D"
date: 2019-09-15T11:23:43-07:00
weight: 30
---
*EPA2D* is a static class containing a single method for computing the penetration vector of two overlapping shapes.
## Methods
##### **public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex simplex)**
Given two sets of shapes and transforms and an initial simplex, computes a penetration vector. When motion along the penetration vector is applied, the shape-transforms are guaranteed to become separated.
**Example:**
```cs
var squareA = new Rectangle(-1, -1, 1, 1);
var transformA = Transform2D.DefaultTransform;
var squareB = new Rectangle(-1, -1, 1, 1);
var transformB = new Transform2D(new Vector2(1.5f, 0));
var (result, simplex) = GJK2D.FindCollisionSimplex(squareA, transformA, squareB, transformB);
if (result)
{
var intersection = EPA2D.Intersect(squareA, transformA, squareB, transformB, simplex);
}
```
In this example, the resulting penetration vector will be (1, 0).

View File

@ -1,41 +0,0 @@
---
title: "GJK2D"
date: 2019-09-15T11:19:13-07:00
weight: 20
---
*GJK2D* is a static class containing methods for narrow-phase collision detection.
## Methods
##### **public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)**
Tests if the two shape-transform pairs are overlapping.
**Example:**
```cs
var circleA = new Circle(2);
var transformA = new Transform2D(new Vector2(-1, -1));
var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(1, 1));
var result = GJK2D.TestCollision(circleA, transformA, circleB, transformB);
```
In this example, these transformed circles are indeed overlapping, so *result* will be true.
##### **public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)**
Tests if the two shape-transform pairs are overlapping, and if so returns a Simplex that can be used by the EPA algorithm to determine a minimum separating vector.
**Example:**
```cs
var circleA = new Circle(2);
var transformA = new Transform2D(new Vector2(-1, -1));
var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(1, 1));
var (result, simplex) = GJK2D.TestCollision(circleA, transformA, circleB, transformB);
```
In this example, these transformed circles are indeed overlapping, so *result* will be true and *simplex* will contain the Simplex that can be used by EPA to determine a minimum separating vector.

26
content/api/IHasAABB2D.md Normal file
View File

@ -0,0 +1,26 @@
---
title: "IHasAABB2D"
date: 2020-07-18T12:30:21-07:00
weight: 6
---
*IHasAABB2D* is an interface that allows for spatial hashing to be performed.
## Properties
##### **public AABB { get; }**
An axis-aligned bounding box for the shape. This is stored so we can efficiently transform the AABB when necessary.
##### **AABB TransformedAABB(Transform2D transform)**
A method which returns the axis-aligned bounding box for the transformed shape.
For example, the TransformedAABB method for Bonk's *Circle* implementation:
```cs
public AABB TransformedAABB(Transform2D Transform2D)
{
return AABB.Transformed(AABB, transform2D);
}
```

View File

@ -4,16 +4,10 @@ date: 2019-09-15T11:06:50-07:00
weight: 5 weight: 5
--- ---
An *IShape2D* is an interface that, when implemented, allows for spatial hashing and the computation of Minkowski Differences. An *IShape2D* is an interface that, when implemented, allows for computation of Minkowski Differences.
Your *IShape2D* implementations should be structs for memory efficiency purposes. Your *IShape2D* implementations should be structs for memory efficiency purposes.
## Properties
##### **public AABB { get; }**
An axis-aligned bounding box for the shape. This is stored so we can efficiently transform the AABB when necessary.
## Methods ## Methods
##### **Vector2 Support(Vector2 direction, Transform2D transform)** ##### **Vector2 Support(Vector2 direction, Transform2D transform)**
@ -30,18 +24,3 @@ public Vector2 Support(Vector2 direction, Transform2D transform)
return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix); return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix);
} }
``` ```
---
##### **AABB TransformedAABB(Transform2D transform)**
A method which returns the axis-aligned bounding box for the transformed shape.
For example, the AABB method for Bonk's *Circle* implementation:
```cs
public AABB TransformedAABB(Transform2D Transform2D)
{
return AABB.Transformed(AABB, transform2D);
}
```

View File

@ -0,0 +1,93 @@
---
title: "NarrowPhase"
date: 2019-09-15T11:19:13-07:00
weight: 20
---
*NarrowPhase* is a static class containing methods for narrow-phase collision detection.
Note that all the **TestCollision** overloads automatically employ fast path checks.
## Methods
##### **public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)**
Tests if the two shape-transform pairs are overlapping.
**Example:**
```cs
var circleA = new Circle(2);
var transformA = new Transform2D(new Vector2(-1, -1));
var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(1, 1));
var result = GJK2D.TestCollision(circleA, transformA, circleB, transformB);
```
In this example, these transformed circles are indeed overlapping, so *result* will be true.
---
##### **public static bool TestCollision(IHasAABB2D hasBoundingBoxA, Transform2D transformA, IHasAABB2D hasBoundingBoxB, Transform2D transformB)**
Detects whether two AABB-transform pairs are overlapping.
---
##### **public static bool TestCollision(MultiShape multiShape, Transform2D multiShapeTransform, IShape2D shape, Transform2D shapeTransform)**
Tests if a multishape-transform and shape-transform pair are overlapping.
---
##### **public static bool TestCollision(IShape2D shape, Transform2D shapeTransform, MultiShape multiShape, Transform2D multiShapeTransform)**
Tests if a multishape-transform and shape-transform pair are overlapping.
---
##### **public static bool TestCollision(MultiShape multiShapeA, Transform2D transformA, MultiShape multiShapeB, Transform2D transformB)**
Tests if two multishape-transform pairs are overlapping.
---
##### **public static bool TestRectangleOverlap(Rectangle rectangleA, Transform2D transformA, Rectangle rectangleB, Transform2D transformB)**
Fast path for axis-aligned rectangles. Assumes that the transforms have zero rotation. If the transforms have non-zero rotation this will be inaccurate.
---
##### **public static bool TestPointRectangleOverlap(Point point, Transform2D pointTransform, Rectangle rectangle, Transform2D rectangleTransform)**
Fast path for overlapping point and axis-aligned rectangle. The rectangle transform must have non-zero rotation.
---
##### **public static bool TestCircleOverlap(Circle circleA, Transform2D transformA, Circle circleB, Transform2D transformB)**
Fast path for overlapping circles. The circles must have uniform scaling.
---
##### **public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)**
Tests if the two shape-transform pairs are overlapping, and if so returns a Simplex that can be used by the EPA algorithm to determine a minimum separating vector.
**Example:**
```cs
var circleA = new Circle(2);
var transformA = new Transform2D(new Vector2(-1, -1));
var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(1, 1));
var (result, simplex) = GJK2D.TestCollision(circleA, transformA, circleB, transformB);
```
In this example, these transformed circles are indeed overlapping, so *result* will be true and *simplex* will contain the Simplex that can be used by EPA to determine a minimum separating vector.
---
##### **public unsafe static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex2D simplex)**
Returns a minimum separating vector in the direction from A to B. This information can be used to push two overlapping shape-transforms apart.

View File

@ -24,9 +24,9 @@ var hash = new SpatialHash<int>(16);
--- ---
##### **public void Insert(T id, IShape2D shape, Transform2D Transform2D)** ##### **public void Insert(T id, IHasAABB2D shape, Transform2D Transform2D)**
Given an ID, a shape, and corresponding transform, inserts into the spatial hash. Uses the shape's AABB to insert into appropriate hash cells. Given an ID, an object that has an AABB, and corresponding transform, inserts into the spatial hash. Uses the transformed AABB to insert into appropriate hash cells.
**Example:** **Example:**
@ -45,9 +45,9 @@ hash.Insert(1, rect, rectTransform);
--- ---
##### **public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D Transform2D)** ##### **public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(T id, IHasAABB2D shape, Transform2D Transform2D)**
Given an ID, a shape, and corresponding transform, retrieves a set of potential collisions from the spatial hash. Given an ID, an object with an AABB, and corresponding transform, retrieves a set of potential collisions from the spatial hash.
**Example:** **Example:**
@ -72,6 +72,10 @@ If a potential colliding shape-transform has the same ID as the one passed into
--- ---
##### **public IEnumerable<(T, IHasAABB2D, Transform2D)> Retrieve(AABB aabb)**
Retrieves objects from the AABB based on a pre-transformed AABB.
##### **public void Clear()** ##### **public void Clear()**
Empties the spatial hash. Useful when the spatial hash contains dynamic data that needs to be updated. Empties the spatial hash. Useful when the spatial hash contains dynamic data that needs to be updated.

11
content/api/SweepTest.md Normal file
View File

@ -0,0 +1,11 @@
---
title: "SweepTest"
date: 2020-07-18T13:07:01-07:00
weight: 30
---
*SweepTest* is a static class containing methods for performing sweep testing.
##### **public static SweepResult<T> Test<T>(SpatialHash<T> spatialHash, Rectangle rectangle, Transform2D transform, Vector2 ray) where T : IEquatable<T>**
Efficiently performs a sweep test on and against rectangles. Returns the position 1 pixel before overlap occurs. Useful for things like platforming collision.

View File

@ -4,9 +4,9 @@ date: 2019-09-14T22:54:35-07:00
weight: 20 weight: 20
--- ---
If an overlap has occurred, often we wish to determine the penetration vector, which is the shortest possible vector by which one of the shapes could be moved in order for them to stop overlapping. For this purpose, Bonk implements the Expanding Polytope Algorithm. If an overlap has occurred, sometimes we wish to determine the penetration vector, which is the shortest possible vector by which one of the shapes could be moved in order for them to stop overlapping. For this purpose, Bonk implements the Expanding Polytope Algorithm.
To use this feature, you must pass the shapes and transforms as well as the simplex that is returned from the *GJK2D.TestCollision* method. To use this feature, you must pass the shapes and transforms as well as the simplex that is returned from the **NarrowPhase.FindCollisionSimplex** method.
```cs ```cs
var squareA = new Rectangle(-1, -1, 1, 1); var squareA = new Rectangle(-1, -1, 1, 1);
@ -14,11 +14,10 @@ var transformA = Transform2D.DefaultTransform;
var squareB = new Rectangle(-1, -1, 1, 1); var squareB = new Rectangle(-1, -1, 1, 1);
var transformB = new Transform2D(new Vector2(1.5f, 0)); var transformB = new Transform2D(new Vector2(1.5f, 0));
var (result, simplex) = GJK2D.TestCollision(squareA, transformA, squareB, transformB); var (result, simplex) = NarrowPhase.FindCollisionSimplex(squareA, transformA, squareB, transformB);
if (result) if (result)
{ {
var intersection = EPA2D.Intersect(squareA, transformA, squareB, transformB, simplex); var intersection = NarrowPhase.Intersect(squareA, transformA, squareB, transformB, simplex);
} }
``` ```

View File

@ -6,7 +6,7 @@ weight: 10
Bonk uses the Gilbert-Johnson-Keerthi, or GJK, algorithm to perform narrow phase collision detection. Bonk uses the Gilbert-Johnson-Keerthi, or GJK, algorithm to perform narrow phase collision detection.
To accurately check a collision, you must pass two sets of shapes and transforms to the *GJK2D.TestCollision* method. Remember that a transform operates on the vertices of a shape: it moves, rotates, and scales them in 2D space. To accurately check a collision, you must pass two sets of shapes and transforms to the **NarrowPhase.TestCollision** method. Remember that a transform operates on the vertices of a shape: it moves, rotates, and scales them in 2D space.
```cs ```cs
var circleA = new Circle(2); var circleA = new Circle(2);
@ -14,7 +14,7 @@ var transformA = new Transform2D(new Vector2(-1, -1));
var circleB = new Circle(2); var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(1, 1)); var transformB = new Transform2D(new Vector2(1, 1));
var (result, simplex) = GJK2D.TestCollision(circleA, transformA, circleB, transformB); var result = NarrowPhase.TestCollision(circleA, transformA, circleB, transformB);
``` ```
Note that this method returns two variables. The first is whether an overlap has occurred. The second is the termination simplex. You can think of the termination simplex as a key that helps you find the penetration vector with *EPA2D*. Note that if there was no collision, the value of the simplex is irrelevant. The GJK algorithm can also return a *termination simplex*. You can think of the termination simplex as a key that helps you find the penetration vector with **NarrowPhase.Intersect**. We have a related method, **NarrowPhase.FindCollisionSimplex** which returns two variables. The first is whether an overlap has occurred. The second is the termination simplex. Note that if there was no collision, the value of the simplex is irrelevant.

View File

@ -0,0 +1,32 @@
---
title: "Sweep Test"
date: 2020-07-18T12:37:29-07:00
weight: 15
---
Sweep testing is an efficient way to check collision positions on moving objects.
At the moment, Bonk only implements sweep testing on Rectangles.
Example:
```cs
var rectangle = new Rectangle(-2, -2, 4, 4);
var transform = new Transform2D(new Position2D(-6, 0));
var otherRectangle = new Rectangle(-2, -2, 4, 4);
var otherTransform = new Transform2D(new Position2D(6, 0));
var farthestRectangle = new Rectangle(-2, -2, 4, 4);
var farthestTransform = new Transform2D(new Position2D(12, 0));
var downRectangle = new Rectangle(-6, -2, 12, 4);
var downTransform = new Transform2D(new Position2D(-6, 20));
var spatialHash = new SpatialHash<int>(16);
spatialHash.Insert(1, otherRectangle, otherTransform);
spatialHash.Insert(2, farthestRectangle, farthestTransform);
spatialHash.Insert(3, downRectangle, downTransform);
var result = SweepTest.Test(spatialHash, rectangle, transform, new Vector2(12, 0)); // hits
```

View File

@ -18,7 +18,7 @@ This polygon, for example, is a triangle.
Be careful not to define a concave Polygon, as this will cause the results of collision detection to be incorrect. Support for concave polygons is planned for a future release. Be careful not to define a concave Polygon, as this will cause the results of collision detection to be incorrect. Support for concave polygons is planned for a future release.
Polygons are considered equal if they define the same vertices, regardless of order. They can even be equivalent to Rectangles: Polygons are considered equal if they define the same vertices, regardless of order.
```cs ```cs
var a = new Polygon( var a = new Polygon(
@ -28,7 +28,12 @@ var a = new Polygon(
new Position2D(-1, 1) new Position2D(-1, 1)
); );
var b = new Rectangle(-1, -1, 1, 1); var b = new Polygon(
new Position2D(-1, 1),
new Position2D(1, 1),
new Position2D(1, -1),
new Position2D(-1, -1)
);
a == b; // true! a == b; // true!
``` ```

View File

@ -7,10 +7,9 @@ weight: 30
To define a rectangle, give a minimum X and Y and a maximum X and Y. To define a rectangle, give a minimum X and Y and a maximum X and Y.
```cs ```cs
var minX = -1; var left = -1;
var minY = -1; var top = -1;
var maxX = 1; var width = 2;
var maxY = 1; var height = 2;
var rectangle = new Rectangle(minX, minY, maxX, maxY); var rectangle = new Rectangle(left, top, width, height);
``` ```