2.5 - Keyframing Bugfixes + Code Cleanups

* DopeSheet + Graph Editor - 'Sample Keyframes' option now tags newly created keyframes as being breakdowns. Also moved reduced the code duplication here by moving the core code for this to the animation module.

* Keyframing (Standard/Auto) - Added proper 'replace' option
Keyframes can now be rekeyed non-destructively when the INSERTKEY_REPLACE flag is provided to the keyframing API functions, since this option will make sure that only the values of the handles get altered.

For the Auto-Keyframing 'Replace/Edit Keys' option, this means that it truly works as it describes now, since it will now only replace the values of the keyframes on the current frame, and won't create new keyframes in the process or destroy the tangents already created for those keys.

For things like the sliders in animation editors, keyframes changing the value won't destroy existing tangents.
This commit is contained in:
Joshua Leung 2009-09-04 04:27:06 +00:00
parent d577e0d986
commit a819ef1bf2
12 changed files with 186 additions and 189 deletions

@ -2003,6 +2003,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
/* get RNA pointer, and resolve the path */
@ -2010,6 +2012,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
/* try to resolve the path stored in the F-Curve */
if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
/* set the special 'replace' flag if on a keyframe */
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
flag |= INSERTKEY_REPLACE;
/* insert a keyframe for this F-Curve */
done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);

@ -357,6 +357,76 @@ void smooth_fcurve (FCurve *fcu)
calchandles_fcurve(fcu);
}
/* ---------------- */
/* little cache for values... */
typedef struct tempFrameValCache {
float frame, val;
} tempFrameValCache;
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
void sample_fcurve (FCurve *fcu)
{
BezTriple *bezt, *start=NULL, *end=NULL;
tempFrameValCache *value_cache, *fp;
int sfra, range;
int i, n, nIndex;
/* find selected keyframes... once pair has been found, add keyframes */
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
if (BEZSELECTED(bezt)) {
if (start) {
/* set end */
end= bezt;
/* cache values then add keyframes using these values, as adding
* keyframes while sampling will affect the outcome...
* - only start sampling+adding from index=1, so that we don't overwrite original keyframe
*/
range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
sfra= (int)( floor(start->vec[1][0]) );
if (range) {
value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
/* sample values */
for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
fp->frame= (float)(sfra + n);
fp->val= evaluate_fcurve(fcu, fp->frame);
}
/* add keyframes with these, tagging as 'breakdowns' */
for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
nIndex= insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
BEZKEYTYPE(fcu->bezt + nIndex)= BEZT_KEYTYPE_BREAKDOWN;
}
/* free temp cache */
MEM_freeN(value_cache);
/* as we added keyframes, we need to compensate so that bezt is at the right place */
bezt = fcu->bezt + i + range - 1;
i += (range - 1);
}
/* bezt was selected, so it now marks the start of a whole new chain to search */
start= bezt;
end= NULL;
}
else {
/* just set start keyframe */
start= bezt;
end= NULL;
}
}
}
/* recalculate channel's handles? */
calchandles_fcurve(fcu);
}
/* **************************************************** */
/* Copy/Paste Tools */
/* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes
@ -529,8 +599,10 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data)
bezt->vec[1][0] += offset;
bezt->vec[2][0] += offset;
/* insert the keyframe */
insert_bezt_fcurve(fcu, bezt);
/* insert the keyframe
* NOTE: no special flags here for now
*/
insert_bezt_fcurve(fcu, bezt, 0);
/* un-apply offset from src beztriple after copying */
bezt->vec[0][0] -= offset;

@ -262,9 +262,8 @@ static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen
* NOTE: any recalculate of the F-Curve that needs to be done will need to
* be done by the caller.
*/
int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
{
BezTriple *newb;
int i= 0;
if (fcu->bezt) {
@ -273,13 +272,34 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
if (replace) {
/* sanity check: 'i' may in rare cases exceed arraylen */
// FIXME: do not overwrite handletype if just replacing...?
if ((i >= 0) && (i < fcu->totvert))
*(fcu->bezt + i) = *bezt;
if ((i >= 0) && (i < fcu->totvert)) {
/* take care with the handletypes and other info if the replacement flags are set */
if (flag & INSERTKEY_REPLACE) {
BezTriple *dst= (fcu->bezt + i);
float dy= bezt->vec[1][1] - dst->vec[1][1];
/* just apply delta value change to the handle values */
dst->vec[0][1] += dy;
dst->vec[1][1] += dy;
dst->vec[2][1] += dy;
// TODO: perform some other operations?
}
else {
/* just brutally replace the values */
*(fcu->bezt + i) = *bezt;
}
}
}
else {
/* add new */
newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
else if ((flag & INSERTKEY_REPLACE) == 0) {
/* add new - if we're not restricted to replacing keyframes only */
BezTriple *newb;
/* allocate a new array only if we have to */
if ((flag & INSERTKEY_FASTR) == 0)
newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
else
newb= fcu->bezt;
/* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
if (i > 0)
@ -292,9 +312,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
if (i < fcu->totvert)
memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple));
/* replace (+ free) old with new */
MEM_freeN(fcu->bezt);
fcu->bezt= newb;
/* replace (+ free) old with new, only if necessary to do so */
if ((flag & INSERTKEY_FASTR) == 0) {
MEM_freeN(fcu->bezt);
fcu->bezt= newb;
}
fcu->totvert++;
}
@ -313,13 +335,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
return i;
}
/* This function is a wrapper for insert_bezt_icu, and should be used when
* adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
* else yet.
*
* 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
/* This function is a wrapper for insert_bezt_fcurve_internal(), and should be used when
* adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet.
* It returns the index at which the keyframe was added.
*/
void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag)
{
BezTriple beztr;
int a;
@ -337,21 +357,22 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one?
/* add temp beztriple to keyframes */
a= insert_bezt_fcurve(fcu, &beztr);
a= insert_bezt_fcurve(fcu, &beztr, flag);
/* what if 'a' is a negative index?
* for now, just exit to prevent any segfaults
*/
if (a < 0) return;
if (a < 0) return -1;
/* don't recalculate handles if fast is set
* - this is a hack to make importers faster
* - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
* - we may calculate twice (due to autohandle needing to be calculated twice)
*/
if (!fast) calchandles_fcurve(fcu);
if ((flag & INSERTKEY_FAST) == 0)
calchandles_fcurve(fcu);
/* set handletype and interpolation */
if (fcu->totvert > 2) {
if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE)==0) {
BezTriple *bezt= (fcu->bezt + a);
char h1, h2;
@ -370,10 +391,14 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
/* don't recalculate handles if fast is set
* - this is a hack to make importers faster
* - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
* - we may calculate twice (due to autohandle needing to be calculated twice)
*/
if (!fast) calchandles_fcurve(fcu);
if ((flag & INSERTKEY_FAST) == 0)
calchandles_fcurve(fcu);
}
/* return the index at which the keyframe was added */
return a;
}
/* -------------- 'Smarter' Keyframing Functions -------------------- */
@ -812,7 +837,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
/* insert new keyframe at current frame */
if (insert_mode)
insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
insert_vert_fcurve(fcu, cfra, curval, flag);
/* delete keyframe immediately before/after newly added */
switch (insert_mode) {
@ -830,7 +855,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
}
else {
/* just insert keyframe */
insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
insert_vert_fcurve(fcu, cfra, curval, flag);
/* return success */
return 1;
@ -1303,6 +1328,15 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
short success= 0;
int a, index, length, all= RNA_boolean_get(op->ptr, "all");
short flag = 0;
/* flags for inserting keyframes */
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
/* try to insert keyframe using property retrieved from UI */
memset(&ptr, 0, sizeof(PointerRNA));
@ -1322,14 +1356,14 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
length= 1;
for (a=0; a<length; a++)
success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, 0);
success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, flag);
MEM_freeN(path);
}
else if (ptr.type == &RNA_NlaStrip) {
/* handle special vars for NLA-strips */
NlaStrip *strip= (NlaStrip *)ptr.data;
FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), flag);
success+= insert_keyframe_direct(ptr, prop, fcu, cfra, 0);
}

@ -879,6 +879,7 @@ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks
*/
int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
Scene *scene= CTX_data_scene(C);
KS_Path *ksp;
int kflag=0, success= 0;
char *groupname= NULL;
@ -891,7 +892,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
/* suppliment with info from the context */
if (IS_AUTOKEY_FLAG(AUTOMATKEY)) kflag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED)) kflag |= INSERTKEY_NEEDED;
// if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
if (IS_AUTOKEY_MODE(scene, EDITKEYS)) kflag |= INSERTKEY_REPLACE;
}
else if (mode == MODIFYKEY_MODE_DELETE)
kflag= 0;

