diff --git a/crates/bevy_math/Cargo.toml b/crates/bevy_math/Cargo.toml index 7ceecc10652dd..8662b029b2c7b 100644 --- a/crates/bevy_math/Cargo.toml +++ b/crates/bevy_math/Cargo.toml @@ -21,7 +21,6 @@ rand = { version = "0.8", features = [ ], default-features = false, optional = true } rand_distr = { version = "0.4.3", optional = true } smallvec = { version = "1.11" } -interpolation = "0.3" bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [ "glam", diff --git a/crates/bevy_math/src/curve/easing.rs b/crates/bevy_math/src/curve/easing.rs index 47e57c9ea9f8f..689ffb24f5730 100644 --- a/crates/bevy_math/src/curve/easing.rs +++ b/crates/bevy_math/src/curve/easing.rs @@ -4,7 +4,6 @@ //! [easing functions]: EaseFunction use crate::{Dir2, Dir3, Dir3A, Quat, Rot2, VectorSpace}; -use interpolation::Ease as IEase; use super::{function_curve, Curve, Interval}; @@ -219,6 +218,79 @@ mod easing_functions { t } + #[inline] + pub(crate) fn quadratic_in(t: f32) -> f32 { + t.squared() + } + #[inline] + pub(crate) fn quadratic_out(t: f32) -> f32 { + 1.0 - (1.0 - t).squared() + } + #[inline] + pub(crate) fn quadratic_in_out(t: f32) -> f32 { + if t < 0.5 { + 2.0 * t.squared() + } else { + 1.0 - (-2.0 * t + 2.0).squared() / 2.0 + } + } + + #[inline] + pub(crate) fn cubic_in(t: f32) -> f32 { + t.cubed() + } + #[inline] + pub(crate) fn cubic_out(t: f32) -> f32 { + 1.0 - (1.0 - t).cubed() + } + #[inline] + pub(crate) fn cubic_in_out(t: f32) -> f32 { + if t < 0.5 { + 4.0 * t.cubed() + } else { + 1.0 - (-2.0 * t + 2.0).cubed() / 2.0 + } + } + + #[inline] + pub(crate) fn quartic_in(t: f32) -> f32 { + t * t * t * t + } + #[inline] + pub(crate) fn quartic_out(t: f32) -> f32 { + 1.0 - (1.0 - t) * (1.0 - t) * (1.0 - t) * (1.0 - t) + } + #[inline] + pub(crate) fn quartic_in_out(t: f32) -> f32 { + if t < 0.5 { + 8.0 * t * t * t * t + } else { + 1.0 - (-2.0 * t + 2.0) * (-2.0 * t + 2.0) * (-2.0 * t + 2.0) * (-2.0 * t + 2.0) / 2.0 + } + } + + #[inline] + pub(crate) fn quintic_in(t: f32) -> f32 { + t * t * t * t * t + } + #[inline] + pub(crate) fn quintic_out(t: f32) -> f32 { + 1.0 - (1.0 - t) * (1.0 - t) * (1.0 - t) * (1.0 - t) * (1.0 - t) + } + #[inline] + pub(crate) fn quintic_in_out(t: f32) -> f32 { + if t < 0.5 { + 16.0 * t * t * t * t * t + } else { + 1.0 - (-2.0 * t + 2.0) + * (-2.0 * t + 2.0) + * (-2.0 * t + 2.0) + * (-2.0 * t + 2.0) + * (-2.0 * t + 2.0) + / 2.0 + } + } + #[inline] pub(crate) fn sine_in(t: f32) -> f32 { 1.0 - ops::cos(t * FRAC_PI_2) @@ -227,6 +299,44 @@ mod easing_functions { pub(crate) fn sine_out(t: f32) -> f32 { ops::sin(t * FRAC_PI_2) } + #[inline] + pub(crate) fn sine_in_out(t: f32) -> f32 { + -(ops::cos(PI * t) - 1.0) / 2.0 + } + + #[inline] + pub(crate) fn circular_in(t: f32) -> f32 { + 1.0 - (1.0 - t.squared()).sqrt() + } + #[inline] + pub(crate) fn circular_out(t: f32) -> f32 { + (1.0 - (t - 1.0).squared()).sqrt() + } + #[inline] + pub(crate) fn circular_in_out(t: f32) -> f32 { + if t < 0.5 { + (1.0 - (1.0 - (2.0 * t).squared()).sqrt()) / 2.0 + } else { + ((1.0 - (-2.0 * t + 2.0).squared()).sqrt() + 1.0) / 2.0 + } + } + + #[inline] + pub(crate) fn exponential_in(t: f32) -> f32 { + ops::powf(2.0, 10.0 * t - 10.0) + } + #[inline] + pub(crate) fn exponential_out(t: f32) -> f32 { + 1.0 - ops::powf(2.0, -10.0 * t) + } + #[inline] + pub(crate) fn exponential_in_out(t: f32) -> f32 { + if t < 0.5 { + ops::powf(2.0, 20.0 * t - 10.0) / 2.0 + } else { + (2.0 - ops::powf(2.0, -20.0 * t + 10.0)) / 2.0 + } + } #[inline] pub(crate) fn back_in(t: f32) -> f32 { @@ -271,6 +381,31 @@ mod easing_functions { } } + #[inline] + pub(crate) fn bounce_in(t: f32) -> f32 { + 1.0 - bounce_out(1.0 - t) + } + #[inline] + pub(crate) fn bounce_out(t: f32) -> f32 { + if t < 4.0 / 11.0 { + (121.0 * t.squared()) / 16.0 + } else if t < 8.0 / 11.0 { + (363.0 / 40.0 * t.squared()) - (99.0 / 10.0 * t) + 17.0 / 5.0 + } else if t < 9.0 / 10.0 { + (4356.0 / 361.0 * t.squared()) - (35442.0 / 1805.0 * t) + 16061.0 / 1805.0 + } else { + (54.0 / 5.0 * t.squared()) - (513.0 / 25.0 * t) + 268.0 / 25.0 + } + } + #[inline] + pub(crate) fn bounce_in_out(t: f32) -> f32 { + if t < 0.5 { + (1.0 - bounce_out(1.0 - 2.0 * t)) / 2.0 + } else { + (1.0 + bounce_out(2.0 * t - 1.0)) / 2.0 + } + } + #[inline] pub(crate) fn steps(num_steps: usize, t: f32) -> f32 { (t * num_steps as f32).round() / num_steps.max(1) as f32 @@ -286,36 +421,36 @@ impl EaseFunction { fn eval(&self, t: f32) -> f32 { match self { EaseFunction::Linear => easing_functions::linear(t), - EaseFunction::QuadraticIn => IEase::quadratic_in(t), - EaseFunction::QuadraticOut => IEase::quadratic_out(t), - EaseFunction::QuadraticInOut => IEase::quadratic_in_out(t), - EaseFunction::CubicIn => IEase::cubic_in(t), - EaseFunction::CubicOut => IEase::cubic_out(t), - EaseFunction::CubicInOut => IEase::cubic_in_out(t), - EaseFunction::QuarticIn => IEase::quartic_in(t), - EaseFunction::QuarticOut => IEase::quartic_out(t), - EaseFunction::QuarticInOut => IEase::quartic_in_out(t), - EaseFunction::QuinticIn => IEase::quintic_in(t), - EaseFunction::QuinticOut => IEase::quintic_out(t), - EaseFunction::QuinticInOut => IEase::quintic_in_out(t), + EaseFunction::QuadraticIn => easing_functions::quadratic_in(t), + EaseFunction::QuadraticOut => easing_functions::quadratic_out(t), + EaseFunction::QuadraticInOut => easing_functions::quadratic_in_out(t), + EaseFunction::CubicIn => easing_functions::cubic_in(t), + EaseFunction::CubicOut => easing_functions::cubic_out(t), + EaseFunction::CubicInOut => easing_functions::cubic_in_out(t), + EaseFunction::QuarticIn => easing_functions::quartic_in(t), + EaseFunction::QuarticOut => easing_functions::quartic_out(t), + EaseFunction::QuarticInOut => easing_functions::quartic_in_out(t), + EaseFunction::QuinticIn => easing_functions::quintic_in(t), + EaseFunction::QuinticOut => easing_functions::quintic_out(t), + EaseFunction::QuinticInOut => easing_functions::quintic_in_out(t), EaseFunction::SineIn => easing_functions::sine_in(t), EaseFunction::SineOut => easing_functions::sine_out(t), - EaseFunction::SineInOut => IEase::sine_in_out(t), - EaseFunction::CircularIn => IEase::circular_in(t), - EaseFunction::CircularOut => IEase::circular_out(t), - EaseFunction::CircularInOut => IEase::circular_in_out(t), - EaseFunction::ExponentialIn => IEase::exponential_in(t), - EaseFunction::ExponentialOut => IEase::exponential_out(t), - EaseFunction::ExponentialInOut => IEase::exponential_in_out(t), + EaseFunction::SineInOut => easing_functions::sine_in_out(t), + EaseFunction::CircularIn => easing_functions::circular_in(t), + EaseFunction::CircularOut => easing_functions::circular_out(t), + EaseFunction::CircularInOut => easing_functions::circular_in_out(t), + EaseFunction::ExponentialIn => easing_functions::exponential_in(t), + EaseFunction::ExponentialOut => easing_functions::exponential_out(t), + EaseFunction::ExponentialInOut => easing_functions::exponential_in_out(t), EaseFunction::ElasticIn => easing_functions::elastic_in(t), EaseFunction::ElasticOut => easing_functions::elastic_out(t), EaseFunction::ElasticInOut => easing_functions::elastic_in_out(t), EaseFunction::BackIn => easing_functions::back_in(t), EaseFunction::BackOut => easing_functions::back_out(t), EaseFunction::BackInOut => easing_functions::back_in_out(t), - EaseFunction::BounceIn => IEase::bounce_in(t), - EaseFunction::BounceOut => IEase::bounce_out(t), - EaseFunction::BounceInOut => IEase::bounce_in_out(t), + EaseFunction::BounceIn => easing_functions::bounce_in(t), + EaseFunction::BounceOut => easing_functions::bounce_out(t), + EaseFunction::BounceInOut => easing_functions::bounce_in_out(t), EaseFunction::Steps(num_steps) => easing_functions::steps(*num_steps, t), EaseFunction::Elastic(omega) => easing_functions::elastic(*omega, t), }