diff --git a/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc b/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc index ac224c08d7f..2f8c7fe5135 100644 --- a/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc +++ b/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc @@ -65,16 +65,17 @@ static float strip_y_rescale(const Sequence *seq, const float y_value) return (y_value * y_range) + seq->machine + SEQ_STRIP_OFSBOTTOM; } -static float handle_x_get(const Sequence *seq, const SeqRetimingHandle *handle) +static float handle_x_get(const Scene *scene, const Sequence *seq, const SeqRetimingHandle *handle) { const SeqRetimingHandle *last_handle = SEQ_retiming_last_handle_get(seq); const bool is_last_handle = (handle == last_handle); - return SEQ_time_start_frame_get(seq) + handle->strip_frame_index + (is_last_handle ? 1 : 0); + return SEQ_retiming_handle_timeline_frame_get(scene, seq, handle) + (is_last_handle ? 1 : 0); } -static const SeqRetimingHandle *mouse_over_handle_get(const Sequence *seq, +static const SeqRetimingHandle *mouse_over_handle_get(const Scene *scene, + const Sequence *seq, const View2D *v2d, const int mval[2]) { @@ -84,7 +85,7 @@ static const SeqRetimingHandle *mouse_over_handle_get(const Sequence *seq, MutableSpan handles = SEQ_retiming_handles_get(seq); for (const SeqRetimingHandle &handle : handles) { int distance = round_fl_to_int( - fabsf(UI_view2d_view_to_region_x(v2d, handle_x_get(seq, &handle)) - mval[0])); + fabsf(UI_view2d_view_to_region_x(v2d, handle_x_get(scene, seq, &handle)) - mval[0])); if (distance < RETIME_HANDLE_MOUSEOVER_THRESHOLD && distance < best_distance) { best_distance = distance; @@ -316,7 +317,7 @@ static void retime_handle_draw(const bContext *C, const SeqRetimingHandle *handle) { const Scene *scene = CTX_data_scene(C); - const float handle_x = handle_x_get(seq, handle); + const float handle_x = handle_x_get(scene, seq, handle); if (handle_x == SEQ_time_left_handle_frame_get(scene, seq)) { return; @@ -371,7 +372,8 @@ static void retime_speed_text_draw(const bContext *C, int next_handle_index = SEQ_retiming_handle_index_get(seq, handle) + 1; const SeqRetimingHandle *next_handle = &SEQ_retiming_handles_get(seq)[next_handle_index]; - if (handle_x_get(seq, next_handle) < start_frame || handle_x_get(seq, handle) > end_frame) { + if (handle_x_get(scene, seq, next_handle) < start_frame || + handle_x_get(scene, seq, handle) > end_frame) { return; /* Label out of strip bounds. */ } @@ -383,9 +385,10 @@ static void retime_speed_text_draw(const bContext *C, const float width = pixels_to_view_width(C, BLF_width(BLF_default(), label_str, label_len)); - const float xmin = max_ff(SEQ_time_left_handle_frame_get(scene, seq), handle_x_get(seq, handle)); + const float xmin = max_ff(SEQ_time_left_handle_frame_get(scene, seq), + handle_x_get(scene, seq, handle)); const float xmax = min_ff(SEQ_time_right_handle_frame_get(scene, seq), - handle_x_get(seq, next_handle)); + handle_x_get(scene, seq, next_handle)); const float text_x = (xmin + xmax - width) / 2; const float text_y = strip_y_rescale(seq, 0) + pixels_to_view_height(C, 5); @@ -437,14 +440,15 @@ static int gizmo_retime_handle_test_select(bContext *C, wmGizmo *gz, const int m Sequence *seq = active_seq_from_context(C); SEQ_retiming_data_ensure(CTX_data_scene(C), seq); - const SeqRetimingHandle *handle = mouse_over_handle_get(seq, UI_view2d_fromcontext(C), mval); + const SeqRetimingHandle *handle = mouse_over_handle_get( + scene, seq, UI_view2d_fromcontext(C), mval); const int handle_index = SEQ_retiming_handle_index_get(seq, handle); if (handle == nullptr) { return -1; } - if (handle_x_get(seq, handle) == SEQ_time_left_handle_frame_get(scene, seq) || + if (handle_x_get(scene, seq, handle) == SEQ_time_left_handle_frame_get(scene, seq) || handle_index == 0) { return -1; } @@ -456,7 +460,7 @@ static int gizmo_retime_handle_test_select(bContext *C, wmGizmo *gz, const int m } gizmo->mouse_over_seq = seq; - gizmo->mouse_over_handle_x = handle_x_get(seq, handle); + gizmo->mouse_over_handle_x = handle_x_get(scene, seq, handle); wmGizmoOpElem *op_elem = WM_gizmo_operator_get(gz, 0); RNA_int_set(&op_elem->ptr, "handle_index", handle_index); @@ -511,14 +515,15 @@ static int gizmo_retime_remove_test_select(bContext *C, wmGizmo *gz, const int m Sequence *seq = active_seq_from_context(C); SEQ_retiming_data_ensure(CTX_data_scene(C), seq); - const SeqRetimingHandle *handle = mouse_over_handle_get(seq, UI_view2d_fromcontext(C), mval); + const SeqRetimingHandle *handle = mouse_over_handle_get( + scene, seq, UI_view2d_fromcontext(C), mval); const int handle_index = SEQ_retiming_handle_index_get(seq, handle); if (handle == nullptr) { return -1; } - if (handle_x_get(seq, handle) == SEQ_time_left_handle_frame_get(scene, seq) || + if (handle_x_get(scene, seq, handle) == SEQ_time_left_handle_frame_get(scene, seq) || handle_index == 0) { return -1; /* Ignore first handle. */ } diff --git a/source/blender/editors/space_sequencer/sequencer_retiming.cc b/source/blender/editors/space_sequencer/sequencer_retiming.cc index 84708b74e77..cc43eae4217 100644 --- a/source/blender/editors/space_sequencer/sequencer_retiming.cc +++ b/source/blender/editors/space_sequencer/sequencer_retiming.cc @@ -111,6 +111,7 @@ static SeqRetimingHandle *closest_retiming_handle_get(const bContext *C, const float mouse_x) { const View2D *v2d = UI_view2d_fromcontext(C); + const Scene *scene = CTX_data_scene(C); int best_distance = INT_MAX; SeqRetimingHandle *closest_handle = nullptr; @@ -119,7 +120,8 @@ static SeqRetimingHandle *closest_retiming_handle_get(const bContext *C, for (int i = 0; i < SEQ_retiming_handles_count(seq); i++) { SeqRetimingHandle *handle = seq->retiming_handles + i; - const int distance = round_fl_to_int(fabsf(handle->strip_frame_index - mouse_x_view)); + const int distance = round_fl_to_int( + fabsf(SEQ_retiming_handle_timeline_frame_get(scene, seq, handle) - mouse_x_view)); if (distance < distance_threshold && distance < best_distance) { best_distance = distance; @@ -143,7 +145,7 @@ static int sequencer_retiming_handle_move_invoke(bContext *C, wmOperator *op, co /* Ensure retiming handle at left handle position. This way user gets more predictable result * when strips have offsets. */ const int left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq); - if (SEQ_retiming_add_handle(seq, left_handle_frame) != nullptr) { + if (SEQ_retiming_add_handle(scene, seq, left_handle_frame) != nullptr) { handle_index++; /* Advance index, because new handle was created. */ } @@ -184,9 +186,9 @@ static int sequencer_retiming_handle_move_modal(bContext *C, wmOperator *op, con SeqRetimingHandle *handle_prev = handle - 1; /* Limit retiming handle movement. */ - int xmin = SEQ_time_start_frame_get(seq) + handle_prev->strip_frame_index + 1; + int xmin = SEQ_retiming_handle_timeline_frame_get(scene, seq, handle_prev) + 1; mouse_x = max_ff(xmin, mouse_x); - offset = mouse_x - (SEQ_time_start_frame_get(seq) + handle->strip_frame_index); + offset = mouse_x - SEQ_retiming_handle_timeline_frame_get(scene, seq, handle); SEQ_retiming_offset_handle(scene, seq, handle, offset); @@ -261,7 +263,7 @@ static int sequesequencer_retiming_handle_add_exec(bContext *C, wmOperator *op) bool inserted = false; const float end_frame = seq->start + SEQ_time_strip_length_get(scene, seq); if (seq->start < timeline_frame && end_frame > timeline_frame) { - SEQ_retiming_add_handle(seq, timeline_frame); + SEQ_retiming_add_handle(scene, seq, timeline_frame); inserted = true; } diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index c12c3ffe6b0..8175416eda4 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -644,7 +644,7 @@ static SeqRetimingHandle *rna_Sequence_retiming_handles_add(ID *id, { Scene *scene = (Scene *)id; - SeqRetimingHandle *handle = SEQ_retiming_add_handle(seq, timeline_frame); + SeqRetimingHandle *handle = SEQ_retiming_add_handle(scene, seq, timeline_frame); SEQ_relations_invalidate_cache_raw(scene, seq); WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); diff --git a/source/blender/sequencer/SEQ_retiming.h b/source/blender/sequencer/SEQ_retiming.h index 84254fda0ea..f9e28ff3998 100644 --- a/source/blender/sequencer/SEQ_retiming.h +++ b/source/blender/sequencer/SEQ_retiming.h @@ -26,7 +26,9 @@ bool SEQ_retiming_is_allowed(const struct Sequence *seq); * This function always reallocates memory, so when function is used all stored pointers will * become invalid. */ -struct SeqRetimingHandle *SEQ_retiming_add_handle(struct Sequence *seq, const int timeline_frame); +struct SeqRetimingHandle *SEQ_retiming_add_handle(struct Scene *scene, + struct Sequence *seq, + const int timeline_frame); struct SeqRetimingHandle *SEQ_retiming_last_handle_get(const struct Sequence *seq); void SEQ_retiming_remove_handle(struct Sequence *seq, struct SeqRetimingHandle *handle); void SEQ_retiming_offset_handle(const struct Scene *scene, @@ -38,6 +40,9 @@ float SEQ_retiming_handle_speed_get(const struct Scene *scene, const struct SeqRetimingHandle *handle); int SEQ_retiming_handle_index_get(const struct Sequence *seq, const struct SeqRetimingHandle *handle); +float SEQ_retiming_handle_timeline_frame_get(const struct Scene *scene, + const struct Sequence *seq, + const struct SeqRetimingHandle *handle); #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 758b1e45d3f..82b024f0164 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -126,7 +126,7 @@ bool SEQ_retiming_is_allowed(const Sequence *seq) SEQ_TYPE_MASK); } -float seq_retiming_evaluate(const Sequence *seq, const int frame_index) +float seq_retiming_evaluate(const Scene *scene, const Sequence *seq, const int frame_index) { const SeqRetimingHandle *previous_handle = retiming_find_segment_start_handle(seq, frame_index); const SeqRetimingHandle *next_handle = previous_handle + 1; @@ -144,13 +144,15 @@ float seq_retiming_evaluate(const Sequence *seq, const int frame_index) const float segment_fac = segment_frame_index / float(segment_length); const float target_diff = next_handle->retiming_factor - previous_handle->retiming_factor; - return previous_handle->retiming_factor + (target_diff * segment_fac); + return previous_handle->retiming_factor + + (target_diff * segment_fac) * seq_time_media_playback_rate_factor_get(scene, seq); } -SeqRetimingHandle *SEQ_retiming_add_handle(Sequence *seq, const int timeline_frame) +SeqRetimingHandle *SEQ_retiming_add_handle(Scene *scene, Sequence *seq, const int timeline_frame) { - float frame_index = timeline_frame - SEQ_time_start_frame_get(seq); - float value = seq_retiming_evaluate(seq, frame_index); + float frame_index = (timeline_frame - SEQ_time_start_frame_get(seq)) * + seq_time_media_playback_rate_factor_get(scene, seq); + float value = seq_retiming_evaluate(scene, seq, frame_index); const SeqRetimingHandle *closest_handle = retiming_find_segment_start_handle(seq, frame_index); if (closest_handle->strip_frame_index == frame_index) { @@ -195,7 +197,7 @@ void SEQ_retiming_offset_handle(const Scene *scene, MutableSpan handles = SEQ_retiming_handles_get(seq); for (; handle < handles.end(); handle++) { - handle->strip_frame_index += offset; + handle->strip_frame_index += offset * seq_time_media_playback_rate_factor_get(scene, seq); } SEQ_time_update_meta_strip_range(scene, seq_sequence_lookup_meta_by_seq(scene, seq)); @@ -245,3 +247,11 @@ float SEQ_retiming_handle_speed_get(const Scene *scene, const float speed = float(fragment_length_retimed) / float(fragment_length_original); return speed; } + +float SEQ_retiming_handle_timeline_frame_get(const Scene *scene, + const Sequence *seq, + const SeqRetimingHandle *handle) +{ + return SEQ_time_start_frame_get(seq) + + handle->strip_frame_index / seq_time_media_playback_rate_factor_get(scene, seq); +} diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 3bdd5e2b80d..2da4e05f7b8 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -59,7 +59,7 @@ int seq_time_strip_original_content_length_get(const Scene *scene, const Sequenc return seq->len; } - return seq->len / seq_time_media_playback_rate_factor_get(scene, seq); + return seq->len; } float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame) @@ -84,16 +84,19 @@ float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_fra frame_index = timeline_frame - sta; } + frame_index = max_ff(frame_index, 0); + if (SEQ_retiming_is_active(seq)) { - const float retiming_factor = seq_retiming_evaluate(seq, frame_index); + const float retiming_factor = seq_retiming_evaluate(scene, seq, frame_index); frame_index = retiming_factor * (length - 1); } else { frame_index *= seq_time_media_playback_rate_factor_get(scene, seq); - /* Clamp frame index to strip frame range. */ - frame_index = clamp_f(frame_index, 0, end - sta); } + /* Clamp frame index to strip content frame range. */ + frame_index = clamp_f(frame_index, 0, length); + if (seq->strobe < 1.0f) { seq->strobe = 1.0f; } @@ -507,10 +510,12 @@ int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq) if (SEQ_retiming_is_active(seq)) { SeqRetimingHandle *handle_start = seq->retiming_handles; SeqRetimingHandle *handle_end = seq->retiming_handles + (SEQ_retiming_handles_count(seq) - 1); - return handle_end->strip_frame_index - handle_start->strip_frame_index + 1; + return handle_end->strip_frame_index / seq_time_media_playback_rate_factor_get(scene, seq) - + (handle_start->strip_frame_index + 1) / + seq_time_media_playback_rate_factor_get(scene, seq); } - return seq_time_strip_original_content_length_get(scene, seq); + return seq->len / seq_time_media_playback_rate_factor_get(scene, seq); } float SEQ_time_start_frame_get(const Sequence *seq) diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index fbd35dc6adf..2abb65240e4 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -45,7 +45,9 @@ float seq_time_media_playback_rate_factor_get(const struct Scene *scene, const struct Sequence *seq); int seq_time_strip_original_content_length_get(const struct Scene *scene, const struct Sequence *seq); -float seq_retiming_evaluate(const struct Sequence *seq, const int frame_index); +float seq_retiming_evaluate(const struct Scene *scene, + const struct Sequence *seq, + const int frame_index); #ifdef __cplusplus }