COLLADA branch: merge from trunk -r 25745:26429.
[blender-staging.git] / source / blender / collada / DocumentImporter.cpp
1 // TODO:
2 // * name imported objects
3 // * import object rotation as euler
4
5 #include "COLLADAFWRoot.h"
6 #include "COLLADAFWIWriter.h"
7 #include "COLLADAFWStableHeaders.h"
8 #include "COLLADAFWAnimationCurve.h"
9 #include "COLLADAFWAnimationList.h"
10 #include "COLLADAFWCamera.h"
11 #include "COLLADAFWColorOrTexture.h"
12 #include "COLLADAFWEffect.h"
13 #include "COLLADAFWFloatOrDoubleArray.h"
14 #include "COLLADAFWGeometry.h"
15 #include "COLLADAFWImage.h"
16 #include "COLLADAFWIndexList.h"
17 #include "COLLADAFWInstanceGeometry.h"
18 #include "COLLADAFWLight.h"
19 #include "COLLADAFWMaterial.h"
20 #include "COLLADAFWMesh.h"
21 #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
22 #include "COLLADAFWNode.h"
23 #include "COLLADAFWPolygons.h"
24 #include "COLLADAFWSampler.h"
25 #include "COLLADAFWSkinController.h"
26 #include "COLLADAFWSkinControllerData.h"
27 #include "COLLADAFWTransformation.h"
28 #include "COLLADAFWTranslate.h"
29 #include "COLLADAFWRotate.h"
30 #include "COLLADAFWScale.h"
31 #include "COLLADAFWMatrix.h"
32 #include "COLLADAFWTypes.h"
33 #include "COLLADAFWVisualScene.h"
34 #include "COLLADAFWFileInfo.h"
35 #include "COLLADAFWArrayPrimitiveType.h"
36
37 #include "COLLADASaxFWLLoader.h"
38
39 // TODO move "extern C" into header files
40 extern "C" 
41 {
42 #include "ED_keyframing.h"
43 #include "ED_armature.h"
44 #include "ED_mesh.h" // ED_vgroup_vert_add, ...
45 #include "ED_anim_api.h"
46 #include "ED_object.h"
47
48 #include "WM_types.h"
49 #include "WM_api.h"
50
51 #include "BKE_main.h"
52 #include "BKE_customdata.h"
53 #include "BKE_library.h"
54 #include "BKE_texture.h"
55 #include "BKE_fcurve.h"
56 #include "BKE_depsgraph.h"
57 #include "BLI_path_util.h"
58 #include "BKE_displist.h"
59 #include "BLI_math.h"
60 #include "BKE_scene.h"
61 }
62 #include "BKE_armature.h"
63 #include "BKE_mesh.h"
64 #include "BKE_global.h"
65 #include "BKE_context.h"
66 #include "BKE_object.h"
67 #include "BKE_image.h"
68 #include "BKE_material.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_action.h"
71
72 #include "BLI_math.h"
73 #include "BLI_listbase.h"
74 #include "BLI_string.h"
75
76 #include "DNA_lamp_types.h"
77 #include "DNA_armature_types.h"
78 #include "DNA_anim_types.h"
79 #include "DNA_curve_types.h"
80 #include "DNA_texture_types.h"
81 #include "DNA_camera_types.h"
82 #include "DNA_object_types.h"
83 #include "DNA_meshdata_types.h"
84 #include "DNA_mesh_types.h"
85 #include "DNA_material_types.h"
86 #include "DNA_scene_types.h"
87 #include "DNA_modifier_types.h"
88
89 #include "MEM_guardedalloc.h"
90
91 #include "DocumentImporter.h"
92 #include "collada_internal.h"
93
94 #include <string>
95 #include <map>
96 #include <algorithm> // sort()
97
98 #include <math.h>
99 #include <float.h>
100
101 // #define COLLADA_DEBUG
102 #define ARMATURE_TEST
103
104 char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
105
106 const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
107 {
108         using namespace COLLADAFW;
109         
110         switch (type) {
111         case MeshPrimitive::LINES:
112                 return "LINES";
113         case MeshPrimitive::LINE_STRIPS:
114                 return "LINESTRIPS";
115         case MeshPrimitive::POLYGONS:
116                 return "POLYGONS";
117         case MeshPrimitive::POLYLIST:
118                 return "POLYLIST";
119         case MeshPrimitive::TRIANGLES:
120                 return "TRIANGLES";
121         case MeshPrimitive::TRIANGLE_FANS:
122                 return "TRIANGLE_FANS";
123         case MeshPrimitive::TRIANGLE_STRIPS:
124                 return "TRIANGLE_FANS";
125         case MeshPrimitive::POINTS:
126                 return "POINTS";
127         case MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
128                 return "UNDEFINED_PRIMITIVE_TYPE";
129         }
130         return "UNKNOWN";
131 }
132 const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
133 {
134         switch (type) {
135         case COLLADAFW::Geometry::GEO_TYPE_MESH:
136                 return "MESH";
137         case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
138                 return "SPLINE";
139         case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
140                 return "CONVEX_MESH";
141         case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
142         default:
143                 return "UNKNOWN";
144         }
145 }
146
147 // works for COLLADAFW::Node, COLLADAFW::Geometry
148 template<class T>
149 const char *get_dae_name(T *node)
150 {
151         const std::string& name = node->getName();
152         return name.size() ? name.c_str() : node->getOriginalId().c_str();
153 }
154
155 // use this for retrieving bone names, since these must be unique
156 template<class T>
157 const char *get_joint_name(T *node)
158 {
159         const std::string& id = node->getOriginalId();
160         return id.size() ? id.c_str() : node->getName().c_str();
161 }
162
163 float get_float_value(const COLLADAFW::FloatOrDoubleArray& array, int index)
164 {
165         if (index >= array.getValuesCount())
166                 return 0.0f;
167
168         if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT)
169                 return array.getFloatValues()->getData()[index];
170         else 
171                 return array.getDoubleValues()->getData()[index];
172 }
173
174 typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap;
175
176 class TransformReader : public TransformBase
177 {
178 protected:
179
180         UnitConverter *unit_converter;
181
182         struct Animation {
183                 Object *ob;
184                 COLLADAFW::Node *node;
185                 COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id
186         };
187
188 public:
189
190         TransformReader(UnitConverter* conv) : unit_converter(conv) {}
191
192         void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map,
193                                           Object *ob)
194         {
195                 float cur[4][4];
196                 float copy[4][4];
197
198                 unit_m4(mat);
199                 
200                 for (int i = 0; i < node->getTransformations().getCount(); i++) {
201
202                         COLLADAFW::Transformation *tm = node->getTransformations()[i];
203                         COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
204
205                         switch(type) {
206                         case COLLADAFW::Transformation::TRANSLATE:
207                                 dae_translate_to_mat4(tm, cur);
208                                 break;
209                         case COLLADAFW::Transformation::ROTATE:
210                                 dae_rotate_to_mat4(tm, cur);
211                                 break;
212                         case COLLADAFW::Transformation::SCALE:
213                                 dae_scale_to_mat4(tm, cur);
214                                 break;
215                         case COLLADAFW::Transformation::MATRIX:
216                                 dae_matrix_to_mat4(tm, cur);
217                                 break;
218                         case COLLADAFW::Transformation::LOOKAT:
219                         case COLLADAFW::Transformation::SKEW:
220                                 fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
221                                 break;
222                         }
223
224                         copy_m4_m4(copy, mat);
225                         mul_m4_m4m4(mat, cur, copy);
226
227                         if (animation_map) {
228                                 // AnimationList that drives this Transformation
229                                 const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList();
230                         
231                                 // store this so later we can link animation data with ob
232                                 Animation anim = {ob, node, tm};
233                                 (*animation_map)[anim_list_id] = anim;
234                         }
235                 }
236         }
237
238         void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
239         {
240                 COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm;
241                 COLLADABU::Math::Vector3& axis = ro->getRotationAxis();
242                 float angle = (float)(ro->getRotationAngle() * M_PI / 180.0f);
243                 float ax[] = {axis[0], axis[1], axis[2]};
244                 // float quat[4];
245                 // axis_angle_to_quat(quat, axis, angle);
246                 // quat_to_mat4(m, quat);
247                 axis_angle_to_mat4(m, ax, angle);
248         }
249
250         void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
251         {
252                 COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm;
253                 COLLADABU::Math::Vector3& t = tra->getTranslation();
254
255                 unit_m4(m);
256
257                 m[3][0] = (float)t[0];
258                 m[3][1] = (float)t[1];
259                 m[3][2] = (float)t[2];
260         }
261
262         void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
263         {
264                 COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale();
265                 float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
266                 size_to_mat4(m, size);
267         }
268
269         void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
270         {
271                 unit_converter->dae_matrix_to_mat4(m, ((COLLADAFW::Matrix*)tm)->getMatrix());
272         }
273 };
274
275 // only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid
276 class MeshImporterBase
277 {
278 public:
279         virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0;
280 };
281
282 // ditto as above
283 class AnimationImporterBase
284 {
285 public:
286         // virtual void change_eul_to_quat(Object *ob, bAction *act) = 0;
287 };
288
289 class ArmatureImporter : private TransformReader
290 {
291 private:
292         Scene *scene;
293         UnitConverter *unit_converter;
294
295         // std::map<int, JointData> joint_index_to_joint_info_map;
296         // std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
297
298         struct LeafBone {
299                 // COLLADAFW::Node *node;
300                 EditBone *bone;
301                 char name[32];
302                 float mat[4][4]; // bone matrix, derived from inv_bind_mat
303         };
304         std::vector<LeafBone> leaf_bones;
305         // int bone_direction_row; // XXX not used
306         float leaf_bone_length;
307         int totbone;
308         // XXX not used
309         // float min_angle; // minimum angle between bone head-tail and a row of bone matrix
310
311 #if 0
312         struct ArmatureJoints {
313                 Object *ob_arm;
314                 std::vector<COLLADAFW::Node*> root_joints;
315         };
316         std::vector<ArmatureJoints> armature_joints;
317 #endif
318
319         Object *empty; // empty for leaf bones
320
321         std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid;
322         std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
323         std::vector<COLLADAFW::Node*> root_joints;
324
325         std::vector<Object*> armature_objects;
326
327         MeshImporterBase *mesh_importer;
328         AnimationImporterBase *anim_importer;
329
330         // This is used to store data passed in write_controller_data.
331         // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members
332         // so that arrays don't get freed until we free them explicitly.
333         class SkinInfo
334         {
335         private:
336                 // to build armature bones from inverse bind matrices
337                 struct JointData {
338                         float inv_bind_mat[4][4]; // joint inverse bind matrix
339                         COLLADAFW::UniqueId joint_uid; // joint node UID
340                         // Object *ob_arm;                        // armature object
341                 };
342
343                 float bind_shape_matrix[4][4];
344
345                 // data from COLLADAFW::SkinControllerData, each array should be freed
346                 COLLADAFW::UIntValuesArray joints_per_vertex;
347                 COLLADAFW::UIntValuesArray weight_indices;
348                 COLLADAFW::IntValuesArray joint_indices;
349                 // COLLADAFW::FloatOrDoubleArray weights;
350                 std::vector<float> weights;
351
352                 std::vector<JointData> joint_data; // index to this vector is joint index
353
354                 UnitConverter *unit_converter;
355
356                 Object *ob_arm;
357                 COLLADAFW::UniqueId controller_uid;
358
359         public:
360
361                 SkinInfo() {}
362
363                 SkinInfo(const SkinInfo& skin) : weights(skin.weights),
364                                                                                  joint_data(skin.joint_data),
365                                                                                  unit_converter(skin.unit_converter),
366                                                                                  ob_arm(skin.ob_arm),
367                                                                                  controller_uid(skin.controller_uid)
368                 {
369                         copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix);
370
371                         transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex);
372                         transfer_uint_array_data_const(skin.weight_indices, weight_indices);
373                         transfer_int_array_data_const(skin.joint_indices, joint_indices);
374                 }
375
376                 SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL) {}
377
378                 // nobody owns the data after this, so it should be freed manually with releaseMemory
379                 template <class T>
380                 void transfer_array_data(T& src, T& dest)
381                 {
382                         dest.setData(src.getData(), src.getCount());
383                         src.yieldOwnerShip();
384                         dest.yieldOwnerShip();
385                 }
386
387                 // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor
388                 void transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest)
389                 {
390                         dest.setData((int*)src.getData(), src.getCount());
391                         dest.yieldOwnerShip();
392                 }
393
394                 void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest)
395                 {
396                         dest.setData((unsigned int*)src.getData(), src.getCount());
397                         dest.yieldOwnerShip();
398                 }
399
400                 void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin)
401                 {
402                         transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex);
403                         transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices);
404                         transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices);
405                         // transfer_array_data(skin->getWeights(), weights);
406
407                         // cannot transfer data for FloatOrDoubleArray, copy values manually
408                         const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights();
409                         for (int i = 0; i < weight.getValuesCount(); i++)
410                                 weights.push_back(get_float_value(weight, i));
411
412                         unit_converter->dae_matrix_to_mat4(bind_shape_matrix, skin->getBindShapeMatrix());
413                 }
414                         
415                 void free()
416                 {
417                         joints_per_vertex.releaseMemory();
418                         weight_indices.releaseMemory();
419                         joint_indices.releaseMemory();
420                         // weights.releaseMemory();
421                 }
422
423                 // using inverse bind matrices to construct armature
424                 // it is safe to invert them to get the original matrices
425                 // because if they are inverse matrices, they can be inverted
426                 void add_joint(const COLLADABU::Math::Matrix4& matrix)
427                 {
428                         JointData jd;
429                         unit_converter->dae_matrix_to_mat4(jd.inv_bind_mat, matrix);
430                         joint_data.push_back(jd);
431                 }
432
433                 // called from write_controller
434                 Object *create_armature(const COLLADAFW::SkinController* co, Scene *scene)
435                 {
436                         ob_arm = add_object(scene, OB_ARMATURE);
437
438                         controller_uid = co->getUniqueId();
439
440                         const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints();
441                         for (int i = 0; i < joint_uids.getCount(); i++) {
442                                 joint_data[i].joint_uid = joint_uids[i];
443
444                                 // // store armature pointer
445                                 // JointData& jd = joint_index_to_joint_info_map[i];
446                                 // jd.ob_arm = ob_arm;
447
448                                 // now we'll be able to get inv bind matrix from joint id
449                                 // joint_id_to_joint_index_map[joint_ids[i]] = i;
450                         }
451
452                         return ob_arm;
453                 }
454
455                 bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node)
456                 {
457                         const COLLADAFW::UniqueId& uid = node->getUniqueId();
458                         std::vector<JointData>::iterator it;
459                         for (it = joint_data.begin(); it != joint_data.end(); it++) {
460                                 if ((*it).joint_uid == uid) {
461                                         copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat);
462                                         return true;
463                                 }
464                         }
465
466                         return false;
467                 }
468
469                 Object *get_armature()
470                 {
471                         return ob_arm;
472                 }
473
474                 const COLLADAFW::UniqueId& get_controller_uid()
475                 {
476                         return controller_uid;
477                 }
478
479                 // some nodes may not be referenced by SkinController,
480                 // in this case to determine if the node belongs to this armature,
481                 // we need to search down the tree
482                 bool uses_joint(COLLADAFW::Node *node)
483                 {
484                         const COLLADAFW::UniqueId& uid = node->getUniqueId();
485                         std::vector<JointData>::iterator it;
486                         for (it = joint_data.begin(); it != joint_data.end(); it++) {
487                                 if ((*it).joint_uid == uid)
488                                         return true;
489                         }
490
491                         COLLADAFW::NodePointerArray& children = node->getChildNodes();
492                         for (int i = 0; i < children.getCount(); i++) {
493                                 if (this->uses_joint(children[i]))
494                                         return true;
495                         }
496
497                         return false;
498                 }
499
500                 void link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
501                                                    TransformReader *tm)
502                 {
503                         Object workob;
504                         Scene *scene = CTX_data_scene(C);
505
506                         ModifierData *md = ED_object_modifier_add(NULL, scene, ob, NULL, eModifierType_Armature);
507                         ((ArmatureModifierData *)md)->object = ob_arm;
508
509                         tm->decompose(bind_shape_matrix, ob->loc, ob->rot, NULL, ob->size);
510
511                         ob->parent = ob_arm;
512                         ob->partype = PAROBJECT;
513
514                         what_does_parent(scene, ob, &workob);
515                         invert_m4_m4(ob->parentinv, workob.obmat);
516
517                         ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
518
519                         ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP;
520
521                         // create all vertex groups
522                         std::vector<JointData>::iterator it;
523                         int joint_index;
524                         for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) {
525                                 const char *name = "Group";
526
527                                 // name group by joint node name
528                                 if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) {
529                                         name = get_joint_name(joint_by_uid[(*it).joint_uid]);
530                                 }
531
532                                 ED_vgroup_add_name(ob, (char*)name);
533                         }
534
535                         // <vcount> - number of joints per vertex - joints_per_vertex
536                         // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices
537                         // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender?
538
539                         // for each vertex in weight indices
540                         //   for each bone index in vertex
541                         //     add vertex to group at group index
542                         //     treat group index -1 specially
543
544                         // get def group by index with BLI_findlink
545
546                         for (int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
547
548                                 int limit = weight + joints_per_vertex[vertex];
549                                 for ( ; weight < limit; weight++) {
550                                         int joint = joint_indices[weight], joint_weight = weight_indices[weight];
551
552                                         // -1 means "weight towards the bind shape", we just don't assign it to any group
553                                         if (joint != -1) {
554                                                 bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint);
555
556                                                 ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE);
557                                         }
558                                 }
559                         }
560
561                         DAG_scene_sort(scene);
562                         DAG_ids_flush_update(0);
563                         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
564                 }
565
566                 bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node)
567                 {
568                         return get_pose_channel(ob_arm->pose, get_joint_name(node));
569                 }
570         };
571
572         std::map<COLLADAFW::UniqueId, SkinInfo> skin_by_data_uid; // data UID = skin controller data UID
573 #if 0
574         JointData *get_joint_data(COLLADAFW::Node *node)
575         {
576                 const COLLADAFW::UniqueId& joint_id = node->getUniqueId();
577
578                 if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
579                         fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
580                                         node->getOriginalId().c_str());
581                         return NULL;
582                 }
583
584                 int joint_index = joint_id_to_joint_index_map[joint_id];
585
586                 return &joint_index_to_joint_info_map[joint_index];
587         }
588 #endif
589
590         void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
591                                          float parent_mat[][4], bArmature *arm)
592         {
593                 float joint_inv_bind_mat[4][4];
594
595                 // JointData* jd = get_joint_data(node);
596
597                 float mat[4][4];
598
599                 if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
600                         // get original world-space matrix
601                         invert_m4_m4(mat, joint_inv_bind_mat);
602                 }
603                 // create a bone even if there's no joint data for it (i.e. it has no influence)
604                 else {
605                         float obmat[4][4];
606
607                         // object-space
608                         get_node_mat(obmat, node, NULL, NULL);
609
610                         // get world-space
611                         if (parent)
612                                 mul_m4_m4m4(mat, obmat, parent_mat);
613                         else
614                                 copy_m4_m4(mat, obmat);
615                 }
616
617                 // TODO rename from Node "name" attrs later
618                 EditBone *bone = ED_armature_edit_bone_add(arm, (char*)get_joint_name(node));
619                 totbone++;
620
621                 if (parent) bone->parent = parent;
622
623                 // set head
624                 copy_v3_v3(bone->head, mat[3]);
625
626                 // set tail, don't set it to head because 0-length bones are not allowed
627                 float vec[3] = {0.0f, 0.5f, 0.0f};
628                 add_v3_v3v3(bone->tail, bone->head, vec);
629
630                 // set parent tail
631                 if (parent && totchild == 1) {
632                         copy_v3_v3(parent->tail, bone->head);
633
634                         // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
635                         // bone->flag |= BONE_CONNECTED;
636
637                         // XXX increase this to prevent "very" small bones?
638                         const float epsilon = 0.000001f;
639
640                         // derive leaf bone length
641                         float length = len_v3v3(parent->head, parent->tail);
642                         if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
643                                 leaf_bone_length = length;
644                         }
645
646                         // treat zero-sized bone like a leaf bone
647                         if (length <= epsilon) {
648                                 add_leaf_bone(parent_mat, parent);
649                         }
650
651                         /*
652 #if 0
653                         // and which row in mat is bone direction
654                         float vec[3];
655                         sub_v3_v3v3(vec, parent->tail, parent->head);
656 #ifdef COLLADA_DEBUG
657                         print_v3("tail - head", vec);
658                         print_m4("matrix", parent_mat);
659 #endif
660                         for (int i = 0; i < 3; i++) {
661 #ifdef COLLADA_DEBUG
662                                 char *axis_names[] = {"X", "Y", "Z"};
663                                 printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i]));
664 #endif
665                                 float angle = angle_v2v2(vec, parent_mat[i]);
666                                 if (angle < min_angle) {
667 #ifdef COLLADA_DEBUG
668                                         print_v3("picking", parent_mat[i]);
669                                         printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node));
670 #endif
671                                         bone_direction_row = i;
672                                         min_angle = angle;
673                                 }
674                         }
675 #endif
676                         */
677                 }
678
679                 COLLADAFW::NodePointerArray& children = node->getChildNodes();
680                 for (int i = 0; i < children.getCount(); i++) {
681                         create_bone(skin, children[i], bone, children.getCount(), mat, arm);
682                 }
683
684                 // in second case it's not a leaf bone, but we handle it the same way
685                 if (!children.getCount() || children.getCount() > 1) {
686                         add_leaf_bone(mat, bone);
687                 }
688         }
689
690         void add_leaf_bone(float mat[][4], EditBone *bone)
691         {
692                 LeafBone leaf;
693
694                 leaf.bone = bone;
695                 copy_m4_m4(leaf.mat, mat);
696                 BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
697
698                 leaf_bones.push_back(leaf);
699         }
700
701         void fix_leaf_bones()
702         {
703                 // just setting tail for leaf bones here
704
705                 std::vector<LeafBone>::iterator it;
706                 for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
707                         LeafBone& leaf = *it;
708
709                         // pointing up
710                         float vec[3] = {0.0f, 0.0f, 1.0f};
711
712                         mul_v3_fl(vec, leaf_bone_length);
713
714                         copy_v3_v3(leaf.bone->tail, leaf.bone->head);
715                         add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
716                 }
717         }
718
719         void set_leaf_bone_shapes(Object *ob_arm)
720         {
721                 bPose *pose = ob_arm->pose;
722
723                 std::vector<LeafBone>::iterator it;
724                 for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
725                         LeafBone& leaf = *it;
726
727                         bPoseChannel *pchan = get_pose_channel(pose, leaf.name);
728                         if (pchan) {
729                                 pchan->custom = get_empty_for_leaves();
730                         }
731                         else {
732                                 fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name);
733                         }
734                 }
735         }
736
737 #if 0
738         void set_euler_rotmode()
739         {
740                 // just set rotmode = ROT_MODE_EUL on pose channel for each joint
741
742                 std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>::iterator it;
743
744                 for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
745
746                         COLLADAFW::Node *joint = it->second;
747
748                         std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
749                         
750                         for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
751                                 SkinInfo& skin = sit->second;
752
753                                 if (skin.uses_joint(joint)) {
754                                         bPoseChannel *pchan = skin.get_pose_channel_from_node(joint);
755
756                                         if (pchan) {
757                                                 pchan->rotmode = ROT_MODE_EUL;
758                                         }
759                                         else {
760                                                 fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint));
761                                         }
762
763                                         break;
764                                 }
765                         }
766                 }
767         }
768 #endif
769
770         Object *get_empty_for_leaves()
771         {
772                 if (empty) return empty;
773                 
774                 empty = add_object(scene, OB_EMPTY);
775                 empty->empty_drawtype = OB_EMPTY_SPHERE;
776
777                 return empty;
778         }
779
780 #if 0
781         Object *find_armature(COLLADAFW::Node *node)
782         {
783                 JointData* jd = get_joint_data(node);
784                 if (jd) return jd->ob_arm;
785
786                 COLLADAFW::NodePointerArray& children = node->getChildNodes();
787                 for (int i = 0; i < children.getCount(); i++) {
788                         Object *ob_arm = find_armature(children[i]);
789                         if (ob_arm) return ob_arm;
790                 }
791
792                 return NULL;
793         }
794
795         ArmatureJoints& get_armature_joints(Object *ob_arm)
796         {
797                 // try finding it
798                 std::vector<ArmatureJoints>::iterator it;
799                 for (it = armature_joints.begin(); it != armature_joints.end(); it++) {
800                         if ((*it).ob_arm == ob_arm) return *it;
801                 }
802
803                 // not found, create one
804                 ArmatureJoints aj;
805                 aj.ob_arm = ob_arm;
806                 armature_joints.push_back(aj);
807
808                 return armature_joints.back();
809         }
810 #endif
811
812         void create_armature_bones(SkinInfo& skin)
813         {
814                 // just do like so:
815                 // - get armature
816                 // - enter editmode
817                 // - add edit bones and head/tail properties using matrices and parent-child info
818                 // - exit edit mode
819                 // - set a sphere shape to leaf bones
820
821                 Object *ob_arm = skin.get_armature();
822
823                 // enter armature edit mode
824                 ED_armature_to_edit(ob_arm);
825
826                 leaf_bones.clear();
827                 totbone = 0;
828                 // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
829                 leaf_bone_length = 0.1f;
830                 // min_angle = 360.0f;          // minimum angle between bone head-tail and a row of bone matrix
831
832                 // create bones
833
834                 std::vector<COLLADAFW::Node*>::iterator it;
835                 for (it = root_joints.begin(); it != root_joints.end(); it++) {
836                         // since root_joints may contain joints for multiple controllers, we need to filter
837                         if (skin.uses_joint(*it)) {
838                                 create_bone(skin, *it, NULL, (*it)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
839                         }
840                 }
841
842                 fix_leaf_bones();
843
844                 // exit armature edit mode
845                 ED_armature_from_edit(ob_arm);
846                 ED_armature_edit_free(ob_arm);
847                 DAG_id_flush_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
848
849                 set_leaf_bone_shapes(ob_arm);
850
851                 // set_euler_rotmode();
852         }
853         
854
855 public:
856
857         ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
858                 TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {}
859
860         ~ArmatureImporter()
861         {
862                 // free skin controller data if we forget to do this earlier
863                 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
864                 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
865                         it->second.free();
866                 }
867         }
868
869         // root - if this joint is the top joint in hierarchy, if a joint
870         // is a child of a node (not joint), root should be true since
871         // this is where we build armature bones from
872         void add_joint(COLLADAFW::Node *node, bool root)
873         {
874                 joint_by_uid[node->getUniqueId()] = node;
875                 if (root) root_joints.push_back(node);
876         }
877
878 #if 0
879         void add_root_joint(COLLADAFW::Node *node)
880         {
881                 // root_joints.push_back(node);
882                 Object *ob_arm = find_armature(node);
883                 if (ob_arm)     {
884                         get_armature_joints(ob_arm).root_joints.push_back(node);
885                 }
886 #ifdef COLLADA_DEBUG
887                 else {
888                         fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node));
889                 }
890 #endif
891         }
892 #endif
893
894         // here we add bones to armatures, having armatures previously created in write_controller
895         void make_armatures(bContext *C)
896         {
897                 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
898                 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
899
900                         SkinInfo& skin = it->second;
901
902                         create_armature_bones(skin);
903
904                         // link armature with an object
905                         Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
906                         if (ob) {
907                                 skin.link_armature(C, ob, joint_by_uid, this);
908                         }
909                         else {
910                                 fprintf(stderr, "Cannot find object to link armature with.\n");
911                         }
912
913                         // free memory stolen from SkinControllerData
914                         skin.free();
915                 }
916         }
917
918 #if 0
919         // link with meshes, create vertex groups, assign weights
920         void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id)
921         {
922                 Object *ob = mesh_importer->get_object_by_geom_uid(geom_id);
923
924                 if (!ob) {
925                         fprintf(stderr, "Cannot find object by geometry UID.\n");
926                         return;
927                 }
928
929                 if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) {
930                         fprintf(stderr, "Cannot find skin info by controller data UID.\n");
931                         return;
932                 }
933
934                 SkinInfo& skin = skin_by_data_uid[conroller_data_id];
935
936                 // create vertex groups
937         }
938 #endif
939
940         bool write_skin_controller_data(const COLLADAFW::SkinControllerData* data)
941         {
942                 // at this stage we get vertex influence info that should go into me->verts and ob->defbase
943                 // there's no info to which object this should be long so we associate it with skin controller data UID
944
945                 // don't forget to call defgroup_unique_name before we copy
946
947                 // controller data uid -> [armature] -> joint data, 
948                 // [mesh object]
949                 // 
950
951                 SkinInfo skin(unit_converter);
952                 skin.borrow_skin_controller_data(data);
953
954                 // store join inv bind matrix to use it later in armature construction
955                 const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices();
956                 for (int i = 0; i < data->getJointsCount(); i++) {
957                         skin.add_joint(inv_bind_mats[i]);
958                 }
959
960                 skin_by_data_uid[data->getUniqueId()] = skin;
961
962                 return true;
963         }
964
965         bool write_controller(const COLLADAFW::Controller* controller)
966         {
967                 // - create and store armature object
968
969                 const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
970
971                 if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
972
973                         COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller;
974
975                         // to find geom id by controller id
976                         geom_uid_by_controller_uid[skin_id] = co->getSource();
977
978                         const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData();
979                         if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
980                                 fprintf(stderr, "Cannot find skin by controller data UID.\n");
981                                 return true;
982                         }
983
984                         Object *ob_arm = skin_by_data_uid[data_uid].create_armature(co, scene);
985
986                         armature_objects.push_back(ob_arm);
987                 }
988                 // morph controller
989                 else {
990                         // shape keys? :)
991                         fprintf(stderr, "Morph controller is not supported yet.\n");
992                 }
993
994                 return true;
995         }
996
997         COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
998         {
999                 if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end())
1000                         return NULL;
1001
1002                 return &geom_uid_by_controller_uid[controller_uid];
1003         }
1004
1005         Object *get_armature_for_joint(COLLADAFW::Node *node)
1006         {
1007                 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1008                 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1009                         SkinInfo& skin = it->second;
1010
1011                         if (skin.uses_joint(node))
1012                                 return skin.get_armature();
1013                 }
1014
1015                 return NULL;
1016         }
1017
1018         void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
1019         {
1020                 BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", get_joint_name(node));
1021         }
1022         
1023 #if 0
1024         void fix_animation()
1025         {
1026                 /* Change Euler rotation to Quaternion for bone animation */
1027                 std::vector<Object*>::iterator it;
1028                 for (it = armature_objects.begin(); it != armature_objects.end(); it++) {
1029                         Object *ob = *it;
1030                         if (!ob || !ob->adt || !ob->adt->action) continue;
1031                         anim_importer->change_eul_to_quat(ob, ob->adt->action);
1032                 }
1033         }
1034 #endif
1035
1036         // gives a world-space mat
1037         bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
1038         {
1039                 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1040                 bool found = false;
1041                 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1042                         SkinInfo& skin = it->second;
1043                         if ((found = skin.get_joint_inv_bind_matrix(m, joint))) {
1044                                 invert_m4(m);
1045                                 break;
1046                         }
1047                 }
1048
1049                 return found;
1050         }
1051 };
1052
1053 class MeshImporter : public MeshImporterBase
1054 {
1055 private:
1056
1057         Scene *scene;
1058         ArmatureImporter *armature_importer;
1059
1060         std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
1061         std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
1062         // this structure is used to assign material indices to faces
1063         // it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
1064         struct Primitive {
1065                 MFace *mface;
1066                 unsigned int totface;
1067         };
1068         typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
1069         std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
1070         
1071         class UVDataWrapper
1072         {
1073                 COLLADAFW::MeshVertexData *mVData;
1074         public:
1075                 UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
1076                 {}
1077
1078 #ifdef COLLADA_DEBUG
1079                 void print()
1080                 {
1081                         fprintf(stderr, "UVs:\n");
1082                         switch(mVData->getType()) {
1083                         case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1084                                 {
1085                                         COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1086                                         if (values->getCount()) {
1087                                                 for (int i = 0; i < values->getCount(); i += 2) {
1088                                                         fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]);
1089                                                 }
1090                                         }
1091                                 }
1092                                 break;
1093                         case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1094                                 {
1095                                         COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1096                                         if (values->getCount()) {
1097                                                 for (int i = 0; i < values->getCount(); i += 2) {
1098                                                         fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]);
1099                                                 }
1100                                         }
1101                                 }
1102                                 break;
1103                         }
1104                         fprintf(stderr, "\n");
1105                 }
1106 #endif
1107
1108                 void getUV(int uv_set_index, int uv_index[2], float *uv)
1109                 {
1110                         switch(mVData->getType()) {
1111                         case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1112                                 {
1113                                         COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1114                                         if (values->empty()) return;
1115                                         uv[0] = (*values)[uv_index[0]];
1116                                         uv[1] = (*values)[uv_index[1]];
1117                                         
1118                                 }
1119                                 break;
1120                         case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1121                                 {
1122                                         COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1123                                         if (values->empty()) return;
1124                                         uv[0] = (float)(*values)[uv_index[0]];
1125                                         uv[1] = (float)(*values)[uv_index[1]];
1126                                         
1127                                 }
1128                                 break;
1129                         case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:      
1130                         default:
1131                                 fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
1132                         }
1133                 }
1134         };
1135
1136         void set_face_indices(MFace *mface, unsigned int *indices, bool quad)
1137         {
1138                 mface->v1 = indices[0];
1139                 mface->v2 = indices[1];
1140                 mface->v3 = indices[2];
1141                 if (quad) mface->v4 = indices[3];
1142                 else mface->v4 = 0;
1143 #ifdef COLLADA_DEBUG
1144                 // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]);
1145 #endif
1146         }
1147
1148         // not used anymore, test_index_face from blenkernel is better
1149 #if 0
1150         // change face indices order so that v4 is not 0
1151         void rotate_face_indices(MFace *mface) {
1152                 mface->v4 = mface->v1;
1153                 mface->v1 = mface->v2;
1154                 mface->v2 = mface->v3;
1155                 mface->v3 = 0;
1156         }
1157 #endif
1158         
1159         void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, int uv_set_index,
1160                                          COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
1161         {
1162                 int uv_indices[4][2];
1163
1164                 // per face vertex indices, this means for quad we have 4 indices, not 8
1165                 COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1166
1167                 // make indices into FloatOrDoubleArray
1168                 for (int i = 0; i < 3; i++) {
1169                         int uv_index = indices[tris_indices[i]];
1170                         uv_indices[i][0] = uv_index * 2;
1171                         uv_indices[i][1] = uv_index * 2 + 1;
1172                 }
1173
1174                 uvs.getUV(uv_set_index, uv_indices[0], mtface->uv[0]);
1175                 uvs.getUV(uv_set_index, uv_indices[1], mtface->uv[1]);
1176                 uvs.getUV(uv_set_index, uv_indices[2], mtface->uv[2]);
1177         }
1178
1179         void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, int uv_set_index,
1180                                         COLLADAFW::IndexList& index_list, int index, bool quad)
1181         {
1182                 int uv_indices[4][2];
1183
1184                 // per face vertex indices, this means for quad we have 4 indices, not 8
1185                 COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1186
1187                 // make indices into FloatOrDoubleArray
1188                 for (int i = 0; i < (quad ? 4 : 3); i++) {
1189                         int uv_index = indices[index + i];
1190                         uv_indices[i][0] = uv_index * 2;
1191                         uv_indices[i][1] = uv_index * 2 + 1;
1192                 }
1193
1194                 uvs.getUV(uv_set_index, uv_indices[0], mtface->uv[0]);
1195                 uvs.getUV(uv_set_index, uv_indices[1], mtface->uv[1]);
1196                 uvs.getUV(uv_set_index, uv_indices[2], mtface->uv[2]);
1197
1198                 if (quad) uvs.getUV(uv_set_index, uv_indices[3], mtface->uv[3]);
1199
1200 #ifdef COLLADA_DEBUG
1201                 /*if (quad) {
1202                         fprintf(stderr, "face uv:\n"
1203                                         "((%d, %d), (%d, %d), (%d, %d), (%d, %d))\n"
1204                                         "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1205
1206                                         uv_indices[0][0], uv_indices[0][1],
1207                                         uv_indices[1][0], uv_indices[1][1],
1208                                         uv_indices[2][0], uv_indices[2][1],
1209                                         uv_indices[3][0], uv_indices[3][1],
1210
1211                                         mtface->uv[0][0], mtface->uv[0][1],
1212                                         mtface->uv[1][0], mtface->uv[1][1],
1213                                         mtface->uv[2][0], mtface->uv[2][1],
1214                                         mtface->uv[3][0], mtface->uv[3][1]);
1215                 }
1216                 else {
1217                         fprintf(stderr, "face uv:\n"
1218                                         "((%d, %d), (%d, %d), (%d, %d))\n"
1219                                         "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1220
1221                                         uv_indices[0][0], uv_indices[0][1],
1222                                         uv_indices[1][0], uv_indices[1][1],
1223                                         uv_indices[2][0], uv_indices[2][1],
1224
1225                                         mtface->uv[0][0], mtface->uv[0][1],
1226                                         mtface->uv[1][0], mtface->uv[1][1],
1227                                         mtface->uv[2][0], mtface->uv[2][1]);
1228                 }*/
1229 #endif
1230         }
1231
1232 #ifdef COLLADA_DEBUG
1233         void print_index_list(COLLADAFW::IndexList& index_list)
1234         {
1235                 fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
1236                 for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
1237                         fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
1238                 }
1239                 fprintf(stderr, "\n");
1240         }
1241 #endif
1242
1243         bool is_nice_mesh(COLLADAFW::Mesh *mesh)
1244         {
1245                 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1246                 int i;
1247
1248                 const char *name = get_dae_name(mesh);
1249                 
1250                 for (i = 0; i < prim_arr.getCount(); i++) {
1251                         
1252                         COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1253                         COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
1254
1255                         const char *type_str = primTypeToStr(type);
1256                         
1257                         // OpenCollada passes POLYGONS type for <polylist>
1258                         if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1259
1260                                 COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
1261                                 COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
1262                                 
1263                                 for(int j = 0; j < vca.getCount(); j++){
1264                                         int count = vca[j];
1265                                         if (count < 3) {
1266                                                 fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
1267                                                                 type_str, name);
1268                                                 return false;
1269                                         }
1270                                 }
1271                                         
1272                         }
1273                         else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
1274                                 fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
1275                                 return false;
1276                         }
1277                 }
1278                 
1279                 if (mesh->getPositions().empty()) {
1280                         fprintf(stderr, "Mesh %s has no vertices.\n", name);
1281                         return false;
1282                 }
1283
1284                 return true;
1285         }
1286
1287         void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
1288         {
1289                 // vertices     
1290                 me->totvert = mesh->getPositions().getFloatValues()->getCount() / 3;
1291                 me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
1292
1293                 const COLLADAFW::MeshVertexData& pos = mesh->getPositions();
1294                 MVert *mvert;
1295                 int i, j;
1296
1297                 for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
1298                         j = i * 3;
1299
1300                         if (pos.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) {
1301                                 const float *array = pos.getFloatValues()->getData();
1302                                 mvert->co[0] = array[j];
1303                                 mvert->co[1] = array[j + 1];
1304                                 mvert->co[2] = array[j + 2];
1305                         }
1306                         else if (pos.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE){
1307                                 const double *array = pos.getDoubleValues()->getData();
1308                                 mvert->co[0] = (float)array[j];
1309                                 mvert->co[1] = (float)array[j + 1];
1310                                 mvert->co[2] = (float)array[j + 2];
1311                         }
1312                         else {
1313                                 fprintf(stderr, "Cannot read vertex positions: unknown data type.\n");
1314                                 break;
1315                         }
1316                 }
1317         }
1318         
1319         int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
1320         {
1321                 ListBase dispbase;
1322                 DispList *dl;
1323                 float *vert;
1324                 int i = 0;
1325                 
1326                 dispbase.first = dispbase.last = NULL;
1327                 
1328                 dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp");
1329                 dl->nr = totvert;
1330                 dl->type = DL_POLY;
1331                 dl->parts = 1;
1332                 dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
1333                 dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
1334
1335                 BLI_addtail(&dispbase, dl);
1336                 
1337                 for (i = 0; i < totvert; i++) {
1338                         copy_v3_v3(vert, verts[indices[i]].co);
1339                         vert += 3;
1340                 }
1341                 
1342                 filldisplist(&dispbase, &dispbase);
1343
1344                 int tottri = 0;
1345                 dl= (DispList*)dispbase.first;
1346
1347                 if (dl->type == DL_INDEX3) {
1348                         tottri = dl->parts;
1349
1350                         int *index = dl->index;
1351                         for (i= 0; i < tottri; i++) {
1352                                 int t[3]= {*index, *(index + 1), *(index + 2)};
1353
1354                                 std::sort(t, t + 3);
1355
1356                                 tri.push_back(t[0]);
1357                                 tri.push_back(t[1]);
1358                                 tri.push_back(t[2]);
1359
1360                                 index += 3;
1361                         }
1362                 }
1363
1364                 freedisplist(&dispbase);
1365
1366                 return tottri;
1367         }
1368         
1369         int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
1370         {
1371                 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1372                 int i, j;
1373                 int tottri = 0;
1374                 
1375                 for (i = 0; i < prim_arr.getCount(); i++) {
1376                         
1377                         COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1378                         int type = mp->getPrimitiveType();
1379                         size_t prim_totface = mp->getFaceCount();
1380                         unsigned int *indices = mp->getPositionIndices().getData();
1381                         
1382                         if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
1383                                 type == COLLADAFW::MeshPrimitive::POLYGONS) {
1384                                 
1385                                 COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
1386                                 COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1387                                 
1388                                 for (j = 0; j < prim_totface; j++) {
1389                                         int vcount = vcounta[j];
1390                                         
1391                                         if (vcount > 4) {
1392                                                 std::vector<unsigned int> tri;
1393                                                 
1394                                                 // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
1395                                                 tottri += triangulate_poly(indices, vcount, me->mvert, tri);
1396                                         }
1397
1398                                         indices += vcount;
1399                                 }
1400                         }
1401                 }
1402                 return tottri;
1403         }
1404         
1405         // TODO: import uv set names
1406         void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
1407         {
1408                 int i;
1409                 
1410                 // allocate faces
1411                 me->totface = mesh->getFacesCount() + new_tris;
1412                 me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
1413                 
1414                 // allocate UV layers
1415                 int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
1416
1417                 for (i = 0; i < totuvset; i++) {
1418                         CustomData_add_layer(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface);
1419                         //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
1420                 }
1421
1422                 // activate the first uv layer
1423                 if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
1424
1425                 UVDataWrapper uvs(mesh->getUVCoords());
1426
1427 #ifdef COLLADA_DEBUG
1428                 // uvs.print();
1429 #endif
1430
1431                 MFace *mface = me->mface;
1432
1433                 MaterialIdPrimitiveArrayMap mat_prim_map;
1434
1435                 int face_index = 0;
1436
1437                 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1438
1439                 for (i = 0; i < prim_arr.getCount(); i++) {
1440                         
1441                         COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1442
1443                         // faces
1444                         size_t prim_totface = mp->getFaceCount();
1445                         unsigned int *indices = mp->getPositionIndices().getData();
1446                         int j, k;
1447                         int type = mp->getPrimitiveType();
1448                         int index = 0;
1449                         
1450                         // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
1451                         Primitive prim = {mface, 0};
1452                         COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
1453
1454 #ifdef COLLADA_DEBUG
1455                         /*
1456                         fprintf(stderr, "Primitive %d:\n", i);
1457                         for (int j = 0; j < totuvset; j++) {
1458                                 print_index_list(*index_list_array[j]);
1459                         }
1460                         */
1461 #endif
1462                         
1463                         if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
1464                                 for (j = 0; j < prim_totface; j++){
1465                                         
1466                                         set_face_indices(mface, indices, false);
1467                                         indices += 3;
1468
1469                                         for (k = 0; k < totuvset; k++) {
1470                                                 // get mtface by face index and uv set index
1471                                                 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1472                                                 set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
1473                                         }
1474
1475                                         test_index_face(mface, &me->fdata, face_index, 3);
1476                                         
1477                                         index += 3;
1478                                         mface++;
1479                                         face_index++;
1480                                         prim.totface++;
1481                                 }
1482                         }
1483                         else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1484                                 COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
1485                                 COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1486                                 
1487                                 for (j = 0; j < prim_totface; j++) {
1488                                         
1489                                         // face
1490                                         int vcount = vcounta[j];
1491                                         if (vcount == 3 || vcount == 4) {
1492                                                 
1493                                                 set_face_indices(mface, indices, vcount == 4);
1494                                                 
1495                                                 // set mtface for each uv set
1496                                                 // it is assumed that all primitives have equal number of UV sets
1497                                                 
1498                                                 for (k = 0; k < totuvset; k++) {
1499                                                         // get mtface by face index and uv set index
1500                                                         MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1501                                                         set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
1502                                                 }
1503
1504                                                 test_index_face(mface, &me->fdata, face_index, vcount);
1505                                                 
1506                                                 mface++;
1507                                                 face_index++;
1508                                                 prim.totface++;
1509                                                 
1510                                         }
1511                                         else {
1512                                                 std::vector<unsigned int> tri;
1513                                                 
1514                                                 triangulate_poly(indices, vcount, me->mvert, tri);
1515                                                 
1516                                                 for (k = 0; k < tri.size() / 3; k++) {
1517                                                         int v = k * 3;
1518                                                         unsigned int uv_indices[3] = {
1519                                                                 index + tri[v],
1520                                                                 index + tri[v + 1],
1521                                                                 index + tri[v + 2]
1522                                                         };
1523                                                         unsigned int tri_indices[3] = {
1524                                                                 indices[tri[v]],
1525                                                                 indices[tri[v + 1]],
1526                                                                 indices[tri[v + 2]]
1527                                                         };
1528
1529                                                         set_face_indices(mface, tri_indices, false);
1530                                                         
1531                                                         for (int l = 0; l < totuvset; l++) {
1532                                                                 // get mtface by face index and uv set index
1533                                                                 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
1534                                                                 set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
1535                                                         }
1536
1537                                                         test_index_face(mface, &me->fdata, face_index, 3);
1538                                                         
1539                                                         mface++;
1540                                                         face_index++;
1541                                                         prim.totface++;
1542                                                 }
1543                                         }
1544
1545                                         index += vcount;
1546                                         indices += vcount;
1547                                 }
1548                         }
1549                         
1550                         mat_prim_map[mp->getMaterialId()].push_back(prim);
1551                 }
1552
1553                 geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
1554         }
1555
1556 public:
1557
1558         MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {}
1559
1560         virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
1561         {
1562                 if (uid_object_map.find(geom_uid) != uid_object_map.end())
1563                         return uid_object_map[geom_uid];
1564                 return NULL;
1565         }
1566         
1567         MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
1568                                                                          Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
1569                                                                          MTex *color_texture)
1570         {
1571                 COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
1572                 char *uvname = CustomData_get_layer_name(&me->fdata, CD_MTFACE, ctexture.getSetIndex());
1573
1574                 if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
1575                         
1576                         fprintf(stderr, "Cannot find texture array by texture index.\n");
1577                         return color_texture;
1578                 }
1579                 
1580                 std::vector<MTex*> textures = texindex_texarray_map[texture_index];
1581                 
1582                 std::vector<MTex*>::iterator it;
1583                 
1584                 for (it = textures.begin(); it != textures.end(); it++) {
1585                         
1586                         MTex *texture = *it;
1587                         
1588                         if (texture) {
1589                                 strcpy(texture->uvname, uvname);
1590                                 if (texture->mapto == MAP_COL) color_texture = texture;
1591                         }
1592                 }
1593                 return color_texture;
1594         }
1595         
1596         MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1597                                                                         std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1598                                                                         Object *ob, const COLLADAFW::UniqueId *geom_uid, 
1599                                                                         MTex **color_texture, char *layername, MTFace *texture_face,
1600                                                                         std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index)
1601         {
1602                 Mesh *me = (Mesh*)ob->data;
1603                 const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1604                 
1605                 // do we know this material?
1606                 if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1607                         
1608                         fprintf(stderr, "Cannot find material by UID.\n");
1609                         return NULL;
1610                 }
1611                 
1612                 Material *ma = uid_material_map[ma_uid];
1613                 assign_material(ob, ma, ob->totcol + 1);
1614                 
1615                 COLLADAFW::TextureCoordinateBindingArray& tex_array = 
1616                         cmaterial.getTextureCoordinateBindingArray();
1617                 TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1618                 unsigned int i;
1619                 // loop through <bind_vertex_inputs>
1620                 for (i = 0; i < tex_array.getCount(); i++) {
1621                         
1622                         *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1623                                                                                                                 *color_texture);
1624                 }
1625                 
1626                 // set texture face
1627                 if (*color_texture &&
1628                         strlen((*color_texture)->uvname) &&
1629                         strcmp(layername, (*color_texture)->uvname) != 0) {
1630                         
1631                         texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1632                                                                                                                            (*color_texture)->uvname);
1633                         strcpy(layername, (*color_texture)->uvname);
1634                 }
1635                 
1636                 MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1637                 COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1638                 
1639                 // assign material indices to mesh faces
1640                 if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1641                         
1642                         std::vector<Primitive>& prims = mat_prim_map[mat_id];
1643                         
1644                         std::vector<Primitive>::iterator it;
1645                         
1646                         for (it = prims.begin(); it != prims.end(); it++) {
1647                                 Primitive& prim = *it;
1648                                 i = 0;
1649                                 while (i++ < prim.totface) {
1650                                         prim.mface->mat_nr = mat_index;
1651                                         prim.mface++;
1652                                         // bind texture images to faces
1653                                         if (texture_face && (*color_texture)) {
1654                                                 texture_face->mode = TF_TEX;
1655                                                 texture_face->tpage = (Image*)(*color_texture)->tex->ima;
1656                                                 texture_face++;
1657                                         }
1658                                 }
1659                         }
1660                 }
1661                 
1662                 return texture_face;
1663         }
1664         
1665         
1666         Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1667                                                            bool isController,
1668                                                            std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1669                                                            std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map)
1670         {
1671                 const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
1672                 
1673                 // check if node instanciates controller or geometry
1674                 if (isController) {
1675                         
1676                         geom_uid = armature_importer->get_geometry_uid(*geom_uid);
1677                         
1678                         if (!geom_uid) {
1679                                 fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
1680                                 return NULL;
1681                         }
1682                 }
1683                 else {
1684                         
1685                         if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
1686                                 // this could happen if a mesh was not created
1687                                 // (e.g. if it contains unsupported geometry)
1688                                 fprintf(stderr, "Couldn't find a mesh by UID.\n");
1689                                 return NULL;
1690                         }
1691                 }
1692                 if (!uid_mesh_map[*geom_uid]) return NULL;
1693                 
1694                 Object *ob = add_object(scene, OB_MESH);
1695
1696                 // store object pointer for ArmatureImporter
1697                 uid_object_map[*geom_uid] = ob;
1698                 
1699                 // name Object
1700                 const std::string& id = node->getOriginalId();
1701                 if (id.length())
1702                         rename_id(&ob->id, (char*)id.c_str());
1703                 
1704                 // replace ob->data freeing the old one
1705                 Mesh *old_mesh = (Mesh*)ob->data;
1706
1707                 set_mesh(ob, uid_mesh_map[*geom_uid]);
1708                 
1709                 if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh);
1710                 
1711                 char layername[100];
1712                 MTFace *texture_face = NULL;
1713                 MTex *color_texture = NULL;
1714                 
1715                 COLLADAFW::MaterialBindingArray& mat_array =
1716                         geom->getMaterialBindings();
1717                 
1718                 // loop through geom's materials
1719                 for (unsigned int i = 0; i < mat_array.getCount(); i++) {
1720                         
1721                         texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
1722                                                                                                    &color_texture, layername, texture_face,
1723                                                                                                    material_texture_mapping_map, i);
1724                 }
1725                         
1726                 return ob;
1727         }
1728
1729         // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
1730         bool write_geometry(const COLLADAFW::Geometry* geom) 
1731         {
1732                 // TODO: import also uvs, normals
1733                 // XXX what to do with normal indices?
1734                 // XXX num_normals may be != num verts, then what to do?
1735
1736                 // check geometry->getType() first
1737                 if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
1738                         // TODO: report warning
1739                         fprintf(stderr, "Mesh type %s is not supported\n", geomTypeToStr(geom->getType()));
1740                         return true;
1741                 }
1742                 
1743                 COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom;
1744                 
1745                 if (!is_nice_mesh(mesh)) {
1746                         fprintf(stderr, "Ignoring mesh %s\n", get_dae_name(mesh));
1747                         return true;
1748                 }
1749                 
1750                 const std::string& str_geom_id = mesh->getOriginalId();
1751                 Mesh *me = add_mesh((char*)str_geom_id.c_str());
1752
1753                 // store the Mesh pointer to link it later with an Object
1754                 this->uid_mesh_map[mesh->getUniqueId()] = me;
1755                 
1756                 int new_tris = 0;
1757                 
1758                 read_vertices(mesh, me);
1759
1760                 new_tris = count_new_tris(mesh, me);
1761                 
1762                 read_faces(mesh, me, new_tris);
1763
1764                 make_edges(me, 0);
1765                 
1766                 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
1767
1768                 return true;
1769         }
1770
1771 };
1772
1773 class AnimationImporter : private TransformReader, public AnimationImporterBase
1774 {
1775 private:
1776
1777         ArmatureImporter *armature_importer;
1778         Scene *scene;
1779
1780         std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > curve_map;
1781         std::map<COLLADAFW::UniqueId, TransformReader::Animation> uid_animated_map;
1782         // std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
1783         std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList*> animlist_map;
1784         std::vector<FCurve*> unused_curves;
1785         std::map<COLLADAFW::UniqueId, Object*> joint_objects;
1786         
1787         FCurve *create_fcurve(int array_index, const char *rna_path)
1788         {
1789                 FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
1790                 
1791                 fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
1792                 fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
1793                 fcu->array_index = array_index;
1794                 return fcu;
1795         }
1796         
1797         void create_bezt(FCurve *fcu, float frame, float output)
1798         {
1799                 BezTriple bez;
1800                 memset(&bez, 0, sizeof(BezTriple));
1801                 bez.vec[1][0] = frame;
1802                 bez.vec[1][1] = output;
1803                 bez.ipo = U.ipo_new; /* use default interpolation mode here... */
1804                 bez.f1 = bez.f2 = bez.f3 = SELECT;
1805                 bez.h1 = bez.h2 = HD_AUTO;
1806                 insert_bezt_fcurve(fcu, &bez, 0);
1807                 calchandles_fcurve(fcu);
1808         }
1809
1810         // create one or several fcurves depending on the number of parameters being animated
1811         void animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
1812         {
1813                 COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
1814                 COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
1815                 // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
1816                 // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
1817                 float fps = (float)FPS;
1818                 size_t dim = curve->getOutDimension();
1819                 int i;
1820
1821                 std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
1822
1823                 if (dim == 1) {
1824                         FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
1825
1826                         fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
1827                         // fcu->rna_path = BLI_strdupn(path, strlen(path));
1828                         fcu->array_index = 0;
1829                         //fcu->totvert = curve->getKeyCount();
1830                         
1831                         // create beztriple for each key
1832                         for (i = 0; i < curve->getKeyCount(); i++) {
1833                                 BezTriple bez;
1834                                 memset(&bez, 0, sizeof(BezTriple));
1835
1836                                 // intangent
1837                                 // bez.vec[0][0] = get_float_value(intan, i + i) * fps;
1838                                 // bez.vec[0][1] = get_float_value(intan, i + i + 1);
1839
1840                                 // input, output
1841                                 bez.vec[1][0] = get_float_value(input, i) * fps;
1842                                 bez.vec[1][1] = get_float_value(output, i);
1843
1844                                 // outtangent
1845                                 // bez.vec[2][0] = get_float_value(outtan, i + i) * fps;
1846                                 // bez.vec[2][1] = get_float_value(outtan, i + i + 1);
1847                                 
1848                                 bez.ipo = U.ipo_new; /* use default interpolation mode here... */
1849                                 bez.f1 = bez.f2 = bez.f3 = SELECT;
1850                                 bez.h1 = bez.h2 = HD_AUTO;
1851                                 insert_bezt_fcurve(fcu, &bez, 0);
1852                         }
1853
1854                         calchandles_fcurve(fcu);
1855
1856                         fcurves.push_back(fcu);
1857                 }
1858                 else if(dim == 3) {
1859                         for (i = 0; i < dim; i++ ) {
1860                                 FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
1861                                 
1862                                 fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
1863                                 // fcu->rna_path = BLI_strdupn(path, strlen(path));
1864                                 fcu->array_index = 0;
1865                                 //fcu->totvert = curve->getKeyCount();
1866                                 
1867                                 // create beztriple for each key
1868                                 for (int j = 0; j < curve->getKeyCount(); j++) {
1869                                         BezTriple bez;
1870                                         memset(&bez, 0, sizeof(BezTriple));
1871
1872                                         // intangent
1873                                         // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
1874                                         // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
1875
1876                                         // input, output
1877                                         bez.vec[1][0] = get_float_value(input, j) * fps; 
1878                                         bez.vec[1][1] = get_float_value(output, j * 3 + i);
1879
1880                                         // outtangent
1881                                         // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
1882                                         // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
1883
1884                                         bez.ipo = U.ipo_new; /* use default interpolation mode here... */
1885                                         bez.f1 = bez.f2 = bez.f3 = SELECT;
1886                                         bez.h1 = bez.h2 = HD_AUTO;
1887                                         insert_bezt_fcurve(fcu, &bez, 0);
1888                                 }
1889
1890                                 calchandles_fcurve(fcu);
1891
1892                                 fcurves.push_back(fcu);
1893                         }
1894                 }
1895
1896                 for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
1897                         unused_curves.push_back(*it);
1898         }
1899
1900         void fcurve_deg_to_rad(FCurve *cu)
1901         {
1902                 for (int i = 0; i < cu->totvert; i++) {
1903                         // TODO convert handles too
1904                         cu->bezt[i].vec[1][1] *= M_PI / 180.0f;
1905                 }
1906         }
1907
1908 #if 0
1909         void make_fcurves_from_animation(COLLADAFW::AnimationCurve *curve,
1910                                                                          COLLADAFW::FloatOrDoubleArray& input,
1911                                                                          COLLADAFW::FloatOrDoubleArray& output,
1912                                                                          COLLADAFW::FloatOrDoubleArray& intan,
1913                                                                          COLLADAFW::FloatOrDoubleArray& outtan, size_t dim, float fps)
1914         {
1915                 int i;
1916                 // char *path = "location";
1917                 std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
1918
1919                 if (dim == 1) {
1920                         // create fcurve
1921                         FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
1922
1923                         fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
1924                         // fcu->rna_path = BLI_strdupn(path, strlen(path));
1925                         fcu->array_index = 0;
1926                         //fcu->totvert = curve->getKeyCount();
1927                         
1928                         // create beztriple for each key
1929                         for (i = 0; i < curve->getKeyCount(); i++) {
1930                                 BezTriple bez;
1931                                 memset(&bez, 0, sizeof(BezTriple));
1932                                 // intangent
1933                                 bez.vec[0][0] = get_float_value(intan, i + i) * fps;
1934                                 bez.vec[0][1] = get_float_value(intan, i + i + 1);
1935                                 // input, output
1936                                 bez.vec[1][0] = get_float_value(input, i) * fps;
1937                                 bez.vec[1][1] = get_float_value(output, i);
1938                                 // outtangent
1939                                 bez.vec[2][0] = get_float_value(outtan, i + i) * fps;
1940                                 bez.vec[2][1] = get_float_value(outtan, i + i + 1);
1941                                 
1942                                 bez.ipo = U.ipo_new; /* use default interpolation mode here... */
1943                                 bez.f1 = bez.f2 = bez.f3 = SELECT;
1944                                 bez.h1 = bez.h2 = HD_AUTO;
1945                                 insert_bezt_fcurve(fcu, &bez, 0);
1946                                 calchandles_fcurve(fcu);
1947                         }
1948
1949                         fcurves.push_back(fcu);
1950                 }
1951                 else if(dim == 3) {
1952                         for (i = 0; i < dim; i++ ) {
1953                                 // create fcurve
1954                                 FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
1955                                 
1956                                 fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
1957                                 // fcu->rna_path = BLI_strdupn(path, strlen(path));
1958                                 fcu->array_index = 0;
1959                                 //fcu->totvert = curve->getKeyCount();
1960                                 
1961                                 // create beztriple for each key
1962                                 for (int j = 0; j < curve->getKeyCount(); j++) {
1963                                         BezTriple bez;
1964                                         memset(&bez, 0, sizeof(BezTriple));
1965                                         // intangent
1966                                         bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
1967                                         bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
1968                                         // input, output
1969                                         bez.vec[1][0] = get_float_value(input, j) * fps; 
1970                                         bez.vec[1][1] = get_float_value(output, j * 3 + i);
1971                                         // outtangent
1972                                         bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
1973                                         bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
1974
1975                                         bez.ipo = U.ipo_new; /* use default interpolation mode here... */
1976                                         bez.f1 = bez.f2 = bez.f3 = SELECT;
1977                                         bez.h1 = bez.h2 = HD_AUTO;
1978                                         insert_bezt_fcurve(fcu, &bez, 0);
1979                                         calchandles_fcurve(fcu);
1980                                 }
1981
1982                                 fcurves.push_back(fcu);
1983                         }
1984                 }
1985         }
1986 #endif
1987         
1988         void add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
1989         {
1990                 bAction *act;
1991                 
1992                 if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
1993                 else act = ob->adt->action;
1994                 
1995                 std::vector<FCurve*>::iterator it;
1996                 int i;
1997
1998 #if 0
1999                 char *p = strstr(rna_path, "rotation_euler");
2000                 bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
2001
2002                 // convert degrees to radians for rotation
2003                 if (is_rotation)
2004                         fcurve_deg_to_rad(fcu);
2005 #endif
2006                 
2007                 for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
2008                         FCurve *fcu = *it;
2009                         fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
2010                         
2011                         if (array_index == -1) fcu->array_index = i;
2012                         else fcu->array_index = array_index;
2013                 
2014                         if (ob->type == OB_ARMATURE) {
2015                                 bActionGroup *grp = NULL;
2016                                 const char *bone_name = get_joint_name(animated->node);
2017                                 
2018                                 if (bone_name) {
2019                                         /* try to find group */
2020                                         grp = action_groups_find_named(act, bone_name);
2021                                         
2022                                         /* no matching groups, so add one */
2023                                         if (grp == NULL) {
2024                                                 /* Add a new group, and make it active */
2025                                                 grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
2026                                                 
2027                                                 grp->flag = AGRP_SELECTED;
2028                                                 BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
2029                                                 
2030                                                 BLI_addtail(&act->groups, grp);
2031                                                 BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
2032                                         }
2033                                         
2034                                         /* add F-Curve to group */
2035                                         action_groups_add_channel(act, grp, fcu);
2036                                         
2037                                 }
2038 #if 0
2039                                 if (is_rotation) {
2040                                         fcurves_actionGroup_map[grp].push_back(fcu);
2041                                 }
2042 #endif
2043                         }
2044                         else {
2045                                 BLI_addtail(&act->curves, fcu);
2046                         }
2047
2048                         // curve is used, so remove it from unused_curves
2049                         unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
2050                 }
2051         }
2052 public:
2053
2054         AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) :
2055                 TransformReader(conv), armature_importer(arm), scene(scene) { }
2056
2057         ~AnimationImporter()
2058         {
2059                 // free unused FCurves
2060                 for (std::vector<FCurve*>::iterator it = unused_curves.begin(); it != unused_curves.end(); it++)
2061                         free_fcurve(*it);
2062
2063                 if (unused_curves.size())
2064                         fprintf(stderr, "removed %u unused curves\n", unused_curves.size());
2065         }
2066
2067         bool write_animation(const COLLADAFW::Animation* anim) 
2068         {
2069                 if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
2070                         COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim;
2071                         
2072                         // XXX Don't know if it's necessary
2073                         // Should we check outPhysicalDimension?
2074                         if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
2075                                 fprintf(stderr, "Inputs physical dimension is not time. \n");
2076                                 return true;
2077                         }
2078
2079                         // a curve can have mixed interpolation type,
2080                         // in this case curve->getInterpolationTypes returns a list of interpolation types per key
2081                         COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType();
2082
2083                         if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
2084                                 switch (interp) {
2085                                 case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
2086                                 case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
2087                                         animation_to_fcurves(curve);
2088                                         break;
2089                                 default:
2090                                         // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types
2091                                         fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n");
2092                                         break;
2093                                 }
2094                         }
2095                         else {
2096                                 // not supported yet
2097                                 fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
2098                         }
2099                 }
2100                 else {
2101                         fprintf(stderr, "FORMULA animation type is not supported yet.\n");
2102                 }
2103                 
2104                 return true;
2105         }
2106         
2107         // called on post-process stage after writeVisualScenes
2108         bool write_animation_list(const COLLADAFW::AnimationList* animlist) 
2109         {
2110                 const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
2111
2112                 animlist_map[animlist_id] = animlist;
2113
2114 #if 0
2115                 // should not happen
2116                 if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
2117                         return true;
2118                 }
2119
2120                 // for bones rna_path is like: pose.bones["bone-name"].rotation
2121                 
2122                 // what does this AnimationList animate?
2123                 Animation& animated = uid_animated_map[animlist_id];
2124                 Object *ob = animated.ob;
2125
2126                 char rna_path[100];
2127                 char joint_path[100];
2128                 bool is_joint = false;
2129
2130                 // if ob is NULL, it should be a JOINT
2131                 if (!ob) {
2132                         ob = armature_importer->get_armature_for_joint(animated.node);
2133
2134                         if (!ob) {
2135                                 fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
2136                                 return true;
2137                         }
2138
2139                         armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path));
2140
2141                         is_joint = true;
2142                 }
2143                 
2144                 const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2145
2146                 switch (animated.tm->getTransformationType()) {
2147                 case COLLADAFW::Transformation::TRANSLATE:
2148                 case COLLADAFW::Transformation::SCALE:
2149                         {
2150                                 bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE;
2151                                 if (is_joint)
2152                                         BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
2153                                 else
2154                                         BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
2155
2156                                 for (int i = 0; i < bindings.getCount(); i++) {
2157                                         const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2158                                         COLLADAFW::UniqueId anim_uid = binding.animation;
2159
2160                                         if (curve_map.find(anim_uid) == curve_map.end()) {
2161                                                 fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2162                                                 continue;
2163                                         }
2164
2165                                         std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2166                                         
2167                                         switch (binding.animationClass) {
2168                                         case COLLADAFW::AnimationList::POSITION_X:
2169                                                 add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2170                                                 break;
2171                                         case COLLADAFW::AnimationList::POSITION_Y:
2172                                                 add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2173                                                 break;
2174                                         case COLLADAFW::AnimationList::POSITION_Z:
2175                                                 add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2176                                                 break;
2177                                         case COLLADAFW::AnimationList::POSITION_XYZ:
2178                                                 add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated);
2179                                                 break;
2180                                         default:
2181                                                 fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
2182                                                                 binding.animationClass, loc ? "TRANSLATE" : "SCALE");
2183                                         }
2184                                 }
2185                         }
2186                         break;
2187                 case COLLADAFW::Transformation::ROTATE:
2188                         {
2189                                 if (is_joint)
2190                                         BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
2191                                 else
2192                                         BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
2193
2194                                 COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm;
2195                                 COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
2196                                 
2197                                 for (int i = 0; i < bindings.getCount(); i++) {
2198                                         const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2199                                         COLLADAFW::UniqueId anim_uid = binding.animation;
2200
2201                                         if (curve_map.find(anim_uid) == curve_map.end()) {
2202                                                 fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2203                                                 continue;
2204                                         }
2205
2206                                         std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2207
2208                                         switch (binding.animationClass) {
2209                                         case COLLADAFW::AnimationList::ANGLE:
2210                                                 if (COLLADABU::Math::Vector3::UNIT_X == axis) {
2211                                                         add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2212                                                 }
2213                                                 else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
2214                                                         add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2215                                                 }
2216                                                 else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
2217                                                         add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2218                                                 }
2219                                                 break;
2220                                         case COLLADAFW::AnimationList::AXISANGLE:
2221                                                 // TODO convert axis-angle to quat? or XYZ?
2222                                         default:
2223                                                 fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
2224                                                                 binding.animationClass);
2225                                         }
2226                                 }
2227                         }
2228                         break;
2229                 case COLLADAFW::Transformation::MATRIX:
2230                 case COLLADAFW::Transformation::SKEW:
2231                 case COLLADAFW::Transformation::LOOKAT:
2232                         fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n");
2233                         break;
2234                 }
2235 #endif
2236                 
2237                 return true;
2238         }
2239
2240         void read_node_transform(COLLADAFW::Node *node, Object *ob)
2241         {
2242                 float mat[4][4];
2243                 TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
2244                 if (ob)
2245                         TransformReader::decompose(mat, ob->loc, ob->rot, NULL, ob->size);
2246         }
2247         
2248 #if 0
2249         virtual void change_eul_to_quat(Object *ob, bAction *act)
2250         {
2251                 bActionGroup *grp;
2252                 int i;
2253                 
2254                 for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) {
2255
2256                         FCurve *eulcu[3] = {NULL, NULL, NULL};
2257                         
2258                         if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
2259                                 continue;
2260
2261                         std::vector<FCurve*> &rot_fcurves = fcurves_actionGroup_map[grp];
2262                         
2263                         if (rot_fcurves.size() > 3) continue;
2264
2265                         for (i = 0; i < rot_fcurves.size(); i++)
2266                                 eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
2267
2268                         char joint_path[100];
2269                         char rna_path[100];
2270
2271                         BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name);
2272                         BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path);
2273
2274                         FCurve *quatcu[4] = {
2275                                 create_fcurve(0, rna_path),
2276                                 create_fcurve(1, rna_path),
2277                                 create_fcurve(2, rna_path),
2278                                 create_fcurve(3, rna_path)
2279                         };
2280
2281                         bPoseChannel *chan = get_pose_channel(ob->pose, grp->name);
2282
2283                         float m4[4][4], irest[3][3];
2284                         invert_m4_m4(m4, chan->bone->arm_mat);
2285                         copy_m3_m4(irest, m4);
2286
2287                         for (i = 0; i < 3; i++) {
2288
2289                                 FCurve *cu = eulcu[i];
2290
2291                                 if (!cu) continue;
2292
2293                                 for (int j = 0; j < cu->totvert; j++) {
2294                                         float frame = cu->bezt[j].vec[1][0];
2295
2296                                         float eul[3] = {
2297                                                 eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f,
2298                                                 eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f,
2299                                                 eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f
2300                                         };
2301
2302                                         // make eul relative to bone rest pose
2303                                         float rot[3][3], rel[3][3], quat[4];
2304
2305                                         /*eul_to_mat3(rot, eul);
2306
2307                                         mul_m3_m3m3(rel, irest, rot);
2308
2309                                         mat3_to_quat(quat, rel);
2310                                         */
2311
2312                                         eul_to_quat(quat, eul);
2313
2314                                         for (int k = 0; k < 4; k++)
2315                                                 create_bezt(quatcu[k], frame, quat[k]);
2316                                 }
2317                         }
2318
2319                         // now replace old Euler curves
2320
2321                         for (i = 0; i < 3; i++) {
2322                                 if (!eulcu[i]) continue;
2323
2324                                 action_groups_remove_channel(act, eulcu[i]);
2325                                 free_fcurve(eulcu[i]);
2326                         }
2327
2328                         chan->rotmode = ROT_MODE_QUAT;
2329
2330                         for (i = 0; i < 4; i++)
2331                                 action_groups_add_channel(act, grp, quatcu[i]);
2332                 }
2333
2334                 bPoseChannel *pchan;
2335                 for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
2336                         pchan->rotmode = ROT_MODE_QUAT;
2337                 }
2338         }
2339 #endif
2340
2341         // prerequisites:
2342         // animlist_map - map animlist id -> animlist
2343         // curve_map - map anim id -> curve(s)
2344 #ifdef ARMATURE_TEST
2345         Object *translate_animation(COLLADAFW::Node *node,
2346                                                                 std::map<COLLADAFW::UniqueId, Object*>& object_map,
2347                                                                 std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
2348                                                                 COLLADAFW::Transformation::TransformationType tm_type,
2349                                                                 Object *par_job = NULL)
2350 #else
2351         void translate_animation(COLLADAFW::Node *node,
2352                                                          std::map<COLLADAFW::UniqueId, Object*>& object_map,
2353                                                          std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
2354                                                          COLLADAFW::Transformation::TransformationType tm_type)
2355 #endif
2356         {
2357                 bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
2358                 bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
2359                 COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
2360                 Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
2361                 const char *bone_name = is_joint ? get_joint_name(node) : NULL;
2362
2363                 if (!ob) {
2364                         fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
2365 #ifdef ARMATURE_TEST
2366                         return NULL;
2367 #else
2368                         return;
2369 #endif
2370                 }
2371
2372                 // frames at which to sample
2373                 std::vector<float> frames;
2374
2375                 // for each <rotate>, <translate>, etc. there is a separate Transformation
2376                 const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2377
2378                 std::vector<FCurve*> old_curves;
2379
2380                 int i;
2381
2382                 // find frames at which to sample plus convert all keys to radians
2383                 for (i = 0; i < tms.getCount(); i++) {
2384                         COLLADAFW::Transformation *tm = tms[i];
2385                         COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2386
2387                         if (type == tm_type) {
2388                                 const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2389
2390                                 if (animlist_map.find(listid) != animlist_map.end()) {
2391                                         const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2392                                         const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2393
2394                                         if (bindings.getCount()) {
2395                                                 for (int j = 0; j < bindings.getCount(); j++) {
2396                                                         std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
2397                                                         bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
2398
2399                                                         if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3)) {
2400                                                                 std::vector<FCurve*>::iterator iter;
2401
2402                                                                 for (iter = curves.begin(); iter != curves.end(); iter++) {
2403                                                                         FCurve *fcu = *iter;
2404
2405                                                                         if (is_rotation)
2406                                                                                 fcurve_deg_to_rad(fcu);
2407
2408                                                                         for (int k = 0; k < fcu->totvert; k++) {
2409                                                                                 float fra = fcu->bezt[k].vec[1][0];
2410                                                                                 if (std::find(frames.begin(), frames.end(), fra) == frames.end())
2411                                                                                         frames.push_back(fra);
2412                                                                         }
2413                                                                 }
2414                                                         }
2415                                                         else {
2416                                                                 fprintf(stderr, "expected 1 or 3 curves, got %u\n", curves.size());
2417                                                         }
2418
2419                                                         for (std::vector<FCurve*>::iterator it = curves.begin(); it != curves.end(); it++)
2420                                                                 old_curves.push_back(*it);
2421                                                 }
2422                                         }
2423                                 }
2424                         }
2425                 }
2426
2427                 sort(frames.begin(), frames.end());
2428
2429                 float irest_dae[4][4];
2430                 float rest[4][4], irest[4][4];
2431
2432                 if (is_joint) {
2433                         if (is_joint)
2434                                 get_joint_rest_mat(irest_dae, root, node);
2435                         else
2436                                 evaluate_transform_at_frame(irest_dae, node, 0.0f);
2437                         invert_m4(irest_dae);
2438
2439                         Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
2440                         if (!bone) {
2441                                 fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
2442 #ifdef ARMATURE_TEST
2443                                 return NULL;
2444 #else
2445                                 return;
2446 #endif
2447                         }
2448
2449                         unit_m4(rest);
2450                         copy_m4_m4(rest, bone->arm_mat);
2451                         invert_m4_m4(irest, rest);
2452                 }
2453
2454                 char rna_path[200];
2455
2456 #ifdef ARMATURE_TEST
2457                 Object *job = get_joint_object(root, node, par_job);
2458                 FCurve *job_curves[4];
2459 #endif
2460
2461                 if (frames.size() == 0) {
2462 #ifdef ARMATURE_TEST
2463                         return job;
2464 #else
2465                         return;
2466 #endif
2467                 }
2468
2469                 const char *tm_str = NULL;
2470                 switch (tm_type) {
2471                 case COLLADAFW::Transformation::ROTATE:
2472                         tm_str = "rotation_quaternion";
2473                         break;
2474                 case COLLADAFW::Transformation::SCALE:
2475                         tm_str = "scale";
2476                         break;
2477                 case COLLADAFW::Transformation::TRANSLATE:
2478                         tm_str = "location";
2479                         break;
2480                 default:
2481 #ifdef ARMATURE_TEST
2482                         return job;
2483 #else
2484                         return;
2485 #endif
2486                 }
2487
2488                 if (is_joint) {
2489                         char joint_path[200];
2490                         armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
2491                         BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
2492                 }
2493                 else {
2494                         strcpy(rna_path, tm_str);
2495                 }
2496
2497                 // new curves
2498                 FCurve *newcu[4];
2499                 int totcu = is_rotation ? 4 : 3;
2500
2501                 for (i = 0; i < totcu; i++) {
2502                         newcu[i] = create_fcurve(i, rna_path);
2503 #ifdef ARMATURE_TEST
2504                         job_curves[i] = create_fcurve(i, tm_str);
2505 #endif
2506                 }
2507
2508                 std::vector<float>::iterator it;
2509
2510                 // sample values at each frame
2511                 for (it = frames.begin(); it != frames.end(); it++) {
2512                         float fra = *it;
2513
2514                         float mat[4][4];
2515
2516                         unit_m4(mat);
2517
2518                         // calc object-space mat
2519                         evaluate_transform_at_frame(mat, node, fra);
2520
2521                         // for joints, we need a special matrix
2522                         if (is_joint) {
2523                                 // special matrix: iR * M * iR_dae * R
2524                                 // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
2525                                 // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
2526                                 float temp[4][4], par[4][4];
2527
2528                                 // calc M
2529                                 calc_joint_parent_mat_rest(par, NULL, root, node);
2530                                 mul_m4_m4m4(temp, mat, par);
2531
2532                                 // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
2533
2534                                 // calc special matrix
2535                                 mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
2536                         }
2537
2538                         float val[4];
2539
2540                         switch (tm_type) {
2541                         case COLLADAFW::Transformation::ROTATE:
2542                                 mat4_to_quat(val, mat);
2543                                 break;
2544                         case COLLADAFW::Transformation::SCALE:
2545                                 mat4_to_size(val, mat);
2546                                 break;
2547                         case COLLADAFW::Transformation::TRANSLATE:
2548                                 copy_v3_v3(val, mat[3]);
2549                                 break;
2550                         default:
2551                                 break;
2552                         }
2553
2554                         // add 4 or 3 keys
2555                         for (i = 0; i < totcu; i++) {
2556                                 add_bezt(newcu[i], fra, val[i]);
2557                         }
2558
2559 #ifdef ARMATURE_TEST
2560                         if (is_joint) {
2561                                 evaluate_transform_at_frame(mat, node, fra);
2562
2563                                 switch (tm_type) {
2564                                 case COLLADAFW::Transformation::ROTATE:
2565                                         mat4_to_quat(val, mat);
2566                                         break;
2567                                 case COLLADAFW::Transformation::SCALE:
2568                                         mat4_to_size(val, mat);
2569                                         break;
2570                                 case COLLADAFW::Transformation::TRANSLATE:
2571                                         copy_v3_v3(val, mat[3]);
2572                                         break;
2573                                 default:
2574                                         break;
2575                                 }
2576
2577                                 for (i = 0; i < totcu; i++)
2578                                         add_bezt(job_curves[i], fra, val[i]);
2579                         }
2580 #endif
2581                 }
2582
2583                 verify_adt_action((ID*)&ob->id, 1);
2584
2585                 ListBase *curves = &ob->adt->action->curves;
2586                 // no longer needed
2587 #if 0
2588                 // remove old curves
2589                 for (std::vector<FCurve*>::iterator it = old_curves.begin(); it != old_curves.end(); it++) {
2590                         if (is_joint)
2591                                 action_groups_remove_channel(ob->adt->action, *it);
2592                         else
2593                                 BLI_remlink(curves, *it);
2594
2595                         // std::remove(unused_curves.begin(), unused_curves.end(), *it);
2596                         // free_fcurve(*it);
2597                 }
2598 #endif
2599
2600                 // add curves
2601                 for (i = 0; i < totcu; i++) {
2602                         if (is_joint)
2603                                 add_bone_fcurve(ob, node, newcu[i]);
2604                         else
2605                                 BLI_addtail(curves, newcu[i]);
2606
2607 #ifdef ARMATURE_TEST
2608                         if (is_joint)
2609                                 BLI_addtail(&job->adt->action->curves, job_curves[i]);
2610 #endif
2611                 }
2612
2613                 if (is_rotation) {
2614                         if (is_joint) {
2615                                 bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
2616                                 chan->rotmode = ROT_MODE_QUAT;
2617                         }
2618                         else {
2619                                 ob->rotmode = ROT_MODE_QUAT;
2620                         }
2621                 }
2622
2623 #ifdef ARMATURE_TEST
2624                 return job;
2625 #endif
2626         }
2627
2628         // internal, better make it private
2629         // warning: evaluates only rotation
2630         // prerequisites: animlist_map, curve_map
2631         void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
2632         {
2633                 const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2634
2635                 unit_m4(mat);
2636
2637                 for (int i = 0; i < tms.getCount(); i++) {
2638                         COLLADAFW::Transformation *tm = tms[i];
2639                         COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2640                         float m[4][4];
2641
2642                         unit_m4(m);
2643
2644                         if (!evaluate_animation(tm, m, fra)) {
2645                                 switch (type) {
2646                                 case COLLADAFW::Transformation::ROTATE:
2647                                         dae_rotate_to_mat4(tm, m);
2648                                         break;
2649                                 case COLLADAFW::Transformation::TRANSLATE:
2650                                         dae_translate_to_mat4(tm, m);
2651                                         break;
2652                                 case COLLADAFW::Transformation::SCALE:
2653                                         dae_scale_to_mat4(tm, m);
2654                                         break;
2655                                 case COLLADAFW::Transformation::MATRIX:
2656                                         dae_matrix_to_mat4(tm, m);
2657                                         break;
2658                                 default:
2659                                         fprintf(stderr, "unsupported transformation type %d\n", type);
2660                                 }
2661                         }
2662
2663                         float temp[4][4];
2664                         copy_m4_m4(temp, mat);
2665
2666                         mul_m4_m4m4(mat, m, temp);
2667                 }
2668         }
2669
2670         bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra)
2671         {
2672                 const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2673
2674                 if (animlist_map.find(listid) != animlist_map.end()) {
2675                         const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2676                         const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2677
2678                         if (bindings.getCount()) {
2679                                 for (int j = 0; j < bindings.getCount(); j++) {
2680                                         std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
2681                                         COLLADAFW::AnimationList::AnimationClass animclass = bindings[j].animationClass;
2682                                         COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2683                                         bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
2684
2685                                         if (type == COLLADAFW::Transformation::ROTATE) {
2686                                                 if (curves.size() != 1) {
2687                                                         fprintf(stderr, "expected 1 curve, got %u\n", curves.size());
2688                                                 }
2689                                                 else {
2690                                                         if (animclass == COLLADAFW::AnimationList::ANGLE) {
2691                                                                 COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
2692                                                                 float ax[3] = {axis[0], axis[1], axis[2]};
2693                                                                 float angle = evaluate_fcurve(curves[0], fra);
2694                                                                 axis_angle_to_mat4(mat, ax, angle);
2695
2696                                                                 return true;
2697                                                         }
2698                                                         else {
2699                                                                 // TODO support other animclasses
2700                                                                 fprintf(stderr, "<rotate> animclass %d is not supported yet\n", bindings[j].animationClass);
2701                                                         }
2702                                                 }
2703                                         }
2704                                         else if (type == COLLADAFW::Transformation::SCALE || type == COLLADAFW::Transformation::TRANSLATE) {
2705                                                 if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3)) {
2706                                                         bool animated = true;
2707                                                         bool scale = (type == COLLADAFW::Transformation::SCALE);
2708
2709                                                         float vec[3] = {0.0f, 0.0f, 0.0f};
2710                                                         if (scale)
2711                                                                 vec[0] = vec[1] = vec[2] = 1.0f;
2712
2713                                                         switch (animclass) {
2714                                                         case COLLADAFW::AnimationList::POSITION_X:
2715                                                                 vec[0] = evaluate_fcurve(curves[0], fra);
2716                                                                 break;
2717                                                         case COLLADAFW::AnimationList::POSITION_Y:
2718                                                                 vec[1] = evaluate_fcurve(curves[0], fra);
2719                                                                 break;
2720                                                         case COLLADAFW::AnimationList::POSITION_Z:
2721                                                                 vec[2] = evaluate_fcurve(curves[0], fra);
2722                                                                 break;
2723                                                         case COLLADAFW::AnimationList::POSITION_XYZ:
2724                                                                 vec[0] = evaluate_fcurve(curves[0], fra);
2725                                                                 vec[1] = evaluate_fcurve(curves[1], fra);
2726                                                                 vec[2] = evaluate_fcurve(curves[2], fra);
2727                                                                 break;
2728                                                         default:
2729                                                                 fprintf(stderr, "<%s> animclass %d is not supported yet\n", scale ? "scale" : "translate", animclass);
2730                                                                 animated = false;
2731                                                                 break;
2732                                                         }
2733
2734                                                         if (animated) {
2735                                                                 if (scale)