Panda3D
Loading...
Searching...
No Matches
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
16TypeHandle 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 */
23MaxNodeDesc(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 */
54MaxNodeDesc::
55~MaxNodeDesc() {}
56
57/**
58 * Indicates an associated between the MaxNodeDesc and some Max Node instance.
59 */
61from_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 */
93has_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 */
102get_max_node() const {
103 nassertr(_max_node != nullptr, _max_node);
104 return _max_node;
105}
106
107
108void MaxNodeDesc::
109set_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 */
120is_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 */
128is_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 */
136is_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 */
143void MaxNodeDesc::
144clear_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 */
160void MaxNodeDesc::
161mark_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 */
175void MaxNodeDesc::
176check_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}
Describes a single instance of a node in the Max scene graph, relating it to the corresponding egg st...
Definition maxNodeDesc.h:22
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
MaxNodeDesc(MaxNodeDesc *parent=nullptr, INode *max_node=nullptr)
Creates a MaxNodeDesc.
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.
bool has_max_node() const
Returns true if a Max INode has been associated with this node, false otherwise.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81