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