Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BCAnimationSampler.h « collada « io « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c78590b8e37666a06f84d3313d2357edf849358e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#pragma once

#include "BCAnimationCurve.h"
#include "BCSampleData.h"
#include "collada_utils.h"

#include "BKE_action.h"
#include "BKE_lib_id.h"

#include "BLI_math_rotation.h"

#include "DNA_action_types.h"

/* Collection of animation curves */
class BCAnimation {
 private:
  Object *reference = NULL;
  bContext *mContext;

 public:
  BCFrameSet frame_set;
  BCAnimationCurveMap curve_map;

  BCAnimation(bContext *C, Object *ob) : mContext(C)
  {
    Main *bmain = CTX_data_main(mContext);
    reference = (Object *)BKE_id_copy(bmain, &ob->id);
    id_us_min(&reference->id);
  }

  ~BCAnimation()
  {
    BCAnimationCurveMap::iterator it;
    for (it = curve_map.begin(); it != curve_map.end(); ++it) {
      delete it->second;
    }

    if (reference && reference->id.us == 0) {
      Main *bmain = CTX_data_main(mContext);
      BKE_id_delete(bmain, &reference->id);
    }
    curve_map.clear();
  }

  Object *get_reference()
  {
    return reference;
  }
};

typedef std::map<Object *, BCAnimation *> BCAnimationObjectMap;

class BCSampleFrame {

  /* Each frame on the timeline that needs to be sampled will have
   * one BCSampleFrame where we collect sample information about all objects
   * that need to be sampled for that frame. */

 private:
  BCSampleMap sampleMap;

 public:
  ~BCSampleFrame()
  {
    BCSampleMap::iterator it;
    for (it = sampleMap.begin(); it != sampleMap.end(); ++it) {
      BCSample *sample = it->second;
      delete sample;
    }
    sampleMap.clear();
  }

  BCSample &add(Object *ob);

  /* Following methods return NULL if object is not in the sampleMap. */

  /** Get the matrix for the given key, returns Unity when the key does not exist. */
  const BCSample *get_sample(Object *ob) const;
  const BCMatrix *get_sample_matrix(Object *ob) const;
  /** Get the matrix for the given Bone, returns Unity when the Object is not sampled. */
  const BCMatrix *get_sample_matrix(Object *ob, Bone *bone) const;

  /** Check if the key is in this BCSampleFrame. */
  bool has_sample_for(Object *ob) const;
  /** Check if the Bone is in this BCSampleFrame. */
  bool has_sample_for(Object *ob, Bone *bone) const;
};

typedef std::map<int, BCSampleFrame> BCSampleFrameMap;

class BCSampleFrameContainer {

  /*
   * The BCSampleFrameContainer stores a map of BCSampleFrame objects
   * with the timeline frame as key.
   *
   * Some details on the purpose:
   * An Animation is made of multiple FCurves where each FCurve can
   * have multiple keyframes. When we want to export the animation we
   * also can decide whether we want to export the keyframes or a set
   * of sample frames at equidistant locations (sample period).
   * In any case we must resample first need to resample it fully
   * to resolve things like:
   *
   * - animations by constraints
   * - animations by drivers
   *
   * For this purpose we need to step through the entire animation and
   * then sample each frame that contains at least one keyFrame or
   * sampleFrame. Then for each frame we have to store the transform
   * information for all exported objects in a BCSampleframe
   *
   * The entire set of BCSampleframes is finally collected into
   * a BCSampleframneContainer
   */

 private:
  BCSampleFrameMap sample_frames;

 public:
  ~BCSampleFrameContainer()
  {
  }

  BCSample &add(Object *ob, int frame_index);
  /** Return either the #BCSampleFrame or NULL if frame does not exist. */
  BCSampleFrame *get_frame(int frame_index);

  /** Return a list of all frames that need to be sampled. */
  int get_frames(std::vector<int> &frames) const;
  int get_frames(Object *ob, BCFrames &frames) const;
  int get_frames(Object *ob, Bone *bone, BCFrames &frames) const;

  int get_samples(Object *ob, BCFrameSampleMap &samples) const;
  int get_matrices(Object *ob, BCMatrixSampleMap &samples) const;
  int get_matrices(Object *ob, Bone *bone, BCMatrixSampleMap &samples) const;
};

class BCAnimationSampler {
 private:
  BCExportSettings &export_settings;
  BCSampleFrameContainer sample_data;
  BCAnimationObjectMap objects;

  void generate_transform(Object *ob, const BCCurveKey &key, BCAnimationCurveMap &curves);
  void generate_transforms(Object *ob,
                           const std::string prep,
                           const BC_animation_type type,
                           BCAnimationCurveMap &curves);
  void generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves);

  void initialize_curves(BCAnimationCurveMap &curves, Object *ob);
  /**
   * Collect all keyframes from all animation curves related to the object.
   * The bc_get... functions check for NULL and correct object type.
   * The #add_keyframes_from() function checks for NULL.
   */
  void initialize_keyframes(BCFrameSet &frameset, Object *ob);
  BCSample &sample_object(Object *ob, int frame_index, bool for_opensim);
  void update_animation_curves(BCAnimation &animation,
                               BCSample &sample,
                               Object *ob,
                               int frame_index);
  void check_property_is_animated(
      BCAnimation &animation, float *ref, float *val, std::string data_path, int length);

 public:
  BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &object_set);
  ~BCAnimationSampler();

  void add_object(Object *ob);

  void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end);

  BCAnimationCurveMap *get_curves(Object *ob);
  void get_object_frames(BCFrames &frames, Object *ob);
  bool get_object_samples(BCMatrixSampleMap &samples, Object *ob);
  void get_bone_frames(BCFrames &frames, Object *ob, Bone *bone);
  bool get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone);

  static void get_animated_from_export_set(std::set<Object *> &animated_objects,
                                           LinkNode &export_set);
  static void find_depending_animated(std::set<Object *> &animated_objects,
                                      std::set<Object *> &candidates);
  static bool is_animated_by_constraint(Object *ob,
                                        ListBase *conlist,
                                        std::set<Object *> &animated_objects);
};