Blender  V2.93
BCAnimationSampler.cpp
Go to the documentation of this file.
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 <algorithm> /* std::find */
21 #include <map>
22 #include <vector>
23 
24 #include "BCAnimationCurve.h"
25 #include "BCAnimationSampler.h"
26 #include "BCMath.h"
27 #include "ExportSettings.h"
28 #include "collada_utils.h"
29 
30 #include "BKE_action.h"
31 #include "BKE_constraint.h"
32 #include "BKE_key.h"
33 #include "BKE_lib_id.h"
34 #include "BKE_main.h"
35 #include "BKE_material.h"
36 
37 #include "BLI_listbase.h"
38 
39 #include "DNA_anim_types.h"
40 #include "DNA_constraint_types.h"
41 #include "DNA_key_types.h"
42 #include "DNA_scene_types.h"
43 
44 #include "ED_object.h"
45 
46 static std::string EMPTY_STRING;
48 
49 BCAnimationSampler::BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &object_set)
50  : export_settings(export_settings)
51 {
52  BCObjectSet::iterator it;
53  for (it = object_set.begin(); it != object_set.end(); ++it) {
54  Object *ob = *it;
55  add_object(ob);
56  }
57 }
58 
60 {
61  BCAnimationObjectMap::iterator it;
62  for (it = objects.begin(); it != objects.end(); ++it) {
63  BCAnimation *animation = it->second;
64  delete animation;
65  }
66 }
67 
69 {
70  BlenderContext blender_context = export_settings.get_blender_context();
71  BCAnimation *animation = new BCAnimation(blender_context.get_context(), ob);
72  objects[ob] = animation;
73 
74  initialize_keyframes(animation->frame_set, ob);
75  initialize_curves(animation->curve_map, ob);
76 }
77 
79 {
80  BCAnimation &animation = *objects[ob];
81  if (animation.curve_map.empty()) {
82  initialize_curves(animation.curve_map, ob);
83  }
84  return &animation.curve_map;
85 }
86 
87 static void get_sample_frames(BCFrameSet &sample_frames,
88  int sampling_rate,
89  bool keyframe_at_end,
90  Scene *scene)
91 {
92  sample_frames.clear();
93 
94  if (sampling_rate < 1) {
95  return; /* no sample frames in this case */
96  }
97 
98  float sfra = scene->r.sfra;
99  float efra = scene->r.efra;
100 
101  int frame_index;
102  for (frame_index = nearbyint(sfra); frame_index < efra; frame_index += sampling_rate) {
103  sample_frames.insert(frame_index);
104  }
105 
106  if (frame_index >= efra && keyframe_at_end) {
107  sample_frames.insert(efra);
108  }
109 }
110 
111 static bool is_object_keyframe(Object *ob, int frame_index)
112 {
113  return false;
114 }
115 
116 static void add_keyframes_from(bAction *action, BCFrameSet &frameset)
117 {
118  if (action) {
119  FCurve *fcu = nullptr;
120  for (fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) {
121  BezTriple *bezt = fcu->bezt;
122  for (int i = 0; i < fcu->totvert; bezt++, i++) {
123  int frame_index = nearbyint(bezt->vec[1][0]);
124  frameset.insert(frame_index);
125  }
126  }
127  }
128 }
129 
130 void BCAnimationSampler::check_property_is_animated(
131  BCAnimation &animation, float *ref, float *val, std::string data_path, int length)
132 {
133  for (int array_index = 0; array_index < length; array_index++) {
134  if (!bc_in_range(ref[length], val[length], 0.00001)) {
135  BCCurveKey key(BC_ANIMATION_TYPE_OBJECT, data_path, array_index);
136  BCAnimationCurveMap::iterator it = animation.curve_map.find(key);
137  if (it == animation.curve_map.end()) {
138  animation.curve_map[key] = new BCAnimationCurve(key, animation.get_reference());
139  }
140  }
141  }
142 }
143 
144 void BCAnimationSampler::update_animation_curves(BCAnimation &animation,
145  BCSample &sample,
146  Object *ob,
147  int frame)
148 {
149  BCAnimationCurveMap::iterator it;
150  for (it = animation.curve_map.begin(); it != animation.curve_map.end(); ++it) {
151  BCAnimationCurve *curve = it->second;
152  if (curve->is_transform_curve()) {
153  curve->add_value_from_matrix(sample, frame);
154  }
155  else {
156  curve->add_value_from_rna(frame);
157  }
158  }
159 }
160 
161 BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool for_opensim)
162 {
163  BCSample &ob_sample = sample_data.add(ob, frame_index);
164  // if (export_settings.get_apply_global_orientation()) {
165  // const BCMatrix &global_transform = export_settings.get_global_transform();
166  // ob_sample.get_matrix(global_transform);
167  //}
168 
169  if (ob->type == OB_ARMATURE) {
170  bPoseChannel *pchan;
171  for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
172  Bone *bone = pchan->bone;
173  Matrix bmat;
174  if (bc_bone_matrix_local_get(ob, bone, bmat, for_opensim)) {
175 
176  ob_sample.add_bone_matrix(bone, bmat);
177  }
178  }
179  }
180  return ob_sample;
181 }
182 
183 void BCAnimationSampler::sample_scene(BCExportSettings &export_settings, bool keyframe_at_end)
184 {
185  BlenderContext blender_context = export_settings.get_blender_context();
186  int sampling_rate = export_settings.get_sampling_rate();
187  bool for_opensim = export_settings.get_open_sim();
188  bool keep_keyframes = export_settings.get_keep_keyframes();
189  BC_export_animation_type export_animation_type = export_settings.get_export_animation_type();
190 
191  Scene *scene = blender_context.get_scene();
192  BCFrameSet scene_sample_frames;
193  get_sample_frames(scene_sample_frames, sampling_rate, keyframe_at_end, scene);
194  BCFrameSet::iterator it;
195 
196  int startframe = scene->r.sfra;
197  int endframe = scene->r.efra;
198 
199  for (int frame_index = startframe; frame_index <= endframe; frame_index++) {
200  /* Loop over all frames and decide for each frame if sampling is necessary */
201  bool is_scene_sample_frame = false;
202  bool needs_update = true;
203  if (scene_sample_frames.find(frame_index) != scene_sample_frames.end()) {
204  bc_update_scene(blender_context, frame_index);
205  needs_update = false;
206  is_scene_sample_frame = true;
207  }
208 
209  bool needs_sampling = is_scene_sample_frame || keep_keyframes ||
210  export_animation_type == BC_ANIMATION_EXPORT_KEYS;
211  if (!needs_sampling) {
212  continue;
213  }
214 
215  BCAnimationObjectMap::iterator obit;
216  for (obit = objects.begin(); obit != objects.end(); ++obit) {
217  Object *ob = obit->first;
218  BCAnimation *animation = obit->second;
219  BCFrameSet &object_keyframes = animation->frame_set;
220  if (is_scene_sample_frame || object_keyframes.find(frame_index) != object_keyframes.end()) {
221 
222  if (needs_update) {
223  bc_update_scene(blender_context, frame_index);
224  needs_update = false;
225  }
226 
227  BCSample &sample = sample_object(ob, frame_index, for_opensim);
228  update_animation_curves(*animation, sample, ob, frame_index);
229  }
230  }
231  }
232 }
233 
235  ListBase *conlist,
236  std::set<Object *> &animated_objects)
237 {
238  bConstraint *con;
239  for (con = (bConstraint *)conlist->first; con; con = con->next) {
240  ListBase targets = {nullptr, nullptr};
241 
243 
244  if (!bc_validateConstraints(con)) {
245  continue;
246  }
247 
248  if (cti && cti->get_constraint_targets) {
249  bConstraintTarget *ct;
250  Object *obtar;
251  cti->get_constraint_targets(con, &targets);
252  for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) {
253  obtar = ct->tar;
254  if (obtar) {
255  if (animated_objects.find(obtar) != animated_objects.end()) {
256  return true;
257  }
258  }
259  }
260  }
261  }
262  return false;
263 }
264 
265 void BCAnimationSampler::find_depending_animated(std::set<Object *> &animated_objects,
266  std::set<Object *> &candidates)
267 {
268  bool found_more;
269  do {
270  found_more = false;
271  std::set<Object *>::iterator it;
272  for (it = candidates.begin(); it != candidates.end(); ++it) {
273  Object *cob = *it;
275  if (is_animated_by_constraint(cob, conlist, animated_objects)) {
276  animated_objects.insert(cob);
277  candidates.erase(cob);
278  found_more = true;
279  break;
280  }
281  }
282  } while (found_more && !candidates.empty());
283 }
284 
285 void BCAnimationSampler::get_animated_from_export_set(std::set<Object *> &animated_objects,
286  LinkNode &export_set)
287 {
288  /* Check if this object is animated. That is: Check if it has its own action, or:
289  *
290  * - Check if it has constraints to other objects.
291  * - at least one of the other objects is animated as well.
292  */
293 
294  animated_objects.clear();
295  std::set<Object *> static_objects;
296  std::set<Object *> candidates;
297 
298  LinkNode *node;
299  for (node = &export_set; node; node = node->next) {
300  Object *cob = (Object *)node->link;
301  if (bc_has_animations(cob)) {
302  animated_objects.insert(cob);
303  }
304  else {
305  ListBase conlist = cob->constraints;
306  if (conlist.first) {
307  candidates.insert(cob);
308  }
309  }
310  }
311  find_depending_animated(animated_objects, candidates);
312 }
313 
315 {
316  sample_data.get_frames(ob, frames);
317 }
318 
320 {
321  sample_data.get_frames(ob, bone, frames);
322 }
323 
325 {
326  sample_data.get_matrices(ob, bone, samples);
327  return bc_is_animated(samples);
328 }
329 
331 {
332  sample_data.get_matrices(ob, samples);
333  return bc_is_animated(samples);
334 }
335 
336 #if 0
349 void BCAnimationSampler::add_value_set(BCAnimationCurve &curve,
350  BCFrameSampleMap &samples,
351  BC_export_animation_type animation_type)
352 {
353  int array_index = curve.get_array_index();
354  const BC_animation_transform_type tm_type = curve.get_transform_type();
355 
356  BCFrameSampleMap::iterator it;
357  for (it = samples.begin(); it != samples.end(); ++it) {
358  const int frame_index = nearbyint(it->first);
359  if (animation_type == BC_ANIMATION_EXPORT_SAMPLES || curve.is_keyframe(frame_index)) {
360 
361  const BCSample *sample = it->second;
362  float val = 0;
363 
364  int subindex = curve.get_subindex();
365  bool good;
366  if (subindex == -1) {
367  good = sample->get_value(tm_type, array_index, &val);
368  }
369  else {
370  good = sample->get_value(tm_type, array_index, &val, subindex);
371  }
372 
373  if (good) {
374  curve.add_value(val, frame_index);
375  }
376  }
377  }
378  curve.remove_unused_keyframes();
379  curve.calchandles();
380 }
381 #endif
382 
383 void BCAnimationSampler::generate_transform(Object *ob,
384  const BCCurveKey &key,
385  BCAnimationCurveMap &curves)
386 {
387  BCAnimationCurveMap::const_iterator it = curves.find(key);
388  if (it == curves.end()) {
389  curves[key] = new BCAnimationCurve(key, ob);
390  }
391 }
392 
393 void BCAnimationSampler::generate_transforms(Object *ob,
394  const std::string prep,
395  const BC_animation_type type,
396  BCAnimationCurveMap &curves)
397 {
398  generate_transform(ob, BCCurveKey(type, prep + "location", 0), curves);
399  generate_transform(ob, BCCurveKey(type, prep + "location", 1), curves);
400  generate_transform(ob, BCCurveKey(type, prep + "location", 2), curves);
401  generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 0), curves);
402  generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 1), curves);
403  generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 2), curves);
404  generate_transform(ob, BCCurveKey(type, prep + "scale", 0), curves);
405  generate_transform(ob, BCCurveKey(type, prep + "scale", 1), curves);
406  generate_transform(ob, BCCurveKey(type, prep + "scale", 2), curves);
407 }
408 
409 void BCAnimationSampler::generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves)
410 {
411  std::string prep = "pose.bones[\"" + std::string(bone->name) + "\"].";
412  generate_transforms(ob, prep, BC_ANIMATION_TYPE_BONE, curves);
413 
414  for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
415  generate_transforms(ob, child, curves);
416  }
417 }
418 
424 void BCAnimationSampler::initialize_keyframes(BCFrameSet &frameset, Object *ob)
425 {
426  frameset.clear();
430 
431  for (int a = 0; a < ob->totcol; a++) {
432  Material *ma = BKE_object_material_get(ob, a + 1);
434  }
435 }
436 
437 void BCAnimationSampler::initialize_curves(BCAnimationCurveMap &curves, Object *ob)
438 {
440 
441  bAction *action = bc_getSceneObjectAction(ob);
442  if (action) {
443  FCurve *fcu = (FCurve *)action->curves.first;
444 
445  for (; fcu; fcu = fcu->next) {
446  object_type = BC_ANIMATION_TYPE_OBJECT;
447  if (ob->type == OB_ARMATURE) {
448  char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
449  if (boneName) {
450  object_type = BC_ANIMATION_TYPE_BONE;
451  MEM_freeN(boneName);
452  }
453  }
454 
455  /* Adding action curves on object */
456  BCCurveKey key(object_type, fcu->rna_path, fcu->array_index);
457  curves[key] = new BCAnimationCurve(key, ob, fcu);
458  }
459  }
460 
461  /* Add missing curves */
462  object_type = BC_ANIMATION_TYPE_OBJECT;
463  generate_transforms(ob, EMPTY_STRING, object_type, curves);
464  if (ob->type == OB_ARMATURE) {
465  bArmature *arm = (bArmature *)ob->data;
466  for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next) {
467  generate_transforms(ob, root_bone, curves);
468  }
469  }
470 
471  /* Add curves on Object->data actions */
472  action = nullptr;
473  if (ob->type == OB_CAMERA) {
474  action = bc_getSceneCameraAction(ob);
475  object_type = BC_ANIMATION_TYPE_CAMERA;
476  }
477  else if (ob->type == OB_LAMP) {
478  action = bc_getSceneLightAction(ob);
479  object_type = BC_ANIMATION_TYPE_LIGHT;
480  }
481 
482  if (action) {
483  /* Add light action or Camera action */
484  FCurve *fcu = (FCurve *)action->curves.first;
485  for (; fcu; fcu = fcu->next) {
486  BCCurveKey key(object_type, fcu->rna_path, fcu->array_index);
487  curves[key] = new BCAnimationCurve(key, ob, fcu);
488  }
489  }
490 
491  /* Add curves on Object->material actions*/
492  object_type = BC_ANIMATION_TYPE_MATERIAL;
493  for (int a = 0; a < ob->totcol; a++) {
494  /* Export Material parameter animations. */
495  Material *ma = BKE_object_material_get(ob, a + 1);
496  if (ma) {
497  action = bc_getSceneMaterialAction(ma);
498  if (action) {
499  /* isMatAnim = true; */
500  FCurve *fcu = (FCurve *)action->curves.first;
501  for (; fcu; fcu = fcu->next) {
502  BCCurveKey key(object_type, fcu->rna_path, fcu->array_index, a);
503  curves[key] = new BCAnimationCurve(key, ob, fcu);
504  }
505  }
506  }
507  }
508 }
509 
510 /* ==================================================================== */
511 
513 {
514  BCSample *sample = new BCSample(ob);
515  sampleMap[ob] = sample;
516  return *sample;
517 }
518 
519 /* Get the matrix for the given key, returns Unity when the key does not exist */
521 {
522  BCSampleMap::const_iterator it = sampleMap.find(ob);
523  if (it == sampleMap.end()) {
524  return nullptr;
525  }
526  return it->second;
527 }
528 
530 {
531  BCSampleMap::const_iterator it = sampleMap.find(ob);
532  if (it == sampleMap.end()) {
533  return nullptr;
534  }
535  BCSample *sample = it->second;
536  return &sample->get_matrix();
537 }
538 
539 /* Get the matrix for the given Bone, returns Unity when the Object is not sampled. */
541 {
542  BCSampleMap::const_iterator it = sampleMap.find(ob);
543  if (it == sampleMap.end()) {
544  return nullptr;
545  }
546 
547  BCSample *sample = it->second;
548  const BCMatrix *bc_bone = sample->get_matrix(bone);
549  return bc_bone;
550 }
551 
552 /* Check if the key is in this BCSampleFrame */
554 {
555  return sampleMap.find(ob) != sampleMap.end();
556 }
557 
558 /* Check if the Bone is in this BCSampleFrame */
560 {
561  const BCMatrix *bc_bone = get_sample_matrix(ob, bone);
562  return bc_bone;
563 }
564 
565 /* ==================================================================== */
566 
568 {
569  BCSampleFrame &frame = sample_frames[frame_index];
570  return frame.add(ob);
571 }
572 
573 /* ====================================================== */
574 /* Below are the getters which we need to export the data */
575 /* ====================================================== */
576 
577 /* Return either the BCSampleFrame or NULL if frame does not exist*/
579 {
580  BCSampleFrameMap::iterator it = sample_frames.find(frame_index);
581  BCSampleFrame *frame = (it == sample_frames.end()) ? nullptr : &it->second;
582  return frame;
583 }
584 
585 /* Return a list of all frames that need to be sampled */
586 int BCSampleFrameContainer::get_frames(std::vector<int> &frames) const
587 {
588  frames.clear(); /* safety; */
589  BCSampleFrameMap::const_iterator it;
590  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
591  frames.push_back(it->first);
592  }
593  return frames.size();
594 }
595 
597 {
598  frames.clear(); /* safety; */
599  BCSampleFrameMap::const_iterator it;
600  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
601  const BCSampleFrame &frame = it->second;
602  if (frame.has_sample_for(ob)) {
603  frames.push_back(it->first);
604  }
605  }
606  return frames.size();
607 }
608 
610 {
611  frames.clear(); /* safety; */
612  BCSampleFrameMap::const_iterator it;
613  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
614  const BCSampleFrame &frame = it->second;
615  if (frame.has_sample_for(ob, bone)) {
616  frames.push_back(it->first);
617  }
618  }
619  return frames.size();
620 }
621 
623 {
624  samples.clear(); /* safety; */
625  BCSampleFrameMap::const_iterator it;
626  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
627  const BCSampleFrame &frame = it->second;
628  const BCSample *sample = frame.get_sample(ob);
629  if (sample) {
630  samples[it->first] = sample;
631  }
632  }
633  return samples.size();
634 }
635 
637 {
638  samples.clear(); /* safety; */
639  BCSampleFrameMap::const_iterator it;
640  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
641  const BCSampleFrame &frame = it->second;
642  const BCMatrix *matrix = frame.get_sample_matrix(ob);
643  if (matrix) {
644  samples[it->first] = matrix;
645  }
646  }
647  return samples.size();
648 }
649 
651 {
652  samples.clear(); /* safety; */
653  BCSampleFrameMap::const_iterator it;
654  for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
655  const BCSampleFrame &frame = it->second;
656  const BCMatrix *sample = frame.get_sample_matrix(ob, bone);
657  if (sample) {
658  samples[it->first] = sample;
659  }
660  }
661  return samples.size();
662 }
BC_animation_type
@ BC_ANIMATION_TYPE_MATERIAL
@ BC_ANIMATION_TYPE_LIGHT
@ BC_ANIMATION_TYPE_OBJECT
@ BC_ANIMATION_TYPE_BONE
@ BC_ANIMATION_TYPE_CAMERA
std::map< BCCurveKey, BCAnimationCurve * > BCAnimationCurveMap
std::vector< float > BCFrames
std::set< float > BCFrameSet
static BCAnimationCurveMap BCEmptyAnimationCurves
static bool is_object_keyframe(Object *ob, int frame_index)
static void add_keyframes_from(bAction *action, BCFrameSet &frameset)
static void get_sample_frames(BCFrameSet &sample_frames, int sampling_rate, bool keyframe_at_end, Scene *scene)
static std::string EMPTY_STRING
std::map< int, const BCSample * > BCFrameSampleMap
Definition: BCSampleData.h:62
std::map< int, const BCMatrix * > BCMatrixSampleMap
Definition: BCSampleData.h:63
Blender kernel action and pose functionality.
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
Definition: constraint.c:5435
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
char * BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:432
@ OB_CAMERA
@ OB_ARMATURE
@ OB_LAMP
struct ListBase * ED_object_constraint_active_list(struct Object *ob)
BC_export_animation_type
@ BC_ANIMATION_EXPORT_KEYS
@ BC_ANIMATION_EXPORT_SAMPLES
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
void get_object_frames(BCFrames &frames, Object *ob)
static void find_depending_animated(std::set< Object * > &animated_objects, std::set< Object * > &candidates)
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)
void get_bone_frames(BCFrames &frames, Object *ob, Bone *bone)
BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &object_set)
void add_object(Object *ob)
void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end)
static bool is_animated_by_constraint(Object *ob, ListBase *conlist, std::set< Object * > &animated_objects)
bool get_object_samples(BCMatrixSampleMap &samples, Object *ob)
BCAnimationCurveMap * get_curves(Object *ob)
Object * get_reference()
BCFrameSet frame_set
BCAnimationCurveMap curve_map
BCSample & add(Object *ob, int frame_index)
int get_frames(std::vector< int > &frames) const
BCSampleFrame * get_frame(int frame_index)
int get_samples(Object *ob, BCFrameSampleMap &samples) const
int get_matrices(Object *ob, BCMatrixSampleMap &samples) const
const BCMatrix * get_sample_matrix(Object *ob) const
bool has_sample_for(Object *ob) const
const BCSample * get_sample(Object *ob) const
BCSample & add(Object *ob)
void add_bone_matrix(Bone *bone, Matrix &mat)
bool bc_has_animations(Object *ob)
bool bc_is_animated(BCMatrixSampleMap &values)
bool bc_validateConstraints(bConstraint *con)
void bc_update_scene(BlenderContext &blender_context, float ctime)
bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim)
std::set< Object * > BCObjectSet
Definition: collada_utils.h:72
bAction * bc_getSceneObjectAction(Object *ob)
Definition: collada_utils.h:82
bool bc_in_range(float a, float b, float range)
bAction * bc_getSceneLightAction(Object *ob)
Definition: collada_utils.h:88
bAction * bc_getSceneMaterialAction(Material *ma)
bAction * bc_getSceneCameraAction(Object *ob)
Definition: collada_utils.h:99
OperationNode * node
Scene scene
Curve curve
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static unsigned a[3]
Definition: RandGen.cpp:92
static void sample(SocketReader *reader, int x, int y, float color[4])
float vec[3][3]
char name[64]
ListBase childbase
struct FCurve * next
char * rna_path
BezTriple * bezt
int array_index
unsigned int totvert
void * first
Definition: DNA_listBase.h:47
ListBase constraints
struct bPose * pose
void * data
struct RenderData r
ListBase curves
ListBase bonebase
struct bConstraintTarget * next
int(* get_constraint_targets)(struct bConstraint *con, struct ListBase *list)
struct bConstraint * next
struct Bone * bone
struct bPoseChannel * next
ListBase chanbase