X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FInterpolator.hh;h=7ad38fe9d4ce22fafd7c98baf66db9226dc62c41;hp=87e3acdbcf26a517fdaaa84cfbdac1c8de1c98d4;hb=71bd9dbaf1c1e3c55a9f63392a73865d8aeee7d4;hpb=c2321281bf12a7efaedde930422c7ddbc92080d4 diff --git a/src/Moof/Interpolator.hh b/src/Moof/Interpolator.hh index 87e3acd..7ad38fe 100644 --- a/src/Moof/Interpolator.hh +++ b/src/Moof/Interpolator.hh @@ -29,51 +29,57 @@ #ifndef _MOOF_INTERPOLATOR_HH_ #define _MOOF_INTERPOLATOR_HH_ +#include +#include + namespace Mf { +// TODO - cleanup these classes + class Interpolator { void clamp(Scalar& value) { if (value > 1.0) { - switch (mode_) + switch (mMode) { case STOP: value = 1.0; - stopped_ = true; + mDone = true; break; case REPEAT: value -= 1.0; break; case OSCILLATE: value = 2.0 - value; - scale_ *= -1.0; + mScale *= -1.0; break; } } else if (value < 0.0) { - switch (mode_) + switch (mMode) { case STOP: value = 0.0; - stopped_ = true; + mDone = true; break; case REPEAT: value += 1.0; break; case OSCILLATE: value = -value; - scale_ *= -1.0; + mScale *= -1.0; break; } } } public: + typedef enum { STOP = 0, @@ -83,81 +89,90 @@ public: void init(Scalar seconds = 1.0, Mode mode = STOP) { - scale_ = 1.0 / seconds; - alpha_ = 0.0; + mScale = 1.0 / seconds; + mAlpha = 0.0; setMode(mode); } void setMode(Mode mode) { - mode_ = mode; - stopped_ = false; + mMode = mode; + mDone = false; } - void update(Scalar dt) + void update(Scalar t, Scalar dt) { - if (!stopped_) + if (!mDone) { - alpha_ += dt * scale_; - clamp(alpha_); - calculate(alpha_); + mAlpha += dt * mScale; + clamp(mAlpha); + calculate(mAlpha); } } + bool isDone() const + { + return mDone; + } + virtual void calculate(Scalar alpha) = 0; private: - Scalar alpha_; - Mode mode_; - Scalar scale_; - bool stopped_; + + Scalar mAlpha; + Mode mMode; + Scalar mScale; + bool mDone; }; -template +template class InterpolatorBase : public Interpolator { public: + void init(Scalar seconds = 1.0, Mode mode = STOP) { Interpolator::init(seconds, mode); calculate(0.0); // set value - calculate(0.0); // set previous + mPrevious = mValue; } void calculate(Scalar alpha) { - previous_ = value_; - calculate(value_, alpha); + mPrevious = mValue; + calculate(mValue, alpha); } virtual void calculate(T& value, Scalar alpha) = 0; - const T& getValue() + const T& getValue() const { - return value_; + return mValue; } - const T getState(Scalar alpha) + const T getState(Scalar alpha) const { - return cml::lerp(previous_, value_, alpha); + return cml::lerp(mPrevious, mValue, alpha); } private: - T value_; - T previous_; + + T mValue; + T mPrevious; }; -template -class BinomialInterpolator : public InterpolatorBase +template +class PolynomialInterpolator : public InterpolatorBase { public: - BinomialInterpolator() {} - explicit BinomialInterpolator(const T coefficients[D+1], + PolynomialInterpolator() {} + + PolynomialInterpolator(const T coefficients[D+1], Scalar seconds = 1.0, Interpolator::Mode mode = Interpolator::STOP) { init(coefficients, seconds, mode); @@ -172,16 +187,16 @@ public: fac[1] = 1.0; // build an array of the computed factorials we will need - for (int i = 2; i <= D; i++) + for (int i = 2; i <= D; ++i) { fac[i] = i * fac[i - 1]; } // combine the coefficients for fast updating - for (int i = 0; i <= D; i++) + for (int i = 0; i <= D; ++i) { // n! / (k! * (n - k)!) - coefficients_[i] = coefficients[i] * fac[D] / (fac[i] * fac[D - i]); + mCoefficients[i] = coefficients[i] * fac[D] / (fac[i] * fac[D - i]); } InterpolatorBase::init(seconds, mode); @@ -192,27 +207,31 @@ public: { Scalar beta = 1.0 - alpha; - value = coefficients_[0] * std::pow(beta, D); + value = mCoefficients[0] * std::pow(beta, D); - for (int i = 1; i <= D; i++) + for (int i = 1; i <= D; ++i) { - value += coefficients_[i] * std::pow(beta, D - i) * + value += mCoefficients[i] * std::pow(beta, D - i) * std::pow(alpha, i); } } private: - T coefficients_[D+1]; + + T mCoefficients[D+1]; }; +// specialized linear interpolator + template -class BinomialInterpolator : public InterpolatorBase +class PolynomialInterpolator<1,T> : public InterpolatorBase { public: - BinomialInterpolator() {} - explicit BinomialInterpolator(const T coefficients[2], Scalar seconds = 1.0, + PolynomialInterpolator() {} + + PolynomialInterpolator(const T coefficients[2], Scalar seconds = 1.0, Interpolator::Mode mode = Interpolator::STOP) //InterpolatorBase(seconds, mode) { @@ -222,8 +241,8 @@ public: void init(const T coefficients[2], Scalar seconds = 1.0, Interpolator::Mode mode = Interpolator::STOP) { - a_ = coefficients[0]; - b_ = coefficients[1]; + mA = coefficients[0]; + mB = coefficients[1]; InterpolatorBase::init(seconds, mode); } @@ -231,12 +250,13 @@ public: void calculate(T& value, Scalar alpha) { - value = cml::lerp(a_, b_, alpha); + value = cml::lerp(mA, mB, alpha); } private: - T a_; - T b_; + + T mA; + T mB; }; @@ -244,20 +264,20 @@ private: // interpolation functions in cml for other types of interpolation such as // slerp and some multi-alpha interpolators. -typedef BinomialInterpolator Lerps; // linear -typedef BinomialInterpolator Lerpv2; -typedef BinomialInterpolator Lerpv3; -typedef BinomialInterpolator Lerpv4; +typedef PolynomialInterpolator<1> Lerp; // linear +typedef PolynomialInterpolator<1,Vector2> Lerp2; +typedef PolynomialInterpolator<1,Vector3> Lerp3; +typedef PolynomialInterpolator<1,Vector4> Lerp4; -typedef BinomialInterpolator Qerps; // quadratic -typedef BinomialInterpolator Qerpv2; -typedef BinomialInterpolator Qerpv3; -typedef BinomialInterpolator Qerpv4; +typedef PolynomialInterpolator<2> Qerp; // quadratic +typedef PolynomialInterpolator<2,Vector2> Qerp2; +typedef PolynomialInterpolator<2,Vector3> Qerp3; +typedef PolynomialInterpolator<2,Vector4> Qerp4; -typedef BinomialInterpolator Cerps; // cubic -typedef BinomialInterpolator Cerpv2; -typedef BinomialInterpolator Cerpv3; -typedef BinomialInterpolator Cerpv4; +typedef PolynomialInterpolator<3> Cerp; // cubic +typedef PolynomialInterpolator<3,Vector2> Cerp2; +typedef PolynomialInterpolator<3,Vector3> Cerp3; +typedef PolynomialInterpolator<3,Vector4> Cerp4; } // namespace Mf