diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index 02f8139a69..05e6921e0a 100644 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -2,7 +2,7 @@ #![warn(missing_docs)] -use std::ops::Deref; +use std::ops::{Add, Deref, Mul}; use std::time::Duration; use bevy_app::{App, Plugin, PostUpdate}; @@ -672,16 +672,22 @@ fn get_keyframe(target_count: usize, keyframes: &[f32], key_index: usize) -> &[f &keyframes[start..end] } -// Helper macro for cubic spline interpolation -// it needs to work on `f32`, `Vec3` and `Quat` -// TODO: replace by a function if the proper trait bounds can be figured out -macro_rules! cubic_spline_interpolation { - ($value_start: expr, $tangent_out_start: expr, $tangent_in_end: expr, $value_end: expr, $lerp: expr, $step_duration: expr,) => { - $value_start * (2.0 * $lerp.powi(3) - 3.0 * $lerp.powi(2) + 1.0) - + $tangent_out_start * ($step_duration) * ($lerp.powi(3) - 2.0 * $lerp.powi(2) + $lerp) - + $value_end * (-2.0 * $lerp.powi(3) + 3.0 * $lerp.powi(2)) - + $tangent_in_end * ($step_duration) * ($lerp.powi(3) - $lerp.powi(2)) - }; +/// Helper function for cubic spline interpolation. +fn cubic_spline_interpolation( + value_start: T, + tangent_out_start: T, + tangent_in_end: T, + value_end: T, + lerp: f32, + step_duration: f32, +) -> T +where + T: Mul + Add, +{ + value_start * (2.0 * lerp.powi(3) - 3.0 * lerp.powi(2) + 1.0) + + tangent_out_start * (step_duration) * (lerp.powi(3) - 2.0 * lerp.powi(2) + lerp) + + value_end * (-2.0 * lerp.powi(3) + 3.0 * lerp.powi(2)) + + tangent_in_end * step_duration * (lerp.powi(3) - lerp.powi(2)) } #[allow(clippy::too_many_arguments)] @@ -828,7 +834,7 @@ fn apply_keyframe( let tangent_out_start = keyframes[step_start * 3 + 2]; let tangent_in_end = keyframes[(step_start + 1) * 3]; let value_end = keyframes[(step_start + 1) * 3 + 1]; - let result = cubic_spline_interpolation!( + let result = cubic_spline_interpolation( value_start, tangent_out_start, tangent_in_end, @@ -852,7 +858,7 @@ fn apply_keyframe( let tangent_out_start = keyframes[step_start * 3 + 2]; let tangent_in_end = keyframes[(step_start + 1) * 3]; let value_end = keyframes[(step_start + 1) * 3 + 1]; - let result = cubic_spline_interpolation!( + let result = cubic_spline_interpolation( value_start, tangent_out_start, tangent_in_end, @@ -876,7 +882,7 @@ fn apply_keyframe( let tangent_out_start = keyframes[step_start * 3 + 2]; let tangent_in_end = keyframes[(step_start + 1) * 3]; let value_end = keyframes[(step_start + 1) * 3 + 1]; - let result = cubic_spline_interpolation!( + let result = cubic_spline_interpolation( value_start, tangent_out_start, tangent_in_end, @@ -918,8 +924,8 @@ fn apply_keyframe( .zip(tangents_in_end) .zip(morph_end) .map( - |(((value_start, tangent_out_start), tangent_in_end), value_end)| { - cubic_spline_interpolation!( + |(((&value_start, &tangent_out_start), &tangent_in_end), &value_end)| { + cubic_spline_interpolation( value_start, tangent_out_start, tangent_in_end,