diff options
author | Joshua Leung <aligorith@gmail.com> | 2011-02-16 12:59:29 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2011-02-16 12:59:29 +0300 |
commit | ac1e2fc977671bb55263811a1f009392a7b64d6c (patch) | |
tree | d7d4002bd8df67c725c515847dd99dbf1861b728 /source | |
parent | b7d349e09c63978721065d899a79697b0a4b0018 (diff) |
Bugfix [#22535] Dupliframes with keyframe Anim are broken
So, it turns out that dupliframes weren't that bad to restore... the
old version didn't do truly accurate transform freezing as it didn't
update ancestors too. However, as a modelling tool, this will probably
suffice.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 70 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 6 |
2 files changed, 49 insertions, 27 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 8fdfca33efb..875132d2776 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -49,6 +49,7 @@ #include "DNA_scene_types.h" #include "DNA_vfont_types.h" +#include "BKE_animsys.h" #include "BKE_curve.h" #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" @@ -742,41 +743,62 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, i static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) { extern int enable_cu_speed; /* object.c */ - Object copyob; - DupliObject *dob; - int cfrao, ok; + int cfrao = scene->r.cfra; + float omat[4][4]; - /* simple preventing of too deep nested groups */ - if(level>MAX_DUPLI_RECUR) return; + /* simple prevention of too deep nested groups */ + if (level > MAX_DUPLI_RECUR) return; - cfrao= scene->r.cfra; - if(ob->parent==NULL && ob->constraints.first==NULL) return; - - if(ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0; - copyob= *ob; /* store transform info */ - - for(scene->r.cfra= ob->dupsta; scene->r.cfra<=ob->dupend; scene->r.cfra++) { - - ok= 1; - if(ob->dupoff) { + /* if we don't have any data/settings which will lead to object movement, + * don't waste time trying, as it will all look the same... + */ + if (ob->parent==NULL && ob->constraints.first==NULL && ob->adt==NULL) + return; + if (ob->adt->action==NULL && ob->adt->nla_tracks.first==NULL && ob->adt->drivers.first==NULL) + return; + + /* make a copy of the object's original transform matrix */ + copy_m4_m4(omat, ob->obmat); + + /* duplicate over the required range */ + if (ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0; + + for (scene->r.cfra= ob->dupsta; scene->r.cfra<=ob->dupend; scene->r.cfra++) { + short ok= 1; + + /* - dupoff = how often a frames within the range shouldn't be made into duplis + * - dupon = the length of each "skipping" block in frames + */ + if (ob->dupoff) { ok= scene->r.cfra - ob->dupsta; ok= ok % (ob->dupon+ob->dupoff); - if(ok < ob->dupon) ok= 1; - else ok= 0; + ok= (ok < ob->dupon); } - if(ok) { -#if 0 // XXX old animation system - do_ob_ipo(scene, ob); -#endif // XXX old animation system + + if (ok) { + DupliObject *dob; + + /* WARNING: doing animation updates in this way is not terribly accurate, as the dependencies + * and/or other objects which may affect this object's transforms are not updated either. + * However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine! + */ + BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ where_is_object_time(scene, ob, (float)scene->r.cfra); + dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated); - copy_m4_m4(dob->omat, copyob.obmat); + copy_m4_m4(dob->omat, omat); } } - *ob= copyob; /* restore transform info */ - scene->r.cfra= cfrao; enable_cu_speed= 1; + + /* reset frame to original frame, then re-evaluate animation as above + * as 2.5 animation data may have far-reaching consequences + */ + scene->r.cfra= cfrao; + + BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ + where_is_object_time(scene, ob, (float)scene->r.cfra); } typedef struct vertexDupliData { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d0f2232a683..06f641fb28a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1688,10 +1688,10 @@ void object_rot_to_mat3(Object *ob, float mat[][3]) else { /* quats are normalised before use to eliminate scaling issues */ float tquat[4]; - + normalize_qt_qt(tquat, ob->quat); quat_to_mat3(rmat, tquat); - + normalize_qt_qt(tquat, ob->dquat); quat_to_mat3(dmat, tquat); } @@ -1735,7 +1735,7 @@ void object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const invert_m4_m4(imat, diff_mat); mul_m4_m4m4(rmat, mat, imat); /* get the parent relative matrix */ object_apply_mat4(ob, rmat, use_compat, FALSE); - + /* same as below, use rmat rather then mat */ mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat); object_mat3_to_rot(ob, rot, use_compat); |