Merge pull request #1 from MoonsideGames/optimization

Optimization
pull/2/head
thatcosmonaut 2019-10-25 13:41:42 -07:00 committed by GitHub
commit 5ddea72d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 249 additions and 261 deletions

View File

@ -3,7 +3,7 @@ version: 2.1
defaults: &defaults defaults: &defaults
working_directory: ~/repo working_directory: ~/repo
docker: docker:
- image: mcr.microsoft.com/dotnet/core/sdk:2.2 - image: mcr.microsoft.com/dotnet/core/sdk:3.0
environment: environment:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
bin/ bin/
obj/ obj/
.vscode

View File

@ -16,5 +16,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MoonTools.Core.Structs" Version="1.0.1"/> <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> </ItemGroup>
</Project> </Project>

View File

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

View File

@ -4,10 +4,10 @@
* https://blog.hamaluik.ca/posts/building-a-collision-engine-part-2-2d-penetration-vectors/ * https://blog.hamaluik.ca/posts/building-a-collision-engine-part-2-2d-penetration-vectors/
*/ */
using Collections.Pooled;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using MoonTools.Core.Structs; using MoonTools.Core.Structs;
using System; using System;
using System.Collections.Generic;
namespace MoonTools.Core.Bonk namespace MoonTools.Core.Bonk
{ {
@ -20,11 +20,11 @@ namespace MoonTools.Core.Bonk
public static class EPA2D public static class EPA2D
{ {
// vector returned gives direction from A to B // 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); simplexVertices.Add(vertex);
} }
@ -55,10 +55,12 @@ namespace MoonTools.Core.Bonk
} }
} }
simplexVertices.Dispose();
return intersection; return intersection;
} }
private static Edge FindClosestEdge(PolygonWinding winding, SimplexVertices simplexVertices) private static Edge FindClosestEdge(PolygonWinding winding, PooledList<Vector2> simplexVertices)
{ {
var closestDistance = float.PositiveInfinity; var closestDistance = float.PositiveInfinity;
var closestNormal = Vector2.Zero; var closestNormal = Vector2.Zero;

View File

@ -1,126 +1,77 @@
/* using Microsoft.Xna.Framework;
* 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 MoonTools.Core.Structs; using MoonTools.Core.Structs;
using System; using MoonTools.Core.Bonk.Extensions;
namespace MoonTools.Core.Bonk namespace MoonTools.Core.Bonk
{ {
public static class GJK2D public static class GJK2D
{ {
private enum SolutionStatus public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB)
{ {
NoIntersection, var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB);
Intersection, var a = minkowskiDifference.Support(Vector2.UnitX);
StillSolving 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 axb = a.Cross(b);
var direction = Transform2DB.Position - Transform2DA.Position; var c = simplex.Support((b - a).Perpendicular());
var axc = a.Cross(c);
var bxc = b.Cross(c);
var cxb = -bxc;
var result = (solutionStatus, 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));
while (result.solutionStatus == SolutionStatus.StillSolving)
{
result = EvolveSimplex(shapeA, Transform2DA, shapeB, Transform2DB, vertices, result.direction);
} }
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: return (false, simplex.WithDirections(a, b));
if (direction == Vector2.Zero)
{
direction = Vector2.UnitX;
} }
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 else
{ {
return (SolutionStatus.Intersection, direction); var c = simplex.Support((b - a).Perpendicular());
} var axb = a.Cross(b);
break; var bxc = b.Cross(c);
}
return (AddSupport(shapeA, Transform2DA, shapeB, Transform2DB, vertices, direction) ? if (axb.Y > 0 != bxc.Y > 0)
SolutionStatus.StillSolving :
SolutionStatus.NoIntersection, direction);
}
private static bool AddSupport(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, SimplexVertices vertices, Vector2 direction)
{ {
var newVertex = shapeA.Support(direction, Transform2DA) - shapeB.Support(-direction, Transform2DB); return Simplex(simplex.WithDirections(b, c));
vertices.Add(newVertex);
return Vector2.Dot(direction, newVertex) >= 0;
} }
else
private static Vector2 TripleProduct(Vector2 a, Vector2 b, Vector2 c)
{ {
var A = new Vector3(a.X, a.Y, 0); var axc = a.Cross(c);
var B = new Vector3(b.X, b.Y, 0); var cxb = -bxc;
var C = new Vector3(c.X, c.Y, 0);
var first = Vector3.Cross(A, B); if (axc.Y > 0 != cxb.Y > 0)
var second = Vector3.Cross(first, C);
return new Vector2(second.X, second.Y);
}
private static Vector2 Perpendicular(Vector2 v)
{ {
return new Vector2(v.Y, -v.X); return Simplex(simplex.WithDirections(a, b));
}
else
{
return (true, simplex.WithDirections(a, b));
}
}
}
} }
} }
} }

View File

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

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using MoonTools.Core.Structs; using MoonTools.Core.Structs;
@ -6,17 +7,28 @@ namespace MoonTools.Core.Bonk
{ {
public struct Line : IShape2D, IEquatable<IShape2D> 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) public Line(Position2D start, Position2D end)
{ {
vertices = new Position2D[2] { start, end }; v0 = start;
v1 = end;
} }
public Vector2 Support(Vector2 direction, Transform2D transform) public Vector2 Support(Vector2 direction, Transform2D transform)
{ {
var TransformedStart = Vector2.Transform(vertices[0], transform.TransformMatrix); var TransformedStart = Vector2.Transform(v0, transform.TransformMatrix);
var TransformedEnd = Vector2.Transform(vertices[1], transform.TransformMatrix); var TransformedEnd = Vector2.Transform(v1, transform.TransformMatrix);
return Vector2.Dot(TransformedStart, direction) > Vector2.Dot(TransformedEnd, direction) ? return Vector2.Dot(TransformedStart, direction) > Vector2.Dot(TransformedEnd, direction) ?
TransformedStart : TransformedStart :
TransformedEnd; TransformedEnd;
@ -32,7 +44,7 @@ namespace MoonTools.Core.Bonk
if (other is Line) if (other is Line)
{ {
var otherLine = (Line)other; 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; return false;

View File

@ -1,6 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using MoonTools.Core.Structs; using MoonTools.Core.Structs;
using MoreLinq;
namespace MoonTools.Core.Bonk namespace MoonTools.Core.Bonk
{ {
@ -11,7 +14,16 @@ namespace MoonTools.Core.Bonk
public int MaxX { get; } public int MaxX { get; }
public int MaxY { 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) public Rectangle(int minX, int minY, int maxX, int maxY)
{ {
@ -19,33 +31,11 @@ namespace MoonTools.Core.Bonk
MinY = minY; MinY = minY;
MaxX = maxX; MaxX = maxX;
MaxY = maxY; 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) public Vector2 Support(Vector2 direction, Transform2D transform)
{ {
var furthestDistance = float.NegativeInfinity; return vertices.Select(vertex => Vector2.Transform(vertex, transform.TransformMatrix)).MaxBy(transformed => Vector2.Dot(transformed, direction)).First();
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;
} }
public AABB AABB(Transform2D Transform2D) public AABB AABB(Transform2D Transform2D)

66
Bonk/Shapes/Simplex.cs Normal file
View File

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

18
Bonk/Vector2Extensions.cs Normal file
View File

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

View File

@ -18,11 +18,11 @@ namespace Tests
var squareB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1); var squareB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
var transformB = new Transform2D(new Vector2(1.5f, 0)); 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.X.Should().Be(1f);
intersection.Y.Should().Be(0); intersection.Y.Should().Be(0);
@ -36,11 +36,11 @@ namespace Tests
var circleB = new Circle(1); var circleB = new Circle(1);
var transformB = new Transform2D(new Vector2(1, 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 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); 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 square = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
var transformB = Transform2D.DefaultTransform; 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.X.Should().Be(-1);
intersection.Y.Should().Be(1); intersection.Y.Should().Be(1);

View File

@ -2,6 +2,7 @@
using MoonTools.Core.Bonk; using MoonTools.Core.Bonk;
using MoonTools.Core.Structs; using MoonTools.Core.Structs;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using FluentAssertions;
namespace Tests namespace Tests
{ {
@ -13,7 +14,7 @@ namespace Tests
var lineA = new Line(new Position2D(-1, -1), new Position2D(1, 1)); var lineA = new Line(new Position2D(-1, -1), new Position2D(1, 1));
var lineB = 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] [Test]
@ -24,7 +25,7 @@ namespace Tests
var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2)); 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] [Test]
@ -33,7 +34,7 @@ namespace Tests
var lineA = new Line(new Position2D(0, 1), new Position2D(1, 0)); var lineA = new Line(new Position2D(0, 1), new Position2D(1, 0));
var lineB = new Line(new Position2D(-1, -1), new Position2D(-2, -2)); 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] [Test]
@ -44,7 +45,7 @@ namespace Tests
var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2)); 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] [Test]
@ -55,7 +56,7 @@ namespace Tests
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));
Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); GJK2D.TestCollision(circleA, transformA, circleB, transformB).Should().BeTrue();
} }
[Test] [Test]
@ -66,7 +67,7 @@ namespace Tests
var circleB = new Circle(2); var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(3, 0), 0f, new Vector2(2, 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] [Test]
@ -77,7 +78,7 @@ namespace Tests
var circleB = new Circle(2); var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(5, 5)); 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] [Test]
@ -88,7 +89,7 @@ namespace Tests
var circleB = new Circle(2); var circleB = new Circle(2);
var transformB = new Transform2D(new Vector2(5, 5), 0, new Vector2(0.2f, 0.2f)); 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] [Test]
@ -108,7 +109,7 @@ namespace Tests
var transformB = new Transform2D(new Vector2(0.5f, 0.5f)); 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] [Test]
@ -128,7 +129,7 @@ namespace Tests
var transformB = new Transform2D(new Vector2(3f, 0f), 0f, new Vector2(3f, 3f)); 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] [Test]
@ -148,7 +149,7 @@ namespace Tests
var transformB = new Transform2D(new Vector2(5, 0)); 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] [Test]
@ -162,13 +163,13 @@ namespace Tests
var transformA = Transform2D.DefaultTransform; var transformA = Transform2D.DefaultTransform;
var shapeB = new Polygon( var shapeB = new Polygon(
new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-2, 2), new Position2D(2, 2),
new Position2D(-1, -1), new Position2D(1, -1) 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] [Test]
@ -185,7 +186,7 @@ namespace Tests
var transformB = Transform2D.DefaultTransform; var transformB = Transform2D.DefaultTransform;
Assert.IsTrue(GJK2D.TestCollision(line, transformA, polygon, transformB).Item1); GJK2D.TestCollision(line, transformA, polygon, transformB).Should().BeTrue();
} }
[Test] [Test]
@ -202,7 +203,7 @@ namespace Tests
var transformB = Transform2D.DefaultTransform; var transformB = Transform2D.DefaultTransform;
Assert.IsFalse(GJK2D.TestCollision(line, transformA, polygon, transformB).Item1); GJK2D.TestCollision(line, transformA, polygon, transformB).Should().BeFalse();
} }
[Test] [Test]
@ -213,7 +214,7 @@ namespace Tests
var circle = new Circle(1); var circle = new Circle(1);
var transformB = Transform2D.DefaultTransform; var transformB = Transform2D.DefaultTransform;
Assert.IsTrue(GJK2D.TestCollision(line, transformA, circle, transformB).Item1); GJK2D.TestCollision(line, transformA, circle, transformB).Should().BeTrue();
} }
[Test] [Test]
@ -224,7 +225,7 @@ namespace Tests
var circle = new Circle(1); var circle = new Circle(1);
var transformB = Transform2D.DefaultTransform; var transformB = Transform2D.DefaultTransform;
Assert.IsFalse(GJK2D.TestCollision(line, transformA, circle, transformB).Item1); GJK2D.TestCollision(line, transformA, circle, transformB).Should().BeFalse();
} }
[Test] [Test]
@ -240,7 +241,7 @@ namespace Tests
var transformB = Transform2D.DefaultTransform; var transformB = Transform2D.DefaultTransform;
Assert.IsTrue(GJK2D.TestCollision(circle, transformA, square, transformB).Item1); GJK2D.TestCollision(circle, transformA, square, transformB).Should().BeTrue();
} }
[Test] [Test]
@ -255,7 +256,7 @@ namespace Tests
); );
var squareTransform = Transform2D.DefaultTransform; var squareTransform = Transform2D.DefaultTransform;
Assert.IsFalse(GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Item1); GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Should().BeFalse();
} }
[Test] [Test]
@ -267,7 +268,7 @@ namespace Tests
var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1); var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
var transformB = new Transform2D(new Vector2(1, 0)); 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] [Test]
@ -279,7 +280,7 @@ namespace Tests
var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1); var rectangleB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
var transformB = new Transform2D(new Vector2(1, 0)); 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();
} }
} }
} }

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>