2
* ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18
* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory, Sukhitha Jayathilake.
20
* ***** END GPL LICENSE BLOCK *****
23
/** \file blender/collada/AnimationImporter.cpp
29
/* COLLADABU_ASSERT, may be able to remove later */
30
#include "COLLADABUPlatform.h"
32
#include "DNA_armature_types.h"
34
#include "ED_keyframing.h"
36
#include "BLI_listbase.h"
38
#include "BLI_path_util.h"
39
#include "BLI_string.h"
41
#include "BKE_action.h"
42
#include "BKE_armature.h"
43
#include "BKE_fcurve.h"
44
#include "BKE_object.h"
46
#include "MEM_guardedalloc.h"
48
#include "collada_utils.h"
49
#include "AnimationImporter.h"
50
#include "ArmatureImporter.h"
51
#include "MaterialExporter.h"
55
// first try node name, if not available (since is optional), fall back to original id
57
static const char *bc_get_joint_name(T *node)
59
const std::string& id = node->getName();
60
return id.size() ? id.c_str() : node->getOriginalId().c_str();
63
FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path)
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;
72
void AnimationImporter::create_bezt(FCurve *fcu, float frame, float output)
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);
85
// create one or several fcurves depending on the number of parameters being animated
86
void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
88
COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
89
COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
91
float fps = (float)FPS;
92
size_t dim = curve->getOutDimension();
95
std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
98
case 1: // X, Y, Z or angle
103
for (i = 0; i < dim; i++ ) {
104
FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
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();
111
// create beztriple for each key
112
for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
114
memset(&bez, 0, sizeof(BezTriple));
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);
122
if ( curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER ||
123
curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP)
125
COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
126
COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
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);
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;
138
bez.ipo = BEZT_IPO_CONST;
139
//bez.h1 = bez.h2 = HD_AUTO;
143
bez.h1 = bez.h2 = HD_AUTO;
144
bez.ipo = BEZT_IPO_LIN;
146
// bez.ipo = U.ipo_new; /* use default interpolation mode here... */
147
bez.f1 = bez.f2 = bez.f3 = SELECT;
149
insert_bezt_fcurve(fcu, &bez, 0);
152
calchandles_fcurve(fcu);
154
fcurves.push_back(fcu);
159
fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", (int)dim, curve->getOriginalId().c_str());
162
for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
163
unused_curves.push_back(*it);
167
void AnimationImporter::fcurve_deg_to_rad(FCurve *cu)
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);
178
void AnimationImporter::add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
182
if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
183
else act = ob->adt->action;
185
std::vector<FCurve*>::iterator it;
189
char *p = strstr(rna_path, "rotation_euler");
190
bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
192
// convert degrees to radians for rotation
194
fcurve_deg_to_rad(fcu);
197
for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
199
fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
201
if (array_index == -1) fcu->array_index = i;
202
else fcu->array_index = array_index;
204
if (ob->type == OB_ARMATURE) {
205
bActionGroup *grp = NULL;
206
const char *bone_name = bc_get_joint_name(animated->node);
209
/* try to find group */
210
grp = action_groups_find_named(act, bone_name);
212
/* no matching groups, so add one */
214
/* Add a new group, and make it active */
215
grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
217
grp->flag = AGRP_SELECTED;
218
BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
220
BLI_addtail(&act->groups, grp);
221
BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
224
/* add F-Curve to group */
225
action_groups_add_channel(act, grp, fcu);
230
fcurves_actionGroup_map[grp].push_back(fcu);
235
BLI_addtail(&act->curves, fcu);
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());
243
AnimationImporter::AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) :
244
TransformReader(conv), armature_importer(arm), scene(scene) { }
246
AnimationImporter::~AnimationImporter()
248
// free unused FCurves
249
for (std::vector<FCurve*>::iterator it = unused_curves.begin(); it != unused_curves.end(); it++)
252
if (unused_curves.size())
253
fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size());
256
bool AnimationImporter::write_animation(const COLLADAFW::Animation* anim)
258
if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
259
COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim;
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");
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();
272
if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
274
case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
275
case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
276
case COLLADAFW::AnimationCurve::INTERPOLATION_STEP:
277
animation_to_fcurves(curve);
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");
287
fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
291
fprintf(stderr, "FORMULA animation type is not supported yet.\n");
297
// called on post-process stage after writeVisualScenes
298
bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* animlist)
300
const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
302
animlist_map[animlist_id] = animlist;
307
if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
311
// for bones rna_path is like: pose.bones["bone-name"].rotation
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)
325
TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
327
copy_m4_m4(ob->obmat, mat);
328
object_apply_mat4(ob, ob->obmat, 0, 0);
333
virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act)
338
for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) {
340
FCurve *eulcu[3] = {NULL, NULL, NULL};
342
if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
345
std::vector<FCurve*> &rot_fcurves = fcurves_actionGroup_map[grp];
347
if (rot_fcurves.size() > 3) continue;
349
for (i = 0; i < rot_fcurves.size(); i++)
350
eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
352
char joint_path[100];
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);
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)
365
bPoseChannel *chan = get_pose_channel(ob->pose, grp->name);
367
float m4[4][4], irest[3][3];
368
invert_m4_m4(m4, chan->bone->arm_mat);
369
copy_m3_m4(irest, m4);
371
for (i = 0; i < 3; i++) {
373
FCurve *cu = eulcu[i];
377
for (int j = 0; j < cu->totvert; j++) {
378
float frame = cu->bezt[j].vec[1][0];
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
386
// make eul relative to bone rest pose
387
float rot[3][3], rel[3][3], quat[4];
389
/*eul_to_mat3(rot, eul);
391
mul_m3_m3m3(rel, irest, rot);
393
mat3_to_quat(quat, rel);
396
eul_to_quat(quat, eul);
398
for (int k = 0; k < 4; k++)
399
create_bezt(quatcu[k], frame, quat[k]);
403
// now replace old Euler curves
405
for (i = 0; i < 3; i++) {
406
if (!eulcu[i]) continue;
408
action_groups_remove_channel(act, eulcu[i]);
409
free_fcurve(eulcu[i]);
412
chan->rotmode = ROT_MODE_QUAT;
414
for (i = 0; i < 4; i++)
415
action_groups_add_channel(act, grp, quatcu[i]);
419
for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
420
pchan->rotmode = ROT_MODE_QUAT;
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 )
429
std::vector<FCurve*>::iterator it;
431
for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) {
433
fcu->rna_path = BLI_strdup(rna_path);
435
if (array_index == -1) fcu->array_index = i;
436
else fcu->array_index = array_index;
438
unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
442
void AnimationImporter::unused_fcurve(std::vector<FCurve*>* curves)
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++) {
448
unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
452
void AnimationImporter::find_frames( std::vector<float>* frames , std::vector<FCurve*>* curves)
454
std::vector<FCurve*>::iterator iter;
455
for (iter = curves->begin(); iter != curves->end(); iter++) {
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);
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)
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;
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);
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());
490
case COLLADAFW::Transformation::TRANSLATE:
491
case COLLADAFW::Transformation::SCALE:
493
bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE;
495
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
497
BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
499
switch (binding->animationClass) {
500
case COLLADAFW::AnimationList::POSITION_X:
501
modify_fcurve(curves, rna_path, 0 );
503
case COLLADAFW::AnimationList::POSITION_Y:
504
modify_fcurve(curves, rna_path, 1 );
506
case COLLADAFW::AnimationList::POSITION_Z:
507
modify_fcurve(curves, rna_path, 2 );
509
case COLLADAFW::AnimationList::POSITION_XYZ:
510
modify_fcurve(curves, rna_path, -1 );
513
unused_fcurve(curves);
514
fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
515
binding->animationClass, loc ? "TRANSLATE" : "SCALE");
521
case COLLADAFW::Transformation::ROTATE:
524
BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
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++) {
531
//if transform is rotation the fcurves values must be turned in to radian.
533
fcurve_deg_to_rad(fcu);
535
COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)transform;
536
COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
538
switch (binding->animationClass) {
539
case COLLADAFW::AnimationList::ANGLE:
540
if (COLLADABU::Math::Vector3::UNIT_X == axis) {
541
modify_fcurve(curves, rna_path, 0 );
543
else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
544
modify_fcurve(curves, rna_path, 1 );
546
else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
547
modify_fcurve(curves, rna_path, 2 );
550
unused_fcurve(curves);
552
case COLLADAFW::AnimationList::AXISANGLE:
553
// TODO convert axis-angle to quat? or XYZ?
555
unused_fcurve(curves);
556
fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
557
binding->animationClass);
562
case COLLADAFW::Transformation::MATRIX:
564
COLLADAFW::Matrix* mat = (COLLADAFW::Matrix*)transform;
565
COLLADABU::Math::Matrix4 mat4 = mat->getMatrix();
566
switch (binding->animationClass) {
567
case COLLADAFW::AnimationList::TRANSFORM:
571
unused_fcurve(curves);
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");
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)
586
BLI_strncpy(rna_path,anim_type, sizeof(rna_path));
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];
595
switch (bindings[j].animationClass) {
596
case COLLADAFW::AnimationList::COLOR_R:
597
modify_fcurve(&animcurves, rna_path, 0 );
599
case COLLADAFW::AnimationList::COLOR_G:
600
modify_fcurve(&animcurves, rna_path, 1 );
602
case COLLADAFW::AnimationList::COLOR_B:
603
modify_fcurve(&animcurves, rna_path, 2 );
605
case COLLADAFW::AnimationList::COLOR_RGB:
606
case COLLADAFW::AnimationList::COLOR_RGBA: // to do-> set intensity
607
modify_fcurve(&animcurves, rna_path, -1 );
611
unused_fcurve(&animcurves);
612
fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
613
bindings[j].animationClass, "COLOR" );
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);
627
void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type)
630
if (animlist_map.find(listid) == animlist_map.end()) {
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];
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);
655
void AnimationImporter::apply_matrix_curves( Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root ,COLLADAFW::Node* node,
656
COLLADAFW::Transformation * tm )
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];
662
armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
664
std::vector<float> frames;
665
find_frames(&frames, &animcurves);
667
float irest_dae[4][4];
668
float rest[4][4], irest[4][4];
671
get_joint_rest_mat(irest_dae, root, node);
672
invert_m4(irest_dae);
674
Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
676
fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
681
copy_m4_m4(rest, bone->arm_mat);
682
invert_m4_m4(irest, rest);
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;
689
for (int i = 0; i < totcu; i++) {
694
tm_str = "rotation_quaternion";
708
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
710
BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
711
newcu[i] = create_fcurve(axis, rna_path);
712
newcu[i]->totvert = frames.size();
715
if (frames.size() == 0)
718
std::sort(frames.begin(), frames.end());
720
std::vector<float>::iterator it;
722
// sample values at each frame
723
for (it = frames.begin(); it != frames.end(); it++) {
731
// calc object-space mat
732
evaluate_transform_at_frame(matfra, node, fra);
735
// for joints, we need a special matrix
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];
743
calc_joint_parent_mat_rest(par, NULL, root, node);
744
mult_m4_m4m4(temp, par, matfra);
746
// evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
748
// calc special matrix
749
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
752
copy_m4_m4(mat, matfra);
755
float rot[4], loc[3], scale[3];
757
mat4_to_quat(rot, mat);
758
/*for ( int i = 0 ; i < 4 ; i ++ )
760
rot[i] = RAD2DEGF(rot[i]);
762
copy_v3_v3(loc, mat[3]);
763
mat4_to_size(scale, mat);
766
for (int i = 0; i < totcu; i++) {
768
add_bezt(newcu[i], fra, rot[i]);
770
add_bezt(newcu[i], fra, loc[i - 4]);
772
add_bezt(newcu[i], fra, scale[i - 7]);
775
verify_adt_action((ID*)&ob->id, 1);
777
ListBase *curves = &ob->adt->action->curves;
780
for (int i= 0; i < totcu; i++) {
782
add_bone_fcurve(ob, node, newcu[i]);
784
BLI_addtail(curves, newcu[i]);
788
bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
789
chan->rotmode = ROT_MODE_QUAT;
792
ob->rotmode = ROT_MODE_QUAT;
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)
804
AnimationImporter::AnimMix* animType = get_animation_type(node, FW_object_map );
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()];
811
fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
817
if ( (animType->transform) != 0 )
819
const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL;
820
char joint_path[200];
823
armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
826
if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
827
else act = ob->adt->action;
829
//Get the list of animation curves of the object
830
ListBase *AnimCurves = &(act->curves);
832
const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
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();
839
bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
840
bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
842
const COLLADAFW::UniqueId& listid = transform->getAnimationList();
844
//check if transformation has animations
845
if (animlist_map.find(listid) == animlist_map.end()) {
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];
857
apply_matrix_curves(ob, animcurves, root , node, transform );
863
add_bone_animation_sampled(ob, animcurves, root, node, transform);
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 );
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;
874
BLI_addtail(AnimCurves, fcu);
881
if (is_rotation && !is_joint) {
882
ob->rotmode = ROT_MODE_EUL;
887
if ((animType->light) != 0)
889
Lamp * lamp = (Lamp*) ob->data;
891
if (!lamp->adt || !lamp->adt->action) act = verify_adt_action((ID*)&lamp->id, 1);
892
else act = lamp->adt->action;
894
ListBase *AnimCurves = &(act->curves);
895
const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
897
for (unsigned int i = 0; i < nodeLights.getCount(); i++) {
898
const COLLADAFW::Light *light = (COLLADAFW::Light *) FW_object_map[nodeLights[i]->getInstanciatedObjectId()];
900
if ((animType->light & LIGHT_COLOR) != 0)
902
const COLLADAFW::Color *col = &(light->getColor());
903
const COLLADAFW::UniqueId& listid = col->getAnimationList();
905
Assign_color_animations(listid, AnimCurves, "color");
907
if ((animType->light & LIGHT_FOA) != 0 )
909
const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle());
910
const COLLADAFW::UniqueId& listid = foa->getAnimationList();
912
Assign_float_animations( listid ,AnimCurves, "spot_size");
914
if ( (animType->light & LIGHT_FOE) != 0 )
916
const COLLADAFW::AnimatableFloat *foe = &(light->getFallOffExponent());
917
const COLLADAFW::UniqueId& listid = foe->getAnimationList();
919
Assign_float_animations( listid ,AnimCurves, "spot_blend");
925
if ( (animType->camera) != 0)
927
Camera * camera = (Camera*) ob->data;
929
if (!camera->adt || !camera->adt->action) act = verify_adt_action((ID*)&camera->id, 1);
930
else act = camera->adt->action;
932
ListBase *AnimCurves = &(act->curves);
933
const COLLADAFW::InstanceCameraPointerArray& nodeCameras= node->getInstanceCameras();
935
for (unsigned int i = 0; i < nodeCameras.getCount(); i++) {
936
const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) FW_object_map[nodeCameras[i]->getInstanciatedObjectId()];
938
if ((animType->camera & CAMERA_XFOV) != 0 )
940
const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov());
941
const COLLADAFW::UniqueId& listid = xfov->getAnimationList();
942
Assign_float_animations( listid ,AnimCurves, "lens");
945
else if ((animType->camera & CAMERA_XMAG) != 0 )
947
const COLLADAFW::AnimatableFloat *xmag = &(camera->getXMag());
948
const COLLADAFW::UniqueId& listid = xmag->getAnimationList();
949
Assign_float_animations( listid ,AnimCurves, "ortho_scale");
952
if ((animType->camera & CAMERA_ZFAR) != 0 )
954
const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane());
955
const COLLADAFW::UniqueId& listid = zfar->getAnimationList();
956
Assign_float_animations( listid ,AnimCurves, "clip_end");
959
if ((animType->camera & CAMERA_ZNEAR) != 0 )
961
const COLLADAFW::AnimatableFloat *znear = &(camera->getNearClippingPlane());
962
const COLLADAFW::UniqueId& listid = znear->getAnimationList();
963
Assign_float_animations( listid ,AnimCurves, "clip_start");
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;
973
ListBase *AnimCurves = &(act->curves);
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" );
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" );
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" );
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" );
1013
void AnimationImporter::add_bone_animation_sampled(Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm)
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));
1019
std::vector<float> frames;
1020
find_frames(&frames, &animcurves);
1022
// convert degrees to radians
1023
if (tm->getTransformationType() == COLLADAFW::Transformation::ROTATE) {
1025
std::vector<FCurve*>::iterator iter;
1026
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
1027
FCurve* fcu = *iter;
1029
fcurve_deg_to_rad(fcu);
1034
float irest_dae[4][4];
1035
float rest[4][4], irest[4][4];
1037
get_joint_rest_mat(irest_dae, root, node);
1038
invert_m4(irest_dae);
1040
Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
1042
fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
1047
copy_m4_m4(rest, bone->arm_mat);
1048
invert_m4_m4(irest, rest);
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;
1055
for (int i = 0; i < totcu; i++) {
1060
tm_str = "rotation_quaternion";
1064
tm_str = "location";
1073
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
1075
newcu[i] = create_fcurve(axis, rna_path);
1076
newcu[i]->totvert = frames.size();
1079
if (frames.size() == 0)
1082
std::sort(frames.begin(), frames.end());
1084
std::vector<float>::iterator it;
1086
// sample values at each frame
1087
for (it = frames.begin(); it != frames.end(); it++) {
1095
// calc object-space mat
1096
evaluate_transform_at_frame(matfra, node, fra);
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];
1107
calc_joint_parent_mat_rest(par, NULL, root, node);
1108
mult_m4_m4m4(temp, par, matfra);
1110
// evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
1112
// calc special matrix
1113
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
1115
float rot[4], loc[3], scale[3];
1117
mat4_to_quat(rot, mat);
1118
copy_v3_v3(loc, mat[3]);
1119
mat4_to_size(scale, mat);
1122
for (int i = 0; i < totcu; i++) {
1124
add_bezt(newcu[i], fra, rot[i]);
1126
add_bezt(newcu[i], fra, loc[i - 4]);
1128
add_bezt(newcu[i], fra, scale[i - 7]);
1131
verify_adt_action((ID*)&ob->id, 1);
1134
for (int i= 0; i < totcu; i++) {
1135
add_bone_fcurve(ob, node, newcu[i]);
1138
bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
1139
chan->rotmode = ROT_MODE_QUAT;
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)
1148
AnimMix *types = new AnimMix();
1150
const COLLADAFW::TransformationPointerArray& nodeTransforms = node->getTransformations();
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();
1157
//check if transformation has animations
1158
if (animlist_map.find(listid) == animlist_map.end()) {
1162
types->transform = types->transform|NODE_TRANSFORM;
1166
const COLLADAFW::InstanceLightPointerArray& nodeLights = node->getInstanceLights();
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);
1174
if ( types->light != 0) break;
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()];
1182
if ( camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE )
1184
types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XFOV);
1188
types->camera = setAnimType(&(camera->getXMag()),(types->camera), CAMERA_XMAG);
1190
types->camera = setAnimType(&(camera->getFarClippingPlane()),(types->camera), CAMERA_ZFAR);
1191
types->camera = setAnimType(&(camera->getNearClippingPlane()),(types->camera), CAMERA_ZNEAR);
1193
if ( types->camera != 0) break;
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);
1219
int AnimationImporter::setAnimType ( const COLLADAFW::Animatable * prop , int types, int addition)
1221
const COLLADAFW::UniqueId& listid = prop->getAnimationList();
1222
if (animlist_map.find(listid) != animlist_map.end())
1223
return types|addition;
1227
// Is not used anymore.
1228
void AnimationImporter::find_frames_old(std::vector<float> * frames, COLLADAFW::Node * node , COLLADAFW::Transformation::TransformationType tm_type)
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();
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();
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()) {
1248
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
1249
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
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);
1257
if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
1258
std::vector<FCurve*>::iterator iter;
1260
for (iter = curves.begin(); iter != curves.end(); iter++) {
1261
FCurve *fcu = *iter;
1263
//if transform is rotation the fcurves values must be turned in to radian.
1265
fcurve_deg_to_rad(fcu);
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);
1277
fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size());
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,
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;
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;
1306
fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
1310
// frames at which to sample
1311
std::vector<float> frames;
1313
find_frames_old(&frames, node , tm_type);
1317
float irest_dae[4][4];
1318
float rest[4][4], irest[4][4];
1321
get_joint_rest_mat(irest_dae, root, node);
1322
invert_m4(irest_dae);
1324
Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
1326
fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
1331
copy_m4_m4(rest, bone->arm_mat);
1332
invert_m4_m4(irest, rest);
1337
#ifdef ARMATURE_TEST
1338
FCurve *job_curves[10];
1339
job = get_joint_object(root, node, par_job);
1342
if (frames.size() == 0)
1345
std::sort(frames.begin(), frames.end());
1347
const char *tm_str = NULL;
1349
case COLLADAFW::Transformation::ROTATE:
1350
tm_str = "rotation_quaternion";
1352
case COLLADAFW::Transformation::SCALE:
1355
case COLLADAFW::Transformation::TRANSLATE:
1356
tm_str = "location";
1358
case COLLADAFW::Transformation::MATRIX:
1365
char joint_path[200];
1368
armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
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);
1374
for (i = 0; i < totcu; i++) {
1380
tm_str = "rotation_quaternion";
1384
tm_str = "location";
1394
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
1396
BLI_strncpy(rna_path, tm_str, sizeof(rna_path));
1397
newcu[i] = create_fcurve(axis, rna_path);
1399
#ifdef ARMATURE_TEST
1401
job_curves[i] = create_fcurve(axis, tm_str);
1405
std::vector<float>::iterator it;
1407
// sample values at each frame
1408
for (it = frames.begin(); it != frames.end(); it++) {
1416
// calc object-space mat
1417
evaluate_transform_at_frame(matfra, node, fra);
1419
// for joints, we need a special matrix
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];
1427
calc_joint_parent_mat_rest(par, NULL, root, node);
1428
mult_m4_m4m4(temp, par, matfra);
1430
// evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
1432
// calc special matrix
1433
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
1436
copy_m4_m4(mat, matfra);
1439
float val[4], rot[4], loc[3], scale[3];
1442
case COLLADAFW::Transformation::ROTATE:
1443
mat4_to_quat(val, mat);
1445
case COLLADAFW::Transformation::SCALE:
1446
mat4_to_size(val, mat);
1448
case COLLADAFW::Transformation::TRANSLATE:
1449
copy_v3_v3(val, mat[3]);
1451
case COLLADAFW::Transformation::MATRIX:
1452
mat4_to_quat(rot, mat);
1453
copy_v3_v3(loc, mat[3]);
1454
mat4_to_size(scale, mat);
1461
for (i = 0; i < totcu; i++) {
1464
add_bezt(newcu[i], fra, rot[i]);
1466
add_bezt(newcu[i], fra, loc[i - 4]);
1468
add_bezt(newcu[i], fra, scale[i - 7]);
1471
add_bezt(newcu[i], fra, val[i]);
1475
#ifdef ARMATURE_TEST
1478
case COLLADAFW::Transformation::ROTATE:
1479
mat4_to_quat(val, matfra);
1481
case COLLADAFW::Transformation::SCALE:
1482
mat4_to_size(val, matfra);
1484
case COLLADAFW::Transformation::TRANSLATE:
1485
copy_v3_v3(val, matfra[3]);
1488
mat4_to_quat(rot, matfra);
1489
copy_v3_v3(loc, matfra[3]);
1490
mat4_to_size(scale, matfra);
1496
for (i = 0; i < totcu; i++) {
1499
add_bezt(job_curves[i], fra, rot[i]);
1501
add_bezt(job_curves[i], fra, loc[i - 4]);
1503
add_bezt(job_curves[i], fra, scale[i - 7]);
1506
add_bezt(job_curves[i], fra, val[i]);
1513
verify_adt_action((ID*)&ob->id, 1);
1515
ListBase *curves = &ob->adt->action->curves;
1518
for (i = 0; i < totcu; i++) {
1520
add_bone_fcurve(ob, node, newcu[i]);
1522
BLI_addtail(curves, newcu[i]);
1524
#ifdef ARMATURE_TEST
1526
BLI_addtail(&job->adt->action->curves, job_curves[i]);
1530
if (is_rotation || is_matrix) {
1532
bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
1533
chan->rotmode = ROT_MODE_QUAT;
1536
ob->rotmode = ROT_MODE_QUAT;
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)
1548
const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
1552
for (unsigned int i = 0; i < tms.getCount(); i++) {
1553
COLLADAFW::Transformation *tm = tms[i];
1554
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
1559
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
1560
if (!evaluate_animation(tm, m, fra, nodename.c_str())) {
1562
case COLLADAFW::Transformation::ROTATE:
1563
dae_rotate_to_mat4(tm, m);
1565
case COLLADAFW::Transformation::TRANSLATE:
1566
dae_translate_to_mat4(tm, m);
1568
case COLLADAFW::Transformation::SCALE:
1569
dae_scale_to_mat4(tm, m);
1571
case COLLADAFW::Transformation::MATRIX:
1572
dae_matrix_to_mat4(tm, m);
1575
fprintf(stderr, "unsupported transformation type %d\n", type);
1577
// dae_matrix_to_mat4(tm, m);
1582
copy_m4_m4(temp, mat);
1584
mult_m4_m4m4(mat, temp, m);
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)
1591
const COLLADAFW::UniqueId& listid = tm->getAnimationList();
1592
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
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);
1602
if (animlist_map.find(listid) == animlist_map.end())
1605
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
1606
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
1608
if (bindings.getCount()) {
1611
bool is_scale = (type == COLLADAFW::Transformation::SCALE);
1612
bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
1615
dae_scale_to_v3(tm, vec);
1616
else if (is_translate)
1617
dae_translate_to_v3(tm, vec);
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;
1626
case COLLADAFW::Transformation::ROTATE:
1627
BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j);
1629
case COLLADAFW::Transformation::SCALE:
1630
BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j);
1632
case COLLADAFW::Transformation::TRANSLATE:
1633
BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j);
1635
case COLLADAFW::Transformation::MATRIX:
1636
BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j);
1642
if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
1643
fprintf(stderr, "%s: UNKNOWN animation class\n", path);
1647
if (type == COLLADAFW::Transformation::ROTATE) {
1648
if (curves.size() != 1) {
1649
fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size());
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);
1659
COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
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);
1667
else if (is_scale || is_translate) {
1668
bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
1670
if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
1672
fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size());
1674
fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size());
1678
switch (animclass) {
1679
case COLLADAFW::AnimationList::POSITION_X:
1680
vec[0] = evaluate_fcurve(curves[0], fra);
1682
case COLLADAFW::AnimationList::POSITION_Y:
1683
vec[1] = evaluate_fcurve(curves[0], fra);
1685
case COLLADAFW::AnimationList::POSITION_Z:
1686
vec[2] = evaluate_fcurve(curves[0], fra);
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);
1694
fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
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());
1705
COLLADABU::Math::Matrix4 matrix;
1708
for (std::vector<FCurve*>::iterator it = curves.begin(); it != curves.end(); it++) {
1709
matrix.setElement(i, j, evaluate_fcurve(*it, fra));
1715
unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), *it), unused_curves.end());
1718
COLLADAFW::Matrix tm(matrix);
1719
dae_matrix_to_mat4(&tm, mat);
1721
std::vector<FCurve*>::iterator it;
1728
size_to_mat4(mat, vec);
1730
copy_v3_v3(mat[3], vec);
1732
return is_scale || is_translate;
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)
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];
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);
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)
1758
par ? copy_m4_m4(mat, par) : unit_m4(mat);
1762
// use bind matrix if available or calc "current" world mat
1763
if (!armature_importer->get_joint_bind_mat(m, node)) {
1766
get_node_mat(temp, node, NULL, NULL);
1767
mult_m4_m4m4(m, par, temp);
1770
get_node_mat(m, node, NULL, NULL);
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))
1783
#ifdef ARMATURE_TEST
1784
Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job)
1786
if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
1787
Object *job = bc_add_object(scene, OB_EMPTY, (char*)get_joint_name(node));
1789
job->lay = object_in_scene(job, scene)->lay = 2;
1791
mul_v3_fl(job->size, 0.5f);
1792
job->recalc |= OB_RECALC_OB;
1794
verify_adt_action((ID*)&job->id, 1);
1796
job->rotmode = ROT_MODE_QUAT;
1799
get_joint_rest_mat(mat, root, node);
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);
1808
TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size);
1811
job->parent = par_job;
1813
par_job->recalc |= OB_RECALC_OB;
1814
job->parsubstr[0] = 0;
1817
where_is_object(scene, job);
1819
// after parenting and layer change
1820
DAG_scene_sort(CTX_data_main(C), scene);
1822
joint_objects[node->getUniqueId()] = job;
1825
return joint_objects[node->getUniqueId()];
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)
1837
evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f);
1838
mult_m4_m4m4(m, par, temp);
1841
evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f);
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))
1860
void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
1862
const char *bone_name = bc_get_joint_name(node);
1863
bAction *act = ob->adt->action;
1865
/* try to find group */
1866
bActionGroup *grp = action_groups_find_named(act, bone_name);
1868
/* no matching groups, so add one */
1870
/* Add a new group, and make it active */
1871
grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
1873
grp->flag = AGRP_SELECTED;
1874
BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
1876
BLI_addtail(&act->groups, grp);
1877
BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
1880
/* add F-Curve to group */
1881
action_groups_add_channel(act, grp, fcu);
1884
void AnimationImporter::add_bezt(FCurve *fcu, float fra, float value)
1886
//float fps = (float)FPS;
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);