Blender  V3.3
AnimationImporter.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <cstddef>
8 
9 /* COLLADABU_ASSERT, may be able to remove later */
10 #include "COLLADABUPlatform.h"
11 
12 #include "DNA_armature_types.h"
13 
14 #include "ED_keyframing.h"
15 
16 #include "BLI_listbase.h"
17 #include "BLI_math.h"
18 #include "BLI_string.h"
19 #include "BLI_string_utils.h"
20 
21 #include "BLT_translation.h"
22 
23 #include "BKE_action.h"
24 #include "BKE_armature.h"
25 #include "BKE_fcurve.h"
26 #include "BKE_object.h"
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "AnimationImporter.h"
31 #include "ArmatureImporter.h"
32 #include "MaterialExporter.h"
33 #include "collada_utils.h"
34 
35 #include <algorithm>
36 
37 /* first try node name, if not available (since is optional), fall back to original id */
38 template<class T> static const char *bc_get_joint_name(T *node)
39 {
40  const std::string &id = node->getName();
41  return id.empty() ? node->getOriginalId().c_str() : id.c_str();
42 }
43 
44 FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path)
45 {
46  FCurve *fcu = BKE_fcurve_create();
48  fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
49  fcu->array_index = array_index;
50  return fcu;
51 }
52 
53 void AnimationImporter::add_bezt(FCurve *fcu,
54  float frame,
55  float value,
57 {
58  // float fps = (float)FPS;
59  BezTriple bez;
60  memset(&bez, 0, sizeof(BezTriple));
61  bez.vec[1][0] = frame;
62  bez.vec[1][1] = value;
63  bez.ipo = ipo; /* use default interpolation mode here... */
64  bez.f1 = bez.f2 = bez.f3 = SELECT;
65  bez.h1 = bez.h2 = HD_AUTO;
68 }
69 
70 void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
71 {
72  COLLADAFW::FloatOrDoubleArray &input = curve->getInputValues();
73  COLLADAFW::FloatOrDoubleArray &output = curve->getOutputValues();
74 
75  float fps = (float)FPS;
76  size_t dim = curve->getOutDimension();
77  unsigned int i;
78 
79  std::vector<FCurve *> &fcurves = curve_map[curve->getUniqueId()];
80 
81  switch (dim) {
82  case 1: /* X, Y, Z or angle */
83  case 3: /* XYZ */
84  case 4:
85  case 16: /* matrix */
86  {
87  for (i = 0; i < dim; i++) {
88  FCurve *fcu = BKE_fcurve_create();
89 
91  fcu->array_index = 0;
92  fcu->auto_smoothing = U.auto_smoothing_new;
93 
94  for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
95  BezTriple bez;
96  memset(&bez, 0, sizeof(BezTriple));
97 
98  /* input, output */
99  bez.vec[1][0] = bc_get_float_value(input, j) * fps;
100  bez.vec[1][1] = bc_get_float_value(output, j * dim + i);
101  bez.h1 = bez.h2 = HD_AUTO;
102 
103  if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ||
104  curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP) {
105  COLLADAFW::FloatOrDoubleArray &intan = curve->getInTangentValues();
106  COLLADAFW::FloatOrDoubleArray &outtan = curve->getOutTangentValues();
107 
108  /* In-tangent. */
109  unsigned int index = 2 * (j * dim + i);
110  bez.vec[0][0] = bc_get_float_value(intan, index) * fps;
111  bez.vec[0][1] = bc_get_float_value(intan, index + 1);
112 
113  /* Out-tangent. */
114  bez.vec[2][0] = bc_get_float_value(outtan, index) * fps;
115  bez.vec[2][1] = bc_get_float_value(outtan, index + 1);
116  if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) {
117  bez.ipo = BEZT_IPO_BEZ;
118  bez.h1 = bez.h2 = HD_AUTO_ANIM;
119  }
120  else {
121  bez.ipo = BEZT_IPO_CONST;
122  }
123  }
124  else {
125  bez.ipo = BEZT_IPO_LIN;
126  }
127 #if 0
128  bez.ipo = U.ipo_new; /* use default interpolation mode here... */
129 #endif
130  bez.f1 = bez.f2 = bez.f3 = SELECT;
131 
133  }
134 
136 
137  fcurves.push_back(fcu);
138  unused_curves.push_back(fcu);
139  }
140  } break;
141  default:
142  fprintf(stderr,
143  "Output dimension of %d is not yet supported (animation id = %s)\n",
144  (int)dim,
145  curve->getOriginalId().c_str());
146  }
147 }
148 
149 void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
150 {
151  for (unsigned int i = 0; i < cu->totvert; i++) {
152  /* TODO: convert handles too. */
153  cu->bezt[i].vec[1][1] *= DEG2RADF(1.0f);
154  cu->bezt[i].vec[0][1] *= DEG2RADF(1.0f);
155  cu->bezt[i].vec[2][1] *= DEG2RADF(1.0f);
156  }
157 }
158 
159 void AnimationImporter::fcurve_scale(FCurve *cu, int scale)
160 {
161  for (unsigned int i = 0; i < cu->totvert; i++) {
162  /* TODO: convert handles too. */
163  cu->bezt[i].vec[1][1] *= scale;
164  cu->bezt[i].vec[0][1] *= scale;
165  cu->bezt[i].vec[2][1] *= scale;
166  }
167 }
168 
169 void AnimationImporter::fcurve_is_used(FCurve *fcu)
170 {
171  unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu),
172  unused_curves.end());
173 }
174 
175 void AnimationImporter::add_fcurves_to_object(Main *bmain,
176  Object *ob,
177  std::vector<FCurve *> &curves,
178  char *rna_path,
179  int array_index,
180  Animation *animated)
181 {
182  bAction *act;
183 
184  if (!ob->adt || !ob->adt->action) {
185  act = ED_id_action_ensure(bmain, (ID *)&ob->id);
186  }
187  else {
188  act = ob->adt->action;
189  }
190 
191  std::vector<FCurve *>::iterator it;
192  int i;
193 
194 #if 0
195  char *p = strstr(rna_path, "rotation_euler");
196  bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
197 
198  /* convert degrees to radians for rotation */
199  if (is_rotation) {
200  fcurve_deg_to_rad(fcu);
201  }
202 #endif
203 
204  for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
205  FCurve *fcu = *it;
206  fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
207 
208  if (array_index == -1) {
209  fcu->array_index = i;
210  }
211  else {
212  fcu->array_index = array_index;
213  }
214 
215  if (ob->type == OB_ARMATURE) {
216  bActionGroup *grp = nullptr;
217  const char *bone_name = bc_get_joint_name(animated->node);
218 
219  if (bone_name) {
220  /* try to find group */
221  grp = BKE_action_group_find_name(act, bone_name);
222 
223  /* no matching groups, so add one */
224  if (grp == nullptr) {
225  /* Add a new group, and make it active */
226  grp = MEM_cnew<bActionGroup>("bActionGroup");
227 
228  grp->flag = AGRP_SELECTED;
229  BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
230 
231  BLI_addtail(&act->groups, grp);
232  BLI_uniquename(&act->groups,
233  grp,
235  '.',
236  offsetof(bActionGroup, name),
237  64);
238  }
239 
240  /* add F-Curve to group */
241  action_groups_add_channel(act, grp, fcu);
242  fcurve_is_used(fcu);
243  }
244 #if 0
245  if (is_rotation) {
246  fcurves_actionGroup_map[grp].push_back(fcu);
247  }
248 #endif
249  }
250  else {
251  BLI_addtail(&act->curves, fcu);
252  fcurve_is_used(fcu);
253  }
254  }
255 }
256 
258 {
259  /* free unused FCurves */
260  for (FCurve *unused_curve : unused_curves) {
261  BKE_fcurve_free(unused_curve);
262  }
263 
264  if (!unused_curves.empty()) {
265  fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size());
266  }
267 }
268 
269 bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim)
270 {
271  if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
272  COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve *)anim;
273 
274  /* XXX Don't know if it's necessary
275  * Should we check outPhysicalDimension? */
276  if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
277  fprintf(stderr, "Inputs physical dimension is not time.\n");
278  return true;
279  }
280 
281  /* a curve can have mixed interpolation type,
282  * in this case curve->getInterpolationTypes returns a list of interpolation types per key */
284 
285  if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
286  switch (interp) {
288  case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
289  case COLLADAFW::AnimationCurve::INTERPOLATION_STEP:
290  animation_to_fcurves(curve);
291  break;
292  default:
293  /* TODO: there are also CARDINAL, HERMITE, BSPLINE and STEP types. */
294  fprintf(stderr,
295  "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n");
296  break;
297  }
298  }
299  else {
300  /* not supported yet */
301  fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
302  }
303  }
304  else {
305  fprintf(stderr, "FORMULA animation type is not supported yet.\n");
306  }
307 
308  return true;
309 }
310 
311 bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList *animlist)
312 {
313  const COLLADAFW::UniqueId &animlist_id = animlist->getUniqueId();
314  animlist_map[animlist_id] = animlist;
315 
316 #if 0
317 
318  /* should not happen */
319  if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
320  return true;
321  }
322 
323  /* for bones rna_path is like: pose.bones["bone-name"].rotation */
324 
325 #endif
326 
327  return true;
328 }
329 
331 {
332  float mat[4][4];
333  TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
334  if (ob) {
335  copy_m4_m4(ob->obmat, mat);
336  BKE_object_apply_mat4(ob, ob->obmat, false, false);
337  }
338 }
339 
340 #if 0
341 virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act)
342 {
343  bActionGroup *grp;
344  int i;
345 
346  for (grp = (bActionGroup *)act->groups.first; grp; grp = grp->next) {
347 
348  FCurve *eulcu[3] = {NULL, NULL, NULL};
349 
350  if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) {
351  continue;
352  }
353 
354  std::vector<FCurve *> &rot_fcurves = fcurves_actionGroup_map[grp];
355 
356  if (rot_fcurves.size() > 3) {
357  continue;
358  }
359 
360  for (i = 0; i < rot_fcurves.size(); i++) {
361  eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
362  }
363 
364  char joint_path[100];
365  char rna_path[100];
366 
367  char grp_name_esc[sizeof(grp->name) * 2];
368  BLI_str_escape(grp_name_esc, grp->name, sizeof(grp_name_esc));
369 
370  BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp_name_esc);
371  BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path);
372 
373  FCurve *quatcu[4] = {
374  create_fcurve(0, rna_path),
375  create_fcurve(1, rna_path),
376  create_fcurve(2, rna_path),
377  create_fcurve(3, rna_path),
378  };
379 
381 
382  float m4[4][4], irest[3][3];
383  invert_m4_m4(m4, chan->bone->arm_mat);
384  copy_m3_m4(irest, m4);
385 
386  for (i = 0; i < 3; i++) {
387 
388  FCurve *cu = eulcu[i];
389 
390  if (!cu) {
391  continue;
392  }
393 
394  for (int j = 0; j < cu->totvert; j++) {
395  float frame = cu->bezt[j].vec[1][0];
396 
397  float eul[3] = {
398  eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f,
399  eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f,
400  eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f,
401  };
402 
403  /* make eul relative to bone rest pose */
404  float rot[3][3], rel[3][3], quat[4];
405 
406 # if 0
407  eul_to_mat3(rot, eul);
408  mul_m3_m3m3(rel, irest, rot);
409  mat3_to_quat(quat, rel);
410 # endif
411 
412  eul_to_quat(quat, eul);
413 
414  for (int k = 0; k < 4; k++) {
415  create_bezt(quatcu[k], frame, quat[k], U.ipo_new);
416  }
417  }
418  }
419 
420  /* now replace old Euler curves */
421 
422  for (i = 0; i < 3; i++) {
423  if (!eulcu[i]) {
424  continue;
425  }
426 
427  action_groups_remove_channel(act, eulcu[i]);
428  BKE_fcurve_free(eulcu[i]);
429  }
430 
431  chan->rotmode = ROT_MODE_QUAT;
432 
433  for (i = 0; i < 4; i++) {
434  action_groups_add_channel(act, grp, quatcu[i]);
435  }
436  }
437 
438  bPoseChannel *pchan;
439  for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
440  pchan->rotmode = ROT_MODE_QUAT;
441  }
442 }
443 #endif
444 
445 void AnimationImporter::modify_fcurve(std::vector<FCurve *> *curves,
446  const char *rna_path,
447  int array_index,
448  int scale)
449 {
450  std::vector<FCurve *>::iterator it;
451  int i;
452  for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
453  FCurve *fcu = *it;
454  fcu->rna_path = BLI_strdup(rna_path);
455 
456  if (array_index == -1) {
457  fcu->array_index = i;
458  }
459  else {
460  fcu->array_index = array_index;
461  }
462 
463  if (scale != 1) {
464  fcurve_scale(fcu, scale);
465  }
466 
467  fcurve_is_used(fcu);
468  }
469 }
470 
471 void AnimationImporter::unused_fcurve(std::vector<FCurve *> *curves)
472 {
473  /* when an error happens and we can't actually use curve remove it from unused_curves */
474  std::vector<FCurve *>::iterator it;
475  for (it = curves->begin(); it != curves->end(); it++) {
476  FCurve *fcu = *it;
477  fcurve_is_used(fcu);
478  }
479 }
480 
481 void AnimationImporter::find_frames(std::vector<float> *frames, std::vector<FCurve *> *curves)
482 {
483  std::vector<FCurve *>::iterator iter;
484  for (iter = curves->begin(); iter != curves->end(); iter++) {
485  FCurve *fcu = *iter;
486 
487  for (unsigned int k = 0; k < fcu->totvert; k++) {
488  /* get frame value from bezTriple */
489  float fra = fcu->bezt[k].vec[1][0];
490  /* if frame already not added add frame to frames */
491  if (std::find(frames->begin(), frames->end(), fra) == frames->end()) {
492  frames->push_back(fra);
493  }
494  }
495  }
496 }
497 
499 {
500  int index;
501  if (COLLADABU::Math::Vector3::UNIT_X == axis) {
502  index = 0;
503  }
504  else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
505  index = 1;
506  }
507  else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
508  index = 2;
509  }
510  else {
511  index = -1;
512  }
513  return index;
514 }
515 
517  COLLADAFW::Transformation *transform,
518  const COLLADAFW::AnimationList::AnimationBinding *binding,
519  std::vector<FCurve *> *curves,
520  bool is_joint,
521  char *joint_path)
522 {
523  COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
524  bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
525  bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
526 
527  /* to check if the no of curves are valid */
528  bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||
529  tm_type == COLLADAFW::Transformation::SCALE) &&
530  binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
531 
532  if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
533  fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
534  return;
535  }
536 
537  char rna_path[100];
538 
539  switch (tm_type) {
540  case COLLADAFW::Transformation::TRANSLATE:
541  case COLLADAFW::Transformation::SCALE: {
542  bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE;
543  if (is_joint) {
544  BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
545  }
546  else {
547  BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
548  }
549 
550  switch (binding->animationClass) {
551  case COLLADAFW::AnimationList::POSITION_X:
552  modify_fcurve(curves, rna_path, 0);
553  break;
554  case COLLADAFW::AnimationList::POSITION_Y:
555  modify_fcurve(curves, rna_path, 1);
556  break;
557  case COLLADAFW::AnimationList::POSITION_Z:
558  modify_fcurve(curves, rna_path, 2);
559  break;
560  case COLLADAFW::AnimationList::POSITION_XYZ:
561  modify_fcurve(curves, rna_path, -1);
562  break;
563  default:
565  fprintf(stderr,
566  "AnimationClass %d is not supported for %s.\n",
567  binding->animationClass,
568  loc ? "TRANSLATE" : "SCALE");
569  }
570  break;
571  }
572 
573  case COLLADAFW::Transformation::ROTATE: {
574  if (is_joint) {
575  BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
576  }
577  else {
578  BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
579  }
580  std::vector<FCurve *>::iterator iter;
581  for (iter = curves->begin(); iter != curves->end(); iter++) {
582  FCurve *fcu = *iter;
583 
584  /* if transform is rotation the fcurves values must be turned in to radian. */
585  if (is_rotation) {
586  fcurve_deg_to_rad(fcu);
587  }
588  }
589  COLLADAFW::Rotate *rot = (COLLADAFW::Rotate *)transform;
590  COLLADABU::Math::Vector3 &axis = rot->getRotationAxis();
591 
592  switch (binding->animationClass) {
593  case COLLADAFW::AnimationList::ANGLE: {
594  int axis_index = get_animation_axis_index(axis);
595  if (axis_index >= 0) {
596  modify_fcurve(curves, rna_path, axis_index);
597  }
598  else {
600  }
601  } break;
602  case COLLADAFW::AnimationList::AXISANGLE:
603  /* TODO: convert axis-angle to quat? or XYZ? */
604  default:
606  fprintf(stderr,
607  "AnimationClass %d is not supported for ROTATE transformation.\n",
608  binding->animationClass);
609  }
610  break;
611  }
612 
613  case COLLADAFW::Transformation::MATRIX:
614 #if 0
615  {
616  COLLADAFW::Matrix *mat = (COLLADAFW::Matrix *)transform;
617  COLLADABU::Math::Matrix4 mat4 = mat->getMatrix();
618  switch (binding->animationClass) {
619  case COLLADAFW::AnimationList::TRANSFORM:
620  }
621  }
622 #endif
624  break;
625  case COLLADAFW::Transformation::SKEW:
626  case COLLADAFW::Transformation::LOOKAT:
628  fprintf(stderr, "Animation of SKEW and LOOKAT transformations is not supported yet.\n");
629  break;
630  }
631 }
632 
633 void AnimationImporter::Assign_color_animations(const COLLADAFW::UniqueId &listid,
634  ListBase *AnimCurves,
635  const char *anim_type)
636 {
637  char rna_path[100];
638  BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
639 
640  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
641  if (animlist == nullptr) {
642  fprintf(stderr,
643  "Collada: No animlist found for ID: %s of type %s\n",
644  listid.toAscii().c_str(),
645  anim_type);
646  return;
647  }
648 
649  const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
650  /* all the curves belonging to the current binding */
651  std::vector<FCurve *> animcurves;
652  for (unsigned int j = 0; j < bindings.getCount(); j++) {
653  animcurves = curve_map[bindings[j].animation];
654 
655  switch (bindings[j].animationClass) {
656  case COLLADAFW::AnimationList::COLOR_R:
657  modify_fcurve(&animcurves, rna_path, 0);
658  break;
659  case COLLADAFW::AnimationList::COLOR_G:
660  modify_fcurve(&animcurves, rna_path, 1);
661  break;
662  case COLLADAFW::AnimationList::COLOR_B:
663  modify_fcurve(&animcurves, rna_path, 2);
664  break;
665  case COLLADAFW::AnimationList::COLOR_RGB:
666  case COLLADAFW::AnimationList::COLOR_RGBA: /* to do-> set intensity */
667  modify_fcurve(&animcurves, rna_path, -1);
668  break;
669 
670  default:
671  unused_fcurve(&animcurves);
672  fprintf(stderr,
673  "AnimationClass %d is not supported for %s.\n",
674  bindings[j].animationClass,
675  "COLOR");
676  }
677 
678  std::vector<FCurve *>::iterator iter;
679  /* Add the curves of the current animation to the object */
680  for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
681  FCurve *fcu = *iter;
682  BLI_addtail(AnimCurves, fcu);
683  fcurve_is_used(fcu);
684  }
685  }
686 }
687 
688 void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listid,
689  ListBase *AnimCurves,
690  const char *anim_type)
691 {
692  char rna_path[100];
693  if (animlist_map.find(listid) == animlist_map.end()) {
694  return;
695  }
696 
697  /* anim_type has animations */
698  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
699  const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
700  /* all the curves belonging to the current binding */
701  std::vector<FCurve *> animcurves;
702  for (unsigned int j = 0; j < bindings.getCount(); j++) {
703  animcurves = curve_map[bindings[j].animation];
704 
705  BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
706  modify_fcurve(&animcurves, rna_path, 0);
707  std::vector<FCurve *>::iterator iter;
708  /* Add the curves of the current animation to the object */
709  for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
710  FCurve *fcu = *iter;
711  /* All anim_types whose values are to be converted from Degree to Radians can be ORed here
712  */
713  if (STREQ("spot_size", anim_type)) {
714  /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10
715  * Reason: old blender versions stored spot_size in radians (was a bug)
716  */
717  if (this->import_from_version.empty() ||
718  BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) {
719  fcurve_deg_to_rad(fcu);
720  }
721  }
724  BLI_addtail(AnimCurves, fcu);
725  fcurve_is_used(fcu);
726  }
727  }
728 }
729 
731  int fov_type,
732  float aspect,
733  float sensorx)
734 {
735  /* NOTE: Needs more testing (As we currently have no official test data for this) */
736  float xfov = (fov_type == CAMERA_YFOV) ?
737  (2.0f * atanf(aspect * tanf(DEG2RADF(in_xfov) * 0.5f))) :
738  DEG2RADF(in_xfov);
739  return fov_to_focallength(xfov, sensorx);
740 }
741 
742 void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid,
743  ListBase *AnimCurves,
744  const double aspect,
745  Camera *cam,
746  const char *anim_type,
747  int fov_type)
748 {
749  char rna_path[100];
750  if (animlist_map.find(listid) == animlist_map.end()) {
751  return;
752  }
753 
754  /* anim_type has animations */
755  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
756  const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
757  /* all the curves belonging to the current binding */
758  std::vector<FCurve *> animcurves;
759  for (unsigned int j = 0; j < bindings.getCount(); j++) {
760  animcurves = curve_map[bindings[j].animation];
761 
762  BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
763 
764  modify_fcurve(&animcurves, rna_path, 0);
765  std::vector<FCurve *>::iterator iter;
766  /* Add the curves of the current animation to the object */
767  for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
768  FCurve *fcu = *iter;
769 
770  for (unsigned int i = 0; i < fcu->totvert; i++) {
771  fcu->bezt[i].vec[0][1] = convert_to_focal_length(
772  fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
773  fcu->bezt[i].vec[1][1] = convert_to_focal_length(
774  fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x);
775  fcu->bezt[i].vec[2][1] = convert_to_focal_length(
776  fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x);
777  }
778 
779  BLI_addtail(AnimCurves, fcu);
780  fcurve_is_used(fcu);
781  }
782  }
783 }
784 
786  std::vector<FCurve *> &animcurves,
787  COLLADAFW::Node *root,
788  COLLADAFW::Node *node,
789  COLLADAFW::Transformation *tm)
790 {
791  bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
792  const char *bone_name = is_joint ? bc_get_joint_name(node) : nullptr;
793  char joint_path[200];
794  if (is_joint) {
795  armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
796  }
797 
798  std::vector<float> frames;
799  find_frames(&frames, &animcurves);
800 
801  float irest_dae[4][4];
802  float rest[4][4], irest[4][4];
803 
804  if (is_joint) {
805  get_joint_rest_mat(irest_dae, root, node);
806  invert_m4(irest_dae);
807 
808  Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name);
809  if (!bone) {
810  fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
811  return;
812  }
813 
814  unit_m4(rest);
815  copy_m4_m4(rest, bone->arm_mat);
816  invert_m4_m4(irest, rest);
817  }
818  /* new curves to assign matrix transform animation */
819  FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
820  unsigned int totcu = 10;
821  const char *tm_str = nullptr;
822  char rna_path[200];
823  for (int i = 0; i < totcu; i++) {
824 
825  int axis = i;
826 
827  if (i < 4) {
828  tm_str = "rotation_quaternion";
829  axis = i;
830  }
831  else if (i < 7) {
832  tm_str = "location";
833  axis = i - 4;
834  }
835  else {
836  tm_str = "scale";
837  axis = i - 7;
838  }
839 
840  if (is_joint) {
841  BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
842  }
843  else {
844  BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
845  }
846  newcu[i] = create_fcurve(axis, rna_path);
847  newcu[i]->totvert = frames.size();
848  }
849 
850  if (frames.empty()) {
851  return;
852  }
853 
854  std::sort(frames.begin(), frames.end());
855 
856  std::vector<float>::iterator it;
857 
858 #if 0
859  float qref[4];
860  unit_qt(qref);
861 #endif
862 
863  /* sample values at each frame */
864  for (it = frames.begin(); it != frames.end(); it++) {
865  float fra = *it;
866 
867  float mat[4][4];
868  float matfra[4][4];
869 
870  unit_m4(matfra);
871 
872  /* calc object-space mat */
873  evaluate_transform_at_frame(matfra, node, fra);
874 
875  /* for joints, we need a special matrix */
876  if (is_joint) {
877  /* special matrix: iR * M * iR_dae * R
878  * where R, iR are bone rest and inverse rest mats in world space (Blender bones),
879  * iR_dae is joint inverse rest matrix (DAE)
880  * and M is an evaluated joint world-space matrix (DAE) */
881  float temp[4][4], par[4][4];
882 
883  /* calc M */
884  calc_joint_parent_mat_rest(par, nullptr, root, node);
885  mul_m4_m4m4(temp, par, matfra);
886 
887 #if 0
888  evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
889 #endif
890 
891  /* calc special matrix */
892  mul_m4_series(mat, irest, temp, irest_dae, rest);
893  }
894  else {
895  copy_m4_m4(mat, matfra);
896  }
897 
898  float rot[4], loc[3], scale[3];
899  mat4_decompose(loc, rot, scale, mat);
900 
901  /* add keys */
902  for (int i = 0; i < totcu; i++) {
903  if (i < 4) {
904  add_bezt(newcu[i], fra, rot[i]);
905  }
906  else if (i < 7) {
907  add_bezt(newcu[i], fra, loc[i - 4]);
908  }
909  else {
910  add_bezt(newcu[i], fra, scale[i - 7]);
911  }
912  }
913  }
914  Main *bmain = CTX_data_main(mContext);
915  ED_id_action_ensure(bmain, (ID *)&ob->id);
916 
917  ListBase *curves = &ob->adt->action->curves;
918 
919  /* add curves */
920  for (int i = 0; i < totcu; i++) {
921  if (is_joint) {
922  add_bone_fcurve(ob, node, newcu[i]);
923  }
924  else {
925  BLI_addtail(curves, newcu[i]);
926  }
927 #if 0
928  fcurve_is_used(newcu[i]); /* never added to unused */
929 #endif
930  }
931 
932  if (is_joint) {
933  bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name);
934  chan->rotmode = ROT_MODE_QUAT;
935  }
936  else {
937  ob->rotmode = ROT_MODE_QUAT;
938  }
939 }
940 
941 /*
942  * This function returns the aspect ration from the Collada camera.
943  *
944  * NOTE:COLLADA allows to specify either XFov, or YFov alone.
945  * In that case the aspect ratio can be determined from
946  * the viewport aspect ratio (which is 1:1 ?)
947  * XXX: check this: its probably wrong!
948  * If both values are specified, then the aspect ration is simply xfov/yfov
949  * and if aspect ratio is defined, then .. well then its that one.
950  */
952 {
953  double aspect = camera->getAspectRatio().getValue();
954 
955  if (aspect == 0) {
956  const double yfov = camera->getYFov().getValue();
957 
958  if (yfov == 0) {
959  aspect = 1; /* assume yfov and xfov are equal */
960  }
961  else {
962  const double xfov = camera->getXFov().getValue();
963  if (xfov == 0) {
964  aspect = 1;
965  }
966  else {
967  aspect = xfov / yfov;
968  }
969  }
970  }
971  return aspect;
972 }
973 
975 {
976  bAction *act;
977  if (!ma->adt || !ma->adt->action) {
978  act = ED_id_action_ensure(bmain, (ID *)&ma->id);
979  }
980  else {
981  act = ma->adt->action;
982  }
983 
984  return act->curves;
985 }
986 
988  COLLADAFW::Node *node,
989  std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map,
990  std::multimap<COLLADAFW::UniqueId, Object *> &object_map,
991  std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map,
992  std::map<COLLADAFW::UniqueId, Material *> uid_material_map)
993 {
994  bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
995  COLLADAFW::UniqueId uid = node->getUniqueId();
996  COLLADAFW::Node *root = root_map.find(uid) == root_map.end() ? node : root_map[uid];
997 
998  Object *ob;
999  if (is_joint) {
1000  ob = armature_importer->get_armature_for_joint(root);
1001  }
1002  else {
1003  ob = object_map.find(uid) == object_map.end() ? NULL : object_map.find(uid)->second;
1004  }
1005 
1006  if (!ob) {
1007  fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
1008  return;
1009  }
1010 
1011  AnimationImporter::AnimMix *animType = get_animation_type(node, FW_object_map);
1012  bAction *act;
1013  Main *bmain = CTX_data_main(mContext);
1014 
1015  if ((animType->transform) != 0) {
1016  /* const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; */ /* UNUSED */
1017  char joint_path[200];
1018 
1019  if (is_joint) {
1020  armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
1021  }
1022 
1023  if (!ob->adt || !ob->adt->action) {
1024  act = ED_id_action_ensure(bmain, (ID *)&ob->id);
1025  }
1026  else {
1027  act = ob->adt->action;
1028  }
1029 
1030  /* Get the list of animation curves of the object */
1031  ListBase *AnimCurves = &(act->curves);
1032 
1033  const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
1034 
1035  /* for each transformation in node */
1036  for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
1037  COLLADAFW::Transformation *transform = nodeTransforms[i];
1038  COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
1039 
1040  bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
1041  bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
1042 
1043  const COLLADAFW::UniqueId &listid = transform->getAnimationList();
1044 
1045  /* check if transformation has animations */
1046  if (animlist_map.find(listid) == animlist_map.end()) {
1047  continue;
1048  }
1049 
1050  /* transformation has animations */
1051  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
1052  const COLLADAFW::AnimationList::AnimationBindings &bindings =
1053  animlist->getAnimationBindings();
1054  /* all the curves belonging to the current binding */
1055  std::vector<FCurve *> animcurves;
1056  for (unsigned int j = 0; j < bindings.getCount(); j++) {
1057  animcurves = curve_map[bindings[j].animation];
1058  if (is_matrix) {
1059  apply_matrix_curves(ob, animcurves, root, node, transform);
1060  }
1061  else {
1062  /* Calculate RNA-paths and array index of F-Curves according to transformation and
1063  * animation class */
1064  Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path);
1065 
1066  std::vector<FCurve *>::iterator iter;
1067  /* Add the curves of the current animation to the object */
1068  for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
1069  FCurve *fcu = *iter;
1070 
1071  BLI_addtail(AnimCurves, fcu);
1072  fcurve_is_used(fcu);
1073  }
1074  }
1075  }
1076 
1077  if (is_rotation && !(is_joint || is_matrix)) {
1078  ob->rotmode = ROT_MODE_EUL;
1079  }
1080  }
1081  }
1082 
1083  if ((animType->light) != 0) {
1084  Light *lamp = (Light *)ob->data;
1085  if (!lamp->adt || !lamp->adt->action) {
1086  act = ED_id_action_ensure(bmain, (ID *)&lamp->id);
1087  }
1088  else {
1089  act = lamp->adt->action;
1090  }
1091 
1092  ListBase *AnimCurves = &(act->curves);
1093  const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
1094 
1095  for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
1096  const COLLADAFW::Light *light = (COLLADAFW::Light *)
1097  FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
1098 
1099  if ((animType->light & LIGHT_COLOR) != 0) {
1100  const COLLADAFW::Color *col = &(light->getColor());
1101  const COLLADAFW::UniqueId &listid = col->getAnimationList();
1102 
1103  Assign_color_animations(listid, AnimCurves, "color");
1104  }
1105  if ((animType->light & LIGHT_FOA) != 0) {
1106  const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle());
1107  const COLLADAFW::UniqueId &listid = foa->getAnimationList();
1108 
1109  Assign_float_animations(listid, AnimCurves, "spot_size");
1110  }
1111  if ((animType->light & LIGHT_FOE) != 0) {
1112  const COLLADAFW::AnimatableFloat *foe = &(light->getFallOffExponent());
1113  const COLLADAFW::UniqueId &listid = foe->getAnimationList();
1114 
1115  Assign_float_animations(listid, AnimCurves, "spot_blend");
1116  }
1117  }
1118  }
1119 
1120  if (animType->camera != 0) {
1121 
1122  Camera *cam = (Camera *)ob->data;
1123  if (!cam->adt || !cam->adt->action) {
1124  act = ED_id_action_ensure(bmain, (ID *)&cam->id);
1125  }
1126  else {
1127  act = cam->adt->action;
1128  }
1129 
1130  ListBase *AnimCurves = &(act->curves);
1131  const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
1132 
1133  for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
1135  FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
1136 
1137  if ((animType->camera & CAMERA_XFOV) != 0) {
1138  const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov());
1139  const COLLADAFW::UniqueId &listid = xfov->getAnimationList();
1140  double aspect = get_aspect_ratio(camera);
1141  Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV);
1142  }
1143 
1144  else if ((animType->camera & CAMERA_YFOV) != 0) {
1145  const COLLADAFW::AnimatableFloat *yfov = &(camera->getYFov());
1146  const COLLADAFW::UniqueId &listid = yfov->getAnimationList();
1147  double aspect = get_aspect_ratio(camera);
1148  Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV);
1149  }
1150 
1151  else if ((animType->camera & CAMERA_XMAG) != 0) {
1152  const COLLADAFW::AnimatableFloat *xmag = &(camera->getXMag());
1153  const COLLADAFW::UniqueId &listid = xmag->getAnimationList();
1154  Assign_float_animations(listid, AnimCurves, "ortho_scale");
1155  }
1156 
1157  else if ((animType->camera & CAMERA_YMAG) != 0) {
1158  const COLLADAFW::AnimatableFloat *ymag = &(camera->getYMag());
1159  const COLLADAFW::UniqueId &listid = ymag->getAnimationList();
1160  Assign_float_animations(listid, AnimCurves, "ortho_scale");
1161  }
1162 
1163  if ((animType->camera & CAMERA_ZFAR) != 0) {
1164  const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane());
1165  const COLLADAFW::UniqueId &listid = zfar->getAnimationList();
1166  Assign_float_animations(listid, AnimCurves, "clip_end");
1167  }
1168 
1169  if ((animType->camera & CAMERA_ZNEAR) != 0) {
1170  const COLLADAFW::AnimatableFloat *znear = &(camera->getNearClippingPlane());
1171  const COLLADAFW::UniqueId &listid = znear->getAnimationList();
1172  Assign_float_animations(listid, AnimCurves, "clip_start");
1173  }
1174  }
1175  }
1176  if (animType->material != 0) {
1177 
1178  Material *ma = BKE_object_material_get(ob, 1);
1179  if (!ma->adt || !ma->adt->action) {
1180  act = ED_id_action_ensure(bmain, (ID *)&ma->id);
1181  }
1182  else {
1183  act = ma->adt->action;
1184  }
1185 
1186  const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
1187  for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
1188  const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
1189  for (unsigned int j = 0; j < matBinds.getCount(); j++) {
1190  const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
1191  const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
1192  if (ef != nullptr) { /* can be NULL T28909. */
1193  Material *ma = uid_material_map[matuid];
1194  if (!ma) {
1195  fprintf(stderr,
1196  "Collada: Node %s refers to undefined material\n",
1197  node->getName().c_str());
1198  continue;
1199  }
1200  ListBase &AnimCurves = get_animation_curves(bmain, ma);
1201  const COLLADAFW::CommonEffectPointerArray &commonEffects = ef->getCommonEffects();
1202  COLLADAFW::EffectCommon *efc = commonEffects[0];
1203  if ((animType->material & MATERIAL_SHININESS) != 0) {
1204  const COLLADAFW::FloatOrParam *shin = &(efc->getShininess());
1205  const COLLADAFW::UniqueId &listid = shin->getAnimationList();
1206  Assign_float_animations(listid, &AnimCurves, "specular_hardness");
1207  }
1208 
1209  if ((animType->material & MATERIAL_IOR) != 0) {
1210  const COLLADAFW::FloatOrParam *ior = &(efc->getIndexOfRefraction());
1211  const COLLADAFW::UniqueId &listid = ior->getAnimationList();
1212  Assign_float_animations(listid, &AnimCurves, "raytrace_transparency.ior");
1213  }
1214 
1215  if ((animType->material & MATERIAL_SPEC_COLOR) != 0) {
1216  const COLLADAFW::ColorOrTexture *cot = &(efc->getSpecular());
1217  const COLLADAFW::UniqueId &listid = cot->getColor().getAnimationList();
1218  Assign_color_animations(listid, &AnimCurves, "specular_color");
1219  }
1220 
1221  if ((animType->material & MATERIAL_DIFF_COLOR) != 0) {
1222  const COLLADAFW::ColorOrTexture *cot = &(efc->getDiffuse());
1223  const COLLADAFW::UniqueId &listid = cot->getColor().getAnimationList();
1224  Assign_color_animations(listid, &AnimCurves, "diffuse_color");
1225  }
1226  }
1227  }
1228  }
1229  }
1230 
1231  delete animType;
1232 }
1233 
1235  std::vector<FCurve *> &animcurves,
1236  COLLADAFW::Node *root,
1237  COLLADAFW::Node *node,
1238  COLLADAFW::Transformation *tm)
1239 {
1240  const char *bone_name = bc_get_joint_name(node);
1241  char joint_path[200];
1242  armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
1243 
1244  std::vector<float> frames;
1245  find_frames(&frames, &animcurves);
1246 
1247  /* convert degrees to radians */
1248  if (tm->getTransformationType() == COLLADAFW::Transformation::ROTATE) {
1249 
1250  std::vector<FCurve *>::iterator iter;
1251  for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
1252  FCurve *fcu = *iter;
1253 
1254  fcurve_deg_to_rad(fcu);
1255  }
1256  }
1257 
1258  float irest_dae[4][4];
1259  float rest[4][4], irest[4][4];
1260 
1261  get_joint_rest_mat(irest_dae, root, node);
1262  invert_m4(irest_dae);
1263 
1264  Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name);
1265  if (!bone) {
1266  fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
1267  return;
1268  }
1269 
1270  unit_m4(rest);
1271  copy_m4_m4(rest, bone->arm_mat);
1272  invert_m4_m4(irest, rest);
1273 
1274  /* new curves to assign matrix transform animation */
1275  FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale. */
1276  unsigned int totcu = 10;
1277  const char *tm_str = nullptr;
1278  char rna_path[200];
1279  for (int i = 0; i < totcu; i++) {
1280 
1281  int axis = i;
1282 
1283  if (i < 4) {
1284  tm_str = "rotation_quaternion";
1285  axis = i;
1286  }
1287  else if (i < 7) {
1288  tm_str = "location";
1289  axis = i - 4;
1290  }
1291  else {
1292  tm_str = "scale";
1293  axis = i - 7;
1294  }
1295 
1296  BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
1297 
1298  newcu[i] = create_fcurve(axis, rna_path);
1299  newcu[i]->totvert = frames.size();
1300  }
1301 
1302  if (frames.empty()) {
1303  return;
1304  }
1305 
1306  std::sort(frames.begin(), frames.end());
1307 
1308  BCQuat qref;
1309 
1310  std::vector<float>::iterator it;
1311 
1312  /* sample values at each frame */
1313  for (it = frames.begin(); it != frames.end(); it++) {
1314  float fra = *it;
1315 
1316  Matrix mat;
1317  Matrix matfra;
1318 
1319  unit_m4(matfra);
1320 
1321  /* calc object-space mat */
1322  evaluate_transform_at_frame(matfra, node, fra);
1323 
1324  /* for joints, we need a special matrix
1325  * special matrix: iR * M * iR_dae * R
1326  * where R, iR are bone rest and inverse rest mats in world space (Blender bones),
1327  * iR_dae is joint inverse rest matrix (DAE)
1328  * and M is an evaluated joint world-space matrix (DAE). */
1329  Matrix temp, par;
1330 
1331  /* calc M */
1332  calc_joint_parent_mat_rest(par, nullptr, root, node);
1333  mul_m4_m4m4(temp, par, matfra);
1334 
1335  // evaluate_joint_world_transform_at_frame(temp, NULL, node, fra);
1336 
1337  /* calc special matrix */
1338  mul_m4_series(mat, irest, temp, irest_dae, rest);
1339 
1340  Vector loc, scale;
1341 
1342  qref.rotate_to(mat);
1343 
1344  copy_v3_v3(loc, mat[3]);
1345  mat4_to_size(scale, mat);
1346 
1347  /* add keys */
1348  for (int i = 0; i < totcu; i++) {
1349  if (i < 4) {
1350  add_bezt(newcu[i], fra, qref.quat()[i]);
1351  }
1352  else if (i < 7) {
1353  add_bezt(newcu[i], fra, loc[i - 4]);
1354  }
1355  else {
1356  add_bezt(newcu[i], fra, scale[i - 7]);
1357  }
1358  }
1359  }
1360  Main *bmain = CTX_data_main(mContext);
1361  ED_id_action_ensure(bmain, (ID *)&ob->id);
1362 
1363  /* add curves */
1364  for (int i = 0; i < totcu; i++) {
1365  add_bone_fcurve(ob, node, newcu[i]);
1366 #if 0
1367  fcurve_is_used(newcu[i]); /* never added to unused */
1368 #endif
1369  }
1370 
1371  bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name);
1372  chan->rotmode = ROT_MODE_QUAT;
1373 }
1374 
1375 AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
1376  const COLLADAFW::Node *node,
1377  std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map)
1378 {
1379  AnimMix *types = new AnimMix();
1380 
1381  const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
1382 
1383  /* for each transformation in node */
1384  for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
1385  COLLADAFW::Transformation *transform = nodeTransforms[i];
1386  const COLLADAFW::UniqueId &listid = transform->getAnimationList();
1387 
1388  /* check if transformation has animations */
1389  if (animlist_map.find(listid) == animlist_map.end()) {
1390  continue;
1391  }
1392 
1393  types->transform = types->transform | BC_NODE_TRANSFORM;
1394  break;
1395  }
1396  const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
1397 
1398  for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
1399  const COLLADAFW::Light *light = (COLLADAFW::Light *)
1400  FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
1401  types->light = setAnimType(&(light->getColor()), (types->light), LIGHT_COLOR);
1402  types->light = setAnimType(&(light->getFallOffAngle()), (types->light), LIGHT_FOA);
1403  types->light = setAnimType(&(light->getFallOffExponent()), (types->light), LIGHT_FOE);
1404 
1405  if (types->light != 0) {
1406  break;
1407  }
1408  }
1409 
1410  const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras();
1411  for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
1413  FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
1414  if (camera == nullptr) {
1415  /* Can happen if the node refers to an unknown camera. */
1416  continue;
1417  }
1418 
1419  const bool is_perspective_type = camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE;
1420 
1421  int addition;
1422  const COLLADAFW::Animatable *mag;
1423  const COLLADAFW::UniqueId listid = camera->getYMag().getAnimationList();
1424  if (animlist_map.find(listid) != animlist_map.end()) {
1425  mag = &(camera->getYMag());
1426  addition = (is_perspective_type) ? CAMERA_YFOV : CAMERA_YMAG;
1427  }
1428  else {
1429  mag = &(camera->getXMag());
1430  addition = (is_perspective_type) ? CAMERA_XFOV : CAMERA_XMAG;
1431  }
1432  types->camera = setAnimType(mag, (types->camera), addition);
1433 
1434  types->camera = setAnimType(&(camera->getFarClippingPlane()), (types->camera), CAMERA_ZFAR);
1435  types->camera = setAnimType(&(camera->getNearClippingPlane()), (types->camera), CAMERA_ZNEAR);
1436 
1437  if (types->camera != 0) {
1438  break;
1439  }
1440  }
1441 
1442  const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries();
1443  for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
1444  const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings();
1445  for (unsigned int j = 0; j < matBinds.getCount(); j++) {
1446  const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial();
1447  const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]);
1448  if (ef != nullptr) { /* can be NULL T28909. */
1449  const COLLADAFW::CommonEffectPointerArray &commonEffects = ef->getCommonEffects();
1450  if (!commonEffects.empty()) {
1451  COLLADAFW::EffectCommon *efc = commonEffects[0];
1452  types->material = setAnimType(
1453  &(efc->getShininess()), (types->material), MATERIAL_SHININESS);
1454  types->material = setAnimType(
1455  &(efc->getSpecular().getColor()), (types->material), MATERIAL_SPEC_COLOR);
1456  types->material = setAnimType(
1457  &(efc->getDiffuse().getColor()), (types->material), MATERIAL_DIFF_COLOR);
1458 #if 0
1459  types->material = setAnimType(&(efc->get()), (types->material), MATERIAL_TRANSPARENCY);
1460 #endif
1461  types->material = setAnimType(
1462  &(efc->getIndexOfRefraction()), (types->material), MATERIAL_IOR);
1463  }
1464  }
1465  }
1466  }
1467  return types;
1468 }
1469 
1470 int AnimationImporter::setAnimType(const COLLADAFW::Animatable *prop, int types, int addition)
1471 {
1472  int anim_type;
1473  const COLLADAFW::UniqueId &listid = prop->getAnimationList();
1474  if (animlist_map.find(listid) != animlist_map.end()) {
1475  anim_type = types | addition;
1476  }
1477  else {
1478  anim_type = types;
1479  }
1480 
1481  return anim_type;
1482 }
1483 
1484 void AnimationImporter::find_frames_old(std::vector<float> *frames,
1485  COLLADAFW::Node *node,
1486  COLLADAFW::Transformation::TransformationType tm_type)
1487 {
1488  bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
1489  bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
1490  /* for each <rotate>, <translate>, etc. there is a separate Transformation */
1491  const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
1492 
1493  unsigned int i;
1494  /* find frames at which to sample plus convert all rotation keys to radians */
1495  for (i = 0; i < nodeTransforms.getCount(); i++) {
1496  COLLADAFW::Transformation *transform = nodeTransforms[i];
1497  COLLADAFW::Transformation::TransformationType nodeTmType = transform->getTransformationType();
1498 
1499  if (nodeTmType == tm_type) {
1500  /* get animation bindings for the current transformation */
1501  const COLLADAFW::UniqueId &listid = transform->getAnimationList();
1502  /* if transform is animated its animlist must exist. */
1503  if (animlist_map.find(listid) != animlist_map.end()) {
1504 
1505  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
1506  const COLLADAFW::AnimationList::AnimationBindings &bindings =
1507  animlist->getAnimationBindings();
1508 
1509  if (bindings.getCount()) {
1510  /* for each AnimationBinding get the fcurves which animate the transform */
1511  for (unsigned int j = 0; j < bindings.getCount(); j++) {
1512  std::vector<FCurve *> &curves = curve_map[bindings[j].animation];
1513  bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE ||
1514  nodeTmType == COLLADAFW::Transformation::SCALE) &&
1515  bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
1516 
1517  if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
1518  std::vector<FCurve *>::iterator iter;
1519 
1520  for (iter = curves.begin(); iter != curves.end(); iter++) {
1521  FCurve *fcu = *iter;
1522 
1523  /* if transform is rotation the fcurves values must be turned in to radian. */
1524  if (is_rotation) {
1525  fcurve_deg_to_rad(fcu);
1526  }
1527 
1528  for (unsigned int k = 0; k < fcu->totvert; k++) {
1529  /* get frame value from bezTriple */
1530  float fra = fcu->bezt[k].vec[1][0];
1531  /* if frame already not added add frame to frames */
1532  if (std::find(frames->begin(), frames->end(), fra) == frames->end()) {
1533  frames->push_back(fra);
1534  }
1535  }
1536  }
1537  }
1538  else {
1539  fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size());
1540  }
1541  }
1542  }
1543  }
1544  }
1545  }
1546 }
1547 
1549  COLLADAFW::Node *node,
1550  std::map<COLLADAFW::UniqueId, Object *> &object_map,
1551  std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map,
1552  COLLADAFW::Transformation::TransformationType tm_type,
1553  Object *par_job)
1554 {
1555 
1556  bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
1557  bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
1558  bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
1559 
1560  COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ?
1561  node :
1562  root_map[node->getUniqueId()];
1563  Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) :
1564  object_map[node->getUniqueId()];
1565  const char *bone_name = is_joint ? bc_get_joint_name(node) : nullptr;
1566  if (!ob) {
1567  fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
1568  return nullptr;
1569  }
1570 
1571  /* frames at which to sample */
1572  std::vector<float> frames;
1573 
1574  find_frames_old(&frames, node, tm_type);
1575 
1576  unsigned int i;
1577 
1578  float irest_dae[4][4];
1579  float rest[4][4], irest[4][4];
1580 
1581  if (is_joint) {
1582  get_joint_rest_mat(irest_dae, root, node);
1583  invert_m4(irest_dae);
1584 
1585  Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name);
1586  if (!bone) {
1587  fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
1588  return nullptr;
1589  }
1590 
1591  unit_m4(rest);
1592  copy_m4_m4(rest, bone->arm_mat);
1593  invert_m4_m4(irest, rest);
1594  }
1595 
1596  Object *job = nullptr;
1597 
1598 #ifdef ARMATURE_TEST
1599  FCurve *job_curves[10];
1600  job = get_joint_object(root, node, par_job);
1601 #endif
1602 
1603  if (frames.empty()) {
1604  return job;
1605  }
1606 
1607  std::sort(frames.begin(), frames.end());
1608 
1609  const char *tm_str = nullptr;
1610  switch (tm_type) {
1611  case COLLADAFW::Transformation::ROTATE:
1612  tm_str = "rotation_quaternion";
1613  break;
1614  case COLLADAFW::Transformation::SCALE:
1615  tm_str = "scale";
1616  break;
1617  case COLLADAFW::Transformation::TRANSLATE:
1618  tm_str = "location";
1619  break;
1620  case COLLADAFW::Transformation::MATRIX:
1621  break;
1622  default:
1623  return job;
1624  }
1625 
1626  char rna_path[200];
1627  char joint_path[200];
1628 
1629  if (is_joint) {
1630  armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
1631  }
1632 
1633  /* new curves */
1634  FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */
1635  unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
1636 
1637  for (i = 0; i < totcu; i++) {
1638 
1639  int axis = i;
1640 
1641  if (is_matrix) {
1642  if (i < 4) {
1643  tm_str = "rotation_quaternion";
1644  axis = i;
1645  }
1646  else if (i < 7) {
1647  tm_str = "location";
1648  axis = i - 4;
1649  }
1650  else {
1651  tm_str = "scale";
1652  axis = i - 7;
1653  }
1654  }
1655 
1656  if (is_joint) {
1657  BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
1658  }
1659  else {
1660  BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
1661  }
1662  newcu[i] = create_fcurve(axis, rna_path);
1663 
1664 #ifdef ARMATURE_TEST
1665  if (is_joint) {
1666  job_curves[i] = create_fcurve(axis, tm_str);
1667  }
1668 #endif
1669  }
1670 
1671  std::vector<float>::iterator it;
1672 
1673  /* sample values at each frame */
1674  for (it = frames.begin(); it != frames.end(); it++) {
1675  float fra = *it;
1676 
1677  float mat[4][4];
1678  float matfra[4][4];
1679 
1680  unit_m4(matfra);
1681 
1682  /* calc object-space mat */
1683  evaluate_transform_at_frame(matfra, node, fra);
1684 
1685  /* for joints, we need a special matrix */
1686  if (is_joint) {
1687  /* special matrix: iR * M * iR_dae * R
1688  * where R, iR are bone rest and inverse rest mats in world space (Blender bones),
1689  * iR_dae is joint inverse rest matrix (DAE)
1690  * and M is an evaluated joint world-space matrix (DAE). */
1691  float temp[4][4], par[4][4];
1692 
1693  /* calc M */
1694  calc_joint_parent_mat_rest(par, nullptr, root, node);
1695  mul_m4_m4m4(temp, par, matfra);
1696 
1697  /* evaluate_joint_world_transform_at_frame(temp, NULL, node, fra); */
1698 
1699  /* calc special matrix */
1700  mul_m4_series(mat, irest, temp, irest_dae, rest);
1701  }
1702  else {
1703  copy_m4_m4(mat, matfra);
1704  }
1705 
1706  float val[4] = {};
1707  float rot[4], loc[3], scale[3];
1708 
1709  switch (tm_type) {
1710  case COLLADAFW::Transformation::ROTATE:
1711  mat4_to_quat(val, mat);
1712  break;
1713  case COLLADAFW::Transformation::SCALE:
1714  mat4_to_size(val, mat);
1715  break;
1716  case COLLADAFW::Transformation::TRANSLATE:
1717  copy_v3_v3(val, mat[3]);
1718  break;
1719  case COLLADAFW::Transformation::MATRIX:
1720  mat4_to_quat(rot, mat);
1721  copy_v3_v3(loc, mat[3]);
1722  mat4_to_size(scale, mat);
1723  break;
1724  default:
1725  break;
1726  }
1727 
1728  /* add keys */
1729  for (i = 0; i < totcu; i++) {
1730  if (is_matrix) {
1731  if (i < 4) {
1732  add_bezt(newcu[i], fra, rot[i]);
1733  }
1734  else if (i < 7) {
1735  add_bezt(newcu[i], fra, loc[i - 4]);
1736  }
1737  else {
1738  add_bezt(newcu[i], fra, scale[i - 7]);
1739  }
1740  }
1741  else {
1742  add_bezt(newcu[i], fra, val[i]);
1743  }
1744  }
1745 
1746 #ifdef ARMATURE_TEST
1747  if (is_joint) {
1748  switch (tm_type) {
1749  case COLLADAFW::Transformation::ROTATE:
1750  mat4_to_quat(val, matfra);
1751  break;
1752  case COLLADAFW::Transformation::SCALE:
1753  mat4_to_size(val, matfra);
1754  break;
1755  case COLLADAFW::Transformation::TRANSLATE:
1756  copy_v3_v3(val, matfra[3]);
1757  break;
1758  case MATRIX:
1759  mat4_to_quat(rot, matfra);
1760  copy_v3_v3(loc, matfra[3]);
1761  mat4_to_size(scale, matfra);
1762  break;
1763  default:
1764  break;
1765  }
1766 
1767  for (i = 0; i < totcu; i++) {
1768  if (is_matrix) {
1769  if (i < 4) {
1770  add_bezt(job_curves[i], fra, rot[i]);
1771  }
1772  else if (i < 7) {
1773  add_bezt(job_curves[i], fra, loc[i - 4]);
1774  }
1775  else {
1776  add_bezt(job_curves[i], fra, scale[i - 7]);
1777  }
1778  }
1779  else {
1780  add_bezt(job_curves[i], fra, val[i]);
1781  }
1782  }
1783  }
1784 #endif
1785  }
1786  Main *bmain = CTX_data_main(mContext);
1787  ED_id_action_ensure(bmain, (ID *)&ob->id);
1788 
1789  ListBase *curves = &ob->adt->action->curves;
1790 
1791  /* add curves */
1792  for (i = 0; i < totcu; i++) {
1793  if (is_joint) {
1794  add_bone_fcurve(ob, node, newcu[i]);
1795  }
1796  else {
1797  BLI_addtail(curves, newcu[i]);
1798  }
1799 
1800 #ifdef ARMATURE_TEST
1801  if (is_joint) {
1802  BLI_addtail(&job->adt->action->curves, job_curves[i]);
1803  }
1804 #endif
1805  }
1806 
1807  if (is_rotation || is_matrix) {
1808  if (is_joint) {
1809  bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name);
1810  chan->rotmode = (is_matrix) ? ROT_MODE_QUAT : ROT_MODE_EUL;
1811  }
1812  else {
1813  ob->rotmode = (is_matrix) ? ROT_MODE_QUAT : ROT_MODE_EUL;
1814  }
1815  }
1816 
1817  return job;
1818 }
1819 
1821  COLLADAFW::Node *node,
1822  float fra)
1823 {
1824  const COLLADAFW::TransformationPointerArray &tms = node->getTransformations();
1825 
1826  unit_m4(mat);
1827 
1828  for (unsigned int i = 0; i < tms.getCount(); i++) {
1829  COLLADAFW::Transformation *tm = tms[i];
1830  COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
1831  float m[4][4];
1832 
1833  unit_m4(m);
1834 
1835  std::string nodename = node->getName().empty() ? node->getOriginalId() : node->getName();
1836  if (!evaluate_animation(tm, m, fra, nodename.c_str())) {
1837  switch (type) {
1838  case COLLADAFW::Transformation::ROTATE:
1839  dae_rotate_to_mat4(tm, m);
1840  break;
1841  case COLLADAFW::Transformation::TRANSLATE:
1842  dae_translate_to_mat4(tm, m);
1843  break;
1844  case COLLADAFW::Transformation::SCALE:
1845  dae_scale_to_mat4(tm, m);
1846  break;
1847  case COLLADAFW::Transformation::MATRIX:
1848  dae_matrix_to_mat4(tm, m);
1849  break;
1850  default:
1851  fprintf(stderr, "unsupported transformation type %d\n", type);
1852  }
1853  }
1854 
1855  float temp[4][4];
1856  copy_m4_m4(temp, mat);
1857 
1858  mul_m4_m4m4(mat, temp, m);
1859  }
1860 }
1861 
1862 static void report_class_type_unsupported(const char *path,
1863  const COLLADAFW::AnimationList::AnimationClass animclass,
1864  const COLLADAFW::Transformation::TransformationType type)
1865 {
1866  if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
1867  fprintf(stderr, "%s: UNKNOWN animation class\n", path);
1868  }
1869  else {
1870  fprintf(stderr,
1871  "%s: animation class %d is not supported yet for transformation type %d\n",
1872  path,
1873  animclass,
1874  type);
1875  }
1876 }
1877 
1878 bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
1879  float mat[4][4],
1880  float fra,
1881  const char *node_id)
1882 {
1883  const COLLADAFW::UniqueId &listid = tm->getAnimationList();
1884  COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
1885 
1886  if (type != COLLADAFW::Transformation::ROTATE && type != COLLADAFW::Transformation::SCALE &&
1887  type != COLLADAFW::Transformation::TRANSLATE && type != COLLADAFW::Transformation::MATRIX) {
1888  fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
1889  return false;
1890  }
1891 
1892  if (animlist_map.find(listid) == animlist_map.end()) {
1893  return false;
1894  }
1895 
1896  const COLLADAFW::AnimationList *animlist = animlist_map[listid];
1897  const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
1898 
1899  if (bindings.getCount()) {
1900  float vec[3];
1901 
1902  bool is_scale = (type == COLLADAFW::Transformation::SCALE);
1903  bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
1904 
1905  if (is_scale) {
1906  dae_scale_to_v3(tm, vec);
1907  }
1908  else if (is_translate) {
1909  dae_translate_to_v3(tm, vec);
1910  }
1911 
1912  for (unsigned int index = 0; index < bindings.getCount(); index++) {
1913  const COLLADAFW::AnimationList::AnimationBinding &binding = bindings[index];
1914  std::vector<FCurve *> &curves = curve_map[binding.animation];
1915  COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
1916  char path[100];
1917 
1918  switch (type) {
1919  case COLLADAFW::Transformation::ROTATE:
1920  BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, index);
1921  break;
1922  case COLLADAFW::Transformation::SCALE:
1923  BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, index);
1924  break;
1925  case COLLADAFW::Transformation::TRANSLATE:
1926  BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, index);
1927  break;
1928  case COLLADAFW::Transformation::MATRIX:
1929  BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, index);
1930  break;
1931  default:
1932  break;
1933  }
1934 
1935  if (type == COLLADAFW::Transformation::ROTATE) {
1936  if (curves.size() != 1) {
1937  fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size());
1938  return false;
1939  }
1940 
1941  /* TODO: support other animation-classes. */
1942  if (animclass != COLLADAFW::AnimationList::ANGLE) {
1943  report_class_type_unsupported(path, animclass, type);
1944  return false;
1945  }
1946 
1947  COLLADABU::Math::Vector3 &axis = ((COLLADAFW::Rotate *)tm)->getRotationAxis();
1948 
1949  float ax[3] = {(float)axis[0], (float)axis[1], (float)axis[2]};
1950  float angle = evaluate_fcurve(curves[0], fra);
1951  axis_angle_to_mat4(mat, ax, angle);
1952 
1953  return true;
1954  }
1955  if (is_scale || is_translate) {
1956  bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
1957 
1958  if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
1959  if (is_xyz) {
1960  fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size());
1961  }
1962  else {
1963  fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
1964  }
1965  return false;
1966  }
1967 
1968  switch (animclass) {
1969  case COLLADAFW::AnimationList::POSITION_X:
1970  vec[0] = evaluate_fcurve(curves[0], fra);
1971  break;
1972  case COLLADAFW::AnimationList::POSITION_Y:
1973  vec[1] = evaluate_fcurve(curves[0], fra);
1974  break;
1975  case COLLADAFW::AnimationList::POSITION_Z:
1976  vec[2] = evaluate_fcurve(curves[0], fra);
1977  break;
1978  case COLLADAFW::AnimationList::POSITION_XYZ:
1979  vec[0] = evaluate_fcurve(curves[0], fra);
1980  vec[1] = evaluate_fcurve(curves[1], fra);
1981  vec[2] = evaluate_fcurve(curves[2], fra);
1982  break;
1983  default:
1984  report_class_type_unsupported(path, animclass, type);
1985  break;
1986  }
1987  }
1988  else if (type == COLLADAFW::Transformation::MATRIX) {
1989  /* for now, of matrix animation,
1990  * support only the case when all values are packed into one animation */
1991  if (curves.size() != 16) {
1992  fprintf(stderr, "%s: expected 16 curves, got %d\n", path, (int)curves.size());
1993  return false;
1994  }
1995 
1996  COLLADABU::Math::Matrix4 matrix;
1997  int mi = 0, mj = 0;
1998 
1999  for (FCurve *curve : curves) {
2000  matrix.setElement(mi, mj, evaluate_fcurve(curve, fra));
2001  mj++;
2002  if (mj == 4) {
2003  mi++;
2004  mj = 0;
2005  }
2006  }
2008  return true;
2009  }
2010  }
2011 
2012  if (is_scale) {
2013  size_to_mat4(mat, vec);
2014  }
2015  else {
2016  copy_v3_v3(mat[3], vec);
2017  }
2018 
2019  return is_scale || is_translate;
2020  }
2021 
2022  return false;
2023 }
2024 
2026  COLLADAFW::Node *root,
2027  COLLADAFW::Node *node)
2028 {
2029  /* if bind mat is not available,
2030  * use "current" node transform, i.e. all those tms listed inside <node> */
2031  if (!armature_importer->get_joint_bind_mat(mat, node)) {
2032  float par[4][4], m[4][4];
2033 
2034  calc_joint_parent_mat_rest(par, nullptr, root, node);
2035  get_node_mat(m, node, nullptr, nullptr);
2036  mul_m4_m4m4(mat, par, m);
2037  }
2038 }
2039 
2041  float par[4][4],
2042  COLLADAFW::Node *node,
2043  COLLADAFW::Node *end)
2044 {
2045  float m[4][4];
2046 
2047  if (node == end) {
2048  par ? copy_m4_m4(mat, par) : unit_m4(mat);
2049  return true;
2050  }
2051 
2052  /* use bind matrix if available or calc "current" world mat */
2053  if (!armature_importer->get_joint_bind_mat(m, node)) {
2054  if (par) {
2055  float temp[4][4];
2056  get_node_mat(temp, node, nullptr, nullptr);
2057  mul_m4_m4m4(m, par, temp);
2058  }
2059  else {
2060  get_node_mat(m, node, nullptr, nullptr);
2061  }
2062  }
2063 
2064  COLLADAFW::NodePointerArray &children = node->getChildNodes();
2065  for (unsigned int i = 0; i < children.getCount(); i++) {
2066  if (calc_joint_parent_mat_rest(mat, m, children[i], end)) {
2067  return true;
2068  }
2069  }
2070 
2071  return false;
2072 }
2073 
2074 #ifdef ARMATURE_TEST
2075 Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root,
2076  COLLADAFW::Node *node,
2077  Object *par_job)
2078 {
2079  if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
2080  Object *job = bc_add_object(scene, OB_EMPTY, (char *)get_joint_name(node));
2081 
2082  job->lay = BKE_scene_base_find(scene, job)->lay = 2;
2083 
2084  mul_v3_fl(job->scale, 0.5f);
2086 
2087  ED_id_action_ensure((ID *)&job->id);
2088 
2089  job->rotmode = ROT_MODE_QUAT;
2090 
2091  float mat[4][4];
2092  get_joint_rest_mat(mat, root, node);
2093 
2094  if (par_job) {
2095  float temp[4][4], ipar[4][4];
2096  invert_m4_m4(ipar, par_job->obmat);
2097  copy_m4_m4(temp, mat);
2098  mul_m4_m4m4(mat, ipar, temp);
2099  }
2100 
2101  bc_decompose(mat, job->loc, NULL, job->quat, job->scale);
2102 
2103  if (par_job) {
2104  job->parent = par_job;
2105 
2107  job->parsubstr[0] = 0;
2108  }
2109 
2110  BKE_object_where_is_calc(scene, job);
2111 
2112  /* after parenting and layer change */
2114 
2115  joint_objects[node->getUniqueId()] = job;
2116  }
2117 
2118  return joint_objects[node->getUniqueId()];
2119 }
2120 #endif
2121 
2122 #if 0
2123 /* recursively evaluates joint tree until end is found,
2124  * mat then is world-space matrix of end mat must be identity on enter, node must be root. */
2125 bool AnimationImporter::evaluate_joint_world_transform_at_frame(
2126  float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra)
2127 {
2128  float m[4][4];
2129  if (par) {
2130  float temp[4][4];
2131  evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f);
2132  mul_m4_m4m4(m, par, temp);
2133  }
2134  else {
2135  evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f);
2136  }
2137 
2138  if (node == end) {
2139  copy_m4_m4(mat, m);
2140  return true;
2141  }
2142  else {
2143  COLLADAFW::NodePointerArray &children = node->getChildNodes();
2144  for (int i = 0; i < children.getCount(); i++) {
2145  if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra)) {
2146  return true;
2147  }
2148  }
2149  }
2150 
2151  return false;
2152 }
2153 #endif
2154 
2155 void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
2156 {
2157  const char *bone_name = bc_get_joint_name(node);
2158  bAction *act = ob->adt->action;
2159 
2160  /* try to find group */
2161  bActionGroup *grp = BKE_action_group_find_name(act, bone_name);
2162 
2163  /* no matching groups, so add one */
2164  if (grp == nullptr) {
2165  /* Add a new group, and make it active */
2166  grp = MEM_cnew<bActionGroup>("bActionGroup");
2167 
2168  grp->flag = AGRP_SELECTED;
2169  BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
2170 
2171  BLI_addtail(&act->groups, grp);
2172  BLI_uniquename(&act->groups,
2173  grp,
2175  '.',
2176  offsetof(bActionGroup, name),
2177  64);
2178  }
2179 
2180  /* add F-Curve to group */
2181  action_groups_add_channel(act, grp, fcu);
2182 }
2183 
2184 void AnimationImporter::set_import_from_version(std::string import_from_version)
2185 {
2186  this->import_from_version = import_from_version;
2187 }
static void report_class_type_unsupported(const char *path, const COLLADAFW::AnimationList::AnimationClass animclass, const COLLADAFW::Transformation::TransformationType type)
static double get_aspect_ratio(const COLLADAFW::Camera *camera)
static ListBase & get_animation_curves(Main *bmain, Material *ma)
static int get_animation_axis_index(const COLLADABU::Math::Vector3 &axis)
static const char * bc_get_joint_name(T *node)
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void action_groups_remove_channel(struct bAction *act, struct FCurve *fcu)
Definition: action.c:542
struct bActionGroup * BKE_action_group_find_name(struct bAction *act, const char name[])
Definition: action.c:582
void action_groups_add_channel(struct bAction *act, struct bActionGroup *agrp, struct FCurve *fcurve)
Definition: action.c:435
struct Bone * BKE_armature_find_bone_name(struct bArmature *arm, const char *name)
Definition: armature.c:594
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2135
void BKE_fcurve_free(struct FCurve *fcu)
Definition: fcurve.c:65
void BKE_fcurve_handles_recalc(struct FCurve *fcu)
Definition: fcurve.c:1303
struct FCurve * BKE_fcurve_create(void)
Definition: fcurve.c:53
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:687
General operations, lookup, etc. for blender objects.
void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: object.cc:3495
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
Definition: object.cc:3575
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1206
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2253
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
#define mul_m4_series(...)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void eul_to_mat3(float mat[3][3], const float eul[3])
void mat3_to_quat(float q[4], const float mat[3][3])
#define DEG2RADF(_deg)
void unit_qt(float q[4])
Definition: math_rotation.c:27
void eul_to_quat(float quat[4], const float eul[3])
void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle)
void mat4_to_quat(float q[4], const float mat[4][4])
float fov_to_focallength(float fov, float sensor)
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:719
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:33
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:250
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_ACTION
#define CTX_DATA_(context, msgid)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ AGRP_SELECTED
@ ROT_MODE_QUAT
@ ROT_MODE_EUL
@ INSERTKEY_NOFLAGS
@ FCURVE_SELECTED
@ FCURVE_VISIBLE
struct Camera Camera
@ HD_AUTO_ANIM
@ HD_AUTO
eBezTriple_Interpolation
@ BEZT_IPO_CONST
@ BEZT_IPO_BEZ
@ BEZT_IPO_LIN
struct Effect Effect
struct Light Light
@ OB_EMPTY
@ OB_ARMATURE
#define FPS
_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
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color or the default fallback if none is specified Separate Split a vector into its and Z components Generates normals with round corners and may slow down renders Vector Displace the surface along an arbitrary direction White Return a random value or color based on an input seed Float Map an input float to a curve and outputs a float value Separate Color
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
#define C
Definition: RandGen.cpp:25
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
unsigned int U
Definition: btGjkEpa3.h:78
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node)
float convert_to_focal_length(float in_xfov, int fov_type, float aspect, float sensorx)
void find_frames(std::vector< float > *frames, std::vector< FCurve * > *curves)
void Assign_float_animations(const COLLADAFW::UniqueId &listid, ListBase *AnimCurves, const char *anim_type)
bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id)
void read_node_transform(COLLADAFW::Node *node, Object *ob)
void Assign_transform_animations(COLLADAFW::Transformation *transform, const COLLADAFW::AnimationList::AnimationBinding *binding, std::vector< FCurve * > *curves, bool is_joint, char *joint_path)
int setAnimType(const COLLADAFW::Animatable *prop, int type, int addition)
void Assign_color_animations(const COLLADAFW::UniqueId &listid, ListBase *AnimCurves, const char *anim_type)
bool write_animation_list(const COLLADAFW::AnimationList *animlist)
AnimMix * get_animation_type(const COLLADAFW::Node *node, std::map< COLLADAFW::UniqueId, const COLLADAFW::Object * > FW_object_map)
Object * translate_animation_OLD(COLLADAFW::Node *node, std::map< COLLADAFW::UniqueId, Object * > &object_map, std::map< COLLADAFW::UniqueId, COLLADAFW::Node * > &root_map, COLLADAFW::Transformation::TransformationType tm_type, Object *par_job=NULL)
void unused_fcurve(std::vector< FCurve * > *curves)
void add_bone_animation_sampled(Object *ob, std::vector< FCurve * > &animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm)
void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
void modify_fcurve(std::vector< FCurve * > *curves, const char *rna_path, int array_index, int scale=1)
bool calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end)
void find_frames_old(std::vector< float > *frames, COLLADAFW::Node *node, COLLADAFW::Transformation::TransformationType tm_type)
void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
void apply_matrix_curves(Object *ob, std::vector< FCurve * > &animcurves, COLLADAFW::Node *root, COLLADAFW::Node *node, COLLADAFW::Transformation *tm)
void translate_Animations(COLLADAFW::Node *Node, std::map< COLLADAFW::UniqueId, COLLADAFW::Node * > &root_map, std::multimap< COLLADAFW::UniqueId, Object * > &object_map, std::map< COLLADAFW::UniqueId, const COLLADAFW::Object * > FW_object_map, std::map< COLLADAFW::UniqueId, Material * > uid_material_map)
bool write_animation(const COLLADAFW::Animation *anim)
void Assign_lens_animations(const COLLADAFW::UniqueId &listid, ListBase *AnimCurves, double aspect, Camera *cam, const char *anim_type, int fov_type)
void set_import_from_version(std::string import_from_version)
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
Object * get_armature_for_joint(COLLADAFW::Node *node)
bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
Definition: BCMath.h:15
void rotate_to(Matrix &mat_to)
Definition: BCMath.cpp:9
Quat & quat()
Definition: BCMath.h:35
void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3])
void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map< COLLADAFW::UniqueId, Animation > *animation_map, Object *ob)
void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3])
void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4])
static void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in)
Object * bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index)
void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
#define tanf(x)
Definition: cuda/compat.h:104
#define SELECT
OperationNode * node
Curve curve
Light lamp
#define rot(x, k)
uint col
float[3] Vector3
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
bAction * ED_id_action_ensure(Main *bmain, ID *id)
Definition: keyframing.c:123
int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
Definition: keyframing.c:410
static char ** types
Definition: makesdna.c:67
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
Definition: math_float2.h:232
#define T
#define atanf(x)
Definition: metal/compat.h:223
bool remove(void *owner, const AttributeIDRef &attribute_id)
static const pxr::TfToken ior("ior", pxr::TfToken::Immortal)
bAction * action
uint8_t h1
uint8_t f3
float vec[3][3]
uint8_t f1
uint8_t f2
uint8_t h2
float arm_mat[4][4]
struct AnimData * adt
float sensor_x
char * rna_path
BezTriple * bezt
int array_index
short flag
unsigned int totvert
char auto_smoothing
Definition: DNA_ID.h:368
struct AnimData * adt
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
struct AnimData * adt
struct bPose * pose
float loc[3]
float scale[3]
float obmat[4][4]
float quat[4]
short rotmode
struct AnimData * adt
struct Object * parent
void * data
char parsubstr[64]
Definition: IMB_anim.h:71
struct bActionGroup * next
ListBase curves
ListBase groups
struct Bone * bone
struct bPoseChannel * next
ListBase chanbase
InterpolationType
Definition: util/texture.h:19
@ INTERPOLATION_LINEAR
Definition: util/texture.h:21