~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/collada/DocumentImporter.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: DocumentImporter.cpp 29658 2010-06-23 17:40:17Z dingto $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
21
19
 *
22
20
 * ***** END GPL LICENSE BLOCK *****
23
21
 */
 
22
 
 
23
/** \file blender/collada/DocumentImporter.cpp
 
24
 *  \ingroup collada
 
25
 */
 
26
 
24
27
// TODO:
25
28
// * name imported objects
26
29
// * import object rotation as euler
27
30
 
 
31
#include <string>
 
32
#include <map>
 
33
#include <algorithm> // sort()
 
34
 
28
35
#include "COLLADAFWRoot.h"
29
 
#include "COLLADAFWIWriter.h"
30
36
#include "COLLADAFWStableHeaders.h"
31
 
#include "COLLADAFWAnimationCurve.h"
32
 
#include "COLLADAFWAnimationList.h"
33
 
#include "COLLADAFWCamera.h"
34
37
#include "COLLADAFWColorOrTexture.h"
35
 
#include "COLLADAFWEffect.h"
36
 
#include "COLLADAFWFloatOrDoubleArray.h"
37
 
#include "COLLADAFWGeometry.h"
38
 
#include "COLLADAFWImage.h"
39
38
#include "COLLADAFWIndexList.h"
40
 
#include "COLLADAFWInstanceGeometry.h"
41
 
#include "COLLADAFWLight.h"
42
 
#include "COLLADAFWMaterial.h"
43
 
#include "COLLADAFWMesh.h"
44
39
#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
45
 
#include "COLLADAFWNode.h"
46
40
#include "COLLADAFWPolygons.h"
47
41
#include "COLLADAFWSampler.h"
48
 
#include "COLLADAFWSkinController.h"
49
 
#include "COLLADAFWSkinControllerData.h"
50
 
#include "COLLADAFWTransformation.h"
51
 
#include "COLLADAFWTranslate.h"
52
 
#include "COLLADAFWRotate.h"
53
 
#include "COLLADAFWScale.h"
54
 
#include "COLLADAFWMatrix.h"
55
42
#include "COLLADAFWTypes.h"
56
43
#include "COLLADAFWVisualScene.h"
57
 
#include "COLLADAFWFileInfo.h"
58
44
#include "COLLADAFWArrayPrimitiveType.h"
 
45
#include "COLLADAFWLibraryNodes.h"
 
46
#include "COLLADAFWCamera.h"
 
47
#include "COLLADAFWLight.h"
59
48
 
60
49
#include "COLLADASaxFWLLoader.h"
61
 
 
62
 
// TODO move "extern C" into header files
63
 
extern "C" 
64
 
{
65
 
#include "ED_keyframing.h"
66
 
#include "ED_armature.h"
67
 
#include "ED_mesh.h" // ED_vgroup_vert_add, ...
68
 
#include "ED_anim_api.h"
69
 
#include "ED_object.h"
70
 
 
71
 
#include "WM_types.h"
72
 
#include "WM_api.h"
73
 
 
 
50
#include "COLLADASaxFWLIExtraDataCallbackHandler.h"
 
51
 
 
52
#include "BLI_listbase.h"
 
53
#include "BLI_math.h"
 
54
#include "BLI_string.h"
 
55
#include "BLI_utildefines.h"
 
56
 
 
57
#include "BKE_camera.h"
74
58
#include "BKE_main.h"
75
 
#include "BKE_customdata.h"
 
59
#include "BKE_lamp.h"
76
60
#include "BKE_library.h"
77
61
#include "BKE_texture.h"
78
62
#include "BKE_fcurve.h"
79
63
#include "BKE_depsgraph.h"
80
64
#include "BLI_path_util.h"
81
 
#include "BKE_displist.h"
82
 
#include "BLI_math.h"
83
65
#include "BKE_scene.h"
84
 
}
85
 
#include "BKE_armature.h"
86
 
#include "BKE_mesh.h"
87
66
#include "BKE_global.h"
88
 
#include "BKE_context.h"
89
 
#include "BKE_object.h"
90
 
#include "BKE_image.h"
91
67
#include "BKE_material.h"
92
68
#include "BKE_utildefines.h"
93
 
#include "BKE_action.h"
94
 
 
95
 
#include "BLI_math.h"
96
 
#include "BLI_listbase.h"
97
 
#include "BLI_string.h"
98
 
 
 
69
#include "BKE_image.h"
 
70
 
 
71
#include "DNA_camera_types.h"
99
72
#include "DNA_lamp_types.h"
100
 
#include "DNA_armature_types.h"
101
 
#include "DNA_anim_types.h"
102
 
#include "DNA_curve_types.h"
103
 
#include "DNA_texture_types.h"
104
 
#include "DNA_camera_types.h"
105
 
#include "DNA_object_types.h"
106
 
#include "DNA_meshdata_types.h"
107
 
#include "DNA_mesh_types.h"
108
 
#include "DNA_material_types.h"
109
 
#include "DNA_scene_types.h"
110
 
#include "DNA_modifier_types.h"
 
73
 
 
74
#include "RNA_access.h"
111
75
 
112
76
#include "MEM_guardedalloc.h"
113
77
 
 
78
#include "ExtraHandler.h"
 
79
#include "ErrorHandler.h"
114
80
#include "DocumentImporter.h"
 
81
#include "TransformReader.h"
 
82
 
115
83
#include "collada_internal.h"
116
 
 
117
 
#include <string>
118
 
#include <map>
119
 
#include <algorithm> // sort()
120
 
 
121
 
#include <math.h>
122
 
#include <float.h>
 
84
#include "collada_utils.h"
 
85
 
 
86
 
 
87
/*
 
88
  COLLADA Importer limitations:
 
89
  - no multiple scene import, all objects are added to active scene
 
90
 */
123
91
 
124
92
// #define COLLADA_DEBUG
125
 
 
126
93
// creates empties for each imported bone on layer 2, for debugging
127
94
// #define ARMATURE_TEST
128
95
 
129
 
char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
130
 
 
131
 
static const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
132
 
{
133
 
        using namespace COLLADAFW;
134
 
        
135
 
        switch (type) {
136
 
        case MeshPrimitive::LINES:
137
 
                return "LINES";
138
 
        case MeshPrimitive::LINE_STRIPS:
139
 
                return "LINESTRIPS";
140
 
        case MeshPrimitive::POLYGONS:
141
 
                return "POLYGONS";
142
 
        case MeshPrimitive::POLYLIST:
143
 
                return "POLYLIST";
144
 
        case MeshPrimitive::TRIANGLES:
145
 
                return "TRIANGLES";
146
 
        case MeshPrimitive::TRIANGLE_FANS:
147
 
                return "TRIANGLE_FANS";
148
 
        case MeshPrimitive::TRIANGLE_STRIPS:
149
 
                return "TRIANGLE_FANS";
150
 
        case MeshPrimitive::POINTS:
151
 
                return "POINTS";
152
 
        case MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
153
 
                return "UNDEFINED_PRIMITIVE_TYPE";
154
 
        }
155
 
        return "UNKNOWN";
156
 
}
157
 
 
158
 
static const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
159
 
{
160
 
        switch (type) {
161
 
        case COLLADAFW::Geometry::GEO_TYPE_MESH:
162
 
                return "MESH";
163
 
        case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
164
 
                return "SPLINE";
165
 
        case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
166
 
                return "CONVEX_MESH";
167
 
        case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
168
 
        default:
169
 
                return "UNKNOWN";
170
 
        }
171
 
}
172
 
 
173
 
// works for COLLADAFW::Node, COLLADAFW::Geometry
174
 
template<class T>
175
 
static const char *get_dae_name(T *node)
176
 
{
177
 
        const std::string& name = node->getName();
178
 
        return name.size() ? name.c_str() : node->getOriginalId().c_str();
179
 
}
180
 
 
181
 
// use this for retrieving bone names, since these must be unique
182
 
template<class T>
183
 
static const char *get_joint_name(T *node)
184
 
{
185
 
        const std::string& id = node->getOriginalId();
186
 
        return id.size() ? id.c_str() : node->getName().c_str();
187
 
}
188
 
 
189
 
static float get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index)
190
 
{
191
 
        if (index >= array.getValuesCount())
192
 
                return 0.0f;
193
 
 
194
 
        if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT)
195
 
                return array.getFloatValues()->getData()[index];
196
 
        else 
197
 
                return array.getDoubleValues()->getData()[index];
198
 
}
199
 
 
200
 
// copied from /editors/object/object_relations.c
201
 
static int test_parent_loop(Object *par, Object *ob)
202
 
{
203
 
        /* test if 'ob' is a parent somewhere in par's parents */
204
 
        
205
 
        if(par == NULL) return 0;
206
 
        if(ob == par) return 1;
207
 
        
208
 
        return test_parent_loop(par->parent, ob);
209
 
}
210
 
 
211
 
// a shortened version of parent_set_exec()
212
 
// if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting
213
 
static int set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true)
214
 
{
215
 
        if (!par || test_parent_loop(par, ob))
216
 
                return false;
217
 
 
218
 
        Object workob;
219
 
        Scene *sce = CTX_data_scene(C);
220
 
 
221
 
        ob->parent = par;
222
 
        ob->partype = PAROBJECT;
223
 
 
224
 
        ob->parsubstr[0] = 0;
225
 
 
226
 
        if (is_parent_space) {
227
 
                // calc par->obmat
228
 
                where_is_object(sce, par);
229
 
 
230
 
                // move child obmat into world space
231
 
                float mat[4][4];
232
 
                mul_m4_m4m4(mat, ob->obmat, par->obmat);
233
 
                copy_m4_m4(ob->obmat, mat);
234
 
        }
235
 
        
236
 
        // apply child obmat (i.e. decompose it into rot/loc/size)
237
 
        object_apply_mat4(ob, ob->obmat);
238
 
 
239
 
        // compute parentinv
240
 
        what_does_parent(sce, ob, &workob);
241
 
        invert_m4_m4(ob->parentinv, workob.obmat);
242
 
 
243
 
        ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
244
 
        par->recalc |= OB_RECALC_OB;
245
 
 
246
 
        DAG_scene_sort(sce);
247
 
        DAG_ids_flush_update(0);
248
 
        WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
 
96
DocumentImporter::DocumentImporter(bContext *C, const char *filename) :
 
97
        mImportStage(General),
 
98
        mFilename(filename),
 
99
        mContext(C),
 
100
        armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
 
101
        mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
 
102
        anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
 
103
{}
 
104
 
 
105
DocumentImporter::~DocumentImporter()
 
106
{
 
107
        TagsMap::iterator etit;
 
108
        etit = uid_tags_map.begin();
 
109
        while(etit!=uid_tags_map.end()) {
 
110
                delete etit->second;
 
111
                etit++;
 
112
        }
 
113
}
 
114
 
 
115
bool DocumentImporter::import()
 
116
{
 
117
        ErrorHandler errorHandler;
 
118
        COLLADASaxFWL::Loader loader(&errorHandler);
 
119
        COLLADAFW::Root root(&loader, this);
 
120
        ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
 
121
        
 
122
        loader.registerExtraDataCallbackHandler(ehandler);
 
123
 
 
124
        // deselect all to select new objects
 
125
        scene_deselect_all(CTX_data_scene(mContext));
 
126
 
 
127
        if (!root.loadDocument(mFilename)) {
 
128
                fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
 
129
                return false;
 
130
        }
 
131
        
 
132
        if (errorHandler.hasError())
 
133
                return false;
 
134
        
 
135
        /** TODO set up scene graph and such here */
 
136
        
 
137
        mImportStage = Controller;
 
138
        
 
139
        COLLADASaxFWL::Loader loader2;
 
140
        COLLADAFW::Root root2(&loader2, this);
 
141
        
 
142
        if (!root2.loadDocument(mFilename)) {
 
143
                fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
 
144
                return false;
 
145
        }
 
146
        
 
147
        
 
148
        delete ehandler;
 
149
 
 
150
        mesh_importer.bmeshConversion();
249
151
 
250
152
        return true;
251
153
}
252
154
 
253
 
typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap;
254
 
 
255
 
class TransformReader : public TransformBase
256
 
{
257
 
protected:
258
 
 
259
 
        UnitConverter *unit_converter;
260
 
 
261
 
        struct Animation {
262
 
                Object *ob;
263
 
                COLLADAFW::Node *node;
264
 
                COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id
265
 
        };
266
 
 
267
 
public:
268
 
 
269
 
        TransformReader(UnitConverter* conv) : unit_converter(conv) {}
270
 
 
271
 
        void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map,
272
 
                                          Object *ob)
273
 
        {
274
 
                float cur[4][4];
275
 
                float copy[4][4];
276
 
 
277
 
                unit_m4(mat);
278
 
                
279
 
                for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {
280
 
 
281
 
                        COLLADAFW::Transformation *tm = node->getTransformations()[i];
282
 
                        COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
283
 
 
284
 
                        switch(type) {
285
 
                        case COLLADAFW::Transformation::TRANSLATE:
286
 
                                dae_translate_to_mat4(tm, cur);
287
 
                                break;
288
 
                        case COLLADAFW::Transformation::ROTATE:
289
 
                                dae_rotate_to_mat4(tm, cur);
290
 
                                break;
291
 
                        case COLLADAFW::Transformation::SCALE:
292
 
                                dae_scale_to_mat4(tm, cur);
293
 
                                break;
294
 
                        case COLLADAFW::Transformation::MATRIX:
295
 
                                dae_matrix_to_mat4(tm, cur);
296
 
                                break;
297
 
                        case COLLADAFW::Transformation::LOOKAT:
298
 
                        case COLLADAFW::Transformation::SKEW:
299
 
                                fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
300
 
                                break;
301
 
                        }
302
 
 
303
 
                        copy_m4_m4(copy, mat);
304
 
                        mul_m4_m4m4(mat, cur, copy);
305
 
 
306
 
                        if (animation_map) {
307
 
                                // AnimationList that drives this Transformation
308
 
                                const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList();
309
 
                        
310
 
                                // store this so later we can link animation data with ob
311
 
                                Animation anim = {ob, node, tm};
312
 
                                (*animation_map)[anim_list_id] = anim;
313
 
                        }
314
 
                }
315
 
        }
316
 
 
317
 
        void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
318
 
        {
319
 
                COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm;
320
 
                COLLADABU::Math::Vector3& axis = ro->getRotationAxis();
321
 
                float angle = (float)(ro->getRotationAngle() * M_PI / 180.0f);
322
 
                float ax[] = {axis[0], axis[1], axis[2]};
323
 
                // float quat[4];
324
 
                // axis_angle_to_quat(quat, axis, angle);
325
 
                // quat_to_mat4(m, quat);
326
 
                axis_angle_to_mat4(m, ax, angle);
327
 
        }
328
 
 
329
 
        void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
330
 
        {
331
 
                COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm;
332
 
                COLLADABU::Math::Vector3& t = tra->getTranslation();
333
 
 
334
 
                unit_m4(m);
335
 
 
336
 
                m[3][0] = (float)t[0];
337
 
                m[3][1] = (float)t[1];
338
 
                m[3][2] = (float)t[2];
339
 
        }
340
 
 
341
 
        void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
342
 
        {
343
 
                COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale();
344
 
                float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
345
 
                size_to_mat4(m, size);
346
 
        }
347
 
 
348
 
        void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
349
 
        {
350
 
                unit_converter->dae_matrix_to_mat4(m, ((COLLADAFW::Matrix*)tm)->getMatrix());
351
 
        }
352
 
 
353
 
        void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3])
354
 
        {
355
 
                dae_vector3_to_v3(((COLLADAFW::Translate*)tm)->getTranslation(), v);
356
 
        }
357
 
 
358
 
        void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3])
359
 
        {
360
 
                dae_vector3_to_v3(((COLLADAFW::Scale*)tm)->getScale(), v);
361
 
        }
362
 
 
363
 
        void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3])
364
 
        {
365
 
                v[0] = v3.x;
366
 
                v[1] = v3.y;
367
 
                v[2] = v3.z;
368
 
        }
369
 
};
370
 
 
371
 
// only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid
372
 
class MeshImporterBase
373
 
{
374
 
public:
375
 
        virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0;
376
 
};
377
 
 
378
 
// ditto as above
379
 
class AnimationImporterBase
380
 
{
381
 
public:
382
 
        // virtual void change_eul_to_quat(Object *ob, bAction *act) = 0;
383
 
};
384
 
 
385
 
class ArmatureImporter : private TransformReader
386
 
{
387
 
private:
388
 
        Scene *scene;
389
 
        UnitConverter *unit_converter;
390
 
 
391
 
        // std::map<int, JointData> joint_index_to_joint_info_map;
392
 
        // std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
393
 
 
394
 
        struct LeafBone {
395
 
                // COLLADAFW::Node *node;
396
 
                EditBone *bone;
397
 
                char name[32];
398
 
                float mat[4][4]; // bone matrix, derived from inv_bind_mat
399
 
        };
400
 
        std::vector<LeafBone> leaf_bones;
401
 
        // int bone_direction_row; // XXX not used
402
 
        float leaf_bone_length;
403
 
        int totbone;
404
 
        // XXX not used
405
 
        // float min_angle; // minimum angle between bone head-tail and a row of bone matrix
406
 
 
407
 
#if 0
408
 
        struct ArmatureJoints {
409
 
                Object *ob_arm;
410
 
                std::vector<COLLADAFW::Node*> root_joints;
411
 
        };
412
 
        std::vector<ArmatureJoints> armature_joints;
413
 
#endif
414
 
 
415
 
        Object *empty; // empty for leaf bones
416
 
 
417
 
        std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid;
418
 
        std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
419
 
        std::vector<COLLADAFW::Node*> root_joints;
420
 
        std::map<COLLADAFW::UniqueId, Object*> joint_parent_map;
421
 
 
422
 
        MeshImporterBase *mesh_importer;
423
 
        AnimationImporterBase *anim_importer;
424
 
 
425
 
        // This is used to store data passed in write_controller_data.
426
 
        // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members
427
 
        // so that arrays don't get freed until we free them explicitly.
428
 
        class SkinInfo
429
 
        {
430
 
        private:
431
 
                // to build armature bones from inverse bind matrices
432
 
                struct JointData {
433
 
                        float inv_bind_mat[4][4]; // joint inverse bind matrix
434
 
                        COLLADAFW::UniqueId joint_uid; // joint node UID
435
 
                        // Object *ob_arm;                        // armature object
436
 
                };
437
 
 
438
 
                float bind_shape_matrix[4][4];
439
 
 
440
 
                // data from COLLADAFW::SkinControllerData, each array should be freed
441
 
                COLLADAFW::UIntValuesArray joints_per_vertex;
442
 
                COLLADAFW::UIntValuesArray weight_indices;
443
 
                COLLADAFW::IntValuesArray joint_indices;
444
 
                // COLLADAFW::FloatOrDoubleArray weights;
445
 
                std::vector<float> weights;
446
 
 
447
 
                std::vector<JointData> joint_data; // index to this vector is joint index
448
 
 
449
 
                UnitConverter *unit_converter;
450
 
 
451
 
                Object *ob_arm;
452
 
                COLLADAFW::UniqueId controller_uid;
453
 
                Object *parent;
454
 
 
455
 
        public:
456
 
 
457
 
                SkinInfo() {}
458
 
 
459
 
                SkinInfo(const SkinInfo& skin) : weights(skin.weights),
460
 
                                                                                 joint_data(skin.joint_data),
461
 
                                                                                 unit_converter(skin.unit_converter),
462
 
                                                                                 ob_arm(skin.ob_arm),
463
 
                                                                                 controller_uid(skin.controller_uid),
464
 
                                                                                 parent(skin.parent)
465
 
                {
466
 
                        copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix);
467
 
 
468
 
                        transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex);
469
 
                        transfer_uint_array_data_const(skin.weight_indices, weight_indices);
470
 
                        transfer_int_array_data_const(skin.joint_indices, joint_indices);
471
 
                }
472
 
 
473
 
                SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {}
474
 
 
475
 
                // nobody owns the data after this, so it should be freed manually with releaseMemory
476
 
                template <class T>
477
 
                void transfer_array_data(T& src, T& dest)
478
 
                {
479
 
                        dest.setData(src.getData(), src.getCount());
480
 
                        src.yieldOwnerShip();
481
 
                        dest.yieldOwnerShip();
482
 
                }
483
 
 
484
 
                // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor
485
 
                void transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest)
486
 
                {
487
 
                        dest.setData((int*)src.getData(), src.getCount());
488
 
                        dest.yieldOwnerShip();
489
 
                }
490
 
 
491
 
                void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest)
492
 
                {
493
 
                        dest.setData((unsigned int*)src.getData(), src.getCount());
494
 
                        dest.yieldOwnerShip();
495
 
                }
496
 
 
497
 
                void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin)
498
 
                {
499
 
                        transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex);
500
 
                        transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices);
501
 
                        transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices);
502
 
                        // transfer_array_data(skin->getWeights(), weights);
503
 
 
504
 
                        // cannot transfer data for FloatOrDoubleArray, copy values manually
505
 
                        const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights();
506
 
                        for (unsigned int i = 0; i < weight.getValuesCount(); i++)
507
 
                                weights.push_back(get_float_value(weight, i));
508
 
 
509
 
                        unit_converter->dae_matrix_to_mat4(bind_shape_matrix, skin->getBindShapeMatrix());
510
 
                }
511
 
                        
512
 
                void free()
513
 
                {
514
 
                        joints_per_vertex.releaseMemory();
515
 
                        weight_indices.releaseMemory();
516
 
                        joint_indices.releaseMemory();
517
 
                        // weights.releaseMemory();
518
 
                }
519
 
 
520
 
                // using inverse bind matrices to construct armature
521
 
                // it is safe to invert them to get the original matrices
522
 
                // because if they are inverse matrices, they can be inverted
523
 
                void add_joint(const COLLADABU::Math::Matrix4& matrix)
524
 
                {
525
 
                        JointData jd;
526
 
                        unit_converter->dae_matrix_to_mat4(jd.inv_bind_mat, matrix);
527
 
                        joint_data.push_back(jd);
528
 
                }
529
 
 
530
 
                void set_controller(const COLLADAFW::SkinController* co)
531
 
                {
532
 
                        controller_uid = co->getUniqueId();
533
 
 
534
 
                        // fill in joint UIDs
535
 
                        const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints();
536
 
                        for (unsigned int i = 0; i < joint_uids.getCount(); i++) {
537
 
                                joint_data[i].joint_uid = joint_uids[i];
538
 
 
539
 
                                // // store armature pointer
540
 
                                // JointData& jd = joint_index_to_joint_info_map[i];
541
 
                                // jd.ob_arm = ob_arm;
542
 
 
543
 
                                // now we'll be able to get inv bind matrix from joint id
544
 
                                // joint_id_to_joint_index_map[joint_ids[i]] = i;
545
 
                        }
546
 
                }
547
 
 
548
 
                // called from write_controller
549
 
                Object *create_armature(Scene *scene)
550
 
                {
551
 
                        ob_arm = add_object(scene, OB_ARMATURE);
552
 
                        return ob_arm;
553
 
                }
554
 
 
555
 
                Object* set_armature(Object *ob_arm)
556
 
                {
557
 
                        if (this->ob_arm)
558
 
                                return this->ob_arm;
559
 
 
560
 
                        this->ob_arm = ob_arm;
561
 
                        return ob_arm;
562
 
                }
563
 
 
564
 
                bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node)
