~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/collada/AnimationImporter.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
 * ***** BEGIN GPL LICENSE BLOCK *****
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory, Sukhitha Jayathilake.
 
19
 *
 
20
 * ***** END GPL LICENSE BLOCK *****
 
21
 */
 
22
 
 
23
/** \file blender/collada/AnimationImporter.cpp
 
24
 *  \ingroup collada
 
25
 */
 
26
 
 
27
#include <stddef.h>
 
28
 
 
29
/* COLLADABU_ASSERT, may be able to remove later */
 
30
#include "COLLADABUPlatform.h"
 
31
 
 
32
#include "DNA_armature_types.h"
 
33
 
 
34
#include "ED_keyframing.h"
 
35
 
 
36
#include "BLI_listbase.h"
 
37
#include "BLI_math.h"
 
38
#include "BLI_path_util.h"
 
39
#include "BLI_string.h"
 
40
 
 
41
#include "BKE_action.h"
 
42
#include "BKE_armature.h"
 
43
#include "BKE_fcurve.h"
 
44
#include "BKE_object.h"
 
45
 
 
46
#include "MEM_guardedalloc.h"
 
47
 
 
48
#include "collada_utils.h"
 
49
#include "AnimationImporter.h"
 
50
#include "ArmatureImporter.h"
 
51
#include "MaterialExporter.h"
 
52
 
 
53
#include <algorithm>
 
54
 
 
55
// first try node name, if not available (since is optional), fall back to original id
 
56
template<class T>
 
57
static const char *bc_get_joint_name(T *node)
 
58
{
 
59
        const std::string& id = node->getName();
 
60
        return id.size() ? id.c_str() : node->getOriginalId().c_str();
 
61
}
 
62
 
 
63
FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path)
 
64
{
 
65
        FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
 
66
        fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
 
67
        fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
 
68
        fcu->array_index = array_index;
 
69
        return fcu;
 
70
}
 
71
        
 
72
void AnimationImporter::create_bezt(FCurve *fcu, float frame, float output)
 
73
{
 
74
        BezTriple bez;
 
75
        memset(&bez, 0, sizeof(BezTriple));
 
76
        bez.vec[1][0] = frame;
 
77
        bez.vec[1][1] = output;
 
78
        bez.ipo = U.ipo_new; /* use default interpolation mode here... */
 
79
        bez.f1 = bez.f2 = bez.f3 = SELECT;
 
80
        bez.h1 = bez.h2 = HD_AUTO;
 
81
        insert_bezt_fcurve(fcu, &bez, 0);
 
82
        calchandles_fcurve(fcu);
 
83
}
 
84
 
 
85
// create one or several fcurves depending on the number of parameters being animated
 
86
void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
 
87
{
 
88
        COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
 
89
        COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
 
90
 
 
91
        float fps = (float)FPS;
 
92
        size_t dim = curve->getOutDimension();
 
93
        unsigned int i;
 
94
 
 
95
        std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
 
96
 
 
97
        switch (dim) {
 
98
        case 1: // X, Y, Z or angle
 
99
        case 3: // XYZ
 
100
        case 4:
 
101
        case 16: // matrix
 
102
                {
 
103
                        for (i = 0; i < dim; i++ ) {
 
104
                                FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
 
105
 
 
106
                                fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
 
107
                                // fcu->rna_path = BLI_strdupn(path, strlen(path));
 
108
                                fcu->array_index = 0;
 
109
                                fcu->totvert = curve->getKeyCount();
 
110
 
 
111
                                // create beztriple for each key
 
112
                                for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
 
113
                                        BezTriple bez;
 
114
                                        memset(&bez, 0, sizeof(BezTriple));
 
115
 
 
116
 
 
117
                                        // input, output
 
118
                                        bez.vec[1][0] = bc_get_float_value(input, j) * fps; 
 
119
                                        bez.vec[1][1] = bc_get_float_value(output, j * dim + i);
 
120
 
 
121
 
 
122
                                        if ( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ||
 
123
                                                curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP) 
 
124
                                        {
 
125
                                                COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
 
126
                                                COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
 
127
 
 
128
                                                // intangent
 
129
                                                bez.vec[0][0] = bc_get_float_value(intan, (j * 2 * dim ) + (2 * i)) * fps;
 
130
                                                bez.vec[0][1] = bc_get_float_value(intan, (j * 2 * dim )+ (2 * i) + 1);
 
131
 
 
132
                                                // outtangent
 
133
                                                bez.vec[2][0] = bc_get_float_value(outtan, (j * 2 * dim ) + (2 * i)) * fps;
 
134
                                                bez.vec[2][1] = bc_get_float_value(outtan, (j * 2 * dim )+ (2 * i) + 1);
 
135
                                                if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) 
 
136
                                                        bez.ipo = BEZT_IPO_BEZ;
 
137
                                                else 
 
138
                                                        bez.ipo = BEZT_IPO_CONST;
 
139
                                                //bez.h1 = bez.h2 = HD_AUTO;    
 
140
                                        }
 
141
                                        else 
 
142
                                        {
 
143
                                                bez.h1 = bez.h2 = HD_AUTO; 
 
144
                                                bez.ipo = BEZT_IPO_LIN;
 
145
                                        }
 
146
                                        // bez.ipo = U.ipo_new; /* use default interpolation mode here... */
 
147
                                        bez.f1 = bez.f2 = bez.f3 = SELECT;
 
148
 
 
149
                                        insert_bezt_fcurve(fcu, &bez, 0);
 
150
                                }
 
151
 
 
152
                                calchandles_fcurve(fcu);
 
153
 
 
154
                                fcurves.push_back(fcu);
 
155
                        }
 
156
                }
 
157
                break;
 
158
        default:
 
159
                fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", (int)dim, curve->getOriginalId().c_str());
 
160
        }
 
161
 
 
162
        for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
 
163
                unused_curves.push_back(*it);
 
164
}
 
165
 
 
166
 
 
167
void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
 
168
{
 
169
        for (unsigned int i = 0; i < cu->totvert; i++) {
 
170
                // TODO convert handles too
 
171
                cu->bezt[i].vec[1][1] *= DEG2RADF(1.0f);
 
172
                cu->bezt[i].vec[0][1] *= DEG2RADF(1.0f);
 
173
                cu->bezt[i].vec[2][1] *= DEG2RADF(1.0f);
 
174
        }
 
175
}
 
176
 
 
177
 
 
178
void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
 
179
{
 
180
        bAction *act;
 
181
        
 
182
        if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
 
183
        else act = ob->adt->action;
 
184
        
 
185
        std::vector<FCurve*>::iterator it;
 
186
        int i;
 
187
 
 
188
#if 0
 
189
        char *p = strstr(rna_path, "rotation_euler");
 
190
        bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
 
191
 
 
192
        // convert degrees to radians for rotation
 
193
        if (is_rotation)
 
194
                fcurve_deg_to_rad(fcu);
 
195
#endif
 
196
        
 
197
        for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
 
198
                FCurve *fcu = *it;
 
199
                fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
 
200
                
 
201
                if (array_index == -1) fcu->array_index = i;
 
202
                else fcu->array_index = array_index;
 
203
        
 
204
                if (ob->type == OB_ARMATURE) {
 
205
                        bActionGroup *grp = NULL;
 
206
                        const char *bone_name = bc_get_joint_name(animated->node);
 
207
                        
 
208
                        if (bone_name) {
 
209
                                /* try to find group */
 
210
                                grp = action_groups_find_named(act, bone_name);
 
211
                                
 
212
                                /* no matching groups, so add one */
 
213
                                if (grp == NULL) {
 
214
                                        /* Add a new group, and make it active */
 
215
                                        grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
 
216
                                        
 
217
                                        grp->flag = AGRP_SELECTED;
 
218
                                        BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
 
219
                                        
 
220
                                        BLI_addtail(&act->groups, grp);
 
221
                                        BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
 
222
                                }
 
223
                                
 
224
                                /* add F-Curve to group */
 
225
                                action_groups_add_channel(act, grp, fcu);
 
226
                                
 
227
                        }
 
228
#if 0
 
229
                        if (is_rotation) {
 
230
                                fcurves_actionGroup_map[grp].push_back(fcu);
 
231
                        }
 
232
#endif
 
233
                }
 
234
                else {
 
235
                        BLI_addtail(&act->curves, fcu);
 
236
                }
 
237
 
 
238
                // curve is used, so remove it from unused_curves
 
239
                unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
 
240
        }
 
241
}
 
242
 
 
243
AnimationImporter::AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) :
 
244
                TransformReader(conv), armature_importer(arm), scene(scene) { }
 
245
 
 
246
AnimationImporter::~AnimationImporter()
 
247
{
 
248
        // free unused FCurves
 
249
        for (std::vector<FCurve*>::iterator it = unused_curves.begin(); it != unused_curves.end(); it++)
 
250
                free_fcurve(*it);
 
251
 
 
252
        if (unused_curves.size())
 
253
                fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size());
 
254
}
 
255
 
 
256
bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim) 
 
257
{
 
258
        if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
 
259
                COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim;
 
260
                
 
261
                // XXX Don't know if it's necessary
 
262
                // Should we check outPhysicalDimension?
 
263
                if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
 
264
                        fprintf(stderr, "Inputs physical dimension is not time.\n");
 
265
                        return true;
 
266
                }
 
267
 
 
268
                // a curve can have mixed interpolation type,
 
