public void Integrate(double duration) { if (duration == 0.0) { throw new InvalidDurationException("Duration can not be zero"); } // Start by using gravity - this is already an acceleration so don't convert from a force var resultingAcceleration = new Vector3(GravityAcceleration); // Work out the acceleration from the force resultingAcceleration.AddScaledVector(AccumulatedForce, InverseMass); // Update position - for the moment we are using full equation - make accn bit configurable? Position.AddScaledVector(Velocity, duration); Position.AddScaledVector(resultingAcceleration, (duration * duration) / 2.0f); // Update the velocity Velocity.AddScaledVector(resultingAcceleration, duration); // Impose drag if there is damping - we are using the full equation for now - make configurable? if (Damping != 1.0f) { Velocity *= Math.Pow(Damping, duration); } // Clear the forces ClearAccumulatedForce(); }
/// <summary> /// Integrates the particle forward in time by the given amount. /// This function uses a Newton-Euler integration method, which is a /// Linear approximation of the correct integral. For this reason it /// May be inaccurate in some cases. /// /// We integrate, because we want to figure out what the next position /// Should be in time given the current velocity. /// /// We also want to figure velocity based on current acceleration, with /// Some damping added to make the physics simulation more stable. /// </summary> /// <param name="timeDuration">Time since last frame in seconds</param> public void Integrate(float timeDuration) { // Zero out stuff ForceAccum = new Vector3(); // Update linear position Position.AddScaledVector(Velocity, timeDuration); // Update velocity Vector3 resulintAcc = Acceleration; resulintAcc.AddScaledVector(ForceAccum, InverseMass); Velocity.AddScaledVector(resulintAcc, timeDuration); Velocity *= (float)Math.Pow(Damping, timeDuration); // Update linked mesh LinkedMesh.Position = new vec3(Position.X, Position.Y, Position.Z); }