| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- // Filename: softNodeTree.cxx
- // Created by: masad (26Sep03)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) 2003, Disney Enterprises, Inc. All rights reserved
- //
- // All use of this software is subject to the terms of the Panda 3d
- // Software license. You should have received a copy of this license
- // along with this source code; you will also find a current copy of
- // the license at http://www.panda3d.org/license.txt .
- //
- // To contact the maintainers of this program write to
- // [email protected] .
- //
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////
- // Includes
- ////////////////////////////////////////////////////////////////////
- #include "softNodeTree.h"
- #include "softEggGroupUserData.h"
- #include "config_softegg.h"
- #include "eggGroup.h"
- #include "eggTable.h"
- #include "eggXfmSAnim.h"
- #include "eggData.h"
- #include "dcast.h"
- #include <SAA.h>
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- SoftNodeTree::
- SoftNodeTree() {
- // _root = new SoftNodeDesc;
- _root = NULL;
- _fps = 0.0;
- _egg_data = (EggData *)NULL;
- _egg_root = (EggGroupNode *)NULL;
- _skeleton_node = (EggGroupNode *)NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GetName
- // Access: Public
- // Description: Given an element, return a copy of the element's
- // name WITHOUT prefix.
- ////////////////////////////////////////////////////////////////////
- char *SoftNodeTree::
- GetName( SAA_Scene *scene, SAA_Elem *element ) {
- int nameLen;
- char *name;
- // get the name
- SAA_elementGetNameLength( scene, element, &nameLen );
- name = new char[++nameLen];
- SAA_elementGetName( scene, element, nameLen, name );
- return name;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: GetFullName
- // Access: Public
- // Description: Given an element, return a copy of the element's
- // name complete with prefix.
- ////////////////////////////////////////////////////////////////////
- char *SoftNodeTree::
- GetFullName( SAA_Scene *scene, SAA_Elem *element )
- {
- int nameLen, prefixLen;
- char *name, *prefix;
- // get the name length
- SAA_elementGetNameLength( scene, element, &nameLen );
- // get the prefix length
- SAA_elementGetPrefixLength( scene, element, &prefixLen );
- // allocate the array to hold name
- name = new char[++nameLen];
- // allocate the array to hold prefix and length + hyphen
- prefix = new char[++prefixLen + nameLen + 4];
- // get the name
- SAA_elementGetName( scene, element, nameLen, name );
- // get the prefix
- SAA_elementGetPrefix( scene, element, prefixLen, prefix );
- // add 'em together
- strcat(prefix, "-");
- strcat(prefix, name);
- // return string
- return prefix;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::build_node
- // Access: Public
- // Description: Returns a pointer to the node corresponding to the
- // indicated dag_path object, creating it first if
- // necessary.
- ////////////////////////////////////////////////////////////////////
- SoftNodeDesc *SoftNodeTree::
- build_node(SAA_Elem *model, const char *name) {
- string node_name = name;
- SoftNodeDesc *node_desc = r_build_node(node_name);
- node_desc->set_model(model);
- return node_desc;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::build_complete_hierarchy
- // Access: Public
- // Description: Walks through the complete Soft hierarchy and builds
- // up the corresponding tree.
- ////////////////////////////////////////////////////////////////////
- bool SoftNodeTree::
- build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database, char **root_name) {
- SI_Error status;
- // Get the entire Soft scene.
- int numModels;
- SAA_Elem *models;
-
- SAA_sceneGetNbModels( &scene, &numModels );
- cout << "Scene has " << numModels << " model(s)...\n";
-
- // This while loop walks through the entire Soft hierarchy, one
- // node at a time.
- bool all_ok = true;
- if ( numModels ) {
- // allocate array of models
- models = (SAA_Elem *) new SAA_Elem[numModels];
- if ( models != NULL ) {
- if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
- return false;
- }
- for ( int i = 0; i < numModels; i++ ) {
- int level;
- status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
- cout << "level " << level << endl;
- char *name = GetName(&scene, &models[i]);
- if ( !level ) {
- // this is the root node, so this should be the name of the model
- *root_name = name;
- }
- SoftNodeDesc *node_desc = build_node(&models[i], name);
- cout << "status is " << status << "\n";
- }
- }
- }
- # if 0
- if (all_ok) {
- _root->check_pseudo_joints(false);
- }
- #endif
- return all_ok;
- }
- #if 0
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::build_selected_hierarchy
- // Access: Public
- // Description: Walks through the selected subset of the Soft
- // hierarchy (or the complete hierarchy, if nothing is
- // selected) and builds up the corresponding tree.
- ////////////////////////////////////////////////////////////////////
- bool SoftNodeTree::
- build_selected_hierarchy(char *scene_name) {
- MStatus status;
- MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
- if (!status) {
- status.perror("MItDag constructor");
- return false;
- }
- // Get only the selected geometry.
- MSelectionList selection;
- status = MGlobal::getActiveSelectionList(selection);
- if (!status) {
- status.perror("MGlobal::getActiveSelectionList");
- return false;
- }
-
- // Get the selected geometry only if the selection is nonempty;
- // otherwise, get the whole scene anyway.
- if (selection.isEmpty()) {
- softegg_cat.info()
- << "Selection list is empty.\n";
- return build_complete_hierarchy();
- }
- bool all_ok = true;
- unsigned int length = selection.length();
- for (unsigned int i = 0; i < length; i++) {
- MDagPath root_path;
- status = selection.getDagPath(i, root_path);
- if (!status) {
- status.perror("MSelectionList::getDagPath");
- } else {
- // Now traverse through the selected dag path and all nested
- // dag paths.
- dag_iterator.reset(root_path);
- while (!dag_iterator.isDone()) {
- MDagPath dag_path;
- status = dag_iterator.getPath(dag_path);
- if (!status) {
- status.perror("MItDag::getPath");
- } else {
- build_node(dag_path);
- }
-
- dag_iterator.next();
- }
- }
- }
- if (all_ok) {
- _root->check_pseudo_joints(false);
- }
- return all_ok;
- }
- #endif
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::get_num_nodes
- // Access: Public
- // Description: Returns the total number of nodes in the hierarchy,
- // not counting the root node.
- ////////////////////////////////////////////////////////////////////
- int SoftNodeTree::
- get_num_nodes() const {
- return _nodes.size();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::get_node
- // Access: Public
- // Description: Returns the nth node in the hierarchy, in an
- // arbitrary ordering.
- ////////////////////////////////////////////////////////////////////
- SoftNodeDesc *SoftNodeTree::
- get_node(int n) const {
- nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
- return _nodes[n];
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::clear_egg
- // Access: Public
- // Description: Removes all of the references to generated egg
- // structures from the tree, and prepares the tree for
- // generating new egg structures.
- ////////////////////////////////////////////////////////////////////
- void SoftNodeTree::
- clear_egg(EggData *egg_data, EggGroupNode *egg_root,
- EggGroupNode *skeleton_node) {
- // _root->clear_egg();
- _egg_data = egg_data;
- _egg_root = egg_root;
- _skeleton_node = skeleton_node;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::get_egg_group
- // Access: Public
- // Description: Returns the EggGroupNode corresponding to the group
- // or joint for the indicated node. Creates the group
- // node if it has not already been created.
- ////////////////////////////////////////////////////////////////////
- EggGroup *SoftNodeTree::
- get_egg_group(SoftNodeDesc *node_desc) {
- nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
- if (node_desc->_egg_group == (EggGroup *)NULL) {
- // We need to make a new group node.
- EggGroup *egg_group;
-
- egg_group = new EggGroup(node_desc->get_name());
- if (node_desc->is_joint()) {
- egg_group->set_group_type(EggGroup::GT_joint);
- }
- // For now lets add this group to egg_root.
- _egg_root->add_child(egg_group);
- #if 0
- SoftEggGroupUserData *parent_user_data = NULL;
- if (node_desc->_parent == _root) {
- // The parent is the root.
- _egg_root->add_child(egg_group);
- } else {
- // The parent is another node.
- EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
- parent_egg_group->add_child(egg_group);
- if (parent_egg_group->has_user_data()) {
- DCAST_INTO_R(parent_user_data, parent_egg_group->get_user_data(), NULL);
- }
- }
- if (node_desc->has_models()) {
- // Check for an object type setting, from Oliver's plug-in.
- MObject dag_object = node_desc->get_dag_path().node();
- string object_type;
- if (get_enum_attribute(dag_object, "eggObjectTypes1", object_type)) {
- egg_group->add_object_type(object_type);
- }
- if (get_enum_attribute(dag_object, "eggObjectTypes2", object_type)) {
- egg_group->add_object_type(object_type);
- }
- if (get_enum_attribute(dag_object, "eggObjectTypes3", object_type)) {
- egg_group->add_object_type(object_type);
- }
- // Is the node flagged to be invisible? If it is, and is has no
- // other egg flags, it is implicitly tagged "backstage", so it
- // won't get converted. (But it might be an invisible collision
- // solid, which is why we do this only if it has no other egg
- // flags.)
- bool visible = true;
- get_bool_attribute(dag_object, "visibility", visible);
- if (!visible && egg_group->get_num_object_types() == 0) {
- egg_group->add_object_type("backstage");
- }
- // We treat the object type "billboard" as a special case: we
- // apply this one right away and also flag the group as an
- // instance.
- if (egg_group->has_object_type("billboard")) {
- egg_group->remove_object_type("billboard");
- egg_group->set_group_type(EggGroup::GT_instance);
- egg_group->set_billboard_type(EggGroup::BT_axis);
-
- } else if (egg_group->has_object_type("billboard-point")) {
- egg_group->remove_object_type("billboard-point");
- egg_group->set_group_type(EggGroup::GT_instance);
- egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
- }
-
- // We also treat the object type "dcs" and "model" as a special
- // case, so we can test for these flags later.
- if (egg_group->has_object_type("dcs")) {
- egg_group->remove_object_type("dcs");
- egg_group->set_dcs_type(EggGroup::DC_default);
- }
- if (egg_group->has_object_type("model")) {
- egg_group->remove_object_type("model");
- egg_group->set_model_flag(true);
- }
-
- // And "vertex-color" and "double-sided" have meaning only to
- // this converter.
- SoftEggGroupUserData *user_data;
- if (parent_user_data == (SoftEggGroupUserData *)NULL) {
- user_data = new SoftEggGroupUserData;
- } else {
- // Inherit the flags from above.
- user_data = new SoftEggGroupUserData(*parent_user_data);
- }
- if (egg_group->has_object_type("vertex-color")) {
- egg_group->remove_object_type("vertex-color");
- user_data->_vertex_color = true;
- }
- if (egg_group->has_object_type("double-sided")) {
- egg_group->remove_object_type("double-sided");
- user_data->_double_sided = true;
- }
- egg_group->set_user_data(user_data);
- }
- #endif
- // EggUserData *user_data = new EggUserData;
- // egg_group->set_user_data(user_data);
- node_desc->_egg_group = egg_group;
- }
- return node_desc->_egg_group;
- }
- #if 0
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::get_egg_table
- // Access: Public
- // Description: Returns the EggTable corresponding to the joint
- // for the indicated node. Creates the table node if it
- // has not already been created.
- ////////////////////////////////////////////////////////////////////
- EggTable *SoftNodeTree::
- get_egg_table(SoftNodeDesc *node_desc) {
- nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
- nassertr(node_desc->is_joint(), NULL);
- if (node_desc->_egg_table == (EggTable *)NULL) {
- // We need to make a new table node.
- nassertr(node_desc->_parent != (SoftNodeDesc *)NULL, NULL);
- EggTable *egg_table = new EggTable(node_desc->get_name());
- node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
- node_desc->_anim->set_fps(_fps);
- egg_table->add_child(node_desc->_anim);
- if (!node_desc->_parent->is_joint()) {
- // The parent is not a joint; put it at the top.
- _skeleton_node->add_child(egg_table);
- } else {
- // The parent is another joint.
- EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
- parent_egg_table->add_child(egg_table);
- }
- node_desc->_egg_table = egg_table;
- }
- return node_desc->_egg_table;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::get_egg_anim
- // Access: Public
- // Description: Returns the anim table corresponding to the joint
- // for the indicated node. Creates the table node if it
- // has not already been created.
- ////////////////////////////////////////////////////////////////////
- EggXfmSAnim *SoftNodeTree::
- get_egg_anim(SoftNodeDesc *node_desc) {
- get_egg_table(node_desc);
- return node_desc->_anim;
- }
- #endif
- ////////////////////////////////////////////////////////////////////
- // Function: SoftNodeTree::r_build_node
- // Access: Private
- // Description: The recursive implementation of build_node().
- ////////////////////////////////////////////////////////////////////
- SoftNodeDesc *SoftNodeTree::
- r_build_node(const string &name) {
- // Otherwise, we have to create it. Do this recursively, so we
- // create each node along the path.
- SoftNodeDesc *node_desc;
- node_desc = new SoftNodeDesc(name);
- _nodes.push_back(node_desc);
- return node_desc;
- }
- //
- //
- //
|