refactor: Basic Collision Resolver
This commit is contained in:
parent
4d9121118d
commit
a3c4afb223
|
@ -2,5 +2,5 @@ namespace Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
public interface ICollisionResolver2D
|
public interface ICollisionResolver2D
|
||||||
{
|
{
|
||||||
void ResolveCollision(ICollider2D colliderA, ICollider2D colliderB);
|
void Resolve(CollisionDetectionInformation collisionInformation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
using Syntriax.Engine.Core;
|
||||||
|
using Syntriax.Engine.Physics2D.Abstract;
|
||||||
|
|
||||||
|
namespace Syntriax.Engine.Physics2D;
|
||||||
|
|
||||||
|
public class CollisionResolver2D : ICollisionResolver2D
|
||||||
|
{
|
||||||
|
public void Resolve(CollisionDetectionInformation collisionInformation)
|
||||||
|
{
|
||||||
|
Vector2D displacementVector = collisionInformation.Normal * collisionInformation.Penetration;
|
||||||
|
|
||||||
|
ICollider2D left = collisionInformation.Left;
|
||||||
|
ICollider2D right = collisionInformation.Right;
|
||||||
|
|
||||||
|
bool isLeftStatic = left.RigidBody2D?.IsStatic ?? true;
|
||||||
|
bool isRightStatic = right.RigidBody2D?.IsStatic ?? true;
|
||||||
|
|
||||||
|
if (isLeftStatic && isRightStatic)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isLeftStatic)
|
||||||
|
right.Transform.Position += displacementVector;
|
||||||
|
else if (isRightStatic)
|
||||||
|
left.Transform.Position -= displacementVector;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float leftMass = left.RigidBody2D?.Mass ?? float.Epsilon;
|
||||||
|
float rightMass = right.RigidBody2D?.Mass ?? float.Epsilon;
|
||||||
|
float sumMass = leftMass + rightMass;
|
||||||
|
|
||||||
|
float leftMomentumPercentage = leftMass / sumMass;
|
||||||
|
float rightMomentumPercentage = rightMass / sumMass;
|
||||||
|
|
||||||
|
right.Transform.Position += leftMomentumPercentage * displacementVector;
|
||||||
|
left.Transform.Position -= rightMomentumPercentage * displacementVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
left.Recalculate();
|
||||||
|
right.Recalculate();
|
||||||
|
|
||||||
|
left.OnCollisionResolved?.Invoke(collisionInformation.Left, collisionInformation);
|
||||||
|
right.OnCollisionResolved?.Invoke(right, collisionInformation);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
|
|
||||||
private int _iterationCount = 1;
|
private int _iterationCount = 1;
|
||||||
private ICollisionDetector2D collisionDetector = new CollisionDetector2D();
|
private ICollisionDetector2D collisionDetector = new CollisionDetector2D();
|
||||||
|
private ICollisionResolver2D collisionResolver = new CollisionResolver2D();
|
||||||
|
|
||||||
public int IterationCount { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; }
|
public int IterationCount { get => _iterationCount; set => _iterationCount = value < 1 ? 1 : value; }
|
||||||
|
|
||||||
|
@ -65,36 +66,7 @@ public class PhysicsEngine2D : IPhysicsEngine2D
|
||||||
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
colliderX.OnCollisionDetected?.Invoke(colliderX, information);
|
||||||
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
colliderY.OnCollisionDetected?.Invoke(colliderY, information);
|
||||||
|
|
||||||
Vector2D displacementVector = information.Normal * information.Penetration;
|
collisionResolver?.Resolve(information);
|
||||||
|
|
||||||
|
|
||||||
bool isStaticLeft = information.Left.RigidBody2D?.IsStatic ?? true;
|
|
||||||
bool isStaticRight = information.Right.RigidBody2D?.IsStatic ?? true;
|
|
||||||
|
|
||||||
if (isStaticLeft && isStaticRight)
|
|
||||||
continue;
|
|
||||||
else if (isStaticLeft)
|
|
||||||
information.Right.Transform.Position += displacementVector;
|
|
||||||
else if (isStaticRight)
|
|
||||||
information.Left.Transform.Position -= displacementVector;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float leftMass = information.Left.RigidBody2D?.Mass ?? float.Epsilon;
|
|
||||||
float rightMass = information.Right.RigidBody2D?.Mass ?? float.Epsilon;
|
|
||||||
float massSum = leftMass + rightMass;
|
|
||||||
|
|
||||||
float leftMomentumPercentage = leftMass / massSum;
|
|
||||||
float rightMomentumPercentage = rightMass / massSum;
|
|
||||||
|
|
||||||
information.Right.Transform.Position += leftMomentumPercentage * displacementVector;
|
|
||||||
information.Left.Transform.Position -= rightMomentumPercentage * displacementVector;
|
|
||||||
}
|
|
||||||
|
|
||||||
information.Left.Recalculate();
|
|
||||||
information.Right.Recalculate();
|
|
||||||
|
|
||||||
colliderX.OnCollisionResolved?.Invoke(colliderX, information);
|
|
||||||
colliderY.OnCollisionResolved?.Invoke(colliderY, information);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue