26 _skeleton_node =
nullptr;
39 node_desc->_joint_entry =
build_joint(max_node, node_desc);
50 MaxNodeDesc *node_desc = r_build_joint(node_joint, max_node);
52 node_desc->set_joint(
true);
56 bool MaxNodeTree::node_in_list(ULONG handle, ULONG *list,
int len) {
57 if (!list)
return true;
58 for (
int i = 0; i < len; i++)
59 if (list[i] == handle)
return true;
63 bool MaxNodeTree::is_joint(INode *node) {
64 Control *c = node->GetTMController();
65 return (node->GetBoneNodeOnOff() ||
67 ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
68 (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
69 (c->ClassID() == FOOTPRINT_CLASS_ID))));
73 r_build_hierarchy(INode *root, ULONG *selection_list,
int len) {
74 if (node_in_list(root->GetHandle(), selection_list, len))
77 for (
int i = 0; i < root->NumberOfChildren(); i++ ) {
79 r_build_hierarchy(root->GetChildNode(i), selection_list, len);
91 if (root ==
nullptr) {
97 r_build_hierarchy(root, selection_list, len);
100 _root->check_pseudo_joints(
false);
112 return _nodes.size();
120 nassertr(n >= 0 && n < (
int)_nodes.size(),
nullptr);
132 _egg_data = egg_data;
133 _egg_root = egg_root;
134 _skeleton_node = skeleton_node;
143 nassertr(_egg_root !=
nullptr,
nullptr);
145 if (node_desc->_egg_group ==
nullptr) {
149 nassertr(node_desc->_parent !=
nullptr,
nullptr);
150 egg_group =
new EggGroup(node_desc->get_name());
152 egg_group->set_group_type(EggGroup::GT_joint);
154 if (node_desc->_parent == _root) {
159 set_collision_tags(node_desc, egg_group);
168 if(node_desc->_parent->_parent == _root)
170 set_collision_tags(node_desc, egg_group);
177 node_desc->_egg_group = egg_group;
180 return node_desc->_egg_group;
189 nassertr(_skeleton_node !=
nullptr,
nullptr);
190 nassertr(node_desc->
is_joint(),
nullptr);
192 if (node_desc->_egg_table ==
nullptr) {
194 nassertr(node_desc->_parent !=
nullptr,
nullptr);
199 node_desc->_anim->set_fps(_fps);
202 if (!node_desc->_parent->
is_joint()) {
212 node_desc->_egg_table = egg_table;
215 return node_desc->_egg_table;
225 return node_desc->_anim;
232 r_build_node(INode* max_node) {
236 ULONG node_handle = 0;
239 node_handle = max_node->GetHandle();
242 NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
243 if (ni != _nodes_by_path.end()) {
258 if (max_node->IsRootNode()) {
259 parent_node =
nullptr;
261 parent_node = max_node->GetParentNode();
264 MaxNodeDesc *parent_node_desc = r_build_node(parent_node);
265 node_desc =
new MaxNodeDesc(parent_node_desc, max_node);
266 _nodes.push_back(node_desc);
269 _nodes_by_path.insert(NodesByPath::value_type(node_handle, node_desc));
277 r_build_joint(
MaxNodeDesc *node_desc, INode *max_node)
280 if (node_desc == _root) {
282 _nodes.push_back(node_joint);
284 }
else if (node_desc->
is_node_joint() && node_desc->_joint_entry) {
285 node_joint =
new MaxNodeDesc(node_desc->_joint_entry, max_node);
286 _nodes.push_back(node_joint);
289 return r_build_joint(node_desc->_parent, max_node);
301 ULONG node_handle = 0;
304 node_handle = max_node->GetHandle();
307 NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
308 if (ni != _nodes_by_path.end()) {
324 return node->_joint_entry;
341 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"polyset"), check)) {
344 egg_group->set_collision_name(node_desc->get_name());
345 egg_group->set_cs_type(EggGroup::CST_polyset);
348 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"plane"), check)) {
351 egg_group->set_collision_name(node_desc->get_name());
352 egg_group->set_cs_type(EggGroup::CST_plane);
355 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"polygon"), check)) {
358 egg_group->set_collision_name(node_desc->get_name());
359 egg_group->set_cs_type(EggGroup::CST_polygon);
362 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"sphere"), check)) {
365 egg_group->set_collision_name(node_desc->get_name());
366 egg_group->set_cs_type(EggGroup::CST_sphere);
369 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"inv-sphere"), check)) {
372 egg_group->set_collision_name(node_desc->get_name());
373 egg_group->set_cs_type(EggGroup::CST_inv_sphere);
376 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"invsphere"), check)) {
379 egg_group->set_collision_name(node_desc->get_name());
380 egg_group->set_cs_type(EggGroup::CST_inv_sphere);
383 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"tube"), check)) {
386 egg_group->set_collision_name(node_desc->get_name());
387 egg_group->set_cs_type(EggGroup::CST_tube);
390 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"floor-mesh"), check)) {
393 egg_group->set_collision_name(node_desc->get_name());
394 egg_group->set_cs_type(EggGroup::CST_floor_mesh);
398 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"descend"), check)) {
401 egg_group->set_collide_flags(EggGroup::CF_descend);
404 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"event"), check)) {
407 egg_group->set_collide_flags(EggGroup::CF_event);
410 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"keep"), check)) {
413 egg_group->set_collide_flags(EggGroup::CF_keep);
416 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"solid"), check)) {
419 egg_group->set_collide_flags(EggGroup::CF_solid);
422 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"center"), check)) {
425 egg_group->set_collide_flags(EggGroup::CF_center);
428 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"turnstile"), check)) {
431 egg_group->set_collide_flags(EggGroup::CF_turnstile);
434 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"level"), check)) {
437 egg_group->set_collide_flags(EggGroup::CF_level);
440 if (node_desc->
get_max_node()->GetUserPropInt(_T(
"intangible"), check)) {
443 egg_group->set_collide_flags(EggGroup::CF_intangible);
EggGroup * get_egg_group(MaxNodeDesc *node_desc)
Returns the EggGroupNode corresponding to the group or joint for the indicated node.
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
A base class for nodes in the hierarchy that are not leaf nodes.
int get_num_nodes() const
Returns the total number of nodes in the hierarchy, not counting the root node.
EggXfmSAnim * get_egg_anim(MaxNodeDesc *node_desc)
Returns the anim table corresponding to the joint for the indicated node.
MaxNodeDesc * build_node(INode *max_node)
Returns a pointer to the node corresponding to the indicated INode object, creating it first if neces...
bool is_node_joint() const
Returns true if the node is the parent or ancestor of a joint.
bool build_complete_hierarchy(INode *root, ULONG *selection_list, int len)
Walks through the complete Max hierarchy and builds up the corresponding tree.
MaxNodeDesc * find_joint(INode *max_node)
The recursive implementation of build_node().
This is the primary interface into all the egg data, and the root of the egg file structure.
void from_INode(INode *max_node)
Indicates an associated between the MaxNodeDesc and some Max Node instance.
MaxNodeDesc * build_joint(INode *max_node, MaxNodeDesc *node_joint)
Returns a pointer to the node corresponding to the indicated INode object, creating it first if neces...
MaxNodeDesc * get_node(int n) const
Returns the nth node in the hierarchy, in an arbitrary ordering.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node)
Removes all of the references to generated egg structures from the tree, and prepares the tree for ge...
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
Describes a single instance of a node in the Max scene graph, relating it to the corresponding egg st...
MaxNodeDesc * find_node(INode *max_node)
The recursive implementation of build_node().
INode * get_max_node() const
Returns the INode associated with this node.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
get_coordinate_system
Returns the coordinate system in which the egg file is defined.
EggTable * get_egg_table(MaxNodeDesc *node_desc)
Returns the EggTable corresponding to the joint for the indicated node.