00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "softNodeTree.h"
00020 #include "softEggGroupUserData.h"
00021 #include "config_softegg.h"
00022 #include "eggGroup.h"
00023 #include "eggTable.h"
00024 #include "eggXfmSAnim.h"
00025 #include "eggData.h"
00026 #include "softToEggConverter.h"
00027 #include "dcast.h"
00028
00029 #include <SAA.h>
00030
00031
00032
00033
00034
00035
00036 SoftNodeTree::
00037 SoftNodeTree() {
00038 _root = new SoftNodeDesc(NULL, "----root");
00039 _root->fullname = "----root";
00040 _fps = 0.0;
00041 _use_prefix = 0;
00042 _search_prefix = NULL;
00043 _egg_data = (EggData *)NULL;
00044 _egg_root = (EggGroupNode *)NULL;
00045 _skeleton_node = (EggGroupNode *)NULL;
00046 }
00047
00048
00049
00050
00051
00052
00053 char *SoftNodeTree::
00054 GetName( SAA_Scene *scene, SAA_Elem *element ) {
00055 int nameLen;
00056 char *name;
00057
00058
00059 SAA_elementGetNameLength( scene, element, &nameLen );
00060 name = new char[++nameLen];
00061 SAA_elementGetName( scene, element, nameLen, name );
00062
00063 return name;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 char *SoftNodeTree::
00073 GetFullName( SAA_Scene *scene, SAA_Elem *element )
00074 {
00075 int nameLen, prefixLen;
00076 char *name, *prefix;
00077
00078
00079 SAA_elementGetNameLength( scene, element, &nameLen );
00080
00081 SAA_elementGetPrefixLength( scene, element, &prefixLen );
00082
00083 name = new char[++nameLen];
00084
00085 prefix = new char[++prefixLen + nameLen + 4];
00086
00087 SAA_elementGetName( scene, element, nameLen, name );
00088
00089 SAA_elementGetPrefix( scene, element, prefixLen, prefix );
00090
00091 strcat(prefix, "-");
00092 strcat(prefix, name);
00093
00094
00095 return prefix;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 char *SoftNodeTree::
00105 GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) {
00106 int size;
00107 char *modelNote = NULL;
00108 SAA_Boolean bigEndian;
00109
00110 SAA_elementGetUserDataSize( scene, model, "MNOT", &size );
00111
00112 if ( size != 0 ) {
00113
00114 modelNote = new char[size + 1];
00115
00116
00117 SAA_elementGetUserData( scene, model, "MNOT", size,
00118 &bigEndian, (void *)modelNote );
00119
00120
00121 char *eol = (char *)memchr( modelNote, '\n', size );
00122 if ( eol != NULL)
00123 *eol = '\0';
00124 else
00125 modelNote[size] = '\0';
00126
00127 softegg_cat.spam() << "\nmodelNote = " << modelNote << endl;
00128 }
00129
00130 return modelNote;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 char *SoftNodeTree::
00140 GetRootName( const char *name ) {
00141 const char *hyphen;
00142 char *root;
00143 int len;
00144
00145 hyphen = strchr( name, '-' );
00146 len = hyphen-name;
00147
00148 if ( (hyphen != NULL) && len ) {
00149 root = new char[len+1];
00150 strncpy( root, name, len );
00151 root[len] = '\0';
00152 }
00153 else {
00154 root = new char[strlen(name)+1];
00155 strcpy( root, name );
00156 }
00157 return( root );
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 bool SoftNodeTree::
00167 build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
00168 SI_Error status;
00169 SoftNodeDesc *node;
00170
00171
00172 int numModels;
00173 SAA_Elem *models;
00174
00175 SAA_sceneGetNbModels( &scene, &numModels );
00176 softegg_cat.spam() << "Scene has " << numModels << " model(s)...\n";
00177
00178
00179
00180 bool all_ok = true;
00181 if ( numModels ) {
00182
00183 models = (SAA_Elem *) new SAA_Elem[numModels];
00184 if ( models != NULL ) {
00185 if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
00186 return false;
00187 }
00188 for ( int i = 0; i < numModels; i++ ) {
00189 int level;
00190 status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
00191 softegg_cat.spam() << "model[" << i << "]" << endl;
00192 softegg_cat.spam() << " level " << level << endl;
00193 softegg_cat.spam() << " status is " << status << "\n";
00194
00195 node = build_node(&scene, &models[i]);
00196 if (!level && node)
00197 node->set_parent(_root);
00198 }
00199 }
00200 }
00201
00202 softegg_cat.spam() << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj\n";
00203
00204
00205 _root->check_junk(false);
00206
00207 softegg_cat.spam() << "jpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjp\n";
00208
00209
00210 _root->check_joint_parent();
00211
00212 softegg_cat.spam() << "pppppppppppppppppppppppppppppppppppppppppppppppppppppppp\n";
00213
00214
00215 _root->check_pseudo_joints(false);
00216
00217 softegg_cat.spam() << "========================================================\n";
00218
00219
00220 _root->set_parentJoint(&scene, NULL);
00221
00222 return all_ok;
00223 }
00224 #if 0
00225
00226
00227
00228
00229
00230
00231
00232 bool SoftNodeTree::
00233 build_selected_hierarchy(char *scene_name) {
00234 MStatus status;
00235
00236 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
00237 if (!status) {
00238 status.perror("MItDag constructor");
00239 return false;
00240 }
00241
00242
00243 MSelectionList selection;
00244 status = MGlobal::getActiveSelectionList(selection);
00245 if (!status) {
00246 status.perror("MGlobal::getActiveSelectionList");
00247 return false;
00248 }
00249
00250
00251
00252 if (selection.isEmpty()) {
00253 softegg_cat.info()
00254 << "Selection list is empty.\n";
00255 return build_complete_hierarchy();
00256 }
00257
00258 bool all_ok = true;
00259 unsigned int length = selection.length();
00260 for (unsigned int i = 0; i < length; i++) {
00261 MDagPath root_path;
00262 status = selection.getDagPath(i, root_path);
00263 if (!status) {
00264 status.perror("MSelectionList::getDagPath");
00265 } else {
00266
00267
00268 dag_iterator.reset(root_path);
00269 while (!dag_iterator.isDone()) {
00270 MDagPath dag_path;
00271 status = dag_iterator.getPath(dag_path);
00272 if (!status) {
00273 status.perror("MItDag::getPath");
00274 } else {
00275 build_node(dag_path);
00276 }
00277
00278 dag_iterator.next();
00279 }
00280 }
00281 }
00282
00283 if (all_ok) {
00284 _root->check_pseudo_joints(false);
00285 }
00286
00287 return all_ok;
00288 }
00289 #endif
00290
00291
00292
00293
00294
00295
00296 int SoftNodeTree::
00297 get_num_nodes() const {
00298 return _nodes.size();
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 SoftNodeDesc *SoftNodeTree::
00308 get_node(int n) const {
00309 nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
00310 return _nodes[n];
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 SoftNodeDesc *SoftNodeTree::
00320 get_node(string name) const {
00321 NodesByName::const_iterator ni = _nodes_by_name.find(name);
00322 if (ni != _nodes_by_name.end())
00323 return (*ni).second;
00324 return NULL;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334 void SoftNodeTree::
00335 clear_egg(EggData *egg_data, EggGroupNode *egg_root,
00336 EggGroupNode *skeleton_node) {
00337 _root->clear_egg();
00338 _egg_data = egg_data;
00339 _egg_root = egg_root;
00340 _skeleton_node = skeleton_node;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350 EggGroup *SoftNodeTree::
00351 get_egg_group(SoftNodeDesc *node_desc) {
00352 nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
00353
00354
00355 softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
00356 if (node_desc->_parent)
00357 softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
00358 else
00359 softegg_cat.spam() << " parent " << node_desc->_parent;
00360 softegg_cat.spam() << endl;
00361
00362 if (node_desc->_egg_group == (EggGroup *)NULL) {
00363
00364 EggGroup *egg_group;
00365
00366 egg_group = new EggGroup(node_desc->get_name());
00367 if (node_desc->is_joint()) {
00368 egg_group->set_group_type(EggGroup::GT_joint);
00369 }
00370
00371 if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
00372
00373 softegg_cat.spam() << "came hereeeee\n";
00374 _egg_root->add_child(egg_group);
00375 } else {
00376
00377 EggGroup *parent_egg_group = get_egg_group(node_desc->_parentJoint);
00378 parent_egg_group->add_child(egg_group);
00379 }
00380
00381 node_desc->_egg_group = egg_group;
00382 }
00383
00384 return node_desc->_egg_group;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394 EggTable *SoftNodeTree::
00395 get_egg_table(SoftNodeDesc *node_desc) {
00396 nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
00397 nassertr(node_desc->is_joint(), NULL);
00398
00399
00400 softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
00401 if (node_desc->_parent)
00402 softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
00403 else
00404 softegg_cat.spam() << " parent " << node_desc->_parent;
00405 softegg_cat.spam() << endl;
00406
00407 if (node_desc->_egg_table == (EggTable *)NULL) {
00408 softegg_cat.spam() << "creating a new table\n";
00409
00410
00411
00412 EggTable *egg_table = new EggTable(node_desc->get_name());
00413 node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
00414 node_desc->_anim->set_fps(_fps);
00415 egg_table->add_child(node_desc->_anim);
00416
00417 if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
00418
00419
00420 _skeleton_node->add_child(egg_table);
00421 } else {
00422
00423 EggTable *parent_egg_table = get_egg_table(node_desc->_parentJoint);
00424 parent_egg_table->add_child(egg_table);
00425 }
00426
00427 node_desc->_egg_table = egg_table;
00428 }
00429
00430 return node_desc->_egg_table;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440 EggXfmSAnim *SoftNodeTree::
00441 get_egg_anim(SoftNodeDesc *node_desc) {
00442 get_egg_table(node_desc);
00443 return node_desc->_anim;
00444 }
00445
00446
00447
00448
00449
00450
00451 void SoftNodeTree::
00452 handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name) {
00453 const char *name = node_name;
00454 SAA_AlgorithmType algo;
00455 SAA_Elem *model = node_desc->get_model();
00456
00457 SAA_modelGetAlgorithm( scene, model, &algo );
00458 softegg_cat.spam() << " null algorithm: " << algo << endl;
00459
00460 if ( algo == SAA_ALG_INV_KIN ) {
00461
00462 node_desc->set_joint();
00463 softegg_cat.spam() << " encountered IK root: " << name << endl;
00464 }
00465 else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
00466
00467 node_desc->set_joint();
00468 softegg_cat.spam() << " encountered IK leaf: " << name << endl;
00469 }
00470 else if ( algo == SAA_ALG_STANDARD ) {
00471 SAA_Boolean isSkeleton = FALSE;
00472 softegg_cat.spam() << " encountered Standard null: " << name << endl;
00473
00474 SAA_modelIsSkeleton( scene, model, &isSkeleton );
00475
00476
00477
00478
00479
00480 if ( isSkeleton || (strstr( name, "joint" ) != NULL) ) {
00481
00482 node_desc->set_joint();
00483 softegg_cat.spam() << " animating Standard null!!!\n";
00484 softegg_cat.spam() << "isSkeleton: " << isSkeleton << endl;
00485 }
00486 }
00487 else
00488 softegg_cat.spam() << " encountered some other NULL: " << algo << endl;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498 SoftNodeDesc *SoftNodeTree::
00499 build_node(SAA_Scene *scene, SAA_Elem *model) {
00500 char *name, *fullname;
00501 string node_name;
00502 int numChildren;
00503 int thisChild;
00504 SAA_Elem *children;
00505 SAA_ModelType type;
00506 SAA_Boolean isSkeleton = FALSE;
00507
00508 fullname = GetFullName(scene, model);
00509 if (_use_prefix)
00510 name = fullname;
00511 else
00512 name = GetName(scene, model);
00513
00514 node_name = name;
00515
00516 SoftNodeDesc *node_desc = r_build_node(NULL, node_name);
00517
00518 node_desc->fullname = fullname;
00519 node_desc->set_model(model);
00520 SAA_modelIsSkeleton( scene, model, &isSkeleton );
00521
00522
00523 SAA_modelGetType( scene, node_desc->get_model(), &type );
00524
00525 if (type == SAA_MJNT || isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != NULL))
00526 node_desc->set_joint();
00527
00528
00529 if (type == SAA_MNILL)
00530 handle_null(scene, node_desc, name);
00531
00532 if (node_desc->is_joint())
00533 softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
00534
00535
00536 SAA_modelGetNbChildren( scene, model, &numChildren );
00537 softegg_cat.spam() << " Model " << node_name << " children: " << numChildren << endl;
00538
00539 if ( numChildren ) {
00540 children = new SAA_Elem[numChildren];
00541 SAA_modelGetChildren( scene, model, numChildren, children );
00542 if (!children)
00543 softegg_cat.info() << "Not enough Memory for children...\n";
00544
00545 for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
00546 fullname = GetFullName(scene, &children[thisChild]);
00547 if (_use_prefix)
00548 node_name = fullname;
00549 else
00550 node_name = GetName(scene, &children[thisChild]);
00551
00552 softegg_cat.spam() << " building child " << thisChild << "...";
00553
00554 SoftNodeDesc *node_child = r_build_node(node_desc, node_name);
00555
00556 node_child->fullname = fullname;
00557 node_child->set_model(&children[thisChild]);
00558 SAA_modelIsSkeleton( scene, &children[thisChild], &isSkeleton );
00559
00560
00561 SAA_modelGetType( scene, node_child->get_model(), &type );
00562
00563 if (type == SAA_MJNT || isSkeleton || (strstr(node_child->get_name().c_str(), "joint") != NULL))
00564 node_child->set_joint();
00565
00566
00567 if (type == SAA_MNILL)
00568 handle_null(scene, node_child, node_name.c_str());
00569
00570 if (node_child->is_joint())
00571 softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
00572 }
00573 }
00574 return node_desc;
00575 }
00576
00577
00578
00579
00580
00581
00582 SoftNodeDesc *SoftNodeTree::
00583 r_build_node(SoftNodeDesc *parent_node, const string &name) {
00584 SoftNodeDesc *node_desc;
00585
00586
00587
00588 NodesByName::const_iterator ni = _nodes_by_name.find(name);
00589 if (ni != _nodes_by_name.end()) {
00590 softegg_cat.spam() << " already built node " << (*ni).first;
00591 node_desc = (*ni).second;
00592 node_desc->set_parent(parent_node);
00593 return node_desc;
00594 }
00595
00596
00597
00598 node_desc = new SoftNodeDesc(parent_node, name);
00599
00600 softegg_cat.spam() << " node name : " << name << endl;
00601 _nodes.push_back(node_desc);
00602
00603 _nodes_by_name.insert(NodesByName::value_type(name, node_desc));
00604
00605 return node_desc;
00606 }
00607
00608
00609
00610