Compare commits
	
		
			8 Commits
		
	
	
		
			9e1f38897f
			...
			0ba8927858
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0ba8927858 | |||
| ab9181fe3f | |||
| 266443504f | |||
| 3c39e6709d | |||
| e7ca96e2e2 | |||
| 3b83be695c | |||
| 601d15fa45 | |||
| 00b80f1a01 | 
@@ -28,6 +28,7 @@ public static class Math
 | 
			
		||||
    public static float MinMagnitude(float x, float y) => MathF.MinMagnitude(x, y);
 | 
			
		||||
    public static float Pow(float x, float y) => MathF.Pow(x, y);
 | 
			
		||||
    public static float Round(float x, int digits, MidpointRounding mode) => MathF.Round(x, digits, mode);
 | 
			
		||||
    public static float Sqr(float x) => x * x;
 | 
			
		||||
    public static float Sqrt(float x) => MathF.Sqrt(x);
 | 
			
		||||
    public static float Truncate(float x) => MathF.Truncate(x);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core.Abstract;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Physics2D.Abstract;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								Engine.Physics2D/Collider2DBehaviourBase.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Engine.Physics2D/Collider2DBehaviourBase.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
using Syntriax.Engine.Core.Abstract;
 | 
			
		||||
using Syntriax.Engine.Physics2D.Abstract;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Physics2D;
 | 
			
		||||
 | 
			
		||||
