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