beginning animation stuff in maya

This commit is contained in:
David Rose 2003-01-21 23:26:29 +00:00
parent 3496d7fedc
commit 41828cfea9
12 changed files with 716 additions and 40 deletions

View File

@ -8,11 +8,13 @@
m
#define SOURCES \
animationConvert.cxx animationConvert.h \
distanceUnit.cxx distanceUnit.h \
somethingToEggConverter.I somethingToEggConverter.cxx \
somethingToEggConverter.h
#define INSTALL_HEADERS \
animationConvert.h \
distanceUnit.h \
somethingToEggConverter.I somethingToEggConverter.h

View File

@ -0,0 +1,70 @@
// Filename: animationConvert.cxx
// Created by: drose (21Jan03)
//
////////////////////////////////////////////////////////////////////
//
// 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 "animationConvert.h"
#include "string_utils.h"
#include "notify.h"
////////////////////////////////////////////////////////////////////
// Function: format_animation_convert
// Description: Returns the string corresponding to this method.
////////////////////////////////////////////////////////////////////
string
format_animation_convert(AnimationConvert convert) {
switch (convert) {
case AC_invalid:
return "invalid";
case AC_none:
return "none";
case AC_flip:
return "flip";
}
nout << "**unexpected AnimationConvert value: (" << (int)convert << ")**";
return "**";
}
////////////////////////////////////////////////////////////////////
// Function: AnimationConvert output operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &
operator << (ostream &out, AnimationConvert convert) {
return out << format_animation_convert(convert);
}
////////////////////////////////////////////////////////////////////
// Function: string_animation_convert
// Description: Converts from a string, as might be input by the
// user, to one of the known AnimationConvert types.
// Returns AC_invalid if the string is unknown.
////////////////////////////////////////////////////////////////////
AnimationConvert
string_animation_convert(const string &str) {
if (cmp_nocase(str, "none") == 0) {
return AC_none;
} else if (cmp_nocase(str, "flip") == 0) {
return AC_flip;
} else {
return AC_invalid;
}
}

View File

@ -0,0 +1,41 @@
// Filename: animationConvert.h
// Created by: drose (21Jan03)
//
////////////////////////////////////////////////////////////////////
//
// 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 ANIMATIONCONVERT_H
#define ANIMATIONCONVERT_H
#include "pandatoolbase.h"
////////////////////////////////////////////////////////////////////
// Enum : AnimationConvert
// Description : This enumerated type lists the methods by which
// animation from an animation package might be
// represented in egg format.
////////////////////////////////////////////////////////////////////
enum AnimationConvert {
AC_invalid,
AC_none,
AC_flip,
};
string format_animation_convert(AnimationConvert unit);
ostream &operator << (ostream &out, AnimationConvert unit);
AnimationConvert string_animation_convert(const string &str);
#endif

View File

