]>
Dogcows Code - chaz/yoink/blob - view.cc
62fcd93ac04155c12accbb949a8a80beede3356d
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
13 #include <cstdlib> // exit, srand
14 #include <ctime> // time
18 #include "fastevents.h"
23 #include "modal_dialog.hh"
24 #include "settings.hh"
33 // Timestep Example Source Code
34 // Copyright (c) Glenn Fiedler 2004
35 // http://www.gaffer.org/articles
49 State
interpolate(const State
&previous
, const State
¤t
, float alpha
)
52 state
.x
= current
.x
*alpha
+ previous
.x
*(1-alpha
);
53 state
.v
= current
.v
*alpha
+ previous
.v
*(1-alpha
);
57 float acceleration(const State
&state
, float t
)
61 return - k
*state
.x
- b
*state
.v
;
64 Derivative
evaluate(const State
&initial
, float t
)
67 output
.dx
= initial
.v
;
68 output
.dv
= acceleration(initial
, t
);
72 Derivative
evaluate(const State
&initial
, float t
, float dt
, const Derivative
&d
)
75 state
.x
= initial
.x
+ d
.dx
*dt
;
76 state
.v
= initial
.v
+ d
.dv
*dt
;
79 output
.dv
= acceleration(state
, t
+dt
);
83 void integrate(State
&state
, float t
, float dt
)
85 Derivative a
= evaluate(state
, t
);
86 Derivative b
= evaluate(state
, t
, dt
*0.5f
, a
);
87 Derivative c
= evaluate(state
, t
, dt
*0.5f
, b
);
88 Derivative d
= evaluate(state
, t
, dt
, c
);
90 const float dxdt
= 1.0f
/6.0f
* (a
.dx
+ 2.0f
*(b
.dx
+ c
.dx
) + d
.dx
);
91 const float dvdt
= 1.0f
/6.0f
* (a
.dv
+ 2.0f
*(b
.dv
+ c
.dv
) + d
.dv
);
93 state
.x
= state
.x
+ dxdt
*dt
;
94 state
.v
= state
.v
+ dvdt
*dt
;
98 class root_view
: public view
100 void update(scalar t
, scalar dt
)
102 if (children().size() == 0) stop();
106 static root_view gRootView
;
113 impl(view
* view
, moof::settings
& settings
, moof::video
& video
) :
115 settings_(&settings
),
122 if (settings
.get("rngseed", randomSeed
)) srand(randomSeed
);
125 scalar timestep
= 80.0;
126 settings
.get("timestep", timestep
);
127 timestep_
= 1.0 / timestep
;
129 scalar framerate
= 40.0;
130 settings
.get("framerate", framerate
);
131 framerate_
= 1.0 / framerate
;
134 settings
.get("showfps", show_fps_
);
148 timestep_
= SCALAR(0.01);
149 framerate_
= SCALAR(0.02);
155 * The main loop. This just calls dispatch_events(), update(), and
156 * draw() over and over again. The timing of the update and draw are
157 * decoupled. The actual frame rate is also calculated here. This
158 * function will return the exit code used to stop the loop.
164 void U(timer
& T
, scalar t
)
166 const int MAX_FRAMESKIP
= 15;
171 while (nextUpdate
< t
&& ++i
< MAX_FRAMESKIP
)
173 totalTime
+= timestep_
; // 3. update state
174 view_
.update(totalTime
, timestep_
);
176 //previous = current;
177 //integrate(current, totalTime, timestep);
179 nextUpdate
+= timestep_
;
183 void D(timer
& T
, scalar t
)
185 const scalar inverseTimestep
= SCALAR(1.0) / timestep_
;
189 scalar alpha
= (t
+ timestep_
- nextUpdate
) * inverseTimestep
;
190 //scalar alpha = (nextUpdate - t) * inverseTimestep;
191 if (alpha
< SCALAR(0.0)) log_error("UH OH!!!!! It's NEGATIVE", alpha
);
192 if (alpha
> SCALAR(1.0)) log_error("UH OH!!!!! It's POSITIVE", alpha
);
193 log_info("alpha:", alpha
);
196 video_
->swap(); // 4. draw state
199 timer utimer
, dtimer
;
203 ASSERT(video_
&& "running without video set");
205 utimer
.init(boost::bind(&impl::U
, this, _1
, _2
), timestep_
, timer::repeat
);
206 dtimer
.init(boost::bind(&impl::D
, this, _1
, _2
), framerate_
, timer::repeat
);
209 nextUpdate
= timer::ticks();
212 //scalar totalTime = 0.0;
213 //scalar ticks = timer::ticks();
215 //scalar nextUpdate = ticks;
216 //scalar nextDraw = ticks;
217 //scalar nextSecond = ticks + SCALAR(1.0);
220 //int frameCount = 0;
222 //const scalar timestep = SCALAR(0.01);//timestep_;
223 //const scalar framerate = framerate_;
225 //const int MAX_FRAMESKIP = 15;
226 //const scalar inverseTimestep = SCALAR(1.0) / timestep;
231 //timer::fire_expired_timers(); // 1. fire timers
232 dispatch_events(); // 2. dispatch events
234 //if (!is_running_) break;
237 //while (nextUpdate < timer::ticks() && i < MAX_FRAMESKIP)
239 //totalTime += timestep; // 3. update state
240 //view_.update(totalTime, timestep);
242 ////previous = current;
243 ////integrate(current, totalTime, timestep);
245 //nextUpdate += timestep;
248 //if (!is_running_) break;
251 ////const float newTime = timer::ticks();
252 ////float deltaTime = newTime - currentTime;
253 ////currentTime = newTime;
255 ////if (deltaTime>0.25f)
256 ////deltaTime = 0.25f;
258 ////accumulator += deltaTime;
260 ////while (accumulator>=dt)
262 ////accumulator -= dt;
263 ////previous = current;
264 ////integrate(current, t, dt);
268 ////if (nextDraw < (ticks = timer::ticks()))
270 //ticks = timer::ticks();
271 //scalar diff = ticks - nextDraw;
272 ////log_info("difference:", diff);
273 //scalar alpha = (ticks + timestep - nextUpdate) * inverseTimestep;
274 ////scalar alpha = (nextUpdate - ticks) * inverseTimestep;
275 ////float alpha = accumulator/dt;
276 //if (alpha < SCALAR(0.0)) log_error("UH OH!!!!! It's NEGATIVE", alpha);
277 //if (alpha > SCALAR(1.0)) log_error("UH OH!!!!! It's POSITIVE", alpha);
278 //log_info("alpha:", alpha);
283 ////State state = interpolate(previous, current, alpha);
284 ////glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
286 ////glBegin(GL_POINTS);
287 ////glColor3f(1,1,1);
288 ////glVertex3f(state.x, 0, 0);
293 //video_->swap(); // 4. draw state
295 //nextDraw += framerate;
298 //if (nextSecond < ticks)//timer::ticks())
303 //if (show_fps_) log_info << fps_ << " fps" << std::endl;
305 //nextSecond += SCALAR(1.0);
309 if (!is_running_
) break;
311 //ticks = timer::ticks(); // 5. yield timeslice
312 //scalar next = std::min(nextUpdate, nextDraw);
313 //next = std::min(next, timer::next_event());
314 //if (ticks < next) timer::sleep(next, timer::absolute);
316 //timer::sleep(timer::next_event(), timer::absolute);
318 // Animation is choppy... the sound timer makes the draw occur
319 // late. It's not usually enough to make the FPS drop, but it
320 // certainly is noticeably choppy. Maybe update and draw
321 // should both be scheduled like timers. That should reduce
322 // the number of times either update or draw occur late. It
323 // doesn't really matter if update is late, but it's ugly if
334 void dispatch_events()
338 while (FE_PollEvent(&event
) == 1)
343 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
344 (SDL_GetModState() & KMOD_CTRL
) )
347 log_warning("escape forced");
352 case SDL_VIDEORESIZE
:
353 video_
->resize(event
.resize
.w
, event
.resize
.h
);
357 view_
.handle_event(event
);
361 bool handle_event(const event
& event
)
363 std::list
<view_ptr
>::iterator it
;
364 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
366 if ((*it
)->handle_event(event
)) return true;
372 void update(scalar t
, scalar dt
)
374 std::list
<view_ptr
>::iterator it
;
375 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
377 (*it
)->update(t
, dt
);
381 void draw(scalar alpha
)
383 std::list
<view_ptr
>::iterator it
;
384 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
391 void add_child(view_ptr child
)
393 ASSERT(child
&& "adding null view");
394 ASSERT(child
.get() != &view_
&& "adding view to itself");
396 child
->impl_
->parent_
->remove_child(child
);
397 children_
.push_back(child
);
399 child
->impl_
->parent_
= &view_
;
400 child
->impl_
->percolate_objects();
402 child
->did_add_to_view();
405 void percolate_objects()
407 bool recurseAgain
= false;
409 if (parent_
->impl_
->video_
&& parent_
->impl_
->video_
!= video_
)
411 video_
= parent_
->impl_
->video_
;
415 if (parent_
->impl_
->settings_
&&
416 parent_
->impl_
->settings_
!= settings_
)
418 settings_
= parent_
->impl_
->settings_
;
424 std::list
<view_ptr
>::iterator it
;
425 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
427 (*it
)->impl_
->percolate_objects();
432 view_ptr
remove_child(view
* child
)
434 ASSERT(child
&& "cannot remove null child");
436 std::list
<view_ptr
>::iterator it
;
437 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
439 if ((*it
).get() == child
)
441 view_ptr found
= *it
;
442 found
->will_remove_from_view();
445 found
->impl_
->parent_
= &gRootView
;
463 moof::settings
* settings_
;
467 std::list
<view_ptr
> children_
;
477 view::view(moof::settings
& settings
, moof::video
& video
) :
479 impl_(new view::impl(this, settings
, video
)) {}
482 impl_(new view::impl(this)) {}
485 void view::update(scalar t
, scalar dt
)
488 impl_
->update(t
, dt
);
491 void view::draw(scalar alpha
) const
497 bool view::handle_event(const event
& event
)
500 return impl_
->handle_event(event
);
504 void view::add_child(view_ptr view
)
507 impl_
->add_child(view
);
510 view_ptr
view::remove_child(view
* view
)
513 return impl_
->remove_child(view
);
516 view_ptr
view::remove_child(view_ptr view
)
519 return impl_
->remove_child(view
.get());
529 view
& view::parent() const
531 return *(impl_
->parent_
);
534 const std::list
<view_ptr
>& view::children() const
536 return impl_
->children_
;
540 moof::settings
& view::settings() const
542 ASSERT(impl_
->settings_
&& "accessing null reference");
544 return *(impl_
->settings_
);
547 video
& view::video() const
549 ASSERT(impl_
->video_
&& "accessing null reference");
551 return *(impl_
->video_
);
564 return impl_
->stop();
567 bool view::is_running() const
570 return impl_
->is_running_
;
This page took 0.054335 seconds and 3 git commands to generate.