269
                // in this case curve->getInterpolationTypes returns a list of interpolation types per key
 
270
                COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType();
 
271
 
 
272
                if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
 
273
                        switch (interp) {
 
274
                        case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
 
275
                        case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
 
276
                        case COLLADAFW::AnimationCurve::INTERPOLATION_STEP:
 
277
                                animation_to_fcurves(curve);
 
278
                                break;
 
279
                        default:
 
280
                                // TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types
 
281
                                fprintf(stderr, "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n");
 
282
                                break;
 
283
                        }
 
284
                }
 
285
                else {
 
286
                        // not supported yet
 
287
                        fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
 
288
                }
 
289
        }
 
290
        else {
 
291
                fprintf(stderr, "FORMULA animation type is not supported yet.\n");
 
292
        }
 
293
        
 
294
        return true;
 
295
}
 
296
        
 
297
// called on post-process stage after writeVisualScenes
 
298
bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* animlist) 
 
299
{
 
300
        const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
 
301
 
 
302
        animlist_map[animlist_id] = animlist;
 
303
 
 
304
#if 0
 
305
 
 
306
        // should not happen
 
307
        if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
 
308
                return true;
 
309
        }
 
310
 
 
311
        // for bones rna_path is like: pose.bones["bone-name"].rotation
 
312
 
 
313
 
 
314
#endif
 
315
 
 
316
        return true;
 
317
}
 
318
 
 
319
// \todo refactor read_node_transform to not automatically apply anything,
 
320
// but rather return the transform matrix, so caller can do with it what is
 
321
// necessary. Same for \ref get_node_mat
 
322
void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob)
 
323
{
 
324
        float mat[4][4];
 
325
        TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
 
326
        if (ob) {
 
327
                copy_m4_m4(ob->obmat, mat);
 
328
                object_apply_mat4(ob, ob->obmat, 0, 0);
 
329
        }
 
330
}
 
331
 
 
332
#if 0
 
333
virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act)
 
334
{
 
335
        bActionGroup *grp;
 
336
        int i;
 
337
        
 
338
        for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) {
 
339
 
 
340
                FCurve *eulcu[3] = {NULL, NULL, NULL};
 
341
                
 
342
                if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
 
343
                        continue;
 
344
 
 
345
                std::vector<FCurve*> &rot_fcurves = fcurves_actionGroup_map[grp];
 
346
                
 
347
                if (rot_fcurves.size() > 3) continue;
 
348
 
 
349
                for (i = 0; i < rot_fcurves.size(); i++)
 
350
                        eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
 
351
 
 
352
                char joint_path[100];
 
353
                char rna_path[100];
 
354
 
 
355
                BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name);
 
356
                BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path);
 
357
 
 
358
                FCurve *quatcu[4] = {
 
359
                        create_fcurve(0, rna_path),
 
360
                        create_fcurve(1, rna_path),
 
361
                        create_fcurve(2, rna_path),
 
362
                        create_fcurve(3, rna_path)
 
363
                };
 
364
 
 
365
                bPoseChannel *chan = get_pose_channel(ob->pose, grp->name);
 
366
 
 
367
                float m4[4][4], irest[3][3];
 
368
                invert_m4_m4(m4, chan->bone->arm_mat);
 
369
                copy_m3_m4(irest, m4);
 
370
 
 
371
                for (i = 0; i < 3; i++) {
 
372
 
 
373
                        FCurve *cu = eulcu[i];
 
374
 
 
375
                        if (!cu) continue;
 
376
 
 
377
                        for (int j = 0; j < cu->totvert; j++) {
 
378
                                float frame = cu->bezt[j].vec[1][0];
 
379
 
 
380
                                float eul[3] = {
 
381
                                        eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f,
 
382
                                        eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f,
 
383
                                        eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f
 
384
                                };
 
385
 
 
386
                                // make eul relative to bone rest pose
 
387
                                float rot[3][3], rel[3][3], quat[4];
 
388
 
 
389
                                /*eul_to_mat3(rot, eul);
 
390
 
 
391
                                mul_m3_m3m3(rel, irest, rot);
 
392
 
 
393
                                mat3_to_quat(quat, rel);
 
394
                                */
 
395
 
 
396
                                eul_to_quat(quat, eul);
 
397
 
 
398
                                for (int k = 0; k < 4; k++)
 
399
                                        create_bezt(quatcu[k], frame, quat[k]);
 
400
                        }
 
401
                }
 
402
 
 
403
                // now replace old Euler curves
 
404
 
 
405
                for (i = 0; i < 3; i++) {
 
406
                        if (!eulcu[i]) continue;
 
407
 
 
408
                        action_groups_remove_channel(act, eulcu[i]);
 
409
                        free_fcurve(eulcu[i]);
 
410
                }
 
411
 
 
412
                chan->rotmode = ROT_MODE_QUAT;
 
413
 
 
414
                for (i = 0; i < 4; i++)
 
415
                        action_groups_add_channel(act, grp, quatcu[i]);
 
416
        }
 
417
 
 
418
        bPoseChannel *pchan;
 
419
        for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 
420
                pchan->rotmode = ROT_MODE_QUAT;
 
421
        }
 
422
}
 
423
#endif
 
424
 
 
425
 
 
426
//sets the rna_path and array index to curve
 
427
void AnimationImporter::modify_fcurve(std::vector<FCurve*>* curves , const char* rna_path , int array_index )
 
428
{
 
429
        std::vector<FCurve*>::iterator it;
 
430
        int i;
 
431
        for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
 
432
                FCurve *fcu = *it;
 
433
                fcu->rna_path = BLI_strdup(rna_path);
 
434
                
 
435
                if (array_index == -1) fcu->array_index = i;
 
436
                else fcu->array_index = array_index;
 
437
 
 
438
                unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
 
439
        }
 
440
}
 
441
 
 
442
void AnimationImporter::unused_fcurve(std::vector<FCurve*>* curves)
 
443
{
 
444
        // when an error happens and we can't actually use curve remove it from unused_curves
 
445
        std::vector<FCurve*>::iterator it;
 
446
        for (it = curves->begin(); it != curves->end(); it++) {
 
447
                FCurve *fcu = *it;
 
448
                unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
 
449
        }
 
450
}
 
451
 
 
452
void AnimationImporter::find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves)
 
453
{
 
454
        std::vector<FCurve*>::iterator iter;
 
455
        for (iter = curves->begin(); iter != curves->end(); iter++) {
 
456
                FCurve *fcu = *iter;
 
457
 
 
458
                for (unsigned int k = 0; k < fcu->totvert; k++) {
 
459
                        //get frame value from bezTriple
 
460
                        float fra = fcu->bezt[k].vec[1][0];
 
461
                        //if frame already not added add frame to frames
 
462
                        if (std::find(frames->begin(), frames->end(), fra) == frames->end())
 
463
                                frames->push_back(fra);
 
464
 
 
465
                }
 
466
        }
 
467
}
 
468
 
 
469
//creates the rna_paths and array indices of fcurves from animations using transformation and bound animation class of each animation.
 
470
void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation * transform , 
 
471
                                                                                                         const COLLADAFW::AnimationList::AnimationBinding * binding,
 
472
                                                                                                         std::vector<FCurve*>* curves, bool is_joint, char * joint_path)
 
473
{
 
474
        COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
 
475
        bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
 
476
        bool is_rotation = tm_type  == COLLADAFW::Transformation::ROTATE;
 
477
 
 
478
        //to check if the no of curves are valid
 
479
        bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE ||tm_type  == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
 
480
 
 
481
 
 
482
        if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) {
 
483
                fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size());
 
484
                return;
 
485
        }
 
486
 
 
487
        char rna_path[100];
 
488
 
 
489
        switch (tm_type) {
 
490
                case COLLADAFW::Transformation::TRANSLATE:
 
491
                case COLLADAFW::Transformation::SCALE:
 
492
                        {
 
493
                                bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE;
 
494
                                if (is_joint)
 
495
                                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
 
496
                                else
 
497
                                        BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
 
498
 
 
499
                                switch (binding->animationClass) {
 
500
                case COLLADAFW::AnimationList::POSITION_X:
 
501
                        modify_fcurve(curves, rna_path, 0 );
 
502
                        break;
 
503
                case COLLADAFW::AnimationList::POSITION_Y:
 
504
                        modify_fcurve(curves, rna_path, 1 );
 
505
                        break;
 
506
                case COLLADAFW::AnimationList::POSITION_Z:
 
507
                        modify_fcurve(curves, rna_path, 2 );
 
508
                        break;
 
509
                case COLLADAFW::AnimationList::POSITION_XYZ:
 
510
                        modify_fcurve(curves, rna_path, -1 );
 
511
                        break;
 
512
                default:
 
513
                        unused_fcurve(curves);
 
514
                        fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
 
515
                                binding->animationClass, loc ? "TRANSLATE" : "SCALE");
 
516
                                }
 
517
                                break;
 
518
                        }
 
519
 
 
520
 
 
521
                case COLLADAFW::Transformation::ROTATE:
 
522
                        {
 
523
                                if (is_joint)
 
524
                                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
 
525
                                else
 
526
                                        BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
 
527
                                std::vector<FCurve*>::iterator iter;
 
528
                                for (iter = curves->begin(); iter != curves->end(); iter++) {
 
529
                                        FCurve* fcu = *iter;
 
530
 
 
531
                                        //if transform is rotation the fcurves values must be turned in to radian.
 
532
                                        if (is_rotation)
 
533
                                                fcurve_deg_to_rad(fcu);          
 
534
                                }                                       
 
535
                                COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)transform;
 
