Panda3D

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