/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef SplineH #define SplineH #include "dumb3d.h" #include "QueryParserComp.hpp" using namespace Math3D; #define B1(t) (t * t * t) #define B2(t) (3 * t * t * (1 - t)) #define B3(t) (3 * t * (1 - t) * (1 - t)) #define B4(t) ((1 - t) * (1 - t) * (1 - t)) #define Interpolate(t, p1, cp1, cp2, p2) (B4(t) * p1 + B3(t) * cp1 + B2(t) * cp2 + B1(t) * p2) class TKnot { public: // inline bool IsCurve() { return (!(Point==CPointIn)); }; // inline vector3 GetDirection() { return (CPointOut-Point); }; TKnot(); TKnot(int n); ~TKnot(); inline float GetRoll(float s) { if (Next) { s /= Length; return ((1 - s) * fRoll + (s)*Next->fRoll); } else return fRoll; // (Length-s) (s-Length) } vector3 GetDirection(float t = 0); inline vector3 InterpolateSegm(float t) { return (Interpolate(t, Point, CPointOut, Next->CPointIn, Next->Point)); }; float GetTFromS(float s); bool Init(TKnot *NNext, TKnot *NPrev); bool InitCPoints(); bool InitLength(); vector3 Point, CPointIn, CPointOut; float fRoll; bool IsCurve; float Length; TKnot *Next, *Prev; float fLengthIn, fLengthOut; bool bSwitchDirectionForward; bool bSwitchDirectionBackward; private: vector3 GetFirstDerivative(float fTime); float RombergIntegral(float fA, float fB); }; class TSpline { public: TSpline(); TSpline(AnsiString asNName); ~TSpline(); bool Create(int n, AnsiString asNName = "foo"); bool AssignKnots(TKnot *FirstKnot, int n); int LoadFromFile(AnsiString FileName, TKnot *FirstKnot = NULL); int Load(TQueryParserComp *Parser, AnsiString asEndString = "endspline"); float GetLength(); vector3 GetCenter(); TKnot * GetLastKnot(); bool Render(); // inline int NextIndex(int n) { return (n