diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-11-23 14:48:04 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-11-23 14:48:04 +0300 |
commit | e4ca1fc4ea43f795441a319ea96b63a58553f070 (patch) | |
tree | 2dcb89adb56958fc26d41ceac51af6dc9dd72814 /source/blender/blenkernel | |
parent | 1318eaf166947e080c05ed689dbc295817496f1a (diff) |
Animation: New Euler filter implementation
This new discontinuity filter performs actions on the entire Euler
rotation, rather than only on the individual X/Y/Z channels. This makes
it fix a wider range of discontinuities, for example those in T52744.
The filter now runs twice on the selected channels, in this order:
- New: Convert X+Y+Z rotation to matrix, then back to Euler angles.
- Old: Add/remove factors of 360° to minimize jumps.
The messaging is streamlined; it now reports how many channels were
filtered, and only warns (instead of errors) when there was an actual
problem with the selected channels (like selecting three or more
channels, but without X/Y/Z triplet).
A new kernel function `BKE_fcurve_keyframe_move_value_with_handles()` is
introduced, to make it possible to move a keyframe's value and move its
handles at the same time.
Manifest Task: T52744
Reviewed By: looch
Differential Revision: https://developer.blender.org/D9602
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_fcurve.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve_test.cc | 31 |
3 files changed, 43 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index f527f40d0d7..4569e68ea4a 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -248,6 +248,10 @@ bool BKE_fcurve_calc_bounds(struct FCurve *fcu, void BKE_fcurve_active_keyframe_set(struct FCurve *fcu, const struct BezTriple *active_bezt); int BKE_fcurve_active_keyframe_index(const struct FCurve *fcu); +/* Move the indexed keyframe to the given value, and move the handles with it to ensure the slope + * remains the same. */ +void BKE_fcurve_keyframe_move_value_with_handles(struct BezTriple *keyframe, float new_value); + /* .............. */ /* Are keyframes on F-Curve of any use (to final result, and to show in editors)? */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index e6d3696b198..bcd2fe098b7 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -884,6 +884,14 @@ int BKE_fcurve_active_keyframe_index(const FCurve *fcu) /** \} */ +void BKE_fcurve_keyframe_move_value_with_handles(struct BezTriple *keyframe, const float new_value) +{ + const float value_delta = new_value - keyframe->vec[1][1]; + keyframe->vec[0][1] += value_delta; + keyframe->vec[1][1] = new_value; + keyframe->vec[2][1] += value_delta; +} + /* -------------------------------------------------------------------- */ /** \name Status Checks * \{ */ diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc index fb6ce02d146..7d6b5fd88be 100644 --- a/source/blender/blenkernel/intern/fcurve_test.cc +++ b/source/blender/blenkernel/intern/fcurve_test.cc @@ -331,4 +331,35 @@ TEST(fcurve_active_keyframe, ActiveKeyframe) BKE_fcurve_free(fcu); } +TEST(BKE_fcurve, BKE_fcurve_keyframe_move_value_with_handles) +{ + FCurve *fcu = BKE_fcurve_create(); + + insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF); + insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF); + insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF); + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][0], 5.2671194f); + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][1], 15.0f); + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[1][0], 8.0f); + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[1][1], 15.0f); + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[2][0], 10.342469f); + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[2][1], 15.0f); + + BKE_fcurve_keyframe_move_value_with_handles(&fcu->bezt[1], 47.0f); + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][0], 5.2671194f) << "Left handle should not move in time"; + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][1], 47.0f) << "Left handle value should have been updated"; + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[1][0], 8.0f) << "Frame should not move in time"; + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[1][1], 47.0f) << "Frame value should have been updated"; + + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[2][0], 10.342469f) << "Right handle should not move in time"; + EXPECT_FLOAT_EQ(fcu->bezt[1].vec[2][1], 47.0f) << "Right handle value should have been updated"; + + BKE_fcurve_free(fcu); +} + } // namespace blender::bke::tests |