From 2bfd391286bd327359074d0700c346926191bbcc Mon Sep 17 00:00:00 2001 From: Syntriax Date: Fri, 26 Jan 2024 18:54:53 +0300 Subject: [PATCH] feat: Basic Shape to Circle Collision Detection --- Engine.Physics2D/CollisionDetector.cs | 39 ++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Engine.Physics2D/CollisionDetector.cs b/Engine.Physics2D/CollisionDetector.cs index 4845f64..9a8f109 100644 --- a/Engine.Physics2D/CollisionDetector.cs +++ b/Engine.Physics2D/CollisionDetector.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Syntriax.Engine.Core; using Syntriax.Engine.Physics2D.Abstract; +using Syntriax.Engine.Physics2D.Primitives; namespace Syntriax.Engine.Physics2D; @@ -30,9 +31,9 @@ public class CollisionDetector : ICollisionDetector return false; } - private bool DetectCircleShape(ICircleCollider2D circleCollider, IShapeCollider2D shapeCollider, out CollisionDetectionInformation? collisionInformation) + private static bool DetectCircleShape(ICircleCollider2D circleCollider, IShapeCollider2D shapeCollider, out CollisionDetectionInformation? collisionInformation) { - throw new System.NotImplementedException(); + return DetectShapeCircle(shapeCollider, circleCollider, out collisionInformation); } private static bool DetectShapeShape(IShapeCollider2D left, IShapeCollider2D right, out CollisionDetectionInformation? collisionInformation) @@ -42,7 +43,39 @@ public class CollisionDetector : ICollisionDetector private static bool DetectShapeCircle(IShapeCollider2D shapeCollider, ICircleCollider2D circleCollider, out CollisionDetectionInformation? collisionInformation) { - throw new System.NotImplementedException(); + collisionInformation = default; + + { + Vector2D shapeToCircleProjectionVector = shapeCollider.Transform.Position.FromTo(circleCollider.CircleWorld.Center).Normalized; + + Projection shapeProjection = shapeCollider.ShapeWorld.ToProjection(shapeToCircleProjectionVector); + Projection circleProjection = circleCollider.CircleWorld.ToProjection(shapeToCircleProjectionVector); + + if (!shapeProjection.Overlaps(circleProjection, out float depth)) + return false; + + if (collisionInformation == default || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth)) + collisionInformation = new(shapeCollider, circleCollider, shapeToCircleProjectionVector, depth); + } + + var vertices = shapeCollider.ShapeWorld.Vertices; + int count = vertices.Count; + + for (int indexProjection = 0; indexProjection < count; indexProjection++) + { + Vector2D projectionVector = vertices[indexProjection].FromTo(vertices[(indexProjection + 1) % count]).Perpendicular().Normalized; + + Projection shapeProjection = shapeCollider.ShapeWorld.ToProjection(projectionVector); + Projection circleProjection = circleCollider.CircleWorld.ToProjection(projectionVector); + + if (!shapeProjection.Overlaps(circleProjection, out float depth)) + return false; + + if (collisionInformation == default || Math.Abs(collisionInformation.Penetration) > Math.Abs(depth)) + collisionInformation = new(shapeCollider, circleCollider, projectionVector, depth); + } + + return true; } private static bool DetectCircleCircle(ICircleCollider2D left, ICircleCollider2D right, out CollisionDetectionInformation? collisionInformation)