Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaia Clary <gaia.clary@machinimatrix.org>2013-01-21 17:45:49 +0400
committerGaia Clary <gaia.clary@machinimatrix.org>2013-01-21 17:45:49 +0400
commitc263753d1770b5b812ea0e5c38174fa296492e2f (patch)
treefecb2a493596b9078e36c43d723d527e172a9546 /source/blender/collada/AnimationExporter.cpp
parent7d286d9a8096438e7a197a2a3f365fbb9df6a0b1 (diff)
Added gsoc-2012 collada improvements from bratwurst branch
Diffstat (limited to 'source/blender/collada/AnimationExporter.cpp')
-rw-r--r--source/blender/collada/AnimationExporter.cpp274
1 files changed, 230 insertions, 44 deletions
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 26b5edf7ea6..493d15135a7 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -24,6 +24,8 @@
#include "AnimationExporter.h"
#include "MaterialExporter.h"
+Global G;
+
template<class Functor>
void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
@@ -82,7 +84,12 @@ void AnimationExporter::operator()(Object *ob)
}
}
-
+
+ export_object_constraint_animation(ob);
+
+ //This needs to be handled by extra profiles, so postponed for now
+ //export_morph_animation(ob);
+
//Export Lamp parameter animations
if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) {
fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
@@ -134,7 +141,69 @@ void AnimationExporter::operator()(Object *ob)
fcu = fcu->next;
}
}
+ }
+
+
+}
+
+void AnimationExporter::export_object_constraint_animation(Object *ob)
+{
+ std::vector<float> fra;
+ //Takes frames of target animations
+ make_anim_frames_from_targets(ob, fra);
+
+ if (fra.size())
+ dae_baked_object_animation(fra, ob);
+}
+
+void AnimationExporter::export_morph_animation(Object *ob)
+{
+ FCurve *fcu;
+ char *transformName;
+ Key *key = BKE_key_from_object(ob);
+ if(!key) return;
+
+ if(key->adt && key->adt->action){
+ fcu = (FCurve *)key->adt->action->curves.first;
+
+ while (fcu) {
+ transformName = extract_transform_name(fcu->rna_path);
+
+ dae_animation(ob, fcu, transformName, true);
+
+ fcu = fcu->next;
+ }
+ }
+
+}
+void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<float> &frames ){
+
+ ListBase *conlist = get_active_constraints(ob);
+ if(conlist == NULL) return;
+ bConstraint *con;
+ for (con = (bConstraint*)conlist->first; con; con = con->next) {
+ ListBase targets = {NULL, NULL};
+
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+
+ if(!validateConstraints(con)) continue;
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+ Object *obtar;
+ /* get targets
+ * - constraints should use ct->matrix, not directly accessing values
+ * - ct->matrix members have not yet been calculated here!
+ */
+ cti->get_constraint_targets(con, &targets);
+ if(cti){
+ for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next){
+ obtar = ct->tar;
+ find_frames(obtar, frames);
+ }
+ }
+ }
}
}
@@ -320,6 +389,9 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
if (ma)
target = translate_id(id_name(ma)) + "-effect" +
"/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
+ //if shape key animation, this is the main problem, how to define the channel targets.
+ /*target = get_morph_id(ob) +
+ "/value" +*/
}
addChannel(COLLADABU::URI(empty, sampler_id), target);
@@ -368,18 +440,23 @@ void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, B
//char prefix[256];
FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first;
- while (fcu) {
+
+ //Check if there is a fcurve in the armature for the bone in param
+ //when baking this check is not needed, solve every bone for every frame.
+ /*while (fcu) {
std::string bone_name = getObjectBoneName(ob_arm, fcu);
int val = BLI_strcasecmp((char *)bone_name.c_str(), bone->name);
if (val == 0) break;
fcu = fcu->next;
}
- if (!(fcu)) return;
+ if (!(fcu)) return;*/
+
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
if (!pchan)
return;
+ //every inserted keyframe of bones.
find_frames(ob_arm, fra);
if (flag & ARM_RESTPOS) {
@@ -415,7 +492,8 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
// create output source
std::string output_id;
- output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
+
+ output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
// create interpolations source
std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
@@ -439,6 +517,48 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
closeAnimation();
}
+void AnimationExporter::dae_baked_object_animation(std::vector<float> &fra, Object *ob)
+{
+ std::string ob_name = id_name(ob);
+ char anim_id[200];
+
+ if (!fra.size())
+ return;
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s", (char*)translate_id(ob_name).c_str(),
+ "object_matrix");
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");
+
+ // create output source
+ std::string output_id;
+ output_id = create_4x4_source( fra, ob, NULL, anim_id);
+
+ // create interpolations source
+ std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name) + "/transform";
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+}
+
// dae_bone_animation -> add_bone_animation
// (blend this into dae_bone_animation)
void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, int tm_type, int axis, std::string ob_name, std::string bone_name)
@@ -762,7 +882,8 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
return source_id;
}
-std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob_arm, Bone *bone, const std::string& anim_id)
+
+std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object * ob, Bone *bone, const std::string& anim_id)
{
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
std::string source_id = anim_id + get_semantic_suffix(semantic);
@@ -777,74 +898,94 @@ std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Obj
add_source_parameters(param, semantic, false, NULL, true);
source.prepareToAppendValues();
-
+
bPoseChannel *parchan = NULL;
bPoseChannel *pchan = NULL;
- bPose *pose = ob_arm->pose;
+ bPoseChannel *rootchan = NULL;
+
+ if (ob->type == OB_ARMATURE ){
+ bPose *pose = ob->pose;
+ pchan = BKE_pose_channel_find_name(pose, bone->name);
+ if (!pchan)
+ return "";
- pchan = BKE_pose_channel_find_name(pose, bone->name);
-
- if (!pchan)
- return "";
-
- parchan = pchan->parent;
-
- enable_fcurves(ob_arm->adt->action, bone->name);
+ parchan = pchan->parent;
+ enable_fcurves(ob->adt->action, bone->name);
+ }
+
std::vector<float>::iterator it;
int j = 0;
for (it = frames.begin(); it != frames.end(); it++) {
float mat[4][4], ipar[4][4];
-
+
float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
-
- BKE_animsys_evaluate_animdata(scene, &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
- BKE_pose_where_is_bone(scene, ob_arm, pchan, ctime, 1);
-
- // compute bone local mat
- if (bone->parent) {
- invert_m4_m4(ipar, parchan->pose_mat);
- mult_m4_m4m4(mat, ipar, pchan->pose_mat);
- }
- else
- copy_m4_m4(mat, pchan->pose_mat);
- UnitConverter converter;
-
+ CFRA = BKE_scene_frame_get_from_ctime(scene, *it);
+ //BKE_scene_update_for_newframe(G.main,scene,scene->lay);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
+
+ if (bone){
+ if( pchan->flag & POSE_CHAIN)
+ {
+ enable_fcurves(ob->adt->action, NULL);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
+ BKE_pose_where_is(scene, ob);
+ }
+ else
+ BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);
+
+ // compute bone local mat
+ if (bone->parent) {
+ invert_m4_m4(ipar, parchan->pose_mat);
+ mult_m4_m4m4(mat, ipar, pchan->pose_mat);
+ }
+ else
+ copy_m4_m4(mat, pchan->pose_mat);
+
// SECOND_LIFE_COMPATIBILITY
// AFAIK animation to second life is via BVH, but no
// reason to not have the collada-animation be correct
- if (export_settings->second_life) {
- float temp[4][4];
- copy_m4_m4(temp, bone->arm_mat);
- temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
- invert_m4(temp);
+ if (export_settings->second_life) {
+ float temp[4][4];
+ copy_m4_m4(temp, bone->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+ invert_m4(temp);
- mult_m4_m4m4(mat, mat, temp);
+ mult_m4_m4m4(mat, mat, temp);
- if (bone->parent) {
- copy_m4_m4(temp, bone->parent->arm_mat);
- temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
+ if (bone->parent) {
+ copy_m4_m4(temp, bone->parent->arm_mat);
+ temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
- mult_m4_m4m4(mat, temp, mat);
+ mult_m4_m4m4(mat, temp, mat);
+ }
}
- }
- float outmat[4][4];
- converter.mat4_to_dae(outmat, mat);
+ }
+ else {
+ calc_ob_mat_at_time(ob, ctime, mat);
+ }
+
+ UnitConverter converter;
+ double outmat[4][4];
+ converter.mat4_to_dae_double(outmat, mat);
source.appendValues(outmat);
-
j++;
+
+ BIK_release_tree(scene, ob, ctime);
}
- enable_fcurves(ob_arm->adt->action, NULL);
+ enable_fcurves(ob->adt->action, NULL);
source.finish();
return source_id;
}
+
+
// only used for sources with OUTPUT semantic ( locations and scale)
std::string AnimationExporter::create_xyz_source(float *v, int tot, const std::string& anim_id)
{
@@ -1184,6 +1325,12 @@ bool AnimationExporter::hasAnimations(Scene *sce)
}
}
+ //check shape key animation
+ if(!fcu){
+ Key *key = BKE_key_from_object(ob);
+ if(key && key->adt && key->adt->action)
+ fcu = (FCurve *)key->adt->action->curves.first;
+ }
if (fcu)
return true;
}
@@ -1351,3 +1498,42 @@ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, i
enable_fcurves(ob_arm->adt->action, NULL);
}
+
+bool AnimationExporter::validateConstraints(bConstraint *con){
+
+ bool valid = true;
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+ /* these we can skip completely (invalid constraints...) */
+ if (cti == NULL) valid = false;
+ if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) valid = false;
+ /* these constraints can't be evaluated anyway */
+ if (cti->evaluate_constraint == NULL) valid = false;
+ /* influence == 0 should be ignored */
+ if (con->enforce == 0.0f) valid = false;
+
+ return valid;
+}
+
+void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4]){
+ ListBase *conlist = get_active_constraints(ob);
+ bConstraint *con;
+ for (con = (bConstraint*)conlist->first; con; con = con->next) {
+ ListBase targets = {NULL, NULL};
+
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+ Object *obtar;
+ cti->get_constraint_targets(con, &targets);
+ for (ct = (bConstraintTarget*)targets.first; ct; ct = ct->next){
+ obtar = ct->tar;
+ BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM);
+ BKE_object_where_is_calc_time(scene, obtar, ctime);
+ }
+ }
+ }
+ BKE_object_where_is_calc_time(scene, ob, ctime);
+ copy_m4_m4(mat, ob->obmat);
+}
+