@ -99,7 +99,7 @@ typedef enum eKeyframeShapeDrawOpts {
} eKeyframeShapeDrawOpts;
/* draw simple diamond-shape keyframe (with OpenGL) */
void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode);
void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode);
/* ******************************* Methods ****************************** */

@ -147,6 +147,7 @@ void duplicate_fcurve_keys(struct FCurve *fcu);
void clean_fcurve(struct FCurve *fcu, float thresh);
void smooth_fcurve(struct FCurve *fcu);
void sample_fcurve(struct FCurve *fcu);
/* ----------- */

@ -65,13 +65,14 @@ struct FCurve *verify_fcurve(struct bAction *act, const char group[], const char
* Use this when validation of necessary animation data isn't necessary as it already
* exists, and there is a beztriple that can be directly copied into the array.
*/
int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt);
int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt, short flag);
/* Main Keyframing API call:
* Use this when validation of necessary animation data isn't necessary as it
* already exists. It will insert a keyframe using the current value being keyframed.
* Returns the index at which a keyframe was added (or -1 if failed)
*/
void insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
/* -------- */

@ -152,6 +152,8 @@ void ui_but_anim_autokey(uiBut *but, Scene *scene, float cfra)
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
fcu->flag &= ~FCURVE_SELECTED;
insert_keyframe(id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);

@ -397,7 +397,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
/* init keyframing flag */
if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
// if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
/* insert keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
@ -679,11 +679,6 @@ void ACT_OT_clean (wmOperatorType *ot)
/* ******************** Sample Keyframes Operator *********************** */
/* little cache for values... */
typedef struct tempFrameValCache {
float frame, val;
} tempFrameValCache;
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_action_keys (bAnimContext *ac)
{
@ -696,64 +691,8 @@ static void sample_action_keys (bAnimContext *ac)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
BezTriple *bezt, *start=NULL, *end=NULL;
tempFrameValCache *value_cache, *fp;
int sfra, range;
int i, n;
/* find selected keyframes... once pair has been found, add keyframes */
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
if (BEZSELECTED(bezt)) {
if (start) {
/* set end */
end= bezt;
/* cache values then add keyframes using these values, as adding
* keyframes while sampling will affect the outcome...
*/
range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
sfra= (int)( floor(start->vec[1][0]) );
if (range) {
value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
/* sample values */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
fp->frame= (float)(sfra + n);
fp->val= evaluate_fcurve(fcu, fp->frame);
}
/* add keyframes with these */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
}
/* free temp cache */
MEM_freeN(value_cache);
/* as we added keyframes, we need to compensate so that bezt is at the right place */
bezt = fcu->bezt + i + range - 1;
i += (range - 1);
}
/* bezt was selected, so it now marks the start of a whole new chain to search */
start= bezt;
end= NULL;
}
else {
/* just set start keyframe */
start= bezt;
end= NULL;
}
}
}
/* recalculate channel's handles? */
calchandles_fcurve(fcu);
}
for (ale= anim_data.first; ale; ale= ale->next)
sample_fcurve((FCurve *)ale->key_data);
/* admin and redraws */
BLI_freelistN(&anim_data);

@ -431,7 +431,7 @@ void action_header_buttons(const bContext *C, ARegion *ar)
"Auto-snapping mode for keyframes when transforming");
}
xco += (70 + 8);
xco += (90 + 8);
}
/* COPY PASTE */

