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