diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/collada/AnimationExporter.cpp | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/collada/AnimationExporter.cpp')
-rw-r--r-- | source/blender/collada/AnimationExporter.cpp | 1234 |
1 files changed, 630 insertions, 604 deletions
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index e9babea7b3d..bfef2d76a3d 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -29,140 +29,138 @@ std::string EMPTY_STRING; std::string AnimationExporter::get_axis_name(std::string channel, int id) { - static std::map<std::string, std::vector<std::string>> BC_COLLADA_AXIS_FROM_TYPE = { - { "color" ,{ "R", "G", "B" } }, - { "specular_color",{ "R", "G", "B" } }, - { "diffuse_color",{ "R", "G", "B" } }, - { "alpha",{ "R", "G", "B" } }, - { "scale",{ "X", "Y", "Z" } }, - { "location",{ "X", "Y", "Z" } }, - { "rotation_euler",{ "X", "Y", "Z" } } - }; - - std::map<std::string, std::vector<std::string>>::const_iterator it; - it = BC_COLLADA_AXIS_FROM_TYPE.find(channel); - if (it == BC_COLLADA_AXIS_FROM_TYPE.end()) - return ""; - - const std::vector<std::string> &subchannel = it->second; - if (id >= subchannel.size()) - return ""; - return subchannel[id]; + static std::map<std::string, std::vector<std::string>> BC_COLLADA_AXIS_FROM_TYPE = { + {"color", {"R", "G", "B"}}, + {"specular_color", {"R", "G", "B"}}, + {"diffuse_color", {"R", "G", "B"}}, + {"alpha", {"R", "G", "B"}}, + {"scale", {"X", "Y", "Z"}}, + {"location", {"X", "Y", "Z"}}, + {"rotation_euler", {"X", "Y", "Z"}}}; + + std::map<std::string, std::vector<std::string>>::const_iterator it; + it = BC_COLLADA_AXIS_FROM_TYPE.find(channel); + if (it == BC_COLLADA_AXIS_FROM_TYPE.end()) + return ""; + + const std::vector<std::string> &subchannel = it->second; + if (id >= subchannel.size()) + return ""; + return subchannel[id]; } bool AnimationExporter::open_animation_container(bool has_container, Object *ob) { - if (!has_container) { - char anim_id[200]; - sprintf(anim_id, "action_container-%s", translate_id(id_name(ob)).c_str()); - openAnimation(anim_id, encode_xml(id_name(ob))); - } - return true; + if (!has_container) { + char anim_id[200]; + sprintf(anim_id, "action_container-%s", translate_id(id_name(ob)).c_str()); + openAnimation(anim_id, encode_xml(id_name(ob))); + } + return true; } void AnimationExporter::openAnimationWithClip(std::string action_id, std::string action_name) { - std::vector<std::string> anim_meta_entry; - anim_meta_entry.push_back(translate_id(action_id)); - anim_meta_entry.push_back(action_name); - anim_meta.push_back(anim_meta_entry); + std::vector<std::string> anim_meta_entry; + anim_meta_entry.push_back(translate_id(action_id)); + anim_meta_entry.push_back(action_name); + anim_meta.push_back(anim_meta_entry); - openAnimation(translate_id(action_id), action_name); + openAnimation(translate_id(action_id), action_name); } void AnimationExporter::close_animation_container(bool has_container) { - if (has_container) - closeAnimation(); + if (has_container) + closeAnimation(); } bool AnimationExporter::exportAnimations() { - Scene *sce = blender_context.get_scene(); - - LinkNode &export_set = *this->export_settings->export_set; - bool has_anim_data = bc_has_animations(sce, export_set); - int animation_count = 0; - if (has_anim_data) { - - BCObjectSet animated_subset; - BCAnimationSampler::get_animated_from_export_set(animated_subset, export_set); - animation_count = animated_subset.size(); - BCAnimationSampler animation_sampler(blender_context, animated_subset); - - try { - animation_sampler.sample_scene( - export_settings->sampling_rate, - /*keyframe_at_end = */ true, - export_settings->open_sim, - export_settings->keep_keyframes, - export_settings->export_animation_type - ); - - openLibrary(); - - BCObjectSet::iterator it; - for (it = animated_subset.begin(); it != animated_subset.end(); ++it) { - Object *ob = *it; - exportAnimation(ob, animation_sampler); - } - } - catch (std::invalid_argument &iae) - { - fprintf(stderr, "Animation export interrupted"); - fprintf(stderr, "Exception was: %s", iae.what()); - } - - closeLibrary(); + Scene *sce = blender_context.get_scene(); + + LinkNode &export_set = *this->export_settings->export_set; + bool has_anim_data = bc_has_animations(sce, export_set); + int animation_count = 0; + if (has_anim_data) { + + BCObjectSet animated_subset; + BCAnimationSampler::get_animated_from_export_set(animated_subset, export_set); + animation_count = animated_subset.size(); + BCAnimationSampler animation_sampler(blender_context, animated_subset); + + try { + animation_sampler.sample_scene(export_settings->sampling_rate, + /*keyframe_at_end = */ true, + export_settings->open_sim, + export_settings->keep_keyframes, + export_settings->export_animation_type); + + openLibrary(); + + BCObjectSet::iterator it; + for (it = animated_subset.begin(); it != animated_subset.end(); ++it) { + Object *ob = *it; + exportAnimation(ob, animation_sampler); + } + } + catch (std::invalid_argument &iae) { + fprintf(stderr, "Animation export interrupted"); + fprintf(stderr, "Exception was: %s", iae.what()); + } + + closeLibrary(); #if 0 - /* TODO: If all actions shall be exported, we need to call the - * AnimationClipExporter which will figure out which actions - * need to be exported for which objects - */ - if (this->export_settings->include_all_actions) { - AnimationClipExporter ace(eval_ctx, sw, export_settings, anim_meta); - ace.exportAnimationClips(sce); - } + /* TODO: If all actions shall be exported, we need to call the + * AnimationClipExporter which will figure out which actions + * need to be exported for which objects + */ + if (this->export_settings->include_all_actions) { + AnimationClipExporter ace(eval_ctx, sw, export_settings, anim_meta); + ace.exportAnimationClips(sce); + } #endif - } - return animation_count; + } + return animation_count; } /* called for each exported object */ void AnimationExporter::exportAnimation(Object *ob, BCAnimationSampler &sampler) { - bool container_is_open = false; + bool container_is_open = false; - //Transform animations (trans, rot, scale) - container_is_open = open_animation_container(container_is_open, ob); + //Transform animations (trans, rot, scale) + container_is_open = open_animation_container(container_is_open, ob); - /* Now take care of the Object Animations - * Note: For Armatures the skeletal animation has already been exported (see above) - * However Armatures also can have Object animation. - */ - bool export_as_matrix = this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX; + /* Now take care of the Object Animations + * Note: For Armatures the skeletal animation has already been exported (see above) + * However Armatures also can have Object animation. + */ + bool export_as_matrix = this->export_settings->export_transformation_type == + BC_TRANSFORMATION_TYPE_MATRIX; - if (export_as_matrix) { - export_matrix_animation(ob, sampler); // export all transform_curves as one single matrix animation - } + if (export_as_matrix) { + export_matrix_animation( + ob, sampler); // export all transform_curves as one single matrix animation + } - export_curve_animation_set(ob, sampler, export_as_matrix); + export_curve_animation_set(ob, sampler, export_as_matrix); - if (ob->type == OB_ARMATURE) { + if (ob->type == OB_ARMATURE) { #ifdef WITH_MORPH_ANIMATION - /* TODO: This needs to be handled by extra profiles, postponed for now */ - export_morph_animation(ob); + /* TODO: This needs to be handled by extra profiles, postponed for now */ + export_morph_animation(ob); #endif - /* Export skeletal animation (if any) */ - bArmature *arm = (bArmature *)ob->data; - for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next) - export_bone_animations_recursive(ob, root_bone, sampler); - } + /* Export skeletal animation (if any) */ + bArmature *arm = (bArmature *)ob->data; + for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next) + export_bone_animations_recursive(ob, root_bone, sampler); + } - close_animation_container(container_is_open); + close_animation_container(container_is_open); } /* @@ -175,88 +173,92 @@ void AnimationExporter::exportAnimation(Object *ob, BCAnimationSampler &sampler) * And when parent inverse matrices are involved (when exporting * object hierarchies) */ -void AnimationExporter::export_curve_animation_set(Object *ob, BCAnimationSampler &sampler, bool export_as_matrix) +void AnimationExporter::export_curve_animation_set(Object *ob, + BCAnimationSampler &sampler, + bool export_as_matrix) { - BCAnimationCurveMap *curves = sampler.get_curves(ob); - bool keep_flat_curves = this->export_settings->keep_flat_curves; - - BCAnimationCurveMap::iterator it; - for (it = curves->begin(); it != curves->end(); ++it) { - BCAnimationCurve &curve = *it->second; - if (curve.get_channel_target() == "rotation_quaternion") { - /* - Can not export Quaternion animation in Collada as far as i know) - Maybe automatically convert to euler rotation? - Discard for now. - */ - continue; - } - - if (export_as_matrix && curve.is_transform_curve()) { - /* All Transform curves will be exported within a single matrix animation, - * see export_matrix_animation() - * No need to export the curves here again. - */ - continue; - } - - if (!keep_flat_curves && !curve.is_animated()) { - continue; - } - - BCAnimationCurve *mcurve = get_modified_export_curve(ob, curve, *curves); - if (mcurve) { - export_curve_animation(ob, *mcurve); - delete mcurve; - } - else { - export_curve_animation(ob, curve); - } - } + BCAnimationCurveMap *curves = sampler.get_curves(ob); + bool keep_flat_curves = this->export_settings->keep_flat_curves; + + BCAnimationCurveMap::iterator it; + for (it = curves->begin(); it != curves->end(); ++it) { + BCAnimationCurve &curve = *it->second; + if (curve.get_channel_target() == "rotation_quaternion") { + /* + Can not export Quaternion animation in Collada as far as i know) + Maybe automatically convert to euler rotation? + Discard for now. + */ + continue; + } + + if (export_as_matrix && curve.is_transform_curve()) { + /* All Transform curves will be exported within a single matrix animation, + * see export_matrix_animation() + * No need to export the curves here again. + */ + continue; + } + + if (!keep_flat_curves && !curve.is_animated()) { + continue; + } + + BCAnimationCurve *mcurve = get_modified_export_curve(ob, curve, *curves); + if (mcurve) { + export_curve_animation(ob, *mcurve); + delete mcurve; + } + else { + export_curve_animation(ob, curve); + } + } } void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler &sampler) { - bool keep_flat_curves = this->export_settings->keep_flat_curves; - - std::vector<float> frames; - sampler.get_object_frames(frames, ob); - if (frames.size() > 0) { - BCMatrixSampleMap samples; - bool is_animated = sampler.get_object_samples(samples, ob); - if (keep_flat_curves || is_animated) { - bAction *action = bc_getSceneObjectAction(ob); - std::string name = encode_xml(id_name(ob)); - std::string action_name = (action == NULL) ? name + "-action" : id_name(action); - std::string channel_type = "transform"; - std::string axis = ""; - std::string id = bc_get_action_id(action_name, name, channel_type, axis); - - std::string target = translate_id(name) + '/' + channel_type; - - export_collada_matrix_animation(id, name, target, frames, samples); - } - } + bool keep_flat_curves = this->export_settings->keep_flat_curves; + + std::vector<float> frames; + sampler.get_object_frames(frames, ob); + if (frames.size() > 0) { + BCMatrixSampleMap samples; + bool is_animated = sampler.get_object_samples(samples, ob); + if (keep_flat_curves || is_animated) { + bAction *action = bc_getSceneObjectAction(ob); + std::string name = encode_xml(id_name(ob)); + std::string action_name = (action == NULL) ? name + "-action" : id_name(action); + std::string channel_type = "transform"; + std::string axis = ""; + std::string id = bc_get_action_id(action_name, name, channel_type, axis); + + std::string target = translate_id(name) + '/' + channel_type; + + export_collada_matrix_animation(id, name, target, frames, samples); + } + } } //write bone animations in transform matrix sources -void AnimationExporter::export_bone_animations_recursive(Object *ob, Bone *bone, BCAnimationSampler &sampler) +void AnimationExporter::export_bone_animations_recursive(Object *ob, + Bone *bone, + BCAnimationSampler &sampler) { - bool keep_flat_curves = this->export_settings->keep_flat_curves; + bool keep_flat_curves = this->export_settings->keep_flat_curves; - std::vector<float> frames; - sampler.get_bone_frames(frames, ob, bone); + std::vector<float> frames; + sampler.get_bone_frames(frames, ob, bone); - if (frames.size()) { - BCMatrixSampleMap samples; - bool is_animated = sampler.get_bone_samples(samples, ob, bone); - if (keep_flat_curves || is_animated) { - export_bone_animation(ob, bone, frames, samples); - } - } + if (frames.size()) { + BCMatrixSampleMap samples; + bool is_animated = sampler.get_bone_samples(samples, ob, bone); + if (keep_flat_curves || is_animated) { + export_bone_animation(ob, bone, frames, samples); + } + } - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) - export_bone_animations_recursive(ob, child, sampler); + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) + export_bone_animations_recursive(ob, child, sampler); } /** @@ -267,511 +269,535 @@ void AnimationExporter::export_bone_animations_recursive(Object *ob, Bone *bone, * 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 *AnimationExporter::get_modified_export_curve(Object *ob, BCAnimationCurve &curve, BCAnimationCurveMap &curves) +BCAnimationCurve *AnimationExporter::get_modified_export_curve(Object *ob, + BCAnimationCurve &curve, + BCAnimationCurveMap &curves) { - std::string channel_target = curve.get_channel_target(); - BCAnimationCurve *mcurve = NULL; - if (channel_target == "lens") { - - /* Create an xfov curve */ - - BCCurveKey key(BC_ANIMATION_TYPE_CAMERA, "xfov", 0); - mcurve = new BCAnimationCurve(key, ob); - - // now tricky part: transform the fcurve - BCValueMap lens_values; - curve.get_value_map(lens_values); - - BCAnimationCurve *sensor_curve = NULL; - BCCurveKey sensor_key(BC_ANIMATION_TYPE_CAMERA, "sensor_width", 0); - BCAnimationCurveMap::iterator cit = curves.find(sensor_key); - if (cit != curves.end()) { - sensor_curve = cit->second; - } - - BCValueMap::const_iterator vit; - for (vit = lens_values.begin(); vit != lens_values.end(); ++vit) { - int frame = vit->first; - float lens_value = vit->second; - - float sensor_value; - if (sensor_curve) { - sensor_value = sensor_curve->get_value(frame); - } - else { - sensor_value = ((Camera *)ob->data)->sensor_x; - } - float value = RAD2DEGF(focallength_to_fov(lens_value, sensor_value)); - mcurve->add_value(value, frame); - } - mcurve->clean_handles(); // to reset the handles - } - return mcurve; + std::string channel_target = curve.get_channel_target(); + BCAnimationCurve *mcurve = NULL; + if (channel_target == "lens") { + + /* Create an xfov curve */ + + BCCurveKey key(BC_ANIMATION_TYPE_CAMERA, "xfov", 0); + mcurve = new BCAnimationCurve(key, ob); + + // now tricky part: transform the fcurve + BCValueMap lens_values; + curve.get_value_map(lens_values); + + BCAnimationCurve *sensor_curve = NULL; + BCCurveKey sensor_key(BC_ANIMATION_TYPE_CAMERA, "sensor_width", 0); + BCAnimationCurveMap::iterator cit = curves.find(sensor_key); + if (cit != curves.end()) { + sensor_curve = cit->second; + } + + BCValueMap::const_iterator vit; + for (vit = lens_values.begin(); vit != lens_values.end(); ++vit) { + int frame = vit->first; + float lens_value = vit->second; + + float sensor_value; + if (sensor_curve) { + sensor_value = sensor_curve->get_value(frame); + } + else { + sensor_value = ((Camera *)ob->data)->sensor_x; + } + float value = RAD2DEGF(focallength_to_fov(lens_value, sensor_value)); + mcurve->add_value(value, frame); + } + mcurve->clean_handles(); // to reset the handles + } + return mcurve; } -void AnimationExporter::export_curve_animation( - Object *ob, - BCAnimationCurve &curve) +void AnimationExporter::export_curve_animation(Object *ob, BCAnimationCurve &curve) { - std::string channel_target = curve.get_channel_target(); - - /* - * Some curves can not be exported as is and need some conversion - * For more information see implementation oif get_modified_export_curve() - * note: if mcurve is not NULL then it must be deleted at end of this method; - */ - - int channel_index = curve.get_channel_index(); - std::string axis = get_axis_name(channel_target, channel_index); // RGB or XYZ or "" - - std::string action_name; - bAction *action = bc_getSceneObjectAction(ob); - action_name = (action) ? id_name(action) : "constraint_anim"; - - const std::string curve_name = encode_xml(curve.get_animation_name(ob)); - std::string id = bc_get_action_id(action_name, curve_name, channel_target, axis, "."); - - std::string collada_target = translate_id(curve_name); - - if (curve.is_of_animation_type(BC_ANIMATION_TYPE_MATERIAL)) { - int material_index = curve.get_subindex(); - Material *ma = give_current_material(ob, material_index + 1); - if (ma) { - collada_target = translate_id(id_name(ma)) + "-effect/common/" + get_collada_sid(curve, axis); - } - } - else { - collada_target += "/" + get_collada_sid(curve, axis); - } - - export_collada_curve_animation(id, curve_name, collada_target, axis, curve); - + std::string channel_target = curve.get_channel_target(); + + /* + * Some curves can not be exported as is and need some conversion + * For more information see implementation oif get_modified_export_curve() + * note: if mcurve is not NULL then it must be deleted at end of this method; + */ + + int channel_index = curve.get_channel_index(); + std::string axis = get_axis_name(channel_target, channel_index); // RGB or XYZ or "" + + std::string action_name; + bAction *action = bc_getSceneObjectAction(ob); + action_name = (action) ? id_name(action) : "constraint_anim"; + + const std::string curve_name = encode_xml(curve.get_animation_name(ob)); + std::string id = bc_get_action_id(action_name, curve_name, channel_target, axis, "."); + + std::string collada_target = translate_id(curve_name); + + if (curve.is_of_animation_type(BC_ANIMATION_TYPE_MATERIAL)) { + int material_index = curve.get_subindex(); + Material *ma = give_current_material(ob, material_index + 1); + if (ma) { + collada_target = translate_id(id_name(ma)) + "-effect/common/" + + get_collada_sid(curve, axis); + } + } + else { + collada_target += "/" + get_collada_sid(curve, axis); + } + + export_collada_curve_animation(id, curve_name, collada_target, axis, curve); } -void AnimationExporter::export_bone_animation(Object *ob, Bone *bone, BCFrames &frames, BCMatrixSampleMap &samples) +void AnimationExporter::export_bone_animation(Object *ob, + Bone *bone, + BCFrames &frames, + BCMatrixSampleMap &samples) { - bAction* action = bc_getSceneObjectAction(ob); - std::string bone_name(bone->name); - std::string name = encode_xml(id_name(ob)); - std::string id = bc_get_action_id(id_name(action), name, bone_name, "pose_matrix"); - std::string target = translate_id(id_name(ob) + "_" + bone_name) + "/transform"; + bAction *action = bc_getSceneObjectAction(ob); + std::string bone_name(bone->name); + std::string name = encode_xml(id_name(ob)); + std::string id = bc_get_action_id(id_name(action), name, bone_name, "pose_matrix"); + std::string target = translate_id(id_name(ob) + "_" + bone_name) + "/transform"; - export_collada_matrix_animation(id, name, target, frames, samples); + export_collada_matrix_animation(id, name, target, frames, samples); } bool AnimationExporter::is_bone_deform_group(Bone *bone) { - bool is_def; - //Check if current bone is deform - if ((bone->flag & BONE_NO_DEFORM) == 0) return true; - //Check child bones - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - //loop through all the children until deform bone is found, and then return - is_def = is_bone_deform_group(child); - if (is_def) return true; - } - } - //no deform bone found in children also - return false; + bool is_def; + //Check if current bone is deform + if ((bone->flag & BONE_NO_DEFORM) == 0) + return true; + //Check child bones + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + //loop through all the children until deform bone is found, and then return + is_def = is_bone_deform_group(child); + if (is_def) + return true; + } + } + //no deform bone found in children also + return false; } - -void AnimationExporter::export_collada_curve_animation( - std::string id, - std::string name, - std::string collada_target, - std::string axis, - BCAnimationCurve &curve) +void AnimationExporter::export_collada_curve_animation(std::string id, + std::string name, + std::string collada_target, + std::string axis, + BCAnimationCurve &curve) { - BCFrames frames; - BCValues values; - curve.get_frames(frames); - curve.get_values(values); - std::string channel_target = curve.get_channel_target(); - - fprintf(stdout, "Export animation curve %s (%d control points)\n", id.c_str(), int(frames.size())); - openAnimation(id, name); - BC_animation_source_type source_type = (curve.is_rotation_curve()) ? BC_SOURCE_TYPE_ANGLE : BC_SOURCE_TYPE_VALUE; - - std::string input_id = collada_source_from_values(BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, axis); - std::string output_id = collada_source_from_values(source_type, COLLADASW::InputSemantic::OUTPUT, values, id, axis); - - bool has_tangents = false; - std::string interpolation_id; - if (this->export_settings->keep_smooth_curves) - interpolation_id = collada_interpolation_source(curve, id, axis, &has_tangents); - else - interpolation_id = collada_linear_interpolation_source(frames.size(), id); - - std::string intangent_id; - std::string outtangent_id; - if (has_tangents) { - intangent_id = collada_tangent_from_curve(COLLADASW::InputSemantic::IN_TANGENT, curve, id, axis); - outtangent_id = collada_tangent_from_curve(COLLADASW::InputSemantic::OUT_TANGENT, curve, id, axis); - } - - std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; - - COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); - - sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); - sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); - sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(EMPTY_STRING, interpolation_id)); - - if (has_tangents) { - sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(EMPTY_STRING, intangent_id)); - sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(EMPTY_STRING, outtangent_id)); - } - - addSampler(sampler); - addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), collada_target); - - closeAnimation(); + BCFrames frames; + BCValues values; + curve.get_frames(frames); + curve.get_values(values); + std::string channel_target = curve.get_channel_target(); + + fprintf( + stdout, "Export animation curve %s (%d control points)\n", id.c_str(), int(frames.size())); + openAnimation(id, name); + BC_animation_source_type source_type = (curve.is_rotation_curve()) ? BC_SOURCE_TYPE_ANGLE : + BC_SOURCE_TYPE_VALUE; + + std::string input_id = collada_source_from_values( + BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, axis); + std::string output_id = collada_source_from_values( + source_type, COLLADASW::InputSemantic::OUTPUT, values, id, axis); + + bool has_tangents = false; + std::string interpolation_id; + if (this->export_settings->keep_smooth_curves) + interpolation_id = collada_interpolation_source(curve, id, axis, &has_tangents); + else + interpolation_id = collada_linear_interpolation_source(frames.size(), id); + + std::string intangent_id; + std::string outtangent_id; + if (has_tangents) { + intangent_id = collada_tangent_from_curve( + COLLADASW::InputSemantic::IN_TANGENT, curve, id, axis); + outtangent_id = collada_tangent_from_curve( + COLLADASW::InputSemantic::OUT_TANGENT, curve, id, axis); + } + + std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; + + COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); + + sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); + sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); + sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, + COLLADABU::URI(EMPTY_STRING, interpolation_id)); + + if (has_tangents) { + sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, + COLLADABU::URI(EMPTY_STRING, intangent_id)); + sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, + COLLADABU::URI(EMPTY_STRING, outtangent_id)); + } + + addSampler(sampler); + addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), collada_target); + + closeAnimation(); } -void AnimationExporter::export_collada_matrix_animation(std::string id, std::string name, std::string target, BCFrames &frames, BCMatrixSampleMap &samples) +void AnimationExporter::export_collada_matrix_animation(std::string id, + std::string name, + std::string target, + BCFrames &frames, + BCMatrixSampleMap &samples) { - fprintf(stdout, "Export animation matrix %s (%d control points)\n", id.c_str(), int(frames.size())); - - openAnimationWithClip(id, name); + fprintf( + stdout, "Export animation matrix %s (%d control points)\n", id.c_str(), int(frames.size())); - std::string input_id = collada_source_from_values(BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, ""); - std::string output_id = collada_source_from_values(samples, id); - std::string interpolation_id = collada_linear_interpolation_source(frames.size(), id); + openAnimationWithClip(id, name); - std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; - COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); + std::string input_id = collada_source_from_values( + BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, ""); + std::string output_id = collada_source_from_values(samples, id); + std::string interpolation_id = collada_linear_interpolation_source(frames.size(), id); + std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; + COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); - sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); - sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); - sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(EMPTY_STRING, interpolation_id)); + sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); + sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); + sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, + COLLADABU::URI(EMPTY_STRING, interpolation_id)); - // Matrix animation has no tangents + // Matrix animation has no tangents - addSampler(sampler); - addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), target); + addSampler(sampler); + addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), target); - closeAnimation(); + closeAnimation(); } std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic) { - switch (semantic) { - case COLLADASW::InputSemantic::INPUT: - return INPUT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::OUTPUT: - return OUTPUT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::INTERPOLATION: - return INTERPOLATION_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::IN_TANGENT: - return INTANGENT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::OUT_TANGENT: - return OUTTANGENT_SOURCE_ID_SUFFIX; - default: - break; - } - return ""; + switch (semantic) { + case COLLADASW::InputSemantic::INPUT: + return INPUT_SOURCE_ID_SUFFIX; + case COLLADASW::InputSemantic::OUTPUT: + return OUTPUT_SOURCE_ID_SUFFIX; + case COLLADASW::InputSemantic::INTERPOLATION: + return INTERPOLATION_SOURCE_ID_SUFFIX; + case COLLADASW::InputSemantic::IN_TANGENT: + return INTANGENT_SOURCE_ID_SUFFIX; + case COLLADASW::InputSemantic::OUT_TANGENT: + return OUTTANGENT_SOURCE_ID_SUFFIX; + default: + break; + } + return ""; } -void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param, - COLLADASW::InputSemantic::Semantics semantic, - bool is_rot, - const std::string axis, - bool transform) +void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList ¶m, + COLLADASW::InputSemantic::Semantics semantic, + bool is_rot, + const std::string axis, + bool transform) { - switch (semantic) { - case COLLADASW::InputSemantic::INPUT: - param.push_back("TIME"); - break; - case COLLADASW::InputSemantic::OUTPUT: - if (is_rot) { - param.push_back("ANGLE"); - } - else { - if (axis != "") { - param.push_back(axis); - } - else - if (transform) { - param.push_back("TRANSFORM"); - } - else { //assumes if axis isn't specified all axises are added - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - } - } - break; - case COLLADASW::InputSemantic::IN_TANGENT: - case COLLADASW::InputSemantic::OUT_TANGENT: - param.push_back("X"); - param.push_back("Y"); - break; - default: - break; - } + switch (semantic) { + case COLLADASW::InputSemantic::INPUT: + param.push_back("TIME"); + break; + case COLLADASW::InputSemantic::OUTPUT: + if (is_rot) { + param.push_back("ANGLE"); + } + else { + if (axis != "") { + param.push_back(axis); + } + else if (transform) { + param.push_back("TRANSFORM"); + } + else { //assumes if axis isn't specified all axises are added + param.push_back("X"); + param.push_back("Y"); + param.push_back("Z"); + } + } + break; + case COLLADASW::InputSemantic::IN_TANGENT: + case COLLADASW::InputSemantic::OUT_TANGENT: + param.push_back("X"); + param.push_back("Y"); + break; + default: + break; + } } -std::string AnimationExporter::collada_tangent_from_curve(COLLADASW::InputSemantic::Semantics semantic, BCAnimationCurve &curve, const std::string& anim_id, std::string axis_name) +std::string AnimationExporter::collada_tangent_from_curve( + COLLADASW::InputSemantic::Semantics semantic, + BCAnimationCurve &curve, + const std::string &anim_id, + std::string axis_name) { - Scene *scene = blender_context.get_scene(); - std::string channel = curve.get_channel_target(); + Scene *scene = blender_context.get_scene(); + std::string channel = curve.get_channel_target(); - const std::string source_id = anim_id + get_semantic_suffix(semantic); + const std::string source_id = anim_id + get_semantic_suffix(semantic); - bool is_angle = (bc_startswith(channel, "rotation") || channel == "spot_size"); + bool is_angle = (bc_startswith(channel, "rotation") || channel == "spot_size"); - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(curve.sample_count()); - source.setAccessorStride(2); + COLLADASW::FloatSourceF source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(curve.sample_count()); + source.setAccessorStride(2); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, is_angle, axis_name, false); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + add_source_parameters(param, semantic, is_angle, axis_name, false); - source.prepareToAppendValues(); + source.prepareToAppendValues(); - const FCurve *fcu = curve.get_fcurve(); - int tangent = (semantic == COLLADASW::InputSemantic::IN_TANGENT) ? 0 : 2; + const FCurve *fcu = curve.get_fcurve(); + int tangent = (semantic == COLLADASW::InputSemantic::IN_TANGENT) ? 0 : 2; - for (int i = 0; i < fcu->totvert; ++i) { - BezTriple &bezt = fcu->bezt[i]; + for (int i = 0; i < fcu->totvert; ++i) { + BezTriple &bezt = fcu->bezt[i]; - float sampled_time = bezt.vec[tangent][0]; - float sampled_val = bezt.vec[tangent][1]; + float sampled_time = bezt.vec[tangent][0]; + float sampled_val = bezt.vec[tangent][1]; - if (is_angle) { - sampled_val = RAD2DEGF(sampled_val); - } + if (is_angle) { + sampled_val = RAD2DEGF(sampled_val); + } - source.appendValues(FRA2TIME(sampled_time)); - source.appendValues(sampled_val); - - } - source.finish(); - return source_id; + source.appendValues(FRA2TIME(sampled_time)); + source.appendValues(sampled_val); + } + source.finish(); + return source_id; } std::string AnimationExporter::collada_source_from_values( - BC_animation_source_type source_type, - COLLADASW::InputSemantic::Semantics semantic, - std::vector<float> &values, - const std::string& anim_id, - const std::string axis_name) + BC_animation_source_type source_type, + COLLADASW::InputSemantic::Semantics semantic, + std::vector<float> &values, + const std::string &anim_id, + const std::string axis_name) { - Scene *scene = blender_context.get_scene(); - /* T can be float, int or double */ - - int stride = 1; - int entry_count = values.size() / stride; - std::string source_id = anim_id + get_semantic_suffix(semantic); - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(entry_count); - source.setAccessorStride(stride); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, source_type== BC_SOURCE_TYPE_ANGLE, axis_name, false); - - source.prepareToAppendValues(); - - for (int i = 0; i < entry_count; i++) { - float val = values[i]; - switch (source_type) { - case BC_SOURCE_TYPE_TIMEFRAME: - val = FRA2TIME(val); - break; - case BC_SOURCE_TYPE_ANGLE: - val = RAD2DEGF(val); - break; - default: break; - } - source.appendValues(val); - } - - source.finish(); - - return source_id; + Scene *scene = blender_context.get_scene(); + /* T can be float, int or double */ + + int stride = 1; + int entry_count = values.size() / stride; + std::string source_id = anim_id + get_semantic_suffix(semantic); + + COLLADASW::FloatSourceF source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(entry_count); + source.setAccessorStride(stride); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + add_source_parameters(param, semantic, source_type == BC_SOURCE_TYPE_ANGLE, axis_name, false); + + source.prepareToAppendValues(); + + for (int i = 0; i < entry_count; i++) { + float val = values[i]; + switch (source_type) { + case BC_SOURCE_TYPE_TIMEFRAME: + val = FRA2TIME(val); + break; + case BC_SOURCE_TYPE_ANGLE: + val = RAD2DEGF(val); + break; + default: + break; + } + source.appendValues(val); + } + + source.finish(); + + return source_id; } /* * Create a collada matrix source for a set of samples */ -std::string AnimationExporter::collada_source_from_values(BCMatrixSampleMap &samples, const std::string &anim_id) +std::string AnimationExporter::collada_source_from_values(BCMatrixSampleMap &samples, + const std::string &anim_id) { - COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT; - std::string source_id = anim_id + get_semantic_suffix(semantic); - - COLLADASW::Float4x4Source source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(samples.size()); - source.setAccessorStride(16); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, false, "", true); - - source.prepareToAppendValues(); - - BCMatrixSampleMap::iterator it; - int precision = (this->export_settings->limit_precision) ? 6 : -1; // could be made configurable - for (it = samples.begin(); it != samples.end(); it++) { - const BCMatrix *sample = it->second; - double daemat[4][4]; - sample->get_matrix(daemat, true, precision); - source.appendValues(daemat); - } - - source.finish(); - return source_id; + COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT; + std::string source_id = anim_id + get_semantic_suffix(semantic); + + COLLADASW::Float4x4Source source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(samples.size()); + source.setAccessorStride(16); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + add_source_parameters(param, semantic, false, "", true); + + source.prepareToAppendValues(); + + BCMatrixSampleMap::iterator it; + int precision = (this->export_settings->limit_precision) ? 6 : -1; // could be made configurable + for (it = samples.begin(); it != samples.end(); it++) { + const BCMatrix *sample = it->second; + double daemat[4][4]; + sample->get_matrix(daemat, true, precision); + source.appendValues(daemat); + } + + source.finish(); + return source_id; } std::string AnimationExporter::collada_interpolation_source(const BCAnimationCurve &curve, - const std::string& anim_id, - const std::string axis, - bool *has_tangents) + const std::string &anim_id, + const std::string axis, + bool *has_tangents) { - std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); - - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(curve.sample_count()); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("INTERPOLATION"); - - source.prepareToAppendValues(); - - *has_tangents = false; - - std::vector<float>frames; - curve.get_frames(frames); - - for (unsigned int i = 0; i < curve.sample_count(); i++) { - float frame = frames[i]; - int ipo = curve.get_interpolation_type(frame); - if (ipo == BEZT_IPO_BEZ) { - source.appendValues(BEZIER_NAME); - *has_tangents = true; - } - else if (ipo == BEZT_IPO_CONST) { - source.appendValues(STEP_NAME); - } - else { // BEZT_IPO_LIN - source.appendValues(LINEAR_NAME); - } - } - // unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS - - source.finish(); - - return source_id; + std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); + + COLLADASW::NameSource source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(curve.sample_count()); + source.setAccessorStride(1); + + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("INTERPOLATION"); + + source.prepareToAppendValues(); + + *has_tangents = false; + + std::vector<float> frames; + curve.get_frames(frames); + + for (unsigned int i = 0; i < curve.sample_count(); i++) { + float frame = frames[i]; + int ipo = curve.get_interpolation_type(frame); + if (ipo == BEZT_IPO_BEZ) { + source.appendValues(BEZIER_NAME); + *has_tangents = true; + } + else if (ipo == BEZT_IPO_CONST) { + source.appendValues(STEP_NAME); + } + else { // BEZT_IPO_LIN + source.appendValues(LINEAR_NAME); + } + } + // unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS + + source.finish(); + + return source_id; } -std::string AnimationExporter::collada_linear_interpolation_source(int tot, const std::string& anim_id) +std::string AnimationExporter::collada_linear_interpolation_source(int tot, + const std::string &anim_id) { - std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); + std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(tot); - source.setAccessorStride(1); + COLLADASW::NameSource source(mSW); + source.setId(source_id); + source.setArrayId(source_id + ARRAY_ID_SUFFIX); + source.setAccessorCount(tot); + source.setAccessorStride(1); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("INTERPOLATION"); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("INTERPOLATION"); - source.prepareToAppendValues(); + source.prepareToAppendValues(); - for (int i = 0; i < tot; i++) { - source.appendValues(LINEAR_NAME); - } + for (int i = 0; i < tot; i++) { + source.appendValues(LINEAR_NAME); + } - source.finish(); + source.finish(); - return source_id; + return source_id; } const std::string AnimationExporter::get_collada_name(std::string channel_target) const { - /* - * Translation table to map FCurve animation types to Collada animation. - * Todo: Maybe we can keep the names from the fcurves here instead of - * mapping. However this is what i found in the old code. So keep - * this map for now. - */ - static std::map<std::string, std::string> BC_CHANNEL_BLENDER_TO_COLLADA = { - { "rotation", "rotation" }, - { "rotation_euler", "rotation" }, - { "rotation_quaternion", "rotation" }, - { "scale", "scale" }, - { "location", "location" }, - - /* Materials */ - { "specular_color", "specular" }, - { "diffuse_color", "diffuse" }, - { "ior", "index_of_refraction" }, - { "specular_hardness", "specular_hardness" }, - { "alpha", "alpha" }, - - /* Lights */ - { "color", "color" }, - { "fall_off_angle", "falloff_angle" }, - { "spot_size", "falloff_angle" }, - { "fall_off_exponent", "falloff_exponent" }, - { "spot_blend", "falloff_exponent" }, - { "blender/blender_dist", "blender/blender_dist" }, // special blender profile (todo: make this more elegant) - { "distance", "blender/blender_dist" }, // special blender profile (todo: make this more elegant) - - /* Cameras */ - { "lens", "xfov" }, - { "xfov", "xfov" }, - { "xmag", "xmag" }, - { "zfar", "zfar" }, - { "znear", "znear" }, - { "ortho_scale", "xmag" }, - { "clip_end", "zfar" }, - { "clip_start", "znear" } - }; - - std::map<std::string, std::string>::iterator name_it = BC_CHANNEL_BLENDER_TO_COLLADA.find(channel_target); - if (name_it == BC_CHANNEL_BLENDER_TO_COLLADA.end()) - return ""; - - std::string tm_name = name_it->second; - return tm_name; + /* + * Translation table to map FCurve animation types to Collada animation. + * Todo: Maybe we can keep the names from the fcurves here instead of + * mapping. However this is what i found in the old code. So keep + * this map for now. + */ + static std::map<std::string, std::string> BC_CHANNEL_BLENDER_TO_COLLADA = { + {"rotation", "rotation"}, + {"rotation_euler", "rotation"}, + {"rotation_quaternion", "rotation"}, + {"scale", "scale"}, + {"location", "location"}, + + /* Materials */ + {"specular_color", "specular"}, + {"diffuse_color", "diffuse"}, + {"ior", "index_of_refraction"}, + {"specular_hardness", "specular_hardness"}, + {"alpha", "alpha"}, + + /* Lights */ + {"color", "color"}, + {"fall_off_angle", "falloff_angle"}, + {"spot_size", "falloff_angle"}, + {"fall_off_exponent", "falloff_exponent"}, + {"spot_blend", "falloff_exponent"}, + {"blender/blender_dist", + "blender/blender_dist"}, // special blender profile (todo: make this more elegant) + {"distance", + "blender/blender_dist"}, // special blender profile (todo: make this more elegant) + + /* Cameras */ + {"lens", "xfov"}, + {"xfov", "xfov"}, + {"xmag", "xmag"}, + {"zfar", "zfar"}, + {"znear", "znear"}, + {"ortho_scale", "xmag"}, + {"clip_end", "zfar"}, + {"clip_start", "znear"}}; + + std::map<std::string, std::string>::iterator name_it = BC_CHANNEL_BLENDER_TO_COLLADA.find( + channel_target); + if (name_it == BC_CHANNEL_BLENDER_TO_COLLADA.end()) + return ""; + + std::string tm_name = name_it->second; + return tm_name; } /* * 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 AnimationExporter::get_collada_sid(const BCAnimationCurve &curve, const std::string axis_name) +std::string AnimationExporter::get_collada_sid(const BCAnimationCurve &curve, + const std::string axis_name) { - std::string channel_target = curve.get_channel_target(); - std::string tm_name = get_collada_name(channel_target); - - bool is_angle = curve.is_rotation_curve(); + std::string channel_target = curve.get_channel_target(); + std::string tm_name = get_collada_name(channel_target); + bool is_angle = curve.is_rotation_curve(); - if (tm_name.size()) { - if (is_angle) - return tm_name + std::string(axis_name) + ".ANGLE"; - else - if (axis_name != "") - return tm_name + "." + std::string(axis_name); - else - return tm_name; - } + if (tm_name.size()) { + if (is_angle) + return tm_name + std::string(axis_name) + ".ANGLE"; + else if (axis_name != "") + return tm_name + "." + std::string(axis_name); + else + return tm_name; + } - return tm_name; + return tm_name; } #ifdef WITH_MORPH_ANIMATION @@ -780,21 +806,21 @@ So we have to update BCSample for this to work. */ void AnimationExporter::export_morph_animation(Object *ob, BCAnimationSampler &sampler) { - FCurve *fcu; - Key *key = BKE_key_from_object(ob); - if (!key) return; - - if (key->adt && key->adt->action) { - fcu = (FCurve *)key->adt->action->curves.first; + FCurve *fcu; + Key *key = BKE_key_from_object(ob); + if (!key) + return; - while (fcu) { - BC_animation_transform_type tm_type = get_transform_type(fcu->rna_path); + if (key->adt && key->adt->action) { + fcu = (FCurve *)key->adt->action->curves.first; - create_keyframed_animation(ob, fcu, tm_type, true, sampler); + while (fcu) { + BC_animation_transform_type tm_type = get_transform_type(fcu->rna_path); - fcu = fcu->next; - } - } + create_keyframed_animation(ob, fcu, tm_type, true, sampler); + fcu = fcu->next; + } + } } #endif |