#pragma once namespace mt { class Path { public: void SetPoints(const List& points); void SetScale(const List& scale); void SetRotation(const List& rotation); vec3 GetPoint(float t) const; float GetScale(float t) const; float GetRotation(float t) const; vec3 GetDirection(float t) const; private: template static void GetValues(const List& source, float& t, T& p0, T& p1, T& p2, T& p3) { auto maxT = source.Count(); auto p1Index = (int)Math::Min(t * maxT, maxT - 1.0f); auto p0Index = (int)Math::Max(p1Index - 1.0f, 0.0f); auto p2Index = (int)Math::Min(p1Index + 1.0f, maxT - 1.0f); auto p3Index = (int)Math::Min(p2Index + 1.0f, maxT - 1.0f); p1 = source[p1Index]; p2 = p1Index == p2Index ? p1 + (p1 - source[p0Index]) : source[p2Index]; p0 = p0Index == p1Index ? p1 - (p2 - p1) : source[p0Index]; p3 = p3Index == p2Index ? p1 + (p2 - p1) : source[p3Index]; t = (t - (1.0f / maxT * p1Index)) / (1.0f / maxT); } static float Spline(float p0, float p1, float p2, float p3, float t); static vec3 Spline(const vec3& p0, const vec3& p1, const vec3& p2, const vec3& p3, float t); private: List points; List rotation; List scale; }; }