This class is one I turn to it again and again, especially when animating OSD components or creating camera controllers.
What it does is update an object's position and velocity towards a target destination over an arbitrary amount of time. The spring velocity will be damped over time meaning it slows down as it reaches its target.
To use it as a camera spring create one for the camera position and another for the target and update these values every frame, then call Update() passing the frame delta.
using Microsoft.Xna.Framework; namespace Utils { public class CriticallyDampedSpring { public CriticallyDampedSpring() { SmoothTime = 100.0f; } public float SmoothTime { get; set; } public Vector3 Current { get; set; } public Vector3 SpringVelocity { get; set; } public Vector3 Target { get { return mValTo; } set { mValFrom = Current; mValTo = value; } } public void Update(float frameTime) { Vector3 diff, temp; float omega, rX, expo; omega = 2.0f / SmoothTime; rX = omega * frameTime; expo = 1.0f / (1.0f + rX + (kQuadraticCoef * rX * rX) + (kCubicCoef * rX * rX * rX)); diff = mValFrom - mValTo; temp = (SpringVelocity + (diff * omega)) * frameTime; SpringVelocity = (SpringVelocity - (temp * omega)) * expo; Current = mValTo + ((diff + temp) * expo); } // Start position of spring head private Vector3 mValFrom = Vector3.Zero; // Target position of spring head private Vector3 mValTo = Vector3.Zero; private const float kQuadraticCoef = 0.48f; private const float kCubicCoef = 0.235f; } }