Fix: Improve retiming speed get/set code precision
Use float for intermediate values when calculating speed or timeline frames. More details on precision improvement itself: In some cases, setting strip speed to say 70% would result in actual speed being set to say 69.5%. With this change, the number would be closer or equal to 70%. There few tangentially related changes: - `SEQ_retiming_key_speed_get` was changed so both functions work in same time domain. - `SEQ_retiming_key_speed_set` now expects speed as float factor instead of percentage. This is consistent with get function return value. - Improve variable names, for better code readability. Pull Request: https://projects.blender.org/blender/blender/pulls/131782
This commit is contained in:
committed by
Richard Antalik
parent
f9c4ad1477
commit
b2660dbd2b
@@ -654,7 +654,7 @@ static int strip_speed_set_exec(bContext *C, const wmOperator *op)
|
||||
continue;
|
||||
}
|
||||
/* TODO: it would be nice to multiply speed with complex retiming by a factor. */
|
||||
SEQ_retiming_key_speed_set(scene, strip, key, RNA_float_get(op->ptr, "speed"), false);
|
||||
SEQ_retiming_key_speed_set(scene, strip, key, RNA_float_get(op->ptr, "speed") / 100.0f, false);
|
||||
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
if (SEQ_transform_test_overlap(scene, seqbase, strip)) {
|
||||
@@ -679,7 +679,7 @@ static int segment_speed_set_exec(const bContext *C,
|
||||
SEQ_retiming_key_speed_set(scene,
|
||||
item.value,
|
||||
item.key,
|
||||
RNA_float_get(op->ptr, "speed"),
|
||||
RNA_float_get(op->ptr, "speed") / 100.0f,
|
||||
RNA_boolean_get(op->ptr, "keep_retiming"));
|
||||
|
||||
if (SEQ_transform_test_overlap(scene, seqbase, item.value)) {
|
||||
|
||||
@@ -781,17 +781,12 @@ float SEQ_retiming_key_speed_get(const Strip *strip, const SeqRetimingKey *key)
|
||||
}
|
||||
|
||||
const SeqRetimingKey *key_prev = key - 1;
|
||||
|
||||
const int frame_index_max = strip->len - 1;
|
||||
const int frame_retimed_prev = round_fl_to_int(key_prev->retiming_factor * frame_index_max);
|
||||
const int frame_index_prev = key_prev->strip_frame_index;
|
||||
const int frame_retimed = round_fl_to_int(key->retiming_factor * frame_index_max);
|
||||
const int frame_index = key->strip_frame_index;
|
||||
|
||||
const int fragment_length_retimed = frame_retimed - frame_retimed_prev;
|
||||
const int fragment_length_original = frame_index - frame_index_prev;
|
||||
|
||||
const float speed = float(fragment_length_retimed) / float(fragment_length_original);
|
||||
const float frame_index_start = round_fl_to_int(key_prev->retiming_factor * frame_index_max);
|
||||
const float frame_index_end = round_fl_to_int(key->retiming_factor * frame_index_max);
|
||||
const float segment_content_frame_count = frame_index_end - frame_index_start;
|
||||
const float segment_length = key->strip_frame_index - key_prev->strip_frame_index;
|
||||
const float speed = segment_content_frame_count / segment_length;
|
||||
return speed;
|
||||
}
|
||||
|
||||
@@ -803,19 +798,18 @@ void SEQ_retiming_key_speed_set(
|
||||
}
|
||||
|
||||
const SeqRetimingKey *key_prev = key - 1;
|
||||
const float speed_fac = 100.0f / speed;
|
||||
|
||||
const int frame_index_max = strip->len - 1;
|
||||
const int frame_retimed_prev = round_fl_to_int(key_prev->retiming_factor * frame_index_max);
|
||||
const int frame_retimed = round_fl_to_int(key->retiming_factor * frame_index_max);
|
||||
const float frame_index_prev = round_fl_to_int(key_prev->retiming_factor * frame_index_max);
|
||||
const float frame_index = round_fl_to_int(key->retiming_factor * frame_index_max);
|
||||
|
||||
const int segment_duration = (frame_retimed - frame_retimed_prev) /
|
||||
SEQ_time_media_playback_rate_factor_get(scene, strip);
|
||||
const int new_duration = segment_duration * speed_fac;
|
||||
const float segment_timeline_duration = (frame_index - frame_index_prev) /
|
||||
SEQ_time_media_playback_rate_factor_get(scene, strip);
|
||||
const float new_timeline_duration = segment_timeline_duration / speed;
|
||||
|
||||
const int orig_timeline_frame = SEQ_retiming_key_timeline_frame_get(scene, strip, key);
|
||||
const int new_timeline_frame = SEQ_retiming_key_timeline_frame_get(scene, strip, key_prev) +
|
||||
new_duration;
|
||||
const float orig_timeline_frame = SEQ_retiming_key_timeline_frame_get(scene, strip, key);
|
||||
const float new_timeline_frame = std::round(
|
||||
SEQ_retiming_key_timeline_frame_get(scene, strip, key_prev) + new_timeline_duration);
|
||||
|
||||
SEQ_retiming_key_timeline_frame_set(scene, strip, key, new_timeline_frame);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user