Merge branch 'master' into blender2.8
[blender.git] / source / blender / collada / AnimationExporter.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #include "GeometryExporter.h"
24 #include "AnimationExporter.h"
25 #include "MaterialExporter.h"
26
27 template<class Functor>
28 void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
29 {
30         LinkNode *node;
31         for (node = export_set; node; node = node->next) {
32                 Object *ob = (Object *)node->link;
33                 f(ob);
34         }
35 }
36
37 bool AnimationExporter::exportAnimations(EvaluationContext *eval_ctx, Scene *sce)
38 {
39         bool has_animations = hasAnimations(sce);
40         if (has_animations) {
41                 this->eval_ctx = eval_ctx;
42                 this->scene = sce;
43
44                 openLibrary();
45
46                 forEachObjectInExportSet(sce, *this, this->export_settings->export_set);
47
48                 closeLibrary();
49         }
50         return has_animations;
51 }
52
53 bool AnimationExporter::is_flat_line(std::vector<float> &values, int channel_count)
54 {
55         for (int i = 0; i < values.size(); i += channel_count) {
56                 for (int j = 0; j < channel_count; j++) {
57                         if (!bc_in_range(values[j], values[i+j], 0.000001))
58                                 return false;
59                 }
60         }
61         return true;
62 }
63 /*
64  *  This function creates a complete LINEAR Collada <Animation> Entry with all needed 
65  *  <source>, <sampler>, and <channel> entries.
66  *  This is is used for creating sampled Transformation Animations for either:
67  *
68  *              1-axis animation:
69  *                  times contains the time points in seconds from within the timeline
70  *                      values contains the data (list of single floats)
71  *                      channel_count = 1
72  *                      axis_name = ['X' | 'Y' | 'Z']
73  *                      is_rot indicates if the animation is a rotation
74  *
75  *              3-axis animation:
76  *                      times contains the time points in seconds from within the timeline
77  *                      values contains the data (list of floats where each 3 entries are one vector)
78  *                      channel_count = 3
79  *                      axis_name = "" (actually not used)
80  *                      is_rot = false (see xxx below)
81  *
82  *      xxx: I tried to create a 3 axis rotation animation 
83  *               like for translation or scale. But i could not 
84  *               figure out how to setup the channel for this case.
85  *               So for now rotations are exported as 3 separate 1-axis collada animations
86  *               See export_sampled_animation() further down.
87  */
88 void AnimationExporter::create_sampled_animation(int channel_count,
89         std::vector<float> &times,
90         std::vector<float> &values,
91         std::string ob_name,
92         std::string label,
93         std::string axis_name,
94         bool is_rot)
95 {
96         char anim_id[200];
97
98         if (is_flat_line(values, channel_count))
99                 return;
100
101         BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), label.c_str(), axis_name.c_str());
102
103         openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
104
105         /* create input source */
106         std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, times, false, anim_id, "");
107
108         /* create output source */
109         std::string output_id;
110         if (channel_count == 1)
111                 output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, &values[0], values.size(), is_rot, anim_id, axis_name.c_str());
112         else if (channel_count == 3)
113                 output_id = create_xyz_source(&values[0], times.size(), anim_id);
114         else if (channel_count == 16)
115                 output_id = create_4x4_source(times, values, anim_id);
116
117         std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
118         COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
119         std::string empty;
120         sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
121         sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
122
123         /* TODO create in/out tangents source (LINEAR) */
124         std::string interpolation_id = fake_interpolation_source(times.size(), anim_id, "");
125
126         /* Create Sampler */
127         sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
128         addSampler(sampler);
129
130         /* Create channel */
131         std::string target = translate_id(ob_name) + "/" + label + axis_name + ((is_rot) ? ".ANGLE" : "");
132         addChannel(COLLADABU::URI(empty, sampler_id), target);
133
134         closeAnimation();
135
136 }
137
138 /*
139  * Export all animation FCurves of an Object.
140  *
141  * Note: This uses the keyframes as sample points,
142  * and exports "baked keyframes" while keeping the tangent infromation
143  * of the FCurves intact. This works for simple cases, but breaks
144  * especially when negative scales are involved in the animation.
145  *
146  * If it is necessary to conserve the Animation precisely then
147  * use export_sampled_animation_set() instead.
148  */
149 void AnimationExporter::export_keyframed_animation_set(Object *ob)
150 {
151         FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
152         if (!fcu) {
153                 return; /* object has no animation */
154         }
155
156         if (this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
157
158                 std::vector<float> ctimes;
159                 std::vector<float[4][4]> values;
160                 find_keyframes(ob, ctimes);
161                 if (ctimes.size() > 0)
162                         export_sampled_matrix_animation(ob, ctimes);
163         }
164         else {
165                 char *transformName;
166                 while (fcu) {
167                         //for armature animations as objects
168                         if (ob->type == OB_ARMATURE)
169                                 transformName = fcu->rna_path;
170                         else
171                                 transformName = extract_transform_name(fcu->rna_path);
172
173                         if (
174                                 STREQ(transformName, "location") ||
175                                 STREQ(transformName, "scale") ||
176                                 (STREQ(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
177                                 STREQ(transformName, "rotation_quaternion"))
178                         {
179                                 create_keyframed_animation(ob, fcu, transformName, false);
180                         }
181                         fcu = fcu->next;
182                 }
183         }
184 }
185
186 /*
187  * Export the sampled animation of an Object.
188  *
189  * Note: This steps over all animation frames (step size is given in export_settings.sample_size)
190  * and then evaluates the transformation,
191  * and exports "baked samples" This works always, however currently the interpolation type is set
192  * to LINEAR for now. (maybe later this can be changed to BEZIER)
193  *
194  * Note: If it is necessary to keep the FCurves intact, then use export_keyframed_animation_set() instead.
195  * However be aware that exporting keyframed animation may modify the animation slightly.
196  * Also keyframed animation exports tend to break when negative scales are involved.
197  */
198 void AnimationExporter::export_sampled_animation_set(Object *ob)
199 {
200         std::vector<float>ctimes;
201         find_sampleframes(ob, ctimes);
202         if (ctimes.size() > 0) {
203                 if (this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX)
204                         export_sampled_matrix_animation(ob, ctimes);
205                 else
206                         export_sampled_transrotloc_animation(ob, ctimes);
207         }
208 }
209
210 void AnimationExporter::export_sampled_matrix_animation(Object *ob, std::vector<float> &ctimes)
211 {
212         UnitConverter converter;
213
214         std::vector<float> values;
215
216         for (std::vector<float>::iterator ctime = ctimes.begin(); ctime != ctimes.end(); ++ctime) {
217                 float fmat[4][4];
218                 float outmat[4][4];
219
220                 bc_update_scene(eval_ctx, scene, *ctime);
221                 BKE_object_matrix_local_get(ob, fmat);
222
223                 converter.mat4_to_dae(outmat, fmat);
224
225                 if (this->export_settings->limit_precision)
226                         bc_sanitize_mat(outmat, 6);
227
228                 for (int i = 0; i < 4; i++)
229                         for (int j = 0; j < 4; j++)
230                                 values.push_back(outmat[j][i]);
231         }
232
233         std::string ob_name = id_name(ob);
234
235         create_sampled_animation(16, ctimes, values, ob_name, "transform", "", false);
236 }
237
238 void AnimationExporter::export_sampled_transrotloc_animation(Object *ob, std::vector<float> &ctimes)
239 {
240         static int LOC   = 0;
241         static int EULX  = 1;
242         static int EULY  = 2;
243         static int EULZ  = 3;
244         static int SCALE = 4;
245
246         std::vector<float> baked_curves[5];
247
248         for (std::vector<float>::iterator ctime = ctimes.begin(); ctime != ctimes.end(); ++ctime ) {
249                 float fmat[4][4];
250                 float floc[3];
251                 float fquat[4];
252                 float fsize[3];
253                 float feul[3];
254
255                 bc_update_scene(eval_ctx, scene, *ctime);
256
257                 BKE_object_matrix_local_get(ob, fmat);
258                 mat4_decompose(floc, fquat, fsize, fmat);
259                 quat_to_eul(feul, fquat);
260
261                 baked_curves[LOC].push_back(floc[0]);
262                 baked_curves[LOC].push_back(floc[1]);
263                 baked_curves[LOC].push_back(floc[2]);
264
265                 baked_curves[EULX].push_back(feul[0]);
266                 baked_curves[EULY].push_back(feul[1]);
267                 baked_curves[EULZ].push_back(feul[2]);
268
269                 baked_curves[SCALE].push_back(fsize[0]);
270                 baked_curves[SCALE].push_back(fsize[1]);
271                 baked_curves[SCALE].push_back(fsize[2]);
272
273         }
274
275         std::string ob_name = id_name(ob);
276
277         create_sampled_animation(3, ctimes, baked_curves[SCALE], ob_name, "scale",   "", false);
278         create_sampled_animation(3, ctimes, baked_curves[LOC],  ob_name, "location", "", false);
279
280         /* Not sure how to export rotation as a 3channel animation, 
281          * so separate into 3 single animations for now:
282          */
283
284         create_sampled_animation(1, ctimes, baked_curves[EULX], ob_name, "rotation", "X", true);
285         create_sampled_animation(1, ctimes, baked_curves[EULY], ob_name, "rotation", "Y", true);
286         create_sampled_animation(1, ctimes, baked_curves[EULZ], ob_name, "rotation", "Z", true);
287
288         fprintf(stdout, "Animation Export: Baked %d frames for %s (sampling rate: %d)\n",
289                 (int)baked_curves[0].size(),
290                 ob->id.name,
291                 this->export_settings->sampling_rate);
292 }
293
294 /* called for each exported object */
295 void AnimationExporter::operator()(Object *ob)
296 {
297         char *transformName;
298
299         /* bool isMatAnim = false; */ /* UNUSED */
300
301         //Export transform animations
302         if (ob->adt && ob->adt->action) {
303
304                 if (ob->type == OB_ARMATURE) {
305                         /* Export skeletal animation (if any)*/
306                         bArmature *arm = (bArmature *)ob->data;
307                         for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next)
308                                 write_bone_animation_matrix(ob, bone);
309                 }
310
311                 /* Armatures can have object animation and skeletal animation*/
312                 if (this->export_settings->sampling_rate < 1) {
313                         export_keyframed_animation_set(ob);
314                 }
315                 else {
316                         export_sampled_animation_set(ob);
317                 }
318         }
319
320         export_object_constraint_animation(ob);
321
322         //This needs to be handled by extra profiles, so postponed for now
323         //export_morph_animation(ob);
324                 
325         //Export Lamp parameter animations
326         if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) {
327                 FCurve *fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
328                 while (fcu) {
329                         transformName = extract_transform_name(fcu->rna_path);
330
331                         if ((STREQ(transformName, "color")) || (STREQ(transformName, "spot_size")) ||
332                             (STREQ(transformName, "spot_blend")) || (STREQ(transformName, "distance")))
333                         {
334                                 create_keyframed_animation(ob, fcu, transformName, true);
335                         }
336                         fcu = fcu->next;
337                 }
338         }
339
340         //Export Camera parameter animations
341         if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action) {
342                 FCurve *fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first);
343                 while (fcu) {
344                         transformName = extract_transform_name(fcu->rna_path);
345
346                         if ((STREQ(transformName, "lens")) ||
347                             (STREQ(transformName, "ortho_scale")) ||
348                             (STREQ(transformName, "clip_end")) || 
349                                 (STREQ(transformName, "clip_start")))
350                         {
351                                 create_keyframed_animation(ob, fcu, transformName, true);
352                         }
353                         fcu = fcu->next;
354                 }
355         }
356
357         //Export Material parameter animations.
358         for (int a = 0; a < ob->totcol; a++) {
359                 Material *ma = give_current_material(ob, a + 1);
360                 if (!ma) continue;
361                 if (ma->adt && ma->adt->action) {
362                         /* isMatAnim = true; */
363                         FCurve *fcu = (FCurve *)ma->adt->action->curves.first;
364                         while (fcu) {
365                                 transformName = extract_transform_name(fcu->rna_path);
366
367                                 if ((STREQ(transformName, "specular_hardness")) || (STREQ(transformName, "specular_color")) ||
368                                     (STREQ(transformName, "diffuse_color")) || (STREQ(transformName, "alpha")) ||
369                                     (STREQ(transformName, "ior")))
370                                 {
371                                         create_keyframed_animation(ob, fcu, transformName, true, ma);
372                                 }
373                                 fcu = fcu->next;
374                         }
375                 }
376         }
377 }
378
379 void AnimationExporter::export_object_constraint_animation(Object *ob)
380 {
381         std::vector<float> fra;
382         //Takes frames of target animations
383         make_anim_frames_from_targets(ob, fra);
384
385         if (fra.size())
386                 dae_baked_object_animation(fra, ob);
387 }
388
389 void AnimationExporter::export_morph_animation(Object *ob)
390
391         FCurve *fcu;
392         char *transformName;
393         Key *key = BKE_key_from_object(ob);
394         if (!key) return;
395
396         if (key->adt && key->adt->action) {
397                 fcu = (FCurve *)key->adt->action->curves.first;
398                 
399                 while (fcu) {
400                         transformName = extract_transform_name(fcu->rna_path);
401
402                         create_keyframed_animation(ob, fcu, transformName, true);
403                         
404                         fcu = fcu->next;
405                 }
406         }
407
408 }
409
410 void AnimationExporter::make_anim_frames_from_targets(Object *ob, std::vector<float> &frames )
411 {
412         ListBase *conlist = get_active_constraints(this->eval_ctx, ob);
413         if (conlist == NULL) return;
414         bConstraint *con;
415         for (con = (bConstraint *)conlist->first; con; con = con->next) {
416                 ListBase targets = {NULL, NULL};
417                 
418                 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
419                 
420                 if (!validateConstraints(con)) continue;
421
422                 if (cti && cti->get_constraint_targets) {
423                         bConstraintTarget *ct;
424                         Object *obtar;
425                         /* get targets 
426                          *  - constraints should use ct->matrix, not directly accessing values
427                          *      - ct->matrix members have not yet been calculated here! 
428                          */
429                         cti->get_constraint_targets(con, &targets);
430
431                         for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
432                                 obtar = ct->tar;
433
434                                 if (obtar)
435                                         find_keyframes(obtar, frames);
436                         }
437
438                         if (cti->flush_constraint_targets)
439                                 cti->flush_constraint_targets(con, &targets, 1);
440                 }
441         }
442 }
443
444 //euler sources from quternion sources
445 float *AnimationExporter::get_eul_source_for_quat(Object *ob)
446 {
447         FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
448         const int keys = fcu->totvert;  
449         float *quat = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 4, "quat output source values");
450         float *eul = (float *)MEM_callocN(sizeof(float) * fcu->totvert * 3, "quat output source values");
451         float temp_quat[4];
452         float temp_eul[3];
453         while (fcu) {
454                 char *transformName = extract_transform_name(fcu->rna_path);
455
456                 if (STREQ(transformName, "rotation_quaternion") ) {
457                         for (int i = 0; i < fcu->totvert; i++) {
458                                 *(quat + (i * 4) + fcu->array_index) = fcu->bezt[i].vec[1][1];
459                         }
460                 }
461                 fcu = fcu->next;
462         }
463
464         for (int i = 0; i < keys; i++) {
465                 for (int j = 0; j < 4; j++)
466                         temp_quat[j] = quat[(i * 4) + j];
467
468                 quat_to_eul(temp_eul, temp_quat);
469
470                 for (int k = 0; k < 3; k++)
471                         eul[i * 3 + k] = temp_eul[k];
472
473         }
474         MEM_freeN(quat);
475         return eul;
476
477 }
478
479 //Get proper name for bones
480 std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu)
481 {
482         //hard-way to derive the bone name from rna_path. Must find more compact method
483         std::string rna_path = std::string(fcu->rna_path);
484
485         char *boneName = strtok((char *)rna_path.c_str(), "\"");
486         boneName = strtok(NULL, "\"");
487
488         if (boneName != NULL)
489                 return /*id_name(ob) + "_" +*/ std::string(boneName);
490         else
491                 return id_name(ob);
492 }
493
494 std::string AnimationExporter::getAnimationPathId(const FCurve *fcu)
495 {
496         std::string rna_path = std::string(fcu->rna_path);
497         return translate_id(rna_path);
498 }
499
500 /* convert f-curves to animation curves and write */
501 void AnimationExporter::create_keyframed_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma)
502 {
503         const char *axis_name = NULL;
504         char anim_id[200];
505
506         bool has_tangents = false;
507         bool quatRotation = false;
508
509         Object *obj = NULL;
510
511         if (STREQ(transformName, "rotation_quaternion") ) {
512                 fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n");
513                 quatRotation = true;
514                 return;
515         }
516
517         //axis names for colors
518         else if (STREQ(transformName, "color") ||
519                  STREQ(transformName, "specular_color") ||
520                  STREQ(transformName, "diffuse_color") ||
521                  STREQ(transformName, "alpha"))
522         {
523                 const char *axis_names[] = {"R", "G", "B"};
524                 if (fcu->array_index < 3)
525                         axis_name = axis_names[fcu->array_index];
526         }
527
528         /*
529          * Note: Handle transformation animations separately (to apply matrix inverse to fcurves)
530          * We will use the object to evaluate the animation on all keyframes and calculate the 
531          * resulting object matrix. We need this to incorporate the
532          * effects of the parent inverse matrix (when it contains a rotation component)
533          *
534          * TODO: try to combine exported fcurves into 3 channel animations like done 
535          * in export_sampled_animation(). For now each channel is exported as separate <Animation>.
536          */
537
538         else if (
539                 STREQ(transformName, "scale") ||
540                 STREQ(transformName, "location") ||
541                 STREQ(transformName, "rotation_euler"))
542         {
543                 const char *axis_names[] = {"X", "Y", "Z"};
544                 if (fcu->array_index < 3) {
545                         axis_name = axis_names[fcu->array_index];
546                         obj = ob;
547                 }
548         }
549         else {
550                 /* no axis name. single parameter */
551                 axis_name = "";
552         }
553
554         std::string ob_name = std::string("null");
555
556         /* Create anim Id */
557         if (ob->type == OB_ARMATURE) {
558                 ob_name =  getObjectBoneName(ob, fcu);
559                 BLI_snprintf(
560                         anim_id,
561                         sizeof(anim_id),
562                         "%s_%s.%s",
563                         (char *)translate_id(ob_name).c_str(),
564                         (char *)translate_id(transformName).c_str(),
565                         axis_name);
566         }
567         else {
568                 if (ma)
569                         ob_name = id_name(ob) + "_material";
570                 else
571                         ob_name = id_name(ob);
572
573                 BLI_snprintf(
574                         anim_id,
575                         sizeof(anim_id),
576                         "%s_%s_%s",
577                         (char *)translate_id(ob_name).c_str(),
578                         (char *)getAnimationPathId(fcu).c_str(),
579                         axis_name);
580         }
581
582         openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
583
584         // create input source
585         std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);
586
587         // create output source
588         std::string output_id;
589
590         //quat rotations are skipped for now, because of complications with determining axis.
591         if (quatRotation) {
592                 float *eul  = get_eul_source_for_quat(ob);
593                 float *eul_axis = (float *)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values");
594                 for (int i = 0; i < fcu->totvert; i++) {
595                         eul_axis[i] = eul[i * 3 + fcu->array_index];
596                 }
597                 output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name);
598                 MEM_freeN(eul);
599                 MEM_freeN(eul_axis);
600         }
601         else if (STREQ(transformName, "lens") && (ob->type == OB_CAMERA)) {
602                 output_id = create_lens_source_from_fcurve((Camera *) ob->data, COLLADASW::InputSemantic::OUTPUT, fcu, anim_id);
603         }
604         else {
605                 output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name, obj);
606         }
607
608         // create interpolations source
609         std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);
610
611         // handle tangents (if required)
612         std::string intangent_id;
613         std::string outtangent_id;
614
615         if (has_tangents) {
616                 // create in_tangent source
617                 intangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::IN_TANGENT, fcu, anim_id, axis_name, obj);
618
619                 // create out_tangent source
620                 outtangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUT_TANGENT, fcu, anim_id, axis_name, obj);
621         }
622
623         std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
624         COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
625         std::string empty;
626         sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
627         sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
628
629         // this input is required
630         sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
631
632         if (has_tangents) {
633                 sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(empty, intangent_id));
634                 sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(empty, outtangent_id));
635         }
636
637         addSampler(sampler);
638
639         std::string target;
640
641         if (!is_param)
642                 target = translate_id(ob_name) +
643                          "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
644         else {
645                 if (ob->type == OB_LAMP)
646                         target = get_light_id(ob) +
647                                  "/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true);
648
649                 if (ob->type == OB_CAMERA)
650                         target = get_camera_id(ob) +
651                                  "/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true);
652
653                 if (ma)
654                         target = translate_id(id_name(ma)) + "-effect" +
655                                  "/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true);
656                 //if shape key animation, this is the main problem, how to define the channel targets.
657                 /*target = get_morph_id(ob) +
658                                  "/value" +*/ 
659         }
660         addChannel(COLLADABU::URI(empty, sampler_id), target);
661
662         closeAnimation();
663 }
664
665
666
667 //write bone animations in transform matrix sources
668 void AnimationExporter::write_bone_animation_matrix(Object *ob_arm, Bone *bone)
669 {
670         if (!ob_arm->adt)
671                 return;
672
673         //This will only export animations of bones in deform group.
674         /* if (!is_bone_deform_group(bone)) return; */
675
676         sample_and_write_bone_animation_matrix(ob_arm, bone);
677
678         for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next)
679                 write_bone_animation_matrix(ob_arm, child);
680 }
681
682 bool AnimationExporter::is_bone_deform_group(Bone *bone)
683 {   
684         bool is_def;
685         //Check if current bone is deform
686         if ((bone->flag & BONE_NO_DEFORM) == 0) return true;
687         //Check child bones
688         else {
689                 for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
690                         //loop through all the children until deform bone is found, and then return
691                         is_def = is_bone_deform_group(child);
692                         if (is_def) return true;
693                 }
694         }
695         //no deform bone found in children also
696         return false;
697 }
698
699 void AnimationExporter::sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone)
700 {
701         bArmature *arm = (bArmature *)ob_arm->data;
702         int flag = arm->flag;
703         std::vector<float> fra;
704         //char prefix[256];
705
706         //Check if there is a fcurve in the armature for the bone in param
707         //when baking this check is not needed, solve every bone for every frame.
708         /*FCurve *fcu = (FCurve *)ob_arm->adt->action->curves.first;
709
710         while (fcu) {
711                 std::string bone_name = getObjectBoneName(ob_arm, fcu);
712                 int val = BLI_strcasecmp((char *)bone_name.c_str(), bone->name);
713                 if (val == 0) break;
714                 fcu = fcu->next;
715         }
716
717         if (!(fcu)) return;*/ 
718
719         bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
720         if (!pchan)
721                 return;
722
723
724         if (this->export_settings->sampling_rate < 1)
725                 find_keyframes(ob_arm, fra);
726         else
727                 find_sampleframes(ob_arm, fra);
728
729         if (flag & ARM_RESTPOS) {
730                 arm->flag &= ~ARM_RESTPOS;
731                 BKE_pose_where_is(eval_ctx, scene, ob_arm);
732         }
733
734         if (fra.size()) {
735                 dae_baked_animation(fra, ob_arm, bone);
736         }
737
738         if (flag & ARM_RESTPOS) 
739                 arm->flag = flag;
740         BKE_pose_where_is(eval_ctx, scene, ob_arm);
741 }
742
743 void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone)
744 {
745         std::string ob_name = id_name(ob_arm);
746         std::string bone_name = bone->name;
747         char anim_id[200];
748
749         if (!fra.size())
750                 return;
751
752         BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
753                      (char *)translate_id(bone_name).c_str(), "pose_matrix");
754
755         openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
756
757         // create input source
758         std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");
759
760         // create output source
761         std::string output_id;
762
763         output_id = create_4x4_source(fra, ob_arm, bone, anim_id);
764
765         // create interpolations source
766         std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
767
768         std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
769         COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
770         std::string empty;
771         sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
772         sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
773
774         // TODO create in/out tangents source
775
776         // this input is required
777         sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
778
779         addSampler(sampler);
780
781         std::string target = get_joint_id(bone, ob_arm) + "/transform";
782         addChannel(COLLADABU::URI(empty, sampler_id), target);
783
784         closeAnimation();
785 }
786
787 void AnimationExporter::dae_baked_object_animation(std::vector<float> &fra, Object *ob)
788 {
789         std::string ob_name = id_name(ob);
790         char anim_id[200];
791
792         if (!fra.size())
793                 return;
794
795         BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s", (char *)translate_id(ob_name).c_str(),
796                      "object_matrix");
797
798         openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
799
800         // create input source
801         std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, "");
802
803         // create output source
804         std::string output_id;
805         output_id = create_4x4_source( fra, ob, NULL, anim_id);
806
807         // create interpolations source
808         std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, "");
809
810         std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
811         COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
812         std::string empty;
813         sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
814         sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
815
816         // TODO create in/out tangents source
817
818         // this input is required
819         sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
820
821         addSampler(sampler);
822
823         std::string target = translate_id(ob_name) + "/transform";
824         addChannel(COLLADABU::URI(empty, sampler_id), target);
825
826         closeAnimation();
827 }
828
829 // dae_bone_animation -> add_bone_animation
830 // (blend this into dae_bone_animation)
831 void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, int tm_type, int axis, std::string ob_name, std::string bone_name)
832 {
833         const char *axis_names[] = {"X", "Y", "Z"};
834         const char *axis_name = NULL;
835         char anim_id[200];
836         bool is_rot = tm_type == 0;
837
838         if (!fra.size())
839                 return;
840
841         char rna_path[200];
842         BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
843                      tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
844
845         if (axis > -1)
846                 axis_name = axis_names[axis];
847
848         std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false);
849
850         BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
851                      (char *)translate_id(bone_name).c_str(), (char *)transform_sid.c_str());
852
853         openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
854
855         // create input source
856         std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, is_rot, anim_id, axis_name);
857
858         // create output source
859         std::string output_id;
860         if (axis == -1)
861                 output_id = create_xyz_source(values, fra.size(), anim_id);
862         else
863                 output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, values, fra.size(), is_rot, anim_id, axis_name);
864
865         // create interpolations source
866         std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, axis_name);
867
868         std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
869         COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
870         std::string empty;
871         sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
872         sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
873
874         // TODO create in/out tangents source
875
876         // this input is required
877         sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
878
879         addSampler(sampler);
880
881         std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
882         addChannel(COLLADABU::URI(empty, sampler_id), target);
883
884         closeAnimation();
885 }
886
887 float AnimationExporter::convert_time(float frame)
888 {
889         return FRA2TIME(frame);
890 }
891
892 float AnimationExporter::convert_angle(float angle)
893 {
894         return COLLADABU::Math::Utils::radToDegF(angle);
895 }
896
897 std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
898 {
899         switch (semantic) {
900                 case COLLADASW::InputSemantic::INPUT:
901                         return INPUT_SOURCE_ID_SUFFIX;
902                 case COLLADASW::InputSemantic::OUTPUT:
903                         return OUTPUT_SOURCE_ID_SUFFIX;
904                 case COLLADASW::InputSemantic::INTERPOLATION:
905                         return INTERPOLATION_SOURCE_ID_SUFFIX;
906                 case COLLADASW::InputSemantic::IN_TANGENT:
907                         return INTANGENT_SOURCE_ID_SUFFIX;
908                 case COLLADASW::InputSemantic::OUT_TANGENT:
909                         return OUTTANGENT_SOURCE_ID_SUFFIX;
910                 default:
911                         break;
912         }
913         return "";
914 }
915
916 void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
917                                               COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform)
918 {
919         switch (semantic) {
920                 case COLLADASW::InputSemantic::INPUT:
921                         param.push_back("TIME");
922                         break;
923                 case COLLADASW::InputSemantic::OUTPUT:
924                         if (is_rot) {
925                                 param.push_back("ANGLE");
926                         }
927                         else {
928                                 if (axis) {
929                                         param.push_back(axis);
930                                 }
931                                 else 
932                                 if (transform) {
933                                         param.push_back("TRANSFORM");
934                                 }
935                                 else {     //assumes if axis isn't specified all axises are added
936                                         param.push_back("X");
937                                         param.push_back("Y");
938                                         param.push_back("Z");
939                                 }
940                         }
941                         break;
942                 case COLLADASW::InputSemantic::IN_TANGENT:
943                 case COLLADASW::InputSemantic::OUT_TANGENT:
944                         param.push_back("X");
945                         param.push_back("Y");
946                         break;
947                 default:
948                         break;
949         }
950 }
951
952 void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool is_angle, float *values, int *length)
953 {
954         switch (semantic) {
955                 case COLLADASW::InputSemantic::INPUT:
956                         *length = 1;
957                         values[0] = convert_time(bezt->vec[1][0]);
958                         break;
959                 case COLLADASW::InputSemantic::OUTPUT:
960                         *length = 1;
961                         if (is_angle) {
962                                 values[0] = RAD2DEGF(bezt->vec[1][1]);
963                         }
964                         else {
965                                 values[0] = bezt->vec[1][1];
966                         }
967                         break;
968
969                 case COLLADASW::InputSemantic::IN_TANGENT:
970                         *length = 2;
971                         values[0] = convert_time(bezt->vec[0][0]);
972                         if (bezt->ipo != BEZT_IPO_BEZ) {
973                                 // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
974                                 values[0] = 0;
975                                 values[1] = 0;
976                         }
977                         else if (is_angle) {
978                                 values[1] = RAD2DEGF(bezt->vec[0][1]);
979                         }
980                         else {
981                                 values[1] = bezt->vec[0][1];
982                         }
983                         break;
984
985                 case COLLADASW::InputSemantic::OUT_TANGENT:
986                         *length = 2;
987                         values[0] = convert_time(bezt->vec[2][0]);
988                         if (bezt->ipo != BEZT_IPO_BEZ) {
989                                 // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
990                                 values[0] = 0;
991                                 values[1] = 0;
992                         }
993                         else if (is_angle) {
994                                 values[1] = RAD2DEGF(bezt->vec[2][1]);
995                         }
996                         else {
997                                 values[1] = bezt->vec[2][1];
998                         }
999                         break;
1000                 default:
1001                         *length = 0;
1002                         break;
1003         }
1004 }
1005
1006 // old function to keep compatibility for calls where offset and object are not needed
1007 std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
1008 {
1009         return create_source_from_fcurve(semantic, fcu, anim_id, axis_name, NULL);
1010 }
1011
1012 void AnimationExporter::evaluate_anim_with_constraints(Object *ob, float ctime)
1013 {
1014         BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
1015         ListBase *conlist = get_active_constraints(this->eval_ctx, ob);
1016         bConstraint *con;
1017         for (con = (bConstraint *)conlist->first; con; con = con->next) {
1018                 ListBase targets = { NULL, NULL };
1019
1020                 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
1021
1022                 if (cti && cti->get_constraint_targets) {
1023                         bConstraintTarget *ct;
1024                         Object *obtar;
1025                         cti->get_constraint_targets(con, &targets);
1026                         for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
1027                                 obtar = ct->tar;
1028
1029                                 if (obtar) {
1030                                         BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM);
1031                                         BKE_object_where_is_calc_time(this->eval_ctx, scene, obtar, ctime);
1032                                 }
1033                         }
1034
1035                         if (cti->flush_constraint_targets)
1036                                 cti->flush_constraint_targets(con, &targets, 1);
1037                 }
1038         }
1039         BKE_object_where_is_calc_time(this->eval_ctx, scene, ob, ctime);
1040 }
1041
1042 /*
1043  * ob is needed to aply parent inverse information to fcurve.
1044  * TODO: Here we have to step over all keyframes for each object and for each fcurve.
1045  * Instead of processing each fcurve one by one, 
1046  * step over the animation from keyframe to keyframe, 
1047  * then create adjusted fcurves (and entries) for all affected objects.
1048  * Then we would need to step through the scene only once.
1049  */
1050 std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name, Object *ob)
1051 {
1052         std::string source_id = anim_id + get_semantic_suffix(semantic);
1053
1054         bool is_angle = (strstr(fcu->rna_path, "rotation") || strstr(fcu->rna_path, "spot_size"));
1055         bool is_euler = strstr(fcu->rna_path, "rotation_euler");
1056         bool is_translation = strstr(fcu->rna_path, "location");
1057         bool is_scale = strstr(fcu->rna_path, "scale");
1058         bool is_tangent = false;
1059         int offset_index = 0;
1060
1061         COLLADASW::FloatSourceF source(mSW);
1062         source.setId(source_id);
1063         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1064         source.setAccessorCount(fcu->totvert);
1065
1066         switch (semantic) {
1067                 case COLLADASW::InputSemantic::INPUT:
1068                 case COLLADASW::InputSemantic::OUTPUT:
1069                         source.setAccessorStride(1);
1070                         offset_index = 0;
1071                         break;
1072                 case COLLADASW::InputSemantic::IN_TANGENT:
1073                 case COLLADASW::InputSemantic::OUT_TANGENT:
1074                         source.setAccessorStride(2);
1075                         offset_index = 1;
1076                         is_tangent = true;
1077                         break;
1078                 default:
1079                         break;
1080         }
1081
1082         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1083         add_source_parameters(param, semantic, is_angle, axis_name, false);
1084
1085         source.prepareToAppendValues();
1086
1087         for (unsigned int frame_index = 0; frame_index < fcu->totvert; frame_index++) {
1088                 float fixed_val = 0;
1089                 if (ob) {
1090                         float fmat[4][4];
1091                         float frame = fcu->bezt[frame_index].vec[1][0];
1092                         float ctime = BKE_scene_frame_get_from_ctime(scene, frame);
1093
1094                         evaluate_anim_with_constraints(ob, ctime); // set object transforms to fcurve's i'th keyframe
1095
1096                         BKE_object_matrix_local_get(ob, fmat);
1097                         float floc[3];
1098                         float fquat[4];
1099                         float fsize[3];
1100                         mat4_decompose(floc, fquat, fsize, fmat);
1101
1102                         if (is_euler) {
1103                                 float eul[3];
1104                                 quat_to_eul(eul, fquat);
1105                                 fixed_val = RAD2DEGF(eul[fcu->array_index]);
1106                         }
1107                         else if (is_translation) {
1108                                 fixed_val = floc[fcu->array_index];
1109                         }
1110                         else if (is_scale) {
1111                                 fixed_val = fsize[fcu->array_index];
1112                         }
1113                 }
1114
1115                 float values[3]; // be careful!
1116                 float offset = 0;
1117                 int length = 0;
1118                 get_source_values(&fcu->bezt[frame_index], semantic, is_angle, values, &length);
1119                 if (is_tangent) {
1120                         float bases[3];
1121                         int len = 0;
1122                         get_source_values(&fcu->bezt[frame_index], COLLADASW::InputSemantic::OUTPUT, is_angle, bases, &len);
1123                         offset = values[offset_index] - bases[0];
1124                 }
1125
1126                 for (int j = 0; j < length; j++) {
1127                         float val;
1128                         if (j == offset_index) {
1129                                 if (ob) {
1130                                         val = fixed_val + offset;
1131                                 }
1132                                 else {
1133                                         val = values[j] + offset;
1134                                 }
1135                         } else {
1136                                 val = values[j];
1137                         }
1138                         source.appendValues(val);
1139                 }
1140         }
1141
1142         source.finish();
1143
1144         return source_id;
1145 }
1146
1147 /*
1148  * Similar to create_source_from_fcurve, but adds conversion of lens
1149  * animation data from focal length to FOV.
1150  */
1151 std::string AnimationExporter::create_lens_source_from_fcurve(Camera *cam, COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id)
1152 {
1153         std::string source_id = anim_id + get_semantic_suffix(semantic);
1154
1155         COLLADASW::FloatSourceF source(mSW);
1156         source.setId(source_id);
1157         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1158         source.setAccessorCount(fcu->totvert);
1159
1160         source.setAccessorStride(1);
1161
1162         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1163         add_source_parameters(param, semantic, false, "", false);
1164
1165         source.prepareToAppendValues();
1166
1167         for (unsigned int i = 0; i < fcu->totvert; i++) {
1168                 float values[3]; // be careful!
1169                 int length = 0;
1170                 get_source_values(&fcu->bezt[i], semantic, false, values, &length);
1171                 for (int j = 0; j < length; j++)
1172                 {
1173                         float val = RAD2DEGF(focallength_to_fov(values[j], cam->sensor_x));
1174                         source.appendValues(val);
1175                 }
1176         }
1177
1178         source.finish();
1179
1180         return source_id;
1181 }
1182
1183 /*
1184  * only to get OUTPUT source values ( if rotation and hence the axis is also specified )
1185  */
1186 std::string AnimationExporter::create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
1187 {
1188         std::string source_id = anim_id + get_semantic_suffix(semantic);
1189
1190         COLLADASW::FloatSourceF source(mSW);
1191         source.setId(source_id);
1192         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1193         source.setAccessorCount(tot);
1194         source.setAccessorStride(1);
1195
1196         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1197         add_source_parameters(param, semantic, is_rot, axis_name,  false);
1198
1199         source.prepareToAppendValues();
1200
1201         for (int i = 0; i < tot; i++) {
1202                 float val = v[i];
1203                 ////if (semantic == COLLADASW::InputSemantic::INPUT)
1204                 //      val = convert_time(val);
1205                 //else
1206                 if (is_rot)
1207                         val = RAD2DEGF(val);
1208                 source.appendValues(val);
1209         }
1210
1211         source.finish();
1212
1213         return source_id;
1214 }
1215
1216 /*
1217  * only used for sources with INPUT semantic
1218  */
1219 std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name)
1220 {
1221         std::string source_id = anim_id + get_semantic_suffix(semantic);
1222
1223         COLLADASW::FloatSourceF source(mSW);
1224         source.setId(source_id);
1225         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1226         source.setAccessorCount(fra.size());
1227         source.setAccessorStride(1);
1228
1229         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1230         add_source_parameters(param, semantic, is_rot, axis_name, false);
1231
1232         source.prepareToAppendValues();
1233
1234         std::vector<float>::iterator it;
1235         for (it = fra.begin(); it != fra.end(); it++) {
1236                 float val = *it;
1237                 //if (semantic == COLLADASW::InputSemantic::INPUT)
1238                 val = convert_time(val);
1239                 /*else if (is_rot)
1240                    val = convert_angle(val);*/
1241                 source.appendValues(val);
1242         }
1243
1244         source.finish();
1245
1246         return source_id;
1247 }
1248
1249 std::string AnimationExporter::create_4x4_source(std::vector<float> &ctimes, std::vector<float> &values , const std::string &anim_id)
1250 {
1251         COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
1252         std::string source_id = anim_id + get_semantic_suffix(semantic);
1253
1254         COLLADASW::Float4x4Source source(mSW);
1255         source.setId(source_id);
1256         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1257         source.setAccessorCount(ctimes.size());
1258         source.setAccessorStride(16);
1259
1260         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1261         add_source_parameters(param, semantic, false, NULL, true);
1262
1263         source.prepareToAppendValues();
1264
1265         std::vector<float>::iterator it;
1266
1267         for (it = values.begin(); it != values.end(); it+=16) {
1268                 float mat[4][4];
1269
1270                 bc_copy_m4_farray(mat, &*it);
1271
1272                 UnitConverter converter;
1273                 double outmat[4][4];
1274                 converter.mat4_to_dae_double(outmat, mat);
1275
1276                 if (this->export_settings->limit_precision)
1277                         bc_sanitize_mat(outmat, 6);
1278
1279                 source.appendValues(outmat);
1280         }
1281
1282         source.finish();
1283         return source_id;
1284 }
1285
1286 std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob, Bone *bone, const std::string &anim_id)
1287 {
1288         bool is_bone_animation = ob->type == OB_ARMATURE && bone;
1289
1290         COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
1291         std::string source_id = anim_id + get_semantic_suffix(semantic);
1292
1293         COLLADASW::Float4x4Source source(mSW);
1294         source.setId(source_id);
1295         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1296         source.setAccessorCount(frames.size());
1297         source.setAccessorStride(16);
1298
1299         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1300         add_source_parameters(param, semantic, false, NULL, true);
1301
1302         source.prepareToAppendValues();
1303
1304         bPoseChannel *parchan = NULL;
1305         bPoseChannel *pchan = NULL;
1306
1307         if (is_bone_animation) {
1308                 bPose *pose = ob->pose;
1309                 pchan = BKE_pose_channel_find_name(pose, bone->name);
1310                 if (!pchan)
1311                         return "";
1312
1313                 parchan = pchan->parent;
1314
1315                 enable_fcurves(ob->adt->action, bone->name);
1316         }
1317         
1318         std::vector<float>::iterator it;
1319         int j = 0;
1320         for (it = frames.begin(); it != frames.end(); it++) {
1321                 float mat[4][4], ipar[4][4];
1322                 float frame = *it;
1323
1324                 float ctime = BKE_scene_frame_get_from_ctime(scene, frame);
1325                 bc_update_scene(eval_ctx, scene, ctime);
1326                 if (is_bone_animation) {
1327
1328                         if (pchan->flag & POSE_CHAIN) {
1329                                 enable_fcurves(ob->adt->action, NULL);
1330                                 BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_ALL);
1331                                 BKE_pose_where_is(eval_ctx, scene, ob);
1332                         }
1333                         else {
1334                                 BKE_pose_where_is_bone(eval_ctx, scene, ob, pchan, ctime, 1);
1335                         }
1336                         
1337                         // compute bone local mat
1338                         if (bone->parent) {
1339                                 invert_m4_m4(ipar, parchan->pose_mat);
1340                                 mul_m4_m4m4(mat, ipar, pchan->pose_mat);
1341                         }
1342                         else
1343                                 copy_m4_m4(mat, pchan->pose_mat);
1344                         
1345                         /* OPEN_SIM_COMPATIBILITY
1346                          * AFAIK animation to second life is via BVH, but no
1347                          * reason to not have the collada-animation be correct
1348                          */
1349                         if (export_settings->open_sim) {
1350                                 float temp[4][4];
1351                                 copy_m4_m4(temp, bone->arm_mat);
1352                                 temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
1353                                 invert_m4(temp);
1354
1355                                 mul_m4_m4m4(mat, mat, temp);
1356
1357                                 if (bone->parent) {
1358                                         copy_m4_m4(temp, bone->parent->arm_mat);
1359                                         temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
1360
1361                                         mul_m4_m4m4(mat, temp, mat);
1362                                 }
1363                         }
1364
1365                 }
1366                 else {
1367                         copy_m4_m4(mat, ob->obmat);
1368                 }
1369                 
1370                 UnitConverter converter;
1371
1372                 double outmat[4][4];
1373                 converter.mat4_to_dae_double(outmat, mat);
1374
1375                 if (this->export_settings->limit_precision)
1376                         bc_sanitize_mat(outmat, 6);
1377
1378                 source.appendValues(outmat);
1379
1380                 j++;
1381
1382                 BIK_release_tree(scene, ob, ctime);
1383         }
1384
1385         if (ob->adt) {
1386                 enable_fcurves(ob->adt->action, NULL);
1387         }
1388
1389         source.finish();
1390
1391         return source_id;
1392 }
1393
1394
1395 /*
1396  * only used for sources with OUTPUT semantic ( locations and scale)
1397  */
1398 std::string AnimationExporter::create_xyz_source(float *v, int tot, const std::string& anim_id)
1399 {
1400         COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
1401         std::string source_id = anim_id + get_semantic_suffix(semantic);
1402
1403         COLLADASW::FloatSourceF source(mSW);
1404         source.setId(source_id);
1405         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1406         source.setAccessorCount(tot);
1407         source.setAccessorStride(3);
1408
1409         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1410         add_source_parameters(param, semantic, false, NULL, false);
1411
1412         source.prepareToAppendValues();
1413
1414         for (int i = 0; i < tot; i++) {
1415                 source.appendValues(*v, *(v + 1), *(v + 2));
1416                 v += 3;
1417         }
1418
1419         source.finish();
1420
1421         return source_id;
1422 }
1423
1424 std::string AnimationExporter::create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents)
1425 {
1426         std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
1427
1428         COLLADASW::NameSource source(mSW);
1429         source.setId(source_id);
1430         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1431         source.setAccessorCount(fcu->totvert);
1432         source.setAccessorStride(1);
1433
1434         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1435         param.push_back("INTERPOLATION");
1436
1437         source.prepareToAppendValues();
1438
1439         *has_tangents = false;
1440
1441         for (unsigned int i = 0; i < fcu->totvert; i++) {
1442                 if (fcu->bezt[i].ipo == BEZT_IPO_BEZ) {
1443                         source.appendValues(BEZIER_NAME);
1444                         *has_tangents = true;
1445                 }
1446                 else if (fcu->bezt[i].ipo == BEZT_IPO_CONST) {
1447                         source.appendValues(STEP_NAME);
1448                 }
1449                 else { // BEZT_IPO_LIN
1450                         source.appendValues(LINEAR_NAME);
1451                 }
1452         }
1453         // unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS
1454
1455         source.finish();
1456
1457         return source_id;
1458 }
1459
1460 std::string AnimationExporter::fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
1461 {
1462         std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
1463
1464         COLLADASW::NameSource source(mSW);
1465         source.setId(source_id);
1466         source.setArrayId(source_id + ARRAY_ID_SUFFIX);
1467         source.setAccessorCount(tot);
1468         source.setAccessorStride(1);
1469
1470         COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
1471         param.push_back("INTERPOLATION");
1472
1473         source.prepareToAppendValues();
1474
1475         for (int i = 0; i < tot; i++) {
1476                 source.appendValues(LINEAR_NAME);
1477         }
1478
1479         source.finish();
1480
1481         return source_id;
1482 }
1483
1484 std::string AnimationExporter::get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
1485 {
1486         std::string tm_name;
1487         // when given rna_path, determine tm_type from it
1488         if (rna_path) {
1489                 char *name = extract_transform_name(rna_path);
1490
1491                 if (STREQ(name, "color"))
1492                         tm_type = 1;
1493                 else if (STREQ(name, "spot_size"))
1494                         tm_type = 2;
1495                 else if (STREQ(name, "spot_blend"))
1496                         tm_type = 3;
1497                 else if (STREQ(name, "distance"))
1498                         tm_type = 4;
1499                 else
1500                         tm_type = -1;
1501         }
1502
1503         switch (tm_type) {
1504                 case 1:
1505                         tm_name = "color";
1506                         break;
1507                 case 2:
1508                         tm_name = "fall_off_angle";
1509                         break;
1510                 case 3:
1511                         tm_name = "fall_off_exponent";
1512                         break;
1513                 case 4:
1514                         tm_name = "blender/blender_dist";
1515                         break;
1516
1517                 default:
1518                         tm_name = "";
1519                         break;
1520         }
1521
1522         if (tm_name.size()) {
1523                 if (axis_name[0])
1524                         return tm_name + "." + std::string(axis_name);
1525                 else 
1526                         return tm_name;
1527         }
1528
1529         return std::string("");
1530 }
1531
1532 std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
1533 {
1534         std::string tm_name;
1535         // when given rna_path, determine tm_type from it
1536         if (rna_path) {
1537                 char *name = extract_transform_name(rna_path);
1538
1539                 if (STREQ(name, "lens"))
1540                         tm_type = 0;
1541                 else if (STREQ(name, "ortho_scale"))
1542                         tm_type = 1;
1543                 else if (STREQ(name, "clip_end"))
1544                         tm_type = 2;
1545                 else if (STREQ(name, "clip_start"))
1546                         tm_type = 3;
1547
1548                 else
1549                         tm_type = -1;
1550         }
1551
1552         switch (tm_type) {
1553                 case 0:
1554                         tm_name = "xfov";
1555                         break;
1556                 case 1:
1557                         tm_name = "xmag";
1558                         break;
1559                 case 2:
1560                         tm_name = "zfar";
1561                         break;
1562                 case 3:
1563                         tm_name = "znear";
1564                         break;
1565
1566                 default:
1567                         tm_name = "";
1568                         break;
1569         }
1570
1571         if (tm_name.size()) {
1572                 if (axis_name[0])
1573                         return tm_name + "." + std::string(axis_name);
1574                 else 
1575                         return tm_name;
1576         }
1577
1578         return std::string("");
1579 }
1580
1581 /*
1582  * Assign sid of the animated parameter or transform for rotation, 
1583  * axis name is always appended and the value of append_axis is ignored
1584  */
1585 std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
1586 {
1587         std::string tm_name;
1588         bool is_angle = false;
1589         // when given rna_path, determine tm_type from it
1590         if (rna_path) {
1591                 char *name = extract_transform_name(rna_path);
1592
1593                 if (STREQ(name, "rotation_euler"))
1594                         tm_type = 0;
1595                 else if (STREQ(name, "rotation_quaternion"))
1596                         tm_type = 1;
1597                 else if (STREQ(name, "scale"))
1598                         tm_type = 2;
1599                 else if (STREQ(name, "location"))
1600                         tm_type = 3;
1601                 else if (STREQ(name, "specular_hardness"))
1602                         tm_type = 4;
1603                 else if (STREQ(name, "specular_color"))
1604                         tm_type = 5;
1605                 else if (STREQ(name, "diffuse_color"))
1606                         tm_type = 6;
1607                 else if (STREQ(name, "alpha"))
1608                         tm_type = 7;
1609                 else if (STREQ(name, "ior"))
1610                         tm_type = 8;
1611
1612                 else
1613                         tm_type = -1;
1614         }
1615
1616         switch (tm_type) {
1617                 case 0:
1618                 case 1:
1619                         tm_name = "rotation";
1620                         is_angle = true;
1621                         break;
1622                 case 2:
1623                         tm_name = "scale";
1624                         break;
1625                 case 3:
1626                         tm_name = "location";
1627                         break;
1628                 case 4:
1629                         tm_name = "shininess";
1630                         break;
1631                 case 5:
1632                         tm_name = "specular";
1633                         break;
1634                 case 6:
1635                         tm_name = "diffuse";
1636                         break;
1637                 case 7:
1638                         tm_name = "transparency";
1639                         break;
1640                 case 8:
1641                         tm_name = "index_of_refraction";
1642                         break;
1643
1644                 default:
1645                         tm_name = "";
1646                         break;
1647         }
1648
1649         if (tm_name.size()) {
1650                 if (is_angle)
1651                         return tm_name + std::string(axis_name) + ".ANGLE";
1652                 else
1653                 if (axis_name[0])
1654                         return tm_name + "." + std::string(axis_name);
1655                 else
1656                         return tm_name;
1657         }
1658
1659         return std::string("");
1660 }
1661
1662 char *AnimationExporter::extract_transform_name(char *rna_path)
1663 {
1664         char *dot = strrchr(rna_path, '.');
1665         return dot ? (dot + 1) : rna_path;
1666 }
1667
1668 /*
1669  * enable fcurves driving a specific bone, disable all the rest
1670  * if bone_name = NULL enable all fcurves
1671  */
1672 void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
1673 {
1674         FCurve *fcu;
1675         char prefix[200];
1676
1677         if (bone_name)
1678                 BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
1679
1680         for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) {
1681                 if (bone_name) {
1682                         if (STREQLEN(fcu->rna_path, prefix, strlen(prefix)))
1683                                 fcu->flag &= ~FCURVE_DISABLED;
1684                         else
1685                                 fcu->flag |= FCURVE_DISABLED;
1686                 }
1687                 else {
1688                         fcu->flag &= ~FCURVE_DISABLED;
1689                 }
1690         }
1691 }
1692
1693 bool AnimationExporter::hasAnimations(Scene *sce)
1694 {
1695         LinkNode *node;
1696
1697         for (node=this->export_settings->export_set; node; node=node->next) {
1698                 Object *ob = (Object *)node->link;
1699
1700                 FCurve *fcu = 0;
1701                 //Check for object transform animations
1702                 if (ob->adt && ob->adt->action)
1703                         fcu = (FCurve *)ob->adt->action->curves.first;
1704                 //Check for Lamp parameter animations
1705                 else if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action)
1706                         fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first);
1707                 //Check for Camera parameter animations
1708                 else if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action)
1709                         fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first);
1710
1711                 //Check Material Effect parameter animations.
1712                 for (int a = 0; a < ob->totcol; a++) {
1713                         Material *ma = give_current_material(ob, a + 1);
1714                         if (!ma) continue;
1715                         if (ma->adt && ma->adt->action) {
1716                                 fcu = (FCurve *)ma->adt->action->curves.first;
1717                         }
1718                 }
1719
1720                 //check shape key animation
1721                 if (!fcu) {
1722                         Key *key = BKE_key_from_object(ob);
1723                         if (key && key->adt && key->adt->action)
1724                                 fcu = (FCurve *)key->adt->action->curves.first;
1725                 }
1726                 if (fcu)
1727                         return true;
1728         }
1729         return false;
1730 }
1731
1732 //------------------------------- Not used in the new system.--------------------------------------------------------
1733 void AnimationExporter::find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
1734 {
1735         if (rotmode > 0)
1736                 find_keyframes(ob, fra, prefix, "rotation_euler");
1737         else if (rotmode == ROT_MODE_QUAT)
1738                 find_keyframes(ob, fra, prefix, "rotation_quaternion");
1739         /*else if (rotmode == ROT_MODE_AXISANGLE)
1740            ;*/
1741 }
1742
1743 /* Take care to always have the first frame and the last frame in the animation
1744  * regardless of the sampling_rate setting
1745  */
1746 void AnimationExporter::find_sampleframes(Object *ob, std::vector<float> &fra)
1747 {
1748         int frame = scene->r.sfra;
1749         do {
1750                 float ctime = BKE_scene_frame_get_from_ctime(scene, frame);
1751                 fra.push_back(ctime);
1752                 if (frame == scene->r.efra)
1753                         break;
1754                 frame += this->export_settings->sampling_rate;
1755                 if (frame > scene->r.efra)
1756                         frame = scene->r.efra; // make sure the last frame is always exported
1757
1758         } while (true);
1759 }
1760
1761 /* 
1762  * find keyframes of all the objects animations
1763  */
1764 void AnimationExporter::find_keyframes(Object *ob, std::vector<float> &fra)
1765 {
1766         if (ob->adt && ob->adt->action) {
1767                 FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
1768
1769                 for (; fcu; fcu = fcu->next) {
1770                         for (unsigned int i = 0; i < fcu->totvert; i++) {
1771                                 float f = fcu->bezt[i].vec[1][0];
1772                                 if (std::find(fra.begin(), fra.end(), f) == fra.end())
1773                                         fra.push_back(f);
1774                         }
1775                 }
1776
1777                 // keep the keys in ascending order
1778                 std::sort(fra.begin(), fra.end());
1779         }
1780 }
1781
1782 void AnimationExporter::find_keyframes(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
1783 {
1784         if (ob->adt && ob->adt->action) {
1785                 FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
1786
1787                 for (; fcu; fcu = fcu->next) {
1788                         if (prefix && !STREQLEN(prefix, fcu->rna_path, strlen(prefix)))
1789                                 continue;
1790
1791                         char *name = extract_transform_name(fcu->rna_path);
1792                         if (STREQ(name, tm_name)) {
1793                                 for (unsigned int i = 0; i < fcu->totvert; i++) {
1794                                         float f = fcu->bezt[i].vec[1][0];
1795                                         if (std::find(fra.begin(), fra.end(), f) == fra.end())
1796                                                 fra.push_back(f);
1797                                 }
1798                         }
1799                 }
1800
1801                 // keep the keys in ascending order
1802                 std::sort(fra.begin(), fra.end());
1803         }
1804 }
1805
1806 void AnimationExporter::write_bone_animation(Object *ob_arm, Bone *bone)
1807 {
1808         if (!ob_arm->adt)
1809                 return;
1810
1811         //write bone animations for 3 transform types
1812         //i=0 --> rotations
1813         //i=1 --> scale
1814         //i=2 --> location
1815         for (int i = 0; i < 3; i++)
1816                 sample_and_write_bone_animation(ob_arm, bone, i);
1817
1818         for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next)
1819                 write_bone_animation(ob_arm, child);
1820 }
1821
1822 void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
1823 {
1824         bArmature *arm = (bArmature *)ob_arm->data;
1825         int flag = arm->flag;
1826         std::vector<float> fra;
1827         char prefix[256];
1828
1829         BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);
1830
1831         bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name);
1832         if (!pchan)
1833                 return;
1834         //Fill frame array with key frame values framed at \param:transform_type
1835         switch (transform_type) {
1836                 case 0:
1837                         find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
1838                         break;
1839                 case 1:
1840                         find_keyframes(ob_arm, fra, prefix, "scale");
1841                         break;
1842                 case 2:
1843                         find_keyframes(ob_arm, fra, prefix, "location");
1844                         break;
1845                 default:
1846                         return;
1847         }
1848
1849         // exit rest position
1850         if (flag & ARM_RESTPOS) {
1851                 arm->flag &= ~ARM_RESTPOS;
1852                 BKE_pose_where_is(eval_ctx, scene, ob_arm);
1853         }
1854         //v array will hold all values which will be exported. 
1855         if (fra.size()) {
1856                 float *values = (float *)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
1857                 sample_animation(values, fra, transform_type, bone, ob_arm, pchan);
1858
1859                 if (transform_type == 0) {
1860                         // write x, y, z curves separately if it is rotation
1861                         float *axisValues = (float *)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
1862
1863                         for (int i = 0; i < 3; i++) {
1864                                 for (unsigned int j = 0; j < fra.size(); j++)
1865                                         axisValues[j] = values[j * 3 + i];
1866
1867                                 dae_bone_animation(fra, axisValues, transform_type, i, id_name(ob_arm), bone->name);
1868                         }
1869                         MEM_freeN(axisValues);
1870                 }
1871                 else {
1872                         // write xyz at once if it is location or scale
1873                         dae_bone_animation(fra, values, transform_type, -1, id_name(ob_arm), bone->name);
1874                 }
1875
1876                 MEM_freeN(values);
1877         }
1878
1879         // restore restpos
1880         if (flag & ARM_RESTPOS) 
1881                 arm->flag = flag;
1882         BKE_pose_where_is(eval_ctx, scene, ob_arm);
1883 }
1884
1885 void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pchan)
1886 {
1887         bPoseChannel *parchan = NULL;
1888         bPose *pose = ob_arm->pose;
1889
1890         pchan = BKE_pose_channel_find_name(pose, bone->name);
1891
1892         if (!pchan)
1893                 return;
1894
1895         parchan = pchan->parent;
1896
1897         enable_fcurves(ob_arm->adt->action, bone->name);
1898
1899         std::vector<float>::iterator it;
1900         for (it = frames.begin(); it != frames.end(); it++) {
1901                 float mat[4][4], ipar[4][4];
1902
1903                 float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
1904
1905
1906                 BKE_animsys_evaluate_animdata(scene, &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM);
1907                 BKE_pose_where_is_bone(eval_ctx, scene, ob_arm, pchan, ctime, 1);
1908
1909                 // compute bone local mat
1910                 if (bone->parent) {
1911                         invert_m4_m4(ipar, parchan->pose_mat);
1912                         mul_m4_m4m4(mat, ipar, pchan->pose_mat);
1913                 }
1914                 else
1915                         copy_m4_m4(mat, pchan->pose_mat);
1916
1917                 switch (type) {
1918                         case 0:
1919                                 mat4_to_eul(v, mat);
1920                                 break;
1921                         case 1:
1922                                 mat4_to_size(v, mat);
1923                                 break;
1924                         case 2:
1925                                 copy_v3_v3(v, mat[3]);
1926                                 break;
1927                 }
1928
1929                 v += 3;
1930         }
1931
1932         enable_fcurves(ob_arm->adt->action, NULL);
1933 }
1934
1935 bool AnimationExporter::validateConstraints(bConstraint *con)
1936 {
1937         bool valid = true;
1938         const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
1939         /* these we can skip completely (invalid constraints...) */
1940         if (cti == NULL) valid = false;
1941         if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) valid = false;
1942         /* these constraints can't be evaluated anyway */
1943         if (cti->evaluate_constraint == NULL) valid = false;
1944         /* influence == 0 should be ignored */
1945         if (con->enforce == 0.0f) valid = false;
1946
1947         return valid;
1948 }
1949
1950 #if 0
1951 /*
1952  * Needed for sampled animations. 
1953  * This function calculates the object matrix at a given time,
1954  * also taking constraints into account.
1955  *
1956  * XXX: Why looking at the constraints here is necessary?
1957  *      Maybe this can be done better?
1958  */
1959 void AnimationExporter::calc_obmat_at_time(Object *ob, float ctime )
1960 {
1961 <<<<<<< HEAD
1962         ListBase *conlist = get_active_constraints(this->eval_ctx, ob);
1963 =======
1964         BKE_scene_frame_set(scene, ctime);
1965
1966         Main *bmain = bc_get_main();
1967         EvaluationContext *ev_context = bc_get_evaluation_context();
1968         BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay);
1969
1970         ListBase *conlist = get_active_constraints(ob);
1971 >>>>>>> master
1972         bConstraint *con;
1973         for (con = (bConstraint *)conlist->first; con; con = con->next) {
1974                 ListBase targets = {NULL, NULL};
1975                 
1976                 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
1977                 
1978                 if (cti && cti->get_constraint_targets) {
1979                         bConstraintTarget *ct;
1980                         Object *obtar;
1981                         cti->get_constraint_targets(con, &targets);
1982                         for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
1983                                 obtar = ct->tar;
1984
1985                                 if (obtar) {
1986                                         BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM);
1987                                         BKE_object_where_is_calc_time(eval_ctx, scene, obtar, ctime);
1988                                 }
1989                         }
1990
1991                         if (cti->flush_constraint_targets)
1992                                 cti->flush_constraint_targets(con, &targets, 1);
1993                 }
1994         }
1995 <<<<<<< HEAD
1996         BKE_object_where_is_calc_time(eval_ctx, scene, ob, ctime);
1997         copy_m4_m4(mat, ob->obmat);
1998 =======
1999         BKE_object_where_is_calc_time(scene, ob, ctime);
2000 >>>>>>> master
2001 }
2002 #endif
2003