565
 
                {
566
 
                        const COLLADAFW::UniqueId& uid = node->getUniqueId();
567
 
                        std::vector<JointData>::iterator it;
568
 
                        for (it = joint_data.begin(); it != joint_data.end(); it++) {
569
 
                                if ((*it).joint_uid == uid) {
570
 
                                        copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat);
571
 
                                        return true;
572
 
                                }
573
 
                        }
574
 
 
575
 
                        return false;
576
 
                }
577
 
 
578
 
                Object *get_armature()
579
 
                {
580
 
                        return ob_arm;
581
 
                }
582
 
 
583
 
                const COLLADAFW::UniqueId& get_controller_uid()
584
 
                {
585
 
                        return controller_uid;
586
 
                }
587
 
 
588
 
                // check if this skin controller references a joint or any descendant of it
589
 
                // 
590
 
                // some nodes may not be referenced by SkinController,
591
 
                // in this case to determine if the node belongs to this armature,
592
 
                // we need to search down the tree
593
 
                bool uses_joint_or_descendant(COLLADAFW::Node *node)
594
 
                {
595
 
                        const COLLADAFW::UniqueId& uid = node->getUniqueId();
596
 
                        std::vector<JointData>::iterator it;
597
 
                        for (it = joint_data.begin(); it != joint_data.end(); it++) {
598
 
                                if ((*it).joint_uid == uid)
599
 
                                        return true;
600
 
                        }
601
 
 
602
 
                        COLLADAFW::NodePointerArray& children = node->getChildNodes();
603
 
                        for (unsigned int i = 0; i < children.getCount(); i++) {
604
 
                                if (uses_joint_or_descendant(children[i]))
605
 
                                        return true;
606
 
                        }
607
 
 
608
 
                        return false;
609
 
                }
610
 
 
611
 
                void link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
612
 
                                                   TransformReader *tm)
613
 
                {
614
 
                        Scene *scene = CTX_data_scene(C);
615
 
 
616
 
                        ModifierData *md = ED_object_modifier_add(NULL, scene, ob, NULL, eModifierType_Armature);
617
 
                        ((ArmatureModifierData *)md)->object = ob_arm;
618
 
 
619
 
                        copy_m4_m4(ob->obmat, bind_shape_matrix);
620
 
                        object_apply_mat4(ob, ob->obmat);
621
 
#if 1
622
 
                        ::set_parent(ob, ob_arm, C);
623
 
#else
624
 
                        Object workob;
625
 
                        ob->parent = ob_arm;
626
 
                        ob->partype = PAROBJECT;
627
 
 
628
 
                        what_does_parent(scene, ob, &workob);
629
 
                        invert_m4_m4(ob->parentinv, workob.obmat);
630
 
 
631
 
                        ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
632
 
 
633
 
                        DAG_scene_sort(scene);
634
 
                        DAG_ids_flush_update(0);
635
 
                        WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
636
 
#endif
637
 
 
638
 
                        ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP;
639
 
 
640
 
                        // create all vertex groups
641
 
                        std::vector<JointData>::iterator it;
642
 
                        int joint_index;
643
 
                        for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) {
644
 
                                const char *name = "Group";
645
 
 
646
 
                                // name group by joint node name
647
 
                                if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) {
648
 
                                        name = get_joint_name(joint_by_uid[(*it).joint_uid]);
649
 
                                }
650
 
 
651
 
                                ED_vgroup_add_name(ob, (char*)name);
652
 
                        }
653
 
 
654
 
                        // <vcount> - number of joints per vertex - joints_per_vertex
655
 
                        // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices
656
 
                        // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender?
657
 
 
658
 
                        // for each vertex in weight indices
659
 
                        //   for each bone index in vertex
660
 
                        //     add vertex to group at group index
661
 
                        //     treat group index -1 specially
662
 
 
663
 
                        // get def group by index with BLI_findlink
664
 
 
665
 
                        for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
666
 
 
667
 
                                unsigned int limit = weight + joints_per_vertex[vertex];
668
 
                                for ( ; weight < limit; weight++) {
669
 
                                        int joint = joint_indices[weight], joint_weight = weight_indices[weight];
670
 
 
671
 
                                        // -1 means "weight towards the bind shape", we just don't assign it to any group
672
 
                                        if (joint != -1) {
673
 
                                                bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint);
674
 
 
675
 
                                                ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE);
676
 
                                        }
677
 
                                }
678
 
                        }
679
 
                }
680
 
 
681
 
                bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node)
682
 
                {
683
 
                        return get_pose_channel(ob_arm->pose, get_joint_name(node));
684
 
                }
685
 
 
686
 
                void set_parent(Object *_parent)
687
 
                {
688
 
                        parent = _parent;
689
 
                }
690
 
 
691
 
                Object* get_parent()
692
 
                {
693
 
                        return parent;
694
 
                }
695
 
 
696
 
                void find_root_joints(const std::vector<COLLADAFW::Node*> &root_joints,
697
 
                                                          std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
698
 
                                                          std::vector<COLLADAFW::Node*>& result)
699
 
                {
700
 
                        std::vector<COLLADAFW::Node*>::const_iterator it;
701
 
                        for (it = root_joints.begin(); it != root_joints.end(); it++) {
702
 
                                COLLADAFW::Node *root = *it;
703
 
                                std::vector<JointData>::iterator ji;
704
 
                                for (ji = joint_data.begin(); ji != joint_data.end(); ji++) {
705
 
                                        COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid];
706
 
                                        if (find_node_in_tree(joint, root)) {
707
 
                                                if (std::find(result.begin(), result.end(), root) == result.end())
708
 
                                                        result.push_back(root);
709
 
                                        }
710
 
                                }
711
 
                        }
712
 
                }
713
 
 
714
 
                bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root)
715
 
                {
716
 
                        if (node == tree_root)
717
 
                                return true;
718
 
 
719
 
                        COLLADAFW::NodePointerArray& children = tree_root->getChildNodes();
720
 
                        for (unsigned int i = 0; i < children.getCount(); i++) {
721
 
                                if (find_node_in_tree(node, children[i]))
722
 
                                        return true;
723
 
                        }
724
 
 
725
 
                        return false;
726
 
                }
727
 
 
728
 
        };
729
 
 
730
 
        std::map<COLLADAFW::UniqueId, SkinInfo> skin_by_data_uid; // data UID = skin controller data UID
731
 
#if 0
732
 
        JointData *get_joint_data(COLLADAFW::Node *node)
733
 
        {
734
 
                const COLLADAFW::UniqueId& joint_id = node->getUniqueId();
735
 
 
736
 
                if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
737
 
                        fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
738
 
                                        node->getOriginalId().c_str());
739
 
                        return NULL;
740
 
                }
741
 
 
742
 
                int joint_index = joint_id_to_joint_index_map[joint_id];
743
 
 
744
 
                return &joint_index_to_joint_info_map[joint_index];
745
 
        }
746
 
#endif
747
 
 
748
 
        void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
749
 
                                         float parent_mat[][4], bArmature *arm)
750
 
        {
751
 
                float joint_inv_bind_mat[4][4];
752
 
 
753
 
                // JointData* jd = get_joint_data(node);
754
 
 
755
 
                float mat[4][4];
756
 
 
757
 
                if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
758
 
                        // get original world-space matrix
759
 
                        invert_m4_m4(mat, joint_inv_bind_mat);
760
 
                }
761
 
                // create a bone even if there's no joint data for it (i.e. it has no influence)
762
 
                else {
763
 
                        float obmat[4][4];
764
 
 
765
 
                        // object-space
766
 
                        get_node_mat(obmat, node, NULL, NULL);
767
 
 
768
 
                        // get world-space
769
 
                        if (parent)
770
 
                                mul_m4_m4m4(mat, obmat, parent_mat);
771
 
                        else
772
 
                                copy_m4_m4(mat, obmat);
773
 
                }
774
 
 
775
 
                // TODO rename from Node "name" attrs later
776
 
                EditBone *bone = ED_armature_edit_bone_add(arm, (char*)get_joint_name(node));
777
 
                totbone++;
778
 
 
779
 
                if (parent) bone->parent = parent;
780
 
 
781
 
                // set head
782
 
                copy_v3_v3(bone->head, mat[3]);
783
 
 
784
 
                // set tail, don't set it to head because 0-length bones are not allowed
785
 
                float vec[3] = {0.0f, 0.5f, 0.0f};
786
 
                add_v3_v3v3(bone->tail, bone->head, vec);
787
 
 
788
 
                // set parent tail
789
 
                if (parent && totchild == 1) {
790
 
                        copy_v3_v3(parent->tail, bone->head);
791
 
 
792
 
                        // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
793
 
                        // bone->flag |= BONE_CONNECTED;
794
 
 
795
 
                        // XXX increase this to prevent "very" small bones?
796
 
                        const float epsilon = 0.000001f;
797
 
 
798
 
                        // derive leaf bone length
799
 
                        float length = len_v3v3(parent->head, parent->tail);
800
 
                        if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
801
 
                                leaf_bone_length = length;
802
 
                        }
803
 
 
804
 
                        // treat zero-sized bone like a leaf bone
805
 
                        if (length <= epsilon) {
806
 
                                add_leaf_bone(parent_mat, parent);
807
 
                        }
808
 
 
809
 
                        /*
810
 
#if 0
811
 
                        // and which row in mat is bone direction
812
 
                        float vec[3];
813
 
                        sub_v3_v3v3(vec, parent->tail, parent->head);
814
 
#ifdef COLLADA_DEBUG
815
 
                        print_v3("tail - head", vec);
816
 
                        print_m4("matrix", parent_mat);
817
 
#endif
818
 
                        for (int i = 0; i < 3; i++) {
819
 
#ifdef COLLADA_DEBUG
820
 
                                char *axis_names[] = {"X", "Y", "Z"};
821
 
                                printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i]));
822
 
#endif
823
 
                                float angle = angle_v2v2(vec, parent_mat[i]);
824
 
                                if (angle < min_angle) {
825
 
#ifdef COLLADA_DEBUG
826
 
                                        print_v3("picking", parent_mat[i]);
827
 
                                        printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node));
828
 
#endif
829
 
                                        bone_direction_row = i;
830
 
                                        min_angle = angle;
831
 
                                }
832
 
                        }
833
 
#endif
834
 
                        */
835
 
                }
836
 
 
837
 
                COLLADAFW::NodePointerArray& children = node->getChildNodes();
838
 
                for (unsigned int i = 0; i < children.getCount(); i++) {
839
 
                        create_bone(skin, children[i], bone, children.getCount(), mat, arm);
840
 
                }
841
 
 
842
 
                // in second case it's not a leaf bone, but we handle it the same way
843
 
                if (!children.getCount() || children.getCount() > 1) {
844
 
                        add_leaf_bone(mat, bone);
845
 
                }
846
 
        }
847
 
 
848
 
        void add_leaf_bone(float mat[][4], EditBone *bone)
849
 
        {
850
 
                LeafBone leaf;
851
 
 
852
 
                leaf.bone = bone;
853
 
                copy_m4_m4(leaf.mat, mat);
854
 
                BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
855
 
 
856
 
                leaf_bones.push_back(leaf);
857
 
        }
858
 
 
859
 
        void fix_leaf_bones()
860
 
        {
861
 
                // just setting tail for leaf bones here
862
 
 
863
 
                std::vector<LeafBone>::iterator it;
864
 
                for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
865
 
                        LeafBone& leaf = *it;
866
 
 
867
 
                        // pointing up
868
 
                        float vec[3] = {0.0f, 0.0f, 1.0f};
869
 
 
870
 
                        mul_v3_fl(vec, leaf_bone_length);
871
 
 
872
 
                        copy_v3_v3(leaf.bone->tail, leaf.bone->head);
873
 
                        add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
874
 
                }
875
 
        }
876
 
 
877
 
        void set_leaf_bone_shapes(Object *ob_arm)
878
 
        {
879
 
                bPose *pose = ob_arm->pose;
880
 
 
881
 
                std::vector<LeafBone>::iterator it;
882
 
                for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
883
 
                        LeafBone& leaf = *it;
884
 
 
885
 
                        bPoseChannel *pchan = get_pose_channel(pose, leaf.name);
886
 
                        if (pchan) {
887
 
                                pchan->custom = get_empty_for_leaves();
888
 
                        }
889
 
                        else {
890
 
                                fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name);
891
 
                        }
892
 
                }
893
 
        }
894
 
 
895
 
#if 0
896
 
        void set_euler_rotmode()
897
 
        {
898
 
                // just set rotmode = ROT_MODE_EUL on pose channel for each joint
899
 
 
900
 
                std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>::iterator it;
901
 
 
902
 
                for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
903
 
 
904
 
                        COLLADAFW::Node *joint = it->second;
905
 
 
906
 
                        std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
907
 
                        
908
 
                        for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
909
 
                                SkinInfo& skin = sit->second;
910
 
 
911
 
                                if (skin.uses_joint_or_descendant(joint)) {
912
 
                                        bPoseChannel *pchan = skin.get_pose_channel_from_node(joint);
913
 
 
914
 
                                        if (pchan) {
915
 
                                                pchan->rotmode = ROT_MODE_EUL;
916
 
                                        }
917
 
                                        else {
918
 
                                                fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint));
919
 
                                        }
920
 
 
921
 
                                        break;
922
 
                                }
923
 
                        }
924
 
                }
925
 
        }
926
 
#endif
927
 
 
928
 
        Object *get_empty_for_leaves()
929
 
        {
930
 
                if (empty) return empty;
931
 
                
932
 
                empty = add_object(scene, OB_EMPTY);
933
 
                empty->empty_drawtype = OB_EMPTY_SPHERE;
934
 
 
935
 
                return empty;
936
 
        }
937
 
 
938
 
#if 0
939
 
        Object *find_armature(COLLADAFW::Node *node)
940
 
        {
941
 
                JointData* jd = get_joint_data(node);
942
 
                if (jd) return jd->ob_arm;
943
 
 
944
 
                COLLADAFW::NodePointerArray& children = node->getChildNodes();
945
 
                for (int i = 0; i < children.getCount(); i++) {
946
 
                        Object *ob_arm = find_armature(children[i]);
947
 
                        if (ob_arm) return ob_arm;
948
 
                }
949
 
 
950
 
                return NULL;
951
 
        }
952
 
 
953
 
        ArmatureJoints& get_armature_joints(Object *ob_arm)
954
 
        {
955
 
                // try finding it
956
 
                std::vector<ArmatureJoints>::iterator it;
957
 
                for (it = armature_joints.begin(); it != armature_joints.end(); it++) {
958
 
                        if ((*it).ob_arm == ob_arm) return *it;
959
 
                }
960
 
 
961
 
                // not found, create one
962
 
                ArmatureJoints aj;
963
 
                aj.ob_arm = ob_arm;
964
 
                armature_joints.push_back(aj);
965
 
 
966
 
                return armature_joints.back();
967
 
        }
968
 
#endif
969
 
 
970
 
        void create_armature_bones(SkinInfo& skin)
971
 
        {
972
 
                // just do like so:
973
 
                // - get armature
974
 
                // - enter editmode
975
 
                // - add edit bones and head/tail properties using matrices and parent-child info
976
 
                // - exit edit mode
977
 
                // - set a sphere shape to leaf bones
978
 
 
979
 
                Object *ob_arm = NULL;
980
 
 
981
 
                /*
982
 
                 * find if there's another skin sharing at least one bone with this skin
983
 
                 * if so, use that skin's armature
984
 
                 */
985
 
 
986
 
                /*
987
 
                  Pseudocode:
988
 
 
989
 
                  find_node_in_tree(node, root_joint)
990
 
 
991
 
                  skin::find_root_joints(root_joints):
992
 
                        std::vector root_joints;
993
 
                        for each root in root_joints:
994
 
                                for each joint in joints:
995
 
                                        if find_node_in_tree(joint, root):
996
 
                                                if (std::find(root_joints.begin(), root_joints.end(), root) == root_joints.end())
997
 
                                                        root_joints.push_back(root);
998
 
 
999
 
                  for (each skin B with armature) {
1000
 
                          find all root joints for skin B
1001
 
 
1002
 
                          for each joint X in skin A:
1003
 
                                for each root joint R in skin B:
1004
 
                                        if (find_node_in_tree(X, R)) {
1005
 
                                                shared = 1;
1006
 
                                                goto endloop;
1007
 
                                        }
1008
 
                  }
1009
 
 
1010
 
                  endloop:
1011
 
                */
1012
 
 
1013
 
                SkinInfo *a = &skin;
1014
 
                Object *shared = NULL;
1015
 
                std::vector<COLLADAFW::Node*> skin_root_joints;
1016
 
 
1017
 
                std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1018
 
                for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1019
 
                        SkinInfo *b = &it->second;
1020
 
                        if (b == a || b->get_armature() == NULL)
1021
 
                                continue;
1022
 
 
1023
 
                        skin_root_joints.clear();
1024
 
 
1025
 
                        b->find_root_joints(root_joints, joint_by_uid, skin_root_joints);
1026
 
 
1027
 
                        std::vector<COLLADAFW::Node*>::iterator ri;
1028
 
                        for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) {
1029
 
                                if (a->uses_joint_or_descendant(*ri)) {
1030
 
                                        shared = b->get_armature();
1031
 
                                        break;
1032
 
                                }
1033
 
                        }
1034
 
 
1035
 
                        if (shared != NULL)
1036
 
                                break;
1037
 
                }
1038
 
 
1039
 
                if (shared)
1040
 
                        ob_arm = skin.set_armature(shared);
 
155
void DocumentImporter::cancel(const COLLADAFW::String& errorMessage)
 
156
{
 
157
        // TODO: if possible show error info
 
158
        //
 
159
        // Should we get rid of invisible Meshes that were created so far
 
160
        // or maybe create objects at coordinate space origin?
 
161
        //
 
162
        // The latter sounds better.
 
163
}
 
164
 
 
165
void DocumentImporter::start()
 
166
{
 
167
}
 
168
 
 
169
void DocumentImporter::finish()
 
170
{
 
171
        if (mImportStage!=General)
 
172
                return;
 
173
                
 
174
        /** TODO Break up and put into 2-pass parsing of DAE */
 
175
        std::vector<const COLLADAFW::VisualScene*>::iterator it;
 
176
        for (it = vscenes.begin(); it != vscenes.end(); it++) {
 
177
                PointerRNA sceneptr, unit_settings;
 
178
                PropertyRNA *system, *scale;
 
179
                // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
 
180
                Scene *sce = CTX_data_scene(mContext);
 
181
                
 
182
                // for scene unit settings: system, scale_length
 
183
                RNA_id_pointer_create(&sce->id, &sceneptr);
 
184
                unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
 
185
                system = RNA_struct_find_property(&unit_settings, "system");
 
186
                scale = RNA_struct_find_property(&unit_settings, "scale_length");
 
187
                
 
188
                switch(unit_converter.isMetricSystem()) {
 
189
                        case UnitConverter::Metric:
 
190
                                RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
 
191
                                break;
 
192
                        case UnitConverter::Imperial:
 
193
                                RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
 
194
                                break;
 
195
                        default:
 
196
                                RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
 
197
                                break;
 
198
                }
 
199
                RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter());
 
200
                
 
201
                const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
 
202
 
 
203
                for (unsigned int i = 0; i < roots.getCount(); i++) {
 
204
                        write_node(roots[i], NULL, sce, NULL, false);
 
205
                }
 
206
        }
 
207
        armature_importer.set_tags_map(this->uid_tags_map);
 
208
        armature_importer.make_armatures(mContext);
 
209
 
 
210
#if 0
 
211
        armature_importer.fix_animation();
 
212
#endif
 
213
 
 
214
        for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
 
215
                const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
 
216
 
 
217
                for (unsigned int i = 0; i < roots.getCount(); i++)
 
218
                        translate_anim_recursive(roots[i],NULL,NULL);
 
219
        }
 
220
 
 
221
        if (libnode_ob.size()) {
 
222
                Scene *sce = CTX_data_scene(mContext);
 
223
 
 
224
                fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
 
225
                // free all library_nodes
 
226
                std::vector<Object*>::iterator it;
 
227
                for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
 
228
                        Object *ob = *it;
 
229
 
 
230
                        Base *base = object_in_scene(ob, sce);
 
231
                        if (base) {
 
232
                                BLI_remlink(&sce->base, base);
 
233
                                free_libblock_us(&G.main->object, base->object);
 
234
                                if (sce->basact==base)
 
235
                                        sce->basact= NULL;
 
236
                                MEM_freeN(base);
 
237
                        }
 
238
                }
 
239
                libnode_ob.clear();
 
240
 
 
241
                DAG_scene_sort(CTX_data_main(mContext), sce);
 
242
                DAG_ids_flush_update(CTX_data_main(mContext), 0);
 
243
        }
 
244
}
 
245
 
 
246
 
 
247
void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
 
248
{
 
249
 
 
250
        // The split in #29246, rootmap must point at actual root when
 
251
        // calculating bones in apply_curves_as_matrix.
 
252
        // This has to do with inverse bind poses being world space
 
253
        // (the sources for skinned bones' restposes) and the way
 
254
        // non-skinning nodes have their "restpose" recursively calculated.
 
255
        // XXX TODO: design issue, how to support unrelated joints taking
 
256
        // part in skinning.
 
257
        if (par) { // && par->getType() == COLLADAFW::Node::JOINT) {
 
258
                // par is root if there's no corresp. key in root_map
 
259
                if (root_map.find(par->getUniqueId()) == root_map.end())
 
260
                        root_map[node->getUniqueId()] = par;
1041
261
                else
1042
 
                        ob_arm = skin.create_armature(scene);
1043
 
 
1044
 
                // enter armature edit mode
1045
 
                ED_armature_to_edit(ob_arm);
1046
 
 
1047
 
                leaf_bones.clear();
1048
 
                totbone = 0;
1049
 
                // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
1050
 
                leaf_bone_length = 0.1f;
1051
 
                // min_angle = 360.0f;          // minimum angle between bone head-tail and a row of bone matrix
1052
 
 
1053
 
                // create bones
1054
 
                /*
1055
 
                   TODO:
1056
 
                   check if bones have already been created for a given joint
1057
 
                */
1058
 
 
1059
 
                std::vector<COLLADAFW::Node*>::iterator ri;
1060
 
                for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
1061
 
                        // for shared armature check if bone tree is already created
1062
 
                        if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end())
1063
 
                                continue;
1064
 
 
1065
 
                        // since root_joints may contain joints for multiple controllers, we need to filter
1066
 
                        if (skin.uses_joint_or_descendant(*ri)) {
1067
 
                                create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
1068
 
 
1069
 
                                if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
1070
 
                                        skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
1071
 
                        }
1072
 
                }
1073
 
 
1074
 
                fix_leaf_bones();
1075
 
 
1076
 
                // exit armature edit mode
1077
 
                ED_armature_from_edit(ob_arm);
1078
 
                ED_armature_edit_free(ob_arm);
1079
 
                DAG_id_flush_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
1080
 
 
1081
 
                set_leaf_bone_shapes(ob_arm);
1082
 
 
1083
 
                // set_euler_rotmode();
1084
 
        }
1085
 
        
1086
 
 
1087
 
public:
1088
 
 
1089
 
        ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
1090
 
                TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {}
1091
 
 
1092
 
        ~ArmatureImporter()
1093
 
        {
1094
 
                // free skin controller data if we forget to do this earlier
1095
 
                std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1096
 
                for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1097
 
                        it->second.free();
1098
 
                }
1099
 
        }
1100
 
 
1101
 
        // root - if this joint is the top joint in hierarchy, if a joint
1102
 
        // is a child of a node (not joint), root should be true since
1103
 
        // this is where we build armature bones from
1104
 
        void add_joint(COLLADAFW::Node *node, bool root, Object *parent)
