00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "maxEgg.h"
00017
00018
00019 #ifndef _M
00020 #define _M(s) (s)
00021 #endif
00022
00023
00024
00025
00026
00027
00028 MaxNodeTree::
00029 MaxNodeTree() {
00030 _root = new MaxNodeDesc;
00031 _fps = 0.0;
00032 _export_mesh = false;
00033 _egg_data = (EggData *)NULL;
00034 _egg_root = (EggGroupNode *)NULL;
00035 _skeleton_node = (EggGroupNode *)NULL;
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045 MaxNodeDesc *MaxNodeTree::
00046 build_node(INode *max_node) {
00047 MaxNodeDesc *node_desc = r_build_node(max_node);
00048 node_desc->from_INode(max_node);
00049 if (node_desc->is_node_joint())
00050 node_desc->_joint_entry = build_joint(max_node, node_desc);
00051 return node_desc;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 MaxNodeDesc *MaxNodeTree::
00062 build_joint(INode *max_node, MaxNodeDesc *node_joint) {
00063 MaxNodeDesc *node_desc = r_build_joint(node_joint, max_node);
00064 node_desc->from_INode(max_node);
00065 node_desc->set_joint(true);
00066 return node_desc;
00067 }
00068
00069 bool MaxNodeTree::node_in_list(ULONG handle, ULONG *list, int len) {
00070 if (!list) return true;
00071 for (int i = 0; i < len; i++)
00072 if (list[i] == handle) return true;
00073 return false;
00074 }
00075
00076 bool MaxNodeTree::is_joint(INode *node) {
00077 Control *c = node->GetTMController();
00078 return (node->GetBoneNodeOnOff() ||
00079 (c &&
00080 ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
00081 (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
00082 (c->ClassID() == FOOTPRINT_CLASS_ID))));
00083 }
00084
00085 bool MaxNodeTree::
00086 r_build_hierarchy(INode *root, ULONG *selection_list, int len) {
00087 if (node_in_list(root->GetHandle(), selection_list, len))
00088 build_node(root);
00089
00090 for ( int i = 0; i < root->NumberOfChildren(); i++ ) {
00091
00092 r_build_hierarchy(root->GetChildNode(i), selection_list, len);
00093 }
00094 return true;
00095 }
00096
00097
00098
00099
00100
00101
00102 bool MaxNodeTree::
00103 build_complete_hierarchy(INode *root, ULONG *selection_list, int len) {
00104
00105
00106 if (root == NULL) {
00107
00108 return false;
00109 }
00110
00111 bool all_ok = true;
00112 r_build_hierarchy(root, selection_list, len);
00113
00114 if (all_ok) {
00115 _root->check_pseudo_joints(false);
00116 }
00117
00118 return all_ok;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 int MaxNodeTree::
00128 get_num_nodes() const {
00129 return _nodes.size();
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 MaxNodeDesc *MaxNodeTree::
00139 get_node(int n) const {
00140 nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
00141 return _nodes[n];
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 void MaxNodeTree::
00152 clear_egg(EggData *egg_data, EggGroupNode *egg_root,
00153 EggGroupNode *skeleton_node) {
00154 _root->clear_egg();
00155 _egg_data = egg_data;
00156 _egg_root = egg_root;
00157 _skeleton_node = skeleton_node;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167 EggGroup *MaxNodeTree::
00168 get_egg_group(MaxNodeDesc *node_desc) {
00169 nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
00170
00171 if (node_desc->_egg_group == (EggGroup *)NULL) {
00172
00173 EggGroup *egg_group;
00174
00175 nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
00176 egg_group = new EggGroup(node_desc->get_name());
00177 if (node_desc->is_joint()) {
00178 egg_group->set_group_type(EggGroup::GT_joint);
00179 }
00180 if (node_desc->_parent == _root) {
00181
00182
00183 if(!_export_mesh)
00184 {
00185 set_collision_tags(node_desc, egg_group);
00186 }
00187 _egg_root->add_child(egg_group);
00188
00189 } else {
00190
00191
00192 if(_export_mesh)
00193 {
00194 if(node_desc->_parent->_parent == _root)
00195 {
00196 set_collision_tags(node_desc, egg_group);
00197 }
00198 }
00199 EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
00200 parent_egg_group->add_child(egg_group);
00201 }
00202
00203 node_desc->_egg_group = egg_group;
00204 }
00205
00206 return node_desc->_egg_group;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 EggTable *MaxNodeTree::
00217 get_egg_table(MaxNodeDesc *node_desc) {
00218 nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
00219 nassertr(node_desc->is_joint(), NULL);
00220
00221 if (node_desc->_egg_table == (EggTable *)NULL) {
00222
00223 nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
00224
00225 EggTable *egg_table = new EggTable(node_desc->get_name());
00226 node_desc->_anim = new EggXfmSAnim("xform",
00227 _egg_data->get_coordinate_system());
00228 node_desc->_anim->set_fps(_fps);
00229 egg_table->add_child(node_desc->_anim);
00230
00231 if (!node_desc->_parent->is_joint()) {
00232
00233 _skeleton_node->add_child(egg_table);
00234
00235 } else {
00236
00237 EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
00238 parent_egg_table->add_child(egg_table);
00239 }
00240
00241 node_desc->_egg_table = egg_table;
00242 }
00243
00244 return node_desc->_egg_table;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254 EggXfmSAnim *MaxNodeTree::
00255 get_egg_anim(MaxNodeDesc *node_desc)
00256 {
00257 get_egg_table(node_desc);
00258 return node_desc->_anim;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 MaxNodeDesc *MaxNodeTree::
00268 r_build_node(INode* max_node)
00269 {
00270
00271
00272
00273 ULONG node_handle = 0;
00274
00275 if (max_node) {
00276 node_handle = max_node->GetHandle();
00277 }
00278
00279 NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
00280 if (ni != _nodes_by_path.end()) {
00281 return (*ni).second;
00282 }
00283
00284
00285
00286 MaxNodeDesc *node_desc;
00287
00288 if (!max_node) {
00289
00290 node_desc = _root;
00291
00292 } else {
00293 INode *parent_node;
00294 string local_name = max_node->GetName();
00295 if (max_node->IsRootNode()) {
00296 parent_node = NULL;
00297 } else {
00298 parent_node = max_node->GetParentNode();
00299 }
00300
00301 MaxNodeDesc *parent_node_desc = r_build_node(parent_node);
00302 node_desc = new MaxNodeDesc(parent_node_desc, local_name);
00303 _nodes.push_back(node_desc);
00304 }
00305
00306 _nodes_by_path.insert(NodesByPath::value_type(node_handle, node_desc));
00307 return node_desc;
00308 }
00309
00310
00311
00312
00313
00314
00315 MaxNodeDesc *MaxNodeTree::
00316 r_build_joint(MaxNodeDesc *node_desc, INode *max_node)
00317 {
00318 MaxNodeDesc *node_joint;
00319 if (node_desc == _root) {
00320 node_joint = new MaxNodeDesc(_root, max_node->GetName());
00321 _nodes.push_back(node_joint);
00322 return node_joint;
00323 } else if (node_desc->is_node_joint() && node_desc->_joint_entry) {
00324 node_joint = new MaxNodeDesc(node_desc->_joint_entry, max_node->GetName());
00325 _nodes.push_back(node_joint);
00326 return node_joint;
00327 } else {
00328 return r_build_joint(node_desc->_parent, max_node);
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337 MaxNodeDesc *MaxNodeTree::
00338 find_node(INode* max_node)
00339 {
00340
00341
00342
00343 ULONG node_handle = 0;
00344
00345 if (max_node) {
00346 node_handle = max_node->GetHandle();
00347 }
00348
00349 NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
00350 if (ni != _nodes_by_path.end()) {
00351 return (*ni).second;
00352 }
00353
00354 return NULL;
00355 }
00356
00357
00358
00359
00360
00361
00362 MaxNodeDesc *MaxNodeTree::
00363 find_joint(INode* max_node)
00364 {
00365 MaxNodeDesc *node = find_node(max_node);
00366 if (!node || (is_joint(max_node) && !node->is_node_joint()))
00367 node = build_node(max_node);
00368 return node->_joint_entry;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378 void MaxNodeTree::set_collision_tags(MaxNodeDesc *node_desc, EggGroup *egg_group) {
00379
00380
00381
00382
00383
00384 int check = 1;
00385
00386
00387
00388 if (node_desc->get_max_node()->GetUserPropInt(_M("polyset"), check)) {
00389
00390 if (check == 1) {
00391 egg_group->set_collision_name(node_desc->get_name());
00392 egg_group->set_cs_type(EggGroup::CST_polyset);
00393 }
00394 }
00395 if (node_desc->get_max_node()->GetUserPropInt(_M("plane"), check)) {
00396
00397 if (check == 1) {
00398 egg_group->set_collision_name(node_desc->get_name());
00399 egg_group->set_cs_type(EggGroup::CST_plane);
00400 }
00401 }
00402 if (node_desc->get_max_node()->GetUserPropInt(_M("polygon"), check)) {
00403
00404 if (check == 1) {
00405 egg_group->set_collision_name(node_desc->get_name());
00406 egg_group->set_cs_type(EggGroup::CST_polygon);
00407 }
00408 }
00409 if (node_desc->get_max_node()->GetUserPropInt(_M("sphere"), check)) {
00410
00411 if (check == 1) {
00412 egg_group->set_collision_name(node_desc->get_name());
00413 egg_group->set_cs_type(EggGroup::CST_sphere);
00414 }
00415 }
00416 if (node_desc->get_max_node()->GetUserPropInt(_M("inv-sphere"), check)) {
00417
00418 if (check == 1) {
00419 egg_group->set_collision_name(node_desc->get_name());
00420 egg_group->set_cs_type(EggGroup::CST_inv_sphere);
00421 }
00422 }
00423 if (node_desc->get_max_node()->GetUserPropInt(_M("invsphere"), check)) {
00424
00425 if (check == 1) {
00426 egg_group->set_collision_name(node_desc->get_name());
00427 egg_group->set_cs_type(EggGroup::CST_inv_sphere);
00428 }
00429 }
00430 if (node_desc->get_max_node()->GetUserPropInt(_M("tube"), check)) {
00431
00432 if (check == 1) {
00433 egg_group->set_collision_name(node_desc->get_name());
00434 egg_group->set_cs_type(EggGroup::CST_tube);
00435 }
00436 }
00437 if (node_desc->get_max_node()->GetUserPropInt(_M("floor-mesh"), check)) {
00438
00439 if (check == 1) {
00440 egg_group->set_collision_name(node_desc->get_name());
00441 egg_group->set_cs_type(EggGroup::CST_floor_mesh);
00442 }
00443 }
00444
00445 if (node_desc->get_max_node()->GetUserPropInt(_M("descend"), check)) {
00446 if (check == 1) {
00447
00448 egg_group->set_collide_flags(EggGroup::CF_descend);
00449 }
00450 }
00451 if (node_desc->get_max_node()->GetUserPropInt(_M("event"), check)) {
00452 if (check == 1) {
00453
00454 egg_group->set_collide_flags(EggGroup::CF_event);
00455 }
00456 }
00457 if (node_desc->get_max_node()->GetUserPropInt(_M("keep"), check)) {
00458 if (check == 1) {
00459
00460 egg_group->set_collide_flags(EggGroup::CF_keep);
00461 }
00462 }
00463 if (node_desc->get_max_node()->GetUserPropInt(_M("solid"), check)) {
00464 if (check == 1) {
00465
00466 egg_group->set_collide_flags(EggGroup::CF_solid);
00467 }
00468 }
00469 if (node_desc->get_max_node()->GetUserPropInt(_M("center"), check)) {
00470 if (check == 1) {
00471
00472 egg_group->set_collide_flags(EggGroup::CF_center);
00473 }
00474 }
00475 if (node_desc->get_max_node()->GetUserPropInt(_M("turnstile"), check)) {
00476 if (check == 1) {
00477
00478 egg_group->set_collide_flags(EggGroup::CF_turnstile);
00479 }
00480 }
00481 if (node_desc->get_max_node()->GetUserPropInt(_M("level"), check)) {
00482 if (check == 1) {
00483
00484 egg_group->set_collide_flags(EggGroup::CF_level);
00485 }
00486 }
00487 if (node_desc->get_max_node()->GetUserPropInt(_M("intangible"), check)) {
00488 if (check == 1) {
00489
00490 egg_group->set_collide_flags(EggGroup::CF_intangible);
00491 }
00492 }
00493 return;
00494 }