00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "animControl.h"
00021 #include "animChannelBase.h"
00022 #include "partBundle.h"
00023 #include "config_chan.h"
00024
00025 #include <event.h>
00026 #include <throw_event.h>
00027
00028
00029 TypeHandle AnimControl::_type_handle;
00030
00031
00032
00033
00034
00035
00036 AnimControl::
00037 AnimControl(PartBundle *part, AnimBundle *anim, int channel_index) {
00038 #ifdef DO_MEMORY_USAGE
00039 MemoryUsage::update_type(this, get_class_type());
00040 #endif
00041
00042 _part = part;
00043 _anim = anim;
00044 _channel_index = channel_index;
00045
00046 _play_rate = 1.0f;
00047 _frame = 0.0f;
00048 _as_of_time = 0.0f;
00049 _playing = false;
00050
00051 _marked_frame = -1;
00052 }
00053
00054
00055
00056
00057
00058
00059 AnimControl::
00060 ~AnimControl() {
00061 get_part()->set_control_effect(this, 0.0f);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071 void AnimControl::
00072 play(const CPT_Event &stop_event) {
00073 nassertv(get_num_frames() > 0);
00074
00075 if (get_play_rate() < 0.0f) {
00076 play(get_num_frames()-1, 0, stop_event);
00077 } else {
00078 play(0, get_num_frames()-1, stop_event);
00079 }
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 void AnimControl::
00094 play(int from, int to, const CPT_Event &stop_event) {
00095 nassertv(get_num_frames() > 0);
00096
00097 nassertv(from >= 0 && from < get_num_frames());
00098 nassertv(to >= 0 && to < get_num_frames());
00099 _as_of_time = ClockObject::get_global_clock()->get_frame_time();
00100 _playing = true;
00101
00102 _actions = _user_actions;
00103 if (stop_event != (Event*)0L) {
00104 insert_event_action(_actions, to, stop_event);
00105 }
00106 insert_stop_action(_actions, to);
00107
00108 get_part()->control_activated(this);
00109 set_frame(from);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119 void AnimControl::
00120 loop(bool restart) {
00121 nassertv(get_num_frames() > 0);
00122
00123 _as_of_time = ClockObject::get_global_clock()->get_frame_time();
00124 _playing = true;
00125
00126 _actions = _user_actions;
00127 get_part()->control_activated(this);
00128
00129 if (restart) {
00130 if (get_play_rate() < 0.0f) {
00131 set_frame(get_num_frames() - 1);
00132 } else {
00133 set_frame(0);
00134 }
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 void AnimControl::
00148 loop(bool restart, int from, int to) {
00149 nassertv(get_num_frames() > 0);
00150
00151 nassertv(from >= 0 && from < get_num_frames());
00152 nassertv(to >= 0 && to < get_num_frames());
00153 _as_of_time = ClockObject::get_global_clock()->get_frame_time();
00154 _playing = true;
00155
00156 _actions = _user_actions;
00157
00158 if (get_play_rate() < 0.0f) {
00159
00160
00161
00162 if ((to == 0 && from == get_num_frames()-1) ||
00163 (to == from-1)) {
00164
00165
00166
00167
00168
00169 } else {
00170
00171
00172
00173
00174
00175
00176 insert_jump_action(_actions, (to-1+get_num_frames())%get_num_frames(),
00177 from);
00178 }
00179 } else {
00180
00181 if ((from == 0 && to == get_num_frames()-1) ||
00182 (from == to-1)) {
00183
00184
00185
00186
00187
00188 } else {
00189
00190
00191
00192
00193
00194
00195 insert_jump_action(_actions, (to+1)%get_num_frames(), from);
00196 }
00197 }
00198
00199 get_part()->control_activated(this);
00200 if (restart) {
00201 set_frame(from);
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 void AnimControl::
00213 pingpong(bool restart, int from, int to) {
00214 if (from == to) {
00215 pose(from);
00216 return;
00217 }
00218
00219 nassertv(get_num_frames() > 0);
00220
00221 nassertv(from >= 0 && from < get_num_frames());
00222 nassertv(to >= 0 && to < get_num_frames());
00223 _as_of_time = ClockObject::get_global_clock()->get_frame_time();
00224 _playing = true;
00225
00226 _actions = _user_actions;
00227
00228 insert_forward_action(_actions, from);
00229 insert_backward_action(_actions, to);
00230
00231 get_part()->control_activated(this);
00232 if (restart) {
00233 set_frame(from);
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244 void AnimControl::
00245 stop() {
00246 _playing = false;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 void AnimControl::
00256 pose(int frame) {
00257 int num_frames = get_num_frames();
00258 nassertv(num_frames > 0);
00259
00260
00261 frame = (int)(frame - cfloor(frame / num_frames) * num_frames);
00262 nassertv(frame >= 0 && frame < num_frames);
00263 _as_of_time = ClockObject::get_global_clock()->get_frame_time();
00264 _playing = false;
00265
00266 _actions = _user_actions;
00267
00268 get_part()->control_activated(this);
00269 set_frame(frame);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 void AnimControl::
00283 add_event(int frame, const CPT_Event &event) {
00284 insert_event_action(_user_actions, frame, event);
00285 if (_playing) {
00286 insert_event_action(_actions, frame, event);
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297 int AnimControl::
00298 remove_event(const string &event_name) {
00299 Actions new_actions;
00300
00301 int removed = 0;
00302
00303 Actions::const_iterator ai;
00304 for (ai = _user_actions.begin(); ai != _user_actions.end(); ++ai) {
00305 const Action &action = (*ai).second;
00306 if (action._type == AT_event &&
00307 action._event->get_name() == event_name) {
00308
00309 removed++;
00310 } else {
00311
00312 new_actions.insert(*ai);
00313 }
00314 }
00315
00316 if (removed != 0) {
00317 _user_actions.swap(new_actions);
00318
00319 if (_playing) {
00320 new_actions.clear();
00321 int p_removed = 0;
00322 for (ai = _actions.begin(); ai != _actions.end(); ++ai) {
00323 const Action &action = (*ai).second;
00324 if (action._type == AT_event &&
00325 action._event->get_name() == event_name) {
00326
00327 p_removed++;
00328 } else {
00329
00330 new_actions.insert(*ai);
00331 }
00332 }
00333 nassertr(p_removed == removed, removed);
00334 _actions.swap(new_actions);
00335 }
00336 }
00337
00338 return removed;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 void AnimControl::
00350 remove_all_events() {
00351 _user_actions.clear();
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 PartBundle *AnimControl::
00361 get_part() const {
00362 return DCAST(PartBundle, _part);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 void AnimControl::
00378 advance_time(double time) {
00379 double elapsed_time = time - _as_of_time;
00380 double elapsed_frames = elapsed_time * get_frame_rate();
00381 _as_of_time = time;
00382
00383 if (_playing && elapsed_frames != 0.0f) {
00384 int orig_frame = get_frame();
00385
00386 _frame += elapsed_frames;
00387 double num_frames = (double)get_num_frames();
00388
00389 int new_frame = get_frame();
00390
00391
00392 if (elapsed_frames < 0.0f) {
00393
00394
00395
00396 if (new_frame >= 0) {
00397 do_actions_backward(orig_frame-1, new_frame);
00398 } else {
00399 if (do_actions_backward(orig_frame-1, 0)) {
00400
00401
00402
00403
00404
00405 _frame = _frame - cfloor(_frame / num_frames) * num_frames;
00406 new_frame = get_frame();
00407 do_actions_backward(get_num_frames(), new_frame);
00408 }
00409 }
00410 } else {
00411
00412
00413 if (new_frame < get_num_frames()) {
00414 do_actions_forward(orig_frame+1, new_frame);
00415 } else {
00416 if (do_actions_forward(orig_frame+1, get_num_frames()-1)) {
00417
00418
00419
00420
00421
00422 _frame = _frame - cfloor(_frame / num_frames) * num_frames;
00423 new_frame = get_frame();
00424 do_actions_forward(0, new_frame);
00425 }
00426 }
00427 }
00428 }
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 bool AnimControl::
00439 channel_has_changed(AnimChannelBase *channel) const {
00440 if (_marked_frame < 0) {
00441 return true;
00442 }
00443
00444 int this_frame = get_frame();
00445
00446 if (this_frame == _marked_frame) {
00447 return false;
00448 }
00449
00450 return channel->has_changed(_marked_frame, this_frame);
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 void AnimControl::
00461 mark_channels() {
00462 _marked_frame = get_frame();
00463 }
00464
00465
00466
00467
00468
00469
00470 void AnimControl::
00471 output(ostream &out) const {
00472 out << "AnimControl(" << get_part()->get_name()
00473 << ", " << get_anim()->get_name() << ")";
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 void AnimControl::
00486 insert_event_action(Actions &actions, int frame, const CPT_Event &event) {
00487 Action new_action;
00488 new_action._type = AT_event;
00489 new_action._event = event;
00490 actions.insert(pair<int, Action>(frame, new_action));
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 void AnimControl::
00502 insert_stop_action(Actions &actions, int frame) {
00503 Action new_action;
00504 new_action._type = AT_stop;
00505 actions.insert(pair<int, Action>(frame, new_action));
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 void AnimControl::
00519 insert_jump_action(Actions &actions, int frame, int jump_to) {
00520 Action new_action;
00521 new_action._type = AT_jump;
00522 new_action._jump_to = jump_to;
00523 actions.insert(pair<int, Action>(frame, new_action));
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 void AnimControl::
00535 insert_forward_action(Actions &actions, int frame) {
00536 Action new_action;
00537 new_action._type = AT_forward;
00538 actions.insert(pair<int, Action>(frame, new_action));
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 void AnimControl::
00550 insert_backward_action(Actions &actions, int frame) {
00551 Action new_action;
00552 new_action._type = AT_backward;
00553 actions.insert(pair<int, Action>(frame, new_action));
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563 void AnimControl::
00564 set_frame(double frame) {
00565 _frame = frame;
00566 int iframe = get_frame();
00567 do_actions_forward(iframe, iframe);
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 bool AnimControl::
00582 do_actions_forward(int from, int to) {
00583 if (to >= from) {
00584 Actions::const_iterator lower = _actions.lower_bound(from);
00585 Actions::const_iterator upper = _actions.lower_bound(to+1);
00586
00587 int sequence_frame = -1;
00588 const Action *sequence_action;
00589
00590 Actions::const_iterator ai;
00591 for (ai = lower; ai != upper; ++ai) {
00592 int frame = (*ai).first;
00593 const Action &action = (*ai).second;
00594
00595 if (sequence_frame != -1 && frame > sequence_frame) {
00596
00597
00598
00599
00600 do_sequence_action(sequence_frame, *sequence_action);
00601 return false;
00602 }
00603
00604 do_action(frame, action, sequence_frame, sequence_action);
00605 }
00606
00607 if (sequence_frame != -1) {
00608 do_sequence_action(sequence_frame, *sequence_action);
00609 return false;
00610 }
00611 }
00612
00613 return true;
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 bool AnimControl::
00628 do_actions_backward(int from, int to) {
00629 if (from >= to) {
00630 #if defined(WIN32_VC) && !defined(NO_PCH)
00631 typedef Actions::const_reverse_iterator Action_reverse_iterator;
00632 #else
00633 typedef reverse_iterator<Actions::const_iterator> Action_reverse_iterator;
00634 #endif
00635 Action_reverse_iterator lower(_actions.upper_bound(from));
00636 Action_reverse_iterator upper(_actions.upper_bound(to-1));
00637
00638 int sequence_frame = -1;
00639 const Action *sequence_action;
00640
00641 Action_reverse_iterator ai;
00642 for (ai = lower; ai != upper; ++ai) {
00643 int frame = (*ai).first;
00644 const Action &action = (*ai).second;
00645
00646 if (sequence_frame != -1 && frame < sequence_frame) {
00647
00648
00649
00650
00651 do_sequence_action(sequence_frame, *sequence_action);
00652 return false;
00653 }
00654
00655 do_action(frame, action, sequence_frame, sequence_action);
00656 }
00657
00658 if (sequence_frame != -1) {
00659 do_sequence_action(sequence_frame, *sequence_action);
00660 return false;
00661 }
00662 }
00663
00664 return true;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 void AnimControl::
00679 do_action(int frame, const Action &action,
00680 int &sequence_frame, const Action *&sequence_action) {
00681 switch (action._type) {
00682 case AT_stop:
00683 case AT_jump:
00684 sequence_frame = frame;
00685 sequence_action = &action;
00686 break;
00687
00688 case AT_forward:
00689
00690
00691 if (_play_rate < 0.0f) {
00692 sequence_frame = frame;
00693 sequence_action = &action;
00694 }
00695 break;
00696
00697 case AT_backward:
00698
00699
00700 if (_play_rate > 0.0f) {
00701 sequence_frame = frame;
00702 sequence_action = &action;
00703 }
00704 break;
00705
00706 case AT_event:
00707 throw_event(action._event);
00708 break;
00709
00710 default:
00711 chan_cat.error() << "Invalid action!\n";
00712 abort();
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 void AnimControl::
00726 do_sequence_action(int frame, const Action &action) {
00727 switch (action._type) {
00728 case AT_stop:
00729 stop();
00730 break;
00731
00732 case AT_jump:
00733 set_frame(action._jump_to);
00734 break;
00735
00736 case AT_forward:
00737 case AT_backward:
00738 _play_rate = -_play_rate;
00739 set_frame(frame);
00740 break;
00741
00742 case AT_event:
00743 default:
00744 chan_cat.error() << "Invalid sequence action!\n";
00745 abort();
00746 }
00747 }
00748
00749
00750
00751
00752
00753
00754 void AnimControl::Action::
00755 output(ostream &out) const {
00756 switch (_type) {
00757 case AT_event:
00758 out << "event " << *_event;
00759 break;
00760
00761 case AT_stop:
00762 out << "stop";
00763 break;
00764
00765 case AT_jump:
00766 out << "jump to " << _jump_to;
00767 break;
00768
00769 case AT_forward:
00770 out << "forward";
00771 break;
00772
00773 case AT_backward:
00774 out << "backward";
00775 break;
00776
00777 default:
00778 out << "**error**";
00779 }
00780 }