1105
 
        {
1106
 
                joint_by_uid[node->getUniqueId()] = node;
1107
 
                if (root) {
1108
 
                        root_joints.push_back(node);
1109
 
 
1110
 
                        if (parent)
1111
 
                                joint_parent_map[node->getUniqueId()] = parent;
1112
 
                }
1113
 
        }
1114
 
 
1115
 
#if 0
1116
 
        void add_root_joint(COLLADAFW::Node *node)
1117
 
        {
1118
 
                // root_joints.push_back(node);
1119
 
                Object *ob_arm = find_armature(node);
1120
 
                if (ob_arm)     {
1121
 
                        get_armature_joints(ob_arm).root_joints.push_back(node);
1122
 
                }
1123
 
#ifdef COLLADA_DEBUG
1124
 
                else {
1125
 
                        fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node));
1126
 
                }
1127
 
#endif
1128
 
        }
1129
 
#endif
1130
 
 
1131
 
        // here we add bones to armatures, having armatures previously created in write_controller
1132
 
        void make_armatures(bContext *C)
1133
 
        {
1134
 
                std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1135
 
                for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1136
 
 
1137
 
                        SkinInfo& skin = it->second;
1138
 
 
1139
 
                        create_armature_bones(skin);
1140
 
 
1141
 
                        // link armature with a mesh object
1142
 
                        Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
1143
 
                        if (ob)
1144
 
                                skin.link_armature(C, ob, joint_by_uid, this);
1145
 
                        else
1146
 
                                fprintf(stderr, "Cannot find object to link armature with.\n");
1147
 
 
1148
 
                        // set armature parent if any
1149
 
                        Object *par = skin.get_parent();
1150
 
                        if (par)
1151
 
                                set_parent(skin.get_armature(), par, C, false);
1152
 
 
1153
 
                        // free memory stolen from SkinControllerData
1154
 
                        skin.free();
1155
 
                }
1156
 
        }
1157
 
 
1158
 
#if 0
1159
 
        // link with meshes, create vertex groups, assign weights
1160
 
        void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id)
1161
 
        {
1162
 
                Object *ob = mesh_importer->get_object_by_geom_uid(geom_id);
1163
 
 
1164
 
                if (!ob) {
1165
 
                        fprintf(stderr, "Cannot find object by geometry UID.\n");
1166
 
                        return;
1167
 
                }
1168
 
 
1169
 
                if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) {
1170
 
                        fprintf(stderr, "Cannot find skin info by controller data UID.\n");
1171
 
                        return;
1172
 
                }
1173
 
 
1174
 
                SkinInfo& skin = skin_by_data_uid[conroller_data_id];
1175
 
 
1176
 
                // create vertex groups
1177
 
        }
1178
 
#endif
1179
 
 
1180
 
        bool write_skin_controller_data(const COLLADAFW::SkinControllerData* data)
1181
 
        {
1182
 
                // at this stage we get vertex influence info that should go into me->verts and ob->defbase
1183
 
                // there's no info to which object this should be long so we associate it with skin controller data UID
1184
 
 
1185
 
                // don't forget to call defgroup_unique_name before we copy
1186
 
 
1187
 
                // controller data uid -> [armature] -> joint data, 
1188
 
                // [mesh object]
1189
 
                // 
1190
 
 
1191
 
                SkinInfo skin(unit_converter);
1192
 
                skin.borrow_skin_controller_data(data);
1193
 
 
1194
 
                // store join inv bind matrix to use it later in armature construction
1195
 
                const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices();
1196
 
                for (unsigned int i = 0; i < data->getJointsCount(); i++) {
1197
 
                        skin.add_joint(inv_bind_mats[i]);
1198
 
                }
1199
 
 
1200
 
                skin_by_data_uid[data->getUniqueId()] = skin;
1201
 
 
1202
 
                return true;
1203
 
        }
1204
 
 
1205
 
        bool write_controller(const COLLADAFW::Controller* controller)
1206
 
        {
1207
 
                // - create and store armature object
1208
 
 
1209
 
                const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
1210
 
 
1211
 
                if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
1212
 
                        COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller;
1213
 
                        // to be able to find geom id by controller id
1214
 
                        geom_uid_by_controller_uid[skin_id] = co->getSource();
1215
 
 
1216
 
                        const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData();
1217
 
                        if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
1218
 
                                fprintf(stderr, "Cannot find skin by controller data UID.\n");
1219
 
                                return true;
1220
 
                        }
1221
 
 
1222
 
                        skin_by_data_uid[data_uid].set_controller(co);
1223
 
                }
1224
 
                // morph controller
1225
 
                else {
1226
 
                        // shape keys? :)
1227
 
                        fprintf(stderr, "Morph controller is not supported yet.\n");
1228
 
                }
1229
 
 
1230
 
                return true;
1231
 
        }
1232
 
 
1233
 
        COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
1234
 
        {
1235
 
                if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end())
1236
 
                        return NULL;
1237
 
 
1238
 
                return &geom_uid_by_controller_uid[controller_uid];
1239
 
        }
1240
 
 
1241
 
        Object *get_armature_for_joint(COLLADAFW::Node *node)
1242
 
        {
1243
 
                std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1244
 
                for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1245
 
                        SkinInfo& skin = it->second;
1246
 
 
1247
 
                        if (skin.uses_joint_or_descendant(node))
1248
 
                                return skin.get_armature();
1249
 
                }
1250
 
 
1251
 
                return NULL;
1252
 
        }
1253
 
 
1254
 
        void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
1255
 
        {
1256
 
                BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", get_joint_name(node));
1257
 
        }
1258
 
        
1259
 
        // gives a world-space mat
1260
 
        bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
1261
 
        {
1262
 
                std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1263
 
                bool found = false;
1264
 
                for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1265
 
                        SkinInfo& skin = it->second;
1266
 
                        if ((found = skin.get_joint_inv_bind_matrix(m, joint))) {
1267
 
                                invert_m4(m);
1268
 
                                break;
1269
 
                        }
1270
 
                }
1271
 
 
1272
 
                return found;
1273
 
        }
1274
 
};
1275
 
 
1276
 
class MeshImporter : public MeshImporterBase
1277
 
{
1278
 
private:
1279
 
 
1280
 
        Scene *scene;
1281
 
        ArmatureImporter *armature_importer;
1282
 
 
1283
 
        std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
1284
 
        std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
1285
 
        // this structure is used to assign material indices to faces
1286
 
        // it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
1287
 
        struct Primitive {
1288
 
                MFace *mface;
1289
 
                unsigned int totface;
1290
 
        };
1291
 
        typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
1292
 
        std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
1293
 
        
1294
 
        class UVDataWrapper
1295
 
        {
1296
 
                COLLADAFW::MeshVertexData *mVData;
1297
 
        public:
1298
 
                UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
1299
 
                {}
1300
 
 
1301
 
#ifdef COLLADA_DEBUG
1302
 
                void print()
1303
 
                {
1304
 
                        fprintf(stderr, "UVs:\n");
1305
 
                        switch(mVData->getType()) {
1306
 
                        case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1307
 
                                {
1308
 
                                        COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1309
 
                                        if (values->getCount()) {
1310
 
                                                for (int i = 0; i < values->getCount(); i += 2) {
1311
 
                                                        fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]);
1312
 
                                                }
1313
 
                                        }
1314
 
                                }
1315
 
                                break;
1316
 
                        case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1317
 
                                {
1318
 
                                        COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1319
 
                                        if (values->getCount()) {
1320
 
                                                for (int i = 0; i < values->getCount(); i += 2) {
1321
 
                                                        fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]);
1322
 
                                                }
1323
 
                                        }
1324
 
                                }
1325
 
                                break;
1326
 
                        }
1327
 
                        fprintf(stderr, "\n");
1328
 
                }
1329
 
#endif
1330
 
 
1331
 
                void getUV(int uv_index[2], float *uv)
1332
 
                {
1333
 
                        switch(mVData->getType()) {
1334
 
                        case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1335
 
                                {
1336
 
                                        COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1337
 
                                        if (values->empty()) return;
1338
 
                                        uv[0] = (*values)[uv_index[0]];
1339
 
                                        uv[1] = (*values)[uv_index[1]];
1340
 
                                        
1341
 
                                }
1342
 
                                break;
1343
 
                        case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1344
 
                                {
1345
 
                                        COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1346
 
                                        if (values->empty()) return;
1347
 
                                        uv[0] = (float)(*values)[uv_index[0]];
1348
 
                                        uv[1] = (float)(*values)[uv_index[1]];
1349
 
                                        
1350
 
                                }
1351
 
                                break;
1352
 
                        case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:      
1353
 
                        default:
1354
 
                                fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
1355
 
                        }
1356
 
                }
1357
 
        };
1358
 
 
1359
 
        void set_face_indices(MFace *mface, unsigned int *indices, bool quad)
1360
 
        {
1361
 
                mface->v1 = indices[0];
1362
 
                mface->v2 = indices[1];
1363
 
                mface->v3 = indices[2];
1364
 
                if (quad) mface->v4 = indices[3];
1365
 
                else mface->v4 = 0;
1366
 
#ifdef COLLADA_DEBUG
1367
 
                // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]);
1368
 
#endif
1369
 
        }
1370
 
 
1371
 
        // not used anymore, test_index_face from blenkernel is better
1372
 
#if 0
1373
 
        // change face indices order so that v4 is not 0
1374
 
        void rotate_face_indices(MFace *mface) {
1375
 
                mface->v4 = mface->v1;
1376
 
                mface->v1 = mface->v2;
1377
 
                mface->v2 = mface->v3;
1378
 
                mface->v3 = 0;
1379
 
        }
1380
 
#endif
1381
 
        
1382
 
        void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
1383
 
                                         COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
1384
 
        {
1385
 
                int uv_indices[4][2];
1386
 
 
1387
 
                // per face vertex indices, this means for quad we have 4 indices, not 8
1388
 
                COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1389
 
 
1390
 
                // make indices into FloatOrDoubleArray
1391
 
                for (int i = 0; i < 3; i++) {
1392
 
                        int uv_index = indices[tris_indices[i]];
1393
 
                        uv_indices[i][0] = uv_index * 2;
1394
 
                        uv_indices[i][1] = uv_index * 2 + 1;
1395
 
                }
1396
 
 
1397
 
                uvs.getUV(uv_indices[0], mtface->uv[0]);
1398
 
                uvs.getUV(uv_indices[1], mtface->uv[1]);
1399
 
                uvs.getUV(uv_indices[2], mtface->uv[2]);
1400
 
        }
1401
 
 
1402
 
        void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
1403
 
                                        COLLADAFW::IndexList& index_list, int index, bool quad)
1404
 
        {
1405
 
                int uv_indices[4][2];
1406
 
 
1407
 
                // per face vertex indices, this means for quad we have 4 indices, not 8
1408
 
                COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1409
 
 
1410
 
                // make indices into FloatOrDoubleArray
1411
 
                for (int i = 0; i < (quad ? 4 : 3); i++) {
1412
 
                        int uv_index = indices[index + i];
1413
 
                        uv_indices[i][0] = uv_index * 2;
1414
 
                        uv_indices[i][1] = uv_index * 2 + 1;
1415
 
                }
1416
 
 
1417
 
                uvs.getUV(uv_indices[0], mtface->uv[0]);
1418
 
                uvs.getUV(uv_indices[1], mtface->uv[1]);
1419
 
                uvs.getUV(uv_indices[2], mtface->uv[2]);
1420
 
 
1421
 
                if (quad) uvs.getUV(uv_indices[3], mtface->uv[3]);
1422
 
 
1423
 
#ifdef COLLADA_DEBUG
1424
 
                /*if (quad) {
1425
 
                        fprintf(stderr, "face uv:\n"
1426
 
                                        "((%d, %d), (%d, %d), (%d, %d), (%d, %d))\n"
1427
 
                                        "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1428
 
 
1429
 
                                        uv_indices[0][0], uv_indices[0][1],
1430
 
                                        uv_indices[1][0], uv_indices[1][1],
1431
 
                                        uv_indices[2][0], uv_indices[2][1],
1432
 
                                        uv_indices[3][0], uv_indices[3][1],
1433
 
 
1434
 
                                        mtface->uv[0][0], mtface->uv[0][1],
1435
 
                                        mtface->uv[1][0], mtface->uv[1][1],
1436
 
                                        mtface->uv[2][0], mtface->uv[2][1],
1437
 
                                        mtface->uv[3][0], mtface->uv[3][1]);
1438
 
                }
1439
 
                else {
1440
 
                        fprintf(stderr, "face uv:\n"
1441
 
                                        "((%d, %d), (%d, %d), (%d, %d))\n"
1442
 
                                        "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1443
 
 
1444
 
                                        uv_indices[0][0], uv_indices[0][1],
1445
 
                                        uv_indices[1][0], uv_indices[1][1],
1446
 
                                        uv_indices[2][0], uv_indices[2][1],
1447
 
 
1448
 
                                        mtface->uv[0][0], mtface->uv[0][1],
1449
 
                                        mtface->uv[1][0], mtface->uv[1][1],
1450
 
                                        mtface->uv[2][0], mtface->uv[2][1]);
1451
 
                }*/
1452
 
#endif
1453
 
        }
1454
 
 
1455
 
#ifdef COLLADA_DEBUG
1456
 
        void print_index_list(COLLADAFW::IndexList& index_list)
1457
 
        {
1458
 
                fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
1459
 
                for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
1460
 
                        fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
1461
 
                }
1462
 
                fprintf(stderr, "\n");
1463
 
        }
1464
 
#endif
1465
 
 
1466
 
        bool is_nice_mesh(COLLADAFW::Mesh *mesh)
1467
 
        {
1468
 
                COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1469
 
 
1470
 
                const char *name = get_dae_name(mesh);
1471
 
                
1472
 
                for (unsigned i = 0; i < prim_arr.getCount(); i++) {
1473
 
                        
1474
 
                        COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1475
 
                        COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
1476
 
 
1477
 
                        const char *type_str = primTypeToStr(type);
1478
 
                        
1479
 
                        // OpenCollada passes POLYGONS type for <polylist>
1480
 
                        if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1481
 
 
1482
 
                                COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
1483
 
                                COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
1484
 
                                
1485
 
                                for(unsigned int j = 0; j < vca.getCount(); j++){
1486
 
                                        int count = vca[j];
1487
 
                                        if (count < 3) {
1488
 
                                                fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
1489
 
                                                                type_str, name);
1490
 
                                                return false;
1491
 
                                        }
1492
 
                                }
1493
 
                                        
1494
 
                        }
1495
 
                        else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
1496
 
                                fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
1497
 
                                return false;
1498
 
                        }
1499
 
                }
1500
 
                
1501
 
                if (mesh->getPositions().empty()) {
1502
 
                        fprintf(stderr, "Mesh %s has no vertices.\n", name);
1503
 
                        return false;
1504
 
                }
1505
 
 
1506
 
                return true;
1507
 
        }
1508
 
 
1509
 
        void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
1510
 
        {
1511
 
                // vertices     
1512
 
                me->totvert = mesh->getPositions().getFloatValues()->getCount() / 3;
1513
 
                me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
1514
 
 
1515
 
                COLLADAFW::MeshVertexData& pos = mesh->getPositions();
1516
 
                MVert *mvert;
1517
 
                int i;
1518
 
 
1519
 
                for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++)
1520
 
                        get_vector(mvert->co, pos, i);
1521
 
        }
1522
 
        
1523
 
        int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
1524
 
        {
1525
 
                ListBase dispbase;
1526
 
                DispList *dl;
1527
 
                float *vert;
1528
 
                int i = 0;
1529
 
                
1530
 
                dispbase.first = dispbase.last = NULL;
1531
 
                
1532
 
                dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp");
1533
 
                dl->nr = totvert;
1534
 
                dl->type = DL_POLY;
1535
 
                dl->parts = 1;
1536
 
                dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
1537
 
                dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
1538
 
 
1539
 
                BLI_addtail(&dispbase, dl);
1540
 
                
1541
 
                for (i = 0; i < totvert; i++) {
1542
 
                        copy_v3_v3(vert, verts[indices[i]].co);
1543
 
                        vert += 3;
1544
 
                }
1545
 
                
1546
 
                filldisplist(&dispbase, &dispbase, 0);
1547
 
 
1548
 
                int tottri = 0;
1549
 
                dl= (DispList*)dispbase.first;
1550
 
 
1551
 
                if (dl->type == DL_INDEX3) {
1552
 
                        tottri = dl->parts;
1553
 
 
1554
 
                        int *index = dl->index;
1555
 
                        for (i= 0; i < tottri; i++) {
1556
 
                                int t[3]= {*index, *(index + 1), *(index + 2)};
1557
 
 
1558
 
                                std::sort(t, t + 3);
1559
 
 
1560
 
                                tri.push_back(t[0]);
1561
 
                                tri.push_back(t[1]);
1562
 
                                tri.push_back(t[2]);
1563
 
 
1564
 
                                index += 3;
1565
 
                        }
1566
 
                }
1567
 
 
1568
 
                freedisplist(&dispbase);
1569
 
 
1570
 
                return tottri;
1571
 
        }
1572
 
        
1573
 
        int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
1574
 
        {
1575
 
                COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1576
 
                unsigned int i;
1577
 
                int tottri = 0;
1578
 
                
1579
 
                for (i = 0; i < prim_arr.getCount(); i++) {
1580
 
                        
1581
 
                        COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1582
 
                        int type = mp->getPrimitiveType();
1583
 
                        size_t prim_totface = mp->getFaceCount();
1584
 
                        unsigned int *indices = mp->getPositionIndices().getData();
1585
 
                        
1586
 
                        if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
1587
 
                                type == COLLADAFW::MeshPrimitive::POLYGONS) {
1588
 
                                
1589
 
                                COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
1590
 
                                COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1591
 
                                
1592
 
                                for (unsigned int j = 0; j < prim_totface; j++) {
1593
 
                                        int vcount = vcounta[j];
1594
 
                                        
1595
 
                                        if (vcount > 4) {
1596
 
                                                std::vector<unsigned int> tri;
1597
 
                                                
1598
 
                                                // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
1599
 
                                                tottri += triangulate_poly(indices, vcount, me->mvert, tri);
1600
 
                                        }
1601
 
 
1602
 
                                        indices += vcount;
1603
 
                                }
1604
 
                        }
1605
 
                }
1606
 
                return tottri;
1607
 
        }
1608
 
        
1609
 
        // TODO: import uv set names
1610
 
        void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
1611
 
        {
1612
 
                unsigned int i;
1613
 
                
1614
 
                // allocate faces
1615
 
                me->totface = mesh->getFacesCount() + new_tris;
1616
 
                me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
1617
 
                
1618
 
                // allocate UV layers
1619
 
                unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
1620
 
 
1621
 
                // for (i = 0; i < totuvset; i++) {
1622
 
                //      if (mesh->getUVCoords().getLength(i) == 0) {
1623
 
                //              totuvset = 0;
1624
 
                //              break;
1625
 
                //      }
1626
 
                // }
1627
 
 
1628
 
                for (i = 0; i < totuvset; i++) {
1629
 
                        CustomData_add_layer(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface);
1630
 
                        //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
1631
 
                }
1632
 
 
1633
 
                // activate the first uv layer
1634
 
                if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
1635
 
 
1636
 
                UVDataWrapper uvs(mesh->getUVCoords());
1637
 
 
1638
 
#ifdef COLLADA_DEBUG
1639
 
                // uvs.print();
1640
 
#endif
1641
 
 
1642
 
                MFace *mface = me->mface;
1643
 
 
1644
 
                MaterialIdPrimitiveArrayMap mat_prim_map;
1645
 
 
1646
 
                int face_index = 0;
1647
 
 
1648
 
                COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1649
 
 
1650
 
                bool has_normals = mesh->hasNormals();
1651
 
                COLLADAFW::MeshVertexData& nor = mesh->getNormals();
1652
 
 
1653
 
                for (i = 0; i < prim_arr.getCount(); i++) {
1654
 
                        
1655
 
                        COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1656
 
 
1657
 
                        // faces
1658
 
                        size_t prim_totface = mp->getFaceCount();
1659
 
                        unsigned int *indices = mp->getPositionIndices().getData();
1660
 
                        unsigned int *nind = mp->getNormalIndices().getData();
1661
 
                        unsigned int j, k;
1662
 
                        int type = mp->getPrimitiveType();
1663
 
                        int index = 0;
1664
 
                        
1665
 
                        // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
1666
 
                        Primitive prim = {mface, 0};
1667
 
                        COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
1668
 
 
1669
 
#ifdef COLLADA_DEBUG
1670
 
                        /*
1671
 
                        fprintf(stderr, "Primitive %d:\n", i);
1672
 
                        for (int j = 0; j < totuvset; j++) {
1673
 
                                print_index_list(*index_list_array[j]);
1674
 
                        }
1675
 
                        */
1676
 
#endif
1677
 
                        
1678
 
                        if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
1679
 
                                for (j = 0; j < prim_totface; j++){
1680
 
                                        
1681
 
                                        set_face_indices(mface, indices, false);
1682
 
                                        indices += 3;
1683
 
 
1684
 
#if 0
1685
 
                                        for (k = 0; k < totuvset; k++) {
1686
 
                                                if (!index_list_array.empty() && index_list_array[k]) {
1687
 
                                                        // get mtface by face index and uv set index
1688
 
                                                        MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1689
 
                                                        set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
1690
 
                                                }
1691
 
                                        }
1692
 
#else
1693
 
                                        for (k = 0; k < index_list_array.getCount(); k++) {
1694
 
                                                int uvset_index = index_list_array[k]->getSetIndex();
1695
 
 
1696
 
                                                // get mtface by face index and uv set index
1697
 
                                                MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1698
 
                                                set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false);
1699
 
                                        }
1700
 
#endif
1701
 
 
1702
 
                                        test_index_face(mface, &me->fdata, face_index, 3);
1703
 
 
1704
 
                                        if (has_normals) {
1705
 
                                                if (!flat_face(nind, nor, 3))
1706
 
                                                        mface->flag |= ME_SMOOTH;
1707
 
 
1708
 
                                                nind += 3;
1709
 
                                        }
1710
 
                                        
1711
 
                                        index += 3;
1712
 
                                        mface++;
1713
 
                                        face_index++;
1714
 
                                        prim.totface++;
1715
 
                                }
1716
 
                        }
1717
 
                        else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1718
 
                                COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
1719
 
                                COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1720
 
                                
1721
 
                                for (j = 0; j < prim_totface; j++) {
1722
 
                                        
1723
 
                                        // face
1724
 
                                        int vcount = vcounta[j];
1725
 
                                        if (vcount == 3 || vcount == 4) {
1726
 
                                                
1727
 
                                                set_face_indices(mface, indices, vcount == 4);
1728
 
                                                
1729
 
                                                // set mtface for each uv set
1730
 
                                                // it is assumed that all primitives have equal number of UV sets
1731
 
                                                
1732
 
#if 0
1733
 
                                                for (k = 0; k < totuvset; k++) {
1734
 
                                                        if (!index_list_array.empty() && index_list_array[k]) {
1735
 
                                                                // get mtface by face index and uv set index
1736
 
                                                                MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1737
 
                                                                set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
1738
 
                                                        }
1739
 
                                                }
1740
 
#else
1741
 
                                                for (k = 0; k < index_list_array.getCount(); k++) {
1742
 
                                                        int uvset_index = index_list_array[k]->getSetIndex();
1743
 
 
1744
 
                                                        // get mtface by face index and uv set index
1745
 
                                                        MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1746
 
                                                        set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, mface->v4 != 0);
1747
 
                                                }
1748
 
#endif
1749
 
 
1750
 
                                                test_index_face(mface, &me->fdata, face_index, vcount);
1751
 
 
1752
 
                                                if (has_normals) {
1753
 
                                                        if (!flat_face(nind, nor, vcount))
1754
 
                                                                mface->flag |= ME_SMOOTH;
1755
 
 
1756
 
                                                        nind += vcount;
1757
 
                                                }
1758
 
                                                
1759
 
                                                mface++;
1760
 
                                                face_index++;
1761
 
                                                prim.totface++;
1762
 
                                                
1763
 
                                        }
