namespace Mf {
-// TODO - cleanup these classes
-
-class Interpolator
-{
- void clamp(Scalar& value)
- {
- if (value > 1.0)
- {
- switch (mMode)
- {
- case STOP:
- value = 1.0;
- mDone = true;
- break;
- case REPEAT:
- value -= 1.0;
- break;
- case OSCILLATE:
- value = 2.0 - value;
- mScale *= -1.0;
- break;
- }
- }
- else if (value < 0.0)
- {
- switch (mMode)
- {
- case STOP:
- value = 0.0;
- mDone = true;
- break;
- case REPEAT:
- value += 1.0;
- break;
- case OSCILLATE:
- value = -value;
- mScale *= -1.0;
- break;
- }
- }
- }
-
-public:
-
- virtual ~Interpolator() {}
+namespace Interp {
typedef enum
{
OSCILLATE = 2
} Mode;
- void init(Scalar seconds = 1.0, Mode mode = STOP)
+} // namespace Interp
+
+
+template <class T>
+class Interpolator : public T
+{
+public:
+
+ Interpolator(Scalar t = 1.0, Interp::Mode mode = Interp::STOP)
{
- mScale = 1.0 / seconds;
- mAlpha = 0.0;
- setMode(mode);
+ reset(t, mode);
}
-
- void setMode(Mode mode)
+ void reset(Scalar t = 1.0, Interp::Mode mode = Interp::STOP)
{
+ mAlpha = 0.0;
+ mScale = 1.0 / t;
mMode = mode;
- mDone = false;
+ mIsDone = false;
}
-
void update(Scalar t, Scalar dt)
{
- if (!mDone)
+ if (!mIsDone)
{
+ mPrevState = T::getValue();
mAlpha += dt * mScale;
- clamp(mAlpha);
- calculate(mAlpha);
+ clamp();
+ if (mPrevState == T::calculate(mAlpha)) mIsDone = true;
}
}
- bool isDone() const
- {
- return mDone;
- }
-
- virtual void calculate(Scalar alpha) = 0;
-
-private:
-
- Scalar mAlpha;
- Mode mMode;
- Scalar mScale;
- bool mDone;
-};
-
-template <class T = Scalar>
-class InterpolatorBase : public Interpolator
-{
-public:
-
- virtual ~InterpolatorBase() {}
-
- void init(Scalar seconds = 1.0, Mode mode = STOP)
+ typename T::Type getState(Scalar alpha) const
{
- Interpolator::init(seconds, mode);
-
- calculate(0.0); // set value
- mPrevious = mValue;
+ return cml::lerp(mPrevState, T::getValue(), alpha);
}
- void calculate(Scalar alpha)
- {
- mPrevious = mValue;
- calculate(mValue, alpha);
- }
-
- virtual void calculate(T& value, Scalar alpha) = 0;
-
- const T& getValue() const
- {
- return mValue;
- }
-
- const T getState(Scalar alpha) const
+ bool isDone() const
{
- return cml::lerp(mPrevious, mValue, alpha);
+ return mIsDone;
}
private:
- T mValue;
- T mPrevious;
-};
-
-
-template <int D, class T = Scalar>
-class PolynomialInterpolator : public InterpolatorBase<T>
-{
-public:
-
- PolynomialInterpolator() {}
-
- PolynomialInterpolator(const T coefficients[D+1],
- Scalar seconds = 1.0, Interpolator::Mode mode = Interpolator::STOP)
- {
- init(coefficients, seconds, mode);
- }
-
- void init(const T coefficients[D+1], Scalar seconds = 1.0,
- Interpolator::Mode mode = Interpolator::STOP)
+ void clamp()
{
- Scalar fac[D+1];
-
- fac[0] = 1.0;
- fac[1] = 1.0;
-
- // build an array of the computed factorials we will need
- for (int i = 2; i <= D; ++i)
+ if (mAlpha > 1.0)
{
- fac[i] = i * fac[i - 1];
- }
-
- // combine the coefficients for fast updating
- for (int i = 0; i <= D; ++i)
- {
- // n! / (k! * (n - k)!)
- mCoefficients[i] = coefficients[i] * fac[D] / (fac[i] * fac[D - i]);
+ switch (mMode)
+ {
+ case Interp::STOP:
+ mAlpha = SCALAR(1.0);
+ break;
+ case Interp::REPEAT:
+ mAlpha -= SCALAR(1.0);
+ break;
+ case Interp::OSCILLATE:
+ mAlpha = SCALAR(2.0) - mAlpha;
+ mScale = -mScale;
+ break;
+ }
}
-
- InterpolatorBase<T>::init(seconds, mode);
- }
-
-
- void calculate(T& value, Scalar alpha)
- {
- Scalar beta = 1.0 - alpha;
-
- value = mCoefficients[0] * std::pow(beta, D);
-
- for (int i = 1; i <= D; ++i)
+ else if (mAlpha < 0.0)
{
- value += mCoefficients[i] * std::pow(beta, D - i) *
- std::pow(alpha, i);
+ switch (mMode)
+ {
+ case Interp::STOP:
+ mAlpha = SCALAR(0.0);
+ break;
+ case Interp::REPEAT:
+ mAlpha += SCALAR(1.0);
+ break;
+ case Interp::OSCILLATE:
+ mAlpha = -mAlpha;
+ mScale = -mScale;
+ break;
+ }
}
}
-private:
+ Scalar mAlpha;
+ Scalar mScale;
+ Interp::Mode mMode;
+ bool mIsDone;
- T mCoefficients[D+1];
+ typename T::Type mPrevState;
};
-// specialized linear interpolator
-
-template <class T>
-class PolynomialInterpolator<1,T> : public InterpolatorBase<T>
+template <typename T = Scalar>
+class Linear
{
public:
- PolynomialInterpolator() {}
+ typedef T Type;
- PolynomialInterpolator(const T coefficients[2], Scalar seconds = 1.0,
- Interpolator::Mode mode = Interpolator::STOP)
- //InterpolatorBase<T>(seconds, mode)
+ void init(const Type& a, const Type& b)
{
- init(coefficients, seconds, mode);
+ mStart = a;
+ mFinish = b;
}
- void init(const T coefficients[2], Scalar seconds = 1.0,
- Interpolator::Mode mode = Interpolator::STOP)
+ const Type& calculate(Scalar alpha)
{
- mA = coefficients[0];
- mB = coefficients[1];
-
- InterpolatorBase<T>::init(seconds, mode);
+ mState = cml::lerp(mStart, mFinish, alpha);
+ return mState;
}
-
- void calculate(T& value, Scalar alpha)
+ const Type& getValue() const
{
- value = cml::lerp(mA, mB, alpha);
+ return mState;
}
private:
- T mA;
- T mB;
+ Type mState;
+ Type mStart;
+ Type mFinish;
};
-// Here are some aliases for more common interpolators. Also see the
-// interpolation functions in cml for other types of interpolation such as
-// slerp and some multi-alpha interpolators.
-
-typedef PolynomialInterpolator<1> Lerp; // linear
-typedef PolynomialInterpolator<1,Vector2> Lerp2;
-typedef PolynomialInterpolator<1,Vector3> Lerp3;
-typedef PolynomialInterpolator<1,Vector4> Lerp4;
-
-typedef PolynomialInterpolator<2> Qerp; // quadratic
-typedef PolynomialInterpolator<2,Vector2> Qerp2;
-typedef PolynomialInterpolator<2,Vector3> Qerp3;
-typedef PolynomialInterpolator<2,Vector4> Qerp4;
-
-typedef PolynomialInterpolator<3> Cerp; // cubic
-typedef PolynomialInterpolator<3,Vector2> Cerp2;
-typedef PolynomialInterpolator<3,Vector3> Cerp3;
-typedef PolynomialInterpolator<3,Vector4> Cerp4;
+typedef Interpolator< Linear<Scalar> > Lerp;
} // namespace Mf
void TitleLayer::addedToCore()
{
- Mf::Scalar coeff[] = {0.0, 1.0};
- mFadeIn.init(coeff, 0.1);
+ mFadeIn.init(0.0, 1.0);
+ mFadeIn.reset(0.1);
mGameLayer = GameLayer::alloc();
}
void TitleLayer::update(Mf::Scalar t, Mf::Scalar dt)
{
- if (!mFadeIn.isDone()) mFadeIn.update(t, dt);
+ mFadeIn.update(t, dt);
}
void TitleLayer::draw(Mf::Scalar alpha) const
switch (event.type)
{
case SDL_KEYUP:
- //if (event.key.keysym.sym == SDLK_ESCAPE)
- //{
- //break;
- //}
+ if (event.key.keysym.sym == SDLK_ESCAPE)
+ {
+ break;
+ }
Mf::LayerP titleLayer = Mf::core.pop(this);
- //core.pushLayer(GameLayer::alloc());
- Mf::Scalar coeff[] = {0.0, 0.75, 0.99, 1.0};
- Mf::PolynomialInterpolator<3> interp(coeff, 0.1);
+ Mf::Lerp interp(0.1);
+ interp.init(0.0, 1.0);
- //Mf::LayerP mGameLayer = GameLayer::alloc();
- Mf::Transition<Mf::PolynomialInterpolator<3> >::Ptr transition =
- Mf::Transition<Mf::PolynomialInterpolator<3> >::alloc(mGameLayer, titleLayer, interp);
+ Mf::Transition<Mf::Lerp>::Ptr transition =
+ Mf::Transition<Mf::Lerp>::alloc(mGameLayer, titleLayer, interp);
Mf::core.push(transition);
+
return true;
}