forked from MoonsideGames/MoonTools.Bonk
				
			
						commit
						5ddea72d72
					
				| 
						 | 
				
			
			@ -3,7 +3,7 @@ version: 2.1
 | 
			
		|||
defaults: &defaults
 | 
			
		||||
  working_directory: ~/repo
 | 
			
		||||
  docker:
 | 
			
		||||
    - image: mcr.microsoft.com/dotnet/core/sdk:2.2
 | 
			
		||||
    - image: mcr.microsoft.com/dotnet/core/sdk:3.0
 | 
			
		||||
      environment:
 | 
			
		||||
        DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
 | 
			
		||||
        DOTNET_CLI_TELEMETRY_OPTOUT: 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,3 @@
 | 
			
		|||
bin/
 | 
			
		||||
obj/
 | 
			
		||||
.vscode
 | 
			
		||||
| 
						 | 
				
			
			@ -16,5 +16,7 @@
 | 
			
		|||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="MoonTools.Core.Structs" Version="1.0.1"/>
 | 
			
		||||
    <PackageReference Include="morelinq" Version="3.2.0"/>
 | 
			
		||||
    <PackageReference Include="Collections.Pooled" Version="1.0.82"/>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
    public struct MinkowskiDifference : IEquatable<MinkowskiDifference>
 | 
			
		||||
    {
 | 
			
		||||
        private IShape2D shapeA;
 | 
			
		||||
        private Transform2D transformA;
 | 
			
		||||
        private IShape2D shapeB;
 | 
			
		||||
        private Transform2D transformB;
 | 
			
		||||
 | 
			
		||||
        public MinkowskiDifference(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
 | 
			
		||||
        {
 | 
			
		||||
            this.shapeA = shapeA;
 | 
			
		||||
            this.transformA = transformA;
 | 
			
		||||
            this.shapeB = shapeB;
 | 
			
		||||
            this.transformB = transformB;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Equals(MinkowskiDifference other)
 | 
			
		||||
        {
 | 
			
		||||
            return
 | 
			
		||||
                shapeA == other.shapeA &&
 | 
			
		||||
                transformA.Equals(other.transformA) &&
 | 
			
		||||
                shapeB == other.shapeB &&
 | 
			
		||||
                transformB.Equals(other.transformB);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 Support(Vector2 direction)
 | 
			
		||||
        {
 | 
			
		||||
            return shapeA.Support(direction, transformA) - shapeB.Support(-direction, transformB);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,10 +4,10 @@
 | 
			
		|||
 * https://blog.hamaluik.ca/posts/building-a-collision-engine-part-2-2d-penetration-vectors/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using Collections.Pooled;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -20,11 +20,11 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
    public static class EPA2D
 | 
			
		||||
    {
 | 
			
		||||
        // vector returned gives direction from A to B
 | 
			
		||||
        public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, IEnumerable<Vector2> givenSimplexVertices)
 | 
			
		||||
        public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex simplex)
 | 
			
		||||
        {
 | 
			
		||||
            var simplexVertices = new SimplexVertices(new Vector2?[36]);
 | 
			
		||||
            var simplexVertices = new PooledList<Vector2>(36, ClearMode.Always);
 | 
			
		||||
 | 
			
		||||
            foreach (var vertex in givenSimplexVertices)
 | 
			
		||||
            foreach (var vertex in simplex.Vertices)
 | 
			
		||||
            {
 | 
			
		||||
                simplexVertices.Add(vertex);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -55,10 +55,12 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            simplexVertices.Dispose();
 | 
			
		||||
 | 
			
		||||
            return intersection;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static Edge FindClosestEdge(PolygonWinding winding, SimplexVertices simplexVertices)
 | 
			
		||||
        private static Edge FindClosestEdge(PolygonWinding winding, PooledList<Vector2> simplexVertices)
 | 
			
		||||
        {
 | 
			
		||||
            var closestDistance = float.PositiveInfinity;
 | 
			
		||||
            var closestNormal = Vector2.Zero;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,126 +1,77 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Implementation of the GJK collision algorithm
 | 
			
		||||
 * Based on some math blogs
 | 
			
		||||
 * https://blog.hamaluik.ca/posts/building-a-collision-engine-part-1-2d-gjk-collision-detection/
 | 
			
		||||
 * and some code from https://github.com/kroitor/gjk.c
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
using System;
 | 
			
		||||
using MoonTools.Core.Bonk.Extensions;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
    public static class GJK2D
 | 
			
		||||
    {
 | 
			
		||||
        private enum SolutionStatus
 | 
			
		||||
        public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
 | 
			
		||||
        {
 | 
			
		||||
            NoIntersection,
 | 
			
		||||
            Intersection,
 | 
			
		||||
            StillSolving
 | 
			
		||||
            var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
 | 
			
		||||
            var a = minkowskiDifference.Support(Vector2.UnitX);
 | 
			
		||||
            var b = minkowskiDifference.Support(-a);
 | 
			
		||||
 | 
			
		||||
            return Vector2.Dot(a, b) > 0 ? false : CheckSimplex(new Simplex(minkowskiDifference, a, b));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ValueTuple<bool, SimplexVertices> TestCollision(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB)
 | 
			
		||||
        private static bool CheckSimplex(Simplex simplex)
 | 
			
		||||
        {
 | 
			
		||||
            var vertices = new SimplexVertices(new Vector2?[] { null, null, null, null });
 | 
			
		||||
            var a = simplex.DirectionA;
 | 
			
		||||
            var b = simplex.DirectionB;
 | 
			
		||||
 | 
			
		||||
            const SolutionStatus solutionStatus = SolutionStatus.StillSolving;
 | 
			
		||||
            var direction = Transform2DB.Position - Transform2DA.Position;
 | 
			
		||||
            var axb = a.Cross(b);
 | 
			
		||||
            var c = simplex.Support((b - a).Perpendicular());
 | 
			
		||||
            var axc = a.Cross(c);
 | 
			
		||||
            var bxc = b.Cross(c);
 | 
			
		||||
            var cxb = -bxc;
 | 
			
		||||
 | 
			
		||||
            var result = (solutionStatus, direction);
 | 
			
		||||
 | 
			
		||||
            while (result.solutionStatus == SolutionStatus.StillSolving)
 | 
			
		||||
            {
 | 
			
		||||
                result = EvolveSimplex(shapeA, Transform2DA, shapeB, Transform2DB, vertices, result.direction);
 | 
			
		||||
            return (b - a) == Vector2.Zero || (axb.Y > 0 != bxc.Y > 0 ? CheckSimplex(simplex.WithDirections(b, c)) : (axc.Y > 0 != cxb.Y > 0 ? CheckSimplex(simplex.WithDirections(a, c)) : true));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            return ValueTuple.Create(result.solutionStatus == SolutionStatus.Intersection, vertices);
 | 
			
		||||
        public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
 | 
			
		||||
        {
 | 
			
		||||
            var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
 | 
			
		||||
            var a = minkowskiDifference.Support(Vector2.UnitX);
 | 
			
		||||
            var b = minkowskiDifference.Support(-a);
 | 
			
		||||
 | 
			
		||||
            return Vector2.Dot(a, b) > 0 ? (false, default(Simplex)) : Simplex(new Simplex(minkowskiDifference, a, b));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static (SolutionStatus, Vector2) EvolveSimplex(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, SimplexVertices vertices, Vector2 direction)
 | 
			
		||||
        private static (bool, Simplex) Simplex(Simplex simplex)
 | 
			
		||||
        {
 | 
			
		||||
            switch(vertices.Count)
 | 
			
		||||
            var a = simplex.DirectionA;
 | 
			
		||||
            var b = simplex.DirectionB;
 | 
			
		||||
 | 
			
		||||
            if ((b - a) == Vector2.Zero)
 | 
			
		||||
            {
 | 
			
		||||
                case 0:
 | 
			
		||||
                    if (direction == Vector2.Zero)
 | 
			
		||||
                    {
 | 
			
		||||
                        direction = Vector2.UnitX;
 | 
			
		||||
                return (false, simplex.WithDirections(a, b));
 | 
			
		||||
            }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 1:
 | 
			
		||||
                    direction *= -1;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 2:
 | 
			
		||||
                    var ab = vertices[1] - vertices[0];
 | 
			
		||||
                    var a0 = vertices[0] * -1;
 | 
			
		||||
 | 
			
		||||
                    direction = TripleProduct(ab, a0, ab);
 | 
			
		||||
                    if (direction == Vector2.Zero)
 | 
			
		||||
                    {
 | 
			
		||||
                        direction = Perpendicular(ab);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 3:
 | 
			
		||||
                    var c0 = vertices[2] * -1;
 | 
			
		||||
                    var bc = vertices[1] - vertices[2];
 | 
			
		||||
                    var ca = vertices[0] - vertices[2];
 | 
			
		||||
 | 
			
		||||
                    var bcNorm = TripleProduct(ca, bc, bc);
 | 
			
		||||
                    var caNorm = TripleProduct(bc, ca, ca);
 | 
			
		||||
 | 
			
		||||
                    // the origin is outside line bc
 | 
			
		||||
                    // get rid of a and add a new support in the direction of bcNorm
 | 
			
		||||
                    if (Vector2.Dot(bcNorm, c0) > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        vertices.RemoveAt(0);
 | 
			
		||||
                        direction = bcNorm;
 | 
			
		||||
                    }
 | 
			
		||||
                    // the origin is outside line ca
 | 
			
		||||
                    // get rid of b and add a new support in the direction of caNorm
 | 
			
		||||
                    else if (Vector2.Dot(caNorm, c0) > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        vertices.RemoveAt(1);
 | 
			
		||||
                        direction = caNorm;
 | 
			
		||||
                    }
 | 
			
		||||
                    // the origin is inside both ab and ac,
 | 
			
		||||
                    // so it must be inside the triangle!
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                        return (SolutionStatus.Intersection, direction);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
                var c = simplex.Support((b - a).Perpendicular());
 | 
			
		||||
                var axb = a.Cross(b);
 | 
			
		||||
                var bxc = b.Cross(c);
 | 
			
		||||
 | 
			
		||||
            return (AddSupport(shapeA, Transform2DA, shapeB, Transform2DB, vertices, direction) ?
 | 
			
		||||
                SolutionStatus.StillSolving :
 | 
			
		||||
                SolutionStatus.NoIntersection, direction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool AddSupport(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, SimplexVertices vertices, Vector2 direction)
 | 
			
		||||
                if (axb.Y > 0 != bxc.Y > 0)
 | 
			
		||||
                {
 | 
			
		||||
            var newVertex = shapeA.Support(direction, Transform2DA) - shapeB.Support(-direction, Transform2DB);
 | 
			
		||||
            vertices.Add(newVertex);
 | 
			
		||||
            return Vector2.Dot(direction, newVertex) >= 0;
 | 
			
		||||
                    return Simplex(simplex.WithDirections(b, c));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
        private static Vector2 TripleProduct(Vector2 a, Vector2 b, Vector2 c)
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
            var A = new Vector3(a.X, a.Y, 0);
 | 
			
		||||
            var B = new Vector3(b.X, b.Y, 0);
 | 
			
		||||
            var C = new Vector3(c.X, c.Y, 0);
 | 
			
		||||
                    var axc = a.Cross(c);
 | 
			
		||||
                    var cxb = -bxc;
 | 
			
		||||
 | 
			
		||||
            var first = Vector3.Cross(A, B);
 | 
			
		||||
            var second = Vector3.Cross(first, C);
 | 
			
		||||
 | 
			
		||||
            return new Vector2(second.X, second.Y);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static Vector2 Perpendicular(Vector2 v)
 | 
			
		||||
                    if (axc.Y > 0 != cxb.Y > 0)
 | 
			
		||||
                    {
 | 
			
		||||
            return new Vector2(v.Y, -v.X);
 | 
			
		||||
                        return Simplex(simplex.WithDirections(a, b));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        return (true, simplex.WithDirections(a, b));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,91 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
    public struct SimplexVertices : IEnumerable<Vector2>
 | 
			
		||||
    {
 | 
			
		||||
        public Vector2?[] vertices;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Make sure to pass in all nulls
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public SimplexVertices(Vector2?[] vertices)
 | 
			
		||||
        {
 | 
			
		||||
            this.vertices = vertices;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 this[int key]
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (!vertices[key].HasValue) { throw new IndexOutOfRangeException(); }
 | 
			
		||||
                return vertices[key].Value;
 | 
			
		||||
            }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                vertices[key] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int Count {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < vertices.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!vertices[i].HasValue) { return i; }
 | 
			
		||||
                }
 | 
			
		||||
                return vertices.Length;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Add(Vector2 vertex)
 | 
			
		||||
        {
 | 
			
		||||
            if (Count > vertices.Length - 1) { throw new IndexOutOfRangeException(); }
 | 
			
		||||
 | 
			
		||||
            vertices[Count] = vertex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Insert(int index, Vector2 vertex)
 | 
			
		||||
        {
 | 
			
		||||
            if (Count >= vertices.Length || index > vertices.Length - 1) { throw new IndexOutOfRangeException(); }
 | 
			
		||||
 | 
			
		||||
            var currentCount = Count;
 | 
			
		||||
 | 
			
		||||
            for (int i = currentCount - 1; i >= index; i--)
 | 
			
		||||
            {
 | 
			
		||||
                vertices[i + 1] = vertices[i];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            vertices[index] = vertex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerator<Vector2> GetEnumerator()
 | 
			
		||||
        {
 | 
			
		||||
            foreach (Vector2? vec in vertices)
 | 
			
		||||
            {
 | 
			
		||||
                if (!vec.HasValue) { yield break; }
 | 
			
		||||
                yield return vec.Value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveAt(int index)
 | 
			
		||||
        {
 | 
			
		||||
            if (index > vertices.Length - 1 || index > Count) { throw new ArgumentOutOfRangeException(); }
 | 
			
		||||
 | 
			
		||||
            for (int i = vertices.Length - 2; i >= index; i--)
 | 
			
		||||
            {
 | 
			
		||||
                vertices[i] = vertices[i + 1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            vertices[vertices.Length - 1] = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
        {
 | 
			
		||||
            return GetEnumerator();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6,17 +7,28 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
{
 | 
			
		||||
    public struct Line : IShape2D, IEquatable<IShape2D>
 | 
			
		||||
    {
 | 
			
		||||
        private Position2D[] vertices;
 | 
			
		||||
        private Position2D v0;
 | 
			
		||||
        private Position2D v1;
 | 
			
		||||
 | 
			
		||||
        private IEnumerable<Position2D> vertices
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                yield return v0;
 | 
			
		||||
                yield return v0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Line(Position2D start, Position2D end)
 | 
			
		||||
        {
 | 
			
		||||
            vertices = new Position2D[2] { start, end };
 | 
			
		||||
            v0 = start;
 | 
			
		||||
            v1 = end;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 Support(Vector2 direction, Transform2D transform)
 | 
			
		||||
        {
 | 
			
		||||
            var TransformedStart = Vector2.Transform(vertices[0], transform.TransformMatrix);
 | 
			
		||||
            var TransformedEnd = Vector2.Transform(vertices[1], transform.TransformMatrix);
 | 
			
		||||
            var TransformedStart = Vector2.Transform(v0, transform.TransformMatrix);
 | 
			
		||||
            var TransformedEnd = Vector2.Transform(v1, transform.TransformMatrix);
 | 
			
		||||
            return Vector2.Dot(TransformedStart, direction) > Vector2.Dot(TransformedEnd, direction) ?
 | 
			
		||||
                TransformedStart :
 | 
			
		||||
                TransformedEnd;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +44,7 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
            if (other is Line)
 | 
			
		||||
            {
 | 
			
		||||
                var otherLine = (Line)other;
 | 
			
		||||
                return vertices[0].ToVector2() == otherLine.vertices[0].ToVector2() && vertices[1].ToVector2() == otherLine.vertices[1].ToVector2();
 | 
			
		||||
                return v0.ToVector2() == otherLine.v0.ToVector2() && v1.ToVector2() == otherLine.v1.ToVector2();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,9 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
using MoreLinq;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +14,16 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
        public int MaxX { get; }
 | 
			
		||||
        public int MaxY { get; }
 | 
			
		||||
 | 
			
		||||
        private Position2D[] vertices;
 | 
			
		||||
        private IEnumerable<Position2D> vertices
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                yield return new Position2D(MinX, MinY);
 | 
			
		||||
                yield return new Position2D(MinX, MaxY);
 | 
			
		||||
                yield return new Position2D(MaxX, MinY);
 | 
			
		||||
                yield return new Position2D(MaxX, MaxY);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Rectangle(int minX, int minY, int maxX, int maxY)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -19,33 +31,11 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
            MinY = minY;
 | 
			
		||||
            MaxX = maxX;
 | 
			
		||||
            MaxY = maxY;
 | 
			
		||||
 | 
			
		||||
            vertices = new Position2D[4]
 | 
			
		||||
            {
 | 
			
		||||
                new Position2D(minX, minY),
 | 
			
		||||
                new Position2D(minX, maxY),
 | 
			
		||||
                new Position2D(maxX, minY),
 | 
			
		||||
                new Position2D(maxX, maxY)
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 Support(Vector2 direction, Transform2D transform)
 | 
			
		||||
        {
 | 
			
		||||
            var furthestDistance = float.NegativeInfinity;
 | 
			
		||||
            var furthestVertex = Vector2.Transform(vertices[0], transform.TransformMatrix);
 | 
			
		||||
 | 
			
		||||
            foreach (var v in vertices)
 | 
			
		||||
            {
 | 
			
		||||
                var TransformedVertex = Vector2.Transform(v, transform.TransformMatrix);
 | 
			
		||||
                var distance = Vector2.Dot(TransformedVertex, direction);
 | 
			
		||||
                if (distance > furthestDistance)
 | 
			
		||||
                {
 | 
			
		||||
                    furthestDistance = distance;
 | 
			
		||||
                    furthestVertex = TransformedVertex;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return furthestVertex;
 | 
			
		||||
            return vertices.Select(vertex => Vector2.Transform(vertex, transform.TransformMatrix)).MaxBy(transformed => Vector2.Dot(transformed, direction)).First();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AABB AABB(Transform2D Transform2D)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
using MoonTools.Core.Bonk.Extensions;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
{
 | 
			
		||||
    public struct Simplex : IShape2D
 | 
			
		||||
    {
 | 
			
		||||
        MinkowskiDifference minkowskiDifference;
 | 
			
		||||
        Vector2 directionA;
 | 
			
		||||
        Vector2 directionB;
 | 
			
		||||
 | 
			
		||||
        public Vector2 DirectionA { get { return directionA; } }
 | 
			
		||||
        public Vector2 DirectionB { get { return directionB; } }
 | 
			
		||||
 | 
			
		||||
        public Simplex(MinkowskiDifference minkowskiDifference, Vector2 directionA, Vector2 directionB)
 | 
			
		||||
        {
 | 
			
		||||
            this.minkowskiDifference = minkowskiDifference;
 | 
			
		||||
            this.directionA = directionA;
 | 
			
		||||
            this.directionB = directionB;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Simplex WithDirections(Vector2 a, Vector2 b)
 | 
			
		||||
        {
 | 
			
		||||
            return new Simplex(minkowskiDifference, a, b);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<Position2D> Vertices
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                yield return (Position2D)Support(directionA);
 | 
			
		||||
                yield return (Position2D)Support(directionB);
 | 
			
		||||
                yield return (Position2D)Support(-(directionB - directionA).Perpendicular());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AABB AABB(Transform2D transform)
 | 
			
		||||
        {
 | 
			
		||||
            return Bonk.AABB.FromTransformedVertices(Vertices, transform);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Equals(IShape2D other)
 | 
			
		||||
        {
 | 
			
		||||
            if (other is Simplex polytope)
 | 
			
		||||
            {
 | 
			
		||||
                return minkowskiDifference.Equals(polytope.minkowskiDifference) &&
 | 
			
		||||
                    directionA == polytope.directionA &&
 | 
			
		||||
                    directionB == polytope.directionB;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 Support(Vector2 direction)
 | 
			
		||||
        {
 | 
			
		||||
            return minkowskiDifference.Support(direction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector2 Support(Vector2 direction, Transform2D transform)
 | 
			
		||||
        {
 | 
			
		||||
            return Vector2.Transform(Support(direction), transform.TransformMatrix);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
using Microsoft.Xna.Framework;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk.Extensions
 | 
			
		||||
{
 | 
			
		||||
    internal static class Vector2Extensions
 | 
			
		||||
    {
 | 
			
		||||
        internal static Vector2 Cross(this Vector2 a, Vector2 b)
 | 
			
		||||
        {
 | 
			
		||||
            var vec3 = Vector3.Cross(new Vector3(a.X, a.Y, 0), new Vector3(b.X, b.Y, 0));
 | 
			
		||||
            return new Vector2(vec3.X, vec3.Y);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal static Vector2 Perpendicular(this Vector2 v)
 | 
			
		||||
        {
 | 
			
		||||
            return new Vector2(v.Y, -v.X);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -18,11 +18,11 @@ namespace Tests
 | 
			
		|||
            var squareB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(1.5f, 0));
 | 
			
		||||
 | 
			
		||||
            var test = GJK2D.TestCollision(squareA, transformA, squareB, transformB);
 | 
			
		||||
            var (result, simplex) = GJK2D.FindCollisionSimplex(squareA, transformA, squareB, transformB);
 | 
			
		||||
 | 
			
		||||
            Assert.That(test.Item1, Is.True);
 | 
			
		||||
            result.Should().BeTrue();
 | 
			
		||||
 | 
			
		||||
            var intersection = EPA2D.Intersect(squareA, transformA, squareB, transformB, test.Item2);
 | 
			
		||||
            var intersection = EPA2D.Intersect(squareA, transformA, squareB, transformB, simplex);
 | 
			
		||||
 | 
			
		||||
            intersection.X.Should().Be(1f);
 | 
			
		||||
            intersection.Y.Should().Be(0);
 | 
			
		||||
| 
						 | 
				
			
			@ -36,11 +36,11 @@ namespace Tests
 | 
			
		|||
            var circleB = new Circle(1);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(1, 1));
 | 
			
		||||
 | 
			
		||||
            var test = GJK2D.TestCollision(circleA, transformA, circleB, transformB);
 | 
			
		||||
            var (result, simplex) = GJK2D.FindCollisionSimplex(circleA, transformA, circleB, transformB);
 | 
			
		||||
 | 
			
		||||
            Assert.That(test.Item1, Is.True);
 | 
			
		||||
            result.Should().BeTrue();
 | 
			
		||||
 | 
			
		||||
            var intersection = EPA2D.Intersect(circleA, transformA, circleB, transformB, test.Item2);
 | 
			
		||||
            var intersection = EPA2D.Intersect(circleA, transformA, circleB, transformB, simplex);
 | 
			
		||||
 | 
			
		||||
            var ix = circleA.Radius * (float)Math.Cos(Math.PI / 4) - (circleB.Radius * (float)Math.Cos(5 * Math.PI / 4) + transformB.Position.X);
 | 
			
		||||
            var iy = circleA.Radius * (float)Math.Sin(Math.PI / 4) - (circleB.Radius * (float)Math.Sin(5 * Math.PI / 4) + transformB.Position.Y);
 | 
			
		||||
| 
						 | 
				
			
			@ -57,11 +57,11 @@ namespace Tests
 | 
			
		|||
            var square = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            var test = GJK2D.TestCollision(line, transformA, square, transformB);
 | 
			
		||||
            var (result, simplex) = GJK2D.FindCollisionSimplex(line, transformA, square, transformB);
 | 
			
		||||
 | 
			
		||||
            Assert.That(test.Item1, Is.True);
 | 
			
		||||
            result.Should().BeTrue();
 | 
			
		||||
 | 
			
		||||
            var intersection = EPA2D.Intersect(line, transformA, square, transformB, test.Item2);
 | 
			
		||||
            var intersection = EPA2D.Intersect(line, transformA, square, transformB, simplex);
 | 
			
		||||
 | 
			
		||||
            intersection.X.Should().Be(-1);
 | 
			
		||||
            intersection.Y.Should().Be(1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
using MoonTools.Core.Bonk;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
using Microsoft.Xna.Framework;
 | 
			
		||||
using FluentAssertions;
 | 
			
		||||
 | 
			
		||||
namespace Tests
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +14,7 @@ namespace Tests
 | 
			
		|||
            var lineA = new Line(new Position2D(-1, -1), new Position2D(1, 1));
 | 
			
		||||
            var lineB = new Line(new Position2D(-1, 1), new Position2D(1, -1));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1);
 | 
			
		||||
            GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +25,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(lineA, transform, lineB, transform).Item1);
 | 
			
		||||
            GJK2D.TestCollision(lineA, transform, lineB, transform).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +34,7 @@ namespace Tests
 | 
			
		|||
            var lineA = new Line(new Position2D(0, 1), new Position2D(1, 0));
 | 
			
		||||
            var lineB = new Line(new Position2D(-1, -1), new Position2D(-2, -2));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1);
 | 
			
		||||
            GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +45,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(lineA, transform, lineB, transform).Item1);
 | 
			
		||||
            GJK2D.TestCollision(lineA, transform, lineB, transform).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +56,7 @@ namespace Tests
 | 
			
		|||
            var circleB = new Circle(2);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(1, 1));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circleA, transformA, circleB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +67,7 @@ namespace Tests
 | 
			
		|||
            var circleB = new Circle(2);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(3, 0), 0f, new Vector2(2, 2));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circleA, transformA, circleB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +78,7 @@ namespace Tests
 | 
			
		|||
            var circleB = new Circle(2);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(5, 5));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circleA, transformA, circleB, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +89,7 @@ namespace Tests
 | 
			
		|||
            var circleB = new Circle(2);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(5, 5), 0, new Vector2(0.2f, 0.2f));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circleA, transformA, circleB, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +109,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(0.5f, 0.5f));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +129,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(3f, 0f), 0f, new Vector2(3f, 3f));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +149,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(5, 0));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -162,13 +163,13 @@ namespace Tests
 | 
			
		|||
            var transformA = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            var shapeB = new Polygon(
 | 
			
		||||
                new Position2D(-1, 1), new Position2D(1, 1),
 | 
			
		||||
                new Position2D(-1, -1), new Position2D(1, -1)
 | 
			
		||||
                new Position2D(-2, 2), new Position2D(2, 2),
 | 
			
		||||
                new Position2D(-2, -2), new Position2D(2, -2)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(2f, 0), 0f, new Vector2(0.2f, 0.2f));
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(3f, 0), 0f, new Vector2(0.5f, 0.5f));
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1);  
 | 
			
		||||
            GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +186,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(line, transformA, polygon, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(line, transformA, polygon, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +203,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(line, transformA, polygon, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(line, transformA, polygon, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +214,7 @@ namespace Tests
 | 
			
		|||
            var circle = new Circle(1);
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(line, transformA, circle, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(line, transformA, circle, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +225,7 @@ namespace Tests
 | 
			
		|||
            var circle = new Circle(1);
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(line, transformA, circle, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(line, transformA, circle, transformB).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +241,7 @@ namespace Tests
 | 
			
		|||
 | 
			
		||||
            var transformB = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(circle, transformA, square, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circle, transformA, square, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +256,7 @@ namespace Tests
 | 
			
		|||
            );
 | 
			
		||||
            var squareTransform = Transform2D.DefaultTransform;
 | 
			
		||||
 | 
			
		||||
            Assert.IsFalse(GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Item1);
 | 
			
		||||
            GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Should().BeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -267,7 +268,7 @@ namespace Tests
 | 
			
		|||
            var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(1, 0));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(rectangleA, transformA, rectangleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(rectangleA, transformA, rectangleB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
| 
						 | 
				
			
			@ -279,7 +280,7 @@ namespace Tests
 | 
			
		|||
            var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
 | 
			
		||||
            var transformB = new Transform2D(new Vector2(1, 0));
 | 
			
		||||
 | 
			
		||||
            Assert.IsTrue(GJK2D.TestCollision(rectangleA, transformA, rectangleB, transformB).Item1);
 | 
			
		||||
            GJK2D.TestCollision(rectangleA, transformA, rectangleB, transformB).Should().BeTrue();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netcoreapp2.2</TargetFramework>
 | 
			
		||||
    <TargetFramework>netcoreapp3.0</TargetFramework>
 | 
			
		||||
    <IsPackable>false</IsPackable>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue