public static void ComputeSpringiness(ref SpringSettingsWide settings, float dt, float constraintCount, out Vector <float> positionErrorToVelocity, out Vector <float> effectiveMassCFMScale, out Vector <float> softnessImpulseScale) { //The only difference between this implementation and the above implementation is that CFM is scaled by constraintCount. //This is derived from stiffness and damping. Since we want N constraints together to be as stiff as 1 constraint of the given spring settings, //we compute CFM and ERP from stiffness and damping coefficients that are scaled by 1/N. Omitting the derivation, it turns out //that just scales the CFM by N. var frequencyDt = settings.NaturalFrequency * new Vector <float>(dt); var twiceDampingRatio = settings.DampingRatio * new Vector <float>(2f); //Could precompute. positionErrorToVelocity = settings.NaturalFrequency / (frequencyDt + twiceDampingRatio); var extra = new Vector <float>(constraintCount) / (frequencyDt * (frequencyDt + twiceDampingRatio)); effectiveMassCFMScale = Vector <float> .One / (Vector <float> .One + extra); softnessImpulseScale = extra * effectiveMassCFMScale; }
public static void ComputeSpringiness(ref SpringSettingsWide settings, float dt, out Vector <float> positionErrorToVelocity, out Vector <float> effectiveMassCFMScale, out Vector <float> softnessImpulseScale) { //For more information behind these values, check the Inequality1DOF constraint comments. //softenedEffectiveMass = effectiveMass * (1 + (naturalFrequency^2 * dt^2 + 2 * dampingRatio * naturalFrequency * dt)^-1)^-1 //CFM/dt * softenedEffectiveMass: //(naturalFrequency^2 * dt^2 + 2 * dampingRatio * naturalFrequency * dt)^-1 * (1 + (naturalFrequency^2 * dt^2 + 2 * dampingRatio * naturalFrequency * dt)^-1)^-1 //ERP = (naturalFrequency * dt) * (naturalFrequency * dt + 2 * dampingRatio)^-1 //"ERP" is the error reduction per frame. Note that it can never exceed 1 given physically valid input. //Since it is a *per frame* term, note that the position error is additionally scaled by inverseDt to get the target velocity //needed to accomplish the desired error reduction in one frame. var frequencyDt = settings.NaturalFrequency * new Vector <float>(dt); var twiceDampingRatio = settings.DampingRatio * new Vector <float>(2); //Could precompute. positionErrorToVelocity = settings.NaturalFrequency / (frequencyDt + twiceDampingRatio); var extra = Vector <float> .One / (frequencyDt * (frequencyDt + twiceDampingRatio)); effectiveMassCFMScale = Vector <float> .One / (Vector <float> .One + extra); softnessImpulseScale = extra * effectiveMassCFMScale; }