00001
00002
00003 #include "disp/animator.H"
00004 #include "net/io_manager.H"
00005 #include "std/config.H"
00006
00007
00008
00009
00010
00011
00012 #ifdef DONT_LINK_GEOM_IN_DISP
00013 inline void
00014 show_msg(Cstr_ptr& msg)
00015 {
00016 err_msg("%s", **msg);
00017 }
00018 #else
00019 #include "geom/world.H"
00020 inline void
00021 show_msg(Cstr_ptr& msg)
00022 {
00023 WORLD::message(msg);
00024 }
00025 #endif
00026
00027 static bool debug = true;
00028
00029
00030
00031 TAGlist* Animator::_a_tags = 0;
00032
00033 Animator::Animator(VIEWptr view) :
00034 _view(view),
00035 _name("animation"),
00036 _fps(12),
00037 _start_frame(0),
00038 _end_frame(0),
00039 _cur_frame(0),
00040 _jog_size(10),
00041 _loop(false),
00042 _on(false),
00043 _play_on(false),
00044 _rend_on(false),
00045 _sync_on(false),
00046 _time_scale(1.0)
00047 {
00048
00049 _timer.reset_hold();
00050 }
00051
00052
00053
00054
00055 void
00056 Animator::toggle_activation()
00057 {
00058 if (!_on) {
00059 if (_fps <= 0) {
00060 show_msg("Cannot activate Animator!");
00061 err_adv(debug, "Animator::toggle_activation() - No fps set");
00062 } else if (_start_frame < 0) {
00063 show_msg("Cannot activate Animator!");
00064 err_adv(debug, "Animator::toggle_activation() - No start_frame set");
00065 } else if (_end_frame < _start_frame) {
00066 show_msg("Cannot activate Animator!");
00067 err_adv(debug, "Animator::toggle_activation() - Bad end_frame");
00068 } else if (_name == NULL_STR) {
00069 show_msg("Cannot activate Animator!");
00070 err_adv(debug, "Animator::toggle_activation() - No name set");
00071 } else {
00072 show_msg("Animator ON");
00073 _on = true;
00074 _timer.set_elapsed_time(0);
00075 }
00076 } else {
00077 _on = false;
00078 show_msg("Animator OFF");
00079 }
00080 }
00081
00082
00083
00084
00085 void
00086 Animator::press_beginning()
00087 {
00088 _timer.set_elapsed_time(0);
00089 _cur_frame = _start_frame;
00090 }
00091
00092
00093
00094
00095 void
00096 Animator::press_play()
00097 {
00098 if (!_play_on) {
00099 _play_on = true;
00100 _timer.resume();
00101 show_msg("Playing...");
00102 } else {
00103 show_msg("Already Playing!");
00104 }
00105 }
00106
00107
00108
00109
00110 void
00111 Animator::press_stop()
00112 {
00113 if (_play_on) {
00114 _play_on = false;
00115 _timer.pause();
00116 show_msg("Stopped");
00117 } else {
00118 show_msg("Already Stopped");
00119 }
00120 }
00121
00122
00123
00124
00125
00126 void
00127 Animator::press_render()
00128 {
00129 if (_rend_on) {
00130 _rend_on = false;
00131
00132 show_msg("Render to Disk Mode OFF");
00133 } else {
00134 if (_sync_on) {
00135 _rend_on = true;
00136 show_msg("Render to Disk Mode ON");
00137 } else {
00138 show_msg("Engage time sync mode first!");
00139 }
00140 }
00141 }
00142
00143
00144
00145
00146 void
00147 Animator::press_sync()
00148 {
00149 if (_rend_on) {
00150
00151 assert(_sync_on);
00152 show_msg("Disengage render to disk mode first!");
00153 } else {
00154 if (_sync_on) {
00155 _sync_on = false;
00156 show_msg("Time Sync Mode OFF");
00157 } else {
00158 _sync_on = true;
00159 show_msg("Time Sync Mode ON");
00160 }
00161 }
00162 }
00163
00164 inline int
00165 wrap(int a, int b, int c)
00166 {
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 int d = c - b;
00178 if (d == 0)
00179 return b;
00180 assert(d > 0);
00181 if (a < b) {
00182 return c + div(a-b,d).rem;
00183 } else if (a > c) {
00184 return b + div(a-b,d).rem;
00185 } else {
00186 return a;
00187 }
00188 }
00189
00190 void
00191 Animator::inc_frame(int inc)
00192 {
00193
00194
00195
00196 _cur_frame = _loop ?
00197 wrap (_cur_frame + inc, _start_frame, _end_frame) :
00198 clamp(_cur_frame + inc, _start_frame, _end_frame);
00199 }
00200
00201
00202
00203
00204 void
00205 Animator::step(int inc)
00206 {
00207 char buf[1024];
00208 if (_play_on) {
00209 show_msg("Press stop before stepping");
00210 return;
00211 } else if (_sync_on) {
00212
00213 inc_frame(inc);
00214 sprintf(buf,"Frame %d of %d to %d", _cur_frame, _start_frame, _end_frame);
00215 show_msg(buf);
00216 } else {
00217
00218 assert(_timer.is_paused());
00219 assert(_fps != 0);
00220 double dt = double(inc)/_fps;
00221 _timer.inc_elapsed_time(dt);
00222 sprintf(buf,"Advanced time by %1.3f seconds", dt);
00223 show_msg(buf);
00224 return;
00225 }
00226 }
00227
00228
00229
00230
00231 double
00232 Animator::pre_draw_CB()
00233 {
00234 assert(_on);
00235
00236 if (_sync_on) {
00237 return _time_scale * (_cur_frame - _start_frame) / _fps;
00238 } else {
00239 return _time_scale * _timer.elapsed_time();
00240 }
00241 }
00242
00243
00244
00245
00246
00247 void
00248 Animator::post_draw_CB()
00249 {
00250 bool use_alpha = Config::get_var_bool("GRAB_ALPHA",true);
00251
00252 if (_play_on && _rend_on) {
00253
00254 char buf[1024];
00255 sprintf (buf, "%s[%dFPS][%dto%d]-%05d.png",
00256 **_name, _fps, _start_frame, _end_frame, _cur_frame);
00257 err_msg("Animator::post_draw_CB() - Writing '%s'...", buf);
00258
00259 int w,h;
00260 VIEW_SIZE (w,h);
00261 Image output (w, h, use_alpha ? 4 : 3);
00262 VIEWimpl* impl = _view->impl();
00263 if (impl) {
00264 _view->set_grabbing_screen(1);
00265 impl->prepare_buf_read();
00266 impl->read_pixels(output.data(),use_alpha);
00267 _view->set_grabbing_screen(0);
00268 impl->end_buf_read();
00269 }
00270 if (!output.write_png(buf)) {
00271 err_msg("Animator::post_draw_CB() - Error writing file!");
00272 }
00273 }
00274
00275 if (_sync_on && _play_on) {
00276 if (_cur_frame >= _end_frame && !_loop) {
00277
00278 press_stop();
00279 } else {
00280
00281
00282 inc_frame(1);
00283 }
00284 }
00285 }
00286
00287 STDdstream&
00288 Animator::format(STDdstream &d) const
00289 {
00290 STDdstream &ret = DATA_ITEM::format(d);
00291
00292
00293
00294
00295
00296 if ( (_fps > 0) &&
00297 (_start_frame >=0) &&
00298 (_end_frame > _start_frame) &&
00299 (_name != NULL_STR) ) {
00300 cerr << "Animator::format: Found .jot file containing multiple frames."
00301 << endl
00302 << "Each frame will be loaded and resaved..." << endl;
00303
00304 str_ptr bname, lname, sname;
00305
00306 char buf[6];
00307
00308 LOADobs::load_status_t lstatus;
00309 SAVEobs::save_status_t sstatus;
00310
00311 for (int i = _end_frame; i >= _start_frame; i--) {
00312 sprintf(buf, "%05d", i);
00313
00314 str_ptr bname = _name + "[" + buf + "].jot";
00315
00316 str_ptr lname = IOManager::cached_prefix() + bname;
00317 str_ptr sname = IOManager::current_prefix() + bname;
00318
00319 err_msg("Animator::format() - Saving frame: '%s'...", **bname);
00320
00321
00322
00323 {
00324 NetStream l(lname, NetStream::ascii_r);
00325 LOADobs::notify_load_obs(l, lstatus, true, false);
00326
00327 if (lstatus != LOADobs::LOAD_ERROR_NONE) {
00328 cerr << "Animator::format: Error loading scene update frame: "
00329 << lname << ", Aborting..." << endl;
00330 break;
00331 }
00332 }
00333
00334 {
00335 NetStream s(sname, NetStream::ascii_w);
00336 SAVEobs::notify_save_obs(s, sstatus, true, false);
00337
00338 if (sstatus != SAVEobs::SAVE_ERROR_NONE) {
00339 cerr << "Animator::format: Error saving scene update frame: "
00340 << sname << ", Aborting..." << endl;
00341 break;
00342 }
00343 }
00344 }
00345 }
00346
00347 return ret;
00348 }
00349
00350
00351
00352
00353 CTAGlist &
00354 Animator::tags() const
00355 {
00356 if (!_a_tags) {
00357 _a_tags = new TAGlist;
00358
00359 *_a_tags += new TAG_val<Animator,int>(
00360 "fps",
00361 &Animator::fps_);
00362 *_a_tags += new TAG_val<Animator,int>(
00363 "start_frame",
00364 &Animator::start_frame_);
00365 *_a_tags += new TAG_val<Animator,int>(
00366 "end_frame",
00367 &Animator::end_frame_);
00368
00369
00370 *_a_tags += new TAG_meth<Animator>(
00371 "name",
00372 &Animator::put_name,
00373 &Animator::get_name,
00374 1);
00375 }
00376 return *_a_tags;
00377 }
00378
00379
00380
00381 void
00382 Animator::get_name (TAGformat &d)
00383 {
00384 str_ptr str, space;
00385 *d >> str;
00386
00387 if (!(*d).ascii())
00388 *d >> space;
00389
00390 if (str == "NULL_STR") {
00391 _name = NULL_STR;
00392 err_mesg(ERR_LEV_SPAM, "Animator::get_name() - Loaded NULL string.");
00393 } else {
00394 _name = str;
00395 err_mesg(ERR_LEV_SPAM, "Animator::get_name() - Loaded string: '%s'.", **str);
00396 }
00397
00398 }
00399
00400
00401
00402
00403 void
00404 Animator::put_name (TAGformat &d) const
00405 {
00406 d.id();
00407 if (_name == NULL_STR) {
00408 err_mesg(ERR_LEV_SPAM, "Animator::put_name() - Wrote NULL string.");
00409 *d << "NULL_STR";
00410 *d << " ";
00411 } else {
00412 *d << _name;
00413 *d << " ";
00414 err_mesg(ERR_LEV_SPAM, "Animator::put_name() - Wrote string: '%s'.", **_name);
00415 }
00416 d.end_id();
00417 }
00418
00419