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)]
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<T>(
value_start: T,
tangent_out_start: T,
tangent_in_end: T,
value_end: T,
lerp: f32,
step_duration: f32,
) -> 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)]
@ -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,