Panda3D
 All Classes Functions Variables Enumerations
maxNodeDesc.cxx
1 // Filename: maxNodeDesc.cxx
2 // Created by: crevilla
3 // from mayaNodeDesc.cxx created by: drose (06Jun03)
4 //
5 ////////////////////////////////////////////////////////////////////
6 //
7 // PANDA 3D SOFTWARE
8 // Copyright (c) Carnegie Mellon University. All rights reserved.
9 //
10 // All use of this software is subject to the terms of the revised BSD
11 // license. You should have received a copy of this license along
12 // with this source code in a file named "LICENSE."
13 //
14 ////////////////////////////////////////////////////////////////////
15 
16 #include "maxEgg.h"
17 
18 TypeHandle MaxNodeDesc::_type_handle;
19 
20 ////////////////////////////////////////////////////////////////////
21 // Function: MaxNodeDesc::Constructor
22 // Access: Public
23 // Description: Creates a MaxNodeDesc. The name is copied from
24 // the given max node. Use from_INode to actually
25 // associate the desc with a given max node.
26 ////////////////////////////////////////////////////////////////////
28 MaxNodeDesc(MaxNodeDesc *parent, INode *max_node) :
29  _parent(parent) {
30 
31  if (max_node != NULL) {
32  const TCHAR *max_name = max_node->GetName();
33 #ifdef _UNICODE
34  char name_mb [1024];
35  name_mb[1023] = 0;
36  wcstombs(name_mb, max_name, 1023);
37  set_name(name_mb);
38 #else
39  set_name(max_name);
40 #endif
41  }
42 
43  _max_node = (INode *)NULL;
44  _egg_group = (EggGroup *)NULL;
45  _egg_table = (EggTable *)NULL;
46  _anim = (EggXfmSAnim *)NULL;
47  _joint_type = JT_none;
48  _joint_entry = NULL;
49 
50  // Add ourselves to our parent.
51  if (_parent != (MaxNodeDesc *)NULL) {
52  _parent->_children.push_back(this);
53  }
54 }
55 
56 ////////////////////////////////////////////////////////////////////
57 // Function: MaxNodeDesc::Destructor
58 // Access: Public
59 // Description:
60 ////////////////////////////////////////////////////////////////////
61 MaxNodeDesc::
62 ~MaxNodeDesc() {}
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: MaxNodeDesc::from_INode
66 // Access: Public
67 // Description: Indicates an associated between the MaxNodeDesc and
68 // some Max Node instance.
69 ////////////////////////////////////////////////////////////////////
70 void MaxNodeDesc::
71 from_INode(INode *max_node) {
72  if (_max_node == (INode *)NULL) {
73  _max_node = max_node;
74 
75  // This is how I decided to check to see if this max node is a
76  // joint. It works in all instances I've seen so far, but this
77  // may be a good starting place to look if joints are not being
78  // picked up correctly in the future.
79 
80  //Check to see if the node's controller is a biped
81  //If so treat it as a joint
82  // Get the node's transform control
83  Control *c = max_node->GetTMController();
84  if (_max_node->GetBoneNodeOnOff() ||
85  (c && //c exists and it's type is a biped
86  ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
87  (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
88  (c->ClassID() == FOOTPRINT_CLASS_ID)))) {
89 
90  // This node is a joint.
91  _joint_type = JT_node_joint;
92  if (_parent != (MaxNodeDesc *)NULL) {
93  _parent->mark_joint_parent();
94  }
95  }
96  }
97 }
98 
99 ////////////////////////////////////////////////////////////////////
100 // Function: MaxNodeDesc::has_max_node
101 // Access: Public
102 // Description: Returns true if a Max INode has been associated
103 // with this node, false otherwise.
104 ////////////////////////////////////////////////////////////////////
105 bool MaxNodeDesc::
106 has_max_node() const {
107  return (_max_node != (INode *)NULL);
108 }
109 
110 ////////////////////////////////////////////////////////////////////
111 // Function: MaxNodeDesc::get_max_node
112 // Access: Public
113 // Description: Returns the INode associated with this node. It
114 // is an error to call this unless has_max_node()
115 // returned true.
116 ////////////////////////////////////////////////////////////////////
117 INode *MaxNodeDesc::
118 get_max_node() const {
119  nassertr(_max_node != (INode *)NULL, _max_node);
120  return _max_node;
121 }
122 
123 
124 void MaxNodeDesc::
125 set_joint(bool onoff) {
126  if (onoff)
127  _joint_type = JT_joint;
128  else
129  _joint_type = JT_none;
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: MaxNodeDesc::is_joint
134 // Access: Private
135 // Description: Returns true if the node should be treated as a joint
136 // by the converter.
137 ////////////////////////////////////////////////////////////////////
138 bool MaxNodeDesc::
139 is_joint() const {
140  return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
141 }
142 
143 ////////////////////////////////////////////////////////////////////
144 // Function: MaxNodeDesc::is_joint_parent
145 // Access: Private
146 // Description: Returns true if the node is the parent or ancestor of
147 // a joint.
148 ////////////////////////////////////////////////////////////////////
149 bool MaxNodeDesc::
151  return _joint_type == JT_joint_parent;
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: MaxNodeDesc::is_joint_parent
156 // Access: Private
157 // Description: Returns true if the node is the parent or ancestor of
158 // a joint.
159 ////////////////////////////////////////////////////////////////////
160 bool MaxNodeDesc::
161 is_node_joint() const {
162  return _joint_type == JT_node_joint;
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: MaxNodeDesc::clear_egg
167 // Access: Private
168 // Description: Recursively clears the egg pointers from this node
169 // and all children.
170 ////////////////////////////////////////////////////////////////////
171 void MaxNodeDesc::
172 clear_egg() {
173  _egg_group = (EggGroup *)NULL;
174  _egg_table = (EggTable *)NULL;
175  _anim = (EggXfmSAnim *)NULL;
176 
177  Children::const_iterator ci;
178  for (ci = _children.begin(); ci != _children.end(); ++ci) {
179  MaxNodeDesc *child = (*ci);
180  child->clear_egg();
181  }
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: MaxNodeDesc::mark_joint_parent
186 // Access: Private
187 // Description: Indicates that this node has at least one child that
188 // is a joint or a pseudo-joint.
189 ////////////////////////////////////////////////////////////////////
190 void MaxNodeDesc::
191 mark_joint_parent() {
192  if (_joint_type == JT_none) {
193  _joint_type = JT_joint_parent;
194  if (_parent != (MaxNodeDesc *)NULL) {
195  _parent->mark_joint_parent();
196  }
197  }
198 }
199 
200 ////////////////////////////////////////////////////////////////////
201 // Function: MaxNodeDesc::check_pseudo_joints
202 // Access: Private
203 // Description: Walks the hierarchy, looking for non-joint nodes that
204 // are both children and parents of a joint. These
205 // nodes are deemed to be pseudo joints, since the
206 // converter must treat them as joints.
207 ////////////////////////////////////////////////////////////////////
208 void MaxNodeDesc::
209 check_pseudo_joints(bool joint_above) {
210  if (_joint_type == JT_joint_parent && joint_above) {
211  // This is one such node: it is the parent of a joint
212  // (JT_joint_parent is set), and it is the child of a joint
213  // (joint_above is set).
214  _joint_type = JT_pseudo_joint;
215  }
216 
217  if (_joint_type == JT_joint) {
218  // If this node is itself a joint, then joint_above is true for
219  // all child nodes.
220  joint_above = true;
221  }
222 
223  // Don't bother traversing further if _joint_type is none, since
224  // that means this node has no joint children.
225  if (_joint_type != JT_none) {
226  Children::const_iterator ci;
227  for (ci = _children.begin(); ci != _children.end(); ++ci) {
228  MaxNodeDesc *child = (*ci);
229  child->check_pseudo_joints(joint_above);
230  }
231  }
232 }
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
bool is_node_joint() const
Returns true if the node is the parent or ancestor of a joint.
bool is_joint_parent() const
Returns true if the node is the parent or ancestor of a joint.
INode * get_max_node() const
Returns the INode associated with this node.
void from_INode(INode *max_node)
Indicates an associated between the MaxNodeDesc and some Max Node instance.
Definition: maxNodeDesc.cxx:71
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:36
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
Definition: eggXfmSAnim.h:33
Describes a single instance of a node in the Max scene graph, relating it to the corresponding egg st...
Definition: maxNodeDesc.h:26
bool has_max_node() const
Returns true if a Max INode has been associated with this node, false otherwise.
MaxNodeDesc(MaxNodeDesc *parent=NULL, INode *max_node=NULL)
Creates a MaxNodeDesc.
Definition: maxNodeDesc.cxx:28
This corresponds to a.
Definition: eggTable.h:31
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85