19 #include "softNodeTree.h"
20 #include "softEggGroupUserData.h"
21 #include "config_softegg.h"
24 #include "eggXfmSAnim.h"
26 #include "softToEggConverter.h"
39 _root->fullname =
"----root";
42 _search_prefix = NULL;
54 GetName( SAA_Scene *scene, SAA_Elem *element ) {
59 SAA_elementGetNameLength( scene, element, &nameLen );
60 name =
new char[++nameLen];
61 SAA_elementGetName( scene, element, nameLen, name );
75 int nameLen, prefixLen;
79 SAA_elementGetNameLength( scene, element, &nameLen );
81 SAA_elementGetPrefixLength( scene, element, &prefixLen );
83 name =
new char[++nameLen];
85 prefix =
new char[++prefixLen + nameLen + 4];
87 SAA_elementGetName( scene, element, nameLen, name );
89 SAA_elementGetPrefix( scene, element, prefixLen, prefix );
107 char *modelNote = NULL;
108 SAA_Boolean bigEndian;
110 SAA_elementGetUserDataSize( scene, model,
"MNOT", &size );
114 modelNote =
new char[size + 1];
117 SAA_elementGetUserData( scene, model,
"MNOT", size,
118 &bigEndian, (
void *)modelNote );
121 char *eol = (
char *)memchr( modelNote,
'\n', size );
125 modelNote[size] =
'\0';
127 softegg_cat.spam() <<
"\nmodelNote = " << modelNote << endl;
145 hyphen = strchr( name,
'-' );
148 if ( (hyphen != NULL) && len ) {
149 root =
new char[len+1];
150 strncpy( root, name, len );
154 root =
new char[strlen(name)+1];
155 strcpy( root, name );
175 SAA_sceneGetNbModels( &scene, &numModels );
176 softegg_cat.spam() <<
"Scene has " << numModels <<
" model(s)...\n";
183 models = (SAA_Elem *)
new SAA_Elem[numModels];
184 if ( models != NULL ) {
185 if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
188 for (
int i = 0; i < numModels; i++ ) {
190 status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
191 softegg_cat.spam() <<
"model[" << i <<
"]" << endl;
192 softegg_cat.spam() <<
" level " << level << endl;
193 softegg_cat.spam() <<
" status is " << status <<
"\n";
202 softegg_cat.spam() <<
"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj\n";
205 _root->check_junk(
false);
207 softegg_cat.spam() <<
"jpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjp\n";
210 _root->check_joint_parent();
212 softegg_cat.spam() <<
"pppppppppppppppppppppppppppppppppppppppppppppppppppppppp\n";
215 _root->check_pseudo_joints(
false);
217 softegg_cat.spam() <<
"========================================================\n";
220 _root->set_parentJoint(&scene, NULL);
233 build_selected_hierarchy(
char *scene_name) {
236 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
238 status.perror(
"MItDag constructor");
243 MSelectionList selection;
244 status = MGlobal::getActiveSelectionList(selection);
246 status.perror(
"MGlobal::getActiveSelectionList");
252 if (selection.isEmpty()) {
254 <<
"Selection list is empty.\n";
259 unsigned int length = selection.length();
260 for (
unsigned int i = 0; i < length; i++) {
262 status = selection.getDagPath(i, root_path);
264 status.perror(
"MSelectionList::getDagPath");
268 dag_iterator.reset(root_path);
269 while (!dag_iterator.isDone()) {
271 status = dag_iterator.getPath(dag_path);
273 status.perror(
"MItDag::getPath");
284 _root->check_pseudo_joints(
false);
298 return _nodes.size();
309 nassertr(n >= 0 && n < (
int)_nodes.size(), NULL);
321 NodesByName::const_iterator ni = _nodes_by_name.find(name);
322 if (ni != _nodes_by_name.end())
338 _egg_data = egg_data;
339 _egg_root = egg_root;
340 _skeleton_node = skeleton_node;
355 softegg_cat.spam() <<
" group " << node_desc->get_name() <<
"(" << node_desc->_egg_group <<
")";
356 if (node_desc->_parent)
357 softegg_cat.spam() <<
" parent " << node_desc->_parent->get_name() <<
"(" << node_desc->_parent <<
")";
359 softegg_cat.spam() <<
" parent " << node_desc->_parent;
360 softegg_cat.spam() << endl;
362 if (node_desc->_egg_group == (
EggGroup *)NULL) {
366 egg_group =
new EggGroup(node_desc->get_name());
368 egg_group->set_group_type(EggGroup::GT_joint);
371 if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
373 softegg_cat.spam() <<
"came hereeeee\n";
381 node_desc->_egg_group = egg_group;
384 return node_desc->_egg_group;
397 nassertr(node_desc->
is_joint(), NULL);
400 softegg_cat.spam() <<
" group " << node_desc->get_name() <<
"(" << node_desc->_egg_group <<
")";
401 if (node_desc->_parent)
402 softegg_cat.spam() <<
" parent " << node_desc->_parent->get_name() <<
"(" << node_desc->_parent <<
")";
404 softegg_cat.spam() <<
" parent " << node_desc->_parent;
405 softegg_cat.spam() << endl;
407 if (node_desc->_egg_table == (
EggTable *)NULL) {
408 softegg_cat.spam() <<
"creating a new table\n";
414 node_desc->_anim->set_fps(_fps);
417 if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
427 node_desc->_egg_table = egg_table;
430 return node_desc->_egg_table;
443 return node_desc->_anim;
453 const char *name = node_name;
454 SAA_AlgorithmType algo;
455 SAA_Elem *model = node_desc->
get_model();
457 SAA_modelGetAlgorithm( scene, model, &algo );
458 softegg_cat.spam() <<
" null algorithm: " << algo << endl;
460 if ( algo == SAA_ALG_INV_KIN ) {
463 softegg_cat.spam() <<
" encountered IK root: " << name << endl;
465 else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
468 softegg_cat.spam() <<
" encountered IK leaf: " << name << endl;
470 else if ( algo == SAA_ALG_STANDARD ) {
471 SAA_Boolean isSkeleton = FALSE;
472 softegg_cat.spam() <<
" encountered Standard null: " << name << endl;
474 SAA_modelIsSkeleton( scene, model, &isSkeleton );
480 if ( isSkeleton || (strstr( name,
"joint" ) != NULL) ) {
483 softegg_cat.spam() <<
" animating Standard null!!!\n";
484 softegg_cat.spam() <<
"isSkeleton: " << isSkeleton << endl;
488 softegg_cat.spam() <<
" encountered some other NULL: " << algo << endl;
500 char *name, *fullname;
506 SAA_Boolean isSkeleton = FALSE;
516 SoftNodeDesc *node_desc = r_build_node(NULL, node_name);
518 node_desc->fullname = fullname;
520 SAA_modelIsSkeleton( scene, model, &isSkeleton );
523 SAA_modelGetType( scene, node_desc->
get_model(), &type );
525 if (type == SAA_MJNT || isSkeleton || (strstr(node_desc->get_name().c_str(),
"joint") != NULL))
529 if (type == SAA_MNILL)
533 softegg_cat.spam() <<
"type: " << type <<
" isSkeleton: " << isSkeleton << endl;
536 SAA_modelGetNbChildren( scene, model, &numChildren );
537 softegg_cat.spam() <<
" Model " << node_name <<
" children: " << numChildren << endl;
540 children =
new SAA_Elem[numChildren];
541 SAA_modelGetChildren( scene, model, numChildren, children );
543 softegg_cat.info() <<
"Not enough Memory for children...\n";
545 for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
546 fullname =
GetFullName(scene, &children[thisChild]);
548 node_name = fullname;
550 node_name =
GetName(scene, &children[thisChild]);
552 softegg_cat.spam() <<
" building child " << thisChild <<
"...";
554 SoftNodeDesc *node_child = r_build_node(node_desc, node_name);
556 node_child->fullname = fullname;
557 node_child->
set_model(&children[thisChild]);
558 SAA_modelIsSkeleton( scene, &children[thisChild], &isSkeleton );
561 SAA_modelGetType( scene, node_child->
get_model(), &type );
563 if (type == SAA_MJNT || isSkeleton || (strstr(node_child->get_name().c_str(),
"joint") != NULL))
567 if (type == SAA_MNILL)
571 softegg_cat.spam() <<
"type: " << type <<
" isSkeleton: " << isSkeleton << endl;
583 r_build_node(
SoftNodeDesc *parent_node,
const string &name) {
588 NodesByName::const_iterator ni = _nodes_by_name.find(name);
589 if (ni != _nodes_by_name.end()) {
590 softegg_cat.spam() <<
" already built node " << (*ni).first;
591 node_desc = (*ni).second;
600 softegg_cat.spam() <<
" node name : " << name << endl;
601 _nodes.push_back(node_desc);
603 _nodes_by_name.insert(NodesByName::value_type(name, node_desc));
int get_num_nodes() const
Returns the total number of nodes in the hierarchy, not counting the root node.
EggTable * get_egg_table(SoftNodeDesc *node_desc)
Returns the EggTable corresponding to the joint for the indicated node.
A base class for nodes in the hierarchy that are not leaf nodes.
char * GetModelNoteInfo(SAA_Scene *, SAA_Elem *)
Given an element, return a string containing the contents of its MODEL NOTE entry.
char * GetName(SAA_Scene *scene, SAA_Elem *element)
Given an element, return a copy of the element's name WITHOUT prefix.
This is the primary interface into all the egg data, and the root of the egg file structure...
char * GetFullName(SAA_Scene *scene, SAA_Elem *element)
Given an element, return a copy of the element's name complete with prefix.
SAA_Elem * get_model() const
Returns the SAA_Elem * associated with this node.
void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node)
Removes all of the references to generated egg structures from the tree, and prepares the tree for ge...
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
CoordinateSystem get_coordinate_system() const
Returns the coordinate system in which the egg file is defined.
char * GetRootName(const char *)
Given a string, return a copy of the string up to the first occurence of '-'.
EggGroup * get_egg_group(SoftNodeDesc *node_desc)
Returns the EggGroupNode corresponding to the group or joint for the indicated node.
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
bool build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database)
Walks through the complete Soft hierarchy and builds up the corresponding tree.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
Describes a single instance of a node aka element in the Soft scene graph, relating it to the corresp...
void set_joint()
sets the _joint_type to JT_joint
SoftNodeDesc * get_node(int n) const
Returns the nth node in the hierarchy, in an arbitrary ordering.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
void set_parent(SoftNodeDesc *parent)
Sometimes, parent is not known at node creation As soon as it is known, set the parent.
void handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name)
Sets joint information for MNILL node.
SoftNodeDesc * build_node(SAA_Scene *scene, SAA_Elem *model)
Returns a pointer to the node corresponding to the indicated dag_path object, creating it first if ne...
EggXfmSAnim * get_egg_anim(SoftNodeDesc *node_desc)
Returns the anim table corresponding to the joint for the indicated node.
void set_model(SAA_Elem *model)
Indicates an associated between the SoftNodeDesc and some SAA_Elem instance.