]> Dogcows Code - chaz/yoink/blobdiff - src/moof/view.cc
initial runloop implementation
[chaz/yoink] / src / moof / view.cc
index 5c10378022032afc7e3aceaaedee110893392808..62fcd93ac04155c12accbb949a8a80beede3356d 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,70 +158,170 @@ public:
         * function will return the exit code used to stop the loop.
         */
 
-       void run()
+       scalar nextUpdate;
+       scalar totalTime;
+
+       void U(timer& T, scalar t)
        {
-               ASSERT(video_ && "running without video set");
+               const int MAX_FRAMESKIP = 15;
 
-               scalar totalTime = 0.0;
-               scalar ticks = timer::ticks();
+               log_info("update");
 
-               scalar nextUpdate = ticks;
-               scalar nextDraw = ticks;
-               scalar nextSecond = ticks + SCALAR(1.0);
+               int i = 0;
+               while (nextUpdate < t && ++i < MAX_FRAMESKIP)
+               {
+                       totalTime += timestep_;                 // 3. update state
+                       view_.update(totalTime, timestep_);
 
-               fps_ = 0;
-               int frameCount = 0;
+                       //previous = current;
+                       //integrate(current, totalTime, timestep);
 
-               const scalar timestep = timestep_;
-               const scalar framerate = framerate_;
+                       nextUpdate += timestep_;
+               }
+       }
 
-               const int MAX_FRAMESKIP = 15;
-               const scalar inverseTimestep = SCALAR(1.0) / timestep;
+       void D(timer& T, scalar t)
+       {
+               const scalar inverseTimestep = SCALAR(1.0) / timestep_;
 
-               is_running_ = true;
-               for (;;)
-               {
-                       timer::fire_expired_timers();           // 1. fire timers
-                       dispatch_events();                                      // 2. dispatch events
+               log_info("draw");
 
-                       if (!is_running_) break;
+               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);
 
-                       int i = 0;
-                       while (nextUpdate < timer::ticks() && i < MAX_FRAMESKIP)
-                       {
-                               totalTime += timestep;                  // 3. update state
-                               view_.update(totalTime, timestep);
+               view_.draw(alpha);
+               video_->swap();                                 // 4. draw state
+       }
 
-                               nextUpdate += timestep;
-                               ++i;
+       timer utimer, dtimer;
 
-                               if (!is_running_) break;
-                       }
+       void run()
+       {
+               ASSERT(video_ && "running without video set");
 
-                       if (nextDraw < (ticks = timer::ticks()))
-                       {
-                               view_.draw(
-                                        (ticks + timestep - nextUpdate) * inverseTimestep);
-                               video_->swap();                                 // 4. draw state
+               utimer.init(boost::bind(&impl::U, this, _1, _2), timestep_, timer::repeat);
+               dtimer.init(boost::bind(&impl::D, this, _1, _2), framerate_, timer::repeat);
 
-                               nextDraw += framerate;
-                               ++frameCount;
+               totalTime = 0.0f;
+               nextUpdate = timer::ticks();
 
-                               if (nextSecond < timer::ticks())
-                               {
-                                       fps_ = frameCount;
-                                       frameCount = 0;
 
-                                       if (show_fps_) log_info << fps_ << " fps" << std::endl;
+               //scalar totalTime = 0.0;
+               //scalar ticks = timer::ticks();
 
-                                       nextSecond += SCALAR(1.0);
-                               }
-                       }
+               //scalar nextUpdate = ticks;
+               //scalar nextDraw = ticks;
+               //scalar nextSecond = ticks + SCALAR(1.0);
+
+               fps_ = 0;
+               //int frameCount = 0;
+
+               //const scalar timestep = SCALAR(0.01);//timestep_;
+               //const scalar framerate = framerate_;
+
+               //const int MAX_FRAMESKIP = 15;
+               //const scalar inverseTimestep = SCALAR(1.0) / timestep;
+
+               is_running_ = true;
+               for (;;)
+               {
+                       //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);
+
+                               ////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 (!is_running_) break;
 
-                       ticks = timer::ticks();                         // 5. yield timeslice
-                       if (ticks < nextUpdate && ticks < nextDraw) timer::sleep(0.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);
+
+                       //timer::sleep(timer::next_event(), timer::absolute);
+
+                       // 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.025646 seconds and 4 git commands to generate.