예제 #1
0
        public static void Prestep(ref BodyInertias inertiaA, ref Vector3Wide angularJacobianA,
                                   out TwistFrictionProjection projection)
        {
            //Compute effective mass matrix contributions. No linear contributions for the twist constraint.
            Triangular3x3Wide.VectorSandwich(ref angularJacobianA, ref inertiaA.InverseInertiaTensor, out var inverseEffectiveMass);

            //No softening; this constraint is rigid by design. (It does support a maximum force, but that is distinct from a proper damping ratio/natural frequency.)
            //Note that we have to guard against two bodies with infinite inertias. This is a valid state!
            //(We do not have to do such guarding on constraints with linear jacobians; dynamic bodies cannot have zero *mass*.)
            //(Also note that there's no need for epsilons here... users shouldn't be setting their inertias to the absurd values it would take to cause a problem.
            //Invalid conditions can't arise dynamically.)
            var inverseIsZero = Vector.Equals(Vector <float> .Zero, inverseEffectiveMass);

            projection.EffectiveMass = Vector.ConditionalSelect(inverseIsZero, Vector <float> .Zero, Vector <float> .One / inverseEffectiveMass);

            //Note that friction constraints have no bias velocity. They target zero velocity.
        }
예제 #2
0
 public static void Solve(ref Vector3Wide angularJacobianA, ref BodyInertias inertiaA, ref BodyInertias inertiaB, ref TwistFrictionProjection projection,
                          ref Vector <float> maximumImpulse, ref Vector <float> accumulatedImpulse, ref BodyVelocities wsvA, ref BodyVelocities wsvB)
 {
     ComputeCorrectiveImpulse(ref angularJacobianA, ref projection, ref wsvA, ref wsvB, ref maximumImpulse, ref accumulatedImpulse, out var correctiveCSI);
     ApplyImpulse(ref angularJacobianA, ref inertiaA, ref inertiaB, ref correctiveCSI, ref wsvA, ref wsvB);
 }
예제 #3
0
        public static void ComputeCorrectiveImpulse(ref Vector3Wide angularJacobianA, ref TwistFrictionProjection projection,
                                                    ref BodyVelocities wsvA, ref BodyVelocities wsvB, ref Vector <float> maximumImpulse,
                                                    ref Vector <float> accumulatedImpulse, out Vector <float> correctiveCSI)
        {
            Vector3Wide.Dot(ref wsvA.AngularVelocity, ref angularJacobianA, out var csvA);
            Vector3Wide.Dot(ref wsvB.AngularVelocity, ref angularJacobianA, out var negatedCSVB);
            var negativeCSI = (csvA + negatedCSVB) * projection.EffectiveMass; //Since there is no bias or softness to give us the negative, we just do it when we apply to the accumulated impulse.

            var previousAccumulated = accumulatedImpulse;

            //The maximum force of friction depends upon the normal impulse.
            accumulatedImpulse = Vector.Min(maximumImpulse, Vector.Max(-maximumImpulse, accumulatedImpulse - negativeCSI));

            correctiveCSI = accumulatedImpulse - previousAccumulated;
        }