Skip to content

Commit

Permalink
Replace the cubic_spline_interpolation macro with a generic function (
Browse files Browse the repository at this point in the history
#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.
  • Loading branch information
Kanabenki authored Jan 29, 2024
1 parent a6ec32a commit e94297f
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit e94297f

Please sign in to comment.