536
                                COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
 
537
 
 
538
                                switch (binding->animationClass) {
 
539
                case COLLADAFW::AnimationList::ANGLE:
 
540
                        if (COLLADABU::Math::Vector3::UNIT_X == axis) {
 
541
                                modify_fcurve(curves, rna_path, 0 );
 
542
                        }
 
543
                        else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
 
544
                                modify_fcurve(curves, rna_path, 1 );
 
545
                        }
 
546
                        else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
 
547
                                modify_fcurve(curves, rna_path, 2 );
 
548
                        }
 
549
                        else
 
550
                                unused_fcurve(curves);
 
551
                        break;
 
552
                case COLLADAFW::AnimationList::AXISANGLE:
 
553
                        // TODO convert axis-angle to quat? or XYZ?
 
554
                default:
 
555
                        unused_fcurve(curves);
 
556
                        fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
 
557
                                binding->animationClass);
 
558
                                }
 
559
                                break;
 
560
                        }
 
561
 
 
562
                case COLLADAFW::Transformation::MATRIX:
 
563
                        /*{
 
564
                        COLLADAFW::Matrix* mat = (COLLADAFW::Matrix*)transform;
 
565
                        COLLADABU::Math::Matrix4 mat4 = mat->getMatrix();
 
566
                        switch (binding->animationClass) {
 
567
                        case COLLADAFW::AnimationList::TRANSFORM:
 
568
 
 
569
                        }
 
570
                        }*/
 
571
                        unused_fcurve(curves);
 
572
                        break;
 
573
                case COLLADAFW::Transformation::SKEW:
 
574
                case COLLADAFW::Transformation::LOOKAT:
 
575
                        unused_fcurve(curves);
 
576
                        fprintf(stderr, "Animation of SKEW and LOOKAT transformations is not supported yet.\n");
 
577
                        break;
 
578
        }
 
579
 
 
580
}
 
581
 
 
582
//creates the rna_paths and array indices of fcurves from animations using color and bound animation class of each animation.
 
583
void AnimationImporter:: Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves ,const char * anim_type)
 
584
{
 
585
        char rna_path[100];
 
586
        BLI_strncpy(rna_path,anim_type, sizeof(rna_path));
 
587
 
 
588
        const COLLADAFW::AnimationList *animlist = animlist_map[listid];
 
589
        const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
 
590
        //all the curves belonging to the current binding
 
591
        std::vector<FCurve*> animcurves;
 
592
        for (unsigned int j = 0; j < bindings.getCount(); j++) {
 
593
                animcurves = curve_map[bindings[j].animation];
 
594
 
 
595
                switch (bindings[j].animationClass) {
 
596
                case COLLADAFW::AnimationList::COLOR_R:
 
597
                        modify_fcurve(&animcurves, rna_path, 0 );
 
598
                        break;
 
599
                case COLLADAFW::AnimationList::COLOR_G:
 
600
                        modify_fcurve(&animcurves, rna_path, 1 );
 
601
                        break;
 
602
                case COLLADAFW::AnimationList::COLOR_B:
 
603
                        modify_fcurve(&animcurves, rna_path, 2 );
 
604
                        break;
 
605
                case COLLADAFW::AnimationList::COLOR_RGB:
 
606
                case COLLADAFW::AnimationList::COLOR_RGBA: // to do-> set intensity
 
607
                        modify_fcurve(&animcurves, rna_path, -1 );
 
608
                        break;
 
609
 
 
610
                default:
 
611
                        unused_fcurve(&animcurves);
 
612
                        fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
 
613
                                bindings[j].animationClass, "COLOR" );
 
614
                }
 
615
 
 
616
                std::vector<FCurve*>::iterator iter;
 
617
                //Add the curves of the current animation to the object
 
618
                for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
 
619
                        FCurve * fcu = *iter;
 
620
                        BLI_addtail(AnimCurves, fcu);   
 
621
                }
 
622
        }
 
623
 
 
624
 
 
625
}
 
626
 
 
627
void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type)
 
628
{
 
629
        char rna_path[100];
 
630
        if (animlist_map.find(listid) == animlist_map.end()) {
 
631
                return;
 
632
        }
 
633
        else {
 
634
                //anim_type has animations
 
635
                const COLLADAFW::AnimationList *animlist = animlist_map[listid];
 
636
                const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
 
637
                //all the curves belonging to the current binding
 
638
                std::vector<FCurve*> animcurves;
 
639
                for (unsigned int j = 0; j < bindings.getCount(); j++) {
 
640
                        animcurves = curve_map[bindings[j].animation];
 
641
 
 
642
                        BLI_strncpy(rna_path, anim_type , sizeof(rna_path));
 
643
                        modify_fcurve(&animcurves, rna_path, 0 );
 
644
                        std::vector<FCurve*>::iterator iter;
 
645
                        //Add the curves of the current animation to the object
 
646
                        for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
 
647
                                FCurve * fcu = *iter;
 
648
                                BLI_addtail(AnimCurves, fcu);
 
649
                        }
 
650
                }
 
651
        }
 
652
        
 
653
}
 
654
 
 
655
void AnimationImporter::apply_matrix_curves( Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root ,COLLADAFW::Node* node, 
 
656
                                                                                                        COLLADAFW::Transformation * tm )
 
657
{
 
658
        bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
 
659
        const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
 
660
        char joint_path[200];
 
661
        if ( is_joint ) 
 
662
                armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
 
663
 
 
664
        std::vector<float> frames;
 
665
        find_frames(&frames, &animcurves);
 
666
 
 
667
        float irest_dae[4][4];
 
668
        float rest[4][4], irest[4][4];
 
669
 
 
670
        if (is_joint) {
 
671
                get_joint_rest_mat(irest_dae, root, node);
 
672
                invert_m4(irest_dae);
 
673
 
 
674
                Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
 
675
                if (!bone) {
 
676
                        fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
 
677
                        return;
 
678
                }
 
679
 
 
680
                unit_m4(rest);
 
681
                copy_m4_m4(rest, bone->arm_mat);
 
682
                invert_m4_m4(irest, rest);
 
683
        }
 
684
        // new curves to assign matrix transform animation
 
685
        FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
 
686
        unsigned int totcu = 10;
 
687
        const char *tm_str = NULL;
 
688
        char rna_path[200];
 
689
        for (int i = 0; i < totcu; i++) {
 
690
 
 
691
                int axis = i;
 
692
 
 
693
                if (i < 4) {
 
694
                        tm_str = "rotation_quaternion";
 
695
                        axis = i;
 
696
                }
 
697
                else if (i < 7) {
 
698
                        tm_str = "location";
 
699
                        axis = i - 4;
 
700
                }
 
701
                else {
 
702
                        tm_str = "scale";
 
703
                        axis = i - 7;
 
704
                }
 
705
 
 
706
 
 
707
                if (is_joint)
 
708
                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
 
709
                else
 
710
                        BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
 
711
                newcu[i] = create_fcurve(axis, rna_path);
 
712
                newcu[i]->totvert = frames.size();
 
713
        }
 
714
 
 
715
        if (frames.size() == 0)
 
716
                return;
 
717
 
 
718
        std::sort(frames.begin(), frames.end());
 
719
 
 
720
        std::vector<float>::iterator it;
 
721
 
 
722
        // sample values at each frame
 
723
        for (it = frames.begin(); it != frames.end(); it++) {
 
724
                float fra = *it;
 
725
 
 
726
                float mat[4][4];
 
727
                float matfra[4][4];
 
728
 
 
729
                unit_m4(matfra);
 
730
 
 
731
                // calc object-space mat
 
732
                evaluate_transform_at_frame(matfra, node, fra);
 
733
 
 
734
 
 
735
                // for joints, we need a special matrix
 
736
                if (is_joint) {
 
737
                        // special matrix: iR * M * iR_dae * R
 
738
                        // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
 
739
                        // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
 
740
                        float temp[4][4], par[4][4];
 
741
 
 
742
                        // calc M
 
743
                        calc_joint_parent_mat_rest(par, NULL, root, node);
 
744
                        mult_m4_m4m4(temp, par, matfra);
 
745
 
 
746
                        // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
 
747
 
 
748
                        // calc special matrix
 
749
                        mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
 
750
                }
 
751
                else {
 
752
                        copy_m4_m4(mat, matfra);
 
753
                }
 
754
 
 
755
                float  rot[4], loc[3], scale[3];
 
756
 
 
757
                mat4_to_quat(rot, mat);
 
758
                /*for ( int i = 0 ; i < 4  ;  i ++ )
 
759
                {
 
760
                rot[i] = RAD2DEGF(rot[i]);
 
761
                }*/
 
762
                copy_v3_v3(loc, mat[3]);
 
763
                mat4_to_size(scale, mat);
 
764
 
 
765
                // add keys
 
766
                for (int i = 0; i < totcu; i++) {
 
767
                        if (i < 4)
 
768
                                add_bezt(newcu[i], fra, rot[i]);
 
769
                        else if (i < 7)
 
770
                                add_bezt(newcu[i], fra, loc[i - 4]);
 
771
                        else
 
772
                                add_bezt(newcu[i], fra, scale[i - 7]);
 
773
                }
 
774
        }
 
775
        verify_adt_action((ID*)&ob->id, 1);
 
776
 
 
777
        ListBase *curves = &ob->adt->action->curves;
 
778
 
 
779
        // add curves
 
780
        for (int i= 0; i < totcu; i++) {
 
781
                if (is_joint)
 
782
                        add_bone_fcurve(ob, node, newcu[i]);
 
783
                else
 
784
                        BLI_addtail(curves, newcu[i]);
 
785
        }
 
786
 
 
787
        if (is_joint) {
 
788
                bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
 
789
                chan->rotmode = ROT_MODE_QUAT;
 
790
        }
 
791
        else {
 
792
                ob->rotmode = ROT_MODE_QUAT;
 
793
        }
 
794
 
 
795
        return;
 
796
 
 
797
}
 
