00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "animInterface.h"
00016 #include "clockObject.h"
00017 #include "bamReader.h"
00018 #include "bamWriter.h"
00019 #include "datagram.h"
00020 #include "datagramIterator.h"
00021
00022 TypeHandle AnimInterface::_type_handle;
00023
00024
00025
00026
00027
00028
00029 AnimInterface::
00030 AnimInterface() :
00031 _num_frames(0)
00032 {
00033 }
00034
00035
00036
00037
00038
00039
00040 AnimInterface::
00041 AnimInterface(const AnimInterface ©) :
00042 _num_frames(copy._num_frames),
00043 _cycler(copy._cycler)
00044 {
00045 }
00046
00047
00048
00049
00050
00051
00052 AnimInterface::
00053 ~AnimInterface() {
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 int AnimInterface::
00067 get_num_frames() const {
00068 return _num_frames;
00069 }
00070
00071
00072
00073
00074
00075
00076 void AnimInterface::
00077 output(ostream &out) const {
00078 CDReader cdata(_cycler);
00079 cdata->output(out);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 void AnimInterface::
00090 animation_activated() {
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 void AnimInterface::
00100 write_datagram(BamWriter *manager, Datagram &dg) {
00101 dg.add_int32(_num_frames);
00102 manager->write_cdata(dg, _cycler);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 void AnimInterface::
00113 fillin(DatagramIterator &scan, BamReader *manager) {
00114 _num_frames = scan.get_int32();
00115 manager->read_cdata(scan, _cycler);
00116 }
00117
00118
00119
00120
00121
00122
00123 AnimInterface::CData::
00124 CData() :
00125 _frame_rate(0.0),
00126 _play_mode(PM_pose),
00127 _start_time(0.0),
00128 _start_frame(0.0),
00129 _play_frames(0.0),
00130 _from_frame(0),
00131 _to_frame(0),
00132 _play_rate(1.0),
00133 _effective_frame_rate(0.0),
00134 _paused(true),
00135 _paused_f(0.0)
00136 {
00137 }
00138
00139
00140
00141
00142
00143
00144 AnimInterface::CData::
00145 CData(const AnimInterface::CData ©) :
00146 _frame_rate(copy._frame_rate),
00147 _play_mode(copy._play_mode),
00148 _start_time(copy._start_time),
00149 _start_frame(copy._start_frame),
00150 _play_frames(copy._play_frames),
00151 _from_frame(copy._from_frame),
00152 _to_frame(copy._to_frame),
00153 _play_rate(copy._play_rate),
00154 _effective_frame_rate(copy._effective_frame_rate),
00155 _paused(copy._paused),
00156 _paused_f(copy._paused_f)
00157 {
00158 }
00159
00160
00161
00162
00163
00164
00165 CycleData *AnimInterface::CData::
00166 make_copy() const {
00167 return new CData(*this);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 void AnimInterface::CData::
00177 write_datagram(BamWriter *, Datagram &dg) const {
00178 dg.add_stdfloat(_frame_rate);
00179 dg.add_uint8(_play_mode);
00180 dg.add_stdfloat(_start_time);
00181 dg.add_stdfloat(_start_frame);
00182 dg.add_stdfloat(_play_frames);
00183 dg.add_int32(_from_frame);
00184 dg.add_int32(_to_frame);
00185 dg.add_stdfloat(_play_rate);
00186 dg.add_bool(_paused);
00187 dg.add_stdfloat(_paused_f);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 void AnimInterface::CData::
00198 fillin(DatagramIterator &scan, BamReader *) {
00199 _frame_rate = scan.get_stdfloat();
00200 _play_mode = (PlayMode)scan.get_uint8();
00201 _start_time = scan.get_stdfloat();
00202 _start_frame = scan.get_stdfloat();
00203 _play_frames = scan.get_stdfloat();
00204 _from_frame = scan.get_int32();
00205 _to_frame = scan.get_int32();
00206 _play_rate = scan.get_stdfloat();
00207 _effective_frame_rate = _frame_rate * _play_rate;
00208 _paused = scan.get_bool();
00209 _paused_f = scan.get_stdfloat();
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 void AnimInterface::CData::
00226 play(double from, double to) {
00227 if (from >= to) {
00228 pose(from);
00229 return;
00230 }
00231
00232 _play_mode = PM_play;
00233 _start_time = ClockObject::get_global_clock()->get_frame_time();
00234 _start_frame = from;
00235 _play_frames = to - from + 1.0;
00236 _from_frame = (int)floor(from);
00237 _to_frame = (int)floor(to);
00238 _paused_f = 0.0;
00239
00240 if (_effective_frame_rate < 0.0) {
00241
00242 _start_time -= _play_frames / _effective_frame_rate;
00243 }
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void AnimInterface::CData::
00256 loop(bool restart, double from, double to) {
00257 if (from >= to) {
00258 pose(from);
00259 return;
00260 }
00261
00262 double fframe = get_full_fframe();
00263
00264 _play_mode = PM_loop;
00265 _start_time = ClockObject::get_global_clock()->get_frame_time();
00266 _start_frame = from;
00267 _play_frames = to - from + 1.0;
00268 _from_frame = (int)floor(from);
00269 _to_frame = (int)floor(to);
00270 _paused_f = 0.0;
00271
00272 if (!restart) {
00273 fframe = min(max(fframe, from), to);
00274 if (_paused) {
00275 _paused_f = fframe - _start_frame;
00276 } else {
00277 _start_time -= (fframe - _start_frame) / _effective_frame_rate;
00278 }
00279 }
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 void AnimInterface::CData::
00290 pingpong(bool restart, double from, double to) {
00291 if (from >= to) {
00292 pose(from);
00293 return;
00294 }
00295
00296 double fframe = get_full_fframe();
00297
00298 _play_mode = PM_pingpong;
00299 _start_time = ClockObject::get_global_clock()->get_frame_time();
00300 _start_frame = from;
00301 _play_frames = to - from + 1.0;
00302 _from_frame = (int)floor(from);
00303 _to_frame = (int)floor(to);
00304 _paused_f = 0.0;
00305
00306 if (!restart) {
00307 fframe = min(max(fframe, from), to);
00308 if (_paused) {
00309 _paused_f = fframe - _start_frame;
00310 } else {
00311 _start_time -= (fframe - _start_frame) / _effective_frame_rate;
00312 }
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 void AnimInterface::CData::
00323 pose(double frame) {
00324 _play_mode = PM_pose;
00325 _start_time = ClockObject::get_global_clock()->get_frame_time();
00326 _start_frame = frame;
00327 _play_frames = 0.0;
00328 _from_frame = (int)floor(frame);
00329 _to_frame = (int)floor(frame);
00330 _paused_f = 0.0;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 int AnimInterface::CData::
00349 get_full_frame(int increment) const {
00350 int frame = (int)floor(get_full_fframe()) + increment;
00351 if (_play_mode == PM_play) {
00352
00353
00354 frame = min(max(frame, _from_frame), _to_frame);
00355 }
00356 return frame;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 double AnimInterface::CData::
00376 get_full_fframe() const {
00377 switch (_play_mode) {
00378 case PM_pose:
00379 return _start_frame;
00380
00381 case PM_play:
00382 return min(max(get_f(), 0.0), _play_frames) + _start_frame;
00383
00384 case PM_loop:
00385 nassertr(_play_frames >= 0.0, 0.0);
00386 return cmod(get_f(), _play_frames) + _start_frame;
00387
00388 case PM_pingpong:
00389 {
00390 nassertr(_play_frames >= 0.0, 0.0);
00391 double f = cmod(get_f(), _play_frames * 2.0);
00392 if (f > _play_frames) {
00393 return (_play_frames * 2.0 - f) + _start_frame;
00394 } else {
00395 return f + _start_frame;
00396 }
00397 }
00398 }
00399
00400 return _start_frame;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 bool AnimInterface::CData::
00412 is_playing() const {
00413 switch (_play_mode) {
00414 case PM_pose:
00415 return false;
00416
00417 case PM_play:
00418 return get_f() < _play_frames;
00419
00420 case PM_loop:
00421 case PM_pingpong:
00422 return true;
00423 }
00424
00425 return false;
00426 }
00427
00428
00429
00430
00431
00432
00433 void AnimInterface::CData::
00434 output(ostream &out) const {
00435 switch (_play_mode) {
00436 case PM_pose:
00437 out << "pose, frame " << get_full_fframe();
00438 return;
00439
00440 case PM_play:
00441 out << "play, frame " << get_full_fframe();
00442 return;
00443
00444 case PM_loop:
00445 out << "loop, frame " << get_full_fframe();
00446 return;
00447
00448 case PM_pingpong:
00449 out << "pingpong, frame " << get_full_fframe();
00450 return;
00451 }
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 void AnimInterface::CData::
00462 internal_set_rate(double frame_rate, double play_rate) {
00463 double f = get_f();
00464
00465 _frame_rate = frame_rate;
00466 _play_rate = play_rate;
00467 _effective_frame_rate = frame_rate * play_rate;
00468
00469 if (_effective_frame_rate == 0.0) {
00470 _paused_f = f;
00471 _paused = true;
00472
00473 } else {
00474
00475
00476 double new_elapsed = f / _effective_frame_rate;
00477 double now = ClockObject::get_global_clock()->get_frame_time();
00478 _start_time = now - new_elapsed;
00479 _paused = false;
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489 double AnimInterface::CData::
00490 get_f() const {
00491 if (_paused) {
00492 return _paused_f;
00493
00494 } else {
00495 double now = ClockObject::get_global_clock()->get_frame_time();
00496 double elapsed = now - _start_time;
00497 return (elapsed * _effective_frame_rate);
00498 }
00499 }