From 4f9eb9259092994de9690cf12f11437c35a6791e Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Thu, 21 Jan 2010 16:20:16 -0700 Subject: [PATCH] cleaned up interpolator classes --- data/yoinkrc | 5 +- src/GameLayer.cc | 4 +- src/GameState.hh | 2 +- src/Main.cc | 4 +- src/Main.hh | 2 +- src/Moof/Interpolator.hh | 259 +++++++++++---------------------------- src/Moof/Log.cc | 2 +- src/Moof/Video.cc | 11 +- src/TitleLayer.cc | 25 ++-- 9 files changed, 97 insertions(+), 217 deletions(-) diff --git a/data/yoinkrc b/data/yoinkrc index 36b6e58..13be9a7 100644 --- a/data/yoinkrc +++ b/data/yoinkrc @@ -50,8 +50,9 @@ resizable = true -- Set the screen resolution or size of the window. The value is an array -- with three number elements representing the width, height, and bits per -- pixel that make up the video mode. If the fullscreen option is set, the --- default behavior is to pick a native resolution. Otherwise, the game --- window will default to 800x600. +-- default behavior is to pick a native resolution. You can use the +-- videomode to override the default resolution. If the fullscreen option +-- is false, videomode will determine the size of the window. videomode = {800, 600} diff --git a/src/GameLayer.cc b/src/GameLayer.cc index 493aa6c..6db27b1 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -124,8 +124,8 @@ GameLayer::GameLayer() : mState.heroine = Heroine::alloc(); mState.heroine->animation.startSequence("FlyDiagonallyUp"); - Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0}; - mState.interp.init(a, 5.0, Mf::Interpolator::OSCILLATE); + mState.interp.init(0.0, 1.0); + mState.interp.reset(4.0, Mf::Interp::OSCILLATE); setProjection(); } diff --git a/src/GameState.hh b/src/GameState.hh index f69a6b0..bc59eaf 100644 --- a/src/GameState.hh +++ b/src/GameState.hh @@ -53,7 +53,7 @@ struct GameState HeroineP heroine; SceneP scene; - Mf::PolynomialInterpolator<5> interp; + Mf::Lerp interp; Mf::Camera camera; }; diff --git a/src/Main.cc b/src/Main.cc index 2cd0f0c..510a9b1 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -53,7 +53,7 @@ Main::Main() { mDispatchHandler = Mf::core.addHandler("video.newcontext", - boost::bind(&Main::contextRecreated)); + boost::bind(&Main::contextCreated)); setupGL(); } @@ -195,7 +195,7 @@ void Main::setupGL() //glMatrixMode(GL_MODELVIEW); } -void Main::contextRecreated() +void Main::contextCreated() { // whenever the context is destroyed and a new one created, it probably // won't contain our state so we need to set that up again diff --git a/src/Main.hh b/src/Main.hh index 1e9ecc9..78d3b71 100644 --- a/src/Main.hh +++ b/src/Main.hh @@ -76,7 +76,7 @@ private: * Set OpenGL to a state we can know and depend on. */ static void setupGL(); - static void contextRecreated(); + static void contextCreated(); Mf::Dispatch::Handler mDispatchHandler; }; diff --git a/src/Moof/Interpolator.hh b/src/Moof/Interpolator.hh index 5c9f097..e49ac69 100644 --- a/src/Moof/Interpolator.hh +++ b/src/Moof/Interpolator.hh @@ -36,51 +36,7 @@ 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 { @@ -89,199 +45,128 @@ public: OSCILLATE = 2 } Mode; - void init(Scalar seconds = 1.0, Mode mode = STOP) +} // namespace Interp + + +template +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 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 -class PolynomialInterpolator : public InterpolatorBase -{ -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::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 PolynomialInterpolator<1,T> : public InterpolatorBase +template +class Linear { public: - PolynomialInterpolator() {} + typedef T Type; - PolynomialInterpolator(const T coefficients[2], Scalar seconds = 1.0, - Interpolator::Mode mode = Interpolator::STOP) - //InterpolatorBase(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::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 > Lerp; } // namespace Mf diff --git a/src/Moof/Log.cc b/src/Moof/Log.cc index 783aec5..863ab87 100644 --- a/src/Moof/Log.cc +++ b/src/Moof/Log.cc @@ -40,7 +40,7 @@ Log::Level Log::gLevel = Log::INFO; void Log::setLevel(Level level) { - if (level != 0) gLevel = level; + gLevel = level; } Log::Level Log::getLevel() diff --git a/src/Moof/Video.cc b/src/Moof/Video.cc index 9e74acb..62addb4 100644 --- a/src/Moof/Video.cc +++ b/src/Moof/Video.cc @@ -131,15 +131,12 @@ void Video::setVideoMode(const long mode[3]) mAttribs.mode[1] = mode[1]; mAttribs.mode[2] = mode[2]; -#if defined(_WIN32) || defined(__WIN32__) - // on win32, creating a new context via SDL_SetVideoMode will wipe - // out the GL state, so we gotta notify everyone to reload their - // state after the change - core.dispatch("video.newcontext"); +#if !defined(linux) && !defined(__linux) && !defined(__linux__) logInfo("video context recreated"); + core.dispatch("video.newcontext"); #endif } - else throw Error(Error::SDL_VIDEOMODE); + else Error(Error::SDL_VIDEOMODE).raise(); } } @@ -383,8 +380,6 @@ Video::Attributes::Attributes() } else { - while (*(modes + 1)) ++modes; // skip to the last - mode[0] = (*modes)->w; mode[1] = (*modes)->h; Mf::logInfo << "choosing native resolution " diff --git a/src/TitleLayer.cc b/src/TitleLayer.cc index 9c60913..afe13e9 100644 --- a/src/TitleLayer.cc +++ b/src/TitleLayer.cc @@ -36,15 +36,15 @@ 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 @@ -58,21 +58,20 @@ bool TitleLayer::handleEvent(const Mf::Event& event) 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 >::Ptr transition = - Mf::Transition >::alloc(mGameLayer, titleLayer, interp); + Mf::Transition::Ptr transition = + Mf::Transition::alloc(mGameLayer, titleLayer, interp); Mf::core.push(transition); + return true; } -- 2.43.0