feat: impl Ease
for Isometry[2/3]d
(#17545)
# Objective - We kind of missed out on implementing the `Ease` trait for some objects like `Isometry2D` and `Isometry3D` even though it makes sense and isn't that hard - Fixes #17539 ## Testing - wrote some minimal tests - ~~noticed that quat easing isn't working as expected yet~~ I just confused degrees and radians once again 🙈
This commit is contained in:
parent
89a1c49377
commit
a893c5d572
@ -5,7 +5,7 @@
|
||||
|
||||
use crate::{
|
||||
curve::{Curve, CurveExt, FunctionCurve, Interval},
|
||||
Dir2, Dir3, Dir3A, Quat, Rot2, VectorSpace,
|
||||
Dir2, Dir3, Dir3A, Isometry2d, Isometry3d, Quat, Rot2, VectorSpace,
|
||||
};
|
||||
|
||||
use variadics_please::all_tuples_enumerated;
|
||||
@ -74,6 +74,42 @@ impl Ease for Dir3A {
|
||||
}
|
||||
}
|
||||
|
||||
impl Ease for Isometry3d {
|
||||
fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
|
||||
FunctionCurve::new(Interval::EVERYWHERE, move |t| {
|
||||
// we can use sample_unchecked here, since both interpolating_curve_unbounded impls
|
||||
// used are defined on the whole domain
|
||||
Isometry3d {
|
||||
rotation: Quat::interpolating_curve_unbounded(start.rotation, end.rotation)
|
||||
.sample_unchecked(t),
|
||||
translation: crate::Vec3A::interpolating_curve_unbounded(
|
||||
start.translation,
|
||||
end.translation,
|
||||
)
|
||||
.sample_unchecked(t),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Ease for Isometry2d {
|
||||
fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
|
||||
FunctionCurve::new(Interval::EVERYWHERE, move |t| {
|
||||
// we can use sample_unchecked here, since both interpolating_curve_unbounded impls
|
||||
// used are defined on the whole domain
|
||||
Isometry2d {
|
||||
rotation: Rot2::interpolating_curve_unbounded(start.rotation, end.rotation)
|
||||
.sample_unchecked(t),
|
||||
translation: crate::Vec2::interpolating_curve_unbounded(
|
||||
start.translation,
|
||||
end.translation,
|
||||
)
|
||||
.sample_unchecked(t),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_ease_tuple {
|
||||
($(#[$meta:meta])* $(($n:tt, $T:ident)),*) => {
|
||||
$(#[$meta])*
|
||||
@ -627,6 +663,9 @@ impl EaseFunction {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{Vec2, Vec3, Vec3A};
|
||||
use approx::assert_abs_diff_eq;
|
||||
|
||||
use super::*;
|
||||
const MONOTONIC_IN_OUT_INOUT: &[[EaseFunction; 3]] = {
|
||||
use EaseFunction::*;
|
||||
@ -719,4 +758,70 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ease_quats() {
|
||||
let quat_start = Quat::from_axis_angle(Vec3::Z, 0.0);
|
||||
let quat_end = Quat::from_axis_angle(Vec3::Z, 90.0_f32.to_radians());
|
||||
|
||||
let quat_curve = Quat::interpolating_curve_unbounded(quat_start, quat_end);
|
||||
|
||||
assert_abs_diff_eq!(
|
||||
quat_curve.sample(0.0).unwrap(),
|
||||
Quat::from_axis_angle(Vec3::Z, 0.0)
|
||||
);
|
||||
{
|
||||
let (before_mid_axis, before_mid_angle) =
|
||||
quat_curve.sample(0.25).unwrap().to_axis_angle();
|
||||
assert_abs_diff_eq!(before_mid_axis, Vec3::Z);
|
||||
assert_abs_diff_eq!(before_mid_angle, 22.5_f32.to_radians());
|
||||
}
|
||||
{
|
||||
let (mid_axis, mid_angle) = quat_curve.sample(0.5).unwrap().to_axis_angle();
|
||||
assert_abs_diff_eq!(mid_axis, Vec3::Z);
|
||||
assert_abs_diff_eq!(mid_angle, 45.0_f32.to_radians());
|
||||
}
|
||||
{
|
||||
let (after_mid_axis, after_mid_angle) =
|
||||
quat_curve.sample(0.75).unwrap().to_axis_angle();
|
||||
assert_abs_diff_eq!(after_mid_axis, Vec3::Z);
|
||||
assert_abs_diff_eq!(after_mid_angle, 67.5_f32.to_radians());
|
||||
}
|
||||
assert_abs_diff_eq!(
|
||||
quat_curve.sample(1.0).unwrap(),
|
||||
Quat::from_axis_angle(Vec3::Z, 90.0_f32.to_radians())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ease_isometries_2d() {
|
||||
let angle = 90.0;
|
||||
let iso_2d_start = Isometry2d::new(Vec2::ZERO, Rot2::degrees(0.0));
|
||||
let iso_2d_end = Isometry2d::new(Vec2::ONE, Rot2::degrees(angle));
|
||||
|
||||
let iso_2d_curve = Isometry2d::interpolating_curve_unbounded(iso_2d_start, iso_2d_end);
|
||||
|
||||
[-1.0, 0.0, 0.5, 1.0, 2.0].into_iter().for_each(|t| {
|
||||
assert_abs_diff_eq!(
|
||||
iso_2d_curve.sample(t).unwrap(),
|
||||
Isometry2d::new(Vec2::ONE * t, Rot2::degrees(angle * t))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ease_isometries_3d() {
|
||||
let angle = 90.0_f32.to_radians();
|
||||
let iso_3d_start = Isometry3d::new(Vec3A::ZERO, Quat::from_axis_angle(Vec3::Z, 0.0));
|
||||
let iso_3d_end = Isometry3d::new(Vec3A::ONE, Quat::from_axis_angle(Vec3::Z, angle));
|
||||
|
||||
let iso_3d_curve = Isometry3d::interpolating_curve_unbounded(iso_3d_start, iso_3d_end);
|
||||
|
||||
[-1.0, 0.0, 0.5, 1.0, 2.0].into_iter().for_each(|t| {
|
||||
assert_abs_diff_eq!(
|
||||
iso_3d_curve.sample(t).unwrap(),
|
||||
Isometry3d::new(Vec3A::ONE * t, Quat::from_axis_angle(Vec3::Z, angle * t))
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user