X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FInterpolator.hh;h=5c9f09788172cb62fd21f03ff4fc748b76b7498e;hp=2c33844262db6835cc5eaf02258f09cf5d11d767;hb=3f6e44698c38b74bb622ad81ea9d2daa636981d2;hpb=29e3d45f7bbbf31eadf793c41ff2b3d9c47b7539 diff --git a/src/Moof/Interpolator.hh b/src/Moof/Interpolator.hh index 2c33844..5c9f097 100644 --- a/src/Moof/Interpolator.hh +++ b/src/Moof/Interpolator.hh @@ -29,53 +29,59 @@ #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: + + virtual ~Interpolator() {} + typedef enum { STOP = 0, @@ -85,81 +91,92 @@ 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: + + virtual ~InterpolatorBase() {} + void init(Scalar seconds = 1.0, Mode mode = STOP) { Interpolator::init(seconds, mode); calculate(0.0); // set value - previous_ = value_; + 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); @@ -174,16 +191,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); @@ -194,27 +211,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) { @@ -224,8 +245,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); } @@ -233,12 +254,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; }; @@ -246,20 +268,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