change collision API to support multi shapes
							parent
							
								
									65568ea234
								
							
						
					
					
						commit
						dccd81e029
					
				|  | @ -77,6 +77,33 @@ namespace MoonWorks.Collision | ||||||
|             return new AABB2D(newCenter - newExtent, newCenter + newExtent); |             return new AABB2D(newCenter - newExtent, newCenter + newExtent); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		public AABB2D Compose(AABB2D aabb) | ||||||
|  | 		{ | ||||||
|  | 			float left = Left; | ||||||
|  | 			float top = Top; | ||||||
|  | 			float right = Right; | ||||||
|  | 			float bottom = Bottom; | ||||||
|  | 
 | ||||||
|  | 			if (aabb.Left < left) | ||||||
|  | 			{ | ||||||
|  | 				left = aabb.Left; | ||||||
|  | 			} | ||||||
|  | 			if (aabb.Right > right) | ||||||
|  | 			{ | ||||||
|  | 				right = aabb.Right; | ||||||
|  | 			} | ||||||
|  | 			if (aabb.Top < top) | ||||||
|  | 			{ | ||||||
|  | 				top = aabb.Top; | ||||||
|  | 			} | ||||||
|  | 			if (aabb.Bottom > bottom) | ||||||
|  | 			{ | ||||||
|  | 				bottom = aabb.Bottom; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			return new AABB2D(left, top, right, bottom); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Creates an AABB for an arbitrary collection of positions. | 		/// Creates an AABB for an arbitrary collection of positions. | ||||||
| 		/// This is less efficient than defining a custom AABB method for most shapes, so avoid using this if possible. | 		/// This is less efficient than defining a custom AABB method for most shapes, so avoid using this if possible. | ||||||
|  |  | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using MoonWorks.Math; | ||||||
|  | 
 | ||||||
|  | namespace MoonWorks.Collision | ||||||
|  | { | ||||||
|  |     public interface ICollidable | ||||||
|  |     { | ||||||
|  | 		IEnumerable<IShape2D> Shapes { get; } | ||||||
|  |         AABB2D AABB { get; } | ||||||
|  |         AABB2D TransformedAABB(Transform2D transform); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,16 +0,0 @@ | ||||||
| using MoonWorks.Math; |  | ||||||
| 
 |  | ||||||
| namespace MoonWorks.Collision |  | ||||||
| { |  | ||||||
| 	public interface IHasAABB2D |  | ||||||
| 	{ |  | ||||||
| 		AABB2D AABB { get; } |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Returns a bounding box based on the shape. |  | ||||||
| 		/// </summary> |  | ||||||
| 		/// <param name="transform">A Transform for transforming the shape vertices.</param> |  | ||||||
| 		/// <returns>Returns a bounding box based on the shape.</returns> |  | ||||||
| 		AABB2D TransformedAABB(Transform2D transform); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -2,7 +2,7 @@ using MoonWorks.Math; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Collision | namespace MoonWorks.Collision | ||||||
| { | { | ||||||
| 	public interface IShape2D : IHasAABB2D, System.IEquatable<IShape2D> | 	public interface IShape2D : ICollidable, System.IEquatable<IShape2D> | ||||||
| 	{ | 	{ | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// A Minkowski support function. Gives the farthest point on the edge of a shape along the given direction. | 		/// A Minkowski support function. Gives the farthest point on the edge of a shape along the given direction. | ||||||
|  |  | ||||||
|  | @ -11,6 +11,22 @@ namespace MoonWorks.Collision | ||||||
| 			public int Index; | 			public int Index; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |         public static bool TestCollision(ICollidable collidableA, Transform2D transformA, ICollidable collidableB, Transform2D transformB) | ||||||
|  |         { | ||||||
|  |             foreach (var shapeA in collidableA.Shapes) | ||||||
|  |             { | ||||||
|  |                 foreach (var shapeB in collidableB.Shapes) | ||||||
|  |                 { | ||||||
|  | 					if (TestCollision(shapeA, transformA, shapeB, transformB)) | ||||||
|  |                     { | ||||||
|  | 						return true; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) | 		public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) | ||||||
| 		{ | 		{ | ||||||
| 			// If we can use a fast path check, let's do that! | 			// If we can use a fast path check, let's do that! | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | using System.Collections.Generic; | ||||||
| using MoonWorks.Math; | using MoonWorks.Math; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Collision | namespace MoonWorks.Collision | ||||||
|  | @ -9,6 +10,13 @@ namespace MoonWorks.Collision | ||||||
| 	{ | 	{ | ||||||
| 		public int Radius { get; } | 		public int Radius { get; } | ||||||
| 		public AABB2D AABB { get; } | 		public AABB2D AABB { get; } | ||||||
|  | 		public IEnumerable<IShape2D> Shapes | ||||||
|  | 		{ | ||||||
|  | 			get | ||||||
|  | 			{ | ||||||
|  | 				yield return this; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		public Circle(int radius) | 		public Circle(int radius) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | using System.Collections.Generic; | ||||||
| using MoonWorks.Math; | using MoonWorks.Math; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Collision | namespace MoonWorks.Collision | ||||||
|  | @ -12,6 +13,14 @@ namespace MoonWorks.Collision | ||||||
| 
 | 
 | ||||||
|         public AABB2D AABB { get; } |         public AABB2D AABB { get; } | ||||||
| 
 | 
 | ||||||
|  | 		public IEnumerable<IShape2D> Shapes | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  | 				yield return this; | ||||||
|  | 			} | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| 		public Line(Vector2 start, Vector2 end) | 		public Line(Vector2 start, Vector2 end) | ||||||
|         { |         { | ||||||
|             Start = start; |             Start = start; | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | using System.Collections.Generic; | ||||||
| using MoonWorks.Math; | using MoonWorks.Math; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Collision | namespace MoonWorks.Collision | ||||||
|  | @ -9,6 +10,13 @@ namespace MoonWorks.Collision | ||||||
| 	public struct Point : IShape2D, System.IEquatable<Point> | 	public struct Point : IShape2D, System.IEquatable<Point> | ||||||
| 	{ | 	{ | ||||||
| 		public AABB2D AABB { get; } | 		public AABB2D AABB { get; } | ||||||
|  | 		public IEnumerable<IShape2D> Shapes | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  | 				yield return this; | ||||||
|  | 			} | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 		public AABB2D TransformedAABB(Transform2D transform) | 		public AABB2D TransformedAABB(Transform2D transform) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | using System.Collections.Generic; | ||||||
| using MoonWorks.Math; | using MoonWorks.Math; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Collision | namespace MoonWorks.Collision | ||||||
|  | @ -15,12 +16,20 @@ namespace MoonWorks.Collision | ||||||
| 		public int Left { get; } | 		public int Left { get; } | ||||||
| 		public int Top { get; } | 		public int Top { get; } | ||||||
| 		public int Bottom { get; } | 		public int Bottom { get; } | ||||||
| 		public Vector2 BottomLeft { get; } | 		public Vector2 TopLeft { get; } | ||||||
| 		public Vector2 TopRight { get; } | 		public Vector2 BottomRight { get; } | ||||||
| 
 | 
 | ||||||
| 		public Vector2 Min { get; } | 		public Vector2 Min { get; } | ||||||
| 		public Vector2 Max { get; } | 		public Vector2 Max { get; } | ||||||
| 
 | 
 | ||||||
|  | 		public IEnumerable<IShape2D> Shapes | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  | 				yield return this; | ||||||
|  | 			} | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| 		public Rectangle(int left, int top, int width, int height) | 		public Rectangle(int left, int top, int width, int height) | ||||||
| 		{ | 		{ | ||||||
| 			Width = width; | 			Width = width; | ||||||
|  | @ -30,8 +39,8 @@ namespace MoonWorks.Collision | ||||||
| 			Top = top; | 			Top = top; | ||||||
| 			Bottom = top + height; | 			Bottom = top + height; | ||||||
| 			AABB = new AABB2D(left, top, Right, Bottom); | 			AABB = new AABB2D(left, top, Right, Bottom); | ||||||
| 			BottomLeft = new Vector2(Left, Bottom); | 			TopLeft = new Vector2(Left, Top); | ||||||
| 			TopRight = new Vector2(Top, Right); | 			BottomRight = new Vector2(Right, Bottom); | ||||||
| 			Min = AABB.Min; | 			Min = AABB.Min; | ||||||
| 			Max = AABB.Max; | 			Max = AABB.Max; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ namespace MoonWorks.Collision | ||||||
| 		private readonly int cellSize; | 		private readonly int cellSize; | ||||||
| 
 | 
 | ||||||
| 		private readonly Dictionary<long, HashSet<T>> hashDictionary = new Dictionary<long, HashSet<T>>(); | 		private readonly Dictionary<long, HashSet<T>> hashDictionary = new Dictionary<long, HashSet<T>>(); | ||||||
| 		private readonly Dictionary<T, (IHasAABB2D, Transform2D, uint)> IDLookup = new Dictionary<T, (IHasAABB2D, Transform2D, uint)>(); | 		private readonly Dictionary<T, (ICollidable, Transform2D, uint)> IDLookup = new Dictionary<T, (ICollidable, Transform2D, uint)>(); | ||||||
| 
 | 
 | ||||||
| 		public int MinX { get; private set; } = 0; | 		public int MinX { get; private set; } = 0; | ||||||
| 		public int MaxX { get; private set; } = 0; | 		public int MaxX { get; private set; } = 0; | ||||||
|  | @ -38,7 +38,7 @@ namespace MoonWorks.Collision | ||||||
| 		/// <param name="shape"></param> | 		/// <param name="shape"></param> | ||||||
| 		/// <param name="transform2D"></param> | 		/// <param name="transform2D"></param> | ||||||
| 		/// <param name="collisionGroups">A bitmask value specifying the groups this object belongs to.</param> | 		/// <param name="collisionGroups">A bitmask value specifying the groups this object belongs to.</param> | ||||||
| 		public void Insert(T id, IHasAABB2D shape, Transform2D transform2D, uint collisionGroups = uint.MaxValue) | 		public void Insert(T id, ICollidable shape, Transform2D transform2D, uint collisionGroups = uint.MaxValue) | ||||||
| 		{ | 		{ | ||||||
| 			var box = shape.TransformedAABB(transform2D); | 			var box = shape.TransformedAABB(transform2D); | ||||||
| 			var minHash = Hash(box.Min); | 			var minHash = Hash(box.Min); | ||||||
|  | @ -68,7 +68,7 @@ namespace MoonWorks.Collision | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID. | 		/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		public IEnumerable<(T, IHasAABB2D, Transform2D, uint)> Retrieve(T id, IHasAABB2D shape, Transform2D transform2D, uint collisionMask = uint.MaxValue) | 		public IEnumerable<(T, ICollidable, Transform2D, uint)> Retrieve(T id, ICollidable shape, Transform2D transform2D, uint collisionMask = uint.MaxValue) | ||||||
| 		{ | 		{ | ||||||
| 			var returned = AcquireHashSet(); | 			var returned = AcquireHashSet(); | ||||||
| 
 | 
 | ||||||
|  | @ -113,7 +113,7 @@ namespace MoonWorks.Collision | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
| 		/// <param name="aabb">A transformed AABB.</param> | 		/// <param name="aabb">A transformed AABB.</param> | ||||||
| 		/// <returns></returns> | 		/// <returns></returns> | ||||||
| 		public IEnumerable<(T, IHasAABB2D, Transform2D, uint)> Retrieve(AABB2D aabb, uint collisionMask = uint.MaxValue) | 		public IEnumerable<(T, ICollidable, Transform2D, uint)> Retrieve(AABB2D aabb, uint collisionMask = uint.MaxValue) | ||||||
| 		{ | 		{ | ||||||
| 			var returned = AcquireHashSet(); | 			var returned = AcquireHashSet(); | ||||||
| 
 | 
 | ||||||
|  | @ -150,6 +150,14 @@ namespace MoonWorks.Collision | ||||||
| 			FreeHashSet(returned); | 			FreeHashSet(returned); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		/// <summary> | ||||||
|  | 		/// Removes a specific ID from the SpatialHash. | ||||||
|  | 		/// </summary> | ||||||
|  | 		public void Remove(T id) | ||||||
|  | 		{ | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Removes everything that has been inserted into the SpatialHash. | 		/// Removes everything that has been inserted into the SpatialHash. | ||||||
| 		/// </summary> | 		/// </summary> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue