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