mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
build a tree of NodeDesc's first, then use to generate joints and tables
This commit is contained in:
parent
da5268db7a
commit
74d002cb4e
@ -17,6 +17,8 @@
|
|||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_mayaegg.cxx config_mayaegg.h \
|
config_mayaegg.cxx config_mayaegg.h \
|
||||||
mayaEggGroupUserData.cxx mayaEggGroupUserData.I mayaEggGroupUserData.h \
|
mayaEggGroupUserData.cxx mayaEggGroupUserData.I mayaEggGroupUserData.h \
|
||||||
|
mayaNodeDesc.cxx mayaNodeDesc.h \
|
||||||
|
mayaNodeTree.cxx mayaNodeTree.h \
|
||||||
mayaToEggConverter.cxx mayaToEggConverter.h
|
mayaToEggConverter.cxx mayaToEggConverter.h
|
||||||
|
|
||||||
#end ss_lib_target
|
#end ss_lib_target
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "config_mayaegg.h"
|
#include "config_mayaegg.h"
|
||||||
#include "mayaEggGroupUserData.h"
|
#include "mayaEggGroupUserData.h"
|
||||||
|
#include "mayaNodeDesc.h"
|
||||||
|
|
||||||
#include "dconfig.h"
|
#include "dconfig.h"
|
||||||
|
|
||||||
@ -45,5 +46,6 @@ init_libmayaegg() {
|
|||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
MayaEggGroupUserData::init_type();
|
MayaEggGroupUserData::init_type();
|
||||||
|
MayaNodeDesc::init_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
191
pandatool/src/mayaegg/mayaNodeDesc.cxx
Executable file
191
pandatool/src/mayaegg/mayaNodeDesc.cxx
Executable file
@ -0,0 +1,191 @@
|
|||||||
|
// Filename: mayaNodeDesc.cxx
|
||||||
|
// Created by: drose (06Jun03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "mayaNodeDesc.h"
|
||||||
|
|
||||||
|
TypeHandle MayaNodeDesc::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeDesc::
|
||||||
|
MayaNodeDesc(MayaNodeDesc *parent, const string &name) :
|
||||||
|
Namable(name),
|
||||||
|
_parent(parent)
|
||||||
|
{
|
||||||
|
_dag_path = (MDagPath *)NULL;
|
||||||
|
_egg_group = (EggGroup *)NULL;
|
||||||
|
_egg_table = (EggTable *)NULL;
|
||||||
|
_anim = (EggXfmSAnim *)NULL;
|
||||||
|
_joint_type = JT_none;
|
||||||
|
|
||||||
|
// Add ourselves to our parent.
|
||||||
|
if (_parent != (MayaNodeDesc *)NULL) {
|
||||||
|
_parent->_children.push_back(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeDesc::
|
||||||
|
~MayaNodeDesc() {
|
||||||
|
if (_dag_path != (MDagPath *)NULL) {
|
||||||
|
delete _dag_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::from_dag_path
|
||||||
|
// Access: Public
|
||||||
|
// Description: Indicates an associated between the MayaNodeDesc and
|
||||||
|
// some Maya instance.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaNodeDesc::
|
||||||
|
from_dag_path(const MDagPath &dag_path) {
|
||||||
|
if (_dag_path == (MDagPath *)NULL) {
|
||||||
|
_dag_path = new MDagPath(dag_path);
|
||||||
|
|
||||||
|
if (_dag_path->hasFn(MFn::kJoint)) {
|
||||||
|
// This node is a joint.
|
||||||
|
_joint_type = JT_joint;
|
||||||
|
if (_parent != (MayaNodeDesc *)NULL) {
|
||||||
|
_parent->mark_joint_parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::has_dag_path
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if a Maya dag path has been associated
|
||||||
|
// with this node, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaNodeDesc::
|
||||||
|
has_dag_path() const {
|
||||||
|
return (_dag_path != (MDagPath *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::get_dag_path
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the dag path associated with this node. It
|
||||||
|
// is an error to call this unless has_dag_path()
|
||||||
|
// returned true.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const MDagPath &MayaNodeDesc::
|
||||||
|
get_dag_path() const {
|
||||||
|
nassertr(_dag_path != (MDagPath *)NULL, *_dag_path);
|
||||||
|
return *_dag_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::is_joint
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns true if the node should be treated as a joint
|
||||||
|
// by the converter.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaNodeDesc::
|
||||||
|
is_joint() const {
|
||||||
|
return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::is_joint_parent
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns true if the node is the parent or ancestor of
|
||||||
|
// a joint.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaNodeDesc::
|
||||||
|
is_joint_parent() const {
|
||||||
|
return _joint_type == JT_joint_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::clear_egg
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recursively clears the egg pointers from this node
|
||||||
|
// and all children.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaNodeDesc::
|
||||||
|
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) {
|
||||||
|
MayaNodeDesc *child = (*ci);
|
||||||
|
child->clear_egg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::mark_joint_parent
|
||||||
|
// Access: Private
|
||||||
|
// Description: Indicates that this node has at least one child that
|
||||||
|
// is a joint or a pseudo-joint.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void MayaNodeDesc::
|
||||||
|
mark_joint_parent() {
|
||||||
|
if (_joint_type == JT_none) {
|
||||||
|
_joint_type = JT_joint_parent;
|
||||||
|
if (_parent != (MayaNodeDesc *)NULL) {
|
||||||
|
_parent->mark_joint_parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeDesc::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 MayaNodeDesc::
|
||||||
|
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) {
|
||||||
|
MayaNodeDesc *child = (*ci);
|
||||||
|
child->check_pseudo_joints(joint_above);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
pandatool/src/mayaegg/mayaNodeDesc.h
Executable file
98
pandatool/src/mayaegg/mayaNodeDesc.h
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
// Filename: mayaNodeDesc.h
|
||||||
|
// Created by: drose (06Jun03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MAYANODEDESC_H
|
||||||
|
#define MAYANODEDESC_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
|
#include "referenceCount.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "namable.h"
|
||||||
|
|
||||||
|
#include "pre_maya_include.h"
|
||||||
|
#include <maya/MDagPath.h>
|
||||||
|
#include "post_maya_include.h"
|
||||||
|
|
||||||
|
class EggGroup;
|
||||||
|
class EggTable;
|
||||||
|
class EggXfmSAnim;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : MayaNodeDesc
|
||||||
|
// Description : Describes a single instance of a node in the Maya
|
||||||
|
// scene graph, relating it to the corresponding egg
|
||||||
|
// structures (e.g. node, group, or table entry) that
|
||||||
|
// will be created.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class MayaNodeDesc : public ReferenceCount, public Namable {
|
||||||
|
public:
|
||||||
|
MayaNodeDesc(MayaNodeDesc *parent = NULL, const string &name = string());
|
||||||
|
~MayaNodeDesc();
|
||||||
|
|
||||||
|
void from_dag_path(const MDagPath &dag_path);
|
||||||
|
bool has_dag_path() const;
|
||||||
|
const MDagPath &get_dag_path() const;
|
||||||
|
|
||||||
|
bool is_joint() const;
|
||||||
|
bool is_joint_parent() const;
|
||||||
|
|
||||||
|
MayaNodeDesc *_parent;
|
||||||
|
typedef pvector< PT(MayaNodeDesc) > Children;
|
||||||
|
Children _children;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clear_egg();
|
||||||
|
void mark_joint_parent();
|
||||||
|
void check_pseudo_joints(bool joint_above);
|
||||||
|
|
||||||
|
MDagPath *_dag_path;
|
||||||
|
|
||||||
|
EggGroup *_egg_group;
|
||||||
|
EggTable *_egg_table;
|
||||||
|
EggXfmSAnim *_anim;
|
||||||
|
|
||||||
|
enum JointType {
|
||||||
|
JT_none, // Not a joint.
|
||||||
|
JT_joint, // An actual joint in Maya.
|
||||||
|
JT_pseudo_joint, // Not a joint in Maya, 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, "MayaNodeDesc",
|
||||||
|
ReferenceCount::get_class_type(),
|
||||||
|
Namable::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class MayaNodeTree;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
387
pandatool/src/mayaegg/mayaNodeTree.cxx
Executable file
387
pandatool/src/mayaegg/mayaNodeTree.cxx
Executable file
@ -0,0 +1,387 @@
|
|||||||
|
// Filename: mayaNodeTree.cxx
|
||||||
|
// Created by: drose (06Jun03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "mayaNodeTree.h"
|
||||||
|
#include "mayaEggGroupUserData.h"
|
||||||
|
#include "config_mayaegg.h"
|
||||||
|
#include "maya_funcs.h"
|
||||||
|
#include "eggGroup.h"
|
||||||
|
#include "eggTable.h"
|
||||||
|
#include "eggXfmSAnim.h"
|
||||||
|
#include "eggData.h"
|
||||||
|
|
||||||
|
#include "pre_maya_include.h"
|
||||||
|
#include <maya/MString.h>
|
||||||
|
#include <maya/MItDag.h>
|
||||||
|
#include <maya/MSelectionList.h>
|
||||||
|
#include <maya/MGlobal.h>
|
||||||
|
#include "post_maya_include.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeTree::
|
||||||
|
MayaNodeTree() {
|
||||||
|
_root = new MayaNodeDesc;
|
||||||
|
_fps = 0.0;
|
||||||
|
_egg_data = (EggData *)NULL;
|
||||||
|
_egg_root = (EggGroupNode *)NULL;
|
||||||
|
_skeleton_node = (EggGroupNode *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::build_node
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns a pointer to the node corresponding to the
|
||||||
|
// indicated dag_path object, creating it first if
|
||||||
|
// necessary.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeDesc *MayaNodeTree::
|
||||||
|
build_node(const MDagPath &dag_path) {
|
||||||
|
MayaNodeDesc *node_desc = r_build_node(dag_path.fullPathName().asChar());
|
||||||
|
node_desc->from_dag_path(dag_path);
|
||||||
|
return node_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::build_complete_hierarchy
|
||||||
|
// Access: Public
|
||||||
|
// Description: Walks through the complete Maya hierarchy and builds
|
||||||
|
// up the corresponding tree.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaNodeTree::
|
||||||
|
build_complete_hierarchy() {
|
||||||
|
MStatus status;
|
||||||
|
|
||||||
|
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||||
|
if (!status) {
|
||||||
|
status.perror("MItDag constructor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the entire Maya scene.
|
||||||
|
|
||||||
|
// This while loop walks through the entire Maya hierarchy, one
|
||||||
|
// node at a time. Maya's MItDag object automatically performs a
|
||||||
|
// depth-first traversal of its scene graph.
|
||||||
|
|
||||||
|
bool all_ok = true;
|
||||||
|
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: MayaNodeTree::build_selected_hierarchy
|
||||||
|
// Access: Public
|
||||||
|
// Description: Walks through the selected subset of the Maya
|
||||||
|
// hierarchy (or the complete hierarchy, if nothing is
|
||||||
|
// selected) and builds up the corresponding tree.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaNodeTree::
|
||||||
|
build_selected_hierarchy() {
|
||||||
|
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: MayaNodeTree::get_num_nodes
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the total number of nodes in the hierarchy,
|
||||||
|
// not counting the root node.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int MayaNodeTree::
|
||||||
|
get_num_nodes() const {
|
||||||
|
return _nodes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::get_node
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the nth node in the hierarchy, in an
|
||||||
|
// arbitrary ordering.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeDesc *MayaNodeTree::
|
||||||
|
get_node(int n) const {
|
||||||
|
nassertr(n >= 0 && n < (int)_nodes.size(), NULL);
|
||||||
|
return _nodes[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::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 MayaNodeTree::
|
||||||
|
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: MayaNodeTree::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 *MayaNodeTree::
|
||||||
|
get_egg_group(MayaNodeDesc *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 != (MayaNodeDesc *)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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
MayaEggGroupUserData *user_data = new MayaEggGroupUserData;
|
||||||
|
user_data->_vertex_color = true;
|
||||||
|
egg_group->set_user_data(user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node_desc->_egg_group = egg_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node_desc->_egg_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::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 *MayaNodeTree::
|
||||||
|
get_egg_table(MayaNodeDesc *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 != (MayaNodeDesc *)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: MayaNodeTree::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 *MayaNodeTree::
|
||||||
|
get_egg_anim(MayaNodeDesc *node_desc) {
|
||||||
|
get_egg_table(node_desc);
|
||||||
|
return node_desc->_anim;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaNodeTree::r_build_node
|
||||||
|
// Access: Private
|
||||||
|
// Description: The recursive implementation of build_node().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
MayaNodeDesc *MayaNodeTree::
|
||||||
|
r_build_node(const string &path) {
|
||||||
|
// If we have already encountered this pathname, return the
|
||||||
|
// corresponding MayaNodeDesc immediately.
|
||||||
|
NodesByPath::const_iterator ni = _nodes_by_path.find(path);
|
||||||
|
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.
|
||||||
|
MayaNodeDesc *node_desc;
|
||||||
|
|
||||||
|
if (path.empty()) {
|
||||||
|
// This is the top.
|
||||||
|
node_desc = _root;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Maya uses vertical bars to separate path components. Remove
|
||||||
|
// everything from the rightmost bar on; this will give us the
|
||||||
|
// parent's path name.
|
||||||
|
size_t bar = path.rfind("|");
|
||||||
|
string parent_path, local_name;
|
||||||
|
if (bar != string::npos) {
|
||||||
|
parent_path = path.substr(0, bar);
|
||||||
|
local_name = path.substr(bar + 1);
|
||||||
|
} else {
|
||||||
|
local_name = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
MayaNodeDesc *parent_node_desc = r_build_node(parent_path);
|
||||||
|
node_desc = new MayaNodeDesc(parent_node_desc, local_name);
|
||||||
|
_nodes.push_back(node_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
_nodes_by_path.insert(NodesByPath::value_type(path, node_desc));
|
||||||
|
return node_desc;
|
||||||
|
}
|
67
pandatool/src/mayaegg/mayaNodeTree.h
Executable file
67
pandatool/src/mayaegg/mayaNodeTree.h
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
// Filename: mayaNodeTree.h
|
||||||
|
// Created by: drose (06Jun03)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MAYANODETREE_H
|
||||||
|
#define MAYANODETREE_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
|
#include "mayaNodeDesc.h"
|
||||||
|
|
||||||
|
class EggData;
|
||||||
|
class EggGroupNode;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : MayaNodeTree
|
||||||
|
// Description : Describes a complete tree of maya nodes for
|
||||||
|
// conversion.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class MayaNodeTree {
|
||||||
|
public:
|
||||||
|
MayaNodeTree();
|
||||||
|
MayaNodeDesc *build_node(const MDagPath &dag_path);
|
||||||
|
bool build_complete_hierarchy();
|
||||||
|
bool build_selected_hierarchy();
|
||||||
|
|
||||||
|
int get_num_nodes() const;
|
||||||
|
MayaNodeDesc *get_node(int n) const;
|
||||||
|
|
||||||
|
void clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
||||||
|
EggGroupNode *skeleton_node);
|
||||||
|
EggGroup *get_egg_group(MayaNodeDesc *node_desc);
|
||||||
|
EggTable *get_egg_table(MayaNodeDesc *node_desc);
|
||||||
|
EggXfmSAnim *get_egg_anim(MayaNodeDesc *node_desc);
|
||||||
|
|
||||||
|
PT(MayaNodeDesc) _root;
|
||||||
|
float _fps;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EggData *_egg_data;
|
||||||
|
EggGroupNode *_egg_root;
|
||||||
|
EggGroupNode *_skeleton_node;
|
||||||
|
|
||||||
|
MayaNodeDesc *r_build_node(const string &path);
|
||||||
|
|
||||||
|
typedef pmap<string, MayaNodeDesc *> NodesByPath;
|
||||||
|
NodesByPath _nodes_by_path;
|
||||||
|
|
||||||
|
typedef pvector<MayaNodeDesc *> Nodes;
|
||||||
|
Nodes _nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -188,8 +188,6 @@ convert_maya(bool from_selection) {
|
|||||||
_from_selection = from_selection;
|
_from_selection = from_selection;
|
||||||
_textures.clear();
|
_textures.clear();
|
||||||
_shaders.clear();
|
_shaders.clear();
|
||||||
_groups.clear();
|
|
||||||
_tables.clear();
|
|
||||||
|
|
||||||
if (!open_api()) {
|
if (!open_api()) {
|
||||||
mayaegg_cat.error()
|
mayaegg_cat.error()
|
||||||
@ -235,6 +233,13 @@ convert_maya(bool from_selection) {
|
|||||||
|
|
||||||
bool all_ok = true;
|
bool all_ok = true;
|
||||||
|
|
||||||
|
if (_from_selection) {
|
||||||
|
all_ok = _tree.build_selected_hierarchy();
|
||||||
|
} else {
|
||||||
|
all_ok = _tree.build_complete_hierarchy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_ok) {
|
||||||
switch (get_animation_convert()) {
|
switch (get_animation_convert()) {
|
||||||
case AC_pose:
|
case AC_pose:
|
||||||
// pose: set to a specific frame, then get out the static geometry.
|
// pose: set to a specific frame, then get out the static geometry.
|
||||||
@ -282,6 +287,7 @@ convert_maya(bool from_selection) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
reparent_decals(&get_egg_data());
|
reparent_decals(&get_egg_data());
|
||||||
|
}
|
||||||
|
|
||||||
if (all_ok) {
|
if (all_ok) {
|
||||||
mayaegg_cat.info()
|
mayaegg_cat.info()
|
||||||
@ -355,10 +361,9 @@ convert_flip(double start_frame, double end_frame, double frame_inc,
|
|||||||
sequence_node->add_child(frame_root);
|
sequence_node->add_child(frame_root);
|
||||||
|
|
||||||
MGlobal::viewFrame(frame);
|
MGlobal::viewFrame(frame);
|
||||||
if (!convert_hierarchy(frame_root)) {
|
if (!convert_hierarchy(&get_egg_data())) {
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
}
|
}
|
||||||
_groups.clear();
|
|
||||||
|
|
||||||
frame += frame_inc;
|
frame += frame_inc;
|
||||||
}
|
}
|
||||||
@ -408,38 +413,10 @@ convert_char_chan(double start_frame, double end_frame, double frame_inc,
|
|||||||
EggTable *skeleton_node = new EggTable("<skeleton>");
|
EggTable *skeleton_node = new EggTable("<skeleton>");
|
||||||
bundle_node->add_child(skeleton_node);
|
bundle_node->add_child(skeleton_node);
|
||||||
|
|
||||||
// First, walk through the scene graph and build up the table of
|
// Set the frame rate before we start asking for anim tables to be
|
||||||
// joints.
|
// created.
|
||||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
_tree._fps = output_frame_rate / frame_inc;
|
||||||
if (!status) {
|
_tree.clear_egg(&get_egg_data(), NULL, skeleton_node);
|
||||||
status.perror("MItDag constructor");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool all_ok = true;
|
|
||||||
while (!dag_iterator.isDone()) {
|
|
||||||
MDagPath dag_path;
|
|
||||||
status = dag_iterator.getPath(dag_path);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MItDag::getPath");
|
|
||||||
} else {
|
|
||||||
if (!process_chan_node(dag_path, skeleton_node)) {
|
|
||||||
all_ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dag_iterator.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now walk through the joints in that table and make sure they're
|
|
||||||
// all set to use the correct frame frame.
|
|
||||||
double fps = output_frame_rate / frame_inc;
|
|
||||||
Tables::iterator ti;
|
|
||||||
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
|
|
||||||
JointAnim *joint_anim = (*ti).second;
|
|
||||||
nassertr(joint_anim != (JointAnim *)NULL &&
|
|
||||||
joint_anim->_anim != (EggXfmSAnim *)NULL, false);
|
|
||||||
joint_anim->_anim->set_fps(fps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can get the animation data by walking through all of the
|
// Now we can get the animation data by walking through all of the
|
||||||
// frames, one at a time, and getting the joint angles at each
|
// frames, one at a time, and getting the joint angles at each
|
||||||
@ -449,6 +426,9 @@ convert_char_chan(double start_frame, double end_frame, double frame_inc,
|
|||||||
// each joint each frame.
|
// each joint each frame.
|
||||||
PT(EggGroup) tgroup = new EggGroup;
|
PT(EggGroup) tgroup = new EggGroup;
|
||||||
|
|
||||||
|
int num_nodes = _tree.get_num_nodes();
|
||||||
|
int i;
|
||||||
|
|
||||||
MTime frame(start_frame, MTime::uiUnit());
|
MTime frame(start_frame, MTime::uiUnit());
|
||||||
MTime frame_stop(end_frame, MTime::uiUnit());
|
MTime frame_stop(end_frame, MTime::uiUnit());
|
||||||
while (frame <= frame_stop) {
|
while (frame <= frame_stop) {
|
||||||
@ -461,114 +441,50 @@ convert_char_chan(double start_frame, double end_frame, double frame_inc,
|
|||||||
}
|
}
|
||||||
MGlobal::viewFrame(frame);
|
MGlobal::viewFrame(frame);
|
||||||
|
|
||||||
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
|
for (i = 0; i < num_nodes; i++) {
|
||||||
JointAnim *joint_anim = (*ti).second;
|
MayaNodeDesc *node_desc = _tree.get_node(i);
|
||||||
get_joint_transform(joint_anim->_dag_path, tgroup);
|
if (node_desc->is_joint()) {
|
||||||
joint_anim->_anim->add_data(tgroup->get_transform());
|
get_joint_transform(node_desc->get_dag_path(), tgroup);
|
||||||
|
_tree.get_egg_anim(node_desc)->add_data(tgroup->get_transform());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
frame += frame_inc;
|
frame += frame_inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now optimize all of the tables we just filled up, for no real
|
||||||
|
// good reason.
|
||||||
|
for (i = 0; i < num_nodes; i++) {
|
||||||
|
MayaNodeDesc *node_desc = _tree.get_node(i);
|
||||||
|
if (node_desc->is_joint()) {
|
||||||
|
_tree.get_egg_anim(node_desc)->optimize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mayaegg_cat.info(false)
|
mayaegg_cat.info(false)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
// Finally, clean up by deleting all of the JointAnim structures we
|
return true;
|
||||||
// created.
|
|
||||||
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
|
|
||||||
JointAnim *joint_anim = (*ti).second;
|
|
||||||
delete joint_anim;
|
|
||||||
}
|
|
||||||
_tables.clear();
|
|
||||||
|
|
||||||
return all_ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaToEggConverter::convert_hierarchy
|
// Function: MayaToEggConverter::convert_hierarchy
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Walks the entire Maya hierarchy, converting it to a
|
// Description: Generates egg structures for each node in the Maya
|
||||||
// corresponding egg hierarchy under the indicated root
|
// hierarchy.
|
||||||
// node.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool MayaToEggConverter::
|
bool MayaToEggConverter::
|
||||||
convert_hierarchy(EggGroupNode *egg_root) {
|
convert_hierarchy(EggGroupNode *egg_root) {
|
||||||
MStatus status;
|
int num_nodes = _tree.get_num_nodes();
|
||||||
|
|
||||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
_tree.clear_egg(&get_egg_data(), egg_root, NULL);
|
||||||
if (!status) {
|
for (int i = 0; i < num_nodes; i++) {
|
||||||
status.perror("MItDag constructor");
|
if (!process_model_node(_tree.get_node(i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_from_selection) {
|
|
||||||
// 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;
|
return true;
|
||||||
// otherwise, get the whole scene anyway.
|
|
||||||
if (!selection.isEmpty()) {
|
|
||||||
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 {
|
|
||||||
if (!process_model_node(dag_path, egg_root)) {
|
|
||||||
all_ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dag_iterator.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return all_ok;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mayaegg_cat.info()
|
|
||||||
<< "Selection list is empty.\n";
|
|
||||||
// Fall through.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the entire Maya scene.
|
|
||||||
|
|
||||||
// This while loop walks through the entire Maya hierarchy, one
|
|
||||||
// node at a time. Maya's MItDag object automatically performs a
|
|
||||||
// depth-first traversal of its scene graph.
|
|
||||||
|
|
||||||
bool all_ok = true;
|
|
||||||
while (!dag_iterator.isDone()) {
|
|
||||||
MDagPath dag_path;
|
|
||||||
status = dag_iterator.getPath(dag_path);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MItDag::getPath");
|
|
||||||
} else {
|
|
||||||
if (!process_model_node(dag_path, egg_root)) {
|
|
||||||
all_ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dag_iterator.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return all_ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -580,7 +496,14 @@ convert_hierarchy(EggGroupNode *egg_root) {
|
|||||||
// successful, false if an error was encountered.
|
// successful, false if an error was encountered.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool MayaToEggConverter::
|
bool MayaToEggConverter::
|
||||||
process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
process_model_node(MayaNodeDesc *node_desc) {
|
||||||
|
if (!node_desc->has_dag_path()) {
|
||||||
|
// If the node has no Maya equivalent, never mind.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDagPath dag_path = node_desc->get_dag_path();
|
||||||
|
|
||||||
MStatus status;
|
MStatus status;
|
||||||
MFnDagNode dag_node(dag_path, &status);
|
MFnDagNode dag_node(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -588,9 +511,11 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string path = dag_path.fullPathName().asChar();
|
||||||
|
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< dag_path.fullPathName().asChar() << ": " << dag_node.typeName();
|
<< path << ": " << dag_node.typeName();
|
||||||
|
|
||||||
if (MAnimUtil::isAnimated(dag_path)) {
|
if (MAnimUtil::isAnimated(dag_path)) {
|
||||||
mayaegg_cat.debug(false)
|
mayaegg_cat.debug(false)
|
||||||
@ -600,70 +525,54 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
mayaegg_cat.debug(false) << "\n";
|
mayaegg_cat.debug(false) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dag_node.inUnderWorld()) {
|
if (node_desc->is_joint()) {
|
||||||
|
// Don't bother with joints unless we're getting an animatable
|
||||||
|
// model.
|
||||||
|
if (_animation_convert == AC_model) {
|
||||||
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
get_joint_transform(dag_path, egg_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (dag_node.inUnderWorld()) {
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< "Ignoring underworld node " << dag_path.fullPathName().asChar()
|
<< "Ignoring underworld node " << path
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_node.isIntermediateObject()) {
|
} else if (dag_node.isIntermediateObject()) {
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< "Ignoring intermediate object " << dag_path.fullPathName().asChar()
|
<< "Ignoring intermediate object " << path
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kCamera)) {
|
} else if (dag_path.hasFn(MFn::kCamera)) {
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< "Ignoring camera node " << dag_path.fullPathName().asChar()
|
<< "Ignoring camera node " << path
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kLight)) {
|
} else if (dag_path.hasFn(MFn::kLight)) {
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< "Ignoring light node " << dag_path.fullPathName().asChar()
|
<< "Ignoring light node " << path
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kJoint)) {
|
|
||||||
// A joint.
|
|
||||||
|
|
||||||
// Don't bother with joints unless we're getting an animatable
|
|
||||||
// model.
|
|
||||||
if (_animation_convert == AC_model) {
|
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
|
||||||
|
|
||||||
if (egg_group != (EggGroup *)NULL) {
|
|
||||||
egg_group->set_group_type(EggGroup::GT_joint);
|
|
||||||
get_joint_transform(dag_path, egg_group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kNurbsSurface)) {
|
} else if (dag_path.hasFn(MFn::kNurbsSurface)) {
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
|
||||||
if (egg_group == (EggGroup *)NULL) {
|
|
||||||
mayaegg_cat.error()
|
|
||||||
<< "Cannot determine group node.\n";
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (_animation_convert != AC_model) {
|
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
}
|
|
||||||
|
|
||||||
MFnNurbsSurface surface(dag_path, &status);
|
MFnNurbsSurface surface(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
mayaegg_cat.info()
|
mayaegg_cat.info()
|
||||||
<< "Error in node " << dag_path.fullPathName().asChar()
|
<< "Error in node " << path
|
||||||
<< ":\n"
|
<< ":\n"
|
||||||
<< " it appears to have a NURBS surface, but does not.\n";
|
<< " it appears to have a NURBS surface, but does not.\n";
|
||||||
} else {
|
} else {
|
||||||
make_nurbs_surface(dag_path, surface, egg_group, egg_root);
|
make_nurbs_surface(dag_path, surface, egg_group);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kNurbsCurve)) {
|
} else if (dag_path.hasFn(MFn::kNurbsCurve)) {
|
||||||
@ -671,61 +580,38 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
// Animated models, as a general rule, don't want these sorts of
|
// Animated models, as a general rule, don't want these sorts of
|
||||||
// things in them.
|
// things in them.
|
||||||
if (_animation_convert != AC_model) {
|
if (_animation_convert != AC_model) {
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
|
||||||
if (egg_group == (EggGroup *)NULL) {
|
|
||||||
mayaegg_cat.error()
|
|
||||||
<< "Cannot determine group node.\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
|
|
||||||
MFnNurbsCurve curve(dag_path, &status);
|
MFnNurbsCurve curve(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
mayaegg_cat.info()
|
mayaegg_cat.info()
|
||||||
<< "Error in node " << dag_path.fullPathName().asChar() << ":\n"
|
<< "Error in node " << path << ":\n"
|
||||||
<< " it appears to have a NURBS curve, but does not.\n";
|
<< " it appears to have a NURBS curve, but does not.\n";
|
||||||
} else {
|
} else {
|
||||||
make_nurbs_curve(dag_path, curve, egg_group, egg_root);
|
make_nurbs_curve(dag_path, curve, egg_group);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kMesh)) {
|
} else if (dag_path.hasFn(MFn::kMesh)) {
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
|
||||||
if (egg_group == (EggGroup *)NULL) {
|
|
||||||
mayaegg_cat.error()
|
|
||||||
<< "Cannot determine group node.\n";
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (_animation_convert != AC_model) {
|
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
}
|
|
||||||
|
|
||||||
MFnMesh mesh(dag_path, &status);
|
MFnMesh mesh(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
mayaegg_cat.info()
|
mayaegg_cat.info()
|
||||||
<< "Error in node " << dag_path.fullPathName().asChar() << ":\n"
|
<< "Error in node " << path << ":\n"
|
||||||
<< " it appears to have a polygon mesh, but does not.\n";
|
<< " it appears to have a polygon mesh, but does not.\n";
|
||||||
} else {
|
} else {
|
||||||
make_polyset(dag_path, mesh, egg_group, egg_root);
|
make_polyset(dag_path, mesh, egg_group);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (dag_path.hasFn(MFn::kLocator)) {
|
} else if (dag_path.hasFn(MFn::kLocator)) {
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
|
||||||
if (egg_group == (EggGroup *)NULL) {
|
|
||||||
mayaegg_cat.error()
|
|
||||||
<< "Cannot determine group node.\n";
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (mayaegg_cat.is_debug()) {
|
if (mayaegg_cat.is_debug()) {
|
||||||
mayaegg_cat.debug()
|
mayaegg_cat.debug()
|
||||||
<< "Locator at " << dag_path.fullPathName().asChar() << "\n";
|
<< "Locator at " << path << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presumably, the locator's position has some meaning to the
|
// Presumably, the locator's position has some meaning to the
|
||||||
@ -737,59 +623,15 @@ process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
// this. Perhaps there's no reason to ever change this, since
|
// this. Perhaps there's no reason to ever change this, since
|
||||||
// locators within character models may not be meaningful.
|
// locators within character models may not be meaningful.
|
||||||
egg_group->set_dcs_type(EggGroup::DC_net);
|
egg_group->set_dcs_type(EggGroup::DC_net);
|
||||||
|
}
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
}
|
make_locator(dag_path, dag_node, egg_group);
|
||||||
make_locator(dag_path, dag_node, egg_group, egg_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Get the translation/rotation/scale data
|
// Just a generic node.
|
||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = _tree.get_egg_group(node_desc);
|
||||||
|
|
||||||
if (egg_group != (EggGroup *)NULL) {
|
|
||||||
if (_animation_convert != AC_model) {
|
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaToEggConverter::process_chan_node
|
|
||||||
// Access: Private
|
|
||||||
// Description: Similar to process_model_node(), but this code path
|
|
||||||
// is followed only when we are building a table of
|
|
||||||
// animation data (AC_chan). It just builds up the
|
|
||||||
// EggTable hierarchy according to the joint table.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool MayaToEggConverter::
|
|
||||||
process_chan_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|
||||||
MStatus status;
|
|
||||||
MFnDagNode dag_node(dag_path, &status);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MFnDagNode constructor");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dag_path.hasFn(MFn::kJoint)) {
|
|
||||||
// A joint.
|
|
||||||
|
|
||||||
if (mayaegg_cat.is_debug()) {
|
|
||||||
mayaegg_cat.debug()
|
|
||||||
<< dag_path.fullPathName().asChar() << ": " << dag_node.typeName();
|
|
||||||
|
|
||||||
if (MAnimUtil::isAnimated(dag_path)) {
|
|
||||||
mayaegg_cat.debug(false)
|
|
||||||
<< " (animated)";
|
|
||||||
}
|
|
||||||
|
|
||||||
mayaegg_cat.debug(false) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
get_egg_table(dag_path, egg_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -802,6 +644,12 @@ process_chan_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaToEggConverter::
|
void MayaToEggConverter::
|
||||||
get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
|
get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
|
||||||
|
if (_animation_convert == AC_model) {
|
||||||
|
// When we're getting an animated model, we only get transforms
|
||||||
|
// for joints.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MStatus status;
|
MStatus status;
|
||||||
MObject transformNode = dag_path.transform(&status);
|
MObject transformNode = dag_path.transform(&status);
|
||||||
if (!status && status.statusCode() == MStatus::kInvalidParameter) {
|
if (!status && status.statusCode() == MStatus::kInvalidParameter) {
|
||||||
@ -959,7 +807,7 @@ get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaToEggConverter::
|
void MayaToEggConverter::
|
||||||
make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
|
make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
|
||||||
EggGroup *egg_group, EggGroupNode *egg_root) {
|
EggGroup *egg_group) {
|
||||||
MStatus status;
|
MStatus status;
|
||||||
string name = surface.name().asChar();
|
string name = surface.name().asChar();
|
||||||
|
|
||||||
@ -1015,7 +863,7 @@ make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
|
|||||||
status.perror("MFnMesh constructor");
|
status.perror("MFnMesh constructor");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
make_polyset(polyset_path, polyset_fn, egg_group, egg_root, shader);
|
make_polyset(polyset_path, polyset_fn, egg_group, shader);
|
||||||
|
|
||||||
// Now remove the polyset we created.
|
// Now remove the polyset we created.
|
||||||
MFnDagNode parent_node(polyset_parent, &status);
|
MFnDagNode parent_node(polyset_parent, &status);
|
||||||
@ -1271,7 +1119,7 @@ make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaToEggConverter::
|
void MayaToEggConverter::
|
||||||
make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
|
make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
|
||||||
EggGroup *egg_group, EggGroupNode *) {
|
EggGroup *egg_group) {
|
||||||
MStatus status;
|
MStatus status;
|
||||||
string name = curve.name().asChar();
|
string name = curve.name().asChar();
|
||||||
|
|
||||||
@ -1360,8 +1208,7 @@ make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaToEggConverter::
|
void MayaToEggConverter::
|
||||||
make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||||
EggGroup *egg_group, EggGroupNode *egg_root,
|
EggGroup *egg_group, MayaShader *default_shader) {
|
||||||
MayaShader *default_shader) {
|
|
||||||
MStatus status;
|
MStatus status;
|
||||||
string name = mesh.name().asChar();
|
string name = mesh.name().asChar();
|
||||||
|
|
||||||
@ -1556,10 +1403,10 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
MFloatArray weights;
|
MFloatArray weights;
|
||||||
if (_animation_convert == AC_model) {
|
if (_animation_convert == AC_model) {
|
||||||
got_weights =
|
got_weights =
|
||||||
get_vertex_weights(dag_path, mesh, egg_root, joints, weights);
|
get_vertex_weights(dag_path, mesh, joints, weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_weights) {
|
if (got_weights && !joints.empty()) {
|
||||||
int num_joints = joints.size();
|
int num_joints = joints.size();
|
||||||
int num_weights = (int)weights.length();
|
int num_weights = (int)weights.length();
|
||||||
int num_verts = num_weights / num_joints;
|
int num_verts = num_weights / num_joints;
|
||||||
@ -1598,7 +1445,7 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void MayaToEggConverter::
|
void MayaToEggConverter::
|
||||||
make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||||
EggGroup *egg_group, EggGroupNode *egg_root) {
|
EggGroup *egg_group) {
|
||||||
MStatus status;
|
MStatus status;
|
||||||
|
|
||||||
unsigned int num_children = dag_node.childCount();
|
unsigned int num_children = dag_node.childCount();
|
||||||
@ -1650,7 +1497,6 @@ make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool MayaToEggConverter::
|
bool MayaToEggConverter::
|
||||||
get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||||
EggGroupNode *egg_root,
|
|
||||||
pvector<EggGroup *> &joints, MFloatArray &weights) {
|
pvector<EggGroup *> &joints, MFloatArray &weights) {
|
||||||
MStatus status;
|
MStatus status;
|
||||||
|
|
||||||
@ -1696,7 +1542,8 @@ get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
joints.clear();
|
joints.clear();
|
||||||
for (unsigned oi = 0; oi < influence_objects.length(); oi++) {
|
for (unsigned oi = 0; oi < influence_objects.length(); oi++) {
|
||||||
MDagPath joint_dag_path = influence_objects[oi];
|
MDagPath joint_dag_path = influence_objects[oi];
|
||||||
EggGroup *joint = get_egg_group(joint_dag_path, egg_root);
|
MayaNodeDesc *joint_node_desc = _tree.build_node(joint_dag_path);
|
||||||
|
EggGroup *joint = _tree.get_egg_group(joint_node_desc);
|
||||||
joints.push_back(joint);
|
joints.push_back(joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1736,189 +1583,6 @@ get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaToEggConverter::get_egg_group
|
|
||||||
// Access: Private
|
|
||||||
// Description: Returns the EggGroup corresponding to the indicated
|
|
||||||
// fully-qualified Maya path name. If there is not
|
|
||||||
// already an EggGroup corresponding to this Maya path,
|
|
||||||
// creates one and returns it.
|
|
||||||
//
|
|
||||||
// In this way we generate a unique EggGroup for each
|
|
||||||
// Maya node we care about about, and also preserve the
|
|
||||||
// Maya hierarchy sensibly.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
EggGroup *MayaToEggConverter::
|
|
||||||
get_egg_group(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|
||||||
return r_get_egg_group(dag_path.fullPathName().asChar(), dag_path, egg_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaToEggConverter::r_get_egg_group
|
|
||||||
// Access: Private
|
|
||||||
// Description: The recursive implementation of get_egg_group().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
EggGroup *MayaToEggConverter::
|
|
||||||
r_get_egg_group(const string &name, const MDagPath &dag_path,
|
|
||||||
EggGroupNode *egg_root) {
|
|
||||||
// If we have already encountered this pathname, return the
|
|
||||||
// corresponding EggGroup immediately.
|
|
||||||
Groups::const_iterator gi = _groups.find(name);
|
|
||||||
if (gi != _groups.end()) {
|
|
||||||
return (*gi).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, we have to create it. Do this recursively, so we
|
|
||||||
// create each node along the path.
|
|
||||||
EggGroup *egg_group;
|
|
||||||
|
|
||||||
if (name.empty()) {
|
|
||||||
// This is the top.
|
|
||||||
egg_group = (EggGroup *)NULL;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Maya uses vertical bars to separate path components. Remove
|
|
||||||
// everything from the rightmost bar on; this will give us the
|
|
||||||
// parent's path name.
|
|
||||||
size_t bar = name.rfind("|");
|
|
||||||
string parent_name, local_name;
|
|
||||||
if (bar != string::npos) {
|
|
||||||
parent_name = name.substr(0, bar);
|
|
||||||
local_name = name.substr(bar + 1);
|
|
||||||
} else {
|
|
||||||
local_name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
EggGroup *parent_egg_group =
|
|
||||||
r_get_egg_group(parent_name, dag_path, egg_root);
|
|
||||||
egg_group = new EggGroup(local_name);
|
|
||||||
|
|
||||||
if (parent_egg_group != (EggGroup *)NULL) {
|
|
||||||
parent_egg_group->add_child(egg_group);
|
|
||||||
} else {
|
|
||||||
egg_root->add_child(egg_group);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for an object type setting, from Oliver's plug-in.
|
|
||||||
MObject dag_object = 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");
|
|
||||||
MayaEggGroupUserData *user_data = new MayaEggGroupUserData;
|
|
||||||
user_data->_vertex_color = true;
|
|
||||||
egg_group->set_user_data(user_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_groups.insert(Groups::value_type(name, egg_group));
|
|
||||||
return egg_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaToEggConverter::get_egg_table
|
|
||||||
// Access: Private
|
|
||||||
// Description: Returns the EggTable corresponding to the indicated
|
|
||||||
// fully-qualified Maya path name. This is similar to
|
|
||||||
// get_egg_group(), but this variant is used only when
|
|
||||||
// we are building a channel file, which is just a
|
|
||||||
// hierarchical collection of animation tables.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
MayaToEggConverter::JointAnim *MayaToEggConverter::
|
|
||||||
get_egg_table(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|
||||||
string name = dag_path.fullPathName().asChar();
|
|
||||||
|
|
||||||
// If we have already encountered this pathname, return the
|
|
||||||
// corresponding EggTable immediately.
|
|
||||||
Tables::const_iterator ti = _tables.find(name);
|
|
||||||
if (ti != _tables.end()) {
|
|
||||||
return (*ti).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, we have to create it.
|
|
||||||
JointAnim *joint_anim;
|
|
||||||
|
|
||||||
if (name.empty()) {
|
|
||||||
// This is the top.
|
|
||||||
joint_anim = (JointAnim *)NULL;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Maya uses vertical bars to separate path components. Remove
|
|
||||||
// everything from the rightmost bar on; this will give us the
|
|
||||||
// parent's path name.
|
|
||||||
size_t bar = name.rfind("|");
|
|
||||||
string parent_name, local_name;
|
|
||||||
if (bar != string::npos) {
|
|
||||||
parent_name = name.substr(0, bar);
|
|
||||||
local_name = name.substr(bar + 1);
|
|
||||||
} else {
|
|
||||||
local_name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look only one level up for the parent. If it hasn't been
|
|
||||||
// defined yet, don't define it; instead, just start from the
|
|
||||||
// root.
|
|
||||||
JointAnim *parent_joint_anim = NULL;
|
|
||||||
if (!parent_name.empty()) {
|
|
||||||
ti = _tables.find(parent_name);
|
|
||||||
if (ti != _tables.end()) {
|
|
||||||
parent_joint_anim = (*ti).second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
joint_anim = new JointAnim;
|
|
||||||
joint_anim->_dag_path = dag_path;
|
|
||||||
joint_anim->_table = new EggTable(local_name);
|
|
||||||
joint_anim->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
|
|
||||||
joint_anim->_table->add_child(joint_anim->_anim);
|
|
||||||
|
|
||||||
if (parent_joint_anim != (JointAnim *)NULL) {
|
|
||||||
parent_joint_anim->_table->add_child(joint_anim->_table);
|
|
||||||
} else {
|
|
||||||
egg_root->add_child(joint_anim->_table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_tables.insert(Tables::value_type(name, joint_anim));
|
|
||||||
return joint_anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaShader::set_shader_attributes
|
// Function: MayaShader::set_shader_attributes
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "pandatoolbase.h"
|
#include "pandatoolbase.h"
|
||||||
#include "somethingToEggConverter.h"
|
#include "somethingToEggConverter.h"
|
||||||
|
#include "mayaNodeTree.h"
|
||||||
|
|
||||||
#include "mayaApi.h"
|
#include "mayaApi.h"
|
||||||
#include "mayaShaders.h"
|
#include "mayaShaders.h"
|
||||||
@ -79,12 +80,13 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool convert_flip(double start_frame, double end_frame,
|
bool convert_flip(double start_frame, double end_frame,
|
||||||
double frame_inc, double output_frame_rate);
|
double frame_inc, double output_frame_rate);
|
||||||
|
|
||||||
bool convert_char_model();
|
bool convert_char_model();
|
||||||
bool convert_char_chan(double start_frame, double end_frame,
|
bool convert_char_chan(double start_frame, double end_frame,
|
||||||
double frame_inc, double output_frame_rate);
|
double frame_inc, double output_frame_rate);
|
||||||
bool convert_hierarchy(EggGroupNode *egg_root);
|
bool convert_hierarchy(EggGroupNode *egg_root);
|
||||||
bool process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root);
|
bool process_model_node(MayaNodeDesc *node_desc);
|
||||||
bool process_chan_node(const MDagPath &dag_path, EggGroupNode *egg_root);
|
|
||||||
void get_transform(const MDagPath &dag_path, EggGroup *egg_group);
|
void get_transform(const MDagPath &dag_path, EggGroup *egg_group);
|
||||||
void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group);
|
void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group);
|
||||||
|
|
||||||
@ -93,35 +95,22 @@ private:
|
|||||||
// reference.
|
// reference.
|
||||||
void make_nurbs_surface(const MDagPath &dag_path,
|
void make_nurbs_surface(const MDagPath &dag_path,
|
||||||
MFnNurbsSurface &surface,
|
MFnNurbsSurface &surface,
|
||||||
EggGroup *group, EggGroupNode *egg_root);
|
EggGroup *group);
|
||||||
EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
|
EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
|
||||||
const string &nurbs_name,
|
const string &nurbs_name,
|
||||||
EggGroupNode *egg_group,
|
EggGroupNode *egg_group,
|
||||||
int trim_curve_index);
|
int trim_curve_index);
|
||||||
void make_nurbs_curve(const MDagPath &dag_path,
|
void make_nurbs_curve(const MDagPath &dag_path,
|
||||||
const MFnNurbsCurve &curve,
|
const MFnNurbsCurve &curve,
|
||||||
EggGroup *group, EggGroupNode *egg_root);
|
EggGroup *group);
|
||||||
void make_polyset(const MDagPath &dag_path,
|
void make_polyset(const MDagPath &dag_path,
|
||||||
const MFnMesh &mesh,
|
const MFnMesh &mesh,
|
||||||
EggGroup *egg_group, EggGroupNode *egg_root,
|
EggGroup *egg_group,
|
||||||
MayaShader *default_shader = NULL);
|
MayaShader *default_shader = NULL);
|
||||||
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
|
||||||
EggGroup *egg_group, EggGroupNode *egg_root);
|
EggGroup *egg_group);
|
||||||
bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
bool get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
||||||
EggGroupNode *egg_root,
|
|
||||||
pvector<EggGroup *> &joints, MFloatArray &weights);
|
pvector<EggGroup *> &joints, MFloatArray &weights);
|
||||||
class JointAnim {
|
|
||||||
public:
|
|
||||||
MDagPath _dag_path;
|
|
||||||
EggTable *_table;
|
|
||||||
EggXfmSAnim *_anim;
|
|
||||||
};
|
|
||||||
|
|
||||||
EggGroup *get_egg_group(const MDagPath &dag_path, EggGroupNode *egg_root);
|
|
||||||
EggGroup *r_get_egg_group(const string &name, const MDagPath &dag_path,
|
|
||||||
EggGroupNode *egg_root);
|
|
||||||
JointAnim *get_egg_table(const MDagPath &dag_path, EggGroupNode *egg_root);
|
|
||||||
JointAnim *get_egg_table(const string &name, EggGroupNode *egg_root);
|
|
||||||
void set_shader_attributes(EggPrimitive &primitive,
|
void set_shader_attributes(EggPrimitive &primitive,
|
||||||
const MayaShader &shader);
|
const MayaShader &shader);
|
||||||
void apply_texture_properties(EggTexture &tex,
|
void apply_texture_properties(EggTexture &tex,
|
||||||
@ -131,15 +120,11 @@ private:
|
|||||||
|
|
||||||
bool reparent_decals(EggGroupNode *egg_parent);
|
bool reparent_decals(EggGroupNode *egg_parent);
|
||||||
|
|
||||||
typedef pmap<string, EggGroup *> Groups;
|
|
||||||
Groups _groups;
|
|
||||||
|
|
||||||
typedef pmap<string, JointAnim *> Tables;
|
|
||||||
Tables _tables;
|
|
||||||
|
|
||||||
string _program_name;
|
string _program_name;
|
||||||
bool _from_selection;
|
bool _from_selection;
|
||||||
|
|
||||||
|
MayaNodeTree _tree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MayaShaders _shaders;
|
MayaShaders _shaders;
|
||||||
EggTextureCollection _textures;
|
EggTextureCollection _textures;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user