00001 // Filename: maxNodeDesc.cxx 00002 // Created by: crevilla 00003 // from mayaNodeDesc.cxx created by: drose (06Jun03) 00004 // 00005 //////////////////////////////////////////////////////////////////// 00006 // 00007 // PANDA 3D SOFTWARE 00008 // Copyright (c) Carnegie Mellon University. All rights reserved. 00009 // 00010 // All use of this software is subject to the terms of the revised BSD 00011 // license. You should have received a copy of this license along 00012 // with this source code in a file named "LICENSE." 00013 // 00014 //////////////////////////////////////////////////////////////////// 00015 00016 #include "maxEgg.h" 00017 00018 TypeHandle MaxNodeDesc::_type_handle; 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: MaxNodeDesc::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 MaxNodeDesc:: 00026 MaxNodeDesc(MaxNodeDesc *parent, const string &name) : 00027 Namable(name), 00028 _parent(parent) 00029 { 00030 _max_node = (INode *)NULL; 00031 _egg_group = (EggGroup *)NULL; 00032 _egg_table = (EggTable *)NULL; 00033 _anim = (EggXfmSAnim *)NULL; 00034 _joint_type = JT_none; 00035 _joint_entry = NULL; 00036 00037 // Add ourselves to our parent. 00038 if (_parent != (MaxNodeDesc *)NULL) { 00039 _parent->_children.push_back(this); 00040 } 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: MaxNodeDesc::Destructor 00045 // Access: Public 00046 // Description: 00047 //////////////////////////////////////////////////////////////////// 00048 MaxNodeDesc:: 00049 ~MaxNodeDesc() {} 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: MaxNodeDesc::from_INode 00053 // Access: Public 00054 // Description: Indicates an associated between the MaxNodeDesc and 00055 // some Max Node instance. 00056 //////////////////////////////////////////////////////////////////// 00057 void MaxNodeDesc:: 00058 from_INode(INode *max_node) { 00059 if (_max_node == (INode *)NULL) { 00060 _max_node = max_node; 00061 00062 // This is how I decided to check to see if this max node is a 00063 // joint. It works in all instances I've seen so far, but this 00064 // may be a good starting place to look if joints are not being 00065 // picked up correctly in the future. 00066 00067 //Check to see if the node's controller is a biped 00068 //If so treat it as a joint 00069 // Get the node's transform control 00070 Control *c = max_node->GetTMController(); 00071 if (_max_node->GetBoneNodeOnOff() || 00072 (c && //c exists and it's type is a biped 00073 ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) || 00074 (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) || 00075 (c->ClassID() == FOOTPRINT_CLASS_ID)))) { 00076 00077 // This node is a joint. 00078 _joint_type = JT_node_joint; 00079 if (_parent != (MaxNodeDesc *)NULL) { 00080 _parent->mark_joint_parent(); 00081 } 00082 } 00083 } 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: MaxNodeDesc::has_max_node 00088 // Access: Public 00089 // Description: Returns true if a Max INode has been associated 00090 // with this node, false otherwise. 00091 //////////////////////////////////////////////////////////////////// 00092 bool MaxNodeDesc:: 00093 has_max_node() const { 00094 return (_max_node != (INode *)NULL); 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: MaxNodeDesc::get_max_node 00099 // Access: Public 00100 // Description: Returns the INode associated with this node. It 00101 // is an error to call this unless has_max_node() 00102 // returned true. 00103 //////////////////////////////////////////////////////////////////// 00104 INode *MaxNodeDesc:: 00105 get_max_node() const { 00106 nassertr(_max_node != (INode *)NULL, _max_node); 00107 return _max_node; 00108 } 00109 00110 00111 void MaxNodeDesc:: 00112 set_joint(bool onoff) { 00113 if (onoff) 00114 _joint_type = JT_joint; 00115 else 00116 _joint_type = JT_none; 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: MaxNodeDesc::is_joint 00121 // Access: Private 00122 // Description: Returns true if the node should be treated as a joint 00123 // by the converter. 00124 //////////////////////////////////////////////////////////////////// 00125 bool MaxNodeDesc:: 00126 is_joint() const { 00127 return _joint_type == JT_joint || _joint_type == JT_pseudo_joint; 00128 } 00129 00130 //////////////////////////////////////////////////////////////////// 00131 // Function: MaxNodeDesc::is_joint_parent 00132 // Access: Private 00133 // Description: Returns true if the node is the parent or ancestor of 00134 // a joint. 00135 //////////////////////////////////////////////////////////////////// 00136 bool MaxNodeDesc:: 00137 is_joint_parent() const { 00138 return _joint_type == JT_joint_parent; 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: MaxNodeDesc::is_joint_parent 00143 // Access: Private 00144 // Description: Returns true if the node is the parent or ancestor of 00145 // a joint. 00146 //////////////////////////////////////////////////////////////////// 00147 bool MaxNodeDesc:: 00148 is_node_joint() const { 00149 return _joint_type == JT_node_joint; 00150 } 00151 00152 //////////////////////////////////////////////////////////////////// 00153 // Function: MaxNodeDesc::clear_egg 00154 // Access: Private 00155 // Description: Recursively clears the egg pointers from this node 00156 // and all children. 00157 //////////////////////////////////////////////////////////////////// 00158 void MaxNodeDesc:: 00159 clear_egg() { 00160 _egg_group = (EggGroup *)NULL; 00161 _egg_table = (EggTable *)NULL; 00162 _anim = (EggXfmSAnim *)NULL; 00163 00164 Children::const_iterator ci; 00165 for (ci = _children.begin(); ci != _children.end(); ++ci) { 00166 MaxNodeDesc *child = (*ci); 00167 child->clear_egg(); 00168 } 00169 } 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: MaxNodeDesc::mark_joint_parent 00173 // Access: Private 00174 // Description: Indicates that this node has at least one child that 00175 // is a joint or a pseudo-joint. 00176 //////////////////////////////////////////////////////////////////// 00177 void MaxNodeDesc:: 00178 mark_joint_parent() { 00179 if (_joint_type == JT_none) { 00180 _joint_type = JT_joint_parent; 00181 if (_parent != (MaxNodeDesc *)NULL) { 00182 _parent->mark_joint_parent(); 00183 } 00184 } 00185 } 00186 00187 //////////////////////////////////////////////////////////////////// 00188 // Function: MaxNodeDesc::check_pseudo_joints 00189 // Access: Private 00190 // Description: Walks the hierarchy, looking for non-joint nodes that 00191 // are both children and parents of a joint. These 00192 // nodes are deemed to be pseudo joints, since the 00193 // converter must treat them as joints. 00194 //////////////////////////////////////////////////////////////////// 00195 void MaxNodeDesc:: 00196 check_pseudo_joints(bool joint_above) { 00197 if (_joint_type == JT_joint_parent && joint_above) { 00198 // This is one such node: it is the parent of a joint 00199 // (JT_joint_parent is set), and it is the child of a joint 00200 // (joint_above is set). 00201 _joint_type = JT_pseudo_joint; 00202 } 00203 00204 if (_joint_type == JT_joint) { 00205 // If this node is itself a joint, then joint_above is true for 00206 // all child nodes. 00207 joint_above = true; 00208 } 00209 00210 // Don't bother traversing further if _joint_type is none, since 00211 // that means this node has no joint children. 00212 if (_joint_type != JT_none) { 00213 Children::const_iterator ci; 00214 for (ci = _children.begin(); ci != _children.end(); ++ci) { 00215 MaxNodeDesc *child = (*ci); 00216 child->check_pseudo_joints(joint_above); 00217 } 00218 } 00219 }