1764
 
                                        else {
1765
 
                                                std::vector<unsigned int> tri;
1766
 
                                                
1767
 
                                                triangulate_poly(indices, vcount, me->mvert, tri);
1768
 
                                                
1769
 
                                                for (k = 0; k < tri.size() / 3; k++) {
1770
 
                                                        int v = k * 3;
1771
 
                                                        unsigned int uv_indices[3] = {
1772
 
                                                                index + tri[v],
1773
 
                                                                index + tri[v + 1],
1774
 
                                                                index + tri[v + 2]
1775
 
                                                        };
1776
 
                                                        unsigned int tri_indices[3] = {
1777
 
                                                                indices[tri[v]],
1778
 
                                                                indices[tri[v + 1]],
1779
 
                                                                indices[tri[v + 2]]
1780
 
                                                        };
1781
 
 
1782
 
                                                        set_face_indices(mface, tri_indices, false);
1783
 
                                                        
1784
 
#if 0
1785
 
                                                        for (unsigned int l = 0; l < totuvset; l++) {
1786
 
                                                                if (!index_list_array.empty() && index_list_array[l]) {
1787
 
                                                                        // get mtface by face index and uv set index
1788
 
                                                                        MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
1789
 
                                                                        set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
1790
 
                                                                }
1791
 
                                                        }
1792
 
#else
1793
 
                                                        for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
1794
 
                                                                int uvset_index = index_list_array[l]->getSetIndex();
1795
 
 
1796
 
                                                                // get mtface by face index and uv set index
1797
 
                                                                MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1798
 
                                                                set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices);
1799
 
                                                        }
1800
 
#endif
1801
 
 
1802
 
 
1803
 
                                                        test_index_face(mface, &me->fdata, face_index, 3);
1804
 
 
1805
 
                                                        if (has_normals) {
1806
 
                                                                unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]};
1807
 
 
1808
 
                                                                if (!flat_face(ntri, nor, 3))
1809
 
                                                                        mface->flag |= ME_SMOOTH;
1810
 
                                                        }
1811
 
                                                        
1812
 
                                                        mface++;
1813
 
                                                        face_index++;
1814
 
                                                        prim.totface++;
1815
 
                                                }
1816
 
 
1817
 
                                                if (has_normals)
1818
 
                                                        nind += vcount;
1819
 
                                        }
1820
 
 
1821
 
                                        index += vcount;
1822
 
                                        indices += vcount;
1823
 
                                }
1824
 
                        }
1825
 
                        
1826
 
                        mat_prim_map[mp->getMaterialId()].push_back(prim);
1827
 
                }
1828
 
 
1829
 
                geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
1830
 
        }
1831
 
 
1832
 
        void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i)
1833
 
        {
1834
 
                i *= 3;
1835
 
 
1836
 
                switch(arr.getType()) {
1837
 
                case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1838
 
                        {
1839
 
                                COLLADAFW::ArrayPrimitiveType<float>* values = arr.getFloatValues();
1840
 
                                if (values->empty()) return;
1841
 
 
1842
 
                                v[0] = (*values)[i++];
1843
 
                                v[1] = (*values)[i++];
1844
 
                                v[2] = (*values)[i];
1845
 
                        }
1846
 
                        break;
1847
 
                case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1848
 
                        {
1849
 
                                COLLADAFW::ArrayPrimitiveType<double>* values = arr.getDoubleValues();
1850
 
                                if (values->empty()) return;
1851
 
 
1852
 
                                v[0] = (float)(*values)[i++];
1853
 
                                v[1] = (float)(*values)[i++];
1854
 
                                v[2] = (float)(*values)[i];
1855
 
                        }
1856
 
                        break;
1857
 
                default:
1858
 
                        break;
1859
 
                }
1860
 
        }
1861
 
 
1862
 
        bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
1863
 
        {
1864
 
                float a[3], b[3];
1865
 
 
1866
 
                get_vector(a, nor, *nind);
1867
 
                normalize_v3(a);
1868
 
 
1869
 
                nind++;
1870
 
 
1871
 
                for (int i = 1; i < count; i++, nind++) {
1872
 
                        get_vector(b, nor, *nind);
1873
 
                        normalize_v3(b);
1874
 
 
1875
 
                        float dp = dot_v3v3(a, b);
1876
 
 
1877
 
                        if (dp < 0.99999f || dp > 1.00001f)
1878
 
                                return false;
1879
 
                }
1880
 
 
1881
 
                return true;
1882
 
        }
1883
 
 
1884
 
public:
1885
 
 
1886
 
        MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {}
1887
 
 
1888
 
        virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
1889
 
        {
1890
 
                if (uid_object_map.find(geom_uid) != uid_object_map.end())
1891
 
                        return uid_object_map[geom_uid];
1892
 
                return NULL;
1893
 
        }
1894
 
        
1895
 
        MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
1896
 
                                                                         Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
1897
 
                                                                         MTex *color_texture)
1898
 
        {
1899
 
                COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
1900
 
                char *uvname = CustomData_get_layer_name(&me->fdata, CD_MTFACE, ctexture.getSetIndex());
1901
 
 
1902
 
                if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
1903
 
                        
1904
 
                        fprintf(stderr, "Cannot find texture array by texture index.\n");
1905
 
                        return color_texture;
1906
 
                }
1907
 
                
1908
 
                std::vector<MTex*> textures = texindex_texarray_map[texture_index];
1909
 
                
1910
 
                std::vector<MTex*>::iterator it;
1911
 
                
1912
 
                for (it = textures.begin(); it != textures.end(); it++) {
1913
 
                        
1914
 
                        MTex *texture = *it;
1915
 
                        
1916
 
                        if (texture) {
1917
 
                                strcpy(texture->uvname, uvname);
1918
 
                                if (texture->mapto == MAP_COL) color_texture = texture;
1919
 
                        }
1920
 
                }
1921
 
                return color_texture;
1922
 
        }
1923
 
        
1924
 
        MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1925
 
                                                                        std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1926
 
                                                                        Object *ob, const COLLADAFW::UniqueId *geom_uid, 
1927
 
                                                                        MTex **color_texture, char *layername, MTFace *texture_face,
1928
 
                                                                        std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index)
1929
 
        {
1930
 
                Mesh *me = (Mesh*)ob->data;
1931
 
                const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1932
 
                
1933
 
                // do we know this material?
1934
 
                if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1935
 
                        
1936
 
                        fprintf(stderr, "Cannot find material by UID.\n");
1937
 
                        return NULL;
1938
 
                }
1939
 
                
1940
 
                Material *ma = uid_material_map[ma_uid];
1941
 
                assign_material(ob, ma, ob->totcol + 1);
1942
 
                
1943
 
                COLLADAFW::TextureCoordinateBindingArray& tex_array = 
1944
 
                        cmaterial.getTextureCoordinateBindingArray();
1945
 
                TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1946
 
                unsigned int i;
1947
 
                // loop through <bind_vertex_inputs>
1948
 
                for (i = 0; i < tex_array.getCount(); i++) {
1949
 
                        
1950
 
                        *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1951
 
                                                                                                                *color_texture);
1952
 
                }
1953
 
                
1954
 
                // set texture face
1955
 
                if (*color_texture &&
1956
 
                        strlen((*color_texture)->uvname) &&
1957
 
                        strcmp(layername, (*color_texture)->uvname) != 0) {
1958
 
                        
1959
 
                        texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1960
 
                                                                                                                           (*color_texture)->uvname);
1961
 
                        strcpy(layername, (*color_texture)->uvname);
1962
 
                }
1963
 
                
1964
 
                MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1965
 
                COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1966
 
                
1967
 
                // assign material indices to mesh faces
1968
 
                if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1969
 
                        
1970
 
                        std::vector<Primitive>& prims = mat_prim_map[mat_id];
1971
 
                        
1972
 
                        std::vector<Primitive>::iterator it;
1973
 
                        
1974
 
                        for (it = prims.begin(); it != prims.end(); it++) {
1975
 
                                Primitive& prim = *it;
1976
 
                                i = 0;
1977
 
                                while (i++ < prim.totface) {
1978
 
                                        prim.mface->mat_nr = mat_index;
1979
 
                                        prim.mface++;
1980
 
                                        // bind texture images to faces
1981
 
                                        if (texture_face && (*color_texture)) {
1982
 
                                                texture_face->mode = TF_TEX;
1983
 
                                                texture_face->tpage = (Image*)(*color_texture)->tex->ima;
1984
 
                                                texture_face++;
1985
 
                                        }
1986
 
                                }
1987
 
                        }
1988
 
                }
1989
 
                
1990
 
                return texture_face;
1991
 
        }
1992
 
        
1993
 
        
1994
 
        Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1995
 
                                                           bool isController,
1996
 
                                                           std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1997
 
                                                           std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map)
1998
 
        {
1999
 
                const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
2000
 
                
2001
 
                // check if node instanciates controller or geometry
2002
 
                if (isController) {
2003
 
                        
2004
 
                        geom_uid = armature_importer->get_geometry_uid(*geom_uid);
2005
 
                        
2006
 
                        if (!geom_uid) {
2007
 
                                fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
2008
 
                                return NULL;
2009
 
                        }
2010
 
                }
2011
 
                else {
2012
 
                        
2013
 
                        if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
2014
 
                                // this could happen if a mesh was not created
2015
 
                                // (e.g. if it contains unsupported geometry)
2016
 
                                fprintf(stderr, "Couldn't find a mesh by UID.\n");
2017
 
                                return NULL;
2018
 
                        }
2019
 
                }
2020
 
                if (!uid_mesh_map[*geom_uid]) return NULL;
2021
 
                
2022
 
                Object *ob = add_object(scene, OB_MESH);
2023
 
 
2024
 
                // store object pointer for ArmatureImporter
2025
 
                uid_object_map[*geom_uid] = ob;
2026
 
                
2027
 
                // name Object
2028
 
                const std::string& id = node->getOriginalId();
2029
 
                if (id.length())
2030
 
                        rename_id(&ob->id, (char*)id.c_str());
2031
 
                
2032
 
                // replace ob->data freeing the old one
2033
 
                Mesh *old_mesh = (Mesh*)ob->data;
2034
 
 
2035
 
                set_mesh(ob, uid_mesh_map[*geom_uid]);
2036
 
                
2037
 
                if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh);
2038
 
                
2039
 
                char layername[100];
2040
 
                MTFace *texture_face = NULL;
2041
 
                MTex *color_texture = NULL;
2042
 
                
2043
 
                COLLADAFW::MaterialBindingArray& mat_array =
2044
 
                        geom->getMaterialBindings();
2045
 
                
2046
 
                // loop through geom's materials
2047
 
                for (unsigned int i = 0; i < mat_array.getCount(); i++) {
2048
 
                        
2049
 
                        texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
2050
 
                                                                                                   &color_texture, layername, texture_face,
2051
 
                                                                                                   material_texture_mapping_map, i);
2052
 
                }
2053
 
                        
2054
 
                return ob;
2055
 
        }
2056
 
 
2057
 
        // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
2058
 
        bool write_geometry(const COLLADAFW::Geometry* geom) 
2059
 
        {
2060
 
                // TODO: import also uvs, normals
2061
 
                // XXX what to do with normal indices?
2062
 
                // XXX num_normals may be != num verts, then what to do?
2063
 
 
2064
 
                // check geometry->getType() first
2065
 
                if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
2066
 
                        // TODO: report warning
2067
 
                        fprintf(stderr, "Mesh type %s is not supported\n", geomTypeToStr(geom->getType()));
2068
 
                        return true;
2069
 
                }
2070
 
                
2071
 
                COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom;
2072
 
                
2073
 
                if (!is_nice_mesh(mesh)) {
2074
 
                        fprintf(stderr, "Ignoring mesh %s\n", get_dae_name(mesh));
2075
 
                        return true;
2076
 
                }
2077
 
                
2078
 
                const std::string& str_geom_id = mesh->getOriginalId();
2079
 
                Mesh *me = add_mesh((char*)str_geom_id.c_str());
2080
 
 
2081
 
                // store the Mesh pointer to link it later with an Object
2082
 
                this->uid_mesh_map[mesh->getUniqueId()] = me;
2083
 
                
2084
 
                int new_tris = 0;
2085
 
                
2086
 
                read_vertices(mesh, me);
2087
 
 
2088
 
                new_tris = count_new_tris(mesh, me);
2089
 
                
2090
 
                read_faces(mesh, me, new_tris);
2091
 
 
2092
 
                make_edges(me, 0);
2093
 
                
2094
 
                mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
2095
 
 
2096
 
                return true;
2097
 
        }
2098
 
 
2099
 
};
2100
 
 
2101
 
class AnimationImporter : private TransformReader, public AnimationImporterBase
2102
 
{
2103
 
private:
2104
 
 
2105
 
        ArmatureImporter *armature_importer;
2106
 
        Scene *scene;
2107
 
 
2108
 
        std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > curve_map;
2109
 
        std::map<COLLADAFW::UniqueId, TransformReader::Animation> uid_animated_map;
2110
 
        // std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
2111
 
        std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList*> animlist_map;
2112
 
        std::vector<FCurve*> unused_curves;
2113
 
        std::map<COLLADAFW::UniqueId, Object*> joint_objects;
2114
 
        
2115
 
        FCurve *create_fcurve(int array_index, const char *rna_path)
2116
 
        {
2117
 
                FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
2118
 
                
2119
 
                fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
2120
 
                fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
2121
 
                fcu->array_index = array_index;
2122
 
                return fcu;
2123
 
        }
2124
 
        
2125
 
        void create_bezt(FCurve *fcu, float frame, float output)
2126
 
        {
2127
 
                BezTriple bez;
2128
 
                memset(&bez, 0, sizeof(BezTriple));
2129
 
                bez.vec[1][0] = frame;
2130
 
                bez.vec[1][1] = output;
2131
 
                bez.ipo = U.ipo_new; /* use default interpolation mode here... */
2132
 
                bez.f1 = bez.f2 = bez.f3 = SELECT;
2133
 
                bez.h1 = bez.h2 = HD_AUTO;
2134
 
                insert_bezt_fcurve(fcu, &bez, 0);
2135
 
                calchandles_fcurve(fcu);
2136
 
        }
2137
 
 
2138
 
        // create one or several fcurves depending on the number of parameters being animated
2139
 
        void animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
2140
 
        {
2141
 
                COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
2142
 
                COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
2143
 
                // COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
2144
 
                // COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
2145
 
                float fps = (float)FPS;
2146
 
                size_t dim = curve->getOutDimension();
2147
 
                unsigned int i;
2148
 
 
2149
 
                std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
2150
 
 
2151
 
                switch (dim) {
2152
 
                case 1: // X, Y, Z or angle
2153
 
                case 3: // XYZ
2154
 
                case 16: // matrix
2155
 
                        {
2156
 
                                for (i = 0; i < dim; i++ ) {
2157
 
                                        FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
2158
 
                                
2159
 
                                        fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
2160
 
                                        // fcu->rna_path = BLI_strdupn(path, strlen(path));
2161
 
                                        fcu->array_index = 0;
2162
 
                                        //fcu->totvert = curve->getKeyCount();
2163
 
                                
2164
 
                                        // create beztriple for each key
2165
 
                                        for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
2166
 
                                                BezTriple bez;
2167
 
                                                memset(&bez, 0, sizeof(BezTriple));
2168
 
 
2169
 
                                                // intangent
2170
 
                                                // bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
2171
 
                                                // bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
2172
 
 
2173
 
                                                // input, output
2174
 
                                                bez.vec[1][0] = get_float_value(input, j) * fps; 
2175
 
                                                bez.vec[1][1] = get_float_value(output, j * dim + i);
2176
 
 
2177
 
                                                // outtangent
2178
 
                                                // bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
2179
 
                                                // bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
2180
 
 
2181
 
                                                bez.ipo = U.ipo_new; /* use default interpolation mode here... */
2182
 
                                                bez.f1 = bez.f2 = bez.f3 = SELECT;
2183
 
                                                bez.h1 = bez.h2 = HD_AUTO;
2184
 
                                                insert_bezt_fcurve(fcu, &bez, 0);
2185
 
                                        }
2186
 
 
2187
 
                                        calchandles_fcurve(fcu);
2188
 
 
2189
 
                                        fcurves.push_back(fcu);
2190
 
                                }
2191
 
                        }
2192
 
                        break;
2193
 
                default:
2194
 
                        fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", dim, curve->getOriginalId().c_str());
2195
 
                }
2196
 
 
2197
 
                for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
2198
 
                        unused_curves.push_back(*it);
2199
 
        }
2200
 
 
2201
 
        void fcurve_deg_to_rad(FCurve *cu)
2202
 
        {
2203
 
                for (unsigned int i = 0; i < cu->totvert; i++) {
2204
 
                        // TODO convert handles too
2205
 
                        cu->bezt[i].vec[1][1] *= M_PI / 180.0f;
2206
 
                }
2207
 
        }
2208
 
 
2209
 
        void add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
2210
 
        {
2211
 
                bAction *act;
2212
 
                
2213
 
                if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
2214
 
                else act = ob->adt->action;
2215
 
                
2216
 
                std::vector<FCurve*>::iterator it;
2217
 
                int i;
2218
 
 
2219
 
#if 0
2220
 
                char *p = strstr(rna_path, "rotation_euler");
2221
 
                bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
2222
 
 
2223
 
                // convert degrees to radians for rotation
2224
 
                if (is_rotation)
2225
 
                        fcurve_deg_to_rad(fcu);
2226
 
#endif
2227
 
                
2228
 
                for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
2229
 
                        FCurve *fcu = *it;
2230
 
                        fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
2231
 
                        
2232
 
                        if (array_index == -1) fcu->array_index = i;
2233
 
                        else fcu->array_index = array_index;
2234
 
                
2235
 
                        if (ob->type == OB_ARMATURE) {
2236
 
                                bActionGroup *grp = NULL;
2237
 
                                const char *bone_name = get_joint_name(animated->node);
2238
 
                                
2239
 
                                if (bone_name) {
2240
 
                                        /* try to find group */
2241
 
                                        grp = action_groups_find_named(act, bone_name);
2242
 
                                        
2243
 
                                        /* no matching groups, so add one */
2244
 
                                        if (grp == NULL) {
2245
 
                                                /* Add a new group, and make it active */
2246
 
                                                grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
2247
 
                                                
2248
 
                                                grp->flag = AGRP_SELECTED;
2249
 
                                                BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
2250
 
                                                
2251
 
                                                BLI_addtail(&act->groups, grp);
2252
 
                                                BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
2253
 
                                        }
2254
 
                                        
2255
 
                                        /* add F-Curve to group */
2256
 
                                        action_groups_add_channel(act, grp, fcu);
2257
 
                                        
2258
 
                                }
2259
 
#if 0
2260
 
                                if (is_rotation) {
2261
 
                                        fcurves_actionGroup_map[grp].push_back(fcu);
2262
 
                                }
2263
 
#endif
2264
 
                        }
2265
 
                        else {
2266
 
                                BLI_addtail(&act->curves, fcu);
2267
 
                        }
2268
 
 
2269
 
                        // curve is used, so remove it from unused_curves
2270
 
                        unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
2271
 
                }
2272
 
        }
2273
 
public:
2274
 
 
2275
 
        AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) :
2276
 
                TransformReader(conv), armature_importer(arm), scene(scene) { }
2277
 
 
2278
 
        ~AnimationImporter()
2279
 
        {
2280
 
                // free unused FCurves
2281
 
                for (std::vector<FCurve*>::iterator it = unused_curves.begin(); it != unused_curves.end(); it++)
2282
 
                        free_fcurve(*it);
2283
 
 
2284
 
                if (unused_curves.size())
2285
 
                        fprintf(stderr, "removed %u unused curves\n", unused_curves.size());
2286
 
        }
2287
 
 
2288
 
        bool write_animation(const COLLADAFW::Animation* anim) 
2289
 
        {
2290
 
                if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
2291
 
                        COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim;
2292
 
                        
2293
 
                        // XXX Don't know if it's necessary
2294
 
                        // Should we check outPhysicalDimension?
2295
 
                        if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
2296
 
                                fprintf(stderr, "Inputs physical dimension is not time. \n");
2297
 
                                return true;
2298
 
                        }
2299
 
 
2300
 
                        // a curve can have mixed interpolation type,
2301
 
                        // in this case curve->getInterpolationTypes returns a list of interpolation types per key
2302
 
                        COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType();
2303
 
 
2304
 
                        if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
2305
 
                                switch (interp) {
2306
 
                                case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
2307
 
                                case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
2308
 
                                        animation_to_fcurves(curve);
2309
 
                                        break;
2310
 
                                default:
2311
 
                                        // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types
2312
 
                                        fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n");
2313
 
                                        break;
2314
 
                                }
2315
 
                        }
2316
 
                        else {
2317
 
                                // not supported yet
2318
 
                                fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
2319
 
                        }
2320
 
                }
2321
 
                else {
2322
 
                        fprintf(stderr, "FORMULA animation type is not supported yet.\n");
2323
 
                }
2324
 
                
2325
 
                return true;
2326
 
        }
2327
 
        
2328
 
        // called on post-process stage after writeVisualScenes
2329
 
        bool write_animation_list(const COLLADAFW::AnimationList* animlist) 
2330
 
        {
2331
 
                const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
2332
 
 
2333
 
                animlist_map[animlist_id] = animlist;
2334
 
 
2335
 
#if 0
2336
 
                // should not happen
2337
 
                if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
2338
 
                        return true;
2339
 
                }
2340
 
 
2341
 
                // for bones rna_path is like: pose.bones["bone-name"].rotation
2342
 
                
2343
 
                // what does this AnimationList animate?
2344
 
                Animation& animated = uid_animated_map[animlist_id];
2345
 
                Object *ob = animated.ob;
2346
 
 
2347
 
                char rna_path[100];
2348
 
                char joint_path[100];
2349
 
                bool is_joint = false;
2350
 
 
2351
 
                // if ob is NULL, it should be a JOINT
2352
 
                if (!ob) {
2353
 
                        ob = armature_importer->get_armature_for_joint(animated.node);
2354
 
 
2355
 
                        if (!ob) {
2356
 
                                fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
2357
 
                                return true;
2358
 
                        }
2359
 
 
2360
 
                        armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path));
2361
 
 
2362
 
                        is_joint = true;
2363
 
                }
2364
 
                
2365
 
                const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2366
 
 