798
 
 
799
void AnimationImporter::translate_Animations ( COLLADAFW::Node * node , 
 
800
                                                                                                   std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
 
801
                                                                                                   std::map<COLLADAFW::UniqueId, Object*>& object_map,
 
802
                                                                                                   std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map)
 
803
{
 
804
        AnimationImporter::AnimMix* animType = get_animation_type(node, FW_object_map );
 
805
 
 
806
        bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
 
807
        COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
 
808
        Object *ob = is_joint ? armature_importer->get_armature_for_joint(root) : object_map[node->getUniqueId()];
 
809
        if (!ob)
 
810
        {
 
811
                fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
 
812
                return;
 
813
        }
 
814
 
 
815
        bAction * act;
 
816
 
 
817
        if ( (animType->transform) != 0 )
 
818
        {
 
819
                const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
 
820
                char joint_path[200];
 
821
 
 
822
                if ( is_joint ) 
 
823
                        armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
 
824
 
 
825
 
 
826
                if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
 
827
                else act = ob->adt->action;
 
828
 
 
829
                //Get the list of animation curves of the object
 
830
                ListBase *AnimCurves = &(act->curves);
 
831
 
 
832
                const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
 
833
 
 
834
                //for each transformation in node 
 
835
                for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
 
836
                        COLLADAFW::Transformation *transform = nodeTransforms[i];
 
837
                        COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
 
838
 
 
839
                        bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
 
840
                        bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
 
841
 
 
842
                        const COLLADAFW::UniqueId& listid = transform->getAnimationList();
 
843
 
 
844
                        //check if transformation has animations
 
845
                        if (animlist_map.find(listid) == animlist_map.end()) {
 
846
                                continue;
 
847
                        }
 
848
                        else {
 
849
                                //transformation has animations
 
850
                                const COLLADAFW::AnimationList *animlist = animlist_map[listid];
 
851
                                const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
 
852
                                //all the curves belonging to the current binding
 
853
                                std::vector<FCurve*> animcurves;
 
854
                                for (unsigned int j = 0; j < bindings.getCount(); j++) {
 
855
                                        animcurves = curve_map[bindings[j].animation];
 
856
                                        if ( is_matrix ) {
 
857
                                                apply_matrix_curves(ob, animcurves, root , node,  transform  );
 
858
                                        }
 
859
                                        else {                          
 
860
 
 
861
                                                if (is_joint) {
 
862
 
 
863
                                                        add_bone_animation_sampled(ob, animcurves, root, node, transform);
 
864
                                                }
 
865
                                                else {
 
866
                                                        //calculate rnapaths and array index of fcurves according to transformation and animation class
 
867
                                                        Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path ); 
 
868
 
 
869
                                                        std::vector<FCurve*>::iterator iter;
 
870
                                                        //Add the curves of the current animation to the object
 
871
                                                        for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
 
872
                                                                FCurve * fcu = *iter;
 
873
                                                        
 
874
                                                                BLI_addtail(AnimCurves, fcu);
 
875
                                                        }
 
876
                                                }
 
877
                                                
 
878
                                        }
 
879
                                }
 
880
                        }
 
881
                        if (is_rotation && !is_joint) {
 
882
                                ob->rotmode = ROT_MODE_EUL;
 
883
                        }
 
884
                }
 
885
        }
 
886
 
 
887
        if ((animType->light) != 0)
 
888
        {
 
889
                Lamp * lamp  = (Lamp*) ob->data;
 
890
 
 
891
                if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID*)&lamp->id, 1);
 
892
                else act = lamp->adt->action;
 
893
 
 
894
                ListBase *AnimCurves = &(act->curves);
 
895
                const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
 
896
 
 
897
                for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
 
898
                        const COLLADAFW::Light *light = (COLLADAFW::Light *) FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
 
899
 
 
900
                        if ((animType->light & LIGHT_COLOR) != 0)
 
901
                        {
 
902
                                const COLLADAFW::Color *col =  &(light->getColor());
 
903
                                const COLLADAFW::UniqueId& listid = col->getAnimationList();
 
904
 
 
905
                                Assign_color_animations(listid, AnimCurves, "color"); 
 
906
                        }
 
907
                        if ((animType->light & LIGHT_FOA) != 0 )
 
908
                        {
 
909
                                const COLLADAFW::AnimatableFloat *foa =  &(light->getFallOffAngle());
 
910
                                const COLLADAFW::UniqueId& listid = foa->getAnimationList();
 
911
 
 
912
                                Assign_float_animations( listid ,AnimCurves, "spot_size"); 
 
913
                        }
 
914
                        if ( (animType->light & LIGHT_FOE) != 0 )
 
915
                        {
 
916
                                const COLLADAFW::AnimatableFloat *foe =  &(light->getFallOffExponent());
 
917
                                const COLLADAFW::UniqueId& listid = foe->getAnimationList();
 
918
 
 
919
                                Assign_float_animations( listid ,AnimCurves, "spot_blend"); 
 
920
 
 
921
                        }
 
922
                }
 
923
        }
 
924
 
 
925
        if ( (animType->camera) != 0) 
 
926
        {
 
927
                Camera * camera  = (Camera*) ob->data;
 
928
 
 
929
                if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID*)&camera->id, 1);
 
930
                else act = camera->adt->action;
 
931
 
 
932
                ListBase *AnimCurves = &(act->curves);
 
933
                const COLLADAFW::InstanceCameraPointerArray& nodeCameras= node->getInstanceCameras();
 
934
 
 
935
                for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
 
936
                        const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
 
937
 
 
938
                        if ((animType->camera & CAMERA_XFOV) != 0 )
 
939
                        {
 
940
                                const COLLADAFW::AnimatableFloat *xfov =  &(camera->getXFov());
 
941
                                const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
 
942
                                Assign_float_animations( listid ,AnimCurves, "lens"); 
 
943
                        }
 
944
 
 
945
                        else if ((animType->camera & CAMERA_XMAG) != 0 )
 
946
                        {
 
947
                                const COLLADAFW::AnimatableFloat *xmag =  &(camera->getXMag());
 
948
                                const COLLADAFW::UniqueId& listid = xmag->getAnimationList();
 
949
                                Assign_float_animations( listid ,AnimCurves, "ortho_scale"); 
 
950
                        }
 
951
 
 
952
                        if ((animType->camera & CAMERA_ZFAR) != 0 )
 
953
                        {
 
954
                                const COLLADAFW::AnimatableFloat *zfar =  &(camera->getFarClippingPlane());
 
955
                                const COLLADAFW::UniqueId& listid = zfar->getAnimationList();
 
956
                                Assign_float_animations( listid ,AnimCurves, "clip_end"); 
 
957
                        }
 
958
 
 
959
                        if ((animType->camera & CAMERA_ZNEAR) != 0 )
 
960
                        {
 
961
                                const COLLADAFW::AnimatableFloat *znear =  &(camera->getNearClippingPlane());
 
962
                                const COLLADAFW::UniqueId& listid = znear->getAnimationList();
 
963
                                Assign_float_animations( listid ,AnimCurves, "clip_start"); 
 
964
                        }
 
965
 
 
966
                }
 
967
        }
 
968
        if ( animType->material != 0) {
 
969
                Material *ma = give_current_material(ob, 1);
 
970
                if (!ma->adt || !ma->adt->action) act = verify_adt_action((ID*)&ma->id, 1);
 
971
                else act = ma->adt->action;
 
972
 
 
973
                ListBase *AnimCurves = &(act->curves);
 
974
 
 
975
                const COLLADAFW::InstanceGeometryPointerArray& nodeGeoms = node->getInstanceGeometries();
 
976
                for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
 
977
                        const COLLADAFW::MaterialBindingArray& matBinds = nodeGeoms[i]->getMaterialBindings();
 
978
                        for (unsigned int j = 0; j < matBinds.getCount(); j++) {
 
979
                                const COLLADAFW::UniqueId & matuid = matBinds[j].getReferencedMaterial();
 
980
                                const COLLADAFW::Effect *ef = (COLLADAFW::Effect *) (FW_object_map[matuid]);
 
981
                                if (ef != NULL) { /* can be NULL [#28909] */
 
982
                                        const COLLADAFW::CommonEffectPointerArray& commonEffects  =  ef->getCommonEffects();
 
983
                                        COLLADAFW::EffectCommon *efc = commonEffects[0];
 
984
                                        if ((animType->material & MATERIAL_SHININESS) != 0) {
 
985
                                                const COLLADAFW::FloatOrParam *shin = &(efc->getShininess());
 
986
                                                const COLLADAFW::UniqueId& listid =  shin->getAnimationList();
 
987
                                                Assign_float_animations( listid, AnimCurves , "specular_hardness" );
 
988
                                        }
 
989
 
 
990
                                        if ((animType->material & MATERIAL_IOR) != 0) {
 
991
                                                const COLLADAFW::FloatOrParam *ior = &(efc->getIndexOfRefraction());
 
992
                                                const COLLADAFW::UniqueId& listid =  ior->getAnimationList();
 
993
                                                Assign_float_animations( listid, AnimCurves , "raytrace_transparency.ior" );
 
994
                                        }
 
995
 
 
996
                                        if ((animType->material & MATERIAL_SPEC_COLOR) != 0) {
 
997
                                                const COLLADAFW::ColorOrTexture *cot = &(efc->getSpecular());
 
998
                                                const COLLADAFW::UniqueId& listid =  cot->getColor().getAnimationList();
 
999
                                                Assign_color_animations( listid, AnimCurves , "specular_color" );
 
1000
                                        }
 
1001
 
 
1002
                                        if ((animType->material & MATERIAL_DIFF_COLOR) != 0) {
 
1003
                                                const COLLADAFW::ColorOrTexture *cot = &(efc->getDiffuse());
 
1004
                                                const COLLADAFW::UniqueId& listid =  cot->getColor().getAnimationList();
 
1005
                                                Assign_color_animations( listid, AnimCurves , "diffuse_color" );
 
1006
                                        }
 
1007
                                }
 
1008
                        }
 
1009
                }       
 
