feat: basic impulse resolving for 2D collisions
This commit is contained in:
@@ -6,8 +6,6 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
{
|
{
|
||||||
public void Resolve(CollisionDetectionInformation collisionInformation)
|
public void Resolve(CollisionDetectionInformation collisionInformation)
|
||||||
{
|
{
|
||||||
Vector2D displacementVector = collisionInformation.Normal * collisionInformation.Penetration;
|
|
||||||
|
|
||||||
ICollider2D left = collisionInformation.Detector;
|
ICollider2D left = collisionInformation.Detector;
|
||||||
ICollider2D right = collisionInformation.Detected;
|
ICollider2D right = collisionInformation.Detected;
|
||||||
|
|
||||||
@@ -17,6 +15,20 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
if (isLeftStatic && isRightStatic)
|
if (isLeftStatic && isRightStatic)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Displace(collisionInformation, left, right, isLeftStatic, isRightStatic);
|
||||||
|
Bounce(collisionInformation, left, right, isLeftStatic, isRightStatic);
|
||||||
|
|
||||||
|
left.Recalculate();
|
||||||
|
right.Recalculate();
|
||||||
|
|
||||||
|
left.Resolve(collisionInformation);
|
||||||
|
right.Resolve(collisionInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Displace(CollisionDetectionInformation collisionInformation, ICollider2D left, ICollider2D right, bool isLeftStatic, bool isRightStatic)
|
||||||
|
{
|
||||||
|
Vector2D displacementVector = collisionInformation.Normal * collisionInformation.Penetration;
|
||||||
|
|
||||||
if (isLeftStatic)
|
if (isLeftStatic)
|
||||||
right.Transform.Position += displacementVector;
|
right.Transform.Position += displacementVector;
|
||||||
else if (isRightStatic)
|
else if (isRightStatic)
|
||||||
@@ -33,11 +45,32 @@ public class CollisionResolver2D : ICollisionResolver2D
|
|||||||
right.Transform.Position += leftMomentumPercentage * displacementVector;
|
right.Transform.Position += leftMomentumPercentage * displacementVector;
|
||||||
left.Transform.Position -= rightMomentumPercentage * displacementVector;
|
left.Transform.Position -= rightMomentumPercentage * displacementVector;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
left.Recalculate();
|
private static void Bounce(CollisionDetectionInformation collisionInformation, ICollider2D left, ICollider2D right, bool isLeftStatic, bool isRightStatic)
|
||||||
right.Recalculate();
|
{
|
||||||
|
Vector2D leftVelocity = left.RigidBody2D?.Velocity ?? Vector2D.Zero;
|
||||||
|
Vector2D rightVelocity = right.RigidBody2D?.Velocity ?? Vector2D.Zero;
|
||||||
|
|
||||||
left.Resolve(collisionInformation);
|
Vector2D relativeVelocity = leftVelocity - rightVelocity;
|
||||||
right.Resolve(collisionInformation);
|
float velocityAlongNormal = Vector2D.Dot(relativeVelocity, collisionInformation.Normal);
|
||||||
|
|
||||||
|
if (velocityAlongNormal > 0)
|
||||||
|
{
|
||||||
|
collisionInformation = collisionInformation.Reverse();
|
||||||
|
velocityAlongNormal = -velocityAlongNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
float e = (left.RigidBody2D?.Material.Restitution ?? 0f).Add(right.RigidBody2D?.Material.Restitution ?? 0f).Divide(2f);
|
||||||
|
|
||||||
|
float leftMassEffective = isLeftStatic ? float.PositiveInfinity : left.RigidBody2D?.Mass ?? float.Epsilon;
|
||||||
|
float rightMassEffective = isRightStatic ? float.PositiveInfinity : right.RigidBody2D?.Mass ?? float.Epsilon;
|
||||||
|
float impulse = -(1f + e) * velocityAlongNormal / ((1f / leftMassEffective) + (1f / rightMassEffective));
|
||||||
|
|
||||||
|
if (!isLeftStatic)
|
||||||
|
left.RigidBody2D?.Velocity += impulse / leftMassEffective * collisionInformation.Normal;
|
||||||
|
|
||||||
|
if (!isRightStatic)
|
||||||
|
right.RigidBody2D?.Velocity -= impulse / rightMassEffective * collisionInformation.Normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user