2367
 
                switch (animated.tm->getTransformationType()) {
2368
 
                case COLLADAFW::Transformation::TRANSLATE:
2369
 
                case COLLADAFW::Transformation::SCALE:
2370
 
                        {
2371
 
                                bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE;
2372
 
                                if (is_joint)
2373
 
                                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
2374
 
                                else
2375
 
                                        BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
2376
 
 
2377
 
                                for (int i = 0; i < bindings.getCount(); i++) {
2378
 
                                        const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2379
 
                                        COLLADAFW::UniqueId anim_uid = binding.animation;
2380
 
 
2381
 
                                        if (curve_map.find(anim_uid) == curve_map.end()) {
2382
 
                                                fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2383
 
                                                continue;
2384
 
                                        }
2385
 
 
2386
 
                                        std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2387
 
                                        
2388
 
                                        switch (binding.animationClass) {
2389
 
                                        case COLLADAFW::AnimationList::POSITION_X:
2390
 
                                                add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2391
 
                                                break;
2392
 
                                        case COLLADAFW::AnimationList::POSITION_Y:
2393
 
                                                add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2394
 
                                                break;
2395
 
                                        case COLLADAFW::AnimationList::POSITION_Z:
2396
 
                                                add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2397
 
                                                break;
2398
 
                                        case COLLADAFW::AnimationList::POSITION_XYZ:
2399
 
                                                add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated);
2400
 
                                                break;
2401
 
                                        default:
2402
 
                                                fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
2403
 
                                                                binding.animationClass, loc ? "TRANSLATE" : "SCALE");
2404
 
                                        }
2405
 
                                }
2406
 
                        }
2407
 
                        break;
2408
 
                case COLLADAFW::Transformation::ROTATE:
2409
 
                        {
2410
 
                                if (is_joint)
2411
 
                                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
2412
 
                                else
2413
 
                                        BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
2414
 
 
2415
 
                                COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm;
2416
 
                                COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
2417
 
                                
2418
 
                                for (int i = 0; i < bindings.getCount(); i++) {
2419
 
                                        const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2420
 
                                        COLLADAFW::UniqueId anim_uid = binding.animation;
2421
 
 
2422
 
                                        if (curve_map.find(anim_uid) == curve_map.end()) {
2423
 
                                                fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2424
 
                                                continue;
2425
 
                                        }
2426
 
 
2427
 
                                        std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2428
 
 
2429
 
                                        switch (binding.animationClass) {
2430
 
                                        case COLLADAFW::AnimationList::ANGLE:
2431
 
                                                if (COLLADABU::Math::Vector3::UNIT_X == axis) {
2432
 
                                                        add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2433
 
                                                }
2434
 
                                                else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
2435
 
                                                        add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2436
 
                                                }
2437
 
                                                else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
2438
 
                                                        add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2439
 
                                                }
2440
 
                                                break;
2441
 
                                        case COLLADAFW::AnimationList::AXISANGLE:
2442
 
                                                // TODO convert axis-angle to quat? or XYZ?
2443
 
                                        default:
2444
 
                                                fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
2445
 
                                                                binding.animationClass);
2446
 
                                        }
2447
 
                                }
2448
 
                        }
2449
 
                        break;
2450
 
                case COLLADAFW::Transformation::MATRIX:
2451
 
                case COLLADAFW::Transformation::SKEW:
2452
 
                case COLLADAFW::Transformation::LOOKAT:
2453
 
                        fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n");
2454
 
                        break;
2455
 
                }
2456
 
#endif
2457
 
                
2458
 
                return true;
2459
 
        }
2460
 
 
2461
 
        void read_node_transform(COLLADAFW::Node *node, Object *ob)
2462
 
        {
2463
 
                float mat[4][4];
2464
 
                TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
2465
 
                if (ob) {
2466
 
                        copy_m4_m4(ob->obmat, mat);
2467
 
                        object_apply_mat4(ob, ob->obmat);
2468
 
                }
2469
 
        }
2470
 
        
2471
 
#if 0
2472
 
        virtual void change_eul_to_quat(Object *ob, bAction *act)
2473
 
        {
2474
 
                bActionGroup *grp;
2475
 
                int i;
2476
 
                
2477
 
                for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) {
2478
 
 
2479
 
                        FCurve *eulcu[3] = {NULL, NULL, NULL};
2480
 
                        
2481
 
                        if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
2482
 
                                continue;
2483
 
 
2484
 
                        std::vector<FCurve*> &rot_fcurves = fcurves_actionGroup_map[grp];
2485
 
                        
2486
 
                        if (rot_fcurves.size() > 3) continue;
2487
 
 
2488
 
                        for (i = 0; i < rot_fcurves.size(); i++)
2489
 
                                eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
2490
 
 
2491
 
                        char joint_path[100];
2492
 
                        char rna_path[100];
2493
 
 
2494
 
                        BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name);
2495
 
                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path);
2496
 
 
2497
 
                        FCurve *quatcu[4] = {
2498
 
                                create_fcurve(0, rna_path),
2499
 
                                create_fcurve(1, rna_path),
2500
 
                                create_fcurve(2, rna_path),
2501
 
                                create_fcurve(3, rna_path)
2502
 
                        };
2503
 
 
2504
 
                        bPoseChannel *chan = get_pose_channel(ob->pose, grp->name);
2505
 
 
2506
 
                        float m4[4][4], irest[3][3];
2507
 
                        invert_m4_m4(m4, chan->bone->arm_mat);
2508
 
                        copy_m3_m4(irest, m4);
2509
 
 
2510
 
                        for (i = 0; i < 3; i++) {
2511
 
 
2512
 
                                FCurve *cu = eulcu[i];
2513
 
 
2514
 
                                if (!cu) continue;
2515
 
 
2516
 
                                for (int j = 0; j < cu->totvert; j++) {
2517
 
                                        float frame = cu->bezt[j].vec[1][0];
2518
 
 
2519
 
                                        float eul[3] = {
2520
 
                                                eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f,
2521
 
                                                eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f,
2522
 
                                                eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f
2523
 
                                        };
2524
 
 
2525
 
                                        // make eul relative to bone rest pose
2526
 
                                        float rot[3][3], rel[3][3], quat[4];
2527
 
 
2528
 
                                        /*eul_to_mat3(rot, eul);
2529
 
 
2530
 
                                        mul_m3_m3m3(rel, irest, rot);
2531
 
 
2532
 
                                        mat3_to_quat(quat, rel);
2533
 
                                        */
2534
 
 
2535
 
                                        eul_to_quat(quat, eul);
2536
 
 
2537
 
                                        for (int k = 0; k < 4; k++)
2538
 
                                                create_bezt(quatcu[k], frame, quat[k]);
2539
 
                                }
2540
 
                        }
2541
 
 
2542
 
                        // now replace old Euler curves
2543
 
 
2544
 
                        for (i = 0; i < 3; i++) {
2545
 
                                if (!eulcu[i]) continue;
2546
 
 
2547
 
                                action_groups_remove_channel(act, eulcu[i]);
2548
 
                                free_fcurve(eulcu[i]);
2549
 
                        }
2550
 
 
2551
 
                        chan->rotmode = ROT_MODE_QUAT;
2552
 
 
2553
 
                        for (i = 0; i < 4; i++)
2554
 
                                action_groups_add_channel(act, grp, quatcu[i]);
2555
 
                }
2556
 
 
2557
 
                bPoseChannel *pchan;
2558
 
                for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
2559
 
                        pchan->rotmode = ROT_MODE_QUAT;
2560
 
                }
2561
 
        }
2562
 
#endif
2563
 
 
2564
 
        // prerequisites:
2565
 
        // animlist_map - map animlist id -> animlist
2566
 
        // curve_map - map anim id -> curve(s)
2567
 
        Object *translate_animation(COLLADAFW::Node *node,
2568
 
                                                                std::map<COLLADAFW::UniqueId, Object*>& object_map,
2569
 
                                                                std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
2570
 
                                                                COLLADAFW::Transformation::TransformationType tm_type,
2571
 
                                                                Object *par_job = NULL)
2572
 
        {
2573
 
                bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
2574
 
                bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
2575
 
                bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
2576
 
 
2577
 
                COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
2578
 
                Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
2579
 
                const char *bone_name = is_joint ? get_joint_name(node) : NULL;
2580
 
 
2581
 
                if (!ob) {
2582
 
                        fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
2583
 
                        return NULL;
2584
 
                }
2585
 
 
2586
 
                // frames at which to sample
2587
 
                std::vector<float> frames;
2588
 
 
2589
 
                // for each <rotate>, <translate>, etc. there is a separate Transformation
2590
 
                const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2591
 
 
2592
 
                unsigned int i;
2593
 
 
2594
 
                // find frames at which to sample plus convert all rotation keys to radians
2595
 
                for (i = 0; i < tms.getCount(); i++) {
2596
 
                        COLLADAFW::Transformation *tm = tms[i];
2597
 
                        COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2598
 
 
2599
 
                        if (type == tm_type) {
2600
 
                                const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2601
 
 
2602
 
                                if (animlist_map.find(listid) != animlist_map.end()) {
2603
 
                                        const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2604
 
                                        const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2605
 
 
2606
 
                                        if (bindings.getCount()) {
2607
 
                                                for (unsigned int j = 0; j < bindings.getCount(); j++) {
2608
 
                                                        std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
2609
 
                                                        bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
2610
 
 
2611
 
                                                        if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
2612
 
                                                                std::vector<FCurve*>::iterator iter;
2613
 
 
2614
 
                                                                for (iter = curves.begin(); iter != curves.end(); iter++) {
2615
 
                                                                        FCurve *fcu = *iter;
2616
 
 
2617
 
                                                                        if (is_rotation)
2618
 
                                                                                fcurve_deg_to_rad(fcu);
2619
 
 
2620
 
                                                                        for (unsigned int k = 0; k < fcu->totvert; k++) {
2621
 
                                                                                float fra = fcu->bezt[k].vec[1][0];
2622
 
                                                                                if (std::find(frames.begin(), frames.end(), fra) == frames.end())
2623
 
                                                                                        frames.push_back(fra);
2624
 
                                                                        }
2625
 
                                                                }
2626
 
                                                        }
2627
 
                                                        else {
2628
 
                                                                fprintf(stderr, "expected %d curves, got %u\n", xyz ? 3 : 1, curves.size());
2629
 
                                                        }
2630
 
                                                }
2631
 
                                        }
2632
 
                                }
2633
 
                        }
2634
 
                }
2635
 
 
2636
 
                float irest_dae[4][4];
2637
 
                float rest[4][4], irest[4][4];
2638
 
 
2639
 
                if (is_joint) {
2640
 
                        get_joint_rest_mat(irest_dae, root, node);
2641
 
                        invert_m4(irest_dae);
2642
 
 
2643
 
                        Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
2644
 
                        if (!bone) {
2645
 
                                fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
2646
 
                                return NULL;
2647
 
                        }
2648
 
 
2649
 
                        unit_m4(rest);
2650
 
                        copy_m4_m4(rest, bone->arm_mat);
2651
 
                        invert_m4_m4(irest, rest);
2652
 
                }
2653
 
 
2654
 
                Object *job = NULL;
2655
 
 
2656
 
#ifdef ARMATURE_TEST
2657
 
                FCurve *job_curves[10];
2658
 
                job = get_joint_object(root, node, par_job);
2659
 
#endif
2660
 
 
2661
 
                if (frames.size() == 0)
2662
 
                        return job;
2663
 
 
2664
 
                std::sort(frames.begin(), frames.end());
2665
 
 
2666
 
                const char *tm_str = NULL;
2667
 
                switch (tm_type) {
2668
 
                case COLLADAFW::Transformation::ROTATE:
2669
 
                        tm_str = "rotation_quaternion";
2670
 
                        break;
2671
 
                case COLLADAFW::Transformation::SCALE:
2672
 
                        tm_str = "scale";
2673
 
                        break;
2674
 
                case COLLADAFW::Transformation::TRANSLATE:
2675
 
                        tm_str = "location";
2676
 
                        break;
2677
 
                case COLLADAFW::Transformation::MATRIX:
2678
 
                        break;
2679
 
                default:
2680
 
                        return job;
2681
 
                }
2682
 
 
2683
 
                char rna_path[200];
2684
 
                char joint_path[200];
2685
 
 
2686
 
                if (is_joint)
2687
 
                        armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
2688
 
 
2689
 
                // new curves
2690
 
                FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
2691
 
                unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
2692
 
 
2693
 
                for (i = 0; i < totcu; i++) {
2694
 
 
2695
 
                        int axis = i;
2696
 
 
2697
 
                        if (is_matrix) {
2698
 
                                if (i < 4) {
2699
 
                                        tm_str = "rotation_quaternion";
2700
 
                                        axis = i;
2701
 
                                }
2702
 
                                else if (i < 7) {
2703
 
                                        tm_str = "location";
2704
 
                                        axis = i - 4;
2705
 
                                }
2706
 
                                else {
2707
 
                                        tm_str = "scale";
2708
 
                                        axis = i - 7;
2709
 
                                }
2710
 
                        }
2711
 
 
2712
 
                        if (is_joint)
2713
 
                                BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
2714
 
                        else
2715
 
                                strcpy(rna_path, tm_str);
2716
 
 
2717
 
                        newcu[i] = create_fcurve(axis, rna_path);
2718
 
 
2719
 
#ifdef ARMATURE_TEST
2720
 
                        if (is_joint)
2721
 
                                job_curves[i] = create_fcurve(axis, tm_str);
2722
 
#endif
2723
 
                }
2724
 
 
2725
 
                std::vector<float>::iterator it;
2726
 
 
2727
 
                // sample values at each frame
2728
 
                for (it = frames.begin(); it != frames.end(); it++) {
2729
 
                        float fra = *it;
2730
 
 
 
262
                        root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
 
263
        }
 
264
 
 
265
        /*COLLADAFW::Transformation::TransformationType types[] = {
 
266
                COLLADAFW::Transformation::ROTATE,
 
267
                COLLADAFW::Transformation::SCALE,
 
268
                COLLADAFW::Transformation::TRANSLATE,
 
269
                COLLADAFW::Transformation::MATRIX
 
270
        };
 
271
 
 
272
        Object *ob;*/
 
273
        unsigned int i;
 
274
 
 
275
        //for (i = 0; i < 4; i++)
 
276
                //ob = 
 
277
        anim_importer.translate_Animations(node, root_map, object_map, FW_object_map);
 
278
 
 
279
        COLLADAFW::NodePointerArray &children = node->getChildNodes();
 
280
        for (i = 0; i < children.getCount(); i++) {
 
281
                translate_anim_recursive(children[i], node, NULL);
 
282
        }
 
283
}
 
