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.
This commit is contained in:
Richard Antalik 2024-01-14 19:14:39 +01:00
parent 665cfbe564
commit a86ed166d7
3 changed files with 29 additions and 57 deletions

View File

@ -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]);

View File

@ -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);

View File

@ -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)