1010
        }
 
1011
}
 
1012
 
 
1013
void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm)
 
1014
{
 
1015
        const char *bone_name = bc_get_joint_name(node);
 
1016
        char joint_path[200];
 
1017
        armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
 
1018
 
 
1019
        std::vector<float> frames;
 
1020
        find_frames(&frames, &animcurves);
 
1021
 
 
1022
        // convert degrees to radians
 
1023
        if (tm->getTransformationType() == COLLADAFW::Transformation::ROTATE) {
 
1024
 
 
1025
                std::vector<FCurve*>::iterator iter;
 
1026
                for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
 
1027
                        FCurve* fcu = *iter;
 
1028
 
 
1029
                        fcurve_deg_to_rad(fcu);          
 
1030
                }                                       
 
1031
        }
 
1032
 
 
1033
 
 
1034
        float irest_dae[4][4];
 
1035
        float rest[4][4], irest[4][4];
 
1036
 
 
1037
        get_joint_rest_mat(irest_dae, root, node);
 
1038
        invert_m4(irest_dae);
 
1039
 
 
1040
        Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
 
1041
        if (!bone) {
 
1042
                fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
 
1043
                return;
 
1044
        }
 
1045
 
 
1046
        unit_m4(rest);
 
1047
        copy_m4_m4(rest, bone->arm_mat);
 
1048
        invert_m4_m4(irest, rest);
 
1049
 
 
1050
        // new curves to assign matrix transform animation
 
1051
        FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
 
1052
        unsigned int totcu = 10;
 
1053
        const char *tm_str = NULL;
 
1054
        char rna_path[200];
 
1055
        for (int i = 0; i < totcu; i++) {
 
1056
 
 
1057
                int axis = i;
 
1058
 
 
1059
                if (i < 4) {
 
1060
                        tm_str = "rotation_quaternion";
 
1061
                        axis = i;
 
1062
                }
 
1063
                else if (i < 7) {
 
1064
                        tm_str = "location";
 
1065
                        axis = i - 4;
 
1066
                }
 
1067
                else {
 
1068
                        tm_str = "scale";
 
1069
                        axis = i - 7;
 
1070
                }
 
1071
 
 
1072
 
 
1073
                BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
 
1074
 
 
1075
                newcu[i] = create_fcurve(axis, rna_path);
 
1076
                newcu[i]->totvert = frames.size();
 
1077
        }
 
1078
 
 
1079
        if (frames.size() == 0)
 
1080
                return;
 
1081
 
 
1082
        std::sort(frames.begin(), frames.end());
 
1083
 
 
1084
        std::vector<float>::iterator it;
 
1085
 
 
1086
        // sample values at each frame
 
1087
        for (it = frames.begin(); it != frames.end(); it++) {
 
1088
                float fra = *it;
 
1089
 
 
1090
                float mat[4][4];
 
1091
                float matfra[4][4];
 
1092
 
 
1093
                unit_m4(matfra);
 
1094
 
 
1095
                // calc object-space mat
 
1096
                evaluate_transform_at_frame(matfra, node, fra);
 
1097
 
 
1098
 
 
1099
                // for joints, we need a special matrix
 
1100
                // special matrix: iR * M * iR_dae * R
 
1101
                // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
 
1102
                // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
 
1103
                float temp[4][4], par[4][4];
 
1104
 
 
1105
 
 
1106
                // calc M
 
1107
                calc_joint_parent_mat_rest(par, NULL, root, node);
 
1108
                mult_m4_m4m4(temp, par, matfra);
 
1109
 
 
1110
                // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
 
1111
 
 
1112
                // calc special matrix
 
1113
                mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
 
1114
 
 
1115
                float  rot[4], loc[3], scale[3];
 
1116
 
 
1117
                mat4_to_quat(rot, mat);
 
1118
                copy_v3_v3(loc, mat[3]);
 
1119
                mat4_to_size(scale, mat);
 
1120
 
 
1121
                // add keys
 
1122
                for (int i = 0; i < totcu; i++) {
 
1123
                        if (i < 4)
 
1124
                                add_bezt(newcu[i], fra, rot[i]);
 
1125
                        else if (i < 7)
 
1126
                                add_bezt(newcu[i], fra, loc[i - 4]);
 
1127
                        else
 
1128
                                add_bezt(newcu[i], fra, scale[i - 7]);
 
1129
                }
 
1130
        }
 
1131
        verify_adt_action((ID*)&ob->id, 1);
 
1132
 
 
1133
        // add curves
 
1134
        for (int i= 0; i < totcu; i++) {
 
1135
                add_bone_fcurve(ob, node, newcu[i]);
 
1136
        }
 
1137
 
 
1138
        bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
 
1139
        chan->rotmode = ROT_MODE_QUAT;
 
1140
 
 
1141
}
 
1142
 
 
1143
 
 
1144
//Check if object is animated by checking if animlist_map holds the animlist_id of node transforms
 
1145
AnimationImporter::AnimMix* AnimationImporter::get_animation_type ( const COLLADAFW::Node * node , 
 
1146
                                                                                        std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map) 
 
1147
{
 
1148
        AnimMix *types = new AnimMix();
 
1149
 
 
1150
        const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
 
1151
 
 
1152
        //for each transformation in node 
 
1153
        for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) {
 
1154
                COLLADAFW::Transformation *transform = nodeTransforms[i];
 
1155
                const COLLADAFW::UniqueId& listid = transform->getAnimationList();
 
1156
 
 
1157
                //check if transformation has animations
 
1158
                if (animlist_map.find(listid) == animlist_map.end()) {
 
1159
                        continue;
 
1160
                }
 
1161
                else {
 
1162
                        types->transform = types->transform|NODE_TRANSFORM;
 
1163
                        break;
 
1164
                }
 
1165
        }
 
1166
        const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
 
1167
 
 
1168
        for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
 
1169
                const COLLADAFW::Light *light = (COLLADAFW::Light *) FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
 
1170
                types->light = setAnimType(&(light->getColor()),(types->light), LIGHT_COLOR);
 
1171
                types->light = setAnimType(&(light->getFallOffAngle()),(types->light), LIGHT_FOA);
 
1172
                types->light = setAnimType(&(light->getFallOffExponent()),(types->light), LIGHT_FOE);
 
1173
 
 
1174
                if ( types->light != 0) break;
 
1175
 
 
1176
        }
 
1177
 
 
1178
        const COLLADAFW::InstanceCameraPointerArray& nodeCameras = node->getInstanceCameras();
 
1179
        for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
 
1180
                const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
 
1181
 
 
1182
                if ( camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE )
 
1183
                {
 
1184
                        types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XFOV);
 
1185
                }
 
1186
                else
 
1187
                {
 
1188
                        types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XMAG);
 
1189
                }
 
1190
                types->camera = setAnimType(&(camera->getFarClippingPlane()),(types->camera), CAMERA_ZFAR);
 
1191
                types->camera = setAnimType(&(camera->getNearClippingPlane()),(types->camera), CAMERA_ZNEAR);
 
1192
 
 
1193
                if ( types->camera != 0) break;
 
1194
 
 
1195
        }
 
1196
 
 
1197
        const COLLADAFW::InstanceGeometryPointerArray& nodeGeoms = node->getInstanceGeometries();
 