284
 
 
285
/** When this method is called, the writer must write the global document asset.
 
286
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
287
bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) 
 
288
{
 
289
        unit_converter.read_asset(asset);
 
290
 
 
291
        return true;
 
292
}
 
293
 
 
294
/** When this method is called, the writer must write the scene.
 
295
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
296
bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene ) 
 
297
{
 
298
        // XXX could store the scene id, but do nothing for now
 
299
        return true;
 
300
}
 
301
Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
 
302
{
 
303
        const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
 
304
        if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {     
 
305
                fprintf(stderr, "Couldn't find camera by UID.\n");
 
306
                return NULL;
 
307
        }
 
308
 
 
309
        Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
 
310
        Camera *cam = uid_camera_map[cam_uid];
 
311
        Camera *old_cam = (Camera*)ob->data;
 
312
        ob->data = cam;
 
313
        old_cam->id.us--;
 
314
        if (old_cam->id.us == 0)
 
315
                free_libblock(&G.main->camera, old_cam);
 
316
        return ob;
 
317
}
 
318
 
 
319
Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
 
320
{
 
321
        const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
 
322
        if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {        
 
323
                fprintf(stderr, "Couldn't find lamp by UID.\n");
 
324
                return NULL;
 
325
        }
 
326
 
 
327
        Object *ob = bc_add_object(sce, OB_LAMP, NULL);
 
328
        Lamp *la = uid_lamp_map[lamp_uid];
 
329
        Lamp *old_lamp = (Lamp*)ob->data;
 
330
        ob->data = la;
 
331
        old_lamp->id.us--;
 
332
        if (old_lamp->id.us == 0)
 
333
                free_libblock(&G.main->lamp, old_lamp);
 
334
        return ob;
 
335
}
 
336
 
 
337
Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node)
 
338
{
 
339
        fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
 
340
 
 
341
        Object *obn = copy_object(source_ob);
 
342
        obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
 
343
        scene_add_base(sce, obn);
 
344
 
 
345
        if (instance_node) {
 
346
                anim_importer.read_node_transform(instance_node, obn);
 
347
                // if we also have a source_node (always ;), take its
 
348
                // transformation matrix and apply it to the newly instantiated
 
349
                // object to account for node hierarchy transforms in
 
350
                // .dae
 
351
                if (source_node) {
 
352
                        COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
 
353
                        COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order
2731
354
                        float mat[4][4];
2732
 
                        float matfra[4][4];
2733
 
 
2734
 
                        unit_m4(matfra);
2735
 
 
2736
 
                        // calc object-space mat
2737
 
                        evaluate_transform_at_frame(matfra, node, fra);
2738
 
 
2739
 
                        // for joints, we need a special matrix
2740
 
                        if (is_joint) {
2741
 
                                // special matrix: iR * M * iR_dae * R
2742
 
                                // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
2743
 
                                // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
2744
 
                                float temp[4][4], par[4][4];
2745
 
 
2746
 
                                // calc M
2747
 
                                calc_joint_parent_mat_rest(par, NULL, root, node);
2748
 
                                mul_m4_m4m4(temp, matfra, par);
2749
 
 
2750
 
                                // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
2751
 
 
2752
 
                                // calc special matrix
2753
 
                                mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
2754
 
                        }
2755
 
                        else {
2756
 
                                copy_m4_m4(mat, matfra);
2757
 
                        }
2758
 
 
2759
 
                        float val[4], rot[4], loc[3], scale[3];
2760
 
 
2761
 
                        switch (tm_type) {
2762
 
                        case COLLADAFW::Transformation::ROTATE:
2763
 
                                mat4_to_quat(val, mat);
2764
 
                                break;
2765
 
                        case COLLADAFW::Transformation::SCALE:
2766
 
                                mat4_to_size(val, mat);
2767
 
                                break;
2768
 
                        case COLLADAFW::Transformation::TRANSLATE:
2769
 
                                copy_v3_v3(val, mat[3]);
2770
 
                                break;
2771
 
                        case COLLADAFW::Transformation::MATRIX:
2772
 
                                mat4_to_quat(rot, mat);
2773
 
                                copy_v3_v3(loc, mat[3]);
2774
 
                                mat4_to_size(scale, mat);
2775
 
                                break;
2776
 
                        default:
2777
 
                                break;
2778
 
                        }
2779
 
 
2780
 
                        // add keys
2781
 
                        for (i = 0; i < totcu; i++) {
2782
 
                                if (is_matrix) {
2783
 
                                        if (i < 4)
2784
 
                                                add_bezt(newcu[i], fra, rot[i]);
2785
 
                                        else if (i < 7)
2786
 
                                                add_bezt(newcu[i], fra, loc[i - 4]);
2787
 
                                        else
2788
 
                                                add_bezt(newcu[i], fra, scale[i - 7]);
2789
 
                                }
2790
 
                                else {
2791
 
                                        add_bezt(newcu[i], fra, val[i]);
2792
 
                                }
2793
 
                        }
2794
 
 
2795
 
#ifdef ARMATURE_TEST
2796
 
                        if (is_joint) {
2797
 
                                switch (tm_type) {
2798
 
                                case COLLADAFW::Transformation::ROTATE:
2799
 
                                        mat4_to_quat(val, matfra);
2800
 
                                        break;
2801
 
                                case COLLADAFW::Transformation::SCALE:
2802
 
                                        mat4_to_size(val, matfra);
2803
 
                                        break;
2804
 
                                case COLLADAFW::Transformation::TRANSLATE:
2805
 
                                        copy_v3_v3(val, matfra[3]);
2806
 
                                        break;
2807
 
                                case MATRIX:
2808
 
                                        mat4_to_quat(rot, matfra);
2809
 
                                        copy_v3_v3(loc, matfra[3]);
2810
 
                                        mat4_to_size(scale, matfra);
2811
 
                                        break;
2812
 
                                default:
2813
 
                                        break;
2814
 
                                }
2815
 
 
2816
 
                                for (i = 0; i < totcu; i++) {
2817
 
                                        if (is_matrix) {
2818
 
                                                if (i < 4)
2819
 
                                                        add_bezt(job_curves[i], fra, rot[i]);
2820
 
                                                else if (i < 7)
2821
 
                                                        add_bezt(job_curves[i], fra, loc[i - 4]);
2822
 
                                                else
2823
 
                                                        add_bezt(job_curves[i], fra, scale[i - 7]);
2824
 
                                        }
2825
 
                                        else {
2826
 
                                                add_bezt(job_curves[i], fra, val[i]);
2827
 
                                        }
2828
 
                                }
2829
 
                        }
2830
 
#endif
2831
 
                }
2832
 
 
2833
 
                verify_adt_action((ID*)&ob->id, 1);
2834
 
 
2835
 
                ListBase *curves = &ob->adt->action->curves;
2836
 
 
2837
 
                // add curves
2838
 
                for (i = 0; i < totcu; i++) {
2839
 
                        if (is_joint)
2840
 
                                add_bone_fcurve(ob, node, newcu[i]);
2841
 
                        else
2842
 
                                BLI_addtail(curves, newcu[i]);
2843
 
 
2844
 
#ifdef ARMATURE_TEST
2845
 
                        if (is_joint)
2846
 
                                BLI_addtail(&job->adt->action->curves, job_curves[i]);
2847
 
#endif
2848
 
                }
2849
 
 
2850
 
                if (is_rotation || is_matrix) {
2851
 
                        if (is_joint) {
2852
 
                                bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
2853
 
                                chan->rotmode = ROT_MODE_QUAT;
2854
 
                        }
2855
 
                        else {
2856
 
                                ob->rotmode = ROT_MODE_QUAT;
2857
 
                        }
2858
 
                }
2859
 
 
2860
 
                return job;
2861
 
        }
2862
 
 
2863
 
        // internal, better make it private
2864
 
        // warning: evaluates only rotation
2865
 
        // prerequisites: animlist_map, curve_map
2866
 
        void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
2867
 
        {
2868
 
                const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2869
 
 
2870
 
                unit_m4(mat);
2871
 
 
2872
 
                for (unsigned int i = 0; i < tms.getCount(); i++) {
2873
 
                        COLLADAFW::Transformation *tm = tms[i];
2874
 
                        COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2875
 
                        float m[4][4];
2876
 
 
2877
 
                        unit_m4(m);
2878
 
 
2879
 
                        if (!evaluate_animation(tm, m, fra, node->getOriginalId().c_str())) {
2880
 
                                switch (type) {
2881
 
                                case COLLADAFW::Transformation::ROTATE:
2882
 
                                        dae_rotate_to_mat4(tm, m);
2883
 
                                        break;
2884
 
                                case COLLADAFW::Transformation::TRANSLATE:
2885
 
                                        dae_translate_to_mat4(tm, m);
2886
 
                                        break;
2887
 
                                case COLLADAFW::Transformation::SCALE:
2888
 
                                        dae_scale_to_mat4(tm, m);
2889
 
                                        break;
2890
 
                                case COLLADAFW::Transformation::MATRIX:
2891
 
                                        dae_matrix_to_mat4(tm, m);
2892
 
                                        break;
2893
 
                                default:
2894
 
                                        fprintf(stderr, "unsupported transformation type %d\n", type);
2895
 
                                }
2896
 
                        }
2897
 
 
2898
 
                        float temp[4][4];
2899
 
                        copy_m4_m4(temp, mat);
2900
 
 
2901
 
                        mul_m4_m4m4(mat, m, temp);
2902
 
                }
2903
 
        }
2904
 
 
2905
 
        // return true to indicate that mat contains a sane value
2906
 
        bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id)
2907
 
        {
2908
 
                const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2909
 
                COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2910
 
 
2911
 
                if (type != COLLADAFW::Transformation::ROTATE &&
2912
 
                    type != COLLADAFW::Transformation::SCALE &&
2913
 
                    type != COLLADAFW::Transformation::TRANSLATE &&
2914
 
                    type != COLLADAFW::Transformation::MATRIX) {
2915
 
                        fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
2916
 
                        return false;
2917
 
                }
2918
 
 
2919
 
                if (animlist_map.find(listid) == animlist_map.end())
2920
 
                        return false;
2921
 
 
2922
 
                const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2923
 
                const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2924
 
 
2925
 
                if (bindings.getCount()) {
2926
 
                        float vec[3];
2927
 
 
2928
 
                        bool is_scale = (type == COLLADAFW::Transformation::SCALE);
2929
 
                        bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
2930
 
 
2931
 
                        if (type == COLLADAFW::Transformation::SCALE)
2932
 
                                dae_scale_to_v3(tm, vec);
2933
 
                        else if (type == COLLADAFW::Transformation::TRANSLATE)
2934
 
                                dae_translate_to_v3(tm, vec);
2935
 
 
2936
 
                        for (unsigned int j = 0; j < bindings.getCount(); j++) {
2937
 
                                const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j];
2938
 
                                std::vector<FCurve*>& curves = curve_map[binding.animation];
2939
 
                                COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
2940
 
                                char path[100];
2941
 
 
2942
 
                                switch (type) {
2943
 
                                case COLLADAFW::Transformation::ROTATE:
2944
 
                                        BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j);
2945
 
                                        break;
2946
 
                                case COLLADAFW::Transformation::SCALE:
2947
 
                                        BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j);
2948
 
                                        break;
2949
 
                                case COLLADAFW::Transformation::TRANSLATE:
2950
 
                                        BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j);
2951
 
                                        break;
2952
 
                                case COLLADAFW::Transformation::MATRIX:
2953
 
                                        BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j);
2954
 
                                        break;
2955
 
                                default:
2956
 
                                        break;
2957
 
                                }
2958
 
 
2959
 
                                if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
2960
 
                                        fprintf(stderr, "%s: UNKNOWN animation class\n", path);
2961
 
                                        continue;
2962
 
                                }
2963
 
 
2964
 
                                if (type == COLLADAFW::Transformation::ROTATE) {
2965
 
                                        if (curves.size() != 1) {
2966
 
                                                fprintf(stderr, "expected 1 curve, got %u\n", curves.size());
2967
 
                                                return false;
2968
 
                                        }
2969
 
 
2970
 
                                        // TODO support other animclasses
2971
 
                                        if (animclass != COLLADAFW::AnimationList::ANGLE) {
2972
 
                                                fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
2973
 
                                                return false;
2974
 
                                        }
2975
 
 
2976
 
                                        COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
2977
 
                                        float ax[3] = {axis[0], axis[1], axis[2]};
2978
 
                                        float angle = evaluate_fcurve(curves[0], fra);
2979
 
                                        axis_angle_to_mat4(mat, ax, angle);
2980
 
 
2981
 
                                        return true;
2982
 
                                }
2983
 
                                else if (is_scale || is_translate) {
2984
 
                                        bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
2985
 
 
2986
 
                                        if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
2987
 
                                                if (is_xyz)
2988
 
                                                        fprintf(stderr, "%s: expected 3 curves, got %u\n", path, curves.size());
2989
 
                                                else
2990
 
                                                        fprintf(stderr, "%s: expected 1 curve, got %u\n", path, curves.size());
2991
 
                                                return false;
2992
 
                                        }
2993
 
                                        
2994
 
                                        switch (animclass) {
2995
 
                                        case COLLADAFW::AnimationList::POSITION_X:
2996
 
                                                vec[0] = evaluate_fcurve(curves[0], fra);
2997
 
                                                break;
2998
 
                                        case COLLADAFW::AnimationList::POSITION_Y:
2999
 
                                                vec[1] = evaluate_fcurve(curves[0], fra);
3000
 
                                                break;
3001
 
                                        case COLLADAFW::AnimationList::POSITION_Z:
3002
 
                                                vec[2] = evaluate_fcurve(curves[0], fra);
3003
 
                                                break;
3004
 
                                        case COLLADAFW::AnimationList::POSITION_XYZ:
3005
 
                                                vec[0] = evaluate_fcurve(curves[0], fra);
3006
 
                                                vec[1] = evaluate_fcurve(curves[1], fra);
3007
 
                                                vec[2] = evaluate_fcurve(curves[2], fra);
3008
 
                                                break;
3009
 
                                        default:
3010
 
                                                fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
3011
 
                                                break;
3012
 
                                        }
3013
 
                                }
3014
 
                                else if (type == COLLADAFW::Transformation::MATRIX) {
3015
 
                                        // for now, of matrix animation, support only the case when all values are packed into one animation
3016
 
                                        if (curves.size() != 16) {
3017
 
                                                fprintf(stderr, "%s: expected 16 curves, got %u\n", path, curves.size());
3018
 
                                                return false;
3019
 
                                        }
3020
 
 
3021
 
                                        COLLADABU::Math::Matrix4 matrix;
3022
 
                                        int i = 0, j = 0;
3023
 
 
3024
 
                                        for (std::vector<FCurve*>::iterator it = curves.begin(); it != curves.end(); it++) {
3025
 
                                                matrix.setElement(i, j, evaluate_fcurve(*it, fra));
3026
 
                                                j++;
3027
 
                                                if (j == 4) {
3028
 
                                                        i++;
3029
 
                                                        j = 0;
3030
 
                                                }
3031
 
                                        }
3032
 
 
3033
 
                                        COLLADAFW::Matrix tm(matrix);
3034
 
                                        dae_matrix_to_mat4(&tm, mat);
3035
 
 
3036
 
                                        return true;
3037
 
                                }
3038
 
                        }
3039
 
 
3040
 
                        if (is_scale)
3041
 
                                size_to_mat4(mat, vec);
3042
 
                        else
3043
 
                                copy_v3_v3(mat[3], vec);
3044
 
 
3045
 
                        return is_scale || is_translate;
3046
 
                }
3047
 
 
3048
 
                return false;
3049
 
        }
3050
 
 
3051
 
        // gives a world-space mat of joint at rest position
3052
 
        void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node)
3053
 
        {
3054
 
                // if bind mat is not available,
3055
 
                // use "current" node transform, i.e. all those tms listed inside <node>
3056
 
                if (!armature_importer->get_joint_bind_mat(mat, node)) {
3057
 
                        float par[4][4], m[4][4];
3058
 
 
3059
 
                        calc_joint_parent_mat_rest(par, NULL, root, node);
3060
 
                        get_node_mat(m, node, NULL, NULL);
3061
 
                        mul_m4_m4m4(mat, m, par);
3062
 
                }
3063
 
        }
3064
 
 
3065
 
        // gives a world-space mat, end's mat not included
3066
 
        bool calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end)
3067
 
        {
3068
 
                float m[4][4];
3069
 
 
3070
 
                if (node == end) {
3071
 
                        par ? copy_m4_m4(mat, par) : unit_m4(mat);
3072
 
                        return true;
3073
 
                }
3074
 
 
3075
 
                // use bind matrix if available or calc "current" world mat
3076
 
                if (!armature_importer->get_joint_bind_mat(m, node)) {
3077
 
                        if (par) {
3078
 
                                float temp[4][4];
3079
 
                                get_node_mat(temp, node, NULL, NULL);
3080
 
                                mul_m4_m4m4(m, temp, par);
3081
 
                        }
3082
 
                        else {
3083
 
                                get_node_mat(m, node, NULL, NULL);
3084
 
                        }
3085
 
                }
3086
 
 
3087
 
                COLLADAFW::NodePointerArray& children = node->getChildNodes();
 
355
                        for (int i = 0; i < 4; i++) {
 
356
                                for (int j = 0; j < 4; j++) {
 
357
                                        mat[i][j] = bmat4[i][j];
 
358
                                }
 
359
                        }
 
360
                        // calc new matrix and apply
 
361
                        mult_m4_m4m4(obn->obmat, obn->obmat, mat);
 
362
                        object_apply_mat4(obn, obn->obmat, 0, 0);
 
363
                }
 
364
        }
 
365
        else {
 
366
                anim_importer.read_node_transform(source_node, obn);
 
367
        }
 
368
 
 
369
        DAG_scene_sort(CTX_data_main(mContext), sce);
 
370
        DAG_ids_flush_update(CTX_data_main(mContext), 0);
 
371
 
 
372
        COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
 
373
        if (children.getCount()) {
3088
374
                for (unsigned int i = 0; i < children.getCount(); i++) {
3089
 
                        if (calc_joint_parent_mat_rest(mat, m, children[i], end))
3090
 
                                return true;
3091
 
                }
3092
 
 
3093
 
                return false;
3094
 
        }
3095
 
 
3096
 
#ifdef ARMATURE_TEST
3097
 
        Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job)
3098
 
        {
3099
 
                if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
3100
 
                        Object *job = add_object(scene, OB_EMPTY);
3101
 
 
3102
 
                        rename_id((ID*)&job->id, (char*)get_joint_name(node));
3103
 
 
3104
 
                        job->lay = object_in_scene(job, scene)->lay = 2;
3105
 
 
3106
 
                        mul_v3_fl(job->size, 0.5f);
3107
 
                        job->recalc |= OB_RECALC_OB;
3108
 
 
3109
 
                        verify_adt_action((ID*)&job->id, 1);
3110
 
 
3111
 
                        job->rotmode = ROT_MODE_QUAT;
3112
 
 
3113
 
                        float mat[4][4];
3114
 
                        get_joint_rest_mat(mat, root, node);
3115
 
 
3116
 
                        if (par_job) {
3117
 
                                float temp[4][4], ipar[4][4];
3118
 
                                invert_m4_m4(ipar, par_job->obmat);
3119
 
                                copy_m4_m4(temp, mat);
3120
 
                                mul_m4_m4m4(mat, temp, ipar);
3121
 
                        }
3122
 
 
3123
 
                        TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size);
3124
 
 
3125
 
                        if (par_job) {
3126
 
                                job->parent = par_job;
3127
 
 
3128
 
                                par_job->recalc |= OB_RECALC_OB;
3129
 
                                job->parsubstr[0] = 0;
3130
 
                        }
3131
 
 
3132
 
                        where_is_object(scene, job);
3133
 
 
3134
 
                        // after parenting and layer change
3135
 
                        DAG_scene_sort(scene);
3136
 
 
3137
 
                        joint_objects[node->getUniqueId()] = job;
3138
 
                }
3139
 
 
3140
 
                return joint_objects[node->getUniqueId()];
3141
 
        }
3142
 
#endif
3143
 
 
3144
 
#if 0
3145
 
        // recursively evaluates joint tree until end is found, mat then is world-space matrix of end
3146
 
        // mat must be identity on enter, node must be root
3147
 
        bool evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra)
3148
 
        {
3149
 
                float m[4][4];
3150
 
                if (par) {
3151
 
                        float temp[4][4];
3152
 
                        evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f);
3153
 
                        mul_m4_m4m4(m, temp, par);
3154
 
                }
3155
 
                else {
3156
 
                        evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f);
3157
 
                }
3158
 
 
3159
 
                if (node == end) {
3160
 
                        copy_m4_m4(mat, m);
3161
 
                        return true;
3162
 
                }
3163
 
                else {
3164
 
                        COLLADAFW::NodePointerArray& children = node->getChildNodes();
3165
 
                        for (int i = 0; i < children.getCount(); i++) {
3166
 
                                if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra))
3167
 
                                        return true;
3168
 
                        }
3169
 
                }
3170
 
 
3171
 
                return false;
3172
 
        }
3173
 
#endif
3174
 
 
3175
 
        void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
3176
 
        {
3177
 
                const char *bone_name = get_joint_name(node);
3178
 
                bAction *act = ob->adt->action;
3179
 
                                
3180
 
                /* try to find group */
3181
 
                bActionGroup *grp = action_groups_find_named(act, bone_name);
3182
 
 
3183
 
                /* no matching groups, so add one */
3184
 
                if (grp == NULL) {
3185
 
                        /* Add a new group, and make it active */
3186
 
                        grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
3187
 
                                                
3188
 
                        grp->flag = AGRP_SELECTED;
3189
 
                        BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
3190
 
                                                
3191
 
                        BLI_addtail(&act->groups, grp);
3192
 
                        BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
3193
 
                }
3194
 
                                        
3195
 
                /* add F-Curve to group */
3196
 
                action_groups_add_channel(act, grp, fcu);
3197
 
        }
3198
 
 
3199
 
        void add_bezt(FCurve *fcu, float fra, float value)
3200
 
        {
3201
 
                BezTriple bez;
3202
 
                memset(&bez, 0, sizeof(BezTriple));
3203
 
                bez.vec[1][0] = fra;
3204
 
                bez.vec[1][1] = value;
3205
 
                bez.ipo = U.ipo_new; /* use default interpolation mode here... */
3206
 
                bez.f1 = bez.f2 = bez.f3 = SELECT;
3207
 
                bez.h1 = bez.h2 = HD_AUTO;
3208
 
                insert_bezt_fcurve(fcu, &bez, 0);
3209
 
                calchandles_fcurve(fcu);
3210
 
        }
3211
 
};
3212
 
 
3213
 
/*
3214
 
 
3215
 
  COLLADA Importer limitations:
3216
 
 
3217
 
  - no multiple scene import, all objects are added to active scene
3218
 
 
3219
 
 */
3220
 
/** Class that needs to be implemented by a writer. 
3221
 
        IMPORTANT: The write functions are called in arbitrary order.*/
3222
 
class Writer: public COLLADAFW::IWriter
3223
 
{
3224
 
private:
3225
 
        std::string mFilename;
3226
 
        
3227
 
        bContext *mContext;
3228
 
 
3229
 
        UnitConverter unit_converter;
3230
 
        ArmatureImporter armature_importer;
3231
 
        MeshImporter mesh_importer;
3232
 
        AnimationImporter anim_importer;
3233
 
 
3234
 
        std::map<COLLADAFW::UniqueId, Image*> uid_image_map;
3235
 
        std::map<COLLADAFW::UniqueId, Material*> uid_material_map;
3236
 
        std::map<COLLADAFW::UniqueId, Material*> uid_effect_map;
3237
 
        std::map<COLLADAFW::UniqueId, Camera*> uid_camera_map;
3238
 
        std::map<COLLADAFW::UniqueId, Lamp*> uid_lamp_map;
3239
 
        std::map<Material*, TexIndexTextureArrayMap> material_texture_mapping_map;
3240
 
        std::map<COLLADAFW::UniqueId, Object*> object_map;
3241
 
        std::vector<const COLLADAFW::VisualScene*> vscenes;
3242
 
 
3243
 
        std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> root_map; // find root joint by child joint uid, for bone tree evaluation during resampling
3244
 
 
3245
 
        // animation
3246
 
        // std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > uid_fcurve_map;
3247
 
        // Nodes don't share AnimationLists (Arystan)
3248
 
        // std::map<COLLADAFW::UniqueId, Animation> uid_animated_map; // AnimationList->uniqueId to AnimatedObject map
3249
 
 
3250
 
public:
3251
 
 
3252
 
        /** Constructor. */
3253
 
        Writer(bContext *C, const char *filename) : mFilename(filename), mContext(C),
3254
 
                                                                                                armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
3255
 
                                                                                                mesh_importer(&armature_importer, CTX_data_scene(C)),
3256
 
                                                                                                anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) {}
3257
 
 
3258
 
        /** Destructor. */
3259
 
        ~Writer() {}
3260
 
 
3261
 
        bool write()
3262
 
        {
3263
 
                COLLADASaxFWL::Loader loader;
3264
 
                COLLADAFW::Root root(&loader, this);
3265
 
 
3266
 
                // XXX report error
3267
 
                if (!root.loadDocument(mFilename))
3268
 
                        return false;
3269
 
 
3270
 
                return true;
3271
 
        }
3272
 
 
3273
 
        /** This method will be called if an error in the loading process occurred and the loader cannot
3274
 
                continue to load. The writer should undo all operations that have been performed.
3275
 
                @param errorMessage A message containing informations about the error that occurred.
3276
 
        */
3277
 
        virtual void cancel(const COLLADAFW::String& errorMessage)
3278
 
        {
3279
 
                // TODO: if possible show error info
3280
 
                //
3281
 
                // Should we get rid of invisible Meshes that were created so far
3282
 
                // or maybe create objects at coordinate space origin?
3283
 
                //
3284
 
                // The latter sounds better.
3285
 
        }
3286
 
 
3287
 
        /** This is the method called. The writer hast to prepare to receive data.*/
3288
 
        virtual void start()
3289
 
        {
3290
 
        }
3291
 
 
3292
 
        /** This method is called after the last write* method. No other methods will be called after this.*/
3293
 
        virtual void finish()
3294
 
        {
3295
 
#if 0
3296
 
                armature_importer.fix_animation();
3297
 
#endif
3298
 
 
3299
 
                for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
3300
 
                        const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
3301
 
 
3302
 
                        for (unsigned int i = 0; i < roots.getCount(); i++)
3303
 
                                translate_anim_recursive(roots[i]);
3304
 
                }
3305
 
 
3306
 
        }
3307
 
 
3308
 
 
3309
 
        void translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
3310
 
        {
3311
 
                if (par && par->getType() == COLLADAFW::Node::JOINT) {
3312
 
                        // par is root if there's no corresp. key in root_map
3313
 
                        if (root_map.find(par->getUniqueId()) == root_map.end())
3314
 
                                root_map[node->getUniqueId()] = par;
3315
 
                        else
3316
 
                                root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
3317
 
                }
3318
 
 
3319
 
                COLLADAFW::Transformation::TransformationType types[] = {
3320
 
                        COLLADAFW::Transformation::ROTATE,
3321
 
                        COLLADAFW::Transformation::SCALE,
3322
 
                        COLLADAFW::Transformation::TRANSLATE,
3323
 
                        COLLADAFW::Transformation::MATRIX
3324
 
                };
3325
 
 
3326
 
                unsigned int i;
3327
 
                Object *ob;
3328
 
 
3329
 
                for (i = 0; i < 4; i++)
3330
 
                        ob = anim_importer.translate_animation(node, object_map, root_map, types[i]);
3331
 
 
3332
 
                COLLADAFW::NodePointerArray &children = node->getChildNodes();
3333
 
                for (i = 0; i < children.getCount(); i++) {
3334
 
                        translate_anim_recursive(children[i], node, ob);
3335
 
                }
3336
 
        }
