diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-11-12 19:41:53 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-12-14 22:19:18 +0300 |
commit | de662e7cd3b3ca45c4220e3830c32e2b3496c9fe (patch) | |
tree | 79b78cc746c5121ac4c964dffef94d961fd14975 /source/blender/editors/animation/anim_channels_defines.c | |
parent | fc74903f272a01784e0376c9ee12c2673017285d (diff) |
NLA: insert keyframes correctly for strips with non-Replace mode.
NLA strips support using the keyframe values in a variety of ways:
adding, subtracting, multiplying, linearly mixing with the result
of strips located below in the stack. This is intended for layering
tweaks on top of a base animation.
However, when inserting keyframes into such strips, it simply inserts
the final value of the property, irrespective of these settings. This
in fact makes the feature nearly useless.
To fix this it is necessary to evaluate the NLA stack below the
edited strip and correctly compute the raw key that would produce
the intended final value, according to the mode and influence.
Differential Revision: https://developer.blender.org/D3927
Diffstat (limited to 'source/blender/editors/animation/anim_channels_defines.c')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 9bd7e277098..341bc25875e 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4125,21 +4125,25 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi ReportList *reports = CTX_wm_reports(C); Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; + ListBase nla_cache = {NULL, NULL}; PointerRNA id_ptr, ptr; PropertyRNA *prop; short flag = 0; bool done = false; float cfra; + /* Get RNA pointer */ + RNA_id_pointer_create(id, &id_ptr); + + /* Get NLA context for value remapping */ + NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(&nla_cache, depsgraph, &id_ptr, adt, (float)CFRA); + /* get current frame and apply NLA-mapping to it (if applicable) */ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); /* get flags for keyframing */ flag = ANIM_get_keyframing_flags(scene, 1); - /* get RNA pointer, and resolve the path */ - RNA_id_pointer_create(id, &id_ptr); - /* try to resolve the path stored in the F-Curve */ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { /* set the special 'replace' flag if on a keyframe */ @@ -4147,11 +4151,13 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi flag |= INSERTKEY_REPLACE; /* insert a keyframe for this F-Curve */ - done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag); + done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag); if (done) WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); } + + BKE_animsys_free_nla_keyframing_context_cache(&nla_cache); } /* callback for shapekey widget sliders - insert keyframes */ @@ -4166,21 +4172,25 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi ReportList *reports = CTX_wm_reports(C); Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; + ListBase nla_cache = {NULL, NULL}; PointerRNA id_ptr, ptr; PropertyRNA *prop; short flag = 0; bool done = false; float cfra; + /* Get RNA pointer */ + RNA_id_pointer_create((ID *)key, &id_ptr); + + /* Get NLA context for value remapping */ + NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(&nla_cache, depsgraph, &id_ptr, key->adt, (float)CFRA); + /* get current frame and apply NLA-mapping to it (if applicable) */ cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP); /* get flags for keyframing */ flag = ANIM_get_keyframing_flags(scene, 1); - /* get RNA pointer, and resolve the path */ - RNA_id_pointer_create((ID *)key, &id_ptr); - /* try to resolve the path stored in the F-Curve */ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) { /* find or create new F-Curve */ @@ -4193,7 +4203,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi flag |= INSERTKEY_REPLACE; /* insert a keyframe for this F-Curve */ - done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag); + done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag); if (done) WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); @@ -4202,6 +4212,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi /* free the path */ if (rna_path) MEM_freeN(rna_path); + + BKE_animsys_free_nla_keyframing_context_cache(&nla_cache); } /* callback for NLA Control Curve widget sliders - insert keyframes */ @@ -4237,7 +4249,7 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C, void *UNUSED(id_po flag |= INSERTKEY_REPLACE; /* insert a keyframe for this F-Curve */ - done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, flag); + done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag); if (done) WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); |