118 – Game Cameras

In this dev diary I talk about how the camera works in Neverending Nightmares as well as provide some general tips for game cameras.

Here is some sample code for critically damped springs. Spring_Update will always move back to 0 no matter what you set the initial position or velocity to. Spring_Lerp is more useful. It uses that spring to minimize the distance between two points.

These all work in 1 dimension. When moving to multiple dimensions, you can have a spring for each axis, or do a 1D spring lerp on the magnitude of the 3D displacement between values. It really depends on the effect you are looking for.

inline float Spring_Exp( float springFactor_dt )
{
return expf( -springFactor_dt );
}

inline void Spring_Update( float *outPos, float *outVel, float pos, float vel, float springFactor, float dt )
{
// p(dt) = (pos + ( vel + k * pos ) * dt ) * e^(-k*dt)
// B = ( vel + k * pos )
// p(dt) = (pos + B * dt ) * e^(-k*dt)
// take the derivative of the position equation to get the velocity
// v(dt) = B * e^(-k*dt) + -k * e^(-k*dt) * (pos + B * dt )
// v(dt) = e^(-k*dt) * ( B - k * (pos + B * dt ) )
const float springExp = Spring_Exp( springFactor * dt );
const float B = vel + springFactor * pos;
const float Pdt = ( pos + B * dt ) * springExp;
const float Vdt = B * springExp - springFactor * Pdt;
*outPos = Pdt;
*outVel = Vdt;
}

inline void Spring_Lerp( float *outPos, float *outVel, float pos, float vel, float targetPos, float springFactor, float dt )
{
const float diff = pos - targetPos;
float diffDt;
Spring_Update( &diffDt, outVel, diff, vel, springFactor, dt );
*outPos = targetPos + diffDt;
}

2 comments on “118 – Game Cameras
  1. Wikzo says:

    Hey. Thanks for the video. Did you ever post some example code of how your camera/spring system works?

Leave a Reply

Your email address will not be published. Required fields are marked *

*