From a86ed166d7affa8e2e7841b9ab315bf749745367 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sun, 14 Jan 2024 19:14:39 +0100 Subject: [PATCH] VSE: Allow mirror axis crossing when moving transition key Transition retiming keys move as if they are mirrored across a point. It is possible to allow them to cross this point instead of limiting transition duration. This change itself doesn't really improve usability, but it is needed for "Add transition and change its size" operator. --- .../transform_convert_sequencer_retiming.cc | 18 +----- source/blender/sequencer/SEQ_retiming.hh | 8 +-- .../sequencer/intern/strip_retiming.cc | 60 ++++++++----------- 3 files changed, 29 insertions(+), 57 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_sequencer_retiming.cc b/source/blender/editors/transform/transform_convert_sequencer_retiming.cc index 5b4990fc8ba..0734e72fe79 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_retiming.cc +++ b/source/blender/editors/transform/transform_convert_sequencer_retiming.cc @@ -107,22 +107,6 @@ static void createTransSeqRetimingData(bContext * /*C*/, TransInfo *t) } } -static void seq_resize_speed_transition(const Scene *scene, - const Sequence *seq, - SeqRetimingKey *key, - const float loc) -{ - SeqRetimingKey *key_start = SEQ_retiming_transition_start_get(key); - float offset; - if (key == key_start) { - offset = loc - SEQ_retiming_key_timeline_frame_get(scene, seq, key); - } - else { - offset = SEQ_retiming_key_timeline_frame_get(scene, seq, key) - loc; - } - SEQ_retiming_offset_transition_key(scene, seq, key_start, offset); -} - static void recalcData_sequencer_retiming(TransInfo *t) { const TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); @@ -142,7 +126,7 @@ static void recalcData_sequencer_retiming(TransInfo *t) if (SEQ_retiming_key_is_transition_type(key) && !SEQ_retiming_selection_has_whole_transition(SEQ_editing_get(t->scene), key)) { - seq_resize_speed_transition(t->scene, seq, key, td2d->loc[0]); + SEQ_retiming_transition_key_frame_set(t->scene, seq, key, round_fl_to_int(td2d->loc[0])); } else { SEQ_retiming_key_timeline_frame_set(t->scene, seq, key, td2d->loc[0]); diff --git a/source/blender/sequencer/SEQ_retiming.hh b/source/blender/sequencer/SEQ_retiming.hh index bd2816a6825..ba78231ea3d 100644 --- a/source/blender/sequencer/SEQ_retiming.hh +++ b/source/blender/sequencer/SEQ_retiming.hh @@ -40,10 +40,10 @@ SeqRetimingKey *SEQ_retiming_add_freeze_frame(const Scene *scene, bool SEQ_retiming_is_last_key(const Sequence *seq, const SeqRetimingKey *key); SeqRetimingKey *SEQ_retiming_last_key_get(const Sequence *seq); void SEQ_retiming_remove_key(const Scene *scene, Sequence *seq, SeqRetimingKey *key); -void SEQ_retiming_offset_transition_key(const Scene *scene, - const Sequence *seq, - SeqRetimingKey *key, - int offset); +void SEQ_retiming_transition_key_frame_set(const Scene *scene, + const Sequence *seq, + SeqRetimingKey *key, + int timeline_frame); float SEQ_retiming_key_speed_get(const Sequence *seq, const SeqRetimingKey *key); void SEQ_retiming_key_speed_set( const Scene *scene, Sequence *seq, SeqRetimingKey *key, float speed, bool keep_retiming); diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index a5929bfc741..6450211dbb4 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -328,46 +328,34 @@ SeqRetimingKey *SEQ_retiming_add_key(const Scene *scene, Sequence *seq, const in return added_key; } -void SEQ_retiming_offset_transition_key(const Scene *scene, - const Sequence *seq, - SeqRetimingKey *key, - const int offset) +void SEQ_retiming_transition_key_frame_set(const Scene * /*scene */, + const Sequence *seq, + SeqRetimingKey *key, + const int timeline_frame) { - SeqRetimingKey *key_start, *key_end; - int corrected_offset; - - if (SEQ_retiming_key_is_transition_type(key)) { - key_start = key; - key_end = key + 1; - corrected_offset = offset; - } - else { - key_start = key - 1; - key_end = key; - corrected_offset = -1 * offset; - } - - /* Prevent transition keys crossing each other. */ - const float start_frame = SEQ_retiming_key_timeline_frame_get(scene, seq, key_start); - const float end_frame = SEQ_retiming_key_timeline_frame_get(scene, seq, key_end); - int xmax = ((start_frame + end_frame) / 2) - 1; - int max_offset = xmax - start_frame; - corrected_offset = min_ii(corrected_offset, max_offset); - /* Prevent mirrored movement crossing any key. */ - SeqRetimingKey *prev_segment_end = key_start - 1, *next_segment_start = key_end + 1; - const int offset_min_left = SEQ_retiming_key_timeline_frame_get(scene, seq, prev_segment_end) + - 1 - start_frame; - const int offset_min_right = - end_frame - SEQ_retiming_key_timeline_frame_get(scene, seq, next_segment_start) - 1; - corrected_offset = max_iii(corrected_offset, offset_min_left, offset_min_right); - + SeqRetimingKey *key_start = SEQ_retiming_transition_start_get(key); + SeqRetimingKey *key_end = key_start + 1; + const int start_frame_index = key_start->strip_frame_index; + const int midpoint = key_start->original_strip_frame_index; + const int new_frame_index = timeline_frame - SEQ_time_start_frame_get(seq); + int new_midpoint_offset = new_frame_index - midpoint; const float prev_segment_step = seq_retiming_segment_step_get(key_start - 1); const float next_segment_step = seq_retiming_segment_step_get(key_end); - key_start->strip_frame_index += corrected_offset; - key_start->retiming_factor += corrected_offset * prev_segment_step; - key_end->strip_frame_index -= corrected_offset; - key_end->retiming_factor -= corrected_offset * next_segment_step; + /* Prevent keys crossing eachother. */ + SeqRetimingKey *prev_segment_end = key_start - 1, *next_segment_start = key_end + 1; + const int offset_max_left = midpoint - prev_segment_end->strip_frame_index - 1; + const int offset_max_right = next_segment_start->strip_frame_index - midpoint - 1; + new_midpoint_offset = abs(new_midpoint_offset); + new_midpoint_offset = min_iii(new_midpoint_offset, offset_max_left, offset_max_right); + new_midpoint_offset = max_ii(new_midpoint_offset, 1); + + key_start->strip_frame_index = midpoint - new_midpoint_offset; + key_end->strip_frame_index = midpoint + new_midpoint_offset; + + const int offset = key_start->strip_frame_index - start_frame_index; + key_start->retiming_factor += offset * prev_segment_step; + key_end->retiming_factor -= offset * next_segment_step; } static void seq_retiming_cleanup_freeze_frame(SeqRetimingKey *key)