3337
 
 
3338
 
        /** When this method is called, the writer must write the global document asset.
3339
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3340
 
        virtual bool writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) 
3341
 
        {
3342
 
                // XXX take up_axis, unit into account
3343
 
                // COLLADAFW::FileInfo::Unit unit = asset->getUnit();
3344
 
                // COLLADAFW::FileInfo::UpAxisType upAxis = asset->getUpAxisType();
3345
 
                unit_converter.read_asset(asset);
3346
 
 
3347
 
                return true;
3348
 
        }
3349
 
 
3350
 
        /** When this method is called, the writer must write the scene.
3351
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3352
 
        virtual bool writeScene ( const COLLADAFW::Scene* scene ) 
3353
 
        {
3354
 
                // XXX could store the scene id, but do nothing for now
3355
 
                return true;
3356
 
        }
3357
 
        Object *create_camera_object(COLLADAFW::InstanceCamera *camera, Object *ob, Scene *sce)
3358
 
        {
3359
 
                const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
3360
 
                if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {     
3361
 
                        fprintf(stderr, "Couldn't find camera by UID. \n");
3362
 
                        return NULL;
3363
 
                }
3364
 
                ob = add_object(sce, OB_CAMERA);
3365
 
                Camera *cam = uid_camera_map[cam_uid];
3366
 
                Camera *old_cam = (Camera*)ob->data;
3367
 
                old_cam->id.us--;
3368
 
                ob->data = cam;
3369
 
                if (old_cam->id.us == 0) free_libblock(&G.main->camera, old_cam);
3370
 
                return ob;
3371
 
        }
3372
 
        
3373
 
        Object *create_lamp_object(COLLADAFW::InstanceLight *lamp, Object *ob, Scene *sce)
3374
 
        {
3375
 
                const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
3376
 
                if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {        
3377
 
                        fprintf(stderr, "Couldn't find lamp by UID. \n");
3378
 
                        return NULL;
3379
 
                }
3380
 
                ob = add_object(sce, OB_LAMP);
3381
 
                Lamp *la = uid_lamp_map[lamp_uid];
3382
 
                Lamp *old_lamp = (Lamp*)ob->data;
3383
 
                old_lamp->id.us--;
3384
 
                ob->data = la;
3385
 
                if (old_lamp->id.us == 0) free_libblock(&G.main->lamp, old_lamp);
3386
 
                return ob;
3387
 
        }
3388
 
        
3389
 
        void write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par)
3390
 
        {
3391
 
                Object *ob = NULL;
3392
 
                bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
3393
 
 
3394
 
                if (is_joint) {
3395
 
                        armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par);
3396
 
                }
3397
 
                else {
3398
 
                        COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
3399
 
                        COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
3400
 
                        COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
3401
 
                        COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
3402
 
                        COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
3403
 
 
3404
 
                        // XXX linking object with the first <instance_geometry>, though a node may have more of them...
3405
 
                        // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
3406
 
                        // <instance_geometry>
3407
 
                        if (geom.getCount() != 0) {
3408
 
                                ob = mesh_importer.create_mesh_object(node, geom[0], false, uid_material_map,
3409
 
                                                                                                          material_texture_mapping_map);
3410
 
                        }
3411
 
                        else if (camera.getCount() != 0) {
3412
 
                                ob = create_camera_object(camera[0], ob, sce);
3413
 
                        }
3414
 
                        else if (lamp.getCount() != 0) {
3415
 
                                ob = create_lamp_object(lamp[0], ob, sce);
3416
 
                        }
3417
 
                        else if (controller.getCount() != 0) {
3418
 
                                COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[0];
3419
 
                                ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
3420
 
                        }
3421
 
                        // XXX instance_node is not supported yet
3422
 
                        else if (inst_node.getCount() != 0) {
3423
 
                                return;
3424
 
                        }
3425
 
                        // if node is empty - create empty object
3426
 
                        // XXX empty node may not mean it is empty object, not sure about this
3427
 
                        else {
3428
 
                                ob = add_object(sce, OB_EMPTY);
3429
 
                                rename_id(&ob->id, (char*)node->getOriginalId().c_str());
3430
 
                        }
3431
 
                        
3432
 
                        // check if object is not NULL
3433
 
                        if (!ob) return;
3434
 
 
3435
 
                        object_map[node->getUniqueId()] = ob;                   
3436
 
                }
3437
 
 
3438
 
                anim_importer.read_node_transform(node, ob);
3439
 
 
3440
 
                if (!is_joint) {
3441
 
                        // if par was given make this object child of the previous 
3442
 
                        if (par && ob)
3443
 
                                set_parent(ob, par, mContext);
3444
 
                }
3445
 
 
3446
 
                // if node has child nodes write them
3447
 
                COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
3448
 
                for (unsigned int i = 0; i < child_nodes.getCount(); i++) {     
3449
 
                        write_node(child_nodes[i], node, sce, ob);
3450
 
                }
3451
 
        }
3452
 
 
3453
 
        /** When this method is called, the writer must write the entire visual scene.
3454
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3455
 
        virtual bool writeVisualScene ( const COLLADAFW::VisualScene* visualScene ) 
3456
 
        {
3457
 
                // this method called on post process after writeGeometry, writeMaterial, etc.
3458
 
 
3459
 
                // for each <node> in <visual_scene>:
3460
 
                // create an Object
3461
 
                // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
3462
 
 
3463
 
                // update: since we cannot link a Mesh with Object in
3464
 
                // writeGeometry because <geometry> does not reference <node>,
3465
 
                // we link Objects with Meshes here
3466
 
 
3467
 
                vscenes.push_back(visualScene);
3468
 
 
3469
 
                // TODO: create a new scene except the selected <visual_scene> - use current blender
3470
 
                // scene for it
3471
 
                Scene *sce = CTX_data_scene(mContext);
3472
 
                const COLLADAFW::NodePointerArray& roots = visualScene->getRootNodes();
3473
 
 
3474
 
                for (unsigned int i = 0; i < roots.getCount(); i++) {
3475
 
                        write_node(roots[i], NULL, sce, NULL);
3476
 
                }
3477
 
 
3478
 
                armature_importer.make_armatures(mContext);
3479
 
                
3480
 
                return true;
3481
 
        }
3482
 
 
3483
 
        /** When this method is called, the writer must handle all nodes contained in the 
3484
 
                library nodes.
3485
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3486
 
        virtual bool writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes ) 
3487
 
        {
3488
 
                return true;
3489
 
        }
3490
 
 
3491
 
        /** When this method is called, the writer must write the geometry.
3492
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3493
 
        virtual bool writeGeometry ( const COLLADAFW::Geometry* geom ) 
3494
 
        {
3495
 
                return mesh_importer.write_geometry(geom);
3496
 
        }
3497
 
 
3498
 
        /** When this method is called, the writer must write the material.
3499
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3500
 
        virtual bool writeMaterial( const COLLADAFW::Material* cmat ) 
3501
 
        {
3502
 
                const std::string& str_mat_id = cmat->getOriginalId();
3503
 
                Material *ma = add_material((char*)str_mat_id.c_str());
3504
 
                
3505
 
                this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
3506
 
                this->uid_material_map[cmat->getUniqueId()] = ma;
3507
 
                
3508
 
                return true;
3509
 
        }
3510
 
        
3511
 
        // create mtex, create texture, set texture image
3512
 
        MTex *create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
3513
 
                                                 int i, TexIndexTextureArrayMap &texindex_texarray_map)
3514
 
        {
3515
 
                COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
3516
 
                COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
3517
 
                        
3518
 
                const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
3519
 
                
3520
 
                if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
3521
 
                        fprintf(stderr, "Couldn't find an image by UID.\n");
3522
 
                        return NULL;
3523
 
                }
3524
 
                
3525
 
                ma->mtex[i] = add_mtex();
3526
 
                ma->mtex[i]->texco = TEXCO_UV;
3527
 
                ma->mtex[i]->tex = add_texture("Texture");
3528
 
                ma->mtex[i]->tex->type = TEX_IMAGE;
3529
 
                ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
3530
 
                ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
3531
 
                
3532
 
                texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
3533
 
                
3534
 
                return ma->mtex[i];
3535
 
        }
3536
 
        
3537
 
        void write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
3538
 
        {
3539
 
                COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
3540
 
                
3541
 
                // blinn
3542
 
                if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
3543
 
                        ma->spec_shader = MA_SPEC_BLINN;
3544
 
                        ma->spec = ef->getShininess().getFloatValue();
3545
 
                }
3546
 
                // phong
3547
 
                else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
3548
 
                        ma->spec_shader = MA_SPEC_PHONG;
3549
 
                        // XXX setting specular hardness instead of specularity intensity
3550
 
                        ma->har = ef->getShininess().getFloatValue() * 4;
3551
 
                }
3552
 
                // lambert
3553
 
                else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
3554
 
                        ma->diff_shader = MA_DIFF_LAMBERT;
3555
 
                }
3556
 
                // default - lambert
3557
 
                else {
3558
 
                        ma->diff_shader = MA_DIFF_LAMBERT;
3559
 
                        fprintf(stderr, "Current shader type is not supported.\n");
3560
 
                }
3561
 
                // reflectivity
3562
 
                ma->ray_mirror = ef->getReflectivity().getFloatValue();
3563
 
                // index of refraction
3564
 
                ma->ang = ef->getIndexOfRefraction().getFloatValue();
3565
 
                
3566
 
                int i = 0;
3567
 
                COLLADAFW::Color col;
3568
 
                MTex *mtex = NULL;
3569
 
                TexIndexTextureArrayMap texindex_texarray_map;
3570
 
                
3571
 
                // DIFFUSE
3572
 
                // color
3573
 
                if (ef->getDiffuse().isColor()) {
3574
 
                        col = ef->getDiffuse().getColor();
3575
 
                        ma->r = col.getRed();
3576
 
                        ma->g = col.getGreen();
3577
 
                        ma->b = col.getBlue();
3578
 
                }
3579
 
                // texture
3580
 
                else if (ef->getDiffuse().isTexture()) {
3581
 
                        COLLADAFW::Texture ctex = ef->getDiffuse().getTexture(); 
3582
 
                        mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3583
 
                        if (mtex != NULL) {
3584
 
                                mtex->mapto = MAP_COL;
3585
 
                                ma->texact = (int)i;
3586
 
                                i++;
3587
 
                        }
3588
 
                }
3589
 
                // AMBIENT
3590
 
                // color
3591
 
                if (ef->getAmbient().isColor()) {
3592
 
                        col = ef->getAmbient().getColor();
3593
 
                        ma->ambr = col.getRed();
3594
 
                        ma->ambg = col.getGreen();
3595
 
                        ma->ambb = col.getBlue();
3596
 
                }
3597
 
                // texture
3598
 
                else if (ef->getAmbient().isTexture()) {
3599
 
                        COLLADAFW::Texture ctex = ef->getAmbient().getTexture(); 
3600
 
                        mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3601
 
                        if (mtex != NULL) {
3602
 
                                mtex->mapto = MAP_AMB; 
3603
 
                                i++;
3604
 
                        }
3605
 
                }
3606
 
                // SPECULAR
3607
 
                // color
3608
 
                if (ef->getSpecular().isColor()) {
3609
 
                        col = ef->getSpecular().getColor();
3610
 
                        ma->specr = col.getRed();
3611
 
                        ma->specg = col.getGreen();
3612
 
                        ma->specb = col.getBlue();
3613
 
                }
3614
 
                // texture
3615
 
                else if (ef->getSpecular().isTexture()) {
3616
 
                        COLLADAFW::Texture ctex = ef->getSpecular().getTexture(); 
3617
 
                        mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3618
 
                        if (mtex != NULL) {
3619
 
                                mtex->mapto = MAP_SPEC; 
3620
 
                                i++;
3621
 
                        }
3622
 
                }
3623
 
                // REFLECTIVE
3624
 
                // color
3625
 
                if (ef->getReflective().isColor()) {
3626
 
                        col = ef->getReflective().getColor();
3627
 
                        ma->mirr = col.getRed();
3628
 
                        ma->mirg = col.getGreen();
3629
 
                        ma->mirb = col.getBlue();
3630
 
                }
3631
 
                // texture
3632
 
                else if (ef->getReflective().isTexture()) {
3633
 
                        COLLADAFW::Texture ctex = ef->getReflective().getTexture(); 
3634
 
                        mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3635
 
                        if (mtex != NULL) {
3636
 
                                mtex->mapto = MAP_REF; 
3637
 
                                i++;
3638
 
                        }
3639
 
                }
3640
 
                // EMISSION
3641
 
                // color
3642
 
                if (ef->getEmission().isColor()) {
3643
 
                        // XXX there is no emission color in blender
3644
 
                        // but I am not sure
3645
 
                }
3646
 
                // texture
3647
 
                else if (ef->getEmission().isTexture()) {
3648
 
                        COLLADAFW::Texture ctex = ef->getEmission().getTexture(); 
3649
 
                        mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3650
 
                        if (mtex != NULL) {
3651
 
                                mtex->mapto = MAP_EMIT; 
3652
 
                                i++;
3653
 
                        }
3654
 
                }
3655
 
                // TRANSPARENT
3656
 
                // color
3657
 
        //      if (ef->getOpacity().isColor()) {
 
375
                        COLLADAFW::Node *child_node = children[i];
 
376
                        const COLLADAFW::UniqueId& child_id = child_node->getUniqueId();
 
377
                        if (object_map.find(child_id) == object_map.end())
 
378
                                continue;
 
379
                        COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
 
380
                        Object *new_child = NULL;
 
381
                        if (inodes.getCount()) { // \todo loop through instance nodes
 
382
                                const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId();
 
383
                                new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, is_library_node);
 
384
                        }
 
385
                        else {
 
386
                                new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, is_library_node);
 
387
                        }
 
388
                        bc_set_parent(new_child, obn, mContext, true);
 
389
 
 
390
                        if (is_library_node)
 
391
                                libnode_ob.push_back(new_child);
 
392
                }
 
393
        }
 
394
 
 
395
        return obn;
 
396
}
 
397
 
 
398
void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
 
399
{
 
400
        Object *ob = NULL;
 
401
        bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
 
402
        bool read_transform = true;
 
403
 
 
404
        if (is_joint) {
 
405
                if ( par ) {
 
406
                Object * empty = par;
 
407
                par = bc_add_object(sce, OB_ARMATURE, NULL);
 
408
                bc_set_parent(par,empty->parent, mContext);
 
409
                //remove empty : todo
 
410
                object_map[parent_node->getUniqueId()] = par;
 
411
                }
 
412
                armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce);
 
413
        }
 
414
        else {
 
415
                COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
 
416
                COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
 
417
                COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
 
418
                COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
 
419
                COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
 
420
                size_t geom_done = 0;
 
421
                size_t camera_done = 0;
 
422
                size_t lamp_done = 0;
 
423
                size_t controller_done = 0;
 
424
                size_t inst_done = 0;
 
425
 
 
426
                // XXX linking object with the first <instance_geometry>, though a node may have more of them...
 
427
                // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
 
428
                // <instance_geometry>
 
429
                while (geom_done < geom.getCount()) {
 
430
                        ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
 
431
                                                                                                  material_texture_mapping_map);
 
432
                        ++geom_done;
 
433
                }
 
434
                while (camera_done < camera.getCount()) {
 
435
                        ob = create_camera_object(camera[camera_done], sce);
 
436
                        ++camera_done;
 
437
                }
 
438
                while (lamp_done < lamp.getCount()) {
 
439
                        ob = create_lamp_object(lamp[lamp_done], sce);
 
440
                        ++lamp_done;
 
441
                }
 
442
                while (controller_done < controller.getCount()) {
 
443
                        COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done];
 
444
                        ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
 
445
                        ++controller_done;
 
446
                }
 
447
                // XXX instance_node is not supported yet
 
448
                while (inst_done < inst_node.getCount()) {
 
449
                        const COLLADAFW::UniqueId& node_id = inst_node[inst_done]->getInstanciatedObjectId();
 
450
                        if (object_map.find(node_id) == object_map.end()) {
 
451
                                fprintf(stderr, "Cannot find object for node referenced by <instance_node name=\"%s\">.\n", inst_node[inst_done]->getName().c_str());
 
452
                                ob = NULL;
 
453
                        }
 
454
                        else {
 
455
                                Object *source_ob = object_map[node_id];
 
456
                                COLLADAFW::Node *source_node = node_map[node_id];
 
457
 
 
458
                                ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
 
459
                        }
 
460
                        ++inst_done;
 
461
 
 
462
                        read_transform = false;
 
463
                }
 
464
                // if node is empty - create empty object
 
465
                // XXX empty node may not mean it is empty object, not sure about this
 
466
                if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
 
467
                        ob = bc_add_object(sce, OB_EMPTY, NULL);
 
468
                }
 
469
                
 
470
                // XXX: if there're multiple instances, only one is stored
 
471
 
 
472
                if (!ob) return;
 
473
                
 
474
                std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
 
475
                rename_id(&ob->id, (char*)nodename.c_str());
 
476
 
 
477
                object_map[node->getUniqueId()] = ob;
 
478
                node_map[node->getUniqueId()] = node;
 
479
 
 
480
                if (is_library_node)
 
481
                        libnode_ob.push_back(ob);
 
482
        }
 
483
 
 
484
        if (read_transform)
 
485
                anim_importer.read_node_transform(node, ob); // overwrites location set earlier
 
486
 
 
487
        if (!is_joint) {
 
488
                // if par was given make this object child of the previous 
 
489
                if (par && ob)
 
490
                        bc_set_parent(ob, par, mContext);
 
491
        }
 
492
 
 
493
        // if node has child nodes write them
 
494
        COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
 
495
        for (unsigned int i = 0; i < child_nodes.getCount(); i++) {     
 
496
                write_node(child_nodes[i], node, sce, ob, is_library_node);
 
497
        }
 
498
}
 
499
 
 
500
/** When this method is called, the writer must write the entire visual scene.
 
501
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
502
bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene ) 
 
503
{
 
504
        if (mImportStage!=General)
 
505
                return true;
 
506
                
 
507
        // this method called on post process after writeGeometry, writeMaterial, etc.
 
508
 
 
509
        // for each <node> in <visual_scene>:
 
510
        // create an Object
 
511
        // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
 
512
 
 
513
        // update: since we cannot link a Mesh with Object in
 
514
        // writeGeometry because <geometry> does not reference <node>,
 
515
        // we link Objects with Meshes here
 
516
 
 
517
        vscenes.push_back(visualScene);
 
518
        
 
519
        return true;
 
520
}
 
521
 
 
522
/** When this method is called, the writer must handle all nodes contained in the 
 
523
        library nodes.
 
524
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
525
bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes ) 
 
526
{
 
527
        if (mImportStage!=General)
 
528
                return true;
 
529
                
 
530
        Scene *sce = CTX_data_scene(mContext);
 
531
 
 
532
        const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes();
 
533
 
 
534
        for (unsigned int i = 0; i < nodes.getCount(); i++) {
 
535
                write_node(nodes[i], NULL, sce, NULL, true);
 
536
        }
 
537
 
 
538
        return true;
 
539
}
 
540
 
 
541
/** When this method is called, the writer must write the geometry.
 
542
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
543
bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom ) 
 
544
{
 
545
        if (mImportStage!=General)
 
546
                return true;
 
547
                
 
548
        return mesh_importer.write_geometry(geom);
 
549
}
 
550
 
 
551
/** When this method is called, the writer must write the material.
 
552
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
553
bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat ) 
 
554
{
 
555
        if (mImportStage!=General)
 
556
                return true;
 
557
                
 
558
        const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
 
559
        Material *ma = add_material((char*)str_mat_id.c_str());
 
560
        
 
561
        this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
 
562
        this->uid_material_map[cmat->getUniqueId()] = ma;
 
563
        
 
564
        return true;
 
565
}
 
566
 
 
567
// create mtex, create texture, set texture image
 
568
MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
 
569
                                         int i, TexIndexTextureArrayMap &texindex_texarray_map)
 
570
{
 
571
        COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
 
572
        COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
 
573
                
 
574
        const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
 
575
        
 
576
        if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
 
577
                fprintf(stderr, "Couldn't find an image by UID.\n");
 
578
                return NULL;
 
579
        }
 
580
        
 
581
        ma->mtex[i] = add_mtex();
 
582
        ma->mtex[i]->texco = TEXCO_UV;
 
583
        ma->mtex[i]->tex = add_texture("Texture");
 
584
        ma->mtex[i]->tex->type = TEX_IMAGE;
 
585
        ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
 
586
        ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
 
587
        
 
588
        texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
 
589
        
 
590
        return ma->mtex[i];
 
591
}
 
592
 
 
593
void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
 
594
{
 
595
        COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
 
596
        
 
597
        // blinn
 
598
        if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
 
599
                ma->spec_shader = MA_SPEC_BLINN;
 
600
                ma->spec = ef->getShininess().getFloatValue();
 
601
        }
 
602
        // phong
 
603
        else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
 
604
                ma->spec_shader = MA_SPEC_PHONG;
 
605
                ma->har = ef->getShininess().getFloatValue();
 
606
        }
 
607
        // lambert
 
608
        else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
 
609
                ma->diff_shader = MA_DIFF_LAMBERT;
 
610
        }
 
611
        // default - lambert
 
612
        else {
 
613
                ma->diff_shader = MA_DIFF_LAMBERT;
 
614
                fprintf(stderr, "Current shader type is not supported, default to lambert.\n");
 
615
        }
 
616
        // reflectivity
 
617
        ma->ray_mirror = ef->getReflectivity().getFloatValue();
 
618
        // index of refraction
 
619
        ma->ang = ef->getIndexOfRefraction().getFloatValue();
 
620
        
 
621
        int i = 0;
 
622
        COLLADAFW::Color col;
 
623
        MTex *mtex = NULL;
 
624
        TexIndexTextureArrayMap texindex_texarray_map;
 
625
        
 
626
        // DIFFUSE
 
627
        // color
 
628
        if (ef->getDiffuse().isColor()) {
 
629
                col = ef->getDiffuse().getColor();
 
630
                ma->r = col.getRed();
 
631
                ma->g = col.getGreen();
 
632
                ma->b = col.getBlue();
 
633
        }
 
634
        // texture
 
635
        else if (ef->getDiffuse().isTexture()) {
 
636
                COLLADAFW::Texture ctex = ef->getDiffuse().getTexture(); 
 
637
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
638
                if (mtex != NULL) {
 
639
                        mtex->mapto = MAP_COL;
 
640
                        ma->texact = (int)i;
 
641
                        i++;
 
642
                }
 
643
        }
 
644
        // AMBIENT
 
645
        // color
 
646
        if (ef->getAmbient().isColor()) {
 
647
                col = ef->getAmbient().getColor();
 
648
                ma->ambr = col.getRed();
 
649
                ma->ambg = col.getGreen();
 
650
                ma->ambb = col.getBlue();
 
651
        }
 
652
        // texture
 
653
        else if (ef->getAmbient().isTexture()) {
 
654
                COLLADAFW::Texture ctex = ef->getAmbient().getTexture(); 
 
655
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
656
                if (mtex != NULL) {
 
657
                        mtex->mapto = MAP_AMB; 
 
658
                        i++;
 
659
                }
 
660
        }
 
661
        // SPECULAR
 
662
        // color
 
663
        if (ef->getSpecular().isColor()) {
 
664
                col = ef->getSpecular().getColor();
 
665
                ma->specr = col.getRed();
 
666
                ma->specg = col.getGreen();
 
667
                ma->specb = col.getBlue();
 
668
        }
 
669
        // texture
 
670
        else if (ef->getSpecular().isTexture()) {
 
671
                COLLADAFW::Texture ctex = ef->getSpecular().getTexture(); 
 
672
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
673
                if (mtex != NULL) {
 
674
                        mtex->mapto = MAP_SPEC; 
 
675
                        i++;
 
676
                }
 
677
        }
 
678
        // REFLECTIVE
 
679
        // color
 
680
        if (ef->getReflective().isColor()) {
 
681
                col = ef->getReflective().getColor();
 
682
                ma->mirr = col.getRed();
 
683
                ma->mirg = col.getGreen();
 
684
                ma->mirb = col.getBlue();
 
685
        }
 
686
        // texture
 
687
        else if (ef->getReflective().isTexture()) {
 
688
                COLLADAFW::Texture ctex = ef->getReflective().getTexture(); 
 
689
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
690
                if (mtex != NULL) {
 
691
                        mtex->mapto = MAP_REF; 
 
692
                        i++;
 
693
                }
 
694
        }
 
695
        // EMISSION
 
696
        // color
 
697
        if (ef->getEmission().isColor()) {
 
698
                // XXX there is no emission color in blender
 
699
                // but I am not sure
 
700
        }
 
701
        // texture
 
702
        else if (ef->getEmission().isTexture()) {
 
703
                COLLADAFW::Texture ctex = ef->getEmission().getTexture(); 
 
704
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
705
                if (mtex != NULL) {
 
706
                        mtex->mapto = MAP_EMIT; 
 
707
                        i++;
 
708
                }
 
709
        }
 
710
        
 
711
        if (ef->getOpacity().isTexture()) {
 
712
                COLLADAFW::Texture ctex = ef->getOpacity().getTexture();
 
713
                mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 
714
                if (mtex != NULL) {
 
715
                        mtex->mapto = MAP_ALPHA;
 
716
                        mtex->tex->imaflag |= TEX_USEALPHA;
 
717
                        i++;
 
718
                        ma->spectra = ma->alpha = 0;
 
719
                        ma->mode |= MA_ZTRANSP|MA_TRANSP;
 
720
                }
 
721
        }
 
722
        // TRANSPARENT
 
723
        // color
 
724
//      if (ef->getOpacity().isColor()) {
3658
725
//                      // XXX don't know what to do here
3659
726
//              }
3660
727
//              // texture
3666
733
//                              if (mtex != NULL) mtex->mapto = MAP_ALPHA;
3667
734
//                      }
3668
735
//              }
3669
 
                material_texture_mapping_map[ma] = texindex_texarray_map;
3670
 
        }
3671
 
        
3672
 
        /** When this method is called, the writer must write the effect.
3673
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3674
 
        
3675
 
        virtual bool writeEffect( const COLLADAFW::Effect* effect ) 
3676
 
        {
3677
 
                
3678
 
                const COLLADAFW::UniqueId& uid = effect->getUniqueId();
3679
 
                if (uid_effect_map.find(uid) == uid_effect_map.end()) {
3680
 
                        fprintf(stderr, "Couldn't find a material by UID.\n");
3681
 
                        return true;
3682
 
                }
3683
 
                
3684
 
                Material *ma = uid_effect_map[uid];
3685
 
                
3686
 
                COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
3687
 
                if (common_efs.getCount() < 1) {
3688
 
                        fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
3689
 
                        return true;
3690
 
                }
3691
 
                // XXX TODO: Take all <profile_common>s
3692
 
                // Currently only first <profile_common> is supported
3693
 
                COLLADAFW::EffectCommon *ef = common_efs[0];
3694
 
                write_profile_COMMON(ef, ma);
3695
 
                
3696
 
                return true;
3697
 
        }
3698
 
        
3699
 
        
3700
 
        /** When this method is called, the writer must write the camera.
3701
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3702
 
        virtual bool writeCamera( const COLLADAFW::Camera* camera ) 
3703
 
        {
3704
 
                Camera *cam = NULL;
3705
 
                std::string cam_id, cam_name;
3706
 
                
3707
 
                cam_id = camera->getOriginalId();
3708
 
                cam_name = camera->getName();
3709
 
                if (cam_name.size()) cam = (Camera*)add_camera((char*)cam_name.c_str());
3710
 
                else cam = (Camera*)add_camera((char*)cam_id.c_str());
3711
 
                
3712
 
                if (!cam) {
3713
 
                        fprintf(stderr, "Cannot create camera. \n");
3714
 
                        return true;
3715
 
                }
3716
 
                cam->clipsta = camera->getNearClippingPlane().getValue();
3717
 
                cam->clipend = camera->getFarClippingPlane().getValue();
3718
 
                
3719
 
                COLLADAFW::Camera::CameraType type = camera->getCameraType();
3720
 
                switch(type) {
3721
 
                case COLLADAFW::Camera::ORTHOGRAPHIC:
3722
 
                        {
3723
 
                                cam->type = CAM_ORTHO;
3724
 
                        }
3725
 
                        break;
3726
 
                case COLLADAFW::Camera::PERSPECTIVE:
3727
 
                        {
3728
 
                                cam->type = CAM_PERSP;
3729
 
                        }
3730
 
                        break;
3731
 
                case COLLADAFW::Camera::UNDEFINED_CAMERATYPE:
3732
 
                        {
3733
 
                                fprintf(stderr, "Current camera type is not supported. \n");
3734
 
                                cam->type = CAM_PERSP;
3735
 
                        }
3736
 
                        break;
3737
 
                }
3738
 
                this->uid_camera_map[camera->getUniqueId()] = cam;
3739
 
                // XXX import camera options
3740
 
                return true;
3741
 
        }
3742
 
 
3743
 
        /** When this method is called, the writer must write the image.
3744
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3745
 
        virtual bool writeImage( const COLLADAFW::Image* image ) 
3746
 
        {
3747
 
                // XXX maybe it is necessary to check if the path is absolute or relative
3748
 
            const std::string& filepath = image->getImageURI().toNativePath();
3749
 
                const char *filename = (const char*)mFilename.c_str();
3750
 
                char dir[FILE_MAX];
3751
 
                char full_path[FILE_MAX];
3752
 
                
3753
 
                BLI_split_dirfile(filename, dir, NULL);
3754
 
                BLI_join_dirfile(full_path, dir, filepath.c_str());
3755
 
                Image *ima = BKE_add_image_file(full_path, 0);
3756
 
                if (!ima) {
3757
 
                        fprintf(stderr, "Cannot create image. \n");
3758
 
                        return true;
3759
 
                }
3760
 
                this->uid_image_map[image->getUniqueId()] = ima;
3761
 
                
3762
 
                return true;
3763
 
        }
3764
 
 
3765
 
        /** When this method is called, the writer must write the light.
3766
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3767
 
        virtual bool writeLight( const COLLADAFW::Light* light ) 
3768
 
        {
3769
 
                Lamp *lamp = NULL;
3770
 
                std::string la_id, la_name;
3771
 
                
3772
 
                la_id = light->getOriginalId();
3773
 
                la_name = light->getName();
3774
 
                if (la_name.size()) lamp = (Lamp*)add_lamp((char*)la_name.c_str());
3775
 
                else lamp = (Lamp*)add_lamp((char*)la_id.c_str());
3776
 
                
3777
 
                if (!lamp) {
3778
 
                        fprintf(stderr, "Cannot create lamp. \n");
3779
 
                        return true;
3780
 
                }
 
736
        material_texture_mapping_map[ma] = texindex_texarray_map;
 
737
}
 
738
 
 
739
/** When this method is called, the writer must write the effect.
 
740
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
741
 
 
742
bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect ) 
 
743
{
 
744
        if (mImportStage!=General)
 
745
                return true;
 
746
        
 
747
        const COLLADAFW::UniqueId& uid = effect->getUniqueId();
 
748
        
 
749
        if (uid_effect_map.find(uid) == uid_effect_map.end()) {
 
750
                fprintf(stderr, "Couldn't find a material by UID.\n");
 
751
                return true;
 
752
        }
 
753
        
 
754
        Material *ma = uid_effect_map[uid];
 
755
        std::map<COLLADAFW::UniqueId, Material*>::iterator  iter;
 
756
        for (iter = uid_material_map.begin(); iter != uid_material_map.end() ; iter++ )
 
757
        {
 
758
                if ( iter->second == ma ) {
 
759
                        this->FW_object_map[iter->first] = effect;
 
760
                        break;
 
761
                }
 
762
        }
 
763
        COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
 
764
        if (common_efs.getCount() < 1) {
 
765
                fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
 
766
                return true;
 
767
        }
 
768
        // XXX TODO: Take all <profile_common>s
 
769
        // Currently only first <profile_common> is supported
 
770
        COLLADAFW::EffectCommon *ef = common_efs[0];
 
771
        write_profile_COMMON(ef, ma);
 
772
        this->FW_object_map[effect->getUniqueId()] = effect;
 
773
                
 
774
        return true;
 
775
}
 
776
 
 
777
 
 
778
/** When this method is called, the writer must write the camera.
 
779
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
780
bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) 
 
781
{
 
782
        if (mImportStage!=General)
 
783
                return true;
 
784
                
 
785
        Camera *cam = NULL;
 
786
        std::string cam_id, cam_name;
 
787
        
 
788
        cam_id = camera->getOriginalId();
 
789
        cam_name = camera->getName();
 
790
        if (cam_name.size()) cam = (Camera*)add_camera((char*)cam_name.c_str());
 
791
        else cam = (Camera*)add_camera((char*)cam_id.c_str());
 
792
        
 
793
        if (!cam) {
 
794
                fprintf(stderr, "Cannot create camera.\n");
 
795
                return true;
 
796
        }
 
797
        cam->clipsta = camera->getNearClippingPlane().getValue();
 
798
        cam->clipend = camera->getFarClippingPlane().getValue();
 
799
        
 
800
        COLLADAFW::Camera::CameraType type = camera->getCameraType();
 
801
        switch(type) {
 
802
        case COLLADAFW::Camera::ORTHOGRAPHIC:
 
803
                {
 
804
                        cam->type = CAM_ORTHO;
 
805
                }
 
806
                break;
 
807
        case COLLADAFW::Camera::PERSPECTIVE:
 
808
                {
 
809
                        cam->type = CAM_PERSP;
 
810
                }
 
811
                break;
 
812
        case COLLADAFW::Camera::UNDEFINED_CAMERATYPE:
 
813
                {
 
814
                        fprintf(stderr, "Current camera type is not supported.\n");
 
815
                        cam->type = CAM_PERSP;
 
816
                }
 
817
                break;
 
818
        }
 
819
        
 
820
        switch(camera->getDescriptionType()) {
 
821
        case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
 
822
                {
 
823
                        switch(cam->type) {
 
824
                                case CAM_ORTHO:
 
825
                                        {
 
826
                                                double ymag = camera->getYMag().getValue();
 
827
                                                double aspect = camera->getAspectRatio().getValue();
 
828
                                                double xmag = aspect*ymag;
 
829
                                                cam->ortho_scale = (float)xmag;
 
830
                                        }
 
831
                                        break;
 
832
                                case CAM_PERSP:
 
833
                                default:
 
834
                                        {
 
835
                                                double yfov = camera->getYFov().getValue();
 
836
                                                double aspect = camera->getAspectRatio().getValue();
 
837
                                                double xfov = aspect*yfov;
 
838
                                                // xfov is in degrees, cam->lens is in millimiters
 
839
                                                cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x);
 
840
                                        }
 
841
                                        break;
 
842
                        }
 
843
                }
 
844
                break;
 
845
        /* XXX correct way to do following four is probably to get also render
 
846
           size and determine proper settings from that somehow */
 
