From 41828cfea9ab6f8f5bcda5f055616fc19c5a882a Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 21 Jan 2003 23:26:29 +0000 Subject: [PATCH] beginning animation stuff in maya --- pandatool/src/converter/Sources.pp | 2 + pandatool/src/converter/animationConvert.cxx | 70 ++++ pandatool/src/converter/animationConvert.h | 41 +++ .../src/converter/somethingToEggConverter.I | 303 ++++++++++++++++++ .../src/converter/somethingToEggConverter.cxx | 7 + .../src/converter/somethingToEggConverter.h | 53 ++- pandatool/src/eggbase/somethingToEgg.cxx | 72 +++++ pandatool/src/eggbase/somethingToEgg.h | 14 + pandatool/src/maya/mayaShaders.cxx | 2 +- pandatool/src/mayaegg/mayaToEggConverter.cxx | 166 ++++++++-- pandatool/src/mayaegg/mayaToEggConverter.h | 7 +- pandatool/src/mayaprogs/mayaToEgg.cxx | 19 ++ 12 files changed, 716 insertions(+), 40 deletions(-) create mode 100644 pandatool/src/converter/animationConvert.cxx create mode 100644 pandatool/src/converter/animationConvert.h diff --git a/pandatool/src/converter/Sources.pp b/pandatool/src/converter/Sources.pp index 464a0d201e..f8d3d66bfd 100644 --- a/pandatool/src/converter/Sources.pp +++ b/pandatool/src/converter/Sources.pp @@ -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 diff --git a/pandatool/src/converter/animationConvert.cxx b/pandatool/src/converter/animationConvert.cxx new file mode 100644 index 0000000000..8ef6451efd --- /dev/null +++ b/pandatool/src/converter/animationConvert.cxx @@ -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; + } +} diff --git a/pandatool/src/converter/animationConvert.h b/pandatool/src/converter/animationConvert.h new file mode 100644 index 0000000000..532f0798e7 --- /dev/null +++ b/pandatool/src/converter/animationConvert.h @@ -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 diff --git a/pandatool/src/converter/somethingToEggConverter.I b/pandatool/src/converter/somethingToEggConverter.I index e043ec96e0..95bc136398 100644 --- a/pandatool/src/converter/somethingToEggConverter.I +++ b/pandatool/src/converter/somethingToEggConverter.I @@ -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 diff --git a/pandatool/src/converter/somethingToEggConverter.cxx b/pandatool/src/converter/somethingToEggConverter.cxx index 2cb8b931a2..4697cde571 100644 --- a/pandatool/src/converter/somethingToEggConverter.cxx +++ b/pandatool/src/converter/somethingToEggConverter.cxx @@ -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; diff --git a/pandatool/src/converter/somethingToEggConverter.h b/pandatool/src/converter/somethingToEggConverter.h index 595899df77..6b814f2a36 100644 --- a/pandatool/src/converter/somethingToEggConverter.h +++ b/pandatool/src/converter/somethingToEggConverter.h @@ -19,10 +19,11 @@ #ifndef SOMETHINGTOEGGCONVERTER_H #define SOMETHINGTOEGGCONVERTER_H -#include +#include "pandatoolbase.h" -#include -#include // 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; diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index 1a684ac81f..13aa83642b 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -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 diff --git a/pandatool/src/eggbase/somethingToEgg.h b/pandatool/src/eggbase/somethingToEgg.h index 2c2946769e..dc92e3293f 100644 --- a/pandatool/src/eggbase/somethingToEgg.h +++ b/pandatool/src/eggbase/somethingToEgg.h @@ -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; diff --git a/pandatool/src/maya/mayaShaders.cxx b/pandatool/src/maya/mayaShaders.cxx index e5a2e1b26b..23102a544e 100644 --- a/pandatool/src/maya/mayaShaders.cxx +++ b/pandatool/src/maya/mayaShaders.cxx @@ -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; } diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index 2a6a6c441d..d3f5a35b3e 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -60,6 +60,8 @@ #include #include #include +#include +#include #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); } } diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index b8d904174e..bd93138fe6 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -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); diff --git a/pandatool/src/mayaprogs/mayaToEgg.cxx b/pandatool/src/mayaprogs/mayaToEgg.cxx index a4dd046929..1df453e6e3 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.cxx +++ b/pandatool/src/mayaprogs/mayaToEgg.cxx @@ -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();