@ -65,6 +65,309 @@ set_model_path_convert(PathConvert mpc,
_mpc_directory = mpc_directory;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_animation_convert
// Access: Public
// Description: Specifies how source animation will be converted into
// egg structures. The default is AC_none, which means
// animation tables will be ignored. This is only
// meaningful for converters that understand animation.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_animation_convert(AnimationConvert animation_convert) {
_animation_convert = animation_convert;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_animation_convert
// Access: Public
// Description: Returns how source animation will be converted into
// egg structures.
////////////////////////////////////////////////////////////////////
INLINE AnimationConvert SomethingToEggConverter::
get_animation_convert() const {
return _animation_convert;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_start_frame
// Access: Public
// Description: Specifies the starting frame of the animation to
// convert, in the units specified by
// set_input_frame_rate(). If this is unspecified, the
// starting frame is taken from the source, for instance
// from the first frame of the animation slider.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_start_frame(double start_frame) {
_start_frame = start_frame;
_control_flags |= CF_start_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::has_start_frame
// Access: Public
// Description: Returns true if the starting frame has been
// explicitly specified via set_start_frame(), or false
// if the starting frame should be implicit based on the
// source.
////////////////////////////////////////////////////////////////////
INLINE bool SomethingToEggConverter::
has_start_frame() const {
return (_control_flags & CF_start_frame) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_start_frame
// Access: Public
// Description: Returns the value set by a previous call to
// set_start_frame(). It is an error to call this if
// has_start_frame() returns false.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_start_frame() const {
nassertr(has_start_frame(), 0.0);
return _start_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::clear_start_frame
// Access: Public
// Description: Removes the value previously set by
// set_start_frame().
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
clear_start_frame() {
_start_frame = 0.0;
_control_flags &= ~CF_start_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_end_frame
// Access: Public
// Description: Specifies the ending frame of the animation to
// convert, in the units specified by
// set_input_frame_rate(). If this is unspecified, the
// ending frame is taken from the source, for instance
// from the last frame of the animation slider.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_end_frame(double end_frame) {
_end_frame = end_frame;
_control_flags |= CF_end_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::has_end_frame
// Access: Public
// Description: Returns true if the ending frame has been
// explicitly specified via set_end_frame(), or false
// if the ending frame should be implicit based on the
// source.
////////////////////////////////////////////////////////////////////
INLINE bool SomethingToEggConverter::
has_end_frame() const {
return (_control_flags & CF_end_frame) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_end_frame
// Access: Public
// Description: Returns the value set by a previous call to
// set_end_frame(). It is an error to call this if
// has_end_frame() returns false.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_end_frame() const {
nassertr(has_end_frame(), 0.0);
return _end_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::clear_end_frame
// Access: Public
// Description: Removes the value previously set by
// set_end_frame().
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
clear_end_frame() {
_end_frame = 0.0;
_control_flags &= ~CF_end_frame;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_frame_inc
// Access: Public
// Description: Specifies the increment between frames to extract.
// This is the amount to increment the time slider (in
// units of internal_frame_rate) between extracting each
// frame. If this is not specified, the default is
// taken from the animation package, or 1.0 if the
// animation package does not specified a frame
// increment.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_frame_inc(double frame_inc) {
_frame_inc = frame_inc;
_control_flags |= CF_frame_inc;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::has_frame_inc
// Access: Public
// Description: Returns true if the frame increment has been
// explicitly specified via set_frame_inc(), or false
// if the ending frame should be implicit based on the
// source.
////////////////////////////////////////////////////////////////////
INLINE bool SomethingToEggConverter::
has_frame_inc() const {
return (_control_flags & CF_frame_inc) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_frame_inc
// Access: Public
// Description: Returns the value set by a previous call to
// set_frame_inc(). It is an error to call this if
// has_frame_inc() returns false.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_frame_inc() const {
nassertr(has_frame_inc(), 0.0);
return _frame_inc;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::clear_frame_inc
// Access: Public
// Description: Removes the value previously set by
// set_frame_inc().
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
clear_frame_inc() {
_frame_inc = 0.0;
_control_flags &= ~CF_frame_inc;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_input_frame_rate
// Access: Public
// Description: Specifies the number of frames per second that is
// represented by the "frame" unit in the animation
// package. If this is omitted, it is taken from
// whatever the file header indicates. Some animation
// packages do not encode a frame rate, in which case
// the default if this is omitted is the same as the
// output frame rate.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_input_frame_rate(double input_frame_rate) {
_input_frame_rate = input_frame_rate;
_control_flags |= CF_input_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::has_input_frame_rate
// Access: Public
// Description: Returns true if the frame rate has been
// explicitly specified via set_input_frame_rate(), or
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SomethingToEggConverter::
has_input_frame_rate() const {
return (_control_flags & CF_input_frame_rate) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_input_frame_rate
// Access: Public
// Description: Returns the value set by a previous call to
// set_input_frame_rate(). It is an error to call this
// if has_input_frame_rate() returns false.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_input_frame_rate() const {
nassertr(has_input_frame_rate(), 0.0);
return _input_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::clear_input_frame_rate
// Access: Public
// Description: Removes the value previously set by
// set_input_frame_rate().
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
clear_input_frame_rate() {
_input_frame_rate = 0.0;
_control_flags &= ~CF_input_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_output_frame_rate
// Access: Public
// Description: Specifies the number of frames per second that the
// resulting animation should be played at. If this is
// omitted, it is taken to be the same as the input
// frame rate.
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
set_output_frame_rate(double output_frame_rate) {
_output_frame_rate = output_frame_rate;
_control_flags |= CF_output_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::has_output_frame_rate
// Access: Public
// Description: Returns true if the frame rate has been
// explicitly specified via set_output_frame_rate(), or
// false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SomethingToEggConverter::
has_output_frame_rate() const {
return (_control_flags & CF_output_frame_rate) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_output_frame_rate
// Access: Public
// Description: Returns the value set by a previous call to
// set_output_frame_rate(). It is an error to call this
// if has_output_frame_rate() returns false.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_output_frame_rate() const {
nassertr(has_output_frame_rate(), 0.0);
return _output_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::clear_output_frame_rate
// Access: Public
// Description: Removes the value previously set by
// set_output_frame_rate().
////////////////////////////////////////////////////////////////////
INLINE void SomethingToEggConverter::
clear_output_frame_rate() {
_output_frame_rate = 0.0;
_control_flags &= ~CF_output_frame_rate;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::get_default_frame_rate
// Access: Public, Static
// Description: Returns the default frame rate if nothing is
// specified for input_frame_rate or output_frame_rate,
// and the animation package does not have an implicit
// frame rate.
////////////////////////////////////////////////////////////////////
INLINE double SomethingToEggConverter::
get_default_frame_rate() {
return 24.0;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEggConverter::set_merge_externals
// Access: Public

View File

@ -31,6 +31,13 @@ SomethingToEggConverter() {
_allow_errors = false;
_tpc = PC_absolute;
_mpc = PC_absolute;
_animation_convert = AC_none;
_start_frame = 0.0;
_end_frame = 0.0;
_frame_inc = 0.0;
_input_frame_rate = 0.0;
_output_frame_rate = 0.0;
_control_flags = 0;
_merge_externals = false;
_egg_data = (EggData *)NULL;
_owns_egg_data = false;

View File

@ -19,10 +19,11 @@
#ifndef SOMETHINGTOEGGCONVERTER_H
#define SOMETHINGTOEGGCONVERTER_H
#include <pandatoolbase.h>
#include "pandatoolbase.h"
#include <filename.h>
#include <config_util.h> // for get_texture_path() and get_model_path()
#include "filename.h"
#include "config_util.h" // for get_texture_path() and get_model_path()
#include "animationConvert.h"
class EggData;
class EggGroupNode;
@ -56,7 +57,38 @@ public:
const Filename &tpc_directory = Filename());
INLINE void set_model_path_convert(PathConvert mpc,
const Filename &mpc_directory = Filename());
// These methods dealing with animation and frame rate are only
// relevant to converter types that understand animation.
INLINE void set_animation_convert(AnimationConvert animation_convert);
INLINE AnimationConvert get_animation_convert() const;
INLINE void set_start_frame(double start_frame);
INLINE bool has_start_frame() const;
INLINE double get_start_frame() const;
INLINE void clear_start_frame();
INLINE void set_end_frame(double end_frame);
INLINE bool has_end_frame() const;
INLINE double get_end_frame() const;
INLINE void clear_end_frame();
INLINE void set_frame_inc(double frame_inc);
INLINE bool has_frame_inc() const;
INLINE double get_frame_inc() const;
INLINE void clear_frame_inc();
INLINE void set_input_frame_rate(double input_frame_rate);
INLINE bool has_input_frame_rate() const;
INLINE double get_input_frame_rate() const;
INLINE void clear_input_frame_rate();
INLINE void set_output_frame_rate(double output_frame_rate);
INLINE bool has_output_frame_rate() const;
INLINE double get_output_frame_rate() const;
INLINE void clear_output_frame_rate();
INLINE static double get_default_frame_rate();
INLINE void set_merge_externals(bool merge_externals);
INLINE bool get_merge_externals() const;
@ -99,6 +131,21 @@ protected:
PathConvert _mpc;
Filename _mpc_directory;
AnimationConvert _animation_convert;
double _start_frame;
double _end_frame;
double _frame_inc;
double _input_frame_rate; // frames per second
double _output_frame_rate; // frames per second
enum ControlFlags {
CF_start_frame = 0x0001,
CF_end_frame = 0x0002,
CF_frame_inc = 0x0004,
CF_input_frame_rate = 0x0008,
CF_output_frame_rate = 0x0010,
};
int _control_flags;
bool _merge_externals;
EggData *_egg_data;

View File

@ -58,6 +58,12 @@ SomethingToEgg(const string &format_name,
_input_units = DU_invalid;
_output_units = DU_invalid;
_animation_convert = AC_none;
_got_start_frame = false;
_got_end_frame = false;
_got_frame_inc = false;
_got_input_frame_rate = false;
_got_output_frame_rate = false;
_texture_path_convert = SomethingToEggConverter::PC_unchanged;
_model_path_convert = SomethingToEggConverter::PC_unchanged;
_append_to_sys_paths = false;
@ -90,6 +96,53 @@ add_units_options() {
&SomethingToEgg::dispatch_units, NULL, &_output_units);
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::add_animation_options
// Access: Public
// Description: Adds options appropriate to animation packages.
////////////////////////////////////////////////////////////////////
void SomethingToEgg::
add_animation_options() {
add_option
("a", "animation-mode", 40,
"Specifies how animation from the " + _format_name + " file is "
"converted to egg, if at all. At present, the following keywords "
"are supported: none and flip.",
&SomethingToEgg::dispatch_animation_convert, NULL, &_animation_convert);
add_option
("sf", "start-frame", 40,
"Specifies the starting frame of animation to extract. If omitted, "
"the first frame of the time slider will be used.",
&SomethingToEgg::dispatch_double, &_got_start_frame, &_start_frame);
add_option
("ef", "end-frame", 40,
"Specifies the ending frame of animation to extract. If omitted, "
"the last frame of the time slider will be used.",
&SomethingToEgg::dispatch_double, &_got_end_frame, &_end_frame);
add_option
("if", "frame-inc", 40,
"Specifies the increment between successive frames. If omitted, "
"this is taken from the time slider settings, or 1.0 if the time "
"slider does not specify.",
&SomethingToEgg::dispatch_double, &_got_frame_inc, &_frame_inc);
add_option
("fri", "fps", 40,
"Specify the frame rate (frames per second) of the input " + _format_name +
" file. Normally, this can be inferred from the file itself.",
&SomethingToEgg::dispatch_double, &_got_input_frame_rate, &_input_frame_rate);
add_option
("fro", "fps", 40,
"Specify the frame rate (frames per second) of the generated animation. "
"If this is specified, the animation speed is scaled by the appropriate "
"factor based on the frame rate of the input file (see -ri).",
&SomethingToEgg::dispatch_double, &_got_output_frame_rate, &_output_frame_rate);
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::add_texture_path_options
// Access: Public
@ -354,6 +407,25 @@ post_process_egg_file() {
EggConverter::post_process_egg_file();
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::dispatch_animation_convert
// Access: Protected, Static
// Description: Dispatch function to set the given animation convert mode
// according to the specified parameter. var is a
// pointer to an AnimationConvert variable.
////////////////////////////////////////////////////////////////////
bool SomethingToEgg::
dispatch_animation_convert(const string &opt, const string &arg, void *var) {
AnimationConvert *ip = (AnimationConvert *)var;
(*ip) = string_animation_convert(arg);
if ((*ip) == AC_invalid) {
nout << "Invalid keyword for -" << opt << ": " << arg << "\n";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: SomethingToEgg::dispatch_path_convert_relative
// Access: Protected, Static

View File

@ -41,6 +41,7 @@ public:
bool allow_stdout = true);
void add_units_options();
void add_animation_options();
void add_texture_path_options();
void add_model_path_options();
void add_rel_dir_options();
@ -54,6 +55,7 @@ protected:
virtual bool post_command_line();
virtual void post_process_egg_file();
static bool dispatch_animation_convert(const string &opt, const string &arg, void *var);
static bool dispatch_path_convert_relative(const string &opt, const string &arg, void *var);
static bool dispatch_path_convert_absolute(const string &opt, const string &arg, void *var);
static bool dispatch_path_convert_rel_abs(const string &opt, const string &arg, void *var);
@ -66,6 +68,18 @@ protected:
DistanceUnit _input_units;
DistanceUnit _output_units;
AnimationConvert _animation_convert;
double _start_frame;
double _end_frame;
double _frame_inc;
double _input_frame_rate;
double _output_frame_rate;
bool _got_start_frame;
bool _got_end_frame;
bool _got_frame_inc;
bool _got_input_frame_rate;
bool _got_output_frame_rate;
SomethingToEggConverter::PathConvert _texture_path_convert;
SomethingToEggConverter::PathConvert _model_path_convert;

View File

@ -95,7 +95,7 @@ find_shader_for_node(MObject node) {
}
// Well, we didn't find a ShadingEngine after all. Huh.
maya_cat.info()
maya_cat.debug()
<< node_fn.name() << " : no shading engine found.\n";
return (MayaShader *)NULL;
}

View File

@ -60,6 +60,8 @@
#include <maya/MTransformationMatrix.h>
#include <maya/MVector.h>
#include <maya/MTesselationParams.h>
#include <maya/MAnimControl.h>
#include <maya/MGlobal.h>
#include "post_maya_include.h"
////////////////////////////////////////////////////////////////////
@ -138,8 +140,7 @@ get_extension() const {
//
// This is designed to be as generic as possible,
// generally in support of run-time loading.
// Command-line converters may choose to use
// convert_maya() instead, as it provides more control.
// Also see convert_maya().
////////////////////////////////////////////////////////////////////
bool MayaToEggConverter::
convert_file(const Filename &filename) {
@ -179,34 +180,50 @@ convert_maya() {
_egg_data->set_coordinate_system(_maya->get_coordinate_system());
}
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
return false;
}
mayaegg_cat.info()
<< "Converting from Maya.\n";
// 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_node(dag_path, get_egg_data())) {
all_ok = false;
}
}
dag_iterator.next();
// Figure out the animation parameters.
double start_frame, end_frame, frame_inc, input_frame_rate, output_frame_rate;
if (has_start_frame()) {
start_frame = get_start_frame();
} else {
start_frame = MAnimControl::minTime().value();
}
if (has_end_frame()) {
end_frame = get_end_frame();
} else {
end_frame = MAnimControl::maxTime().value();
}
if (has_frame_inc()) {
frame_inc = get_frame_inc();
} else {
frame_inc = 1.0;
}
if (has_input_frame_rate()) {
input_frame_rate = get_input_frame_rate();
} else {
MTime time(1.0, MTime::kSeconds);
input_frame_rate = time.as(MTime::uiUnit());
}
if (has_output_frame_rate()) {
output_frame_rate = get_output_frame_rate();
} else {
output_frame_rate = input_frame_rate;
}
bool all_ok = true;
switch (get_animation_convert()) {
case AC_none:
all_ok = convert_hierarchy(&get_egg_data());
break;
case AC_flip:
all_ok = convert_flip(start_frame, end_frame, frame_inc,
output_frame_rate);
break;
};
if (all_ok) {
mayaegg_cat.info()
@ -248,6 +265,87 @@ close_api() {
_maya.clear();
}
////////////////////////////////////////////////////////////////////
// Function: MayaToEggConverter::convert_flip
// Access: Private
// Description: Converts the animation as a series of models that
// cycle (flip) from one to the next at the appropriate
// frame rate. This is the most likely to convert
// precisely (since we ask Maya to tell us the vertex
// position each time) but it is the most wasteful in
// terms of memory utilization (since a complete of the
// model is stored for each frame).
////////////////////////////////////////////////////////////////////
bool MayaToEggConverter::
convert_flip(double start_frame, double end_frame, double frame_inc,
double output_frame_rate) {
bool all_ok = true;
EggGroup *sequence_node = new EggGroup("model");
get_egg_data().add_child(sequence_node);
sequence_node->set_switch_flag(true);
sequence_node->set_switch_fps(output_frame_rate / frame_inc);
MTime frame(start_frame, MTime::uiUnit());
MTime frame_stop(end_frame, MTime::uiUnit());
while (frame <= frame_stop) {
nout << "frame " << frame.value() << "\n";
ostringstream name_strm;
name_strm << "frame" << frame.value();
EggGroup *frame_root = new EggGroup(name_strm.str());
sequence_node->add_child(frame_root);
MGlobal::viewFrame(frame);
if (!convert_hierarchy(frame_root)) {
all_ok = false;
}
_groups.clear();
frame += frame_inc;
}
return all_ok;
}
////////////////////////////////////////////////////////////////////
// Function: MayaToEggConverter::convert_hierarchy
// Access: Private
// Description: Walks the entire Maya hierarchy, converting it to a
// corresponding egg hierarchy under the indicated root
// node.
////////////////////////////////////////////////////////////////////
bool MayaToEggConverter::
convert_hierarchy(EggGroupNode *egg_root) {
MStatus status;
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (!status) {
status.perror("MItDag constructor");
return false;
}
// 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_node(dag_path, egg_root)) {
all_ok = false;
}
}
dag_iterator.next();
}
return all_ok;
}
////////////////////////////////////////////////////////////////////
// Function: MayaToEggConverter::process_node
// Access: Private
@ -257,7 +355,7 @@ close_api() {
// successful, false if an error was encountered.
////////////////////////////////////////////////////////////////////
bool MayaToEggConverter::
process_node(const MDagPath &dag_path, EggData &data) {
process_node(const MDagPath &dag_path, EggGroupNode *egg_root) {
MStatus status;
MFnDagNode dag_node(dag_path, &status);
if (!status) {
@ -285,7 +383,7 @@ process_node(const MDagPath &dag_path, EggData &data) {
} else if (dag_path.hasFn(MFn::kNurbsSurface)) {
EggGroup *egg_group =
get_egg_group(dag_path.fullPathName().asChar(), data);
get_egg_group(dag_path.fullPathName().asChar(), egg_root);
if (egg_group == (EggGroup *)NULL) {
mayaegg_cat.error()
@ -307,7 +405,7 @@ process_node(const MDagPath &dag_path, EggData &data) {
} else if (dag_path.hasFn(MFn::kNurbsCurve)) {
EggGroup *egg_group =
get_egg_group(dag_path.fullPathName().asChar(), data);
get_egg_group(dag_path.fullPathName().asChar(), egg_root);
if (egg_group == (EggGroup *)NULL) {
nout << "Cannot determine group node.\n";
@ -327,7 +425,7 @@ process_node(const MDagPath &dag_path, EggData &data) {
} else if (dag_path.hasFn(MFn::kMesh)) {
EggGroup *egg_group =
get_egg_group(dag_path.fullPathName().asChar(), data);
get_egg_group(dag_path.fullPathName().asChar(), egg_root);
if (egg_group == (EggGroup *)NULL) {
mayaegg_cat.error()
@ -350,7 +448,7 @@ process_node(const MDagPath &dag_path, EggData &data) {
} else {
// Get the translation/rotation/scale data
EggGroup *egg_group =
get_egg_group(dag_path.fullPathName().asChar(), data);
get_egg_group(dag_path.fullPathName().asChar(), egg_root);
if (egg_group != (EggGroup *)NULL) {
get_transform(dag_path, egg_group);
@ -938,7 +1036,7 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
// Maya hierarchy sensibly.
////////////////////////////////////////////////////////////////////
EggGroup *MayaToEggConverter::
get_egg_group(const string &name, EggData &data) {
get_egg_group(const string &name, EggGroupNode *egg_root) {
// If we have already encountered this pathname, return the
// corresponding EggGroup immediately.
Groups::const_iterator gi = _groups.find(name);
@ -967,13 +1065,13 @@ get_egg_group(const string &name, EggData &data) {
local_name = name;
}
EggGroup *parent_egg_group = get_egg_group(parent_name, data);
EggGroup *parent_egg_group = get_egg_group(parent_name, egg_root);
egg_group = new EggGroup(local_name);
if (parent_egg_group != (EggGroup *)NULL) {
parent_egg_group->add_child(egg_group);
} else {
data.add_child(egg_group);
egg_root->add_child(egg_group);
}
}

View File

@ -68,7 +68,10 @@ public:
void close_api();
private:
bool process_node(const MDagPath &dag_path, EggData &data);
bool convert_flip(double start_frame, double end_frame, double frame_inc,
double output_frame_rate);
bool convert_hierarchy(EggGroupNode *egg_root);
bool process_node(const MDagPath &dag_path, EggGroupNode *egg_root);
void get_transform(const MDagPath &dag_path, EggGroup *egg_group);
// I ran into core dumps trying to pass around a MFnMesh object by
@ -89,7 +92,7 @@ private:
EggGroup *egg_group,
MayaShader *default_shader = NULL);
EggGroup *get_egg_group(const string &name, EggData &data);
EggGroup *get_egg_group(const string &name, EggGroupNode *egg_root);
void set_shader_attributes(EggPrimitive &primitive,
const MayaShader &shader);

View File

@ -29,6 +29,7 @@ MayaToEgg::
MayaToEgg() :
SomethingToEgg("Maya", ".mb")
{
add_animation_options();
add_units_options();
add_normals_options();
add_transform_options();
@ -97,6 +98,24 @@ run() {
converter._polygon_tolerance = _polygon_tolerance;
converter._ignore_transforms = _ignore_transforms;
// Copy in the animation parameters.
converter.set_animation_convert(_animation_convert);
if (_got_start_frame) {
converter.set_start_frame(_start_frame);
}
if (_got_end_frame) {
converter.set_end_frame(_end_frame);
}
if (_got_frame_inc) {
converter.set_frame_inc(_frame_inc);
}
if (_got_input_frame_rate) {
converter.set_input_frame_rate(_input_frame_rate);
}
if (_got_output_frame_rate) {
converter.set_output_frame_rate(_output_frame_rate);
}
// Set the coordinate system to match Maya's.
if (!_got_coordinate_system) {
_coordinate_system = converter._maya->get_coordinate_system();