847
        case COLLADAFW::Camera::ASPECTRATIO_AND_X:
 
848
        case COLLADAFW::Camera::SINGLE_X:
 
849
        case COLLADAFW::Camera::X_AND_Y:
 
850
                {
 
851
                        switch(cam->type) {
 
852
                                case CAM_ORTHO:
 
853
                                        cam->ortho_scale = (float)camera->getXMag().getValue();
 
854
                                        break;
 
855
                                case CAM_PERSP:
 
856
                                default:
 
857
                                        {
 
858
                                                double x = camera->getXFov().getValue();
 
859
                                                // x is in degrees, cam->lens is in millimiters
 
860
                                                cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
 
861
                                        }
 
862
                                        break;
 
863
                        }
 
864
                }
 
865
                break;
 
866
        case COLLADAFW::Camera::SINGLE_Y:
 
867
                {
 
868
                        switch(cam->type) {
 
869
                                case CAM_ORTHO:
 
870
                                        cam->ortho_scale = (float)camera->getYMag().getValue();
 
871
                                        break;
 
872
                                case CAM_PERSP:
 
873
                                default:
 
874
                                        {
 
875
                                        double yfov = camera->getYFov().getValue();
 
876
                                        // yfov is in degrees, cam->lens is in millimiters
 
877
                                        cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
 
878
                                        }
 
879
                                        break;
 
880
                        }
 
881
                }
 
882
                break;
 
883
        case COLLADAFW::Camera::UNDEFINED:
 
884
                // read nothing, use blender defaults.
 
885
                break;
 
886
        }
 
887
        
 
888
        this->uid_camera_map[camera->getUniqueId()] = cam;
 
889
        this->FW_object_map[camera->getUniqueId()] = camera;
 
890
        // XXX import camera options
 
891
        return true;
 
892
}
 
893
 
 
894
/** When this method is called, the writer must write the image.
 
895
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
896
bool DocumentImporter::writeImage( const COLLADAFW::Image* image ) 
 
897
{
 
898
        if (mImportStage!=General)
 
899
                return true;
 
900
                
 
901
        // XXX maybe it is necessary to check if the path is absolute or relative
 
902
        const std::string& filepath = image->getImageURI().toNativePath();
 
903
        const char *filename = (const char*)mFilename.c_str();
 
904
        char dir[FILE_MAX];
 
905
        char full_path[FILE_MAX];
 
906
        
 
907
        BLI_split_dir_part(filename, dir, sizeof(dir));
 
908
        BLI_join_dirfile(full_path, sizeof(full_path), dir, filepath.c_str());
 
909
        Image *ima = BKE_add_image_file(full_path);
 
910
        if (!ima) {
 
911
                fprintf(stderr, "Cannot create image.\n");
 
912
                return true;
 
913
        }
 
914
        this->uid_image_map[image->getUniqueId()] = ima;
 
915
        
 
916
        return true;
 
917
}
 
918
 
 
919
/** When this method is called, the writer must write the light.
 
920
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
921
bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) 
 
922
{
 
923
        if (mImportStage!=General)
 
924
                return true;
 
925
 
 
926
        Lamp *lamp = NULL;
 
927
        std::string la_id, la_name;
 
928
 
 
929
        TagsMap::iterator etit;
 
930
        ExtraTags *et = 0;
 
931
        etit = uid_tags_map.find(light->getUniqueId().toAscii());
 
932
        if (etit != uid_tags_map.end())
 
933
                et = etit->second;
 
934
 
 
935
        la_id = light->getOriginalId();
 
936
        la_name = light->getName();
 
937
        if (la_name.size()) lamp = (Lamp*)add_lamp((char*)la_name.c_str());
 
938
        else lamp = (Lamp*)add_lamp((char*)la_id.c_str());
 
939
 
 
940
        if (!lamp) {
 
941
                fprintf(stderr, "Cannot create lamp.\n");
 
942
                return true;
 
943
        }
 
944
 
 
945
        // if we find an ExtraTags for this, use that instead.
 
946
        if (et && et->isProfile("blender")) {
 
947
                et->setData("type", &(lamp->type));
 
948
                et->setData("flag", &(lamp->flag));
 
949
                et->setData("mode", &(lamp->mode));
 
950
                et->setData("gamma", &(lamp->k));
 
951
                et->setData("red", &(lamp->r));
 
952
                et->setData("green", &(lamp->g));
 
953
                et->setData("blue", &(lamp->b));
 
954
                et->setData("shadow_r", &(lamp->shdwr));
 
955
                et->setData("shadow_g", &(lamp->shdwg));
 
956
                et->setData("shadow_b", &(lamp->shdwb));
 
957
                et->setData("energy", &(lamp->energy));
 
958
                et->setData("dist", &(lamp->dist));
 
959
                et->setData("spotsize", &(lamp->spotsize));
 
960
                et->setData("spotblend", &(lamp->spotblend));
 
961
                et->setData("halo_intensity", &(lamp->haint));
 
962
                et->setData("att1", &(lamp->att1));
 
963
                et->setData("att2", &(lamp->att2));
 
964
                et->setData("falloff_type", &(lamp->falloff_type));
 
965
                et->setData("clipsta", &(lamp->clipsta));
 
966
                et->setData("clipend", &(lamp->clipend));
 
967
                et->setData("shadspotsize", &(lamp->shadspotsize));
 
968
                et->setData("bias", &(lamp->bias));
 
969
                et->setData("soft", &(lamp->soft));
 
970
                et->setData("compressthresh", &(lamp->compressthresh));
 
971
                et->setData("bufsize", &(lamp->bufsize));
 
972
                et->setData("samp", &(lamp->samp));
 
973
                et->setData("buffers", &(lamp->buffers));
 
974
                et->setData("filtertype", &(lamp->filtertype));
 
975
                et->setData("bufflag", &(lamp->bufflag));
 
976
                et->setData("buftype", &(lamp->buftype));
 
977
                et->setData("ray_samp", &(lamp->ray_samp));
 
978
                et->setData("ray_sampy", &(lamp->ray_sampy));
 
979
                et->setData("ray_sampz", &(lamp->ray_sampz));
 
980
                et->setData("ray_samp_type", &(lamp->ray_samp_type));
 
981
                et->setData("area_shape", &(lamp->area_shape));
 
982
                et->setData("area_size", &(lamp->area_size));
 
983
                et->setData("area_sizey", &(lamp->area_sizey));
 
984
                et->setData("area_sizez", &(lamp->area_sizez));
 
985
                et->setData("adapt_thresh", &(lamp->adapt_thresh));
 
986
                et->setData("ray_samp_method", &(lamp->ray_samp_method));
 
987
                et->setData("shadhalostep", &(lamp->shadhalostep));
 
988
                et->setData("sun_effect_type", &(lamp->shadhalostep));
 
989
                et->setData("skyblendtype", &(lamp->skyblendtype));
 
990
                et->setData("horizon_brightness", &(lamp->horizon_brightness));
 
991
                et->setData("spread", &(lamp->spread));
 
992
                et->setData("sun_brightness", &(lamp->sun_brightness));
 
993
                et->setData("sun_size", &(lamp->sun_size));
 
994
                et->setData("backscattered_light", &(lamp->backscattered_light));
 
995
                et->setData("sun_intensity", &(lamp->sun_intensity));
 
996
                et->setData("atm_turbidity", &(lamp->atm_turbidity));
 
997
                et->setData("atm_extinction_factor", &(lamp->atm_extinction_factor));
 
998
                et->setData("atm_distance_factor", &(lamp->atm_distance_factor));
 
999
                et->setData("skyblendfac", &(lamp->skyblendfac));
 
1000
                et->setData("sky_exposure", &(lamp->sky_exposure));
 
1001
                et->setData("sky_colorspace", &(lamp->sky_colorspace));
 
1002
        }
 
1003
        else {
 
1004
                float constatt = light->getConstantAttenuation().getValue();
 
1005
                float linatt = light->getLinearAttenuation().getValue();
 
1006
                float quadatt = light->getQuadraticAttenuation().getValue();
 
1007
                float d = 25.0f;
 
1008
                float att1 = 0.0f;
 
1009
                float att2 = 0.0f;
 
1010
                float e = 1.0f;
 
1011
 
3781
1012
                if (light->getColor().isValid()) {
3782
1013
                        COLLADAFW::Color col = light->getColor();
3783
1014
                        lamp->r = col.getRed();
3784
1015
                        lamp->g = col.getGreen();
3785
1016
                        lamp->b = col.getBlue();
3786
1017
                }
 
1018
 
 
1019
                if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
 
1020
                        att2 = quadatt;
 
1021
                        d = sqrt(1.0f/quadatt);
 
1022
                }
 
1023
                // linear light
 
1024
                else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
 
1025
                        att1 = linatt;
 
1026
                        d = (1.0f/linatt);
 
1027
                }
 
1028
                else if (IS_EQ(constatt, 1.0f)) {
 
1029
                        att1 = 1.0f;
 
1030
                }
 
1031
                else {
 
1032
                        // assuming point light (const att = 1.0);
 
1033
                        att1 = 1.0f;
 
1034
                }
 
1035
                
 
1036
                d *= ( 1.0f / unit_converter.getLinearMeter());
 
1037
 
 
1038
                lamp->energy = e;
 
1039
                lamp->dist = d;
 
1040
 
3787
1041
                COLLADAFW::Light::LightType type = light->getLightType();
3788
1042
                switch(type) {
3789
 
                case COLLADAFW::Light::AMBIENT_LIGHT:
3790
 
                        {
3791
 
                                lamp->type = LA_HEMI;
3792
 
                        }
3793
 
                        break;
3794
 
                case COLLADAFW::Light::SPOT_LIGHT:
3795
 
                        {
3796
 
                                lamp->type = LA_SPOT;
3797
 
                                lamp->falloff_type = LA_FALLOFF_SLIDERS;
3798
 
                                lamp->att1 = light->getLinearAttenuation().getValue();
3799
 
                                lamp->att2 = light->getQuadraticAttenuation().getValue();
3800
 
                                lamp->spotsize = light->getFallOffAngle().getValue();
3801
 
                                lamp->spotblend = light->getFallOffExponent().getValue();
3802
 
                        }
3803
 
                        break;
3804
 
                case COLLADAFW::Light::DIRECTIONAL_LIGHT:
3805
 
                        {
3806
 
                                lamp->type = LA_SUN;
3807
 
                        }
3808
 
                        break;
3809
 
                case COLLADAFW::Light::POINT_LIGHT:
3810
 
                        {
3811
 
                                lamp->type = LA_LOCAL;
3812
 
                                lamp->att1 = light->getLinearAttenuation().getValue();
3813
 
                                lamp->att2 = light->getQuadraticAttenuation().getValue();
3814
 
                        }
3815
 
                        break;
3816
 
                case COLLADAFW::Light::UNDEFINED:
3817
 
                        {
3818
 
                                fprintf(stderr, "Current lamp type is not supported. \n");
3819
 
                                lamp->type = LA_LOCAL;
3820
 
                        }
3821
 
                        break;
 
1043
                        case COLLADAFW::Light::AMBIENT_LIGHT:
 
1044
                                {
 
1045
                                        lamp->type = LA_HEMI;
 
1046
                                }
 
1047
                                break;
 
1048
                        case COLLADAFW::Light::SPOT_LIGHT:
 
1049
                                {
 
1050
                                        lamp->type = LA_SPOT;
 
1051
                                        lamp->att1 = att1;
 
1052
                                        lamp->att2 = att2;
 
1053
                                        if (IS_EQ(att1, 0.0f) && att2 > 0)
 
1054
                                                lamp->falloff_type = LA_FALLOFF_INVSQUARE;
 
1055
                                        if (IS_EQ(att2, 0.0f) && att1 > 0)
 
1056
                                                lamp->falloff_type = LA_FALLOFF_INVLINEAR;
 
1057
                                        lamp->spotsize = light->getFallOffAngle().getValue();
 
1058
                                        lamp->spotblend = light->getFallOffExponent().getValue();
 
1059
                                }
 
1060
                                break;
 
1061
                        case COLLADAFW::Light::DIRECTIONAL_LIGHT:
 
1062
                                {
 
1063
                                        /* our sun is very strong, so pick a smaller energy level */
 
1064
                                        lamp->type = LA_SUN;
 
1065
                                        lamp->mode |= LA_NO_SPEC;
 
1066
                                }
 
1067
                                break;
 
1068
                        case COLLADAFW::Light::POINT_LIGHT:
 
1069
                                {
 
1070
                                        lamp->type = LA_LOCAL;
 
1071
                                        lamp->att1 = att1;
 
1072
                                        lamp->att2 = att2;
 
1073
                                        if (IS_EQ(att1, 0.0f) && att2 > 0)
 
1074
                                                lamp->falloff_type = LA_FALLOFF_INVSQUARE;
 
1075
                                        if (IS_EQ(att2, 0.0f) && att1 > 0)
 
1076
                                                lamp->falloff_type = LA_FALLOFF_INVLINEAR;
 
1077
                                }
 
1078
                                break;
 
1079
                        case COLLADAFW::Light::UNDEFINED:
 
1080
                                {
 
1081
                                        fprintf(stderr, "Current lamp type is not supported.\n");
 
1082
                                        lamp->type = LA_LOCAL;
 
1083
                                }
 
1084
                                break;
3822
1085
                }
3823
 
                        
3824
 
                this->uid_lamp_map[light->getUniqueId()] = lamp;
3825
 
                return true;
3826
 
        }
3827
 
        
3828
 
        // this function is called only for animations that pass COLLADAFW::validate
3829
 
        virtual bool writeAnimation( const COLLADAFW::Animation* anim ) 
3830
 
        {
3831
 
                // return true;
3832
 
                return anim_importer.write_animation(anim);
3833
 
        }
3834
 
        
3835
 
        // called on post-process stage after writeVisualScenes
3836
 
        virtual bool writeAnimationList( const COLLADAFW::AnimationList* animationList ) 
3837
 
        {
3838
 
                // return true;
3839
 
                return anim_importer.write_animation_list(animationList);
3840
 
        }
3841
 
        
3842
 
        /** When this method is called, the writer must write the skin controller data.
3843
 
                @return The writer should return true, if writing succeeded, false otherwise.*/
3844
 
        virtual bool writeSkinControllerData( const COLLADAFW::SkinControllerData* skin ) 
3845
 
        {
3846
 
                return armature_importer.write_skin_controller_data(skin);
3847
 
        }
3848
 
 
3849
 
        // this is called on postprocess, before writeVisualScenes
3850
 
        virtual bool writeController( const COLLADAFW::Controller* controller ) 
3851
 
        {
3852
 
                return armature_importer.write_controller(controller);
3853
 
        }
3854
 
 
3855
 
        virtual bool writeFormulas( const COLLADAFW::Formulas* formulas )
3856
 
        {
3857
 
                return true;
3858
 
        }
3859
 
 
3860
 
        virtual bool writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene )
3861
 
        {
3862
 
                return true;
3863
 
        }
3864
 
};
3865
 
 
3866
 
void DocumentImporter::import(bContext *C, const char *filename)
3867
 
{
3868
 
        Writer w(C, filename);
3869
 
        w.write();
3870
 
}
 
1086
        }
 
1087
 
 
1088
        this->uid_lamp_map[light->getUniqueId()] = lamp;
 
1089
        this->FW_object_map[light->getUniqueId()] = light;
 
1090
        return true;
 
1091
}
 
1092
 
 
1093
// this function is called only for animations that pass COLLADAFW::validate
 
1094
bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim ) 
 
1095
{
 
1096
        if (mImportStage!=General)
 
1097
                return true;
 
1098
                
 
1099
        // return true;
 
1100
        return anim_importer.write_animation(anim);
 
1101
}
 
1102
 
 
1103
// called on post-process stage after writeVisualScenes
 
1104
bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* animationList ) 
 
1105
{
 
1106
        if (mImportStage!=General)
 
1107
                return true;
 
1108
                
 
1109
        // return true;
 
1110
        return anim_importer.write_animation_list(animationList);
 
1111
}
 
1112
 
 
1113
/** When this method is called, the writer must write the skin controller data.
 
1114
        \return The writer should return true, if writing succeeded, false otherwise.*/
 
1115
bool DocumentImporter::writeSkinControllerData( const COLLADAFW::SkinControllerData* skin ) 
 
1116
{
 
1117
        return armature_importer.write_skin_controller_data(skin);
 
1118
}
 
1119
 
 
1120
// this is called on postprocess, before writeVisualScenes
 
1121
bool DocumentImporter::writeController( const COLLADAFW::Controller* controller ) 
 
1122
{
 
1123
        if (mImportStage!=General)
 
1124
                return true;
 
1125
                
 
1126
        return armature_importer.write_controller(controller);
 
1127
}
 
1128
 
 
1129
bool DocumentImporter::writeFormulas( const COLLADAFW::Formulas* formulas )
 
1130
{
 
1131
        return true;
 
1132
}
 
1133
 
 
1134
bool DocumentImporter::writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene )
 
1135
{
 
1136
        return true;
 
1137
}
 
1138
 
 
1139
ExtraTags* DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
 
1140
{
 
1141
        if (uid_tags_map.find(uid.toAscii())==uid_tags_map.end()) {
 
1142
                return NULL;
 
1143
        }
 
1144
        return uid_tags_map[uid.toAscii()];
 
1145
}
 
1146
 
 
1147
bool DocumentImporter::addExtraTags( const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
 
1148
{
 
1149
        uid_tags_map[uid.toAscii()] = extra_tags;
 
1150
        return true;
 
1151
}
 
1152