public abstract class Collider2DBehaviourBase : BehaviourOverride, ICollider2D
 | 
			
		||||
{
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionPreResolve { get; set; } = null;
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionResolved { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected bool NeedsRecalculation { get; private set; } = true;
 | 
			
		||||
    protected IRigidBody2D? _rigidBody2D = null;
 | 
			
		||||
 | 
			
		||||
    public IRigidBody2D? RigidBody2D => _rigidBody2D;
 | 
			
		||||
 | 
			
		||||
    ITransform IAssignableTransform.Transform => Transform;
 | 
			
		||||
    Action<IAssignableTransform>? IAssignableTransform.OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
 | 
			
		||||
    bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
 | 
			
		||||
 | 
			
		||||
    public void Recalculate()
 | 
			
		||||
    {
 | 
			
		||||
        if (!NeedsRecalculation)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        CalculateCollider();
 | 
			
		||||
        NeedsRecalculation = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract void CalculateCollider();
 | 
			
		||||
 | 
			
		||||
    protected override void OnInitialize()
 | 
			
		||||
    {
 | 
			
		||||
        BehaviourController.TryGetBehaviour(out _rigidBody2D);
 | 
			
		||||
 | 
			
		||||
        BehaviourController.OnBehaviourAdded += OnBehaviourAddedToController;
 | 
			
		||||
        BehaviourController.OnBehaviourRemoved += OnBehaviourRemovedFromController;
 | 
			
		||||
 | 
			
		||||
        Transform.OnPositionChanged += OnPositionChanged;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour)
 | 
			
		||||
    {
 | 
			
		||||
        if (behaviour is IRigidBody2D rigidbody)
 | 
			
		||||
            _rigidBody2D = rigidbody;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void OnBehaviourRemovedFromController(IBehaviourController _, IBehaviour behaviour)
 | 
			
		||||
    {
 | 
			
		||||
        if (behaviour is IRigidBody2D _)
 | 
			
		||||
            _rigidBody2D = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void OnPositionChanged(ITransform transform) => NeedsRecalculation = true;
 | 
			
		||||
 | 
			
		||||
    protected override void OnFinalize()
 | 
			
		||||
    {
 | 
			
		||||
        BehaviourController.OnBehaviourAdded -= OnBehaviourAddedToController;
 | 
			
		||||
        BehaviourController.OnBehaviourRemoved -= OnBehaviourRemovedFromController;
 | 
			
		||||
 | 
			
		||||
        Transform.OnPositionChanged -= OnPositionChanged;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,26 +1,14 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
using Syntriax.Engine.Core.Abstract;
 | 
			
		||||
using Syntriax.Engine.Physics2D.Abstract;
 | 
			
		||||
using Syntriax.Engine.Physics2D.Primitives;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Physics2D;
 | 
			
		||||
 | 
			
		||||
public class Collider2DCircleBehaviour : BehaviourOverride, ICircleCollider2D
 | 
			
		||||
public class Collider2DCircleBehaviour : Collider2DBehaviourBase, ICircleCollider2D
 | 
			
		||||
{
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionPreResolve { get; set; } = null;
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionResolved { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public Circle CircleWorld { get; protected set; } = new(Vector2D.Zero, 1f);
 | 
			
		||||
    public Circle CircleLocal { get; set; } = new(Vector2D.Zero, 1f);
 | 
			
		||||
    public IRigidBody2D? RigidBody2D { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ITransform IAssignableTransform.Transform => Transform;
 | 
			
		||||
    Action<IAssignableTransform>? IAssignableTransform.OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
 | 
			
		||||
    bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
 | 
			
		||||
 | 
			
		||||
    public virtual void Recalculate() => CircleWorld = Transform.TransformCircle(CircleLocal).Displace(Transform.Position);
 | 
			
		||||
    public override void CalculateCollider() => CircleWorld = Transform.TransformCircle(CircleLocal);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,14 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
using Syntriax.Engine.Core.Abstract;
 | 
			
		||||
using Syntriax.Engine.Physics2D.Abstract;
 | 
			
		||||
using Syntriax.Engine.Physics2D.Primitives;
 | 
			
		||||
 | 
			
		||||
namespace Syntriax.Engine.Physics2D;
 | 
			
		||||
 | 
			
		||||
public class Collider2DShapeBehaviour : BehaviourOverride, IShapeCollider2D
 | 
			
		||||
public class Collider2DShapeBehaviour : Collider2DBehaviourBase, IShapeCollider2D
 | 
			
		||||
{
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionPreResolve { get; set; } = null;
 | 
			
		||||
    public Action<ICollider2D, ICollider2D>? OnCollisionResolved { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public Shape ShapeWorld => _shapeWorld;
 | 
			
		||||
    public Shape ShapeLocal { get; set; } = new([new(1f, 1f), new(-1f, 1f), new(-1f, -1f), new(1f, -1f)]);
 | 
			
		||||
    public IRigidBody2D? RigidBody2D { get; set; } = null;
 | 
			
		||||
 | 
			
		||||
    protected Shape _shapeWorld = new([new(1f, 1f), new(-1f, 1f), new(-1f, -1f), new(1f, -1f)]);
 | 
			
		||||
 | 
			
		||||
    ITransform IAssignableTransform.Transform => Transform;
 | 
			
		||||
    Action<IAssignableTransform>? IAssignableTransform.OnTransformAssigned { get => GameObject.OnTransformAssigned; set => GameObject.OnTransformAssigned = value; }
 | 
			
		||||
    bool IAssignableTransform.Assign(ITransform transform) => GameObject.Assign(transform);
 | 
			
		||||
 | 
			
		||||
    public virtual void Recalculate() => Transform.TransformShape(ShapeLocal, ref _shapeWorld);
 | 
			
		||||
    public override void CalculateCollider() => Transform.TransformShape(ShapeLocal, ref _shapeWorld);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,15 +50,15 @@ public class CollisionDetector : ICollisionDetector
 | 
			
		||||
        collisionInformation = default;
 | 
			
		||||
 | 
			
		||||
        Vector2D leftToRightCenter = left.CircleWorld.Center.FromTo(right.CircleWorld.Center);
 | 
			
		||||
        float distanceCircleCenterSquared = leftToRightCenter.MagnitudeSquared;
 | 
			
		||||
        float radiusSumSquared = left.CircleWorld.RadiusSquared + right.CircleWorld.RadiusSquared;
 | 
			
		||||
        float distanceCircleCenter = leftToRightCenter.Magnitude;
 | 
			
		||||
        float radiusSum = left.CircleWorld.Radius + right.CircleWorld.Radius;
 | 
			
		||||
 | 
			
		||||
        float circleSurfaceDistanceSquared = distanceCircleCenterSquared - radiusSumSquared;
 | 
			
		||||
        float circleSurfaceDistance = distanceCircleCenter - radiusSum;
 | 
			
		||||
 | 
			
		||||
        bool collision = circleSurfaceDistanceSquared <= 0f;
 | 
			
		||||
        bool collision = circleSurfaceDistance <= 0f;
 | 
			
		||||
 | 
			
		||||
        if (collision)
 | 
			
		||||
            collisionInformation = new(left, right, leftToRightCenter.Normalized, Math.Sqrt(circleSurfaceDistanceSquared));
 | 
			
		||||
            collisionInformation = new(left, right, leftToRightCenter.Normalized, -circleSurfaceDistance);
 | 
			
		||||
 | 
			
		||||
        return collision;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
using Syntriax.Engine.Core;
 | 
			
		||||
@@ -54,17 +53,20 @@ public class PhysicsEngine2D : IPhysicsEngine2D
 | 
			
		||||
            for (int x = 0; x < colliders.Count; x++)
 | 
			
		||||
            {
 | 
			
		||||
                ICollider2D? colliderX = colliders[x];
 | 
			
		||||
                for (int y = 0; y < colliders.Count; y++)
 | 
			
		||||
                for (int y = x + 1; y < colliders.Count; y++)
 | 
			
		||||
                {
 | 
			
		||||
                    ICollider2D? colliderY = colliders[y];
 | 
			
		||||
 | 
			
		||||
                    if (colliderX.RigidBody2D == colliderY.RigidBody2D && colliderY.RigidBody2D is null)
 | 
			
		||||
                    if (colliderX.RigidBody2D == colliderY.RigidBody2D)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    if (collisionDetector.TryDetect(colliderX, colliderY, out CollisionDetectionInformation? information))
 | 
			
		||||
                    {
 | 
			
		||||
                        information.Left.Transform.Position -= .5f * information.Normal * information.Penetration;
 | 
			
		||||
                        information.Right.Transform.Position += .5f * information.Normal * information.Penetration;
 | 
			
		||||
                        Vector2D displacementVector = .5f * information.Normal * information.Penetration;
 | 
			
		||||
                        information.Left.Transform.Position -= displacementVector;
 | 
			
		||||
                        information.Right.Transform.Position += displacementVector;
 | 
			
		||||
                        information.Left.Recalculate();
 | 
			
		||||
                        information.Right.Recalculate();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user