From fbba3c2052195d5daf6d19d5c1f061a2f5899913 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sun, 15 Sep 2019 11:42:12 -0700 Subject: [PATCH] API --- content/api/EPA2D.md | 31 ++++++++++++++++ content/api/GJK2D.md | 25 +++++++++++++ content/api/IShape2D.md | 46 +++++++++++++++++++++++ content/api/SpatialHash.md | 75 ++++++++++++++++++++++++++++++++++++++ content/api/_index.md | 13 +++++++ 5 files changed, 190 insertions(+) create mode 100644 content/api/EPA2D.md create mode 100644 content/api/GJK2D.md create mode 100644 content/api/IShape2D.md create mode 100644 content/api/SpatialHash.md create mode 100644 content/api/_index.md diff --git a/content/api/EPA2D.md b/content/api/EPA2D.md new file mode 100644 index 0000000..171291c --- /dev/null +++ b/content/api/EPA2D.md @@ -0,0 +1,31 @@ +--- +title: "EPA2D" +date: 2019-09-15T11:23:43-07:00 +weight: 30 +--- + +*EPA2D* is a static class containing a single public method which is used for computing the penetration vector of two overlapping shapes. + +## Methods + +##### **public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, IEnumerable givenSimplexVertices)** + +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.TestCollision(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). \ No newline at end of file diff --git a/content/api/GJK2D.md b/content/api/GJK2D.md new file mode 100644 index 0000000..b054e66 --- /dev/null +++ b/content/api/GJK2D.md @@ -0,0 +1,25 @@ +--- +title: "GJK2D" +date: 2019-09-15T11:19:13-07:00 +weight: 20 +--- + +*GJK2D* is a static class containing a single public method which is used for narrow-phase collision detection. + +## Methods + +##### **public static (bool, SimplexVertices) TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)** + +Returns a tuple containing two values: the collision result and the simplex. If there is an overlap, the simplex will contain the termination simplex that can be used as a starting point for the Expanding Polytope Algorithm to compute a penetration vector. Otherwise, the simplex can be ignored. + +**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 termination simplex. \ No newline at end of file diff --git a/content/api/IShape2D.md b/content/api/IShape2D.md new file mode 100644 index 0000000..513a8fe --- /dev/null +++ b/content/api/IShape2D.md @@ -0,0 +1,46 @@ +--- +title: "IShape2D" +date: 2019-09-15T11:06:50-07:00 +weight: 5 +--- + +An *IShape2D* is an interface that, when implemented, allows for spatial hashing and the computation of Minkowski Differences. + +Your *IShape2D* types should be structs for memory efficiency purposes. + +## Methods + +##### **Vector2 Support(Vector2 direction, Transform2D transform)** + +A method which implements a support function for use with a Minkowski Difference. + +The support function must, given a directional vector and a Transform2D, return the farthest possible vertex of the transformed shape in the given direction. + +For example, the support function for Bonk's *Circle* implementation: + +```cs +public Vector2 Support(Vector2 direction, Transform2D transform) +{ + return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix); +} +``` + +--- + +##### **AABB AABB(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 AABB(Transform2D Transform2D) +{ + return new AABB( + Transform2D.Position.X - Radius, + Transform2D.Position.Y - Radius, + Transform2D.Position.X + Radius, + Transform2D.Position.Y + Radius + ); +} +``` \ No newline at end of file diff --git a/content/api/SpatialHash.md b/content/api/SpatialHash.md new file mode 100644 index 0000000..4cd0bef --- /dev/null +++ b/content/api/SpatialHash.md @@ -0,0 +1,75 @@ +--- +title: "SpatialHash" +date: 2019-09-15T11:28:40-07:00 +weight: 10 +--- + +*SpatialHash* is used for broad-phase collision detection. It can quickly return a set of potential collisions of a transformed shape. *SpatialHash* takes an ID type that is used to avoid comparing certain shape-transforms. + +## Methods + +##### **public SpatialHash(int cellSize)** + +Constructor method. Takes an integer representing the width of a cell in the spatial hash. + +The cell width must not be too large or too small. If the cell width is too small, then shape-transforms will occupy many cells, and the hash check will have to check all of those cells for potential collisions. If the cell width is too large, then many shape-transforms will be contained in each cell and many expensive collision tests will have to be made. + +A good rule of thumb is picking a cell width that is roughly twice the size of the most common objects in your game. + +**Example:** + +```cs +var hash = new SpatialHash(16); +``` + +--- + +##### **public void Insert(T id, IShape2D 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. + +**Example:** + +```cs +var hash = new SpatialHash(16); + +var circle = new MoonTools.Core.Bonk.Circle(8); +var circleTransform = new Transform2D(new Vector2(16, 16)); + +var rect = new Rectangle(-2, -2, 2, 2); +var rectTransform = new Transform2D(new Vector2(8, 8)); + +hash.Insert(0, circle, circleTransform); +hash.Insert(1, rect, rectTransform); +``` + +--- + +##### **public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D Transform2D)** + +Given an ID, a shape, and corresponding transform, retrieves a set of potential collisions from the spatial hash. + +**Example:** + +```cs +var hash = new SpatialHash(16); + +var circle = new MoonTools.Core.Bonk.Circle(8); +var circleTransform = new Transform2D(new Vector2(16, 16)); + +var rect = new Rectangle(-2, -2, 2, 2); +var rectTransform = new Transform2D(new Vector2(8, 8)); + +hash.Insert(0, circle, circleTransform); +hash.Insert(1, rect, rectTransform); + +hash.Retrieve(1, rect, rectTransform); +``` + +In this example, the circle we inserted will be in the *IEnumerable* returned by the *Retrieve* call because they both exist in the same hash cell. + +--- + +##### **public void Clear()** + +Empties the spatial hash. Useful when the spatial hash contains dynamic data that needs to be updated. \ No newline at end of file diff --git a/content/api/_index.md b/content/api/_index.md new file mode 100644 index 0000000..6f054e9 --- /dev/null +++ b/content/api/_index.md @@ -0,0 +1,13 @@ ++++ +title = "API" +date = 2019-09-14T23:45:20-07:00 +weight = 50 +chapter = true +pre = "6. " ++++ + +### Chapter 6 + +# API + +Technicalities. \ No newline at end of file