00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "partGroup.h"
00016 #include "animGroup.h"
00017 #include "config_chan.h"
00018 #include "partSubset.h"
00019
00020 #include "indent.h"
00021 #include "datagram.h"
00022 #include "datagramIterator.h"
00023 #include "bamReader.h"
00024 #include "bamWriter.h"
00025
00026 #include <algorithm>
00027
00028 TypeHandle PartGroup::_type_handle;
00029
00030
00031
00032
00033
00034
00035
00036
00037 PartGroup::
00038 PartGroup(PartGroup *parent, const string &name) :
00039 Namable(name),
00040 _children(get_class_type())
00041 {
00042 nassertv(parent != NULL);
00043
00044 parent->_children.push_back(this);
00045 }
00046
00047
00048
00049
00050
00051
00052 PartGroup::
00053 ~PartGroup() {
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063 bool PartGroup::
00064 is_character_joint() const {
00065 return false;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074 PartGroup *PartGroup::
00075 make_copy() const {
00076 return new PartGroup(*this);
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 PartGroup *PartGroup::
00086 copy_subgraph() const {
00087 PartGroup *root = make_copy();
00088
00089 if (root->get_type() != get_type()) {
00090 chan_cat.warning()
00091 << "Don't know how to copy " << get_type() << "\n";
00092 }
00093
00094 Children::const_iterator ci;
00095 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00096 PartGroup *child = (*ci)->copy_subgraph();
00097 root->_children.push_back(child);
00098 }
00099
00100 return root;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 int PartGroup::
00110 get_num_children() const {
00111 return _children.size();
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 PartGroup *PartGroup::
00121 get_child(int n) const {
00122 nassertr(n >= 0 && n < (int)_children.size(), NULL);
00123 return _children[n];
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 PartGroup *PartGroup::
00136 get_child_named(const string &name) const {
00137 Children::const_iterator ci;
00138 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00139 PartGroup *child = (*ci);
00140 if (child->get_name() == name) {
00141 return child;
00142 }
00143 }
00144
00145 return (PartGroup *)NULL;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 PartGroup *PartGroup::
00157 find_child(const string &name) const {
00158 Children::const_iterator ci;
00159 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00160 PartGroup *child = (*ci);
00161 if (child->get_name() == name) {
00162 return child;
00163 }
00164 PartGroup *result = child->find_child(name);
00165 if (result != (PartGroup *)NULL) {
00166 return result;
00167 }
00168 }
00169
00170 return (PartGroup *)NULL;
00171 }
00172
00173
00174 class PartGroupAlphabeticalOrder {
00175 public:
00176 bool operator()(const PT(PartGroup) &a, const PT(PartGroup) &b) const {
00177 return a->get_name() < b->get_name();
00178 }
00179 };
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void PartGroup::
00191 sort_descendants() {
00192 stable_sort(_children.begin(), _children.end(), PartGroupAlphabeticalOrder());
00193
00194 Children::iterator ci;
00195 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00196 (*ci)->sort_descendants();
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 bool PartGroup::
00212 apply_freeze(const TransformState *transform) {
00213 return apply_freeze_matrix(transform->get_pos(), transform->get_hpr(), transform->get_scale()) || apply_freeze_scalar(transform->get_pos()[0]);
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 bool PartGroup::
00228 apply_freeze_matrix(const LVecBase3 &pos, const LVecBase3 &hpr, const LVecBase3 &scale) {
00229 return false;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 bool PartGroup::
00244 apply_freeze_scalar(PN_stdfloat value) {
00245 return false;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 bool PartGroup::
00262 apply_control(PandaNode *node) {
00263 return false;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 bool PartGroup::
00278 clear_forced_channel() {
00279 return false;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 AnimChannelBase *PartGroup::
00291 get_forced_channel() const {
00292 return NULL;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302 void PartGroup::
00303 write(ostream &out, int indent_level) const {
00304 indent(out, indent_level)
00305 << get_type() << " " << get_name() << " {\n";
00306 write_descendants(out, indent_level + 2);
00307 indent(out, indent_level) << "}\n";
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void PartGroup::
00317 write_with_value(ostream &out, int indent_level) const {
00318 indent(out, indent_level)
00319 << get_type() << " " << get_name() << " {\n";
00320 write_descendants_with_value(out, indent_level + 2);
00321 indent(out, indent_level) << "}\n";
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 TypeHandle PartGroup::
00333 get_value_type() const {
00334 return TypeHandle::none();
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 bool PartGroup::
00351 check_hierarchy(const AnimGroup *anim, const PartGroup *,
00352 int hierarchy_match_flags) const {
00353 Thread::consider_yield();
00354 if (anim->get_value_type() != get_value_type()) {
00355 if (chan_cat.is_error()) {
00356 chan_cat.error()
00357 << "Part " << get_name() << " expects type " << get_value_type()
00358 << " while matching anim node has type " << anim->get_value_type()
00359 << ".\n";
00360 }
00361 return false;
00362 }
00363
00364 if (chan_cat.is_info()) {
00365
00366
00367
00368
00369 bool match = true;
00370 if (anim->get_num_children() != get_num_children()) {
00371
00372
00373
00374
00375 if (anim->get_num_children() == get_num_children() + 1 &&
00376 anim->get_child_named("morph") != NULL &&
00377 get_child_named("morph") == NULL) {
00378
00379
00380
00381 } else if (get_num_children() == anim->get_num_children() + 1 &&
00382 get_child_named("morph") != NULL &&
00383 anim->get_child_named("morph") == NULL) {
00384
00385
00386
00387 } else {
00388 chan_cat.info()
00389 << "Part " << get_name() << " has " << get_num_children()
00390 << " children, while matching anim node has "
00391 << anim->get_num_children() << ":\n";
00392 match = false;
00393 }
00394
00395 } else {
00396 for (int i = 0; match && i < get_num_children(); i++) {
00397 PartGroup *pc = get_child(i);
00398 AnimGroup *ac = anim->get_child(i);
00399
00400 match = (pc->get_name() == ac->get_name());
00401 }
00402 if (!match) {
00403 chan_cat.info()
00404 << "Part " << get_name() << " has a different set of children "
00405 << " than matching anim node:\n";
00406 }
00407 }
00408 if (!match) {
00409 int i = 0, j = 0;
00410 while (i < get_num_children() &&
00411 j < anim->get_num_children()) {
00412 PartGroup *pc = get_child(i);
00413 AnimGroup *ac = anim->get_child(j);
00414
00415 if (pc->get_name() < ac->get_name()) {
00416 chan_cat.info()
00417 << " part has " << pc->get_name()
00418 << ", not in anim.\n";
00419 i++;
00420 } else if (ac->get_name() < pc->get_name()) {
00421 chan_cat.info()
00422 << " anim has " << ac->get_name()
00423 << ", not in part.\n";
00424 j++;
00425 } else {
00426
00427 i++;
00428 j++;
00429 }
00430 }
00431
00432 while (i < get_num_children()) {
00433 PartGroup *pc = get_child(i);
00434 chan_cat.info()
00435 << " part has " << pc->get_name()
00436 << ", not in anim.\n";
00437 i++;
00438 }
00439
00440 while (j < anim->get_num_children()) {
00441 AnimGroup *ac = anim->get_child(j);
00442 chan_cat.info()
00443 << " anim has " << ac->get_name()
00444 << ", not in part.\n";
00445 j++;
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453 int i = 0, j = 0;
00454 while (i < get_num_children() &&
00455 j < anim->get_num_children()) {
00456 PartGroup *pc = get_child(i);
00457 AnimGroup *ac = anim->get_child(j);
00458
00459 if (pc->get_name() < ac->get_name()) {
00460 if (pc->get_name() == "morph") {
00461
00462 } else {
00463 if ((hierarchy_match_flags & HMF_ok_part_extra) == 0) {
00464 return false;
00465 }
00466 }
00467 i++;
00468 } else if (ac->get_name() < pc->get_name()) {
00469 if (ac->get_name() == "morph") {
00470
00471 } else {
00472 if ((hierarchy_match_flags & HMF_ok_anim_extra) == 0) {
00473 return false;
00474 }
00475 }
00476 j++;
00477 } else {
00478 if (!pc->check_hierarchy(ac, this, hierarchy_match_flags)) {
00479 return false;
00480 }
00481 i++;
00482 j++;
00483 }
00484 }
00485
00486 while (i < get_num_children()) {
00487
00488 PartGroup *pc = get_child(i);
00489
00490 if (pc->get_name() == "morph") {
00491
00492 } else {
00493 if ((hierarchy_match_flags & HMF_ok_part_extra) == 0) {
00494 return false;
00495 }
00496 }
00497 i++;
00498 }
00499
00500 while (j < anim->get_num_children()) {
00501
00502 AnimGroup *ac = anim->get_child(j);
00503
00504 if (ac->get_name() == "morph") {
00505
00506 } else {
00507 if ((hierarchy_match_flags & HMF_ok_anim_extra) == 0) {
00508 return false;
00509 }
00510 }
00511 j++;
00512 }
00513
00514 return true;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 bool PartGroup::
00531 do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *,
00532 bool parent_changed, bool anim_changed, Thread *current_thread) {
00533 bool any_changed = false;
00534
00535 Children::iterator ci;
00536 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00537 if ((*ci)->do_update(root, root_cdata, this, parent_changed,
00538 anim_changed, current_thread)) {
00539 any_changed = true;
00540 }
00541 }
00542
00543 return any_changed;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553 void PartGroup::
00554 do_xform(const LMatrix4 &mat, const LMatrix4 &inv_mat) {
00555 Children::const_iterator ci;
00556
00557 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00558 (*ci)->do_xform(mat, inv_mat);
00559 }
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569 void PartGroup::
00570 determine_effective_channels(const CycleData *root_cdata) {
00571 Children::iterator ci;
00572 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00573 (*ci)->determine_effective_channels(root_cdata);
00574 }
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584 void PartGroup::
00585 write_descendants(ostream &out, int indent_level) const {
00586 Children::const_iterator ci;
00587
00588 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00589 (*ci)->write(out, indent_level);
00590 }
00591 }
00592
00593
00594
00595
00596
00597
00598
00599 void PartGroup::
00600 write_descendants_with_value(ostream &out, int indent_level) const {
00601 Children::const_iterator ci;
00602
00603 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00604 (*ci)->write_with_value(out, indent_level);
00605 }
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 void PartGroup::
00617 pick_channel_index(plist<int> &holes, int &next) const {
00618 Children::const_iterator ci;
00619 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00620 (*ci)->pick_channel_index(holes, next);
00621 }
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631 void PartGroup::
00632 bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
00633 bool is_included, BitArray &bound_joints,
00634 const PartSubset &subset) {
00635 Thread::consider_yield();
00636 if (subset.matches_include(get_name())) {
00637 is_included = true;
00638 } else if (subset.matches_exclude(get_name())) {
00639 is_included = false;
00640 }
00641
00642 int i = 0, j = 0;
00643 int part_num_children = get_num_children();
00644 int anim_num_children = (anim == NULL) ? 0 : anim->get_num_children();
00645
00646 while (i < part_num_children && j < anim_num_children) {
00647 PartGroup *pc = get_child(i);
00648 AnimGroup *ac = anim->get_child(j);
00649
00650 if (pc->get_name() < ac->get_name()) {
00651
00652
00653 pc->bind_hierarchy(NULL, channel_index, joint_index, is_included,
00654 bound_joints, subset);
00655 i++;
00656
00657 } else if (ac->get_name() < pc->get_name()) {
00658
00659 j++;
00660
00661 } else {
00662
00663 pc->bind_hierarchy(ac, channel_index, joint_index, is_included,
00664 bound_joints, subset);
00665 i++;
00666 j++;
00667 }
00668 }
00669
00670
00671 while (i < part_num_children) {
00672 PartGroup *pc = get_child(i);
00673 pc->bind_hierarchy(NULL, channel_index, joint_index, is_included,
00674 bound_joints, subset);
00675 i++;
00676 }
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 void PartGroup::
00691 find_bound_joints(int &joint_index, bool is_included, BitArray &bound_joints,
00692 const PartSubset &subset) {
00693 if (subset.matches_include(get_name())) {
00694 is_included = true;
00695 } else if (subset.matches_exclude(get_name())) {
00696 is_included = false;
00697 }
00698
00699 int part_num_children = get_num_children();
00700 for (int i = 0; i < part_num_children; ++i) {
00701 PartGroup *pc = get_child(i);
00702 pc->find_bound_joints(joint_index, is_included, bound_joints, subset);
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 void PartGroup::
00713 write_datagram(BamWriter *manager, Datagram &me) {
00714 me.add_string(get_name());
00715 me.add_uint16(_children.size());
00716 for (size_t i = 0; i < _children.size(); i++) {
00717 manager->write_pointer(me, _children[i]);
00718 }
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 void PartGroup::
00730 fillin(DatagramIterator &scan, BamReader *manager) {
00731 set_name(scan.get_string());
00732
00733 if (manager->get_file_minor_ver() == 11) {
00734
00735 scan.get_bool();
00736 LMatrix4 mat;
00737 mat.read_datagram(scan);
00738 }
00739
00740 int num_children = scan.get_uint16();
00741 _children.reserve(num_children);
00742 for (int i = 0; i < num_children; i++) {
00743 manager->read_pointer(scan);
00744 _children.push_back(NULL);
00745 }
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755 int PartGroup::
00756 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00757 int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
00758
00759 Children::iterator ci;
00760 for (ci = _children.begin(); ci != _children.end(); ++ci) {
00761 (*ci) = DCAST(PartGroup, p_list[pi++]);
00762 }
00763
00764 return pi;
00765 }
00766
00767
00768
00769
00770
00771
00772 TypedWritable* PartGroup::
00773 make_PartGroup(const FactoryParams ¶ms) {
00774 PartGroup *me = new PartGroup;
00775 DatagramIterator scan;
00776 BamReader *manager;
00777
00778 parse_params(params, scan, manager);
00779 me->fillin(scan, manager);
00780 return me;
00781 }
00782
00783
00784
00785
00786
00787
00788 void PartGroup::
00789 register_with_read_factory() {
00790 BamReader::get_factory()->register_factory(get_class_type(), make_PartGroup);
00791 }
00792