
class BezierInterpolator3
{
	Vector3 _p0;
	Vector3 _p1;
	Vector3 _p2;

	void Set(const Vector3&in p0, const Vector3&in p1, const Vector3&in p2)
	{
		_p0 = p0;
		_p1 = p1;
		_p2 = p2;
	}

	Vector3 Get(float t)
	{
		Vector3 a01 = _p0.Lerp(_p1, t);
		Vector3 a12 = _p1.Lerp(_p2, t);
		Vector3 b01 = a01.Lerp(a12, t);
		return b01;
	}
}

class BezierInterpolator4
{
	Vector3 _p0;
	Vector3 _p1;
	Vector3 _p2;
	Vector3 _p3;

	void Set(const Vector3&in p0, const Vector3&in p1, const Vector3&in p2, const Vector3&in p3)
	{
		_p0 = p0;
		_p1 = p1;
		_p2 = p2;
		_p3 = p3;
	}

	Vector3 Get(float t)
	{
		Vector3 a01 = _p0.Lerp(_p1, t);
		Vector3 a12 = _p1.Lerp(_p2, t);
		Vector3 a23 = _p2.Lerp(_p3, t);
		Vector3 b01 = a01.Lerp(a12, t);
		Vector3 b12 = a12.Lerp(a23, t);
		Vector3 c01 = b01.Lerp(b12, t);
		return c01;
	}
}

class BezierInterpolator5
{
	Vector3 _p0;
	Vector3 _p1;
	Vector3 _p2;
	Vector3 _p3;
	Vector3 _p4;

	void Set(const Vector3&in p0, const Vector3&in p1, const Vector3&in p2, const Vector3&in p3, const Vector3&in p4)
	{
		_p0 = p0;
		_p1 = p1;
		_p2 = p2;
		_p3 = p3;
		_p4 = p4;		
	}

	Vector3 Get(float t)
	{
		Vector3 a01 = _p0.Lerp(_p1, t);
		Vector3 a12 = _p1.Lerp(_p2, t);
		Vector3 a23 = _p2.Lerp(_p3, t);
		Vector3 a34 = _p3.Lerp(_p4, t);
		Vector3 b01 = a01.Lerp(a12, t);
		Vector3 b12 = a12.Lerp(a23, t);
		Vector3 b23 = a23.Lerp(a34, t);	
		Vector3 c01 = b01.Lerp(b12, t);
		Vector3 c12 = b12.Lerp(b23, t);	
		Vector3 d01 = c01.Lerp(c12, t);
		return d01;
	}
}

class SmoothMove3 : ScriptObject
{
    Vector3 point_0;
	Vector3 point_1;
	Vector3 point_2;
	float speed = 0.1;
	float _time = 0.0;
	BezierInterpolator3 _bint;

	void Start()
	{	
		_bint = BezierInterpolator3();
		_time = 0.0;
	}

    void Update(float timeStep)
    {
    	_bint.Set(point_0, point_1, point_2);
		_time += timeStep * speed;

		if (_time > 1.0)
		    _time = 0.0;

		Vector3 p = _bint.Get(_time);
        node.position = p;
    }
}

class SmoothMove4 : ScriptObject
{
    Vector3 point_0;
	Vector3 point_1;
	Vector3 point_2;
	Vector3 point_3;
	float speed = 0.1;
	float _time = 0.0;
	BezierInterpolator4 _bint;

	void Start()
	{	
		_bint = BezierInterpolator4();
		_time = 0.0;
	}

    void Update(float timeStep)
    {
    	_bint.Set(point_0, point_1, point_2, point_3);
		_time += timeStep * speed;

		if (_time > 1.0)
		    _time = 0.0;

		Vector3 p = _bint.Get(_time);
        node.position = p;
    }
}

class SmoothMove5 : ScriptObject
{
    Vector3 point_0;
	Vector3 point_1;
	Vector3 point_2;
	Vector3 point_3;
	Vector3 point_4;	
	float speed = 0.1;
	float _time = 0.0;
	BezierInterpolator5 _bint;

	void Start()
	{	
		_bint = BezierInterpolator5();
		_time = 0.0;
	}

    void Update(float timeStep)
    {
    	_bint.Set(point_0, point_1, point_2, point_3, point_4);
		_time += timeStep * speed;

		if (_time > 1.0)
		    _time = 0.0;

		Vector3 p = _bint.Get(_time);
        node.position = p;
    }
}