1198
        for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) {
 
1199
                const COLLADAFW::MaterialBindingArray& matBinds = nodeGeoms[i]->getMaterialBindings();
 
1200
                for (unsigned int j = 0; j < matBinds.getCount(); j++) {
 
1201
                        const COLLADAFW::UniqueId & matuid = matBinds[j].getReferencedMaterial();
 
1202
                        const COLLADAFW::Effect *ef = (COLLADAFW::Effect *) (FW_object_map[matuid]);
 
1203
                        if (ef != NULL) { /* can be NULL [#28909] */
 
1204
                                const COLLADAFW::CommonEffectPointerArray& commonEffects = ef->getCommonEffects();
 
1205
                                if (!commonEffects.empty()) {
 
1206
                                        COLLADAFW::EffectCommon *efc = commonEffects[0];
 
1207
                                        types->material =  setAnimType(&(efc->getShininess()),(types->material), MATERIAL_SHININESS);
 
1208
                                        types->material =  setAnimType(&(efc->getSpecular().getColor()),(types->material), MATERIAL_SPEC_COLOR);
 
1209
                                        types->material =  setAnimType(&(efc->getDiffuse().getColor()),(types->material), MATERIAL_DIFF_COLOR);
 
1210
                                        // types->material =  setAnimType(&(efc->get()),(types->material), MATERIAL_TRANSPARENCY);
 
1211
                                        types->material =  setAnimType(&(efc->getIndexOfRefraction()),(types->material), MATERIAL_IOR);
 
1212
                                }
 
1213
                        }
 
1214
                }
 
1215
        }
 
1216
        return types;
 
1217
}
 
1218
 
 
1219
int AnimationImporter::setAnimType ( const COLLADAFW::Animatable * prop , int types, int addition)
 
1220
{
 
1221
        const COLLADAFW::UniqueId& listid =  prop->getAnimationList();
 
1222
        if (animlist_map.find(listid) != animlist_map.end())
 
1223
                return types|addition;
 
1224
        else return types;
 
1225
}               
 
1226
 
 
1227
// Is not used anymore.
 
1228
void AnimationImporter::find_frames_old(std::vector<float> * frames, COLLADAFW::Node * node , COLLADAFW::Transformation::TransformationType tm_type)
 
1229
{
 
1230
        bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
 
1231
        bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
 
1232
        // for each <rotate>, <translate>, etc. there is a separate Transformation
 
1233
        const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
 
1234
 
 
1235
        unsigned int i;
 
1236
        // find frames at which to sample plus convert all rotation keys to radians
 
1237
        for (i = 0; i < nodeTransforms.getCount(); i++) {
 
1238
                COLLADAFW::Transformation *transform = nodeTransforms[i];
 
1239
                COLLADAFW::Transformation::TransformationType nodeTmType = transform->getTransformationType();
 
1240
 
 
1241
 
 
1242
                if (nodeTmType == tm_type) {
 
1243
                        //get animation bindings for the current transformation
 
1244
                        const COLLADAFW::UniqueId& listid = transform->getAnimationList();
 
1245
                        //if transform is animated its animlist must exist.
 
1246
                        if (animlist_map.find(listid) != animlist_map.end()) {
 
1247
                                
 
1248
                                const COLLADAFW::AnimationList *animlist = animlist_map[listid];
 
1249
                                const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
 
1250
 
 
1251
                                if (bindings.getCount()) {
 
1252
                                        //for each AnimationBinding get the fcurves which animate the transform
 
1253
                                        for (unsigned int j = 0; j < bindings.getCount(); j++) {
 
1254
                                                std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
 
1255
                                                bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE || nodeTmType == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
 
1256
 
 
1257
                                                if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
 
1258
                                                        std::vector<FCurve*>::iterator iter;
 
1259
 
 
1260
                                                        for (iter = curves.begin(); iter != curves.end(); iter++) {
 
1261
                                                                FCurve *fcu = *iter;
 
1262
 
 
1263
                                                                //if transform is rotation the fcurves values must be turned in to radian.
 
1264
                                                                if (is_rotation)
 
1265
                                                                        fcurve_deg_to_rad(fcu);
 
1266
 
 
1267
                                                                for (unsigned int k = 0; k < fcu->totvert; k++) {
 
1268
                                                                        //get frame value from bezTriple
 
1269
                                                                        float fra = fcu->bezt[k].vec[1][0];
 
1270
                                                                        //if frame already not added add frame to frames
 
1271
                                                                        if (std::find(frames->begin(), frames->end(), fra) == frames->end())
 
1272
                                                                                frames->push_back(fra);
 
1273
                                                                }
 
1274
                                                        }
 
1275
                                                }
 
1276
                                                else {
 
1277
                                                        fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size());
 
1278
                                                }
 
1279
                                        }
 
1280
                                }
 
1281
                        }
 
1282
                }
 
1283
        }
 
1284
}
 
1285
 
 
1286
 
 
1287
 
 
1288
// prerequisites:
 
1289
// animlist_map - map animlist id -> animlist
 
1290
// curve_map - map anim id -> curve(s)
 
1291
Object *AnimationImporter::translate_animation_OLD(COLLADAFW::Node *node,
 
1292
                                                        std::map<COLLADAFW::UniqueId, Object*>& object_map,
 
1293
                                                        std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
 
1294
                                                        COLLADAFW::Transformation::TransformationType tm_type,
 
1295
                                                        Object *par_job)
 
1296
{
 
1297
        
 
1298
        bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
 
1299
        bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
 
1300
        bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
 
1301
        
 
1302
        COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
 
1303
        Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
 
1304
        const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
 
1305
        if (!ob) {
 
1306
                fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
 
1307
                return NULL;
 
1308
        }
 
1309
 
 
1310
        // frames at which to sample
 
1311
        std::vector<float> frames;
 
1312
        
 
1313
        find_frames_old(&frames, node , tm_type);
 
1314
        
 
1315
        unsigned int i;
 
1316
        
 
1317
        float irest_dae[4][4];
 
1318
        float rest[4][4], irest[4][4];
 
1319
 
 
1320
        if (is_joint) {
 
1321
                get_joint_rest_mat(irest_dae, root, node);
 
1322
                invert_m4(irest_dae);
 
1323
 
 
1324
                Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
 
1325
                if (!bone) {
 
1326
                        fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
 
1327
                        return NULL;
 
1328
                }
 
1329
 
 
1330
                unit_m4(rest);
 
1331
                copy_m4_m4(rest, bone->arm_mat);
 
1332
                invert_m4_m4(irest, rest);
 
1333
        }
 
1334
 
 
1335
        Object *job = NULL;
 
1336
 
 
1337
#ifdef ARMATURE_TEST
 
1338
        FCurve *job_curves[10];
 
1339
        job = get_joint_object(root, node, par_job);
 
1340
#endif
 
1341
 
 
1342
        if (frames.size() == 0)
 
1343
                return job;
 
1344
 
 
1345
        std::sort(frames.begin(), frames.end());
 
1346
 
 
1347
        const char *tm_str = NULL;
 
1348
        switch (tm_type) {
 
1349
        case COLLADAFW::Transformation::ROTATE:
 
1350
                tm_str = "rotation_quaternion";
 
1351
                break;
 
1352
        case COLLADAFW::Transformation::SCALE:
 
1353
                tm_str = "scale";
 
1354
                break;
 
1355
        case COLLADAFW::Transformation::TRANSLATE:
 
1356
                tm_str = "location";
 
1357
                break;
 
1358
        case COLLADAFW::Transformation::MATRIX:
 
1359
                break;
 
1360
        default:
 
1361
                return job;
 
1362
        }
 
1363
 
 
1364
        char rna_path[200];
 
1365
        char joint_path[200];
 
1366
 
 
1367
        if (is_joint)
 
1368
                armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
 
1369
 
 
1370
        // new curves
 
1371
        FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
 
1372
        unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
 
1373
 
 
1374
        for (i = 0; i < totcu; i++) {
 
1375
 
 
1376
                int axis = i;
 
1377
 
 
1378
                if (is_matrix) {
 
1379
                        if (i < 4) {
 
1380
                                tm_str = "rotation_quaternion";
 
1381
                                axis = i;
 
1382
                        }
 
1383
                        else if (i < 7) {
 
1384
                                tm_str = "location";
 
1385
                                axis = i - 4;
 
1386
                        }
 
1387
                        else {
 
1388
                                tm_str = "scale";
 
1389
                                axis = i - 7;
 
1390
                        }
 
1391
                }
 
1392
 
 
1393
                if (is_joint)
 
1394
                        BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
 
1395
                else
 
1396
                        BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
 
1397
                newcu[i] = create_fcurve(axis, rna_path);
 
1398
 
 
1399
#ifdef ARMATURE_TEST
 
1400
                if (is_joint)
 
1401
                        job_curves[i] = create_fcurve(axis, tm_str);
 
1402
#endif
 
1403
        }
 
1404
 
 
1405
        std::vector<float>::iterator it;
 
1406
 
 
1407
        // sample values at each frame
 
1408
        for (it = frames.begin(); it != frames.end(); it++) {
 
1409
                float fra = *it;
 
1410
 
 
1411
                float mat[4][4];
 
1412
                float matfra[4][4];
 
1413
 
 
1414
                unit_m4(matfra);
 
1415
 
 
1416
                // calc object-space mat
 
1417
                evaluate_transform_at_frame(matfra, node, fra);
 
1418
 
 
1419
                // for joints, we need a special matrix
 
1420
                if (is_joint) {
 
1421
                        // special matrix: iR * M * iR_dae * R
 
1422
                        // where R, iR are bone rest and inverse rest mats in world space (Blender bones),
 
1423
                        // iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
 
1424
                        float temp[4][4], par[4][4];
 
1425
 
 
1426
                        // calc M
 
1427
                        calc_joint_parent_mat_rest(par, NULL, root, node);
 
1428
                        mult_m4_m4m4(temp, par, matfra);
 
1429
 
 
1430
                        // evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
 
1431
 
 
1432
                        // calc special matrix
 
1433
                        mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
 
1434
                }
 
1435
                else {
 
1436
                        copy_m4_m4(mat, matfra);
 
1437
                }
 
1438
 
 
1439
                float val[4], rot[4], loc[3], scale[3];
 
1440
 
 
1441
                switch (tm_type) {
 
1442
                case COLLADAFW::Transformation::ROTATE:
 
1443
                        mat4_to_quat(val, mat);
 
1444
                        break;
 
1445
                case COLLADAFW::Transformation::SCALE:
 
1446
                        mat4_to_size(val, mat);
 
1447
                        break;
 
1448
                case COLLADAFW::Transformation::TRANSLATE:
 
1449
                        copy_v3_v3(val, mat[3]);
 
1450
                        break;
 
1451
                case COLLADAFW::Transformation::MATRIX:
 
1452
                        mat4_to_quat(rot, mat);
 
1453
                        copy_v3_v3(loc, mat[3]);
 
1454
                        mat4_to_size(scale, mat);
 
1455
                        break;
 
1456
                default:
 
1457
                        break;
 
1458
                }
 
1459
 
 
1460
                // add keys
 
1461
                for (i = 0; i < totcu; i++) {
 
1462
                        if (is_matrix) {
 
1463
                                if (i < 4)
 
1464
                                        add_bezt(newcu[i], fra, rot[i]);
 
1465
                                else if (i < 7)
 
1466
                                        add_bezt(newcu[i], fra, loc[i - 4]);
 
1467
                                else
 
1468
                                        add_bezt(newcu[i], fra, scale[i - 7]);
 
1469
                        }
 
1470
                        else {
 
1471
                                add_bezt(newcu[i], fra, val[i]);
 
1472
                        }
 
1473
                }
 
1474
 
 
1475
#ifdef ARMATURE_TEST
 
1476
                if (is_joint) {
 
1477
                        switch (tm_type) {
 
1478
                        case COLLADAFW::Transformation::ROTATE:
 
1479
                                mat4_to_quat(val, matfra);
 
1480
                                break;
 
1481
                        case COLLADAFW::Transformation::SCALE:
 
1482
                                mat4_to_size(val, matfra);
 
1483
                                break;
 
1484
                        case COLLADAFW::Transformation::TRANSLATE:
 
1485
                                copy_v3_v3(val, matfra[3]);
 
1486
                                break;
 
1487
                        case MATRIX:
 
1488
                                mat4_to_quat(rot, matfra);
 
1489
                                copy_v3_v3(loc, matfra[3]);
 
1490
                                mat4_to_size(scale, matfra);
 
1491
                                break;
 
1492
                        default:
 
1493
                                break;
 
1494
                        }
 
1495
 
 
1496
                        for (i = 0; i < totcu; i++) {
 
1497
                                if (is_matrix) {
 
1498
                                        if (i < 4)
 
1499
                                                add_bezt(job_curves[i], fra, rot[i]);
 
1500
                                        else if (i < 7)
 
1501
                                                add_bezt(job_curves[i], fra, loc[i - 4]);
 
1502
                                        else
 
1503
                                                add_bezt(job_curves[i], fra, scale[i - 7]);
 
1504
                                }
 
1505
                                else {
 
1506
                                        add_bezt(job_curves[i], fra, val[i]);
 
1507
                                }
 
1508
                        }
 
1509
                }
 
1510
#endif
 
1511
        }
 
1512
 
 
1513
        verify_adt_action((ID*)&ob->id, 1);
 
1514
 
 
1515
        ListBase *curves = &ob->adt->action->curves;
 
1516
 
 
1517
        // add curves
 
1518
        for (i = 0; i < totcu; i++) {
 
1519
                if (is_joint)
 
1520
                        add_bone_fcurve(ob, node, newcu[i]);
 
1521
                else
 
1522
                        BLI_addtail(curves, newcu[i]);
 
1523
 
 
1524
#ifdef ARMATURE_TEST
 
1525
                if (is_joint)
 
1526
                        BLI_addtail(&job->adt->action->curves, job_curves[i]);
 
1527
#endif
 
1528
        }
 
1529
 
 
1530
        if (is_rotation || is_matrix) {
 
1531
                if (is_joint) {
 
1532
                        bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
 
1533
                        chan->rotmode = ROT_MODE_QUAT;
 
1534
                }
 
1535
                else {
 
1536
                        ob->rotmode = ROT_MODE_QUAT;
 
1537
                }
 
1538
        }
 
1539
 
 
1540
        return job;
 
1541
}
 
