Catmull Rom Spline

https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline


// Loop around the total time if necessary
if (elapsedTime >= endTime) {
    if (loop) {
        while (elapsedTime > endTime)
            elapsedTime -= endTime;
    }
    else {
        position = frames[frames.size() - 1].position;
        return;
    }
}

int i = 0;
// Find the index of the current frame
while (frames[i+1].time < elapsedTime) i++;
	
// Find the time since the beginning of this frame
elapsedTime -= frames[i].time;

// Find how far we are between the current and next frame (0 to 1)
float fraction = (float)(elapsedTime / (frames[i + 1].time - frames[i].time));

// Interpolate position and rotation values between frames
position = glm::catmullRom (
                   frames[wrap(i - 1, frames.size() - 1)].position,
                   frames[wrap(i, frames.size() - 1)].position,
                   frames[wrap(i + 1, frames.size() - 1)].position,
                   frames[wrap(i + 2, frames.size() - 1)].position,
                   fraction);
template<typename genType> 
GLM_FUNC_QUALIFIER genType catmullRom(
		genType const& v1,
		genType const& v2,
		genType const& v3,
		genType const& v4,
		typename genType::value_type const& s
	) {
    typename genType::value_type s2 = pow2(s);
    typename genType::value_type s3 = pow3(s);

    typename genType::value_type f1 = -s3 + typename genType::value_type(2) * s2 - s;
    typename genType::value_type f2 = typename genType::value_type(3) * s3 - typename genType::value_type(5) * s2 + typename genType::value_type(2);
    typename genType::value_type f3 = typename genType::value_type(-3) * s3 + typename genType::value_type(4) * s2 + s;
    typename genType::value_type f4 = s3 - s2;

    return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) / typename genType::value_type(2);
}

http://www.lighthouse3d.com/tutorials/maths/catmull-rom-spline/

f(x) = [1, x, x^2, x^3] * M * [v1, v2, v3, v4]

/* Coefficients for Matrix M */
#define M11	 0.0
#define M12	 1.0
#define M13	 0.0
#define M14	 0.0
#define M21	-0.5
#define M22	 0.0
#define M23	 0.5
#define M24	 0.0
#define M31	 1.0
#define M32	-2.5
#define M33	 2.0
#define M34	-0.5
#define M41	-0.5
#define M42	 1.5
#define M43	-1.5
#define M44	 0.5

double catmullRomSpline(float x, float v1,float v2, float v3,float v4) {
	double c1,c2,c3,c4;

	c1 =  	      M12*v2;
	c2 = M21*v1          + M23*v3;
	c3 = M31*v1 + M32*v2 + M33*v3 + M34*v4;
	c4 = M41*v1 + M42*v2 + M43*v3 + M44*v4;

	return(((c4*x + c3)*x +c2)*x + c1);
}