public void Execute(ref ModifiableJacobianHeader jacHeader, ref ModifiableContactJacobian contactJacobian) { Entity entityA = jacHeader.Entities.EntityA; Entity entityB = jacHeader.Entities.EntityB; ModifyContactJacobians.ModificationType typeA = ModifyContactJacobians.ModificationType.None; if (modificationData.Exists(entityA)) { typeA = modificationData[entityA].type; } ModifyContactJacobians.ModificationType typeB = ModifyContactJacobians.ModificationType.None; if (modificationData.Exists(entityB)) { typeB = modificationData[entityB].type; } { // Check for jacobians we want to ignore: if (typeA == ModifyContactJacobians.ModificationType.DisabledContact || typeB == ModifyContactJacobians.ModificationType.DisabledContact) { jacHeader.Flags = jacHeader.Flags | JacobianFlags.Disabled; } // Check if NoTorque modifier if (typeA == ModifyContactJacobians.ModificationType.NoAngularEffects || typeB == ModifyContactJacobians.ModificationType.NoAngularEffects) { // Disable all friction angular effects var friction0 = contactJacobian.Friction0; friction0.AngularA = 0.0f; friction0.AngularB = 0.0f; contactJacobian.Friction0 = friction0; var friction1 = contactJacobian.Friction1; friction1.AngularA = 0.0f; friction1.AngularB = 0.0f; contactJacobian.Friction1 = friction1; var angularFriction = contactJacobian.AngularFriction; angularFriction.AngularA = 0.0f; angularFriction.AngularB = 0.0f; contactJacobian.AngularFriction = angularFriction; } // Check if SurfaceVelocity present if (jacHeader.HasSurfaceVelocity && (typeA == ModifyContactJacobians.ModificationType.SurfaceVelocity || typeB == ModifyContactJacobians.ModificationType.SurfaceVelocity)) { // Since surface normal can change, make sure angular velocity is always relative to it, not independent float3 angVel = contactJacobian.Normal * (new float3(0.0f, 1.0f, 0.0f)); float3 linVel = float3.zero; Math.CalculatePerpendicularNormalized(contactJacobian.Normal, out float3 dir0, out float3 dir1); float linVel0 = math.dot(linVel, dir0); float linVel1 = math.dot(linVel, dir1); float angVelProj = math.dot(angVel, contactJacobian.Normal); //jacHeader.SurfaceVelocity = new SurfaceVelocity { ExtraFrictionDv = new float3(linVel0, linVel1, angVelProj) }; } /* * // Check if MaxImpulse present * if (jacHeader.HasMaxImpulse && * (typeA == ModifyContactJacobians.ModificationType.ClippedImpulse || typeB == ModifyContactJacobians.ModificationType.ClippedImpulse)) * { * // Max impulse in Ns (Newton-second) * jacHeader.MaxImpulse = 20.0f; * } */ // Check if MassFactors present if (jacHeader.HasMassFactors && (typeA == ModifyContactJacobians.ModificationType.InfiniteInertia || typeB == ModifyContactJacobians.ModificationType.InfiniteInertia)) { // Give both bodies infinite inertia jacHeader.MassFactors = new MassFactors { InvInertiaAndMassFactorA = new float4(0.0f, 0.0f, 0.0f, 1.0f), InvInertiaAndMassFactorB = new float4(0.0f, 0.0f, 0.0f, 1.0f) }; } } // Angular jacobian modifications for (int i = 0; i < contactJacobian.NumContacts; i++) { ContactJacAngAndVelToReachCp jacobianAngular = jacHeader.GetAngularJacobian(i); // Check if NoTorque modifier if (typeA == ModifyContactJacobians.ModificationType.NoAngularEffects || typeB == ModifyContactJacobians.ModificationType.NoAngularEffects) { // Disable all angular effects jacobianAngular.Jac.AngularA = 0.0f; jacobianAngular.Jac.AngularB = 0.0f; } // Check if SoftContact modifier if (typeA == ModifyContactJacobians.ModificationType.SoftContact || typeB == ModifyContactJacobians.ModificationType.SoftContact) { jacobianAngular.Jac.EffectiveMass *= 0.1f; if (jacobianAngular.VelToReachCp > 0.0f) { jacobianAngular.VelToReachCp *= 0.5f; } } jacHeader.SetAngularJacobian(i, jacobianAngular); } }
// Don't do anything for triggers public void Execute(ref ModifiableJacobianHeader h, ref ModifiableTriggerJacobian j) { }
public void Execute(ref ModifiableJacobianHeader jacHeader, ref ModifiableContactJacobian contactJacobian) { Entity entityA = jacHeader.EntityA; Entity entityB = jacHeader.EntityB; ModifyContactJacobians.ModificationType typeA = ModifyContactJacobians.ModificationType.None; if (modificationData.HasComponent(entityA)) { typeA = modificationData[entityA].type; } ModifyContactJacobians.ModificationType typeB = ModifyContactJacobians.ModificationType.None; if (modificationData.HasComponent(entityB)) { typeB = modificationData[entityB].type; } { // Check for jacobians we want to ignore: if (typeA == ModifyContactJacobians.ModificationType.DisabledContact || typeB == ModifyContactJacobians.ModificationType.DisabledContact) { jacHeader.Flags = jacHeader.Flags | JacobianFlags.Disabled; } // Check if NoTorque modifier, or friction should be disabled through jacobian if (typeA == ModifyContactJacobians.ModificationType.NoAngularEffects || typeB == ModifyContactJacobians.ModificationType.NoAngularEffects || typeA == ModifyContactJacobians.ModificationType.DisabledAngularFriction || typeB == ModifyContactJacobians.ModificationType.DisabledAngularFriction) { // Disable all friction angular effects var friction0 = contactJacobian.Friction0; friction0.AngularA = 0.0f; friction0.AngularB = 0.0f; contactJacobian.Friction0 = friction0; var friction1 = contactJacobian.Friction1; friction1.AngularA = 0.0f; friction1.AngularB = 0.0f; contactJacobian.Friction1 = friction1; var angularFriction = contactJacobian.AngularFriction; angularFriction.AngularA = 0.0f; angularFriction.AngularB = 0.0f; contactJacobian.AngularFriction = angularFriction; } // Check if SurfaceVelocity present if (jacHeader.HasSurfaceVelocity && (typeA == ModifyContactJacobians.ModificationType.SurfaceVelocity || typeB == ModifyContactJacobians.ModificationType.SurfaceVelocity)) { // Since surface normal can change, make sure angular velocity is always relative to it, not independent jacHeader.SurfaceVelocity = new SurfaceVelocity { LinearVelocity = float3.zero, AngularVelocity = contactJacobian.Normal * (new float3(0.0f, 1.0f, 0.0f)) }; } // Check if MassFactors present if (jacHeader.HasMassFactors && (typeA == ModifyContactJacobians.ModificationType.InfiniteInertia || typeB == ModifyContactJacobians.ModificationType.InfiniteInertia)) { // Give both bodies infinite inertia jacHeader.MassFactors = new MassFactors { InverseInertiaFactorA = float3.zero, InverseMassFactorA = 1.0f, InverseInertiaFactorB = float3.zero, InverseMassFactorB = 1.0f }; } } // Angular jacobian modifications for (int i = 0; i < contactJacobian.NumContacts; i++) { ContactJacAngAndVelToReachCp jacobianAngular = jacHeader.GetAngularJacobian(i); // Check if NoTorque modifier if (typeA == ModifyContactJacobians.ModificationType.NoAngularEffects || typeB == ModifyContactJacobians.ModificationType.NoAngularEffects) { // Disable all angular effects jacobianAngular.Jac.AngularA = 0.0f; jacobianAngular.Jac.AngularB = 0.0f; } // Check if SoftContact modifier if (typeA == ModifyContactJacobians.ModificationType.SoftContact || typeB == ModifyContactJacobians.ModificationType.SoftContact) { jacobianAngular.Jac.EffectiveMass *= 0.1f; if (jacobianAngular.VelToReachCp > 0.0f) { jacobianAngular.VelToReachCp *= 0.5f; } } jacHeader.SetAngularJacobian(i, jacobianAngular); } }