23 static std::map<std::string, std::vector<std::string>> BC_COLLADA_AXIS_FROM_TYPE = {
24 {
"color", {
"R",
"G",
"B"}},
25 {
"specular_color", {
"R",
"G",
"B"}},
26 {
"diffuse_color", {
"R",
"G",
"B"}},
27 {
"alpha", {
"R",
"G",
"B"}},
28 {
"scale", {
"X",
"Y",
"Z"}},
29 {
"location", {
"X",
"Y",
"Z"}},
30 {
"rotation_euler", {
"X",
"Y",
"Z"}}};
32 std::map<std::string, std::vector<std::string>>::const_iterator it;
34 it = BC_COLLADA_AXIS_FROM_TYPE.find(channel_type);
35 if (it == BC_COLLADA_AXIS_FROM_TYPE.end()) {
39 const std::vector<std::string> &subchannel = it->second;
40 if (
id >= subchannel.size()) {
43 return subchannel[id];
58 std::vector<std::string> anim_meta_entry;
60 anim_meta_entry.push_back(action_name);
75 Scene *sce = export_settings.get_scene();
77 LinkNode *export_set = this->export_settings.get_export_set();
79 int animation_count = 0;
84 animation_count = animated_subset.size();
92 BCObjectSet::iterator it;
93 for (it = animated_subset.begin(); it != animated_subset.end(); ++it) {
98 catch (std::invalid_argument &iae) {
99 fprintf(stderr,
"Animation export interrupted");
100 fprintf(stderr,
"Exception was: %s", iae.what());
110 if (this->export_settings->include_all_actions) {
116 return animation_count;
121 bool container_is_open =
false;
130 bool export_as_matrix = this->export_settings.get_animation_transformation_type() ==
133 if (export_as_matrix) {
142#ifdef WITH_MORPH_ANIMATION
159 bool export_as_matrix)
162 bool keep_flat_curves = this->export_settings.get_keep_flat_curves();
164 BCAnimationCurveMap::iterator it;
165 for (it = curves->begin(); it != curves->end(); ++it) {
168 if (channel_type ==
"rotation_quaternion") {
200 bool keep_flat_curves = this->export_settings.get_keep_flat_curves();
202 std::vector<float> frames;
204 if (!frames.empty()) {
207 if (keep_flat_curves || is_animated) {
210 std::string action_name = (action ==
nullptr) ? name +
"-action" :
id_name(action);
211 std::string channel_type =
"transform";
215 std::string target =
translate_id(name) +
'/' + channel_type;
219 id, name, target, frames, samples, global_rotation_type, ob->
parentinv);
226 bool is_export_root = this->export_settings.is_export_root(ob);
227 if (!is_export_root) {
231 bool apply_global_rotation = this->export_settings.get_apply_global_orientation();
240 bool keep_flat_curves = this->export_settings.get_keep_flat_curves();
242 std::vector<float> frames;
245 if (!frames.empty()) {
248 if (keep_flat_curves || is_animated) {
264 if (channel_type ==
"lens") {
277 BCAnimationCurveMap::iterator cit = curves.find(sensor_key);
278 if (cit != curves.end()) {
279 sensor_curve = cit->second;
282 BCValueMap::const_iterator vit;
283 for (vit = lens_values.begin(); vit != lens_values.end(); ++vit) {
284 int frame = vit->first;
285 float lens_value = vit->second;
289 sensor_value = sensor_curve->
get_value(frame);
292 sensor_value = ((
Camera *)ob->
data)->sensor_x;
316 std::string axis =
get_axis_name(channel_type, channel_index);
318 std::string action_name;
320 action_name = (action) ?
id_name(action) :
"constraint_anim";
323 std::string
id =
bc_get_action_id(action_name, curve_name, channel_target, axis,
".");
341 id, curve_name, collada_target, axis, curve, global_rotation_type);
350 std::string bone_name(bone->
name);
357 id, name, target, frames, samples, global_rotation_type, ob->
parentinv);
384 std::string collada_target,
395 stdout,
"Export animation curve %s (%d control points)\n",
id.c_str(),
int(frames.size()));
396 openAnimation(
id, name);
403 source_type, COLLADASW::InputSemantic::OUTPUT, values,
id, axis);
405 bool has_tangents =
false;
406 std::string interpolation_id;
407 if (this->export_settings.get_keep_smooth_curves()) {
414 std::string intangent_id;
415 std::string outtangent_id;
418 COLLADASW::InputSemantic::IN_TANGENT, curve,
id, axis);
420 COLLADASW::InputSemantic::OUT_TANGENT, curve,
id, axis);
423 std::string sampler_id = std::string(
id) + SAMPLER_ID_SUFFIX;
425 COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
427 sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(
EMPTY_STRING, input_id));
428 sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(
EMPTY_STRING, output_id));
429 sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION,
433 sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT,
435 sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT,
440 addChannel(COLLADABU::URI(
EMPTY_STRING, sampler_id), collada_target);
455 stdout,
"Export animation matrix %s (%d control points)\n",
id.c_str(),
int(frames.size()));
464 std::string sampler_id = std::string(
id) + SAMPLER_ID_SUFFIX;
465 COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
467 sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(
EMPTY_STRING, input_id));
468 sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(
EMPTY_STRING, output_id));
469 sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION,
475 addChannel(COLLADABU::URI(
EMPTY_STRING, sampler_id), target);
483 case COLLADASW::InputSemantic::INPUT:
484 return INPUT_SOURCE_ID_SUFFIX;
485 case COLLADASW::InputSemantic::OUTPUT:
486 return OUTPUT_SOURCE_ID_SUFFIX;
487 case COLLADASW::InputSemantic::INTERPOLATION:
488 return INTERPOLATION_SOURCE_ID_SUFFIX;
489 case COLLADASW::InputSemantic::IN_TANGENT:
490 return INTANGENT_SOURCE_ID_SUFFIX;
491 case COLLADASW::InputSemantic::OUT_TANGENT:
492 return OUTTANGENT_SOURCE_ID_SUFFIX;
500 COLLADASW::InputSemantic::Semantics semantic,
502 const std::string axis,
506 case COLLADASW::InputSemantic::INPUT:
507 param.emplace_back(
"TIME");
509 case COLLADASW::InputSemantic::OUTPUT:
511 param.emplace_back(
"ANGLE");
515 param.push_back(axis);
518 param.emplace_back(
"TRANSFORM");
522 param.emplace_back(
"X");
523 param.emplace_back(
"Y");
524 param.emplace_back(
"Z");
528 case COLLADASW::InputSemantic::IN_TANGENT:
529 case COLLADASW::InputSemantic::OUT_TANGENT:
530 param.emplace_back(
"X");
531 param.emplace_back(
"Y");
539 COLLADASW::InputSemantic::Semantics semantic,
541 const std::string &anim_id,
542 std::string axis_name)
544 Scene *scene = this->export_settings.get_scene();
550 bool is_angle = (
bc_startswith(channel,
"rotation") || channel ==
"spot_size");
552 COLLADASW::FloatSourceF source(mSW);
553 source.setId(source_id);
554 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
556 source.setAccessorStride(2);
558 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
561 source.prepareToAppendValues();
564 int tangent = (semantic == COLLADASW::InputSemantic::IN_TANGENT) ? 0 : 2;
569 float sampled_time = bezt.
vec[tangent][0];
570 float sampled_val = bezt.
vec[tangent][1];
573 sampled_val =
RAD2DEGF(sampled_val);
576 source.appendValues(
FRA2TIME(sampled_time));
577 source.appendValues(sampled_val);
585 COLLADASW::InputSemantic::Semantics semantic,
586 std::vector<float> &values,
587 const std::string &anim_id,
588 const std::string axis_name)
590 BlenderContext &blender_context = this->export_settings.get_blender_context();
595 int entry_count = values.size() / stride;
598 COLLADASW::FloatSourceF source(mSW);
599 source.setId(source_id);
600 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
601 source.setAccessorCount(entry_count);
602 source.setAccessorStride(stride);
604 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
607 source.prepareToAppendValues();
609 for (
int i = 0;
i < entry_count;
i++) {
610 float val = values[
i];
611 switch (source_type) {
621 source.appendValues(val);
631 const std::string &anim_id,
635 COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
638 COLLADASW::Float4x4Source source(mSW);
639 source.setId(source_id);
640 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
641 source.setAccessorCount(samples.size());
642 source.setAccessorStride(16);
644 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
647 source.prepareToAppendValues();
649 BCMatrixSampleMap::iterator it;
651 int precision = this->export_settings.get_limit_precision() ? 6 : -1;
652 for (it = samples.begin(); it != samples.end(); it++) {
654 BCMatrix global_transform = this->export_settings.get_global_transform();
656 if (this->export_settings.get_apply_global_orientation()) {
657 sample.apply_transform(global_transform);
660 sample.add_transform(global_transform);
662 sample.get_matrix(daemat,
true, precision);
663 source.appendValues(daemat);
671 const std::string &anim_id,
672 const std::string axis,
675 std::string source_id = anim_id +
get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
677 COLLADASW::NameSource source(mSW);
678 source.setId(source_id);
679 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
681 source.setAccessorStride(1);
683 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
684 param.emplace_back(
"INTERPOLATION");
686 source.prepareToAppendValues();
688 *has_tangents =
false;
690 std::vector<float> frames;
694 float frame = frames[
i];
697 source.appendValues(BEZIER_NAME);
698 *has_tangents =
true;
701 source.appendValues(STEP_NAME);
705 source.appendValues(LINEAR_NAME);
716 const std::string &anim_id)
718 std::string source_id = anim_id +
get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
720 COLLADASW::NameSource source(mSW);
721 source.setId(source_id);
722 source.setArrayId(source_id + ARRAY_ID_SUFFIX);
723 source.setAccessorCount(tot);
724 source.setAccessorStride(1);
726 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
727 param.emplace_back(
"INTERPOLATION");
729 source.prepareToAppendValues();
731 for (
int i = 0;
i < tot;
i++) {
732 source.appendValues(LINEAR_NAME);
748 static std::map<std::string, std::string> BC_CHANNEL_BLENDER_TO_COLLADA = {
749 {
"rotation",
"rotation"},
750 {
"rotation_euler",
"rotation"},
751 {
"rotation_quaternion",
"rotation"},
753 {
"location",
"location"},
756 {
"specular_color",
"specular"},
757 {
"diffuse_color",
"diffuse"},
758 {
"ior",
"index_of_refraction"},
759 {
"specular_hardness",
"specular_hardness"},
764 {
"fall_off_angle",
"falloff_angle"},
765 {
"spot_size",
"falloff_angle"},
766 {
"fall_off_exponent",
"falloff_exponent"},
767 {
"spot_blend",
"falloff_exponent"},
769 {
"blender/blender_dist",
"blender/blender_dist"},
771 {
"distance",
"blender/blender_dist"},
779 {
"ortho_scale",
"xmag"},
780 {
"clip_end",
"zfar"},
781 {
"clip_start",
"znear"}};
783 std::map<std::string, std::string>::iterator name_it = BC_CHANNEL_BLENDER_TO_COLLADA.find(
785 if (name_it == BC_CHANNEL_BLENDER_TO_COLLADA.end()) {
788 std::string tm_name = name_it->second;
793 const std::string axis_name)
800 if (!tm_name.empty()) {
802 return tm_name + std::string(axis_name) +
".ANGLE";
804 if (!axis_name.empty()) {
805 return tm_name +
"." + std::string(axis_name);
814#ifdef WITH_MORPH_ANIMATION
825 BC_animation_transform_type tm_type = get_transform_type(fcu->rna_path);
827 create_keyframed_animation(ob, fcu, tm_type,
true, sampler);
@ BC_SOURCE_TYPE_TIMEFRAME
std::vector< float > BCValues
std::map< BCCurveKey, BCAnimationCurve * > BCAnimationCurveMap
std::vector< float > BCFrames
@ BC_ANIMATION_TYPE_MATERIAL
@ BC_ANIMATION_TYPE_CAMERA
std::map< int, float > BCValueMap
std::map< int, const BCMatrix * > BCMatrixSampleMap
Key * BKE_key_from_object(Object *ob)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
#define LISTBASE_FOREACH(type, var, list)
float focallength_to_fov(float focal_length, float sensor)
#define SNPRINTF(dst, format,...)
@ BC_TRANSFORMATION_TYPE_MATRIX
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
void exportAnimationClips(Scene *sce)
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)
std::string get_axis_name(std::string channel, int id)
std::string collada_interpolation_source(const BCAnimationCurve &curve, const std::string &anim_id, std::string axis_name, bool *has_tangents)
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList ¶m, COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const std::string axis, bool transform)
void close_animation_container(bool has_container)
void openAnimationWithClip(std::string id, std::string name)
bool open_animation_container(bool has_container, Object *ob)
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)
void exportAnimation(Object *ob, BCAnimationSampler &sampler)
void export_matrix_animation(Object *ob, BCAnimationSampler &sampler)
void export_curve_animation_set(Object *ob, BCAnimationSampler &sampler, bool export_as_matrix)
bool is_bone_deform_group(Bone *bone)
void export_bone_animations_recursive(Object *ob_arm, Bone *bone, BCAnimationSampler &sampler)
void export_bone_animation(Object *ob, Bone *bone, BCFrames &frames, BCMatrixSampleMap &samples)
BCAnimationCurve * get_modified_export_curve(Object *ob, BCAnimationCurve &curve, BCAnimationCurveMap &curves)
void export_curve_animation(Object *ob, BCAnimationCurve &curve)
void export_morph_animation(Object *ob)
std::string get_collada_name(std::string channel_type) const
std::string collada_linear_interpolation_source(int tot, const std::string &anim_id)
std::string get_collada_sid(const BCAnimationCurve &curve, const std::string axis_name)
std::vector< std::vector< std::string > > anim_meta
std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
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_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)
FCurve * get_fcurve() const
float get_value(float frame)
void get_values(BCValues &values) const
void add_value(float val, int frame)
std::string get_channel_type() const
bool is_rotation_curve() const
void get_value_map(BCValueMap &value_map)
int get_interpolation_type(float sample_frame) const
bool is_of_animation_type(BC_animation_type type) const
void get_frames(BCFrames &frames) const
bool is_transform_curve() const
std::string get_channel_target() const
int get_channel_index() const
std::string get_animation_name(Object *ob) const
void get_object_frames(BCFrames &frames, Object *ob)
bool get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone)
static void get_animated_from_export_set(std::set< Object * > &animated_objects, LinkNode &export_set)
void get_bone_frames(BCFrames &frames, Object *ob, Bone *bone)
void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end)
bool get_object_samples(BCMatrixSampleMap &samples, Object *ob)
BCAnimationCurveMap * get_curves(Object *ob)
std::string encode_xml(const std::string &xml)
std::string translate_id(const char *idString)
std::string id_name(void *id)
bool bc_has_animations(Object *ob)
std::string bc_get_action_id(const std::string &action_name, const std::string &ob_name, const std::string &channel_type, const std::string &axis_name, const std::string &axis_separator)
bAction * bc_getSceneObjectAction(Object *ob)
std::set< Object * > BCObjectSet
bool bc_startswith(std::string const &value, std::string const &starting)
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)