Fix T67389: Transform constraints fail at large distances
[blender.git] / source / blender / collada / BCAnimationSampler.h
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
17 #ifndef __BC_ANIMATION_CURVE_CONTAINER_H__
18 #define __BC_ANIMATION_CURVE_CONTAINER_H__
19
20 #include "BCAnimationCurve.h"
21 #include "BCSampleData.h"
22 #include "collada_utils.h"
23
24 extern "C" {
25 #include "BKE_action.h"
26 #include "BKE_library.h"
27 #include "BLI_math_rotation.h"
28 #include "DNA_action_types.h"
29 }
30
31 /* Collection of animation curves */
32 class BCAnimation {
33  private:
34   Object *reference = NULL;
35   bContext *mContext;
36
37  public:
38   BCFrameSet frame_set;
39   BCAnimationCurveMap curve_map;
40
41   BCAnimation(bContext *C, Object *ob) : mContext(C)
42   {
43     Main *bmain = CTX_data_main(mContext);
44     reference = BKE_object_copy(bmain, ob);
45   }
46
47   ~BCAnimation()
48   {
49     BCAnimationCurveMap::iterator it;
50     for (it = curve_map.begin(); it != curve_map.end(); ++it) {
51       delete it->second;
52     }
53
54     if (reference && reference->id.us == 0) {
55       Main *bmain = CTX_data_main(mContext);
56       BKE_id_delete(bmain, &reference->id);
57     }
58     curve_map.clear();
59   }
60
61   Object *get_reference()
62   {
63     return reference;
64   }
65 };
66
67 typedef std::map<Object *, BCAnimation *> BCAnimationObjectMap;
68
69 class BCSampleFrame {
70
71   /* Each frame on the timeline that needs to be sampled will have
72    * one BCSampleFrame where we collect sample information about all objects
73    * that need to be sampled for that frame. */
74
75  private:
76   BCSampleMap sampleMap;
77
78  public:
79   ~BCSampleFrame()
80   {
81     BCSampleMap::iterator it;
82     for (it = sampleMap.begin(); it != sampleMap.end(); ++it) {
83       BCSample *sample = it->second;
84       delete sample;
85     }
86     sampleMap.clear();
87   }
88
89   BCSample &add(Object *ob);
90
91   /* Following methods return NULL if object is not in the sampleMap*/
92   const BCSample *get_sample(Object *ob) const;
93   const BCMatrix *get_sample_matrix(Object *ob) const;
94   const BCMatrix *get_sample_matrix(Object *ob, Bone *bone) const;
95
96   const bool has_sample_for(Object *ob) const;
97   const bool has_sample_for(Object *ob, Bone *bone) const;
98 };
99
100 typedef std::map<int, BCSampleFrame> BCSampleFrameMap;
101
102 class BCSampleFrameContainer {
103
104   /*
105    * The BCSampleFrameContainer stores a map of BCSampleFrame objects
106    * with the timeline frame as key.
107    *
108    * Some details on the purpose:
109    * An Animation is made of multiple FCurves where each FCurve can
110    * have multiple keyframes. When we want to export the animation we
111    * also can decide whether we want to export the keyframes or a set
112    * of sample frames at equidistant locations (sample period).
113    * In any case we must resample first need to resample it fully
114    * to resolve things like:
115    *
116    * - animations by constraints
117    * - animations by drivers
118    *
119    * For this purpose we need to step through the entire animation and
120    * then sample each frame that contains at least one keyFrame or
121    * sampleFrame. Then for each frame we have to store the transform
122    * information for all exported objects in a BCSampleframe
123    *
124    * The entire set of BCSampleframes is finally collected into
125    * a BCSampleframneContainer
126    */
127
128  private:
129   BCSampleFrameMap sample_frames;
130
131  public:
132   ~BCSampleFrameContainer()
133   {
134   }
135
136   BCSample &add(Object *ob, int frame_index);
137   BCSampleFrame *get_frame(int frame_index);  // returns NULL if frame does not exist
138
139   const int get_frames(std::vector<int> &frames) const;
140   const int get_frames(Object *ob, BCFrames &frames) const;
141   const int get_frames(Object *ob, Bone *bone, BCFrames &frames) const;
142
143   const int get_samples(Object *ob, BCFrameSampleMap &samples) const;
144   const int get_matrices(Object *ob, BCMatrixSampleMap &matrices) const;
145   const int get_matrices(Object *ob, Bone *bone, BCMatrixSampleMap &bones) const;
146 };
147
148 class BCAnimationSampler {
149  private:
150   BCExportSettings &export_settings;
151   BCSampleFrameContainer sample_data;
152   BCAnimationObjectMap objects;
153
154   void generate_transform(Object *ob, const BCCurveKey &key, BCAnimationCurveMap &curves);
155   void generate_transforms(Object *ob,
156                            const std::string prep,
157                            const BC_animation_type type,
158                            BCAnimationCurveMap &curves);
159   void generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves);
160
161   void initialize_curves(BCAnimationCurveMap &curves, Object *ob);
162   void initialize_keyframes(BCFrameSet &frameset, Object *ob);
163   BCSample &sample_object(Object *ob, int frame_index, bool for_opensim);
164   void update_animation_curves(BCAnimation &animation,
165                                BCSample &sample,
166                                Object *ob,
167                                int frame_index);
168   void check_property_is_animated(
169       BCAnimation &animation, float *ref, float *val, std::string data_path, int length);
170
171  public:
172   BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &animated_subset);
173   ~BCAnimationSampler();
174
175   void add_object(Object *ob);
176
177   void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end);
178
179   BCAnimationCurveMap *get_curves(Object *ob);
180   void get_object_frames(BCFrames &frames, Object *ob);
181   bool get_object_samples(BCMatrixSampleMap &samples, Object *ob);
182   void get_bone_frames(BCFrames &frames, Object *ob, Bone *bone);
183   bool get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone);
184
185   static void get_animated_from_export_set(std::set<Object *> &animated_objects,
186                                            LinkNode &export_set);
187   static void find_depending_animated(std::set<Object *> &animated_objects,
188                                       std::set<Object *> &candidates);
189   static bool is_animated_by_constraint(Object *ob,
190                                         ListBase *conlist,
191                                         std::set<Object *> &animated_objects);
192 };
193
194 #endif