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