/** * Integrates the particle forward in time by the given amount. * This function uses a Newton-Euler integration method, which is a * linear approximation to the correct integral. For this reason it * may be inaccurate in some cases. */ public void Integrate(double duration) { // We don't integrate things with zero mass. if (inverseMass <= 0.0f) { return; } Debug.Assert(duration > 0.0); // Update linear position. position.AddScaledVector(this.velocity, duration); // Work out the acceleration from the force MyVector3 resultingAcc = acceleration; resultingAcc.AddScaledVector(forceAccum, inverseMass); // Update linear velocity from the acceleration. velocity.AddScaledVector(resultingAcc, duration); // Impose drag. velocity *= System.Math.Pow(damping, duration); // Clear the forces. ClearAccumulator(); }
/** * Integrates the rigid body forward in time by the given amount. * This function uses a Newton-Euler integration method */ public void integrate(real duration) { if (!isAwake) { return; } lastFrameAcceleration = acceleration; lastFrameAcceleration.AddScaledVector(forceAccum, inverseMass); MyVector3 angularAcceleration = inverseInertiaTensorWorld.transform(torqueAccum); velocity.AddScaledVector(lastFrameAcceleration, duration); rotation.AddScaledVector(angularAcceleration, duration); velocity *= Mathf.Pow((float)linearDamping, (float)duration); rotation *= Mathf.Pow((float)angularDamping, (float)duration); position.AddScaledVector(velocity, duration); orientation.addScaledVector(rotation, duration); calculateDerivedData(); clearAccumulators(); if (canSleep) { real currentMotion = velocity.ScalarProduct(velocity) + rotation.ScalarProduct(rotation); real bias = Mathf.Pow(0.5f, (float)duration); motion = bias * motion + (1 - bias) * currentMotion; if (motion < sleepEpsilon) { setAwake(false); } else if (motion > 10 * sleepEpsilon) { motion = 10 * sleepEpsilon; } } }