Example #1
0
        // 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);
        }