/*
	Twilight Prophecy 3D/Multimedia SDK
	A multi-platform development system for virtual reality and multimedia.

	Copyright (C) 1997-2001 by Twilight 3D Finland Oy Ltd.
*/
#ifndef PRMATH_SPLINE_HPP
#define PRMATH_SPLINE_HPP



namespace prmath
{
	
	class Spline
	{
		public:

		Spline() {}
		Spline(float time);

		void	SetTime(float time);
		float	GetBezier(float a, float b, float c, float d) const;
		float	GetCatmull(float a, float b, float c, float d) const;
		float	GetBiCubic(float a, float b, float c, float d) const;
		float	GetBSpline(float a, float b, float c, float d) const;

		private:
		
		float	t, t2, t3;
	};


inline Spline::Spline(float time)
{
	SetTime( time );
}

inline void Spline::SetTime(float time)
{
	t = time;
	t2 = time * time;
	t3 = t2 * time;
}

inline float Spline::GetBezier(float a, float b, float c, float d) const
{
	float tp1 = 1 - t;
	float tp2 = tp1 * tp1;
	return a * tp2 * tp1 + b * 3 * tp2 * t + c * 3 * tp1 * t2 + d * t * t2;
}

inline float Spline::GetCatmull(float a, float b, float c, float d) const
{
	float a5 = a * -0.5f;
	float d5 = d * 0.5f;
	return (float)(t3 * (a5 + 1.5*b - 1.5*c + d5) + t2 * (a - 2.5*b + 2*c - d5) + t * (a5 + 0.5*c) + b);
}

inline float Spline::GetBiCubic(float a, float b, float c, float d) const
{
	float s1 = c - a;
	float s2 = d - b;
	return t3 * (2*b - 2*c + s1 + s2) + t2 * (-3*b + 3*c - 2*s1 - s2) + t * s1 + b;
}

inline float Spline::GetBSpline(float a, float b, float c, float d) const
{
	float c3 = c * 3;
	float a3 = a * 3;
	return ( t3 * (-a + 3*b - c3 + d) + t2 * (a3 - 6*b + c3) + t * (-a3 + c3) + (a + 4*b + c) ) * (1/(float)6);
}
	
} // namespace prmath



#endif