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.Immutable;
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Bonk
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +23,17 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
            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)
 | 
			
		||||
            {
 | 
			
		||||
                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>
 | 
			
		||||
        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; }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
        /// <returns></returns>
 | 
			
		||||
        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; }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -106,9 +106,9 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
        /// <returns></returns>
 | 
			
		||||
        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; }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,26 +1,21 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
using MoonTools.Core.Structs;
 | 
			
		||||
 | 
			
		||||
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 Vector2 Motion { 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;
 | 
			
		||||
            Motion = motion;
 | 
			
		||||
            ID = id;
 | 
			
		||||
            Shape = shape;
 | 
			
		||||
            Transform = transform;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
    public static class SweepTest
 | 
			
		||||
    {
 | 
			
		||||
        /// <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>
 | 
			
		||||
        /// <typeparam name="T"></typeparam>
 | 
			
		||||
        /// <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="ray">Given in world-space.</param>
 | 
			
		||||
        /// <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 sweepBox = SweepBox(transformedAABB, ray);
 | 
			
		||||
| 
						 | 
				
			
			@ -108,14 +108,19 @@ namespace MoonTools.Core.Bonk
 | 
			
		|||
                var overlapPosition = ray * shortestDistance;
 | 
			
		||||
                var correctionX = -Math.Sign(ray.X);
 | 
			
		||||
                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
 | 
			
		||||
            {
 | 
			
		||||
                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)
 | 
			
		||||
        {
 | 
			
		||||
            return new AABB(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue