]> Dogcows Code - chaz/yoink/blobdiff - src/moof/view.cc
testing improved runloop scheduling
[chaz/yoink] / src / moof / view.cc
index 5c10378022032afc7e3aceaaedee110893392808..ab0058b5b115954262d0c105d3cba85791484a2d 100644 (file)
 namespace moof {
 
 
+// Timestep Example Source Code
+// Copyright (c) Glenn Fiedler 2004
+// http://www.gaffer.org/articles
+
+struct State
+{
+       float x;
+       float v;
+};
+
+struct Derivative
+{
+       float dx;
+       float dv;
+};
+
+State interpolate(const State &previous, const State &current, float alpha)
+{
+       State state;
+       state.x = current.x*alpha + previous.x*(1-alpha);
+       state.v = current.v*alpha + previous.v*(1-alpha);
+       return state;
+}
+
+float acceleration(const State &state, float t)
+{
+       const float k = 10;
+       const float b = 1;
+       return - k*state.x - b*state.v;
+}
+
+Derivative evaluate(const State &initial, float t)
+{
+       Derivative output;
+       output.dx = initial.v;
+       output.dv = acceleration(initial, t);
+       return output;
+}
+
+Derivative evaluate(const State &initial, float t, float dt, const Derivative &d)
+{
+       State state;
+       state.x = initial.x + d.dx*dt;
+       state.v = initial.v + d.dv*dt;
+       Derivative output;
+       output.dx = state.v;
+       output.dv = acceleration(state, t+dt);
+       return output;
+}
+
+void integrate(State &state, float t, float dt)
+{
+       Derivative a = evaluate(state, t);
+       Derivative b = evaluate(state, t, dt*0.5f, a);
+       Derivative c = evaluate(state, t, dt*0.5f, b);
+       Derivative d = evaluate(state, t, dt, c);
+       
+       const float dxdt = 1.0f/6.0f * (a.dx + 2.0f*(b.dx + c.dx) + d.dx);
+       const float dvdt = 1.0f/6.0f * (a.dv + 2.0f*(b.dv + c.dv) + d.dv);
+       
+       state.x = state.x + dxdt*dt;
+       state.v = state.v + dvdt*dt;
+}
+
+
 class root_view : public view
 {
        void update(scalar t, scalar dt)
@@ -93,10 +158,57 @@ public:
         * function will return the exit code used to stop the loop.
         */
 
+       scalar nextUpdate;
+       scalar totalTime;
+
+       void U(timer& T, scalar t)
+       {
+               const int MAX_FRAMESKIP = 15;
+
+               log_info("update");
+
+               int i = 0;
+               while (nextUpdate < t && ++i < MAX_FRAMESKIP)
+               {
+                       totalTime += timestep_;                 // 3. update state
+                       view_.update(totalTime, timestep_);
+
+                       //previous = current;
+                       //integrate(current, totalTime, timestep);
+
+                       nextUpdate += timestep_;
+               }
+       }
+
+       void D(timer& T, scalar t)
+       {
+               const scalar inverseTimestep = SCALAR(1.0) / timestep_;
+
+               log_info("draw");
+
+               scalar alpha = (t + timestep_ - nextUpdate) * inverseTimestep;
+               //scalar alpha = (nextUpdate - t) * inverseTimestep;
+               if (alpha < SCALAR(0.0)) log_error("UH OH!!!!!  It's NEGATIVE", alpha);
+               if (alpha > SCALAR(1.0)) log_error("UH OH!!!!!  It's POSITIVE", alpha);
+               log_info("alpha:", alpha);
+
+               view_.draw(alpha);
+               video_->swap();                                 // 4. draw state
+       }
+
+       timer utimer, dtimer;
+
        void run()
        {
                ASSERT(video_ && "running without video set");
 
+               utimer.init(boost::bind(&impl::U, this, _1, _2), timestep_, timer::repeat);
+               dtimer.init(boost::bind(&impl::D, this, _1, _2), framerate_, timer::repeat);
+
+               totalTime = 0.0f;
+               nextUpdate = timer::ticks();
+
+
                scalar totalTime = 0.0;
                scalar ticks = timer::ticks();
 
@@ -107,7 +219,7 @@ public:
                fps_ = 0;
                int frameCount = 0;
 
-               const scalar timestep = timestep_;
+               const scalar timestep = SCALAR(0.01);//timestep_;
                const scalar framerate = framerate_;
 
                const int MAX_FRAMESKIP = 15;
@@ -119,44 +231,97 @@ public:
                        timer::fire_expired_timers();           // 1. fire timers
                        dispatch_events();                                      // 2. dispatch events
 
-                       if (!is_running_) break;
-
-                       int i = 0;
-                       while (nextUpdate < timer::ticks() && i < MAX_FRAMESKIP)
-                       {
-                               totalTime += timestep;                  // 3. update state
-                               view_.update(totalTime, timestep);
-
-                               nextUpdate += timestep;
-                               ++i;
-
-                               if (!is_running_) break;
-                       }
-
-                       if (nextDraw < (ticks = timer::ticks()))
-                       {
-                               view_.draw(
-                                        (ticks + timestep - nextUpdate) * inverseTimestep);
-                               video_->swap();                                 // 4. draw state
-
-                               nextDraw += framerate;
-                               ++frameCount;
-
-                               if (nextSecond < timer::ticks())
-                               {
-                                       fps_ = frameCount;
-                                       frameCount = 0;
+                       //if (!is_running_) break;
+
+                       //int i = 0;
+                       //while (nextUpdate < timer::ticks() && i < MAX_FRAMESKIP)
+                       //{
+                               //totalTime += timestep;                        // 3. update state
+                               //view_.update(totalTime, timestep);
+
+                               ////previous = current;
+                               ////integrate(current, totalTime, timestep);
+
+                               //nextUpdate += timestep;
+                               //++i;
+
+                               //if (!is_running_) break;
+                       //}
+
+               ////const float newTime = timer::ticks();
+               ////float deltaTime = newTime - currentTime;
+               ////currentTime = newTime;
+               
+               ////if (deltaTime>0.25f)
+                       ////deltaTime = 0.25f;
+               
+               ////accumulator += deltaTime;
+               
+               ////while (accumulator>=dt)
+               ////{
+                       ////accumulator -= dt;
+                       ////previous = current;
+                       ////integrate(current, t, dt);
+                       ////t += dt;
+               ////}
+
+                       ////if (nextDraw < (ticks = timer::ticks()))
+                       ////{
+                       //ticks = timer::ticks();
+                               //scalar diff = ticks - nextDraw;
+                               ////log_info("difference:", diff);
+                               //scalar alpha = (ticks + timestep - nextUpdate) * inverseTimestep;
+                               ////scalar alpha = (nextUpdate - ticks) * inverseTimestep;
+                               ////float alpha = accumulator/dt;
+                               //if (alpha < SCALAR(0.0)) log_error("UH OH!!!!!  It's NEGATIVE", alpha);
+                               //if (alpha > SCALAR(1.0)) log_error("UH OH!!!!!  It's POSITIVE", alpha);
+                               //log_info("alpha:", alpha);
+
+                               //view_.draw(alpha);
+
+                               //// TEMP
+                       ////State state = interpolate(previous, current, alpha);
+                       ////glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+                       ////glBegin(GL_POINTS);
+                       ////glColor3f(1,1,1);
+                       ////glVertex3f(state.x, 0, 0);
+                       ////glEnd();
+               
+
+
+                               //video_->swap();                                       // 4. draw state
+
+                               //nextDraw += framerate;
+                               //++frameCount;
+
+                               //if (nextSecond < ticks)//timer::ticks())
+                               //{
+                                       //fps_ = frameCount;
+                                       //frameCount = 0;
+
+                                       //if (show_fps_) log_info << fps_ << " fps" << std::endl;
+
+                                       //nextSecond += SCALAR(1.0);
+                               //}
+                       ////}
 
-                                       if (show_fps_) log_info << fps_ << " fps" << std::endl;
+                       if (!is_running_) break;
 
-                                       nextSecond += SCALAR(1.0);
-                               }
-                       }
+                       //ticks = timer::ticks();                               // 5. yield timeslice
+                       //scalar next = std::min(nextUpdate, nextDraw);
+                       //next = std::min(next, timer::next_event());
+                       //if (ticks < next) timer::sleep(next, timer::absolute);
 
-                       if (!is_running_) break;
+                       timer::sleep(timer::next_event(), timer::absolute);
 
-                       ticks = timer::ticks();                         // 5. yield timeslice
-                       if (ticks < nextUpdate && ticks < nextDraw) timer::sleep(0.0);
+                       // Animation is choppy... the sound timer makes the draw occur
+                       // late.  It's not usually enough to make the FPS drop, but it
+                       // certainly is noticeably choppy.  Maybe update and draw
+                       // should both be scheduled like timers.  That should reduce
+                       // the number of times either update or draw occur late.  It
+                       // doesn't really matter if update is late, but it's ugly if
+                       // draw is late.
                }
        }
 
This page took 0.02326 seconds and 4 git commands to generate.