Replace the cubic_spline_interpolation macro with a generic function (#11605)

# Objective

- Address a `TODO` item in `bevy_animation`.

## Solution

- Replace the `cubic_spline_interpolation` macro with a function.

The function isn't marked as `#[inline(always)]` but from what I checked
with `cargo asm` it gets inlined (even in debug, unless I explicitly add
`#[inline(never)]`), so this should be identical to the macro. If needed
I can add the attribute.
This commit is contained in:
Kanabenki 2024-01-29 20:50:30 +01:00 committed by GitHub
parent a6ec32aca4
commit e94297fdce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

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