cleaned up interpolator classes
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Thu, 21 Jan 2010 23:20:16 +0000 (16:20 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Thu, 21 Jan 2010 23:20:16 +0000 (16:20 -0700)
data/yoinkrc
src/GameLayer.cc
src/GameState.hh
src/Main.cc
src/Main.hh
src/Moof/Interpolator.hh
src/Moof/Log.cc
src/Moof/Video.cc
src/TitleLayer.cc

index 36b6e58d5ea9e9e982fc33ced1e2a65b4edbd140..13be9a754ef7fd7990c8146ae1b437ad9a0cd795 100644 (file)
@@ -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}
 
index 493aa6cfa5392334c6c4165edfcc0e7c5f0e948a..6db27b16bb8b34011f9a6829c3ea81eca711d81f 100644 (file)
@@ -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();
 }
index f69a6b055551e9c36f44d0bb27ff6544abc2cbea..bc59eaff30cd2b1c168a8918a5a76cf0d6c96590 100644 (file)
@@ -53,7 +53,7 @@ struct GameState
        HeroineP                heroine;
        SceneP                  scene;
 
-       Mf::PolynomialInterpolator<5> interp;
+       Mf::Lerp                interp;
 
        Mf::Camera              camera;
 };
index 2cd0f0c08aaf87f62fe3a2ba99c17684a0309a60..510a9b1b3a1e8bedc3f78926859842e32f3d8785 100644 (file)
@@ -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
index 1e9ecc9a29a755b569424d29178769eb54b47e3b..78d3b710a8eb9e0f0d36a952ea411f0a72763547 100644 (file)
@@ -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;
 };
index 5c9f09788172cb62fd21f03ff4fc748b76b7498e..e49ac694c2d0c3876c3b0028ca46e85e6131e462 100644 (file)
 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 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
index 783aec5087d22a29e3009c305767502f4e16458e..863ab87317c6cc9f2e7235877a1fa7d0818c8147 100644 (file)
@@ -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()
index 9e74acbf2b75dae0b09cb53f17883ed1eb4063b8..62addb406dc804b7a31644ef586b3a43b3dd1dce 100644 (file)
@@ -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 "
index 9c609137ce45187977ad1d105cdded4d58a41ffb..afe13e91771a5f3ac2e7b7edb3639e2a1a124d91 100644 (file)
 
 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<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;
        }
 
This page took 0.037299 seconds and 4 git commands to generate.