1542
 
 
1543
// internal, better make it private
 
1544
// warning: evaluates only rotation and only assigns matrix transforms now
 
1545
// prerequisites: animlist_map, curve_map
 
1546
void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
 
1547
{
 
1548
        const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
 
1549
 
 
1550
        unit_m4(mat);
 
1551
 
 
1552
        for (unsigned int i = 0; i < tms.getCount(); i++) {
 
1553
                COLLADAFW::Transformation *tm = tms[i];
 
1554
                COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
 
1555
                float m[4][4];
 
1556
 
 
1557
                unit_m4(m);
 
1558
 
 
1559
                std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
 
1560
                if (!evaluate_animation(tm, m, fra, nodename.c_str())) {
 
1561
                        switch (type) {
 
1562
                        case COLLADAFW::Transformation::ROTATE:
 
1563
                                dae_rotate_to_mat4(tm, m);
 
1564
                                break;
 
1565
                        case COLLADAFW::Transformation::TRANSLATE:
 
1566
                                dae_translate_to_mat4(tm, m);
 
1567
                                break;
 
1568
                        case COLLADAFW::Transformation::SCALE:
 
1569
                                dae_scale_to_mat4(tm, m);
 
1570
                                break;
 
1571
                        case COLLADAFW::Transformation::MATRIX:
 
1572
                                dae_matrix_to_mat4(tm, m);
 
1573
                                break;
 
1574
                        default:
 
1575
                                fprintf(stderr, "unsupported transformation type %d\n", type);
 
1576
                        }
 
1577
                        // dae_matrix_to_mat4(tm, m);
 
1578
                        
 
1579
                }
 
1580
 
 
1581
                float temp[4][4];
 
1582
                copy_m4_m4(temp, mat);
 
1583
 
 
1584
                mult_m4_m4m4(mat, temp, m);
 
1585
        }
 
1586
}
 
1587
 
 
1588
// return true to indicate that mat contains a sane value
 
1589
bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id)
 
1590
{
 
1591
        const COLLADAFW::UniqueId& listid = tm->getAnimationList();
 
1592
        COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
 
1593
 
 
1594
        if (type != COLLADAFW::Transformation::ROTATE &&
 
1595
                type != COLLADAFW::Transformation::SCALE &&
 
1596
                type != COLLADAFW::Transformation::TRANSLATE &&
 
1597
                type != COLLADAFW::Transformation::MATRIX) {
 
1598
                fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
 
1599
                return false;
 
1600
        }
 
1601
 
 
1602
        if (animlist_map.find(listid) == animlist_map.end())
 
1603
                return false;
 
1604
 
 
1605
        const COLLADAFW::AnimationList *animlist = animlist_map[listid];
 
1606
        const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
 
1607
 
 
1608
        if (bindings.getCount()) {
 
1609
                float vec[3];
 
1610
 
 
1611
                bool is_scale = (type == COLLADAFW::Transformation::SCALE);
 
1612
                bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
 
1613
 
 
1614
                if (is_scale)
 
1615
                        dae_scale_to_v3(tm, vec);
 
1616
                else if (is_translate)
 
1617
                        dae_translate_to_v3(tm, vec);
 
1618
 
 
1619
                for (unsigned int j = 0; j < bindings.getCount(); j++) {
 
1620
                        const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j];
 
1621
                        std::vector<FCurve*>& curves = curve_map[binding.animation];
 
1622
                        COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
 
1623
                        char path[100];
 
1624
 
 
1625
                        switch (type) {
 
1626
                        case COLLADAFW::Transformation::ROTATE:
 
1627
                                BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j);
 
1628
                                break;
 
1629
                        case COLLADAFW::Transformation::SCALE:
 
1630
                                BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j);
 
1631
                                break;
 
1632
                        case COLLADAFW::Transformation::TRANSLATE:
 
1633
                                BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j);
 
1634
                                break;
 
1635
                        case COLLADAFW::Transformation::MATRIX:
 
1636
                                BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j);
 
1637
                                break;
 
1638
                        default:
 
1639
                                break;
 
1640
                        }
 
1641
 
 
1642
                        if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
 
1643
                                fprintf(stderr, "%s: UNKNOWN animation class\n", path);
 
1644
                                //continue;
 
1645
                        }
 
1646
 
 
1647
                        if (type == COLLADAFW::Transformation::ROTATE) {
 
1648
                                if (curves.size() != 1) {
 
1649
                                        fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size());
 
1650
                                        return false;
 
1651
                                }
 
1652
 
 
1653
                                // TODO support other animclasses
 
1654
                                if (animclass != COLLADAFW::AnimationList::ANGLE) {
 
1655
                                        fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
 
1656
                                        return false;
 
1657
                                }
 
1658
 
 
1659
                                COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
 
1660
 
 
1661
                                float ax[3] = {axis[0], axis[1], axis[2]};
 
1662
                                float angle = evaluate_fcurve(curves[0], fra);
 
1663
                                axis_angle_to_mat4(mat, ax, angle);
 
1664
 
 
1665
                                return true;
 
