00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "mayaNodeTree.h"
00016 #include "mayaBlendDesc.h"
00017 #include "mayaEggGroupUserData.h"
00018 #include "mayaToEggConverter.h"
00019 #include "config_mayaegg.h"
00020 #include "maya_funcs.h"
00021 #include "eggGroup.h"
00022 #include "eggTable.h"
00023 #include "eggXfmSAnim.h"
00024 #include "eggSAnimData.h"
00025 #include "eggData.h"
00026 #include "eggSwitchCondition.h"
00027 #include "dcast.h"
00028
00029 #include "pre_maya_include.h"
00030 #include <maya/MString.h>
00031 #include <maya/MItDag.h>
00032 #include <maya/MSelectionList.h>
00033 #include <maya/MGlobal.h>
00034 #include "post_maya_include.h"
00035
00036
00037
00038
00039
00040
00041 MayaNodeTree::
00042 MayaNodeTree(MayaToEggConverter *converter) :
00043 _converter(converter)
00044 {
00045 _root = new MayaNodeDesc(this);
00046 _fps = 0.0;
00047 _egg_data = (EggData *)NULL;
00048 _egg_root = (EggGroupNode *)NULL;
00049 _skeleton_node = (EggGroupNode *)NULL;
00050 _morph_node = (EggGroupNode *)NULL;
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060 MayaNodeDesc *MayaNodeTree::
00061 build_node(const MDagPath &dag_path) {
00062 MayaNodeDesc *node_desc = r_build_node(dag_path.fullPathName().asChar());
00063 node_desc->from_dag_path(dag_path, _converter);
00064 return node_desc;
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 bool MayaNodeTree::
00074 build_hierarchy() {
00075 MStatus status;
00076
00077 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
00078 if (!status) {
00079 status.perror("MItDag constructor");
00080 return false;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 bool all_ok = true;
00094 while (!dag_iterator.isDone()) {
00095 MDagPath dag_path;
00096 status = dag_iterator.getPath(dag_path);
00097 if (!status) {
00098 status.perror("MItDag::getPath");
00099 } else {
00100 build_node(dag_path);
00101 }
00102
00103 dag_iterator.next();
00104 }
00105
00106 if (all_ok) {
00107 _root->check_pseudo_joints(false);
00108 _root->check_lods();
00109 }
00110
00111 return all_ok;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120 void MayaNodeTree::
00121 tag_joint_all() {
00122 _root->tag_joint_recursively();
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 bool MayaNodeTree::
00134 tag_joint_named(const GlobPattern &glob) {
00135
00136
00137 bool found_any = false;
00138
00139 Nodes::iterator ni;
00140 for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
00141 MayaNodeDesc *node = (*ni);
00142 if (glob.matches(node->get_name())) {
00143 node->tag_joint_recursively();
00144 found_any = true;
00145 }
00146 }
00147
00148 return found_any;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 void MayaNodeTree::
00158 tag_all() {
00159 _root->tag_recursively();
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 bool MayaNodeTree::
00171 tag_named(const GlobPattern &glob) {
00172
00173
00174 bool found_any = false;
00175
00176 Nodes::iterator ni;
00177 for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
00178 MayaNodeDesc *node = (*ni);
00179 if (glob.matches(node->get_name())) {
00180 node->tag_recursively();
00181 found_any = true;
00182 }
00183 }
00184
00185 return found_any;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 bool MayaNodeTree::
00197 untag_named(const GlobPattern &glob) {
00198
00199
00200 bool found_any = false;
00201
00202 Nodes::iterator ni;
00203 for (ni = _nodes.begin(); ni != _nodes.end(); ++ni) {
00204 MayaNodeDesc *node = (*ni);
00205 if (glob.matches(node->get_name())) {
00206 node->untag_recursively();
00207 found_any = true;
00208 }
00209 }
00210
00211 return found_any;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221 bool MayaNodeTree::
00222 tag_selected() {
00223 MStatus status;
00224
00225 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
00226 if (!status) {
00227 status.perror("MItDag constructor");
00228 return false;
00229 }
00230
00231 MSelectionList selection;
00232 status = MGlobal::getActiveSelectionList(selection);
00233 if (!status) {
00234 status.perror("MGlobal::getActiveSelectionList");
00235 return false;
00236 }
00237
00238 if (selection.isEmpty()) {
00239 mayaegg_cat.info()
00240 << "Selection list is empty.\n";
00241 tag_all();
00242 return true;
00243 }
00244
00245 bool all_ok = true;
00246 unsigned int length = selection.length();
00247 for (unsigned int i = 0; i < length; i++) {
00248 MDagPath root_path;
00249 status = selection.getDagPath(i, root_path);
00250 if (!status) {
00251 status.perror("MSelectionList::getDagPath");
00252 } else {
00253
00254
00255 dag_iterator.reset(root_path);
00256 while (!dag_iterator.isDone()) {
00257 MDagPath dag_path;
00258 status = dag_iterator.getPath(dag_path);
00259 if (!status) {
00260 status.perror("MItDag::getPath");
00261 } else {
00262 build_node(dag_path)->tag();
00263 }
00264
00265 dag_iterator.next();
00266 }
00267 }
00268 }
00269
00270 if (all_ok) {
00271 _root->check_pseudo_joints(false);
00272 }
00273
00274 return all_ok;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 int MayaNodeTree::
00284 get_num_nodes() const {
00285 return _nodes.size();
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 MayaNodeDesc *MayaNodeTree::
00295 get_node(int n) const {
00296 nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
00297 return _nodes[n];
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 void MayaNodeTree::
00307 clear() {
00308 _root = new MayaNodeDesc(this);
00309 _fps = 0.0;
00310 _egg_data = (EggData *)NULL;
00311 _egg_root = (EggGroupNode *)NULL;
00312 _skeleton_node = (EggGroupNode *)NULL;
00313 _morph_node = (EggGroupNode *)NULL;
00314 _nodes_by_path.clear();
00315 _nodes.clear();
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 void MayaNodeTree::
00326 clear_egg(EggData *egg_data, EggGroupNode *egg_root,
00327 EggGroupNode *skeleton_node, EggGroupNode *morph_node) {
00328 _root->clear_egg();
00329 BlendDescs::iterator bi;
00330 for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
00331 (*bi)->clear_egg();
00332 }
00333
00334 _egg_data = egg_data;
00335 _egg_root = egg_root;
00336 _skeleton_node = skeleton_node;
00337 _morph_node = morph_node;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 EggGroup *MayaNodeTree::
00348 get_egg_group(MayaNodeDesc *node_desc) {
00349 nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
00350
00351 if (node_desc->_egg_group == (EggGroup *)NULL) {
00352
00353 EggGroup *egg_group;
00354
00355 nassertr(node_desc->_parent != (MayaNodeDesc *)NULL, NULL);
00356 egg_group = new EggGroup(node_desc->get_name());
00357 if (node_desc->is_joint()) {
00358 if (_converter->get_animation_convert() == AC_model ||
00359 _converter->get_animation_convert() == AC_both) {
00360 egg_group->set_group_type(EggGroup::GT_joint);
00361 }
00362 }
00363
00364 MayaEggGroupUserData *parent_user_data = NULL;
00365
00366 if (node_desc->_parent == _root) {
00367
00368 _egg_root->add_child(egg_group);
00369
00370 } else {
00371
00372 EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
00373 parent_egg_group->add_child(egg_group);
00374
00375 if (parent_egg_group->has_user_data()) {
00376 DCAST_INTO_R(parent_user_data, parent_egg_group->get_user_data(), NULL);
00377 }
00378 }
00379
00380 if (node_desc->has_dag_path()) {
00381
00382 MObject dag_object = node_desc->get_dag_path().node();
00383 string object_type;
00384 LVector3d value;
00385 if (get_enum_attribute(dag_object, "eggObjectTypes1", object_type)) {
00386 egg_group->add_object_type(object_type);
00387 }
00388 if (get_enum_attribute(dag_object, "eggObjectTypes2", object_type)) {
00389 egg_group->add_object_type(object_type);
00390 }
00391 if (get_enum_attribute(dag_object, "eggObjectTypes3", object_type)) {
00392 egg_group->add_object_type(object_type);
00393 }
00394
00395 if(has_attribute(dag_object, "scrollUV")) {
00396 if(get_vec3d_attribute(dag_object, "scrollUV", value)) {
00397 egg_group->set_scroll_u(value[0]);
00398 egg_group->set_scroll_v(value[1]);
00399 egg_group->set_scroll_r(value[2]);
00400 }
00401 }
00402
00403 pvector<string> tag_attribute_names;
00404 get_tag_attribute_names(dag_object, tag_attribute_names);
00405 for (uint ti=0; ti < tag_attribute_names.size(); ti++) {
00406 if (get_enum_attribute(dag_object, tag_attribute_names[ti], object_type)) {
00407 egg_group->set_tag(tag_attribute_names[ti].substr(3), object_type);
00408 }
00409 }
00410
00411
00412
00413
00414
00415 bool visible = true;
00416 get_bool_attribute(dag_object, "visibility", visible);
00417 if (!visible && egg_group->get_num_object_types() == 0) {
00418 egg_group->set_visibility_mode(EggGroup::VM_hidden);
00419 }
00420
00421
00422
00423
00424 if (egg_group->has_object_type("billboard")) {
00425 egg_group->remove_object_type("billboard");
00426 egg_group->set_group_type(EggGroup::GT_instance);
00427 egg_group->set_billboard_type(EggGroup::BT_axis);
00428
00429 } else if (egg_group->has_object_type("billboard-point")) {
00430 egg_group->remove_object_type("billboard-point");
00431 egg_group->set_group_type(EggGroup::GT_instance);
00432 egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
00433
00434 } else if (egg_group->has_object_type("bbpoint")) {
00435 egg_group->remove_object_type("bbpoint");
00436 egg_group->set_group_type(EggGroup::GT_instance);
00437 egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
00438 }
00439
00440
00441
00442 if (egg_group->has_object_type("dcs")) {
00443 egg_group->remove_object_type("dcs");
00444 egg_group->set_dcs_type(EggGroup::DC_default);
00445 }
00446 if (egg_group->has_object_type("model")) {
00447 egg_group->remove_object_type("model");
00448 egg_group->set_model_flag(true);
00449 }
00450
00451
00452
00453 MayaEggGroupUserData *user_data;
00454 if (parent_user_data == (MayaEggGroupUserData *)NULL) {
00455 user_data = new MayaEggGroupUserData;
00456 } else {
00457
00458 user_data = new MayaEggGroupUserData(*parent_user_data);
00459 }
00460
00461 if (egg_group->has_object_type("vertex-color")) {
00462 egg_group->remove_object_type("vertex-color");
00463 user_data->_vertex_color = true;
00464 }
00465 if (egg_group->has_object_type("double-sided")) {
00466 egg_group->remove_object_type("double-sided");
00467 user_data->_double_sided = true;
00468 }
00469 egg_group->set_user_data(user_data);
00470 }
00471
00472 if (node_desc->_is_lod) {
00473
00474 egg_group->set_lod(EggSwitchConditionDistance(node_desc->_switch_in,
00475 node_desc->_switch_out,
00476 LPoint3d::zero()));
00477 }
00478
00479 node_desc->_egg_group = egg_group;
00480 }
00481
00482 return node_desc->_egg_group;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492 EggTable *MayaNodeTree::
00493 get_egg_table(MayaNodeDesc *node_desc) {
00494 nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
00495 nassertr(node_desc->is_joint(), NULL);
00496
00497 if (node_desc->_egg_table == (EggTable *)NULL) {
00498
00499 nassertr(node_desc->_parent != (MayaNodeDesc *)NULL, NULL);
00500
00501 EggTable *egg_table = new EggTable(node_desc->get_name());
00502 node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
00503 node_desc->_anim->set_fps(_fps);
00504 egg_table->add_child(node_desc->_anim);
00505
00506 if (!node_desc->_parent->is_joint()) {
00507
00508 _skeleton_node->add_child(egg_table);
00509
00510 } else {
00511
00512 EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
00513 parent_egg_table->add_child(egg_table);
00514 }
00515
00516 node_desc->_egg_table = egg_table;
00517 }
00518
00519 return node_desc->_egg_table;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 EggXfmSAnim *MayaNodeTree::
00530 get_egg_anim(MayaNodeDesc *node_desc) {
00531 get_egg_table(node_desc);
00532 return node_desc->_anim;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542 EggSAnimData *MayaNodeTree::
00543 get_egg_slider(MayaBlendDesc *blend_desc) {
00544 nassertr(_morph_node != (EggGroupNode *)NULL, NULL);
00545
00546 if (blend_desc->_anim == (EggSAnimData *)NULL) {
00547
00548 EggSAnimData *egg_anim = new EggSAnimData(blend_desc->get_name());
00549 egg_anim->set_fps(_fps);
00550 _morph_node->add_child(egg_anim);
00551
00552 blend_desc->_anim = egg_anim;
00553 }
00554
00555 return blend_desc->_anim;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564 bool MayaNodeTree::
00565 ignore_slider(const string &name) const {
00566 return _converter->ignore_slider(name);
00567 }
00568
00569
00570
00571
00572
00573
00574
00575 void MayaNodeTree::
00576 report_ignored_slider(const string &name) {
00577 if (_ignored_slider_names.insert(name).second) {
00578 mayaegg_cat.info()
00579 << "Ignoring slider " << name << "\n";
00580 }
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 MayaBlendDesc *MayaNodeTree::
00598 add_blend_desc(MayaBlendDesc *blend_desc) {
00599 BlendDescs::iterator bi = _blend_descs.insert(blend_desc).first;
00600
00601 return (*bi);
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611 int MayaNodeTree::
00612 get_num_blend_descs() const {
00613 return _blend_descs.size();
00614 }
00615
00616
00617
00618
00619
00620
00621
00622 MayaBlendDesc *MayaNodeTree::
00623 get_blend_desc(int n) const {
00624 nassertr(n >= 0 && n < (int)_blend_descs.size(), NULL);
00625 return _blend_descs[n];
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 void MayaNodeTree::
00635 reset_sliders() {
00636 BlendDescs::iterator bi;
00637 for (bi = _blend_descs.begin(); bi != _blend_descs.end(); ++bi) {
00638 (*bi)->set_slider(0.0);
00639 }
00640 }
00641
00642
00643
00644
00645
00646
00647
00648 MayaNodeDesc *MayaNodeTree::
00649 r_build_node(const string &path) {
00650
00651
00652 NodesByPath::const_iterator ni = _nodes_by_path.find(path);
00653 if (ni != _nodes_by_path.end()) {
00654 return (*ni).second;
00655 }
00656
00657
00658
00659 MayaNodeDesc *node_desc;
00660
00661
00662 if (path.empty()) {
00663
00664
00665 node_desc = _root;
00666
00667 } else {
00668
00669
00670
00671 size_t bar = path.rfind("|");
00672 string parent_path, local_name;
00673 if (bar != string::npos) {
00674 parent_path = path.substr(0, bar);
00675
00676 local_name = path.substr(bar + 1);
00677 if (local_name == _subroot_parent_name) {
00678 node_desc = _root;
00679 }
00680 } else {
00681 local_name = path;
00682 }
00683
00684
00685 if (node_desc != _root) {
00686 MayaNodeDesc *parent_node_desc = r_build_node(parent_path);
00687 if (parent_node_desc == (MayaNodeDesc *)NULL)
00688 mayaegg_cat.info() << "empty parent: " << local_name << endl;
00689 node_desc = new MayaNodeDesc(this, parent_node_desc, local_name);
00690 _nodes.push_back(node_desc);
00691 }
00692 }
00693
00694 _nodes_by_path.insert(NodesByPath::value_type(path, node_desc));
00695 return node_desc;
00696 }