// Based off of Randy Gaul's ImpulseEngine code private bool FixClipping(List <Manifold> collisions, float divisions) { const float allowance = 1 / 128f; var percent = MathHelper.Clamp(1f / divisions, 0.01f, 1f); var done = true; foreach (var collision in collisions) { if (!collision.Hard) { continue; } var penetration = _physicsManager.CalculatePenetration(collision.A, collision.B); if (penetration <= allowance) { continue; } done = false; var correction = collision.Normal * Math.Abs(penetration) * percent; if (collision.A.CanMove()) { collision.A.Owner.Transform.WorldPosition -= correction; } if (collision.B.CanMove()) { collision.B.Owner.Transform.WorldPosition += correction; } } return(done); }
// Based off of Randy Gaul's ImpulseEngine code // https://github.com/RandyGaul/ImpulseEngine/blob/5181fee1648acc4a889b9beec8e13cbe7dac9288/Manifold.cpp#L123a private bool FixClipping(List <Manifold> collisions, float divisions) { const float allowance = 1 / 128.0f; var percent = MathHelper.Clamp(0.4f / divisions, 0.01f, 1f); var done = true; foreach (var collision in collisions) { if (!collision.Hard) { continue; } var penetration = _physicsManager.CalculatePenetration(collision.A, collision.B); if (penetration <= allowance) { continue; } done = false; //var correction = collision.Normal * Math.Abs(penetration) * percent; var correction = collision.Normal * Math.Max(penetration - allowance, 0.0f) / (collision.A.InvMass + collision.B.InvMass) * percent; if (collision.A.CanMove()) { collision.A.Owner.Transform.DeferUpdates = true; _deferredUpdates.Add(collision.A); collision.A.Owner.Transform.WorldPosition -= correction * collision.A.InvMass; } if (collision.B.CanMove()) { collision.B.Owner.Transform.DeferUpdates = true; _deferredUpdates.Add(collision.B); collision.B.Owner.Transform.WorldPosition += correction * collision.B.InvMass; } } return(done); }