1666
                        }
 
1667
                        else if (is_scale || is_translate) {
 
1668
                                bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
 
1669
 
 
1670
                                if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
 
1671
                                        if (is_xyz)
 
1672
                                                fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size());
 
1673
                                        else
 
1674
                                                fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
 
1675
                                        return false;
 
1676
                                }
 
1677
                                
 
1678
                                switch (animclass) {
 
1679
                                case COLLADAFW::AnimationList::POSITION_X:
 
1680
                                        vec[0] = evaluate_fcurve(curves[0], fra);
 
1681
                                        break;
 
1682
                                case COLLADAFW::AnimationList::POSITION_Y:
 
1683
                                        vec[1] = evaluate_fcurve(curves[0], fra);
 
1684
                                        break;
 
1685
                                case COLLADAFW::AnimationList::POSITION_Z:
 
1686
                                        vec[2] = evaluate_fcurve(curves[0], fra);
 
1687
                                        break;
 
1688
                                case COLLADAFW::AnimationList::POSITION_XYZ:
 
1689
                                        vec[0] = evaluate_fcurve(curves[0], fra);
 
1690
                                        vec[1] = evaluate_fcurve(curves[1], fra);
 
1691
                                        vec[2] = evaluate_fcurve(curves[2], fra);
 
1692
                                        break;
 
1693
                                default:
 
1694
                                        fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
 
1695
                                        break;
 
1696
                                }
 
1697
                        }
 
1698
                        else if (type == COLLADAFW::Transformation::MATRIX) {
 
1699
                                // for now, of matrix animation, support only the case when all values are packed into one animation
 
1700
                                if (curves.size() != 16) {
 
1701
                                        fprintf(stderr, "%s: expected 16 curves, got %d\n", path, (int)curves.size());
 
1702
                                        return false;
 
1703
                                }
 
1704
 
 
1705
                                COLLADABU::Math::Matrix4 matrix;
 
1706
                                int i = 0, j = 0;
 
1707
 
 
1708
                                for (std::vector<FCurve*>::iterator it = curves.begin(); it != curves.end(); it++) {
 
1709
                                        matrix.setElement(i, j, evaluate_fcurve(*it, fra));
 
1710
                                        j++;
 
1711
                                        if (j == 4) {
 
1712
                                                i++;
 
1713
                                                j = 0;
 
1714
                                        }
 
1715
                                        unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), *it), unused_curves.end());
 
1716
                                }
 
1717
 
 
1718
                                COLLADAFW::Matrix tm(matrix);
 
1719
                                dae_matrix_to_mat4(&tm, mat);
 
1720
 
 
1721
                                std::vector<FCurve*>::iterator it;
 
1722
 
 
1723
                                return true;
 
1724
                        }
 
1725
                }
 
1726
 
 
1727
                if (is_scale)
 
1728
                        size_to_mat4(mat, vec);
 
1729
                else
 
1730
                        copy_v3_v3(mat[3], vec);
 
1731
 
 
1732
                return is_scale || is_translate;
 
1733
        }
 
1734
 
 
1735
        return false;
 
1736
}
 
1737
 
 
1738
// gives a world-space mat of joint at rest position
 
1739
void AnimationImporter::get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node)
 
1740
{
 
1741
        // if bind mat is not available,
 
1742
        // use "current" node transform, i.e. all those tms listed inside <node>
 
1743
        if (!armature_importer->get_joint_bind_mat(mat, node)) {
 
1744
                float par[4][4], m[4][4];
 
1745
 
 
1746
                calc_joint_parent_mat_rest(par, NULL, root, node);
 
1747
                get_node_mat(m, node, NULL, NULL);
 
1748
                mult_m4_m4m4(mat, par, m);
 
1749
        }
 
1750
}
 
1751
 
 
1752
// gives a world-space mat, end's mat not included
 
1753
bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end)
 
1754
{
 
1755
        float m[4][4];
 
1756
 
 
1757
        if (node == end) {
 
1758
                par ? copy_m4_m4(mat, par) : unit_m4(mat);
 
1759
                return true;
 
1760
        }
 
1761
 
 
1762
        // use bind matrix if available or calc "current" world mat
 
1763
        if (!armature_importer->get_joint_bind_mat(m, node)) {
 
1764
                if (par) {
 
1765
                        float temp[4][4];
 
1766
                        get_node_mat(temp, node, NULL, NULL);
 
1767
                        mult_m4_m4m4(m, par, temp);
 
1768
                }
 
1769
                else {
 
1770
                        get_node_mat(m, node, NULL, NULL);
 
1771
                }
 
1772
        }
 
1773
 
 
1774
        COLLADAFW::NodePointerArray& children = node->getChildNodes();
 
1775
        for (unsigned int i = 0; i < children.getCount(); i++) {
 
1776
                if (calc_joint_parent_mat_rest(mat, m, children[i], end))
 
1777
                        return true;
 
1778
        }
 
1779
 
 
1780
        return false;
 
1781
}
 
1782
 
 
1783
#ifdef ARMATURE_TEST
 
1784
Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job)
 
1785
{
 
1786
        if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
 
1787
                Object *job = bc_add_object(scene, OB_EMPTY, (char*)get_joint_name(node));
 
1788
 
 
1789
                job->lay = object_in_scene(job, scene)->lay = 2;
 
1790
 
 
1791
                mul_v3_fl(job->size, 0.5f);
 
1792
                job->recalc |= OB_RECALC_OB;
 
1793
 
 
1794
                verify_adt_action((ID*)&job->id, 1);
 
1795
 
 
1796
                job->rotmode = ROT_MODE_QUAT;
 
1797
 
 
1798
                float mat[4][4];
 
1799
                get_joint_rest_mat(mat, root, node);
 
1800
 
 
1801
                if (par_job) {
 
1802
                        float temp[4][4], ipar[4][4];
 
1803
                        invert_m4_m4(ipar, par_job->obmat);
 
1804
                        copy_m4_m4(temp, mat);
 
1805
                        mult_m4_m4m4(mat, ipar, temp);
 
1806
                }
 
1807
 
 
1808
                TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size);
 
1809
 
 
1810
                if (par_job) {
 
1811
                        job->parent = par_job;
 
1812
 
 
1813
                        par_job->recalc |= OB_RECALC_OB;
 
1814
                        job->parsubstr[0] = 0;
 
1815
                }
 
1816
 
 
1817
                where_is_object(scene, job);
 
1818
 
 
1819
                // after parenting and layer change
 
1820
                DAG_scene_sort(CTX_data_main(C), scene);
 
1821
 
 
1822
                joint_objects[node->getUniqueId()] = job;
 
1823
        }
 
1824
 
 
1825
        return joint_objects[node->getUniqueId()];
 
1826
}
 
1827
#endif
 
1828
 
 
1829
#if 0
 
1830
// recursively evaluates joint tree until end is found, mat then is world-space matrix of end
 
1831
// mat must be identity on enter, node must be root
 
1832
bool AnimationImporter::evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra)
 
1833
{
 
1834
        float m[4][4];
 
1835
        if (par) {
 
1836
                float temp[4][4];
 
1837
                evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f);
 
1838
                mult_m4_m4m4(m, par, temp);
 
1839
        }
 
1840
        else {
 
1841
                evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f);
 
1842
        }
 
1843
 
 
1844
        if (node == end) {
 
1845
                copy_m4_m4(mat, m);
 
1846
                return true;
 
1847
        }
 
1848
        else {
 
1849
                COLLADAFW::NodePointerArray& children = node->getChildNodes();
 
1850
                for (int i = 0; i < children.getCount(); i++) {
 
1851
                        if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra))
 
1852
                                return true;
 
1853
                }
 
1854
        }
 
1855
 
 
1856
        return false;
 
1857
}
 
1858
#endif
 
1859
 
 
1860
void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
 
1861
{
 
1862
        const char *bone_name = bc_get_joint_name(node);
 
1863
        bAction *act = ob->adt->action;
 
1864
                        
 
1865
        /* try to find group */
 
1866
        bActionGroup *grp = action_groups_find_named(act, bone_name);
 
1867
 
 
1868
        /* no matching groups, so add one */
 
1869
        if (grp == NULL) {
 
1870
                /* Add a new group, and make it active */
 
1871
                grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
 
1872
                                        
 
1873
                grp->flag = AGRP_SELECTED;
 
1874
                BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
 
1875
                                        
 
1876
                BLI_addtail(&act->groups, grp);
 
1877
                BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
 
1878
        }
 
1879
                                
 
1880
        /* add F-Curve to group */
 
1881
        action_groups_add_channel(act, grp, fcu);
 
1882
}
 
1883
 
 
1884
void AnimationImporter::add_bezt(FCurve *fcu, float fra, float value)
 
1885
{
 
1886
        //float fps = (float)FPS;
 
1887
        BezTriple bez;
 
1888
        memset(&bez, 0, sizeof(BezTriple));
 
1889
        bez.vec[1][0] = fra;
 
1890
        bez.vec[1][1] = value;
 
1891
        bez.ipo = BEZT_IPO_LIN ;/* use default interpolation mode here... */
 
1892
        bez.f1 = bez.f2 = bez.f3 = SELECT;
 
1893
        bez.h1 = bez.h2 = HD_AUTO;
 
1894
        insert_bezt_fcurve(fcu, &bez, 0);
 
1895
        calchandles_fcurve(fcu);
 
1896
}
 
1897