From 9d1c03966bca72f33368c69490c8d94563147887 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Sun, 2 Apr 2023 20:09:47 -0700 Subject: [PATCH 01/11] Added functions --- scripts/startup/bl_ui/space_graph.py | 1 + .../editors/animation/keyframes_general.c | 64 +++++++++ .../editors/include/ED_keyframes_edit.h | 1 + .../editors/space_graph/graph_intern.h | 1 + .../blender/editors/space_graph/graph_ops.c | 1 + .../editors/space_graph/graph_slider_ops.c | 124 ++++++++++++++++++ 6 files changed, 192 insertions(+) diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 999a9e3cef7..3b7a93d798f 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -329,6 +329,7 @@ class GRAPH_MT_slider(Menu): layout.operator("graph.breakdown", text="Breakdown") layout.operator("graph.blend_to_neighbor", text="Blend to Neighbor") layout.operator("graph.blend_to_default", text="Blend to Default Value") + layout.operator("graph.blend_ease", text="Blend to Ease") layout.operator("graph.ease", text="Ease") layout.operator("graph.gaussian_smooth", text="Smooth") diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index f1848e4cc42..70d5cdff3d8 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -491,6 +491,70 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor /* ---------------- */ +float s_curve(float x, float slope, float width, float height, float xshift, float yshift) { + /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve vertiacly or horizontaly. + * The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it (width and height) and move it (xshift and y yshift) + * to crop the part of the curve we need. Slope determins how curvy the shape is */ + float curve = height * pow((x - xshift), slope) / (pow((x - xshift), slope) + pow((width - (x - xshift)), slope)) + yshift; + + /* The curve has some noise beyond our margins so we clamp the values */ + if (x > xshift + width) { + curve = height + yshift; + } else if (x < xshift) { + curve = yshift; + } + return curve; +} + +void ease_b_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) +{ + const BezTriple *left_key = fcurve_segment_start_get(fcu, segment->start_index); + const float left_x = left_key->vec[1][0]; + const float left_y = left_key->vec[1][1]; + + const BezTriple *right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); + + const float key_x_range = right_key->vec[1][0] - left_x; + const float key_y_range = right_key->vec[1][1] - left_y; + + /* Happens if there is only 1 key on the FCurve. Needs to be skipped because it + * would be a divide by 0. */ + if (IS_EQF(key_x_range, 0.0f)) { + return; + } + + /* The calculation needs diferent values for each side of the slider. */ + const bool slider_right_side = factor > 0.5; + + /* The factor goes from 0 to 1, but for this tool it needs to go from 0 to 1 on each side of the slider. */ + const float ping_pong_factor = fabs(factor * 2 - 1) * 5; + + /* By duplicating the size of the curve we get only half of the "S" shape (kind of a "C" shape). */ + const float width = 2.0; + const float height = 2.0; + float xshift = 0.0; + float yshift = 0.0; + + for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { + /* For easy calculation of the curve, the values are normalized. */ + const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; + + /* For values on the right side of the slider we need the other half of the "S" shape. */ + if (slider_right_side) { + xshift = -1.0; + yshift = -1.0; + } + + /* The factor is used to affect the slope of the the "C" shape. */ + float ease = s_curve(normalized_x, ping_pong_factor, width, height, xshift, yshift); + + const float key_y_value = left_key->vec[1][1] + key_y_range * ease; + move_key(&fcu->bezt[i], key_y_value); + } +} + +/* ---------------- */ + void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { const BezTriple *left_bezt = fcurve_segment_start_get(fcu, segment->start_index); diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 69f103c6cba..dd631b724e0 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -437,6 +437,7 @@ void smooth_fcurve_segment(struct FCurve *fcu, int kernel_size, double *kernel); void ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); +void blend_ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); bool decimate_fcurve(struct bAnimListElem *ale, float remove_ratio, float error_sq_max); void blend_to_default_fcurve(struct PointerRNA *id_ptr, struct FCurve *fcu, float factor); /** diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 7128f805a23..013620fd854 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -114,6 +114,7 @@ void GRAPH_OT_clean(struct wmOperatorType *ot); void GRAPH_OT_blend_to_neighbor(struct wmOperatorType *ot); void GRAPH_OT_breakdown(struct wmOperatorType *ot); void GRAPH_OT_ease(struct wmOperatorType *ot); +void GRAPH_OT_blend_ease(struct wmOperatorType *ot); void GRAPH_OT_decimate(struct wmOperatorType *ot); void GRAPH_OT_blend_to_default(struct wmOperatorType *ot); void GRAPH_OT_gaussian_smooth(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index b64884da06c..350afb38f5b 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -463,6 +463,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_blend_to_neighbor); WM_operatortype_append(GRAPH_OT_breakdown); WM_operatortype_append(GRAPH_OT_ease); + WM_operatortype_append(GRAPH_OT_blend_ease); WM_operatortype_append(GRAPH_OT_blend_to_default); WM_operatortype_append(GRAPH_OT_gaussian_smooth); WM_operatortype_append(GRAPH_OT_euler_filter); diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index 184bd8329e8..e7347903596 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -1060,6 +1060,130 @@ void GRAPH_OT_ease(wmOperatorType *ot) 1.0f); } +/* -------------------------------------------------------------------- */ +/** \name Blend Ease Operator + * \{ */ + +static void blend_ease_graph_keys(bAnimContext *ac, const float factor) +{ + ListBase anim_data = {NULL, NULL}; + + ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype); + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + FCurve *fcu = (FCurve *)ale->key_data; + ListBase segments = find_fcurve_segments(fcu); + + LISTBASE_FOREACH (FCurveSegment *, segment, &segments) { + blend_ease_fcurve_segment(fcu, segment, factor); + } + + ale->update |= ANIM_UPDATE_DEFAULT; + BLI_freelistN(&segments); + } + + ANIM_animdata_update(ac, &anim_data); + ANIM_animdata_freelist(&anim_data); +} + +static void blend_ease_draw_status_header(bContext *C, tGraphSliderOp *gso) +{ + char status_str[UI_MAX_DRAW_STR]; + char mode_str[32]; + char slider_string[UI_MAX_DRAW_STR]; + + ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR); + + strcpy(mode_str, TIP_("Blend Ease Keys")); + + if (hasNumInput(&gso->num)) { + char str_ofs[NUM_STR_REP_LEN]; + + outputNumInput(&gso->num, str_ofs, &gso->scene->unit); + + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs); + } + else { + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string); + } + + ED_workspace_status_text(C, status_str); +} + +static void blend_ease_modal_update(bContext *C, wmOperator *op) +{ + tGraphSliderOp *gso = op->customdata; + + blend_ease_draw_status_header(C, gso); + + /* Reset keyframes to the state at invoke. */ + reset_bezts(gso); + const float factor = slider_factor_get_and_remember(op); + blend_ease_graph_keys(&gso->ac, factor); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); +} + +static int blend_ease_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + const int invoke_result = graph_slider_invoke(C, op, event); + + if (invoke_result == OPERATOR_CANCELLED) { + return invoke_result; + } + + tGraphSliderOp *gso = op->customdata; + gso->modal_update = blend_ease_modal_update; + gso->factor_prop = RNA_struct_find_property(op->ptr, "factor"); + blend_ease_draw_status_header(C, gso); + + return invoke_result; +} + +static int blend_ease_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + + /* Get editor data. */ + if (ANIM_animdata_get_context(C, &ac) == 0) { + return OPERATOR_CANCELLED; + } + + const float factor = RNA_float_get(op->ptr, "factor"); + + blend_ease_graph_keys(&ac, factor); + + /* Set notifier that keyframes have changed. */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_blend_ease(wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Blend Ease Keyframes"; + ot->idname = "GRAPH_OT_blend_ease"; + ot->description = "Align keyframes on a ease-in or ease-out curve"; + + /* API callbacks. */ + ot->invoke = blend_ease_invoke; + ot->modal = graph_slider_modal; + ot->exec = blend_ease_exec; + ot->poll = graphop_editable_keyframes_poll; + + /* Flags. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float_factor(ot->srna, + "factor", + 0.5f, + -FLT_MAX, + FLT_MAX, + "Curve Bend", + "Control the bend of the curve", + 0.0f, + 1.0f); +} + /** \} */ /* -------------------------------------------------------------------- */ /** \name Gauss Smooth Operator -- 2.30.2 From cb45fcb306c1c1bdbd04e841240a854dd3f72871 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Sun, 2 Apr 2023 20:28:40 -0700 Subject: [PATCH 02/11] change names of the functions to include "to" and fixed one functions that was actually the wrong one --- scripts/startup/bl_ui/space_graph.py | 2 +- .../editors/animation/keyframes_general.c | 33 ++++++++-------- .../editors/include/ED_keyframes_edit.h | 2 +- .../editors/space_graph/graph_intern.h | 2 +- .../blender/editors/space_graph/graph_ops.c | 2 +- .../editors/space_graph/graph_slider_ops.c | 38 +++++++++---------- 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/scripts/startup/bl_ui/space_graph.py b/scripts/startup/bl_ui/space_graph.py index 3b7a93d798f..38ef96fe3ad 100644 --- a/scripts/startup/bl_ui/space_graph.py +++ b/scripts/startup/bl_ui/space_graph.py @@ -329,7 +329,7 @@ class GRAPH_MT_slider(Menu): layout.operator("graph.breakdown", text="Breakdown") layout.operator("graph.blend_to_neighbor", text="Blend to Neighbor") layout.operator("graph.blend_to_default", text="Blend to Default Value") - layout.operator("graph.blend_ease", text="Blend to Ease") + layout.operator("graph.blend_to_ease", text="Blend to Ease") layout.operator("graph.ease", text="Ease") layout.operator("graph.gaussian_smooth", text="Smooth") diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 70d5cdff3d8..fc48807ba1c 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -506,7 +506,7 @@ float s_curve(float x, float slope, float width, float height, float xshift, flo return curve; } -void ease_b_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) +void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { const BezTriple *left_key = fcurve_segment_start_get(fcu, segment->start_index); const float left_x = left_key->vec[1][0]; @@ -515,7 +515,7 @@ void ease_b_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float fact const BezTriple *right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); const float key_x_range = right_key->vec[1][0] - left_x; - const float key_y_range = right_key->vec[1][1] - left_y; + const float key_y_range = right_key->vec[1][1] - left_x; /* Happens if there is only 1 key on the FCurve. Needs to be skipped because it * would be a divide by 0. */ @@ -526,29 +526,30 @@ void ease_b_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float fact /* The calculation needs diferent values for each side of the slider. */ const bool slider_right_side = factor > 0.5; - /* The factor goes from 0 to 1, but for this tool it needs to go from 0 to 1 on each side of the slider. */ - const float ping_pong_factor = fabs(factor * 2 - 1) * 5; + /* The factor goes from 0 to 1, but for this tool it needs to go from -1 to 1. */ + const float long_factor = factor * 2 - 1; + + float y_delta = 0; + float base = 0; - /* By duplicating the size of the curve we get only half of the "S" shape (kind of a "C" shape). */ - const float width = 2.0; - const float height = 2.0; - float xshift = 0.0; - float yshift = 0.0; for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { /* For easy calculation of the curve, the values are normalized. */ const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; - /* For values on the right side of the slider we need the other half of the "S" shape. */ + if (slider_right_side) { - xshift = -1.0; - yshift = -1.0; + float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); + base = left_key->vec[1][1] + key_y_range * ease; + y_delta = base - fcu->bezt[i].vec[1][1]; + } + else { + float ease = s_curve(normalized_x, 3, 2.0, 2.0, 0.0, 0.0); + base = left_key->vec[1][1] + key_y_range * ease; + y_delta = fcu->bezt[i].vec[1][1] - base; } - /* The factor is used to affect the slope of the the "C" shape. */ - float ease = s_curve(normalized_x, ping_pong_factor, width, height, xshift, yshift); - - const float key_y_value = left_key->vec[1][1] + key_y_range * ease; + const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * long_factor; move_key(&fcu->bezt[i], key_y_value); } } diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index dd631b724e0..fc2f249369a 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -437,7 +437,7 @@ void smooth_fcurve_segment(struct FCurve *fcu, int kernel_size, double *kernel); void ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); -void blend_ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); +void blend_to_ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); bool decimate_fcurve(struct bAnimListElem *ale, float remove_ratio, float error_sq_max); void blend_to_default_fcurve(struct PointerRNA *id_ptr, struct FCurve *fcu, float factor); /** diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 013620fd854..0ee281ac403 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -114,7 +114,7 @@ void GRAPH_OT_clean(struct wmOperatorType *ot); void GRAPH_OT_blend_to_neighbor(struct wmOperatorType *ot); void GRAPH_OT_breakdown(struct wmOperatorType *ot); void GRAPH_OT_ease(struct wmOperatorType *ot); -void GRAPH_OT_blend_ease(struct wmOperatorType *ot); +void GRAPH_OT_blend_to_ease(struct wmOperatorType *ot); void GRAPH_OT_decimate(struct wmOperatorType *ot); void GRAPH_OT_blend_to_default(struct wmOperatorType *ot); void GRAPH_OT_gaussian_smooth(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 350afb38f5b..646a432ad2e 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -463,7 +463,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_blend_to_neighbor); WM_operatortype_append(GRAPH_OT_breakdown); WM_operatortype_append(GRAPH_OT_ease); - WM_operatortype_append(GRAPH_OT_blend_ease); + WM_operatortype_append(GRAPH_OT_blend_to_ease); WM_operatortype_append(GRAPH_OT_blend_to_default); WM_operatortype_append(GRAPH_OT_gaussian_smooth); WM_operatortype_append(GRAPH_OT_euler_filter); diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index e7347903596..b78ccdf6e63 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -1061,10 +1061,10 @@ void GRAPH_OT_ease(wmOperatorType *ot) } /* -------------------------------------------------------------------- */ -/** \name Blend Ease Operator +/** \name Blend to Ease Operator * \{ */ -static void blend_ease_graph_keys(bAnimContext *ac, const float factor) +static void blend_to_ease_graph_keys(bAnimContext *ac, const float factor) { ListBase anim_data = {NULL, NULL}; @@ -1074,7 +1074,7 @@ static void blend_ease_graph_keys(bAnimContext *ac, const float factor) ListBase segments = find_fcurve_segments(fcu); LISTBASE_FOREACH (FCurveSegment *, segment, &segments) { - blend_ease_fcurve_segment(fcu, segment, factor); + blend_to_ease_fcurve_segment(fcu, segment, factor); } ale->update |= ANIM_UPDATE_DEFAULT; @@ -1085,7 +1085,7 @@ static void blend_ease_graph_keys(bAnimContext *ac, const float factor) ANIM_animdata_freelist(&anim_data); } -static void blend_ease_draw_status_header(bContext *C, tGraphSliderOp *gso) +static void blend_to_ease_draw_status_header(bContext *C, tGraphSliderOp *gso) { char status_str[UI_MAX_DRAW_STR]; char mode_str[32]; @@ -1093,7 +1093,7 @@ static void blend_ease_draw_status_header(bContext *C, tGraphSliderOp *gso) ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR); - strcpy(mode_str, TIP_("Blend Ease Keys")); + strcpy(mode_str, TIP_("Blend to Ease Keys")); if (hasNumInput(&gso->num)) { char str_ofs[NUM_STR_REP_LEN]; @@ -1109,20 +1109,20 @@ static void blend_ease_draw_status_header(bContext *C, tGraphSliderOp *gso) ED_workspace_status_text(C, status_str); } -static void blend_ease_modal_update(bContext *C, wmOperator *op) +static void blend_to_ease_modal_update(bContext *C, wmOperator *op) { tGraphSliderOp *gso = op->customdata; - blend_ease_draw_status_header(C, gso); + blend_to_ease_draw_status_header(C, gso); /* Reset keyframes to the state at invoke. */ reset_bezts(gso); const float factor = slider_factor_get_and_remember(op); - blend_ease_graph_keys(&gso->ac, factor); + blend_to_ease_graph_keys(&gso->ac, factor); WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } -static int blend_ease_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int blend_to_ease_invoke(bContext *C, wmOperator *op, const wmEvent *event) { const int invoke_result = graph_slider_invoke(C, op, event); @@ -1131,14 +1131,14 @@ static int blend_ease_invoke(bContext *C, wmOperator *op, const wmEvent *event) } tGraphSliderOp *gso = op->customdata; - gso->modal_update = blend_ease_modal_update; + gso->modal_update = blend_to_ease_modal_update; gso->factor_prop = RNA_struct_find_property(op->ptr, "factor"); - blend_ease_draw_status_header(C, gso); + blend_to_ease_draw_status_header(C, gso); return invoke_result; } -static int blend_ease_exec(bContext *C, wmOperator *op) +static int blend_to_ease_exec(bContext *C, wmOperator *op) { bAnimContext ac; @@ -1149,7 +1149,7 @@ static int blend_ease_exec(bContext *C, wmOperator *op) const float factor = RNA_float_get(op->ptr, "factor"); - blend_ease_graph_keys(&ac, factor); + blend_to_ease_graph_keys(&ac, factor); /* Set notifier that keyframes have changed. */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); @@ -1157,17 +1157,17 @@ static int blend_ease_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GRAPH_OT_blend_ease(wmOperatorType *ot) +void GRAPH_OT_blend_to_ease(wmOperatorType *ot) { /* Identifiers. */ - ot->name = "Blend Ease Keyframes"; - ot->idname = "GRAPH_OT_blend_ease"; - ot->description = "Align keyframes on a ease-in or ease-out curve"; + ot->name = "Blend to Ease Keyframes"; + ot->idname = "GRAPH_OT_blend_to_ease"; + ot->description = "Blends keyframes from current state to an ease-in or ease-out curve"; /* API callbacks. */ - ot->invoke = blend_ease_invoke; + ot->invoke = blend_to_ease_invoke; ot->modal = graph_slider_modal; - ot->exec = blend_ease_exec; + ot->exec = blend_to_ease_exec; ot->poll = graphop_editable_keyframes_poll; /* Flags. */ -- 2.30.2 From 6ddc483989e6713a4af0d61bd27b389b86181bfe Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Sun, 2 Apr 2023 22:57:45 -0700 Subject: [PATCH 03/11] changed some variables to constant --- source/blender/editors/animation/keyframes_general.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index fc48807ba1c..78c58e1e961 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -530,8 +530,6 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo const float long_factor = factor * 2 - 1; float y_delta = 0; - float base = 0; - for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { /* For easy calculation of the curve, the values are normalized. */ @@ -540,13 +538,13 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo if (slider_right_side) { float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); - base = left_key->vec[1][1] + key_y_range * ease; - y_delta = base - fcu->bezt[i].vec[1][1]; + const float base = left_key->vec[1][1] + key_y_range * ease; + const float y_delta = base - fcu->bezt[i].vec[1][1]; } else { float ease = s_curve(normalized_x, 3, 2.0, 2.0, 0.0, 0.0); - base = left_key->vec[1][1] + key_y_range * ease; - y_delta = fcu->bezt[i].vec[1][1] - base; + const float base = left_key->vec[1][1] + key_y_range * ease; + const float y_delta = fcu->bezt[i].vec[1][1] - base; } const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * long_factor; -- 2.30.2 From 1ef18cc8c70b7cbdb7d581eb939090e51940a4b2 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Sun, 2 Apr 2023 23:07:09 -0700 Subject: [PATCH 04/11] changed some variables declaration --- source/blender/editors/animation/keyframes_general.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 78c58e1e961..cda560ba43f 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -529,7 +529,7 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo /* The factor goes from 0 to 1, but for this tool it needs to go from -1 to 1. */ const float long_factor = factor * 2 - 1; - float y_delta = 0; + float y_delta; for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { /* For easy calculation of the curve, the values are normalized. */ @@ -537,14 +537,14 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo if (slider_right_side) { - float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); + const float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); const float base = left_key->vec[1][1] + key_y_range * ease; - const float y_delta = base - fcu->bezt[i].vec[1][1]; + y_delta = base - fcu->bezt[i].vec[1][1]; } else { - float ease = s_curve(normalized_x, 3, 2.0, 2.0, 0.0, 0.0); + const float ease = s_curve(normalized_x, 3, 2.0, 2.0, 0.0, 0.0); const float base = left_key->vec[1][1] + key_y_range * ease; - const float y_delta = fcu->bezt[i].vec[1][1] - base; + y_delta = fcu->bezt[i].vec[1][1] - base; } const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * long_factor; -- 2.30.2 From 181c5389ebeb124d05f3d1d2e18999afd3c5ec49 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Mon, 3 Apr 2023 10:57:08 -0700 Subject: [PATCH 05/11] Fixed some formating --- .../editors/animation/keyframes_general.c | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index cda560ba43f..f96c0e5f1c7 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -491,19 +491,24 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor /* ---------------- */ -float s_curve(float x, float slope, float width, float height, float xshift, float yshift) { - /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve vertiacly or horizontaly. - * The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it (width and height) and move it (xshift and y yshift) - * to crop the part of the curve we need. Slope determins how curvy the shape is */ - float curve = height * pow((x - xshift), slope) / (pow((x - xshift), slope) + pow((width - (x - xshift)), slope)) + yshift; +float s_curve(float x, float slope, float width, float height, float xshift, float yshift) +{ + /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve vertiacly + * or horizontaly. The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it + * (width and height) and move it (xshift and y yshift) to crop the part of the curve we need. + * Slope determins how curvy the shape is */ + float curve = height * pow((x - xshift), slope) / + (pow((x - xshift), slope) + pow((width - (x - xshift)), slope)) + + yshift; - /* The curve has some noise beyond our margins so we clamp the values */ - if (x > xshift + width) { - curve = height + yshift; - } else if (x < xshift) { - curve = yshift; - } - return curve; + /* The curve has some noise beyond our margins so we clamp the values */ + if (x > xshift + width) { + curve = height + yshift; + } + else if (x < xshift) { + curve = yshift; + } + return curve; } void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) @@ -527,7 +532,7 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo const bool slider_right_side = factor > 0.5; /* The factor goes from 0 to 1, but for this tool it needs to go from -1 to 1. */ - const float long_factor = factor * 2 - 1; + const float long_factor = factor * 2 - 1; float y_delta; @@ -535,7 +540,6 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo /* For easy calculation of the curve, the values are normalized. */ const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; - if (slider_right_side) { const float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); const float base = left_key->vec[1][1] + key_y_range * ease; -- 2.30.2 From 1e5227c635ab4f595e1d65fce012d63430fc5c51 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Mon, 10 Apr 2023 16:04:42 -0700 Subject: [PATCH 06/11] simplified the function and fixed an error --- source/blender/editors/animation/keyframes_general.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index f96c0e5f1c7..85239a2a8dc 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -491,7 +491,7 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor /* ---------------- */ -float s_curve(float x, float slope, float width, float height, float xshift, float yshift) +static float s_curve(float x, float slope, float width, float height, float xshift, float yshift) { /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve vertiacly * or horizontaly. The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it @@ -514,13 +514,10 @@ float s_curve(float x, float slope, float width, float height, float xshift, flo void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { const BezTriple *left_key = fcurve_segment_start_get(fcu, segment->start_index); - const float left_x = left_key->vec[1][0]; - const float left_y = left_key->vec[1][1]; - const BezTriple *right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); - const float key_x_range = right_key->vec[1][0] - left_x; - const float key_y_range = right_key->vec[1][1] - left_x; + const float key_x_range = right_key->vec[1][0] - left_key->vec[1][0]; + const float key_y_range = right_key->vec[1][1] - left_key->vec[1][1]; /* Happens if there is only 1 key on the FCurve. Needs to be skipped because it * would be a divide by 0. */ -- 2.30.2 From c17a5dda7fb0d676952196b2b466307fac0160eb Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Fri, 14 Apr 2023 11:29:21 -0700 Subject: [PATCH 07/11] addressed Christoph's notes to change variable name and simplify --- .../editors/animation/keyframes_general.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 85239a2a8dc..c1e26640c2e 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -497,18 +497,18 @@ static float s_curve(float x, float slope, float width, float height, float xshi * or horizontaly. The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it * (width and height) and move it (xshift and y yshift) to crop the part of the curve we need. * Slope determins how curvy the shape is */ - float curve = height * pow((x - xshift), slope) / - (pow((x - xshift), slope) + pow((width - (x - xshift)), slope)) + - yshift; + float y = height * pow((x - xshift), slope) / + (pow((x - xshift), slope) + pow((width - (x - xshift)), slope)) + + yshift; /* The curve has some noise beyond our margins so we clamp the values */ if (x > xshift + width) { - curve = height + yshift; + y = height + yshift; } else if (x < xshift) { - curve = yshift; + y = yshift; } - return curve; + return y; } void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) @@ -525,9 +525,6 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo return; } - /* The calculation needs diferent values for each side of the slider. */ - const bool slider_right_side = factor > 0.5; - /* The factor goes from 0 to 1, but for this tool it needs to go from -1 to 1. */ const float long_factor = factor * 2 - 1; @@ -537,7 +534,7 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo /* For easy calculation of the curve, the values are normalized. */ const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; - if (slider_right_side) { + if (factor > 0.5) { const float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); const float base = left_key->vec[1][1] + key_y_range * ease; y_delta = base - fcu->bezt[i].vec[1][1]; -- 2.30.2 From 90fdaf9ad7c8f562e33c7982697b90902ff82308 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Mon, 17 Apr 2023 22:06:14 -0700 Subject: [PATCH 08/11] converted the slider to bidirectional and disabled the offset --- source/blender/editors/animation/keyframes_general.c | 7 ++----- source/blender/editors/space_graph/graph_slider_ops.c | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index c1e26640c2e..a1777d37892 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -525,16 +525,13 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo return; } - /* The factor goes from 0 to 1, but for this tool it needs to go from -1 to 1. */ - const float long_factor = factor * 2 - 1; - float y_delta; for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { /* For easy calculation of the curve, the values are normalized. */ const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; - if (factor > 0.5) { + if (factor > 0) { const float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); const float base = left_key->vec[1][1] + key_y_range * ease; y_delta = base - fcu->bezt[i].vec[1][1]; @@ -545,7 +542,7 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo y_delta = fcu->bezt[i].vec[1][1] - base; } - const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * long_factor; + const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * factor; move_key(&fcu->bezt[i], key_y_value); } } diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index b78ccdf6e63..c379353c879 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -1134,6 +1134,9 @@ static int blend_to_ease_invoke(bContext *C, wmOperator *op, const wmEvent *even gso->modal_update = blend_to_ease_modal_update; gso->factor_prop = RNA_struct_find_property(op->ptr, "factor"); blend_to_ease_draw_status_header(C, gso); + ED_slider_allow_overshoot_set(gso->slider, false); + ED_slider_is_bidirectional_set(gso->slider, true); + ED_slider_factor_set(gso->slider, 0.0f); return invoke_result; } -- 2.30.2 From 5a2d9b9012d50d5bf19e35d90acb62eff9362f63 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Wed, 19 Apr 2023 01:52:19 -0700 Subject: [PATCH 09/11] removed magic numbers and took some lines out of the loop --- .../editors/animation/keyframes_general.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index a1777d37892..02801a44759 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -525,20 +525,29 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo return; } + const float slope = 3.0; + const float width = 2.0; + const float height = 2.0; + float xy_shift; float y_delta; + if (factor > 0) { + xy_shift = -1.0; + } + else { + xy_shift = 0.0; + } + for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { - /* For easy calculation of the curve, the values are normalized. */ - const float normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; + + const float x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; + const float ease = s_curve(x, slope, width, height, xy_shift, xy_shift); + const float base = left_key->vec[1][1] + key_y_range * ease; if (factor > 0) { - const float ease = s_curve(normalized_x, 3, 2.0, 2.0, -1.0, -1.0); - const float base = left_key->vec[1][1] + key_y_range * ease; y_delta = base - fcu->bezt[i].vec[1][1]; } else { - const float ease = s_curve(normalized_x, 3, 2.0, 2.0, 0.0, 0.0); - const float base = left_key->vec[1][1] + key_y_range * ease; y_delta = fcu->bezt[i].vec[1][1] - base; } -- 2.30.2 From f898da502269d686c3a7310aff3804255f5df595 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Wed, 19 Apr 2023 02:05:23 -0700 Subject: [PATCH 10/11] added some comments --- source/blender/editors/animation/keyframes_general.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 02801a44759..ee602d92d6a 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -493,7 +493,7 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor static float s_curve(float x, float slope, float width, float height, float xshift, float yshift) { - /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve vertiacly + /* Formula for 'S' curve we use for the "ease" sliders. The shift values move the curve verticaly * or horizontaly. The range of the curve used is from 0 to 1 on "x" and "y" so we can scale it * (width and height) and move it (xshift and y yshift) to crop the part of the curve we need. * Slope determins how curvy the shape is */ @@ -526,11 +526,13 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo } const float slope = 3.0; + /* By doubling the size of the "S" curve we just one side of it, a "C" shape. */ const float width = 2.0; const float height = 2.0; float xy_shift; float y_delta; + /* Shifting the x and y values we can decide what side of the "S" shape to use. */ if (factor > 0) { xy_shift = -1.0; } @@ -539,7 +541,7 @@ void blend_to_ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const flo } for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { - + const float x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range; const float ease = s_curve(x, slope, width, height, xy_shift, xy_shift); const float base = left_key->vec[1][1] + key_y_range * ease; -- 2.30.2 From 27ae422111c15e08ce0ca1dc6eeee793b5a485a6 Mon Sep 17 00:00:00 2001 From: Ares Deveaux Date: Thu, 20 Apr 2023 12:45:13 -0700 Subject: [PATCH 11/11] corrected a small error in the operator --- source/blender/editors/space_graph/graph_slider_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index c379353c879..181c9b90d9c 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -1178,12 +1178,12 @@ void GRAPH_OT_blend_to_ease(wmOperatorType *ot) RNA_def_float_factor(ot->srna, "factor", - 0.5f, + 0.0f, -FLT_MAX, FLT_MAX, "Curve Bend", "Control the bend of the curve", - 0.0f, + -1.0f, 1.0f); } -- 2.30.2