Repaired some damaged caused by license change
This commit is contained in:
parent
c6a3f28530
commit
c1f4a937b6
|
|
@ -4,3 +4,219 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "maxNodeDesc.h"
|
||||
#include "maxLogger.h"
|
||||
#define MTEC Logger::ST_MAP_ME_TO_APP_SPECIFIC_SYSTEM4
|
||||
|
||||
TypeHandle MaxNodeDesc::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc::
|
||||
MaxNodeDesc(MaxNodeDesc *parent, const string &name) :
|
||||
Namable(name),
|
||||
_parent(parent)
|
||||
{
|
||||
_max_node = (INode *)NULL;
|
||||
_egg_group = (EggGroup *)NULL;
|
||||
_egg_table = (EggTable *)NULL;
|
||||
_anim = (EggXfmSAnim *)NULL;
|
||||
_joint_type = JT_none;
|
||||
_joint_entry = NULL;
|
||||
|
||||
// Add ourselves to our parent.
|
||||
if (_parent != (MaxNodeDesc *)NULL) {
|
||||
_parent->_children.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc::
|
||||
~MaxNodeDesc() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::from_INode
|
||||
// Access: Public
|
||||
// Description: Indicates an associated between the MaxNodeDesc and
|
||||
// some Max Node instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaxNodeDesc::
|
||||
from_INode(INode *max_node) {
|
||||
if (_max_node == (INode *)NULL) {
|
||||
_max_node = max_node;
|
||||
|
||||
// This is how I decided to check to see if this max node is a
|
||||
// joint. It works in all instances I've seen so far, but this
|
||||
// may be a good starting place to look if joints are not being
|
||||
// picked up correctly in the future.
|
||||
|
||||
//Check to see if the node's controller is a biped
|
||||
//If so treat it as a joint
|
||||
// Get the node's transform control
|
||||
Control *c = max_node->GetTMController();
|
||||
if (_max_node->GetBoneNodeOnOff() ||
|
||||
(c && //c exists and it's type is a biped
|
||||
((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
|
||||
(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
|
||||
(c->ClassID() == FOOTPRINT_CLASS_ID)))) {
|
||||
Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL, "Found a joint." );
|
||||
|
||||
// This node is a joint.
|
||||
_joint_type = JT_node_joint;
|
||||
if (_parent != (MaxNodeDesc *)NULL) {
|
||||
_parent->mark_joint_parent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::has_max_node
|
||||
// Access: Public
|
||||
// Description: Returns true if a Max INode has been associated
|
||||
// with this node, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeDesc::
|
||||
has_max_node() const {
|
||||
return (_max_node != (INode *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::get_max_node
|
||||
// Access: Public
|
||||
// Description: Returns the INode associated with this node. It
|
||||
// is an error to call this unless has_max_node()
|
||||
// returned true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INode *MaxNodeDesc::
|
||||
get_max_node() const {
|
||||
nassertr(_max_node != (INode *)NULL, _max_node);
|
||||
return _max_node;
|
||||
}
|
||||
|
||||
|
||||
void MaxNodeDesc::
|
||||
set_joint(bool onoff) {
|
||||
if (onoff)
|
||||
_joint_type = JT_joint;
|
||||
else
|
||||
_joint_type = JT_none;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::is_joint
|
||||
// Access: Private
|
||||
// Description: Returns true if the node should be treated as a joint
|
||||
// by the converter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeDesc::
|
||||
is_joint() const {
|
||||
return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::is_joint_parent
|
||||
// Access: Private
|
||||
// Description: Returns true if the node is the parent or ancestor of
|
||||
// a joint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeDesc::
|
||||
is_joint_parent() const {
|
||||
return _joint_type == JT_joint_parent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::is_joint_parent
|
||||
// Access: Private
|
||||
// Description: Returns true if the node is the parent or ancestor of
|
||||
// a joint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeDesc::
|
||||
is_node_joint() const {
|
||||
return _joint_type == JT_node_joint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::clear_egg
|
||||
// Access: Private
|
||||
// Description: Recursively clears the egg pointers from this node
|
||||
// and all children.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaxNodeDesc::
|
||||
clear_egg() {
|
||||
_egg_group = (EggGroup *)NULL;
|
||||
_egg_table = (EggTable *)NULL;
|
||||
_anim = (EggXfmSAnim *)NULL;
|
||||
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MaxNodeDesc *child = (*ci);
|
||||
child->clear_egg();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::mark_joint_parent
|
||||
// Access: Private
|
||||
// Description: Indicates that this node has at least one child that
|
||||
// is a joint or a pseudo-joint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaxNodeDesc::
|
||||
mark_joint_parent() {
|
||||
if (_joint_type == JT_none) {
|
||||
_joint_type = JT_joint_parent;
|
||||
if (_parent != (MaxNodeDesc *)NULL) {
|
||||
_parent->mark_joint_parent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeDesc::check_pseudo_joints
|
||||
// Access: Private
|
||||
// Description: Walks the hierarchy, looking for non-joint nodes that
|
||||
// are both children and parents of a joint. These
|
||||
// nodes are deemed to be pseudo joints, since the
|
||||
// converter must treat them as joints.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaxNodeDesc::
|
||||
check_pseudo_joints(bool joint_above) {
|
||||
if (_joint_type == JT_joint_parent && joint_above) {
|
||||
// This is one such node: it is the parent of a joint
|
||||
// (JT_joint_parent is set), and it is the child of a joint
|
||||
// (joint_above is set).
|
||||
_joint_type = JT_pseudo_joint;
|
||||
}
|
||||
|
||||
if (_joint_type == JT_joint) {
|
||||
// If this node is itself a joint, then joint_above is true for
|
||||
// all child nodes.
|
||||
joint_above = true;
|
||||
}
|
||||
|
||||
// Don't bother traversing further if _joint_type is none, since
|
||||
// that means this node has no joint children.
|
||||
if (_joint_type != JT_none) {
|
||||
Children::const_iterator ci;
|
||||
for (ci = _children.begin(); ci != _children.end(); ++ci) {
|
||||
MaxNodeDesc *child = (*ci);
|
||||
child->check_pseudo_joints(joint_above);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,3 +4,108 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MAXNODEDESC_H
|
||||
#define MAXNODEDESC_H
|
||||
|
||||
#pragma conform(forScope, off)
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "namable.h"
|
||||
|
||||
#ifdef MAX5
|
||||
//Disable the "Too many actual parameters in istdplug.h" warning in Max5
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4002)
|
||||
#include "max_pre_include.h"
|
||||
#endif
|
||||
#include <Max.h>
|
||||
#include "bipexp.h"
|
||||
#ifdef MAX5
|
||||
#include "max_post_include.h"
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
class EggGroup;
|
||||
class EggTable;
|
||||
class EggXfmSAnim;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MaxNodeDesc
|
||||
// Description : Describes a single instance of a node in the Max
|
||||
// scene graph, relating it to the corresponding egg
|
||||
// structures (e.g. node, group, or table entry) that
|
||||
// will be created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class MaxNodeDesc : public ReferenceCount, public Namable {
|
||||
public:
|
||||
MaxNodeDesc(MaxNodeDesc *parent = NULL, const string &name = string());
|
||||
~MaxNodeDesc();
|
||||
|
||||
void from_INode(INode *max_node);
|
||||
bool has_max_node() const;
|
||||
INode *get_max_node() const;
|
||||
|
||||
void set_joint(bool onoff);
|
||||
bool is_joint() const;
|
||||
bool is_joint_parent() const;
|
||||
bool is_node_joint() const;
|
||||
|
||||
MaxNodeDesc *_parent;
|
||||
MaxNodeDesc *_joint_entry;
|
||||
typedef pvector< MaxNodeDesc* > Children;
|
||||
Children _children;
|
||||
|
||||
private:
|
||||
void clear_egg();
|
||||
void mark_joint_parent();
|
||||
void check_pseudo_joints(bool joint_above);
|
||||
|
||||
INode *_max_node;
|
||||
|
||||
EggGroup *_egg_group;
|
||||
EggTable *_egg_table;
|
||||
EggXfmSAnim *_anim;
|
||||
|
||||
enum JointType {
|
||||
JT_none, // Not a joint.
|
||||
JT_node_joint, // Node that represents a joint in the geometry
|
||||
// but not the actual joint itself
|
||||
JT_joint, // An actual joint in Max.
|
||||
JT_pseudo_joint, // Not a joint in Max, but treated just like a
|
||||
// joint for the purposes of the converter.
|
||||
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
|
||||
};
|
||||
JointType _joint_type;
|
||||
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
Namable::init_type();
|
||||
register_type(_type_handle, "MaxNodeDesc",
|
||||
ReferenceCount::get_class_type(),
|
||||
Namable::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class MaxNodeTree;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,3 +4,488 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "maxNodeTree.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "eggData.h"
|
||||
|
||||
#ifdef MAX5
|
||||
//Disable the "Too many actual parameters in istdplug.h" warning in Max5
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4002)
|
||||
#include "max_pre_include.h"
|
||||
#endif
|
||||
#include "Max.h"
|
||||
#ifdef MAX5
|
||||
#include "max_post_include.h"
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include "maxToEggConverter.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeTree::
|
||||
MaxNodeTree() {
|
||||
_root = new MaxNodeDesc;
|
||||
_fps = 0.0;
|
||||
_egg_data = (EggData *)NULL;
|
||||
_egg_root = (EggGroupNode *)NULL;
|
||||
_skeleton_node = (EggGroupNode *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::build_node
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the node corresponding to the
|
||||
// indicated INode object, creating it first if
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
build_node(INode *max_node) {
|
||||
MaxNodeDesc *node_desc = r_build_node(max_node);
|
||||
node_desc->from_INode(max_node);
|
||||
if (node_desc->is_node_joint())
|
||||
node_desc->_joint_entry = build_joint(max_node, node_desc);
|
||||
return node_desc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::build_node
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the node corresponding to the
|
||||
// indicated INode object, creating it first if
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
build_joint(INode *max_node, MaxNodeDesc *node_joint) {
|
||||
MaxNodeDesc *node_desc = r_build_joint(node_joint, max_node);
|
||||
node_desc->from_INode(max_node);
|
||||
node_desc->set_joint(true);
|
||||
return node_desc;
|
||||
}
|
||||
|
||||
bool MaxNodeTree::node_in_list(ULONG handle, ULONG *list, int len) {
|
||||
if (!list) return true;
|
||||
for (int i = 0; i < len; i++)
|
||||
if (list[i] == handle) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MaxNodeTree::is_joint(INode *node) {
|
||||
Control *c = node->GetTMController();
|
||||
return (node->GetBoneNodeOnOff() || //joints
|
||||
(c && //bipeds
|
||||
((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) ||
|
||||
(c->ClassID() == BIPBODY_CONTROL_CLASS_ID) ||
|
||||
(c->ClassID() == FOOTPRINT_CLASS_ID))));
|
||||
}
|
||||
|
||||
bool MaxNodeTree::
|
||||
r_build_hierarchy(INode *root, ULONG *selection_list, int len) {
|
||||
if (node_in_list(root->GetHandle(), selection_list, len))
|
||||
build_node(root);
|
||||
// Export children
|
||||
for ( int i = 0; i < root->NumberOfChildren(); i++ ) {
|
||||
// *** Should probably be checking the return value of the following line
|
||||
r_build_hierarchy(root->GetChildNode(i), selection_list, len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::build_complete_hierarchy
|
||||
// Access: Public
|
||||
// Description: Walks through the complete Max hierarchy and builds
|
||||
// up the corresponding tree.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeTree::
|
||||
build_complete_hierarchy(INode *root, ULONG *selection_list, int len) {
|
||||
|
||||
// Get the entire Max scene.
|
||||
if (root == NULL) {
|
||||
// *** Log an error
|
||||
return false;
|
||||
}
|
||||
|
||||
bool all_ok = true;
|
||||
r_build_hierarchy(root, selection_list, len);
|
||||
|
||||
if (all_ok) {
|
||||
_root->check_pseudo_joints(false);
|
||||
}
|
||||
|
||||
Logger::Log( MTEC, Logger::SAT_MEDIUM_LEVEL,
|
||||
"finished building complete hierarchy" );
|
||||
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::build_selected_hierarchy
|
||||
// Access: Public
|
||||
// Description: Walks through the selected subset of the Max
|
||||
// hierarchy (or the complete hierarchy, if nothing is
|
||||
// selected) and builds up the corresponding tree.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MaxNodeTree::
|
||||
build_selected_hierarchy(INode *root) {
|
||||
// *** Write this later when it's time to do selection
|
||||
/*
|
||||
MStatus status;
|
||||
|
||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||
if (!status) {
|
||||
status.perror("MItDag constructor");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get only the selected geometry.
|
||||
MSelectionList selection;
|
||||
status = MGlobal::getActiveSelectionList(selection);
|
||||
if (!status) {
|
||||
status.perror("MGlobal::getActiveSelectionList");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the selected geometry only if the selection is nonempty;
|
||||
// otherwise, get the whole scene anyway.
|
||||
if (selection.isEmpty()) {
|
||||
mayaegg_cat.info()
|
||||
<< "Selection list is empty.\n";
|
||||
return build_complete_hierarchy();
|
||||
}
|
||||
*/
|
||||
bool all_ok = true;
|
||||
/*
|
||||
unsigned int length = selection.length();
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
MDagPath root_path;
|
||||
status = selection.getDagPath(i, root_path);
|
||||
if (!status) {
|
||||
status.perror("MSelectionList::getDagPath");
|
||||
} else {
|
||||
// Now traverse through the selected dag path and all nested
|
||||
// dag paths.
|
||||
dag_iterator.reset(root_path);
|
||||
while (!dag_iterator.isDone()) {
|
||||
MDagPath dag_path;
|
||||
status = dag_iterator.getPath(dag_path);
|
||||
if (!status) {
|
||||
status.perror("MItDag::getPath");
|
||||
} else {
|
||||
build_node(dag_path);
|
||||
}
|
||||
|
||||
dag_iterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_ok) {
|
||||
_root->check_pseudo_joints(false);
|
||||
}
|
||||
*/
|
||||
return all_ok;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_num_nodes
|
||||
// Access: Public
|
||||
// Description: Returns the total number of nodes in the hierarchy,
|
||||
// not counting the root node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int MaxNodeTree::
|
||||
get_num_nodes() const {
|
||||
return _nodes.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_node
|
||||
// Access: Public
|
||||
// Description: Returns the nth node in the hierarchy, in an
|
||||
// arbitrary ordering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
get_node(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
|
||||
return _nodes[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::clear_egg
|
||||
// Access: Public
|
||||
// Description: Removes all of the references to generated egg
|
||||
// structures from the tree, and prepares the tree for
|
||||
// generating new egg structures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaxNodeTree::
|
||||
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
||||
EggGroupNode *skeleton_node) {
|
||||
_root->clear_egg();
|
||||
_egg_data = egg_data;
|
||||
_egg_root = egg_root;
|
||||
_skeleton_node = skeleton_node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_egg_group
|
||||
// Access: Public
|
||||
// Description: Returns the EggGroupNode corresponding to the group
|
||||
// or joint for the indicated node. Creates the group
|
||||
// node if it has not already been created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggGroup *MaxNodeTree::
|
||||
get_egg_group(MaxNodeDesc *node_desc) {
|
||||
nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
|
||||
|
||||
if (node_desc->_egg_group == (EggGroup *)NULL) {
|
||||
// We need to make a new group node.
|
||||
EggGroup *egg_group;
|
||||
|
||||
nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
|
||||
egg_group = new EggGroup(node_desc->get_name());
|
||||
if (node_desc->is_joint()) {
|
||||
egg_group->set_group_type(EggGroup::GT_joint);
|
||||
}
|
||||
|
||||
if (node_desc->_parent == _root) {
|
||||
// The parent is the root.
|
||||
_egg_root->add_child(egg_group);
|
||||
|
||||
} else {
|
||||
// The parent is another node.
|
||||
EggGroup *parent_egg_group = get_egg_group(node_desc->_parent);
|
||||
parent_egg_group->add_child(egg_group);
|
||||
}
|
||||
|
||||
// *** This is probably something that a Max plugin would need to be
|
||||
// written for. May want to ask Disney about it
|
||||
/*
|
||||
if (node_desc->has_dag_path()) {
|
||||
// Check for an object type setting, from Oliver's plug-in.
|
||||
MObject dag_object = node_desc->get_dag_path().node();
|
||||
string object_type;
|
||||
if (get_enum_attribute(dag_object, "eggObjectTypes1", object_type)) {
|
||||
egg_group->add_object_type(object_type);
|
||||
}
|
||||
if (get_enum_attribute(dag_object, "eggObjectTypes2", object_type)) {
|
||||
egg_group->add_object_type(object_type);
|
||||
}
|
||||
if (get_enum_attribute(dag_object, "eggObjectTypes3", object_type)) {
|
||||
egg_group->add_object_type(object_type);
|
||||
}
|
||||
|
||||
// We treat the object type "billboard" as a special case: we
|
||||
// apply this one right away and also flag the group as an
|
||||
// instance.
|
||||
if (egg_group->has_object_type("billboard")) {
|
||||
egg_group->remove_object_type("billboard");
|
||||
egg_group->set_group_type(EggGroup::GT_instance);
|
||||
egg_group->set_billboard_type(EggGroup::BT_axis);
|
||||
|
||||
} else if (egg_group->has_object_type("billboard-point")) {
|
||||
egg_group->remove_object_type("billboard-point");
|
||||
egg_group->set_group_type(EggGroup::GT_instance);
|
||||
egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
|
||||
}
|
||||
|
||||
// We also treat the object type "dcs" and "model" as a special
|
||||
// case, so we can test for these flags later.
|
||||
if (egg_group->has_object_type("dcs")) {
|
||||
egg_group->remove_object_type("dcs");
|
||||
egg_group->set_dcs_type(EggGroup::DC_default);
|
||||
}
|
||||
if (egg_group->has_object_type("model")) {
|
||||
egg_group->remove_object_type("model");
|
||||
egg_group->set_model_flag(true);
|
||||
}
|
||||
|
||||
// And "vertex-color" has meaning only to this converter.
|
||||
if (egg_group->has_object_type("vertex-color")) {
|
||||
egg_group->remove_object_type("vertex-color");
|
||||
MaxEggGroupUserData *user_data = new MaxEggGroupUserData;
|
||||
user_data->_vertex_color = true;
|
||||
egg_group->set_user_data(user_data);
|
||||
}
|
||||
}
|
||||
*/
|
||||
node_desc->_egg_group = egg_group;
|
||||
}
|
||||
|
||||
return node_desc->_egg_group;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_egg_table
|
||||
// Access: Public
|
||||
// Description: Returns the EggTable corresponding to the joint
|
||||
// for the indicated node. Creates the table node if it
|
||||
// has not already been created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggTable *MaxNodeTree::
|
||||
get_egg_table(MaxNodeDesc *node_desc) {
|
||||
nassertr(_skeleton_node != (EggGroupNode *)NULL, NULL);
|
||||
nassertr(node_desc->is_joint(), NULL);
|
||||
|
||||
if (node_desc->_egg_table == (EggTable *)NULL) {
|
||||
// We need to make a new table node.
|
||||
nassertr(node_desc->_parent != (MaxNodeDesc *)NULL, NULL);
|
||||
|
||||
EggTable *egg_table = new EggTable(node_desc->get_name());
|
||||
node_desc->_anim = new EggXfmSAnim("xform",
|
||||
_egg_data->get_coordinate_system());
|
||||
node_desc->_anim->set_fps(_fps);
|
||||
egg_table->add_child(node_desc->_anim);
|
||||
|
||||
if (!node_desc->_parent->is_joint()) {
|
||||
// The parent is not a joint; put it at the top.
|
||||
_skeleton_node->add_child(egg_table);
|
||||
|
||||
} else {
|
||||
// The parent is another joint.
|
||||
EggTable *parent_egg_table = get_egg_table(node_desc->_parent);
|
||||
parent_egg_table->add_child(egg_table);
|
||||
}
|
||||
|
||||
node_desc->_egg_table = egg_table;
|
||||
}
|
||||
|
||||
return node_desc->_egg_table;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::get_egg_anim
|
||||
// Access: Public
|
||||
// Description: Returns the anim table corresponding to the joint
|
||||
// for the indicated node. Creates the table node if it
|
||||
// has not already been created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggXfmSAnim *MaxNodeTree::
|
||||
get_egg_anim(MaxNodeDesc *node_desc)
|
||||
{
|
||||
get_egg_table(node_desc);
|
||||
return node_desc->_anim;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::r_build_node
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of build_node().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
r_build_node(INode* max_node)
|
||||
{
|
||||
// If we have already encountered this pathname, return the
|
||||
// corresponding MaxNodeDesc immediately.
|
||||
|
||||
ULONG node_handle = 0;
|
||||
|
||||
if (max_node) {
|
||||
node_handle = max_node->GetHandle();
|
||||
}
|
||||
|
||||
NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
|
||||
if (ni != _nodes_by_path.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
|
||||
// Otherwise, we have to create it. Do this recursively, so we
|
||||
// create each node along the path.
|
||||
MaxNodeDesc *node_desc;
|
||||
|
||||
if (!max_node) {
|
||||
// This is the top.
|
||||
node_desc = _root;
|
||||
|
||||
} else {
|
||||
INode *parent_node;
|
||||
string local_name = max_node->GetName();
|
||||
if (max_node->IsRootNode()) {
|
||||
parent_node = NULL;
|
||||
} else {
|
||||
parent_node = max_node->GetParentNode();
|
||||
}
|
||||
|
||||
MaxNodeDesc *parent_node_desc = r_build_node(parent_node);
|
||||
node_desc = new MaxNodeDesc(parent_node_desc, local_name);
|
||||
_nodes.push_back(node_desc);
|
||||
}
|
||||
|
||||
_nodes_by_path.insert(NodesByPath::value_type(node_handle, node_desc));
|
||||
return node_desc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::r_build_joint
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of build_joint().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
r_build_joint(MaxNodeDesc *node_desc, INode *max_node)
|
||||
{
|
||||
MaxNodeDesc *node_joint;
|
||||
if (node_desc == _root) {
|
||||
node_joint = new MaxNodeDesc(_root, max_node->GetName());
|
||||
_nodes.push_back(node_joint);
|
||||
return node_joint;
|
||||
} else if (node_desc->is_node_joint() && node_desc->_joint_entry) {
|
||||
node_joint = new MaxNodeDesc(node_desc->_joint_entry, max_node->GetName());
|
||||
_nodes.push_back(node_joint);
|
||||
return node_joint;
|
||||
} else {
|
||||
return r_build_joint(node_desc->_parent, max_node);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::find_node
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of build_node().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
find_node(INode* max_node)
|
||||
{
|
||||
// If we have already encountered this pathname, return the
|
||||
// corresponding MaxNodeDesc immediately.
|
||||
|
||||
ULONG node_handle = 0;
|
||||
|
||||
if (max_node) {
|
||||
node_handle = max_node->GetHandle();
|
||||
}
|
||||
|
||||
NodesByPath::const_iterator ni = _nodes_by_path.find(node_handle);
|
||||
if (ni != _nodes_by_path.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaxNodeTree::find_joint
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of build_node().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MaxNodeDesc *MaxNodeTree::
|
||||
find_joint(INode* max_node)
|
||||
{
|
||||
MaxNodeDesc *node = find_node(max_node);
|
||||
if (!node || (is_joint(max_node) && !node->is_node_joint()))
|
||||
node = build_node(max_node);
|
||||
return node->_joint_entry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,3 +4,68 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MAXNODETREE_H
|
||||
#define MAXNODETREE_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "maxNodeDesc.h"
|
||||
|
||||
class EggData;
|
||||
class EggGroupNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MaxNodeTree
|
||||
// Description : Describes a complete tree of max nodes for
|
||||
// conversion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class MaxNodeTree {
|
||||
public:
|
||||
MaxNodeTree();
|
||||
MaxNodeDesc *build_node(INode *max_node);
|
||||
MaxNodeDesc *build_joint(INode *max_node, MaxNodeDesc *node_joint);
|
||||
bool build_complete_hierarchy(INode *root, ULONG *selection_list, int len);
|
||||
bool build_selected_hierarchy(INode *root);
|
||||
MaxNodeDesc *find_node(INode *max_node);
|
||||
MaxNodeDesc *find_joint(INode *max_node);
|
||||
|
||||
int get_num_nodes() const;
|
||||
MaxNodeDesc *get_node(int n) const;
|
||||
|
||||
void clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
||||
EggGroupNode *skeleton_node);
|
||||
EggGroup *get_egg_group(MaxNodeDesc *node_desc);
|
||||
EggTable *get_egg_table(MaxNodeDesc *node_desc);
|
||||
EggXfmSAnim *get_egg_anim(MaxNodeDesc *node_desc);
|
||||
|
||||
MaxNodeDesc* _root;
|
||||
float _fps;
|
||||
|
||||
private:
|
||||
EggData *_egg_data;
|
||||
EggGroupNode *_egg_root;
|
||||
EggGroupNode *_skeleton_node;
|
||||
|
||||
MaxNodeDesc *r_build_node(INode *max_node);
|
||||
MaxNodeDesc *r_build_joint(MaxNodeDesc *node_desc, INode *max_node);
|
||||
bool node_in_list(ULONG handle, ULONG *list, int len);
|
||||
bool r_build_hierarchy(INode *root, ULONG *selection_list, int len);
|
||||
bool is_joint(INode *node);
|
||||
|
||||
typedef pmap<ULONG, MaxNodeDesc *> NodesByPath;
|
||||
NodesByPath _nodes_by_path;
|
||||
|
||||
typedef pvector<MaxNodeDesc *> Nodes;
|
||||
Nodes _nodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,3 +3,18 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This header file works in conjunction with pre_maya_include.h; it
|
||||
// cleans up some of the definitions that it left open.
|
||||
|
||||
// Remove the symbols defined from pre_maya_include.h.
|
||||
#undef ostream
|
||||
#undef istream
|
||||
|
|
|
|||
|
|
@ -3,3 +3,29 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This header file defines a few things that are necessary to define
|
||||
// before including any Maya headers, just to work around some of
|
||||
// Max's assumptions about the compiler. It must not try to protect
|
||||
// itself from multiple inclusion with #ifdef .. #endif, since it must
|
||||
// be used each time it is included.
|
||||
|
||||
// Max will try to typedef bool unless this symbol is defined.
|
||||
#ifndef _BOOL
|
||||
#define _BOOL 1
|
||||
#endif
|
||||
|
||||
// Max tries to make a forward declaration for class ostream, but
|
||||
// this is not necessarily a class! Curses. We can't use any of the
|
||||
// built-in Max stream operators, and we have to protect ourselves
|
||||
// from them.
|
||||
#define ostream max_ostream
|
||||
#define istream max_istream
|
||||
|
|
|
|||
Loading…
Reference in New Issue