VSE preview transform autokeying improvements
NOTE: this patch originated in T98015 which was split into multiple reports. While it could be split into multiple patches these are very much related so keeping as one for now This patch fixes the following issues: [1] autokeying transforms in preview only creates keyframes if there is an FCurve already [2] autokeying transforms in preview only creates keyframes for rotation/scale if rotating/scaling around cursor (should keyframe position as well) [3] autokeying transforms in preview does not work during animation playback For [1], a param was added to `ED_autokeyframe_property` which can tweak its default behavior of only creating keyframes on already keyed properties (which was fine because this is mostly called from buttons where this behavior is desired). Callers such as gizmos (or the VSE in our case) can use this additional param so that keyframes are also created on "not-yet-keyframed" properties. For [2], the pivot is checked and position properties also keyed if necessary (which is also consistent with the way objects are keyed in the 3DView) For [3], `animrecord_check_state` was changed to be able to work on scenes as well and the transform system in the VSE preview was made aware of the screen's `animtimer`. NOTE: there are still things to be improved for keyframing in the VSE, the most obvious is probably a `keyframe_insert` operator (with keyingsets) Fixes T98429, T98430, T98431 Maniphest Tasks: T98015, T98431, T98430, T98429 Differential Revision: https://developer.blender.org/D15047
This commit is contained in:
parent
4580c18c56
commit
9ccc21dde3
Notes:
blender-bot
2023-05-29 09:17:12 +02:00
Referenced by issue #98429, VSE autokeying transforms in preview only creates keyframes for rotation/scale if rotating/scaling around cursor (should keyframe position as well) Referenced by issue #98430, VSE autokeying transforms in preview only creates keyframes if there is an FCurve already Referenced by issue #98431, VSE autokeying transforms in preview does not work during animation playback Referenced by issue #98015, VSE strip transforms do not animate correctly and persist after clearing the animation
|
@ -3094,8 +3094,13 @@ bool ED_autokeyframe_pchan(
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ED_autokeyframe_property(
|
||||
bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra)
|
||||
bool ED_autokeyframe_property(bContext *C,
|
||||
Scene *scene,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int rnaindex,
|
||||
float cfra,
|
||||
const bool only_if_property_keyed)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
|
@ -3114,7 +3119,8 @@ bool ED_autokeyframe_property(
|
|||
fcu = BKE_fcurve_find_by_rna_context_ui(
|
||||
C, ptr, prop, rnaindex_check, NULL, &action, &driven, &special);
|
||||
|
||||
if (fcu == NULL) {
|
||||
/* Only early out when we actually want an existing fcurve already (e.g. auto-keyframing from buttons). */
|
||||
if (fcu == NULL && (driven || special || only_if_property_keyed)) {
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
@ -3150,23 +3156,28 @@ bool ED_autokeyframe_property(
|
|||
ReportList *reports = CTX_wm_reports(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
const eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene, true);
|
||||
char *path = RNA_path_from_ID_to_property(ptr, prop);
|
||||
|
||||
/* NOTE: We use rnaindex instead of fcu->array_index,
|
||||
* because a button may control all items of an array at once.
|
||||
* E.g., color wheels (see T42567). */
|
||||
BLI_assert((fcu->array_index == rnaindex) || (rnaindex == -1));
|
||||
if (only_if_property_keyed) {
|
||||
/* NOTE: We use rnaindex instead of fcu->array_index,
|
||||
* because a button may control all items of an array at once.
|
||||
* E.g., color wheels (see T42567). */
|
||||
BLI_assert((fcu->array_index == rnaindex) || (rnaindex == -1));
|
||||
}
|
||||
changed = insert_keyframe(bmain,
|
||||
reports,
|
||||
id,
|
||||
action,
|
||||
((fcu->grp) ? (fcu->grp->name) : (NULL)),
|
||||
fcu->rna_path,
|
||||
(fcu && fcu->grp) ? fcu->grp->name : NULL,
|
||||
fcu ? fcu->rna_path : path,
|
||||
rnaindex,
|
||||
&anim_eval_context,
|
||||
ts->keyframe_type,
|
||||
NULL,
|
||||
flag) != 0;
|
||||
|
||||
if (path) {
|
||||
MEM_freeN(path);
|
||||
}
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -658,15 +658,20 @@ bool ED_autokeyframe_pchan(struct bContext *C,
|
|||
struct Object *ob,
|
||||
struct bPoseChannel *pchan,
|
||||
struct KeyingSet *ks);
|
||||
|
||||
/**
|
||||
* Use for auto-key-framing from the UI.
|
||||
* Use for auto-key-framing
|
||||
* \param only_if_property_keyed: if true, auto-key-framing only creates keyframes on already keyed
|
||||
* properties. This is by design when using buttons. For other callers such as gizmos or VSE preview
|
||||
* transform, creating new animation/keyframes also on non-keyed properties is desired.
|
||||
*/
|
||||
bool ED_autokeyframe_property(struct bContext *C,
|
||||
struct Scene *scene,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
int rnaindex,
|
||||
float cfra);
|
||||
float cfra,
|
||||
bool only_if_property_keyed);
|
||||
|
||||
/* Names for builtin keying sets so we don't confuse these with labels/text,
|
||||
* defined in python script: `keyingsets_builtins.py`. */
|
||||
|
|
|
@ -293,7 +293,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str)
|
|||
|
||||
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
|
||||
{
|
||||
ED_autokeyframe_property(C, scene, &but->rnapoin, but->rnaprop, but->rnaindex, cfra);
|
||||
ED_autokeyframe_property(C, scene, &but->rnapoin, but->rnaprop, but->rnaindex, cfra, true);
|
||||
}
|
||||
|
||||
void ui_but_anim_copy_driver(bContext *C)
|
||||
|
|
|
@ -1607,10 +1607,9 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc)
|
|||
}
|
||||
}
|
||||
|
||||
void animrecord_check_state(TransInfo *t, struct Object *ob)
|
||||
void animrecord_check_state(TransInfo *t, struct ID *id)
|
||||
{
|
||||
Scene *scene = t->scene;
|
||||
ID *id = &ob->id;
|
||||
wmTimer *animtimer = t->animtimer;
|
||||
ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc);
|
|||
/**
|
||||
* For the realtime animation recording feature, handle overlapping data.
|
||||
*/
|
||||
void animrecord_check_state(TransInfo *t, struct Object *ob);
|
||||
void animrecord_check_state(TransInfo *t, struct ID *id);
|
||||
|
||||
/* transform_convert_action.c */
|
||||
|
||||
|
|
|
@ -1471,7 +1471,7 @@ void recalcData_pose(TransInfo *t)
|
|||
/* XXX: this currently doesn't work, since flags aren't set yet! */
|
||||
int targetless_ik = (t->flag & T_AUTOIK);
|
||||
|
||||
animrecord_check_state(t, ob);
|
||||
animrecord_check_state(t, &ob->id);
|
||||
autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
|
||||
}
|
||||
|
||||
|
|
|
@ -884,7 +884,7 @@ void recalcData_objects(TransInfo *t)
|
|||
/* TODO: autokeyframe calls need some setting to specify to add samples
|
||||
* (FPoints) instead of keyframes? */
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
|
||||
animrecord_check_state(t, ob);
|
||||
animrecord_check_state(t, &ob->id);
|
||||
autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,6 +154,42 @@ void createTransSeqImageData(TransInfo *t)
|
|||
SEQ_collection_free(strips);
|
||||
}
|
||||
|
||||
static bool autokeyframe_sequencer_image(bContext *C,
|
||||
Scene *scene,
|
||||
StripTransform *transform,
|
||||
const int tmode)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
RNA_pointer_create(&scene->id, &RNA_SequenceTransform, transform, &ptr);
|
||||
|
||||
const bool around_cursor = scene->toolsettings->sequencer_tool_settings->pivot_point ==
|
||||
V3D_AROUND_CURSOR;
|
||||
const bool do_loc = tmode == TFM_TRANSLATION || around_cursor;
|
||||
const bool do_rot = tmode == TFM_ROTATION;
|
||||
const bool do_scale = tmode == TFM_RESIZE;
|
||||
|
||||
bool changed = false;
|
||||
if (do_rot) {
|
||||
prop = RNA_struct_find_property(&ptr, "rotation");
|
||||
changed |= ED_autokeyframe_property(C, scene, &ptr, prop, -1, CFRA, false);
|
||||
}
|
||||
if (do_loc) {
|
||||
prop = RNA_struct_find_property(&ptr, "offset_x");
|
||||
changed |= ED_autokeyframe_property(C, scene, &ptr, prop, -1, CFRA, false);
|
||||
prop = RNA_struct_find_property(&ptr, "offset_y");
|
||||
changed |= ED_autokeyframe_property(C, scene, &ptr, prop, -1, CFRA, false);
|
||||
}
|
||||
if (do_scale) {
|
||||
prop = RNA_struct_find_property(&ptr, "scale_x");
|
||||
changed |= ED_autokeyframe_property(C, scene, &ptr, prop, -1, CFRA, false);
|
||||
prop = RNA_struct_find_property(&ptr, "scale_y");
|
||||
changed |= ED_autokeyframe_property(C, scene, &ptr, prop, -1, CFRA, false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void recalcData_sequencer_image(TransInfo *t)
|
||||
{
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
@ -199,6 +235,12 @@ void recalcData_sequencer_image(TransInfo *t)
|
|||
if (t->mode == TFM_ROTATION) {
|
||||
transform->rotation = tdseq->orig_rotation - t->values_final[0];
|
||||
}
|
||||
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
|
||||
animrecord_check_state(t, &t->scene->id);
|
||||
autokeyframe_sequencer_image(t->context, t->scene, transform, t->mode);
|
||||
}
|
||||
|
||||
SEQ_relations_invalidate_cache_preprocessed(t->scene, seq);
|
||||
}
|
||||
}
|
||||
|
@ -211,9 +253,6 @@ void special_aftertrans_update__sequencer_image(bContext *UNUSED(C), TransInfo *
|
|||
TransData2D *td2d = NULL;
|
||||
int i;
|
||||
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
|
||||
for (i = 0, td = tc->data, td2d = tc->data_2d; i < tc->data_len; i++, td++, td2d++) {
|
||||
TransDataSeq *tdseq = td->extra;
|
||||
Sequence *seq = tdseq->seq;
|
||||
|
@ -225,24 +264,8 @@ void special_aftertrans_update__sequencer_image(bContext *UNUSED(C), TransInfo *
|
|||
continue;
|
||||
}
|
||||
|
||||
Scene *scene = t->scene;
|
||||
RNA_pointer_create(&scene->id, &RNA_SequenceTransform, transform, &ptr);
|
||||
|
||||
if (t->mode == TFM_ROTATION) {
|
||||
prop = RNA_struct_find_property(&ptr, "rotation");
|
||||
ED_autokeyframe_property(t->context, scene, &ptr, prop, -1, CFRA);
|
||||
}
|
||||
if (t->mode == TFM_TRANSLATION) {
|
||||
prop = RNA_struct_find_property(&ptr, "offset_x");
|
||||
ED_autokeyframe_property(t->context, scene, &ptr, prop, -1, CFRA);
|
||||
prop = RNA_struct_find_property(&ptr, "offset_y");
|
||||
ED_autokeyframe_property(t->context, scene, &ptr, prop, -1, CFRA);
|
||||
}
|
||||
if (t->mode == TFM_RESIZE) {
|
||||
prop = RNA_struct_find_property(&ptr, "scale_x");
|
||||
ED_autokeyframe_property(t->context, scene, &ptr, prop, -1, CFRA);
|
||||
prop = RNA_struct_find_property(&ptr, "scale_y");
|
||||
ED_autokeyframe_property(t->context, scene, &ptr, prop, -1, CFRA);
|
||||
if (IS_AUTOKEY_ON(t->scene)) {
|
||||
autokeyframe_sequencer_image(t->context, t->scene, transform, t->mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,6 +358,10 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
|||
}
|
||||
else if (t->spacetype == SPACE_SEQ && region->regiontype == RGN_TYPE_PREVIEW) {
|
||||
t->options |= CTX_SEQUENCER_IMAGE;
|
||||
|
||||
/* Needed for autokeying transforms in preview during playback. */
|
||||
bScreen *animscreen = ED_screen_animation_playing(CTX_wm_manager(C));
|
||||
t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
|
||||
}
|
||||
|
||||
setTransformViewAspect(t, t->aspect);
|
||||
|
|
|
@ -345,7 +345,7 @@ void WM_gizmo_target_property_anim_autokey(bContext *C,
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
const float cfra = (float)CFRA;
|
||||
const int index = gz_prop->index == -1 ? 0 : gz_prop->index;
|
||||
ED_autokeyframe_property(C, scene, &gz_prop->ptr, gz_prop->prop, index, cfra);
|
||||
ED_autokeyframe_property(C, scene, &gz_prop->ptr, gz_prop->prop, index, cfra, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue