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