@ -430,7 +430,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
/* init keyframing flag */
if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
// if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
/* insert keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
@ -989,13 +989,6 @@ void GRAPH_OT_bake (wmOperatorType *ot)
* of selected keyframes. It is useful for creating keyframes for tweaking overlap.
*/
// XXX some of the common parts (with DopeSheet) should be unified in animation module...
/* little cache for values... */
typedef struct tempFrameValCache {
float frame, val;
} tempFrameValCache;
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_graph_keys (bAnimContext *ac)
{
@ -1008,64 +1001,8 @@ static void sample_graph_keys (bAnimContext *ac)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
BezTriple *bezt, *start=NULL, *end=NULL;
tempFrameValCache *value_cache, *fp;
int sfra, range;
int i, n;
/* find selected keyframes... once pair has been found, add keyframes */
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
if (BEZSELECTED(bezt)) {
if (start) {
/* set end */
end= bezt;
/* cache values then add keyframes using these values, as adding
* keyframes while sampling will affect the outcome...
*/
range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
sfra= (int)( floor(start->vec[1][0]) );
if (range) {
value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
/* sample values */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
fp->frame= (float)(sfra + n);
fp->val= evaluate_fcurve(fcu, fp->frame);
}
/* add keyframes with these */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
}
/* free temp cache */
MEM_freeN(value_cache);
/* as we added keyframes, we need to compensate so that bezt is at the right place */
bezt = fcu->bezt + i + range - 1;
i += (range - 1);
}
/* bezt was selected, so it now marks the start of a whole new chain to search */
start= bezt;
end= NULL;
}
else {
/* just set start keyframe */
start= bezt;
end= NULL;
}
}
}
/* recalculate channel's handles? */
calchandles_fcurve(fcu);
}
for (ale= anim_data.first; ale; ale= ale->next)
sample_fcurve((FCurve *)ale->key_data);
/* admin and redraws */
BLI_freelistN(&anim_data);

@ -1748,7 +1748,7 @@ void flushTransParticles(TransInfo *t)
Object *ob = OBACT;
PTCacheEdit *edit = PE_get_current(scene, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd;
ParticleSystemModifierData *psmd = NULL;
PTCacheEditPoint *point;
PTCacheEditKey *key;
TransData *td;
@ -4348,12 +4348,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
AnimData *adt= ob->adt;
float cfra= (float)CFRA; // xxx this will do for now
short flag = 0;
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
/* only key on available channels */
if (adt && adt->action) {
@ -4365,7 +4367,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
short doLoc=0, doRot=0, doScale=0;
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
doLoc = 1;
@ -4377,7 +4379,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (v3d->around == V3D_CURSOR)
doLoc = 1;
if ((v3d->flag & V3D_ALIGN)==0)
doRot = 1;
}
@ -4388,11 +4390,11 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
}
else if (v3d->around == V3D_CURSOR)
doLoc = 1;
if ((v3d->flag & V3D_ALIGN)==0)
doScale = 1;
}
// TODO: the group names here are temporary...
// TODO: should this be made to use the builtin KeyingSets instead?
if (doLoc) {
@ -4417,16 +4419,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag);
insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag);
}
// XXX todo... find a way to send notifiers from here...
}
}
@ -4450,7 +4452,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
float cfra= (float)CFRA;
short flag= 0;
char buf[512];
/* flag is initialised from UserPref keyframing settings
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
* visual keyframes even if flag not set, as it's not that useful otherwise
@ -4460,12 +4462,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
flag |= INSERTKEY_MATRIX;
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
flag |= INSERTKEY_NEEDED;
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
flag |= INSERTKEY_REPLACE;
for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
/* clear any 'unkeyed' flag it may have */
pchan->bone->flag &= ~BONE_UNKEYED;
/* only insert into available channels? */
if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
if (act) {
@ -4476,7 +4480,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
/* only insert keyframe if needed? */
else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
short doLoc=0, doRot=0, doScale=0;
/* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
if (tmode == TFM_TRANSLATION) {
if (targetless_ik)
@ -4487,18 +4491,18 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
else if (tmode == TFM_ROTATION) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
doLoc = 1;
if ((v3d->flag & V3D_ALIGN)==0)
doRot = 1;
}
else if (tmode == TFM_RESIZE) {
if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
doLoc = 1;
if ((v3d->flag & V3D_ALIGN)==0)
doScale = 1;
}
if (doLoc) {
sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@ -4533,7 +4537,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
if (pchan->rotmode == PCHAN_ROT_QUAT) {
sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@ -4547,7 +4551,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
}
sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
@ -4555,14 +4559,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
}
}
}
// XXX todo... figure out way to get appropriate notifiers sent
/* do the bone paths */
#if 0 // TRANSFORM_FIX_ME
#if 0 // XXX TRANSFORM FIX ME
if (arm->pathflag & ARM_PATH_ACFRA) {
pose_clear_paths(ob);
pose_recalculate_paths(ob);
//pose_clear_paths(ob); // XXX for now, don't need to clear
ED_pose_recalculate_paths(C, scene, ob);
}
#endif
}