/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once #include #include #include #include "BCAnimationCurve.h" #include "DNA_action_types.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_light_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" #include "BLI_utildefines.h" #include "BIK_api.h" #include "BKE_action.h" /* pose functions */ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_fcurve.h" #include "BKE_object.h" #include "BKE_scene.h" #include "ED_object.h" #include "MEM_guardedalloc.h" #include "RNA_access.h" #include "COLLADASWBaseInputElement.h" #include "COLLADASWConstants.h" #include "COLLADASWInputList.h" #include "COLLADASWInstanceGeometry.h" #include "COLLADASWLibraryAnimations.h" #include "COLLADASWParamBase.h" #include "COLLADASWParamTemplate.h" #include "COLLADASWPrimitves.h" #include "COLLADASWSampler.h" #include "COLLADASWSource.h" #include "COLLADASWVertices.h" #include "BCAnimationSampler.h" #include "EffectExporter.h" #include "collada_internal.h" #include "IK_solver.h" #include /* std::find */ #include #include typedef enum BC_animation_source_type { BC_SOURCE_TYPE_VALUE, BC_SOURCE_TYPE_ANGLE, BC_SOURCE_TYPE_TIMEFRAME, } BC_animation_source_type; typedef enum BC_global_rotation_type { BC_NO_ROTATION, BC_OBJECT_ROTATION, BC_DATA_ROTATION } BC_global_rotation_type; class AnimationExporter : COLLADASW::LibraryAnimations { private: COLLADASW::StreamWriter *sw; BCExportSettings &export_settings; BC_global_rotation_type get_global_rotation_type(Object *ob); public: AnimationExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) : COLLADASW::LibraryAnimations(sw), sw(sw), export_settings(export_settings) { } bool exportAnimations(); /** Called for each exported object. */ void operator()(Object *ob); protected: void export_object_constraint_animation(Object *ob); void export_morph_animation(Object *ob); void write_bone_animation_matrix(Object *ob_arm, Bone *bone); void write_bone_animation(Object *ob_arm, Bone *bone); void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type); void sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone); void sample_animation(float *v, std::vector &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pChan); void sample_animation(std::vector &mats, std::vector &frames, Bone *bone, Object *ob_arm, bPoseChannel *pChan); /* dae_bone_animation -> add_bone_animation * (blend this into dae_bone_animation) */ void dae_bone_animation(std::vector &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name); void dae_baked_animation(std::vector &fra, Object *ob_arm, Bone *bone); void dae_baked_object_animation(std::vector &fra, Object *ob); float convert_time(float frame); float convert_angle(float angle); std::vector> anim_meta; /** Main entry point into Animation export (called for each exported object). */ void exportAnimation(Object *ob, BCAnimationSampler &sampler); /** * Export all animation FCurves of an Object. * * \note This uses the keyframes as sample points, * and exports "baked keyframes" while keeping the tangent information * of the FCurves intact. This works for simple cases, but breaks * especially when negative scales are involved in the animation. * And when parent inverse matrices are involved (when exporting * object hierarchies) */ void export_curve_animation_set(Object *ob, BCAnimationSampler &sampler, bool export_as_matrix); /** Export one single curve. */ void export_curve_animation(Object *ob, BCAnimationCurve &curve); /** Export animation as matrix data. */ void export_matrix_animation(Object *ob, BCAnimationSampler &sampler); /** Write bone animations in transform matrix sources (step through the bone hierarchy). */ void export_bone_animations_recursive(Object *ob_arm, Bone *bone, BCAnimationSampler &sampler); /** Export for one bone. */ void export_bone_animation(Object *ob, Bone *bone, BCFrames &frames, BCMatrixSampleMap &samples); /** Call to the low level collada exporter. */ void export_collada_curve_animation(std::string id, std::string name, std::string target, std::string axis, BCAnimationCurve &curve, BC_global_rotation_type global_rotation_type); /** Call to the low level collada exporter. */ void export_collada_matrix_animation(std::string id, std::string name, std::string target, BCFrames &frames, BCMatrixSampleMap &samples, BC_global_rotation_type global_rotation_type, Matrix &parentinv); /** * In some special cases the exported Curve needs to be replaced * by a modified curve (for collada purposes) * This method checks if a conversion is necessary and if applicable * returns a pointer to the modified BCAnimationCurve. * IMPORTANT: the modified curve must be deleted by the caller when no longer needed * if no conversion is needed this method returns a NULL; */ BCAnimationCurve *get_modified_export_curve(Object *ob, BCAnimationCurve &curve, BCAnimationCurveMap &curves); /* Helper functions. */ void openAnimationWithClip(std::string id, std::string name); bool open_animation_container(bool has_container, Object *ob); void close_animation_container(bool has_container); /** Input and Output sources (single valued). */ std::string collada_source_from_values(BC_animation_source_type source_type, COLLADASW::InputSemantic::Semantics semantic, std::vector &values, const std::string &anim_id, const std::string axis_name); /** Output sources (matrix data). * Create a collada matrix source for a set of samples. */ std::string collada_source_from_values(BCMatrixSampleMap &samples, const std::string &anim_id, BC_global_rotation_type global_rotation_type, Matrix &parentinv); /** Interpolation sources. */ std::string collada_linear_interpolation_source(int tot, const std::string &anim_id); /* source ID = animation_name + semantic_suffix */ std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic); void add_source_parameters(COLLADASW::SourceBase::ParameterNameList ¶m, COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const std::string axis, bool transform); int get_point_in_curve(BCBezTriple &bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_angle, float *values); int get_point_in_curve(const BCAnimationCurve &curve, float sample_frame, COLLADASW::InputSemantic::Semantics semantic, bool is_angle, float *values); std::string collada_tangent_from_curve(COLLADASW::InputSemantic::Semantics semantic, BCAnimationCurve &curve, const std::string &anim_id, const std::string axis_name); std::string collada_interpolation_source(const BCAnimationCurve &curve, const std::string &anim_id, std::string axis_name, bool *has_tangents); std::string get_axis_name(std::string channel, int id); std::string get_collada_name(std::string channel_type) const; /** * Assign sid of the animated parameter or transform for rotation, * axis name is always appended and the value of append_axis is ignored. */ std::string get_collada_sid(const BCAnimationCurve &curve, const std::string axis_name); /* ===================================== */ /* Currently unused or not (yet?) needed */ /* ===================================== */ bool is_bone_deform_group(Bone *bone); #if 0 BC_animation_transform_type _get_transform_type(const std::string path); void get_eul_source_for_quat(std::vector &cache, Object *ob); #endif #ifdef WITH_MORPH_ANIMATION void export_morph_animation(Object *ob, BCAnimationSampler &sampler); #endif };