ee574e2968ba35bbeef2085161bf101d1adbfe9f
[blender.git] / source / blender / collada / BCAnimationSampler.cpp
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19
20 #include <vector>
21 #include <map>
22 #include <algorithm>  // std::find
23
24 #include "ExportSettings.h"
25 #include "BCAnimationCurve.h"
26 #include "BCAnimationSampler.h"
27 #include "collada_utils.h"
28
29 extern "C" {
30 #include "BKE_action.h"
31 #include "BKE_constraint.h"
32 #include "BKE_key.h"
33 #include "BKE_main.h"
34 #include "BKE_library.h"
35 #include "BKE_material.h"
36 #include "BLI_listbase.h"
37 #include "DNA_anim_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_key_types.h"
40 #include "DNA_constraint_types.h"
41 #include "ED_object.h"
42 }
43
44 static std::string EMPTY_STRING;
45 static BCAnimationCurveMap BCEmptyAnimationCurves;
46
47 BCAnimationSampler::BCAnimationSampler(BlenderContext &blender_context, BCObjectSet &object_set)
48     : blender_context(blender_context)
49 {
50   BCObjectSet::iterator it;
51   for (it = object_set.begin(); it != object_set.end(); ++it) {
52     Object *ob = *it;
53     add_object(ob);
54   }
55 }
56
57 BCAnimationSampler::~BCAnimationSampler()
58 {
59   BCAnimationObjectMap::iterator it;
60   for (it = objects.begin(); it != objects.end(); ++it) {
61     BCAnimation *animation = it->second;
62     delete animation;
63   }
64 }
65
66 void BCAnimationSampler::add_object(Object *ob)
67 {
68   BCAnimation *animation = new BCAnimation(blender_context.get_context(), ob);
69   objects[ob] = animation;
70
71   initialize_keyframes(animation->frame_set, ob);
72   initialize_curves(animation->curve_map, ob);
73 }
74
75 BCAnimationCurveMap *BCAnimationSampler::get_curves(Object *ob)
76 {
77   BCAnimation &animation = *objects[ob];
78   if (animation.curve_map.size() == 0)
79     initialize_curves(animation.curve_map, ob);
80   return &animation.curve_map;
81 }
82
83 static void get_sample_frames(BCFrameSet &sample_frames,
84                               int sampling_rate,
85                               bool keyframe_at_end,
86                               Scene *scene)
87 {
88   sample_frames.clear();
89
90   if (sampling_rate < 1)
91     return;  // no sample frames in this case
92
93   float sfra = scene->r.sfra;
94   float efra = scene->r.efra;
95
96   int frame_index;
97   for (frame_index = nearbyint(sfra); frame_index < efra; frame_index += sampling_rate) {
98     sample_frames.insert(frame_index);
99   }
100
101   if (frame_index >= efra && keyframe_at_end) {
102     sample_frames.insert(efra);
103   }
104 }
105
106 static bool is_object_keyframe(Object *ob, int frame_index)
107 {
108   return false;
109 }
110
111 static void add_keyframes_from(bAction *action, BCFrameSet &frameset)
112 {
113   if (action) {
114     FCurve *fcu = NULL;
115     for (fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) {
116       BezTriple *bezt = fcu->bezt;
117       for (int i = 0; i < fcu->totvert; bezt++, i++) {
118         int frame_index = nearbyint(bezt->vec[1][0]);
119         frameset.insert(frame_index);
120       }
121     }
122   }
123 }
124
125 void BCAnimationSampler::check_property_is_animated(
126     BCAnimation &animation, float *ref, float *val, std::string data_path, int length)
127 {
128   for (int array_index = 0; array_index < length; ++array_index) {
129     if (!bc_in_range(ref[length], val[length], 0.00001)) {
130       BCCurveKey key(BC_ANIMATION_TYPE_OBJECT, data_path, array_index);
131       BCAnimationCurveMap::iterator it = animation.curve_map.find(key);
132       if (it == animation.curve_map.end()) {
133         animation.curve_map[key] = new BCAnimationCurve(key, animation.get_reference());
134       }
135     }
136   }
137 }
138
139 void BCAnimationSampler::update_animation_curves(BCAnimation &animation,
140                                                  BCSample &sample,
141                                                  Object *ob,
142                                                  int frame)
143 {
144   BCAnimationCurveMap::iterator it;
145   for (it = animation.curve_map.begin(); it != animation.curve_map.end(); ++it) {
146     BCAnimationCurve *curve = it->second;
147     if (curve->is_transform_curve()) {
148       curve->add_value_from_matrix(sample, frame);
149     }
150     else {
151       curve->add_value_from_rna(frame);
152     }
153   }
154 }
155
156 BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool for_opensim)
157 {
158   BCSample &ob_sample = sample_data.add(ob, frame_index);
159
160   if (ob->type == OB_ARMATURE) {
161     bPoseChannel *pchan;
162     for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
163       Bone *bone = pchan->bone;
164       Matrix bmat;
165       if (bc_bone_matrix_local_get(ob, bone, bmat, for_opensim)) {
166         ob_sample.add_bone_matrix(bone, bmat);
167       }
168     }
169   }
170   return ob_sample;
171 }
172
173 void BCAnimationSampler::sample_scene(int sampling_rate,
174                                       int keyframe_at_end,
175                                       bool for_opensim,
176                                       bool keep_keyframes,
177                                       BC_export_animation_type export_animation_type)
178 {
179   Scene *scene = blender_context.get_scene();
180   BCFrameSet scene_sample_frames;
181   get_sample_frames(scene_sample_frames, sampling_rate, keyframe_at_end, scene);
182   BCFrameSet::iterator it;
183
184   int startframe = scene->r.sfra;
185   int endframe = scene->r.efra;
186
187   for (int frame_index = startframe; frame_index <= endframe; ++frame_index) {
188     /* Loop over all frames and decide for each frame if sampling is necessary */
189     bool is_scene_sample_frame = false;
190     bool needs_update = true;
191     if (scene_sample_frames.find(frame_index) != scene_sample_frames.end()) {
192       bc_update_scene(blender_context, frame_index);
193       needs_update = false;
194       is_scene_sample_frame = true;
195     }
196
197     bool needs_sampling = is_scene_sample_frame || keep_keyframes ||
198                           export_animation_type == BC_ANIMATION_EXPORT_KEYS;
199     if (!needs_sampling) {
200       continue;
201     }
202
203     BCAnimationObjectMap::iterator obit;
204     for (obit = objects.begin(); obit != objects.end(); ++obit) {
205       Object *ob = obit->first;
206       BCAnimation *animation = obit->second;
207       BCFrameSet &object_keyframes = animation->frame_set;
208       if (is_scene_sample_frame || object_keyframes.find(frame_index) != object_keyframes.end()) {
209
210         if (needs_update) {
211           bc_update_scene(blender_context, frame_index);
212           needs_update = false;
213         }
214
215         BCSample &sample = sample_object(ob, frame_index, for_opensim);
216         update_animation_curves(*animation, sample, ob, frame_index);
217       }
218     }
219   }
220 }
221
222 bool BCAnimationSampler::is_animated_by_constraint(Object *ob,
223                                                    ListBase *conlist,
224                                                    std::set<Object *> &animated_objects)
225 {
226   bConstraint *con;
227   for (con = (bConstraint *)conlist->first; con; con = con->next) {
228     ListBase targets = {NULL, NULL};
229
230     const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
231
232     if (!bc_validateConstraints(con))
233       continue;
234
235     if (cti && cti->get_constraint_targets) {
236       bConstraintTarget *ct;
237       Object *obtar;
238       cti->get_constraint_targets(con, &targets);
239       for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
240         obtar = ct->tar;
241         if (obtar) {
242           if (animated_objects.find(obtar) != animated_objects.end())
243             return true;
244         }
245       }
246     }
247   }
248   return false;
249 }
250
251 void BCAnimationSampler::find_depending_animated(std::set<Object *> &animated_objects,
252                                                  std::set<Object *> &candidates)
253 {
254   bool found_more;
255   do {
256     found_more = false;
257     std::set<Object *>::iterator it;
258     for (it = candidates.begin(); it != candidates.end(); ++it) {
259       Object *cob = *it;
260       ListBase *conlist = get_active_constraints(cob);
261       if (is_animated_by_constraint(cob, conlist, animated_objects)) {
262         animated_objects.insert(cob);
263         candidates.erase(cob);
264         found_more = true;
265         break;
266       }
267     }
268   } while (found_more && candidates.size() > 0);
269 }
270
271 void BCAnimationSampler::get_animated_from_export_set(std::set<Object *> &animated_objects,
272                                                       LinkNode &export_set)
273 {
274   /* Check if this object is animated. That is: Check if it has its own action, or:
275    *
276    * - Check if it has constraints to other objects.
277    * - at least one of the other objects is animated as well.
278    */
279
280   animated_objects.clear();
281   std::set<Object *> static_objects;
282   std::set<Object *> candidates;
283
284   LinkNode *node;
285   for (node = &export_set; node; node = node->next) {
286     Object *cob = (Object *)node->link;
287     if (bc_has_animations(cob)) {
288       animated_objects.insert(cob);
289     }
290     else {
291       ListBase conlist = cob->constraints;
292       if (conlist.first)
293         candidates.insert(cob);
294     }
295   }
296   find_depending_animated(animated_objects, candidates);
297 }
298
299 void BCAnimationSampler::get_object_frames(BCFrames &frames, Object *ob)
300 {
301   sample_data.get_frames(ob, frames);
302 }
303
304 void BCAnimationSampler::get_bone_frames(BCFrames &frames, Object *ob, Bone *bone)
305 {
306   sample_data.get_frames(ob, bone, frames);
307 }
308
309 bool BCAnimationSampler::get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone)
310 {
311   sample_data.get_matrices(ob, bone, samples);
312   return bc_is_animated(samples);
313 }
314
315 bool BCAnimationSampler::get_object_samples(BCMatrixSampleMap &samples, Object *ob)
316 {
317   sample_data.get_matrices(ob, samples);
318   return bc_is_animated(samples);
319 }
320
321 #if 0
322 /**
323  * Add sampled values to FCurve
324  * If no FCurve exists, create a temporary FCurve;
325  * Note: The temporary FCurve will later be removed when the
326  * BCAnimationSampler is removed (by its destructor)
327  *
328  * curve: The curve to whioch the data is added
329  * matrices: The set of matrix values from where the data is taken
330  * animation_type BC_ANIMATION_EXPORT_SAMPLES: Use all matrix data
331  * animation_type BC_ANIMATION_EXPORT_KEYS: Only take data from matrices for keyframes
332  */
333 void BCAnimationSampler::add_value_set(BCAnimationCurve &curve,
334                                        BCFrameSampleMap &samples,
335                                        BC_export_animation_type animation_type)
336 {
337   int array_index = curve.get_array_index();
338   const BC_animation_transform_type tm_type = curve.get_transform_type();
339
340   BCFrameSampleMap::iterator it;
341   for (it = samples.begin(); it != samples.end(); ++it) {
342     const int frame_index = nearbyint(it->first);
343     if (animation_type == BC_ANIMATION_EXPORT_SAMPLES || curve.is_keyframe(frame_index)) {
344
345       const BCSample *sample = it->second;
346       float val = 0;
347
348       int subindex = curve.get_subindex();
349       bool good;
350       if (subindex == -1) {
351         good = sample->get_value(tm_type, array_index, &val);
352       }
353       else {
354         good = sample->get_value(tm_type, array_index, &val, subindex);
355       }
356
357       if (good) {
358         curve.add_value(val, frame_index);
359       }
360     }
361   }
362   curve.remove_unused_keyframes();
363   curve.calchandles();
364 }
365 #endif
366
367 void BCAnimationSampler::generate_transform(Object *ob,
368                                             const BCCurveKey &key,
369                                             BCAnimationCurveMap &curves)
370 {
371   BCAnimationCurveMap::const_iterator it = curves.find(key);
372   if (it == curves.end()) {
373     curves[key] = new BCAnimationCurve(key, ob);
374   }
375 }
376
377 void BCAnimationSampler::generate_transforms(Object *ob,
378                                              const std::string prep,
379                                              const BC_animation_type type,
380                                              BCAnimationCurveMap &curves)
381 {
382   generate_transform(ob, BCCurveKey(type, prep + "location", 0), curves);
383   generate_transform(ob, BCCurveKey(type, prep + "location", 1), curves);
384   generate_transform(ob, BCCurveKey(type, prep + "location", 2), curves);
385   generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 0), curves);
386   generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 1), curves);
387   generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 2), curves);
388   generate_transform(ob, BCCurveKey(type, prep + "scale", 0), curves);
389   generate_transform(ob, BCCurveKey(type, prep + "scale", 1), curves);
390   generate_transform(ob, BCCurveKey(type, prep + "scale", 2), curves);
391 }
392
393 void BCAnimationSampler::generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves)
394 {
395   std::string prep = "pose.bones[\"" + std::string(bone->name) + "\"].";
396   generate_transforms(ob, prep, BC_ANIMATION_TYPE_BONE, curves);
397
398   for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next)
399     generate_transforms(ob, child, curves);
400 }
401
402 /**
403  * Collect all keyframes from all animation curves related to the object.
404  * The bc_get... functions check for NULL and correct object type.
405  * The #add_keyframes_from() function checks for NULL.
406  */
407 void BCAnimationSampler::initialize_keyframes(BCFrameSet &frameset, Object *ob)
408 {
409   frameset.clear();
410   add_keyframes_from(bc_getSceneObjectAction(ob), frameset);
411   add_keyframes_from(bc_getSceneCameraAction(ob), frameset);
412   add_keyframes_from(bc_getSceneLightAction(ob), frameset);
413
414   for (int a = 0; a < ob->totcol; a++) {
415     Material *ma = give_current_material(ob, a + 1);
416     add_keyframes_from(bc_getSceneMaterialAction(ma), frameset);
417   }
418 }
419
420 void BCAnimationSampler::initialize_curves(BCAnimationCurveMap &curves, Object *ob)
421 {
422   BC_animation_type object_type = BC_ANIMATION_TYPE_OBJECT;
423
424   bAction *action = bc_getSceneObjectAction(ob);
425   if (action) {
426     FCurve *fcu = (FCurve *)action->curves.first;
427
428     for (; fcu; fcu = fcu->next) {
429       object_type = BC_ANIMATION_TYPE_OBJECT;
430       if (ob->type == OB_ARMATURE) {
431         char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
432         if (boneName) {
433           object_type = BC_ANIMATION_TYPE_BONE;
434         }
435       }
436
437       /* Adding action curves on object */
438       BCCurveKey key(object_type, fcu->rna_path, fcu->array_index);
439       curves[key] = new BCAnimationCurve(key, ob, fcu);
440     }
441   }
442
443   /* Add missing curves */
444   object_type = BC_ANIMATION_TYPE_OBJECT;
445   generate_transforms(ob, EMPTY_STRING, object_type, curves);
446   if (ob->type == OB_ARMATURE) {
447     bArmature *arm = (bArmature *)ob->data;
448     for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next)
449       generate_transforms(ob, root_bone, curves);
450   }
451
452   /* Add curves on Object->data actions */
453   action = NULL;
454   if (ob->type == OB_CAMERA) {
455     action = bc_getSceneCameraAction(ob);
456     object_type = BC_ANIMATION_TYPE_CAMERA;
457   }
458   else if (ob->type == OB_LAMP) {
459     action = bc_getSceneLightAction(ob);
460     object_type = BC_ANIMATION_TYPE_LIGHT;
461   }
462
463   if (action) {
464     /* Add light action or Camera action */
465     FCurve *fcu = (FCurve *)action->curves.first;
466     for (; fcu; fcu = fcu->next) {
467       BCCurveKey key(object_type, fcu->rna_path, fcu->array_index);
468       curves[key] = new BCAnimationCurve(key, ob, fcu);
469     }
470   }
471
472   /* Add curves on Object->material actions*/
473   object_type = BC_ANIMATION_TYPE_MATERIAL;
474   for (int a = 0; a < ob->totcol; a++) {
475     /* Export Material parameter animations. */
476     Material *ma = give_current_material(ob, a + 1);
477     if (ma) {
478       action = bc_getSceneMaterialAction(ma);
479       if (action) {
480         /* isMatAnim = true; */
481         FCurve *fcu = (FCurve *)action->curves.first;
482         for (; fcu; fcu = fcu->next) {
483           BCCurveKey key(object_type, fcu->rna_path, fcu->array_index, a);
484           curves[key] = new BCAnimationCurve(key, ob, fcu);
485         }
486       }
487     }
488   }
489 }
490
491 /* ==================================================================== */
492
493 BCSample &BCSampleFrame::add(Object *ob)
494 {
495   BCSample *sample = new BCSample(ob);
496   sampleMap[ob] = sample;
497   return *sample;
498 }
499
500 /* Get the matrix for the given key, returns Unity when the key does not exist */
501 const BCSample *BCSampleFrame::get_sample(Object *ob) const
502 {
503   BCSampleMap::const_iterator it = sampleMap.find(ob);
504   if (it == sampleMap.end()) {
505     return NULL;
506   }
507   return it->second;
508 }
509
510 const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob) const
511 {
512   BCSampleMap::const_iterator it = sampleMap.find(ob);
513   if (it == sampleMap.end()) {
514     return NULL;
515   }
516   BCSample *sample = it->second;
517   return &sample->get_matrix();
518 }
519
520 /* Get the matrix for the given Bone, returns Unity when the Objewct is not sampled */
521 const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob, Bone *bone) const
522 {
523   BCSampleMap::const_iterator it = sampleMap.find(ob);
524   if (it == sampleMap.end()) {
525     return NULL;
526   }
527
528   BCSample *sample = it->second;
529   const BCMatrix *bc_bone = sample->get_matrix(bone);
530   return bc_bone;
531 }
532
533 /* Check if the key is in this BCSampleFrame */
534 const bool BCSampleFrame::has_sample_for(Object *ob) const
535 {
536   return sampleMap.find(ob) != sampleMap.end();
537 }
538
539 /* Check if the Bone is in this BCSampleFrame */
540 const bool BCSampleFrame::has_sample_for(Object *ob, Bone *bone) const
541 {
542   const BCMatrix *bc_bone = get_sample_matrix(ob, bone);
543   return (bc_bone);
544 }
545
546 /* ==================================================================== */
547
548 BCSample &BCSampleFrameContainer::add(Object *ob, int frame_index)
549 {
550   BCSampleFrame &frame = sample_frames[frame_index];
551   return frame.add(ob);
552 }
553
554 /* ====================================================== */
555 /* Below are the getters which we need to export the data */
556 /* ====================================================== */
557
558 /* Return either the BCSampleFrame or NULL if frame does not exist*/
559 BCSampleFrame *BCSampleFrameContainer::get_frame(int frame_index)
560 {
561   BCSampleFrameMap::iterator it = sample_frames.find(frame_index);
562   BCSampleFrame *frame = (it == sample_frames.end()) ? NULL : &it->second;
563   return frame;
564 }
565
566 /* Return a list of all frames that need to be sampled */
567 const int BCSampleFrameContainer::get_frames(std::vector<int> &frames) const
568 {
569   frames.clear();  // safety;
570   BCSampleFrameMap::const_iterator it;
571   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
572     frames.push_back(it->first);
573   }
574   return frames.size();
575 }
576
577 const int BCSampleFrameContainer::get_frames(Object *ob, BCFrames &frames) const
578 {
579   frames.clear();  // safety;
580   BCSampleFrameMap::const_iterator it;
581   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
582     const BCSampleFrame &frame = it->second;
583     if (frame.has_sample_for(ob)) {
584       frames.push_back(it->first);
585     }
586   }
587   return frames.size();
588 }
589
590 const int BCSampleFrameContainer::get_frames(Object *ob, Bone *bone, BCFrames &frames) const
591 {
592   frames.clear();  // safety;
593   BCSampleFrameMap::const_iterator it;
594   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
595     const BCSampleFrame &frame = it->second;
596     if (frame.has_sample_for(ob, bone)) {
597       frames.push_back(it->first);
598     }
599   }
600   return frames.size();
601 }
602
603 const int BCSampleFrameContainer::get_samples(Object *ob, BCFrameSampleMap &samples) const
604 {
605   samples.clear();  // safety;
606   BCSampleFrameMap::const_iterator it;
607   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
608     const BCSampleFrame &frame = it->second;
609     const BCSample *sample = frame.get_sample(ob);
610     if (sample) {
611       samples[it->first] = sample;
612     }
613   }
614   return samples.size();
615 }
616
617 const int BCSampleFrameContainer::get_matrices(Object *ob, BCMatrixSampleMap &samples) const
618 {
619   samples.clear();  // safety;
620   BCSampleFrameMap::const_iterator it;
621   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
622     const BCSampleFrame &frame = it->second;
623     const BCMatrix *matrix = frame.get_sample_matrix(ob);
624     if (matrix) {
625       samples[it->first] = matrix;
626     }
627   }
628   return samples.size();
629 }
630
631 const int BCSampleFrameContainer::get_matrices(Object *ob,
632                                                Bone *bone,
633                                                BCMatrixSampleMap &samples) const
634 {
635   samples.clear();  // safety;
636   BCSampleFrameMap::const_iterator it;
637   for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
638     const BCSampleFrame &frame = it->second;
639     const BCMatrix *sample = frame.get_sample_matrix(ob, bone);
640     if (sample) {
641       samples[it->first] = sample;
642     }
643   }
644   return samples.size();
645 }