forked from MoonsideGames/MoonTools.Bonk
change how multishape shapes are transformed and add point sweep test
parent
17084154a2
commit
7875342da8
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Numerics;
|
||||||
using MoonTools.Core.Structs;
|
using MoonTools.Core.Structs;
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
|
@ -22,11 +23,17 @@ namespace MoonTools.Core.Bonk
|
||||||
return AABB.Transformed(AABB, transform);
|
return AABB.Transformed(AABB, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<(IShape2D, Transform2D)> TransformedShapeTransforms(Transform2D transform)
|
/// <summary>
|
||||||
|
/// Moves the shapes by pivoting with an offset transform.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offsetTransform"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IEnumerable<(IShape2D, Transform2D)> TransformShapesUsingOffset(Transform2D offsetTransform)
|
||||||
{
|
{
|
||||||
foreach (var (shape, shapeTransform) in ShapeTransformPairs)
|
foreach (var (shape, shapeTransform) in ShapeTransformPairs)
|
||||||
{
|
{
|
||||||
yield return (shape, transform.Compose(shapeTransform));
|
var newTransform = new Transform2D(Vector2.Transform(shapeTransform.Position, offsetTransform.TransformMatrix), offsetTransform.Rotation, offsetTransform.Scale);
|
||||||
|
yield return (shape, newTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace MoonTools.Core.Bonk
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool TestCollision(MultiShape multiShape, Transform2D multiShapeTransform, IShape2D shape, Transform2D shapeTransform)
|
public static bool TestCollision(MultiShape multiShape, Transform2D multiShapeTransform, IShape2D shape, Transform2D shapeTransform)
|
||||||
{
|
{
|
||||||
foreach (var (otherShape, otherTransform) in multiShape.TransformedShapeTransforms(multiShapeTransform))
|
foreach (var (otherShape, otherTransform) in multiShape.TransformShapesUsingOffset(multiShapeTransform))
|
||||||
{
|
{
|
||||||
if (TestCollision(shape, shapeTransform, otherShape, otherTransform)) { return true; }
|
if (TestCollision(shape, shapeTransform, otherShape, otherTransform)) { return true; }
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ namespace MoonTools.Core.Bonk
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool TestCollision(IShape2D shape, Transform2D shapeTransform, MultiShape multiShape, Transform2D multiShapeTransform)
|
public static bool TestCollision(IShape2D shape, Transform2D shapeTransform, MultiShape multiShape, Transform2D multiShapeTransform)
|
||||||
{
|
{
|
||||||
foreach (var (otherShape, otherTransform) in multiShape.TransformedShapeTransforms(multiShapeTransform))
|
foreach (var (otherShape, otherTransform) in multiShape.TransformShapesUsingOffset(multiShapeTransform))
|
||||||
{
|
{
|
||||||
if (TestCollision(shape, shapeTransform, otherShape, otherTransform)) { return true; }
|
if (TestCollision(shape, shapeTransform, otherShape, otherTransform)) { return true; }
|
||||||
}
|
}
|
||||||
|
@ -106,9 +106,9 @@ namespace MoonTools.Core.Bonk
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool TestCollision(MultiShape multiShapeA, Transform2D transformA, MultiShape multiShapeB, Transform2D transformB)
|
public static bool TestCollision(MultiShape multiShapeA, Transform2D transformA, MultiShape multiShapeB, Transform2D transformB)
|
||||||
{
|
{
|
||||||
foreach (var (shapeA, shapeTransformA) in multiShapeA.TransformedShapeTransforms(transformA))
|
foreach (var (shapeA, shapeTransformA) in multiShapeA.TransformShapesUsingOffset(transformA))
|
||||||
{
|
{
|
||||||
foreach (var (shapeB, shapeTransformB) in multiShapeB.TransformedShapeTransforms(transformB))
|
foreach (var (shapeB, shapeTransformB) in multiShapeB.TransformShapesUsingOffset(transformB))
|
||||||
{
|
{
|
||||||
if (TestCollision(shapeA, shapeTransformA, shapeB, shapeTransformB)) { return true; }
|
if (TestCollision(shapeA, shapeTransformA, shapeB, shapeTransformB)) { return true; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using MoonTools.Core.Structs;
|
|
||||||
|
|
||||||
namespace MoonTools.Core.Bonk
|
namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
public struct SweepResult<T, U> where T : IEquatable<T> where U : struct, IShape2D
|
public struct SweepResult<T> where T : IEquatable<T>
|
||||||
{
|
{
|
||||||
public static SweepResult<T, U> False = new SweepResult<T, U>();
|
public static SweepResult<T> False = new SweepResult<T>();
|
||||||
|
|
||||||
public bool Hit { get; }
|
public bool Hit { get; }
|
||||||
public Vector2 Motion { get; }
|
public Vector2 Motion { get; }
|
||||||
public T ID { get; }
|
public T ID { get; }
|
||||||
public U Shape { get; }
|
|
||||||
public Transform2D Transform { get; }
|
|
||||||
|
|
||||||
public SweepResult(bool hit, Vector2 motion, T id, U shape, Transform2D transform)
|
public SweepResult(bool hit, Vector2 motion, T id)
|
||||||
{
|
{
|
||||||
Hit = hit;
|
Hit = hit;
|
||||||
Motion = motion;
|
Motion = motion;
|
||||||
ID = id;
|
ID = id;
|
||||||
Shape = shape;
|
|
||||||
Transform = transform;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace MoonTools.Core.Bonk
|
||||||
public static class SweepTest
|
public static class SweepTest
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a sweep test on rectangles. Returns the position 1 pixel before overlap occurs.
|
/// Performs a sweep test on and against rectangles. Returns the position 1 pixel before overlap occurs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="spatialHash">A spatial hash.</param>
|
/// <param name="spatialHash">A spatial hash.</param>
|
||||||
|
@ -15,7 +15,7 @@ namespace MoonTools.Core.Bonk
|
||||||
/// <param name="transform">A transform by which to transform the IHasAABB2D.</param>
|
/// <param name="transform">A transform by which to transform the IHasAABB2D.</param>
|
||||||
/// <param name="ray">Given in world-space.</param>
|
/// <param name="ray">Given in world-space.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static SweepResult<T, Rectangle> Rectangle<T>(SpatialHash<T> spatialHash, Rectangle rectangle, Transform2D transform, Vector2 ray) where T : IEquatable<T>
|
public static SweepResult<T> Test<T>(SpatialHash<T> spatialHash, Rectangle rectangle, Transform2D transform, Vector2 ray) where T : IEquatable<T>
|
||||||
{
|
{
|
||||||
var transformedAABB = rectangle.TransformedAABB(transform);
|
var transformedAABB = rectangle.TransformedAABB(transform);
|
||||||
var sweepBox = SweepBox(transformedAABB, ray);
|
var sweepBox = SweepBox(transformedAABB, ray);
|
||||||
|
@ -108,14 +108,19 @@ namespace MoonTools.Core.Bonk
|
||||||
var overlapPosition = ray * shortestDistance;
|
var overlapPosition = ray * shortestDistance;
|
||||||
var correctionX = -Math.Sign(ray.X);
|
var correctionX = -Math.Sign(ray.X);
|
||||||
var correctionY = -Math.Sign(ray.Y);
|
var correctionY = -Math.Sign(ray.Y);
|
||||||
return new SweepResult<T, Rectangle>(true, new Position2D((int)overlapPosition.X + correctionX, (int)overlapPosition.Y + correctionY), nearestID, nearestRectangle.Value, nearestTransform.Value);
|
return new SweepResult<T>(true, new Position2D((int)overlapPosition.X + correctionX, (int)overlapPosition.Y + correctionY), nearestID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return SweepResult<T, Rectangle>.False;
|
return SweepResult<T>.False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SweepResult<T> Test<T>(SpatialHash<T> spatialHash, Point point, Transform2D transform, Vector2 ray) where T : IEquatable<T>
|
||||||
|
{
|
||||||
|
return Test(spatialHash, new Rectangle(0, 0), transform, ray);
|
||||||
|
}
|
||||||
|
|
||||||
private static AABB SweepBox(AABB aabb, Vector2 ray)
|
private static AABB SweepBox(AABB aabb, Vector2 ray)
|
||||||
{
|
{
|
||||||
return new AABB(
|
return new AABB(
|
||||||
|
|
Loading…
Reference in New Issue