using System.Collections.Generic; using System.Collections.Immutable; using System.Numerics; using MoonTools.Structs; namespace MoonTools.Bonk { public struct MultiShape2D : IHasAABB2D { public ImmutableArray<(IShape2D, Transform2D)> ShapeTransformPairs { get; } public AABB2D AABB { get; } public MultiShape2D(ImmutableArray<(IShape2D, Transform2D)> shapeTransformPairs) { ShapeTransformPairs = shapeTransformPairs; AABB = AABBFromShapes(shapeTransformPairs); } public AABB2D TransformedAABB(Transform2D transform) { return AABB2D.Transformed(AABB, transform); } /// /// Moves the shapes by pivoting with an offset transform. /// /// /// public IEnumerable<(IShape2D, Transform2D)> TransformShapesUsingOffset(Transform2D offsetTransform) { foreach (var (shape, shapeTransform) in ShapeTransformPairs) { var newTransform = new Transform2D(Vector2.Transform(shapeTransform.Position, offsetTransform.TransformMatrix), offsetTransform.Rotation, offsetTransform.Scale); yield return (shape, newTransform); } } public bool IsSingleShape() where T : struct, IShape2D { return ShapeTransformPairs.Length == 1 && ShapeTransformPairs[0].Item1 is T; } public (T, Transform2D) ShapeTransformPair() where T : struct, IShape2D { return ((T, Transform2D))ShapeTransformPairs[0]; } private static AABB2D AABBFromShapes(IEnumerable<(IShape2D, Transform2D)> shapeTransforms) { var minX = float.MaxValue; var minY = float.MaxValue; var maxX = float.MinValue; var maxY = float.MinValue; foreach (var (shape, transform) in shapeTransforms) { var aabb = shape.TransformedAABB(transform); if (aabb.Min.X < minX) { minX = aabb.Min.X; } if (aabb.Min.Y < minY) { minY = aabb.Min.Y; } if (aabb.Max.X > maxX) { maxX = aabb.Max.X; } if (aabb.Max.Y > maxY) { maxY = aabb.Max.Y; } } return new AABB2D(minX, minY, maxX, maxY); } } }