mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
VSE: Slip keyframes with strip content
The "slip strip contents" operator in the VSE now can move the strip keyframes. There is a property to enable keyframe slipping. The property is disabled by default, mainly because animation is often used for fade in/out, which would be annoying if it moved with content. Pull Request: https://projects.blender.org/blender/blender/pulls/136386
This commit is contained in:
parent
a7026e817c
commit
3e023fcf79
5 changed files with 49 additions and 19 deletions
|
|
@ -548,7 +548,8 @@ static wmOperatorStatus sequencer_slip_invoke(bContext *C, wmOperator *op, const
|
|||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static void sequencer_slip_strips(Scene *scene, SlipData *data, int delta, float subframe_delta)
|
||||
static void sequencer_slip_strips(
|
||||
Scene *scene, SlipData *data, int delta, float subframe_delta, bool slip_keyframes)
|
||||
{
|
||||
for (int i = data->num_seq - 1; i >= 0; i--) {
|
||||
Strip *strip = data->strip_array[i];
|
||||
|
|
@ -558,7 +559,7 @@ static void sequencer_slip_strips(Scene *scene, SlipData *data, int delta, float
|
|||
continue;
|
||||
}
|
||||
|
||||
seq::time_slip_strip(scene, strip, delta, subframe_delta);
|
||||
seq::time_slip_strip(scene, strip, delta, subframe_delta, slip_keyframes);
|
||||
}
|
||||
|
||||
for (int i = data->num_seq - 1; i >= 0; i--) {
|
||||
|
|
@ -614,6 +615,7 @@ static wmOperatorStatus sequencer_slip_exec(bContext *C, wmOperator *op)
|
|||
|
||||
slip_add_sequences(ed->seqbasep, data->strip_array);
|
||||
|
||||
bool slip_keyframes = RNA_boolean_get(op->ptr, "slip_keyframes");
|
||||
float offset_fl = RNA_float_get(op->ptr, "offset");
|
||||
int offset = round_fl_to_int(offset_fl);
|
||||
|
||||
|
|
@ -624,7 +626,7 @@ static wmOperatorStatus sequencer_slip_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
sequencer_slip_apply_limits(scene, data, &offset);
|
||||
sequencer_slip_strips(scene, data, offset, subframe_delta);
|
||||
sequencer_slip_strips(scene, data, offset, subframe_delta, slip_keyframes);
|
||||
|
||||
MEM_freeN(data->strip_array);
|
||||
MEM_freeN(data);
|
||||
|
|
@ -679,7 +681,9 @@ static void handle_number_input(
|
|||
data->subframe_restore += subframe_delta;
|
||||
}
|
||||
data->previous_subframe_offset = offset_fl;
|
||||
sequencer_slip_strips(scene, data, delta_offset, subframe_delta);
|
||||
|
||||
bool slip_keyframes = RNA_boolean_get(op->ptr, "slip_keyframes");
|
||||
sequencer_slip_strips(scene, data, delta_offset, subframe_delta, slip_keyframes);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
}
|
||||
|
|
@ -738,7 +742,9 @@ static wmOperatorStatus sequencer_slip_modal(bContext *C, wmOperator *op, const
|
|||
data->subframe_restore = 0.0f;
|
||||
}
|
||||
data->previous_subframe_offset = offset_fl;
|
||||
sequencer_slip_strips(scene, data, delta_offset, subframe_delta);
|
||||
|
||||
bool slip_keyframes = RNA_boolean_get(op->ptr, "slip_keyframes");
|
||||
sequencer_slip_strips(scene, data, delta_offset, subframe_delta, slip_keyframes);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
}
|
||||
|
|
@ -764,7 +770,8 @@ static wmOperatorStatus sequencer_slip_modal(bContext *C, wmOperator *op, const
|
|||
case RIGHTMOUSE: {
|
||||
int offset = data->previous_offset;
|
||||
float subframe_delta = data->subframe_restore;
|
||||
sequencer_slip_strips(scene, data, -offset, -subframe_delta);
|
||||
bool slip_keyframes = RNA_boolean_get(op->ptr, "slip_keyframes");
|
||||
sequencer_slip_strips(scene, data, -offset, -subframe_delta, slip_keyframes);
|
||||
|
||||
MEM_freeN(data->strip_array);
|
||||
MEM_freeN(data);
|
||||
|
|
@ -834,6 +841,11 @@ void SEQUENCER_OT_slip(wmOperatorType *ot)
|
|||
-FLT_MAX,
|
||||
FLT_MAX);
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, 0);
|
||||
RNA_def_boolean(ot->srna,
|
||||
"slip_keyframes",
|
||||
false,
|
||||
"Slip Keyframes",
|
||||
"Move the keyframes alongside the media");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ struct ListBase;
|
|||
struct Scene;
|
||||
struct Strip;
|
||||
struct SeqAnimationBackup;
|
||||
|
||||
namespace blender::seq {
|
||||
|
||||
bool animation_keyframes_exist(Scene *scene);
|
||||
bool animation_keyframes_exist(const Scene *scene);
|
||||
bool animation_drivers_exist(Scene *scene);
|
||||
void free_animdata(Scene *scene, Strip *strip);
|
||||
void offset_animdata(Scene *scene, Strip *strip, int ofs);
|
||||
void offset_animdata(const Scene *scene, Strip *strip, float ofs);
|
||||
|
||||
/**
|
||||
* Return whether the fcurve targets the given sequence.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -125,7 +125,8 @@ void time_update_meta_strip_range(const Scene *scene, Strip *strip_meta);
|
|||
/**
|
||||
* Move contents of a strip without moving the strip handles.
|
||||
*/
|
||||
void time_slip_strip(const Scene *scene, Strip *strip, int delta, float subframe_delta);
|
||||
void time_slip_strip(
|
||||
const Scene *scene, Strip *strip, int delta, float subframe_delta, bool slip_keyframes);
|
||||
/**
|
||||
* Get difference between scene and movie strip frame-rate.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
namespace blender::seq {
|
||||
|
||||
bool animation_keyframes_exist(Scene *scene)
|
||||
bool animation_keyframes_exist(const Scene *scene)
|
||||
{
|
||||
return scene->adt != nullptr && scene->adt->action != nullptr &&
|
||||
scene->adt->action->wrap().has_keyframes(scene->adt->slot_handle);
|
||||
|
|
@ -39,9 +39,9 @@ bool fcurve_matches(const Strip &strip, const FCurve &fcurve)
|
|||
fcurve, "sequence_editor.strips_all[", strip.name + 2);
|
||||
}
|
||||
|
||||
void offset_animdata(Scene *scene, Strip *strip, int ofs)
|
||||
void offset_animdata(const Scene *scene, Strip *strip, float ofs)
|
||||
{
|
||||
if (!animation_keyframes_exist(scene) || ofs == 0) {
|
||||
if (!animation_keyframes_exist(scene) || ofs == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "MOV_read.hh"
|
||||
|
||||
#include "SEQ_animation.hh"
|
||||
#include "SEQ_channels.hh"
|
||||
#include "SEQ_iterator.hh"
|
||||
#include "SEQ_render.hh"
|
||||
|
|
@ -551,14 +552,18 @@ void strip_time_translate_handles(const Scene *scene, Strip *strip, const int of
|
|||
time_update_meta_strip_range(scene, lookup_meta_by_strip(scene->ed, strip));
|
||||
}
|
||||
|
||||
static void strip_time_slip_strip_ex(
|
||||
const Scene *scene, Strip *strip, int delta, float subframe_delta, bool recursed)
|
||||
static void strip_time_slip_strip_ex(const Scene *scene,
|
||||
Strip *strip,
|
||||
int delta,
|
||||
float subframe_delta,
|
||||
bool slip_keyframes,
|
||||
bool recursed)
|
||||
{
|
||||
if (strip->type == STRIP_TYPE_SOUND_RAM && subframe_delta != 0.0f) {
|
||||
strip->sound_offset += subframe_delta / FPS;
|
||||
}
|
||||
|
||||
if (delta == 0) {
|
||||
if (delta == 0 && (!slip_keyframes || subframe_delta == 0.0f)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -580,12 +585,23 @@ static void strip_time_slip_strip_ex(
|
|||
if (BLI_listbase_is_empty(&strip->seqbase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Strip *, strip_child, &strip->seqbase) {
|
||||
strip_time_slip_strip_ex(scene, strip_child, delta, subframe_delta, true);
|
||||
/* The keyframes of strips inside meta strips should always be moved. */
|
||||
strip_time_slip_strip_ex(scene, strip_child, delta, subframe_delta, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
strip->start = strip->start + delta;
|
||||
|
||||
if (slip_keyframes) {
|
||||
float anim_offset = delta;
|
||||
if (strip->type == STRIP_TYPE_SOUND_RAM) {
|
||||
anim_offset += subframe_delta;
|
||||
}
|
||||
offset_animdata(scene, strip, anim_offset);
|
||||
}
|
||||
|
||||
if (!recursed) {
|
||||
strip->startofs = strip->startofs - delta;
|
||||
strip->endofs = strip->endofs + delta;
|
||||
|
|
@ -599,9 +615,10 @@ static void strip_time_slip_strip_ex(
|
|||
strip_time_update_effects_strip_range(scene, effects);
|
||||
}
|
||||
|
||||
void time_slip_strip(const Scene *scene, Strip *strip, int delta, float subframe_delta)
|
||||
void time_slip_strip(
|
||||
const Scene *scene, Strip *strip, int delta, float subframe_delta, bool slip_keyframes)
|
||||
{
|
||||
strip_time_slip_strip_ex(scene, strip, delta, subframe_delta, false);
|
||||
strip_time_slip_strip_ex(scene, strip, delta, subframe_delta, slip_keyframes, false);
|
||||
}
|
||||
|
||||
int time_get_rounded_sound_offset(const Strip *strip, const float frames_per_second)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue