VSE: Speed Effect layout updates

**Changes:**
- New enums correspond to 4 modes: `Stretch`, `Multiply`, `Frame Number` and `Length`.
- "`Multiply Factor`" has been removed;
- Value corresponding to "`use as speed`" enabled is now the value appended to the `Multiply` enum;
- Value corresponding to "`use as speed`" disabled is now the value appended to the `Frame Number` enum;
- Value corresponding to "`Scale to Length`" enabled is now the value appended to the `Length` enum;
- Except `Stretch` each mode has now its respective control values.

Differential Revision: https://developer.blender.org/D11856
This commit is contained in:
Germano Cavalcante 2021-07-01 15:03:14 -03:00 committed by Germano Cavalcante
parent e77a1dc6b0
commit f013e3de81
6 changed files with 185 additions and 87 deletions

View File

@ -1156,14 +1156,19 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
flow.prop(strip, "use_only_boost")
elif strip_type == 'SPEED':
layout.prop(strip, "use_default_fade", text="Stretch to Input Strip Length")
if not strip.use_default_fade:
layout.prop(strip, "use_as_speed")
if strip.use_as_speed:
layout.prop(strip, "speed_factor")
else:
layout.prop(strip, "speed_factor", text="Frame Number")
layout.prop(strip, "use_scale_to_length")
col = layout.column(align=True)
col.prop(strip, "speed_control", text="Speed Control")
if strip.speed_control == "MULTIPLY":
col.prop(strip, "speed_factor", text=" ")
elif strip.speed_control == "LENGTH":
col.prop(strip, "speed_length", text=" ")
elif strip.speed_control == "FRAME_NUMBER":
col.prop(strip, "speed_frame_number", text=" ")
row = layout.row(align=True)
row.enabled = strip.speed_control != "STRETCH"
row = layout.row(align=True, heading="Interpolation")
row.prop(strip, "use_frame_interpolate", text="")
elif strip_type == 'TRANSFORM':
col = layout.column()
@ -1233,11 +1238,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
layout.prop(strip, "wrap_width", text="Wrap Width")
col = layout.column(align=True)
if strip_type == 'SPEED':
col.prop(strip, "multiply_speed")
col.prop(strip, "use_frame_interpolate")
elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
if strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
col.prop(strip, "use_default_fade", text="Default Fade")
if not strip.use_default_fade:
col.prop(strip, "effect_fader", text="Effect Fader")

View File

@ -29,6 +29,7 @@
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
#include "DNA_collection_types.h"
#include "DNA_curve_types.h"
#include "DNA_genfile.h"
#include "DNA_listBase.h"
#include "DNA_material_types.h"
@ -41,6 +42,7 @@
#include "BKE_asset.h"
#include "BKE_collection.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -49,11 +51,10 @@
#include "BLO_readfile.h"
#include "MEM_guardedalloc.h"
#include "readfile.h"
#include "versioning_common.h"
#include "SEQ_sequencer.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "versioning_common.h"
@ -113,6 +114,74 @@ static void move_vertex_group_names_to_object_data(Main *bmain)
}
}
static void do_versions_sequencer_speed_effect_recursive(Scene *scene, const ListBase *seqbase)
{
/* Old SpeedControlVars->flags. */
#define SEQ_SPEED_INTEGRATE (1 << 0)
#define SEQ_SPEED_COMPRESS_IPO_Y (1 << 2)
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
if (seq->type == SEQ_TYPE_SPEED) {
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
const char *substr = NULL;
float globalSpeed = v->globalSpeed;
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
if (globalSpeed == 1.0f) {
v->speed_control_type = SEQ_SPEED_STRETCH;
}
else {
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = globalSpeed *
((float)seq->seq1->len /
max_ff((float)(seq->seq1->enddisp - seq->seq1->start), 1.0f));
}
}
else if (v->flags & SEQ_SPEED_INTEGRATE) {
v->speed_control_type = SEQ_SPEED_MULTIPLY;
v->speed_fader = seq->speed_fader * globalSpeed;
}
else if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
globalSpeed *= 100.0f;
v->speed_control_type = SEQ_SPEED_LENGTH;
v->speed_fader_length = seq->speed_fader * globalSpeed;
substr = "speed_length";
}
else {
v->speed_control_type = SEQ_SPEED_FRAME_NUMBER;
v->speed_fader_frame_number = (int)(seq->speed_fader * globalSpeed);
substr = "speed_frame_number";
}
v->flags &= ~(SEQ_SPEED_INTEGRATE | SEQ_SPEED_COMPRESS_IPO_Y);
if (substr || globalSpeed != 1.0f) {
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
if (fcu) {
if (globalSpeed != 1.0f) {
for (int i = 0; i < fcu->totvert; i++) {
BezTriple *bezt = &fcu->bezt[i];
bezt->vec[0][1] *= globalSpeed;
bezt->vec[1][1] *= globalSpeed;
bezt->vec[2][1] *= globalSpeed;
}
}
if (substr) {
char *new_path = BLI_str_replaceN(fcu->rna_path, "speed_factor", substr);
MEM_freeN(fcu->rna_path);
fcu->rna_path = new_path;
}
}
}
}
else if (seq->type == SEQ_TYPE_META) {
do_versions_sequencer_speed_effect_recursive(scene, &seq->seqbase);
}
}
#undef SEQ_SPEED_INTEGRATE
#undef SEQ_SPEED_COMPRESS_IPO_Y
}
void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
@ -161,6 +230,14 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
move_vertex_group_names_to_object_data(bmain);
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 13)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
do_versions_sequencer_speed_effect_recursive(scene, &scene->ed->seqbase);
}
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -201,6 +201,7 @@ typedef struct Sequence {
ListBase anims;
float effect_fader;
/* DEPRECATED, only used for versioning. */
float speed_fader;
/* pointers for effects: */
@ -335,12 +336,28 @@ typedef struct SolidColorVars {
typedef struct SpeedControlVars {
float *frameMap;
/* DEPRECATED, only used for versioning. */
float globalSpeed;
/* DEPRECATED, only used for versioning. */
int flags;
int length;
int lastValidFrame;
int speed_control_type;
float speed_fader;
float speed_fader_length;
float speed_fader_frame_number;
} SpeedControlVars;
/* SpeedControlVars.speed_control_type */
enum {
SEQ_SPEED_STRETCH = 0,
SEQ_SPEED_MULTIPLY = 1,
SEQ_SPEED_LENGTH = 2,
SEQ_SPEED_FRAME_NUMBER = 3,
};
typedef struct GaussianBlurVars {
float size_x;
float size_y;
@ -485,9 +502,9 @@ typedef struct SequencerScopes {
#define SEQ_EDIT_PROXY_DIR_STORAGE 1
/* SpeedControlVars->flags */
#define SEQ_SPEED_INTEGRATE (1 << 0)
#define SEQ_SPEED_UNUSED_2 (1 << 0) /* cleared */
#define SEQ_SPEED_UNUSED_1 (1 << 1) /* cleared */
#define SEQ_SPEED_COMPRESS_IPO_Y (1 << 2)
#define SEQ_SPEED_UNUSED_3 (1 << 2) /* cleared */
#define SEQ_SPEED_USE_INTERPOLATION (1 << 3)
/* ***************** SEQUENCE ****************** */

View File

@ -1921,16 +1921,6 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_update(
prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
prop = RNA_def_property(srna, "speed_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_fader");
RNA_def_property_ui_text(
prop,
"Speed Factor",
"Multiply the current speed of the sequence with this number or remap current frame "
"to this frame");
RNA_def_property_update(
prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_preprocessed_update");
/* modifiers */
prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "SequenceModifier");
@ -2787,24 +2777,48 @@ static void rna_def_speed_control(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "SpeedControlVars", "effectdata");
prop = RNA_def_property(srna, "multiply_speed", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "globalSpeed");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* seq->facf0 is used to animate this */
RNA_def_property_ui_text(
prop, "Multiply Speed", "Multiply the resulting speed after the speed factor");
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, -1);
static const EnumPropertyItem speed_control_items[] = {
{SEQ_SPEED_STRETCH,
"STRETCH",
0,
"Stretch",
"Adjust input playback speed, so its duration fits strip length"},
{SEQ_SPEED_MULTIPLY, "MULTIPLY", 0, "Multiply", "Multiply with the speed factor"},
{SEQ_SPEED_FRAME_NUMBER,
"FRAME_NUMBER",
0,
"Frame Number",
"Frame number of the input strip"},
{SEQ_SPEED_LENGTH, "LENGTH", 0, "Length", "Percentage of the input strip length"},
{0, NULL, 0, NULL, NULL},
};
prop = RNA_def_property(srna, "speed_control", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "speed_control_type");
RNA_def_property_enum_items(prop, speed_control_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Speed Control", "Speed control method");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "use_as_speed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_INTEGRATE);
prop = RNA_def_property(srna, "speed_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_fader");
RNA_def_property_ui_text(
prop, "Use as Speed", "Interpret the value as speed instead of a frame number");
prop,
"Multiply Factor",
"Multiply the current speed of the sequence with this number or remap current frame "
"to this frame");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "use_scale_to_length", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_COMPRESS_IPO_Y);
RNA_def_property_ui_text(
prop, "Scale to Length", "Scale values from 0.0 to 1.0 to target sequence length");
prop = RNA_def_property(srna, "speed_frame_number", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "speed_fader_frame_number");
RNA_def_property_ui_text(prop, "Frame Number", "Frame number of input strip");
RNA_def_property_ui_range(prop, 0.0, MAXFRAME, 1.0, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "speed_length", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_sdna(prop, NULL, "speed_fader_length");
RNA_def_property_ui_text(prop, "Length", "Percentage of input strip length");
RNA_def_property_ui_range(prop, 0.0, 100.0, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "use_frame_interpolate", PROP_BOOLEAN, PROP_NONE);

View File

@ -70,9 +70,6 @@ struct SeqEffectHandle {
* 2: out = ibuf2 */
int (*early_out)(struct Sequence *seq, float facf0, float facf1);
/* stores the y-range of the effect IPO */
void (*store_icu_yrange)(struct Sequence *seq, short adrcode, float *ymin, float *ymax);
/* stores the default facf0 and facf1 if no IPO is present */
void (*get_default_fac)(struct Sequence *seq, float timeline_frame, float *facf0, float *facf1);

View File

@ -3086,10 +3086,12 @@ static void init_speed_effect(Sequence *seq)
seq->effectdata = MEM_callocN(sizeof(SpeedControlVars), "speedcontrolvars");
v = (SpeedControlVars *)seq->effectdata;
v->globalSpeed = 1.0;
v->frameMap = NULL;
v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
v->length = 0;
v->speed_control_type = SEQ_SPEED_STRETCH;
v->speed_fader = 1.0f;
v->speed_fader_length = 0.0f;
v->speed_fader_frame_number = 0.0f;
}
static void load_speed_effect(Sequence *seq)
@ -3131,29 +3133,6 @@ static int early_out_speed(Sequence *UNUSED(seq), float UNUSED(facf0), float UNU
return EARLY_DO_EFFECT;
}
static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float *ymin, float *ymax)
{
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
/* if not already done, load / initialize data */
SEQ_effect_handle_get(seq);
if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
*ymin = -100.0;
*ymax = 100.0;
}
else {
if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
*ymin = 0.0;
*ymax = 1.0;
}
else {
*ymin = 0.0;
*ymax = seq->len;
}
}
}
/**
* Generator strips with zero inputs have their length set to 1 permanently. In some cases it is
* useful to use speed effect on these strips because they can be animated. This can be done by
@ -3174,7 +3153,6 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
float fallback_fac = 1.0f;
SpeedControlVars *v = (SpeedControlVars *)seq->effectdata;
FCurve *fcu = NULL;
int flags = v->flags;
/* if not already done, load / initialize data */
SEQ_effect_handle_get(seq);
@ -3189,7 +3167,20 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
/* XXX(campbell): new in 2.5x. should we use the animation system this way?
* The fcurve is needed because many frames need evaluating at once. */
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
switch (v->speed_control_type) {
case SEQ_SPEED_MULTIPLY: {
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
break;
}
case SEQ_SPEED_FRAME_NUMBER: {
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_frame_number", 0, NULL);
break;
}
case SEQ_SPEED_LENGTH: {
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_length", 0, NULL);
break;
}
}
if (!v->frameMap || v->length != seq->len) {
if (v->frameMap) {
MEM_freeN(v->frameMap);
@ -3204,21 +3195,33 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
const int target_strip_length = seq_effect_speed_get_strip_content_length(seq->seq1);
if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) {
if (v->speed_control_type == SEQ_SPEED_STRETCH) {
if ((seq->seq1->enddisp != seq->seq1->start) && (target_strip_length != 0)) {
fallback_fac = (float)target_strip_length / (float)(seq->seq1->enddisp - seq->seq1->start);
flags = SEQ_SPEED_INTEGRATE;
fcu = NULL;
}
}
else {
/* if there is no fcurve, use value as simple multiplier */
if (!fcu) {
fallback_fac = seq->speed_fader; /* Same as speed_factor in RNA. */
switch (v->speed_control_type) {
case SEQ_SPEED_MULTIPLY: {
fallback_fac = v->speed_fader;
break;
}
case SEQ_SPEED_FRAME_NUMBER: {
fallback_fac = v->speed_fader_frame_number;
break;
}
case SEQ_SPEED_LENGTH: {
fallback_fac = v->speed_fader_length;
break;
}
}
}
}
if (flags & SEQ_SPEED_INTEGRATE) {
if (ELEM(v->speed_control_type, SEQ_SPEED_MULTIPLY, SEQ_SPEED_STRETCH)) {
float cursor = 0;
float facf;
@ -3232,7 +3235,6 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
else {
facf = fallback_fac;
}
facf *= v->globalSpeed;
cursor += facf;
@ -3258,10 +3260,10 @@ void seq_effect_speed_rebuild_map(Scene *scene, Sequence *seq, bool force)
facf = fallback_fac;
}
if (flags & SEQ_SPEED_COMPRESS_IPO_Y) {
if (v->speed_control_type == SEQ_SPEED_LENGTH) {
facf *= target_strip_length;
facf /= 100.0f;
}
facf *= v->globalSpeed;
if (facf >= target_strip_length) {
facf = target_strip_length - 1;
@ -4083,14 +4085,6 @@ static int early_out_mul_input2(Sequence *UNUSED(seq), float facf0, float facf1)
return EARLY_DO_EFFECT;
}
static void store_icu_yrange_noop(Sequence *UNUSED(seq),
short UNUSED(adrcode),
float *UNUSED(ymin),
float *UNUSED(ymax))
{
/* defaults are fine */
}
static void get_default_fac_noop(Sequence *UNUSED(seq),
float UNUSED(timeline_frame),
float *facf0,
@ -4130,7 +4124,6 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.free = free_noop;
rval.early_out = early_out_noop;
rval.get_default_fac = get_default_fac_noop;
rval.store_icu_yrange = store_icu_yrange_noop;
rval.execute = NULL;
rval.init_execution = init_execution;
rval.execute_slice = NULL;
@ -4244,7 +4237,6 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.copy = copy_speed_effect;
rval.execute = do_speed_effect;
rval.early_out = early_out_speed;
rval.store_icu_yrange = store_icu_yrange_speed;
break;
case SEQ_TYPE_COLOR:
rval.init = init_solid_color;