mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
maya animation
This commit is contained in:
parent
4579327cbe
commit
c07ff46206
@ -45,6 +45,9 @@ format_animation_convert(AnimationConvert convert) {
|
|||||||
|
|
||||||
case AC_chan:
|
case AC_chan:
|
||||||
return "chan";
|
return "chan";
|
||||||
|
|
||||||
|
case AC_both:
|
||||||
|
return "both";
|
||||||
}
|
}
|
||||||
nout << "**unexpected AnimationConvert value: (" << (int)convert << ")**";
|
nout << "**unexpected AnimationConvert value: (" << (int)convert << ")**";
|
||||||
return "**";
|
return "**";
|
||||||
@ -82,6 +85,9 @@ string_animation_convert(const string &str) {
|
|||||||
} else if (cmp_nocase(str, "chan") == 0) {
|
} else if (cmp_nocase(str, "chan") == 0) {
|
||||||
return AC_chan;
|
return AC_chan;
|
||||||
|
|
||||||
|
} else if (cmp_nocase(str, "both") == 0) {
|
||||||
|
return AC_both;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return AC_invalid;
|
return AC_invalid;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ enum AnimationConvert {
|
|||||||
AC_flip, // A flip (sequence) of static geometry models.
|
AC_flip, // A flip (sequence) of static geometry models.
|
||||||
AC_model, // A character model, with joints.
|
AC_model, // A character model, with joints.
|
||||||
AC_chan, // Animation tables for the above model.
|
AC_chan, // Animation tables for the above model.
|
||||||
|
AC_both, // A character model and tables in the same file.
|
||||||
};
|
};
|
||||||
|
|
||||||
string format_animation_convert(AnimationConvert unit);
|
string format_animation_convert(AnimationConvert unit);
|
||||||
|
@ -274,6 +274,55 @@ clear_frame_inc() {
|
|||||||
_control_flags &= ~CF_frame_inc;
|
_control_flags &= ~CF_frame_inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SomethingToEggConverter::set_neutral_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Specifies the frame of animation to represent the
|
||||||
|
// neutral pose of the model.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void SomethingToEggConverter::
|
||||||
|
set_neutral_frame(double neutral_frame) {
|
||||||
|
_neutral_frame = neutral_frame;
|
||||||
|
_control_flags |= CF_neutral_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SomethingToEggConverter::has_neutral_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the neutral frame has been
|
||||||
|
// explicitly specified via set_neutral_frame(), or
|
||||||
|
// false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool SomethingToEggConverter::
|
||||||
|
has_neutral_frame() const {
|
||||||
|
return (_control_flags & CF_neutral_frame) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SomethingToEggConverter::get_neutral_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the value set by a previous call to
|
||||||
|
// set_neutral_frame(). It is an error to call this if
|
||||||
|
// has_neutral_frame() returns false.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE double SomethingToEggConverter::
|
||||||
|
get_neutral_frame() const {
|
||||||
|
nassertr(has_neutral_frame(), 0.0);
|
||||||
|
return _neutral_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SomethingToEggConverter::clear_neutral_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Removes the value previously set by
|
||||||
|
// set_neutral_frame().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void SomethingToEggConverter::
|
||||||
|
clear_neutral_frame() {
|
||||||
|
_neutral_frame = 0.0;
|
||||||
|
_control_flags &= ~CF_neutral_frame;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: SomethingToEggConverter::set_input_frame_rate
|
// Function: SomethingToEggConverter::set_input_frame_rate
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -35,6 +35,7 @@ SomethingToEggConverter() {
|
|||||||
_start_frame = 0.0;
|
_start_frame = 0.0;
|
||||||
_end_frame = 0.0;
|
_end_frame = 0.0;
|
||||||
_frame_inc = 0.0;
|
_frame_inc = 0.0;
|
||||||
|
_neutral_frame = 0.0;
|
||||||
_input_frame_rate = 0.0;
|
_input_frame_rate = 0.0;
|
||||||
_output_frame_rate = 0.0;
|
_output_frame_rate = 0.0;
|
||||||
_control_flags = 0;
|
_control_flags = 0;
|
||||||
|
@ -80,6 +80,11 @@ public:
|
|||||||
INLINE double get_frame_inc() const;
|
INLINE double get_frame_inc() const;
|
||||||
INLINE void clear_frame_inc();
|
INLINE void clear_frame_inc();
|
||||||
|
|
||||||
|
INLINE void set_neutral_frame(double neutral_frame);
|
||||||
|
INLINE bool has_neutral_frame() const;
|
||||||
|
INLINE double get_neutral_frame() const;
|
||||||
|
INLINE void clear_neutral_frame();
|
||||||
|
|
||||||
INLINE void set_input_frame_rate(double input_frame_rate);
|
INLINE void set_input_frame_rate(double input_frame_rate);
|
||||||
INLINE bool has_input_frame_rate() const;
|
INLINE bool has_input_frame_rate() const;
|
||||||
INLINE double get_input_frame_rate() const;
|
INLINE double get_input_frame_rate() const;
|
||||||
@ -139,14 +144,16 @@ protected:
|
|||||||
double _start_frame;
|
double _start_frame;
|
||||||
double _end_frame;
|
double _end_frame;
|
||||||
double _frame_inc;
|
double _frame_inc;
|
||||||
|
double _neutral_frame;
|
||||||
double _input_frame_rate; // frames per second
|
double _input_frame_rate; // frames per second
|
||||||
double _output_frame_rate; // frames per second
|
double _output_frame_rate; // frames per second
|
||||||
enum ControlFlags {
|
enum ControlFlags {
|
||||||
CF_start_frame = 0x0001,
|
CF_start_frame = 0x0001,
|
||||||
CF_end_frame = 0x0002,
|
CF_end_frame = 0x0002,
|
||||||
CF_frame_inc = 0x0004,
|
CF_frame_inc = 0x0004,
|
||||||
CF_input_frame_rate = 0x0008,
|
CF_neutral_frame = 0x0008,
|
||||||
CF_output_frame_rate = 0x0010,
|
CF_input_frame_rate = 0x0010,
|
||||||
|
CF_output_frame_rate = 0x0020,
|
||||||
};
|
};
|
||||||
int _control_flags;
|
int _control_flags;
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ SomethingToEgg(const string &format_name,
|
|||||||
_got_start_frame = false;
|
_got_start_frame = false;
|
||||||
_got_end_frame = false;
|
_got_end_frame = false;
|
||||||
_got_frame_inc = false;
|
_got_frame_inc = false;
|
||||||
|
_got_neutral_frame = false;
|
||||||
_got_input_frame_rate = false;
|
_got_input_frame_rate = false;
|
||||||
_got_output_frame_rate = false;
|
_got_output_frame_rate = false;
|
||||||
_texture_path_convert = SomethingToEggConverter::PC_unchanged;
|
_texture_path_convert = SomethingToEggConverter::PC_unchanged;
|
||||||
@ -107,7 +108,8 @@ add_animation_options() {
|
|||||||
("a", "animation-mode", 40,
|
("a", "animation-mode", 40,
|
||||||
"Specifies how animation from the " + _format_name + " file is "
|
"Specifies how animation from the " + _format_name + " file is "
|
||||||
"converted to egg, if at all. At present, the following keywords "
|
"converted to egg, if at all. At present, the following keywords "
|
||||||
"are supported: none, pose, or flip.",
|
"are supported: none, pose, flip, model, chan, or both. The default "
|
||||||
|
"is none, which means not to convert animation.",
|
||||||
&SomethingToEgg::dispatch_animation_convert, NULL, &_animation_convert);
|
&SomethingToEgg::dispatch_animation_convert, NULL, &_animation_convert);
|
||||||
|
|
||||||
add_option
|
add_option
|
||||||
@ -120,7 +122,8 @@ add_animation_options() {
|
|||||||
add_option
|
add_option
|
||||||
("sf", "start-frame", 40,
|
("sf", "start-frame", 40,
|
||||||
"Specifies the starting frame of animation to extract. If omitted, "
|
"Specifies the starting frame of animation to extract. If omitted, "
|
||||||
"the first frame of the time slider will be used.",
|
"the first frame of the time slider will be used. For -a pose, this "
|
||||||
|
"is the one frame of animation to extract.",
|
||||||
&SomethingToEgg::dispatch_double, &_got_start_frame, &_start_frame);
|
&SomethingToEgg::dispatch_double, &_got_start_frame, &_start_frame);
|
||||||
|
|
||||||
add_option
|
add_option
|
||||||
@ -136,6 +139,14 @@ add_animation_options() {
|
|||||||
"slider does not specify.",
|
"slider does not specify.",
|
||||||
&SomethingToEgg::dispatch_double, &_got_frame_inc, &_frame_inc);
|
&SomethingToEgg::dispatch_double, &_got_frame_inc, &_frame_inc);
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("nf", "neutral-frame", 40,
|
||||||
|
"Specifies the frame number to use for the neutral pose. The model "
|
||||||
|
"will be set to this frame before extracting out the neutral character. "
|
||||||
|
"If omitted, the current frame of the model is used. This is only "
|
||||||
|
"relevant for -a model or -a both.",
|
||||||
|
&SomethingToEgg::dispatch_double, &_got_neutral_frame, &_neutral_frame);
|
||||||
|
|
||||||
add_option
|
add_option
|
||||||
("fri", "fps", 40,
|
("fri", "fps", 40,
|
||||||
"Specify the frame rate (frames per second) of the input " + _format_name +
|
"Specify the frame rate (frames per second) of the input " + _format_name +
|
||||||
|
@ -73,11 +73,13 @@ protected:
|
|||||||
double _start_frame;
|
double _start_frame;
|
||||||
double _end_frame;
|
double _end_frame;
|
||||||
double _frame_inc;
|
double _frame_inc;
|
||||||
|
double _neutral_frame;
|
||||||
double _input_frame_rate;
|
double _input_frame_rate;
|
||||||
double _output_frame_rate;
|
double _output_frame_rate;
|
||||||
bool _got_start_frame;
|
bool _got_start_frame;
|
||||||
bool _got_end_frame;
|
bool _got_end_frame;
|
||||||
bool _got_frame_inc;
|
bool _got_frame_inc;
|
||||||
|
bool _got_neutral_frame;
|
||||||
bool _got_input_frame_rate;
|
bool _got_input_frame_rate;
|
||||||
bool _got_output_frame_rate;
|
bool _got_output_frame_rate;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "eggData.h"
|
#include "eggData.h"
|
||||||
#include "eggGroup.h"
|
#include "eggGroup.h"
|
||||||
|
#include "eggTable.h"
|
||||||
#include "eggVertex.h"
|
#include "eggVertex.h"
|
||||||
#include "eggVertexPool.h"
|
#include "eggVertexPool.h"
|
||||||
#include "eggNurbsSurface.h"
|
#include "eggNurbsSurface.h"
|
||||||
@ -31,6 +32,7 @@
|
|||||||
#include "eggPrimitive.h"
|
#include "eggPrimitive.h"
|
||||||
#include "eggTexture.h"
|
#include "eggTexture.h"
|
||||||
#include "eggTextureCollection.h"
|
#include "eggTextureCollection.h"
|
||||||
|
#include "eggXfmSAnim.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
|
||||||
#include "pre_maya_include.h"
|
#include "pre_maya_include.h"
|
||||||
@ -180,6 +182,7 @@ convert_maya() {
|
|||||||
_textures.clear();
|
_textures.clear();
|
||||||
_shaders.clear();
|
_shaders.clear();
|
||||||
_groups.clear();
|
_groups.clear();
|
||||||
|
_tables.clear();
|
||||||
|
|
||||||
if (!open_api()) {
|
if (!open_api()) {
|
||||||
mayaegg_cat.error()
|
mayaegg_cat.error()
|
||||||
@ -228,7 +231,8 @@ convert_maya() {
|
|||||||
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.
|
||||||
nout << "frame " << start_frame << "\n";
|
mayaegg_cat.info(false)
|
||||||
|
<< "frame " << start_frame << "\n";
|
||||||
MGlobal::viewFrame(MTime(start_frame, MTime::uiUnit()));
|
MGlobal::viewFrame(MTime(start_frame, MTime::uiUnit()));
|
||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
@ -237,17 +241,36 @@ convert_maya() {
|
|||||||
all_ok = convert_hierarchy(&get_egg_data());
|
all_ok = convert_hierarchy(&get_egg_data());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AC_flip:
|
||||||
|
// flip: get out a series of static models, one per frame, under a
|
||||||
|
// sequence node.
|
||||||
|
all_ok = convert_flip(start_frame, end_frame, frame_inc,
|
||||||
|
output_frame_rate);
|
||||||
|
break;
|
||||||
|
|
||||||
case AC_model:
|
case AC_model:
|
||||||
// model: get out an animatable model with joints and vertex
|
// model: get out an animatable model with joints and vertex
|
||||||
// membership.
|
// membership.
|
||||||
all_ok = convert_char_model();
|
all_ok = convert_char_model();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_flip:
|
case AC_chan:
|
||||||
// flip: get out a series of static models, one per frame, under a
|
// chan: get out a series of animation tables.
|
||||||
// sequence node.
|
all_ok = convert_char_chan(start_frame, end_frame, frame_inc,
|
||||||
all_ok = convert_flip(start_frame, end_frame, frame_inc,
|
output_frame_rate);
|
||||||
output_frame_rate);
|
break;
|
||||||
|
|
||||||
|
case AC_both:
|
||||||
|
// both: Put a model and its animation into the same egg file.
|
||||||
|
_animation_convert = AC_model;
|
||||||
|
if (!convert_char_model()) {
|
||||||
|
all_ok = false;
|
||||||
|
}
|
||||||
|
_animation_convert = AC_chan;
|
||||||
|
if (!convert_char_chan(start_frame, end_frame, frame_inc,
|
||||||
|
output_frame_rate)) {
|
||||||
|
all_ok = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,21 +314,6 @@ close_api() {
|
|||||||
_maya.clear();
|
_maya.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: MayaToEggConverter::convert_char_model
|
|
||||||
// Access: Private
|
|
||||||
// Description: Converts the animation as an animatable character
|
|
||||||
// model, with joints and vertex membership.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool MayaToEggConverter::
|
|
||||||
convert_char_model() {
|
|
||||||
EggGroup *char_node = new EggGroup(_character_name);
|
|
||||||
get_egg_data().add_child(char_node);
|
|
||||||
char_node->set_dart_type(EggGroup::DT_default);
|
|
||||||
|
|
||||||
return convert_hierarchy(char_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaToEggConverter::convert_flip
|
// Function: MayaToEggConverter::convert_flip
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -330,7 +338,8 @@ convert_flip(double start_frame, double end_frame, double frame_inc,
|
|||||||
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) {
|
||||||
nout << "frame " << frame.value() << "\n";
|
mayaegg_cat.info(false)
|
||||||
|
<< "frame " << frame.value() << "\n";
|
||||||
ostringstream name_strm;
|
ostringstream name_strm;
|
||||||
name_strm << "frame" << frame.value();
|
name_strm << "frame" << frame.value();
|
||||||
EggGroup *frame_root = new EggGroup(name_strm.str());
|
EggGroup *frame_root = new EggGroup(name_strm.str());
|
||||||
@ -348,6 +357,123 @@ convert_flip(double start_frame, double end_frame, double frame_inc,
|
|||||||
return all_ok;
|
return all_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaToEggConverter::convert_char_model
|
||||||
|
// Access: Private
|
||||||
|
// Description: Converts the file as an animatable character
|
||||||
|
// model, with joints and vertex membership.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaToEggConverter::
|
||||||
|
convert_char_model() {
|
||||||
|
if (has_neutral_frame()) {
|
||||||
|
MTime frame(get_neutral_frame(), MTime::uiUnit());
|
||||||
|
mayaegg_cat.info(false)
|
||||||
|
<< "neutral frame " << frame.value() << "\n";
|
||||||
|
MGlobal::viewFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
EggGroup *char_node = new EggGroup(_character_name);
|
||||||
|
get_egg_data().add_child(char_node);
|
||||||
|
char_node->set_dart_type(EggGroup::DT_default);
|
||||||
|
|
||||||
|
return convert_hierarchy(char_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: MayaToEggConverter::convert_char_chan
|
||||||
|
// Access: Private
|
||||||
|
// Description: Converts the animation as a series of tables to apply
|
||||||
|
// to the character model, as retrieved earlier via
|
||||||
|
// AC_model.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool MayaToEggConverter::
|
||||||
|
convert_char_chan(double start_frame, double end_frame, double frame_inc,
|
||||||
|
double output_frame_rate) {
|
||||||
|
MStatus status;
|
||||||
|
|
||||||
|
EggTable *root_table_node = new EggTable();
|
||||||
|
get_egg_data().add_child(root_table_node);
|
||||||
|
EggTable *bundle_node = new EggTable(_character_name);
|
||||||
|
bundle_node->set_table_type(EggTable::TT_bundle);
|
||||||
|
root_table_node->add_child(bundle_node);
|
||||||
|
EggTable *skeleton_node = new EggTable("<skeleton>");
|
||||||
|
bundle_node->add_child(skeleton_node);
|
||||||
|
|
||||||
|
// First, walk through the scene graph and build up the table of
|
||||||
|
// joints.
|
||||||
|
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
||||||
|
if (!status) {
|
||||||
|
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
|
||||||
|
// frames, one at a time, and getting the joint angles at each
|
||||||
|
// frame.
|
||||||
|
|
||||||
|
// This is just a temporary EggGroup to receive the transform for
|
||||||
|
// each joint each frame.
|
||||||
|
PT(EggGroup) tgroup = new EggGroup;
|
||||||
|
|
||||||
|
MTime frame(start_frame, MTime::uiUnit());
|
||||||
|
MTime frame_stop(end_frame, MTime::uiUnit());
|
||||||
|
while (frame <= frame_stop) {
|
||||||
|
if (mayaegg_cat.is_debug()) {
|
||||||
|
mayaegg_cat.debug(false)
|
||||||
|
<< "frame " << frame.value() << "\n";
|
||||||
|
} else {
|
||||||
|
mayaegg_cat.info(false)
|
||||||
|
<< ".";
|
||||||
|
}
|
||||||
|
MGlobal::viewFrame(frame);
|
||||||
|
|
||||||
|
for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
|
||||||
|
JointAnim *joint_anim = (*ti).second;
|
||||||
|
get_transform(joint_anim->_dag_path, tgroup);
|
||||||
|
joint_anim->_anim->add_data(tgroup->get_transform());
|
||||||
|
}
|
||||||
|
|
||||||
|
frame += frame_inc;
|
||||||
|
}
|
||||||
|
mayaegg_cat.info(false)
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
// Finally, clean up by deleting all of the JointAnim structures we
|
||||||
|
// 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
|
||||||
@ -376,7 +502,7 @@ convert_hierarchy(EggGroupNode *egg_root) {
|
|||||||
if (!status) {
|
if (!status) {
|
||||||
status.perror("MItDag::getPath");
|
status.perror("MItDag::getPath");
|
||||||
} else {
|
} else {
|
||||||
if (!process_node(dag_path, egg_root)) {
|
if (!process_model_node(dag_path, egg_root)) {
|
||||||
all_ok = false;
|
all_ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,7 +514,7 @@ convert_hierarchy(EggGroupNode *egg_root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaToEggConverter::process_node
|
// Function: MayaToEggConverter::process_model_node
|
||||||
// Access: Private
|
// Access: Private
|
||||||
// Description: Converts the indicated Maya node (given a MDagPath,
|
// Description: Converts the indicated Maya node (given a MDagPath,
|
||||||
// similar in concept to Panda's NodePath) to the
|
// similar in concept to Panda's NodePath) to the
|
||||||
@ -396,7 +522,7 @@ convert_hierarchy(EggGroupNode *egg_root) {
|
|||||||
// successful, false if an error was encountered.
|
// successful, false if an error was encountered.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool MayaToEggConverter::
|
bool MayaToEggConverter::
|
||||||
process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
||||||
MStatus status;
|
MStatus status;
|
||||||
MFnDagNode dag_node(dag_path, &status);
|
MFnDagNode dag_node(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -451,7 +577,9 @@ process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
get_transform(dag_path, egg_group);
|
if (_animation_convert != AC_model) {
|
||||||
|
get_transform(dag_path, egg_group);
|
||||||
|
}
|
||||||
|
|
||||||
MFnNurbsSurface surface(dag_path, &status);
|
MFnNurbsSurface surface(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -471,7 +599,8 @@ process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
||||||
|
|
||||||
if (egg_group == (EggGroup *)NULL) {
|
if (egg_group == (EggGroup *)NULL) {
|
||||||
nout << "Cannot determine group node.\n";
|
mayaegg_cat.error()
|
||||||
|
<< "Cannot determine group node.\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
get_transform(dag_path, egg_group);
|
get_transform(dag_path, egg_group);
|
||||||
@ -496,7 +625,9 @@ process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
get_transform(dag_path, egg_group);
|
if (_animation_convert != AC_model) {
|
||||||
|
get_transform(dag_path, egg_group);
|
||||||
|
}
|
||||||
|
|
||||||
MFnMesh mesh(dag_path, &status);
|
MFnMesh mesh(dag_path, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -513,13 +644,53 @@ process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
|
|||||||
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
EggGroup *egg_group = get_egg_group(dag_path, egg_root);
|
||||||
|
|
||||||
if (egg_group != (EggGroup *)NULL) {
|
if (egg_group != (EggGroup *)NULL) {
|
||||||
get_transform(dag_path, egg_group);
|
if (_animation_convert != AC_model) {
|
||||||
|
get_transform(dag_path, egg_group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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() << ": " << 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;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: MayaToEggConverter::get_transform
|
// Function: MayaToEggConverter::get_transform
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -762,7 +933,8 @@ make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
|
|||||||
if (segment.hasFn(MFn::kNurbsCurve)) {
|
if (segment.hasFn(MFn::kNurbsCurve)) {
|
||||||
MFnNurbsCurve curve(segment, &status);
|
MFnNurbsCurve curve(segment, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
nout << "Trim curve appears to be a nurbs curve, but isn't.\n";
|
mayaegg_cat.error()
|
||||||
|
<< "Trim curve appears to be a nurbs curve, but isn't.\n";
|
||||||
} else {
|
} else {
|
||||||
// Finally, we have a valid curve!
|
// Finally, we have a valid curve!
|
||||||
EggNurbsCurve *egg_curve =
|
EggNurbsCurve *egg_curve =
|
||||||
@ -773,7 +945,8 @@ make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nout << "Trim curve segment is not a nurbs curve.\n";
|
mayaegg_cat.error()
|
||||||
|
<< "Trim curve segment is not a nurbs curve.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1199,7 +1372,7 @@ get_vertex_weights(const MDagPath &dag_path, const MFnMesh &mesh,
|
|||||||
status.perror("MFnSkinCluster::getWeights");
|
status.perror("MFnSkinCluster::getWeights");
|
||||||
} else {
|
} else {
|
||||||
if (influence_count != influence_objects.length()) {
|
if (influence_count != influence_objects.length()) {
|
||||||
maya_cat.error()
|
mayaegg_cat.error()
|
||||||
<< "MFnSkinCluster::influenceObjects() returns "
|
<< "MFnSkinCluster::influenceObjects() returns "
|
||||||
<< influence_objects.length()
|
<< influence_objects.length()
|
||||||
<< " objects, but MFnSkinCluster::getWeights() reports "
|
<< " objects, but MFnSkinCluster::getWeights() reports "
|
||||||
@ -1289,6 +1462,74 @@ get_egg_group(const string &name, EggGroupNode *egg_root) {
|
|||||||
return 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: Public
|
// Access: Public
|
||||||
|
@ -28,11 +28,17 @@
|
|||||||
#include "distanceUnit.h"
|
#include "distanceUnit.h"
|
||||||
#include "coordinateSystem.h"
|
#include "coordinateSystem.h"
|
||||||
|
|
||||||
|
#include "pre_maya_include.h"
|
||||||
|
#include <maya/MDagPath.h>
|
||||||
|
#include "post_maya_include.h"
|
||||||
|
|
||||||
class EggData;
|
class EggData;
|
||||||
class EggGroup;
|
class EggGroup;
|
||||||
|
class EggTable;
|
||||||
class EggVertexPool;
|
class EggVertexPool;
|
||||||
class EggNurbsCurve;
|
class EggNurbsCurve;
|
||||||
class EggPrimitive;
|
class EggPrimitive;
|
||||||
|
class EggXfmSAnim;
|
||||||
|
|
||||||
class MDagPath;
|
class MDagPath;
|
||||||
class MFnNurbsSurface;
|
class MFnNurbsSurface;
|
||||||
@ -69,11 +75,14 @@ public:
|
|||||||
void close_api();
|
void close_api();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool convert_flip(double start_frame, double end_frame,
|
||||||
|
double frame_inc, double output_frame_rate);
|
||||||
bool convert_char_model();
|
bool convert_char_model();
|
||||||
bool convert_flip(double start_frame, double end_frame, double frame_inc,
|
bool convert_char_chan(double start_frame, double end_frame,
|
||||||
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_node(const MDagPath &dag_path, EggGroupNode *egg_root);
|
bool process_model_node(const MDagPath &dag_path, EggGroupNode *egg_root);
|
||||||
|
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);
|
||||||
|
|
||||||
// I ran into core dumps trying to pass around a MFnMesh object by
|
// I ran into core dumps trying to pass around a MFnMesh object by
|
||||||
@ -96,15 +105,26 @@ private:
|
|||||||
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,
|
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 *get_egg_group(const MDagPath &dag_path, EggGroupNode *egg_root);
|
||||||
EggGroup *get_egg_group(const string &name, EggGroupNode *egg_root);
|
EggGroup *get_egg_group(const string &name, 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);
|
||||||
|
|
||||||
typedef pmap<string, EggGroup *> Groups;
|
typedef pmap<string, EggGroup *> Groups;
|
||||||
Groups _groups;
|
Groups _groups;
|
||||||
|
|
||||||
|
typedef pmap<string, JointAnim *> Tables;
|
||||||
|
Tables _tables;
|
||||||
|
|
||||||
string _program_name;
|
string _program_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -110,6 +110,9 @@ run() {
|
|||||||
if (_got_frame_inc) {
|
if (_got_frame_inc) {
|
||||||
converter.set_frame_inc(_frame_inc);
|
converter.set_frame_inc(_frame_inc);
|
||||||
}
|
}
|
||||||
|
if (_got_neutral_frame) {
|
||||||
|
converter.set_neutral_frame(_neutral_frame);
|
||||||
|
}
|
||||||
if (_got_input_frame_rate) {
|
if (_got_input_frame_rate) {
|
||||||
converter.set_input_frame_rate(_input_frame_rate);
|
converter.set_input_frame_rate(_input_frame_rate);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user