From 2e246e355ecbd4f008e2e939889d1b7ec4e5be85 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 13 Jul 2023 15:37:46 +0200 Subject: [PATCH] Fix #109799: Smooth (Gaussian) introduces stepping When keys were not perfectly on the frame, the index logic would fail and duplicate data across 2 frames. Using `round()` solves this. It does not add subframe support though. Pull Request: https://projects.blender.org/blender/blender/pulls/110059 --- source/blender/editors/animation/keyframes_general.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.cc b/source/blender/editors/animation/keyframes_general.cc index dc5ec85806a..6110fc8963d 100644 --- a/source/blender/editors/animation/keyframes_general.cc +++ b/source/blender/editors/animation/keyframes_general.cc @@ -614,9 +614,11 @@ void smooth_fcurve_segment(FCurve *fcu, double *kernel) { const int segment_end_index = segment->start_index + segment->length; - const int segment_start_x = fcu->bezt[segment->start_index].vec[1][0]; + const float segment_start_x = fcu->bezt[segment->start_index].vec[1][0]; for (int i = segment->start_index; i < segment_end_index; i++) { - const int sample_index = (int)(fcu->bezt[i].vec[1][0] - segment_start_x) + kernel_size; + /* Using round() instead of (int). The latter would create stepping on x-values that are just + * below a full frame. */ + const int sample_index = round(fcu->bezt[i].vec[1][0] - segment_start_x) + kernel_size; /* Apply the kernel. */ double filter_result = samples[sample_index] * kernel[0]; for (int j = 1; j <= kernel_size; j++) {