bevy/crates
scottmcm f96653498b
[math] Add SmoothStep and SmootherStep easing functions (#16957)
# Objective

Almost all of the `*InOut` easing functions are not actually smooth
(`SineInOut` is the one exception).

Because they're defined piecewise, they jump from accelerating upwards
to accelerating downwards, causing infinite jerk at t=½.

## Solution

This PR adds the well-known
[smoothstep](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml),
as well as its higher-degree version
[smootherstep](https://en.wikipedia.org/wiki/Smoothstep#Variations), as
easing functions.

Mathematically, these are the classic [Hermite
interpolation](https://en.wikipedia.org/wiki/Hermite_interpolation)
results:
- for smoothstep, the cubic with velocity zero at both ends
- for smootherstep, the quintic with velocity zero *and acceleration
zero* at both ends

And because they're simple polynomials, there's no branching and thus
they don't have the acceleration jump in the middle.

I also added some more information and cross-linking to the
documentation for these and some of the other easing functions, to help
clarify why one might want to use these over other existing ones. In
particular, I suspect that if people are willing to pay for a quintic
they might prefer `SmootherStep` to `QuinticInOut`.

For consistency with how everything else has triples, I added
`Smooth(er)Step{In,Out}` as well, in case people want to run the `In`
and `Out` versions separately for some reason. Qualitatively they're not
hugely different from `Quadratic{In,Out}` or `Cubic{In,Out}`, though, so
could be removed if you'd rather. They're low cost to keep, though, and
convenient for testing.

## Testing

These are simple polynomials, so their coefficients can be read directly
from the Horner's method implementation and compared to the reference
materials. The tests from #16910 were updated to also test these 6 new
easing functions, ensuring basic behaviour, plus one was updated to
better check that the InOut versions of things match their rescaled In
and Out versions.

Even small changes like
```diff
-    (((2.5 + (-1.875 + 0.375*t) * t) * t) * t) * t
+    (((2.5 + (-1.85 + 0.375*t) * t) * t) * t) * t
```
are caught by multiple tests this way.

If you want to confirm them visually, here are the 6 new ones graphed:
<https://www.desmos.com/calculator/2d3ofujhry>

![smooth-and-smoother-step](https://github.com/user-attachments/assets/a114530e-e55f-4b6a-85e7-86e7abf51482)

---

## Migration Guide

This version of bevy marks `EaseFunction` as `#[non_exhaustive]` to that
future changes to add more easing functions will be non-breaking. If you
were exhaustively matching that enum -- which you probably weren't --
you'll need to add a catch-all (`_ =>`) arm to cover unknown easing
functions.
2024-12-24 17:17:28 +00:00
..
bevy_a11y Replace bevy_a11y::Focus with InputFocus (#16863) 2024-12-18 00:16:19 +00:00
bevy_animation Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_app Expose access to SubApps within App (#16952) 2024-12-24 06:15:16 +00:00
bevy_asset Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_audio Move Volume and GlobalVolume to own file (#16838) 2024-12-16 19:28:30 +00:00
bevy_color Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_core_pipeline Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_derive Add benchmarks and compile_fail tests back to workspace (#16858) 2024-12-21 22:30:29 +00:00
bevy_dev_tools Draw the UI debug overlay using the UI renderer (#16693) 2024-12-11 00:49:47 +00:00
bevy_diagnostic Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_dylib
bevy_ecs Remove vestigial helper functions for Commands and EntityCommands (#16936) 2024-12-24 03:07:28 +00:00
bevy_encase_derive Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_gilrs Deny derive_more error feature and replace it with thiserror (#16684) 2024-12-06 17:03:55 +00:00
bevy_gizmos Add dashed lines (#16884) 2024-12-18 20:43:58 +00:00
bevy_gltf Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_hierarchy Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_image Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_input Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_input_focus Remove SetInputFocus helper trait (#16888) 2024-12-19 00:40:10 +00:00
bevy_internal Expose bevy_image as a feature (#16948) 2024-12-24 03:11:01 +00:00
bevy_log Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_macro_utils Use one BevyManifest instance in proc macros (#16766) 2024-12-15 15:00:05 +00:00
bevy_math [math] Add SmoothStep and SmootherStep easing functions (#16957) 2024-12-24 17:17:28 +00:00
bevy_mesh Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_mikktspace Rust 1.83, allow -> expect (missing_docs) (#16561) 2024-12-16 23:27:57 +00:00
bevy_pbr Expose Tonemapping LUT binding indices (#16934) 2024-12-24 03:02:14 +00:00
bevy_picking Rename "focus" in bevy_picking to "hover" (#16872) 2024-12-24 06:22:13 +00:00
bevy_ptr Fix MSRVs for standalone crates (#16333) 2024-11-17 09:38:13 +00:00
bevy_reflect Replace impl_param_set proc macro with a macro_rules macro (#16847) 2024-12-18 18:30:46 +00:00
bevy_remote BRP strict field in query (#16725) 2024-12-14 05:22:19 +00:00
bevy_render impl EntityBorrow for more types (#16917) 2024-12-24 02:47:03 +00:00
bevy_scene Add missing #[reflect(Component, Default)] to SceneRoot and DynamicSceneRoot. (#16816) 2024-12-15 19:18:22 +00:00
bevy_sprite Remove unnecessary cast in DynamicTextureAtlasBuilder (#16937) 2024-12-24 17:14:06 +00:00
bevy_state Replace impl_param_set proc macro with a macro_rules macro (#16847) 2024-12-18 18:30:46 +00:00
bevy_tasks Remove bevy_core (#16897) 2024-12-19 18:36:51 +00:00
bevy_text Drive-by Docs Fixes: bevy_picking, bevy_text (#16946) 2024-12-23 22:23:33 +00:00
bevy_time Use en-us locale for typos (#16037) 2024-10-20 18:55:17 +00:00
bevy_transform track_change_detection: Also track spawns/despawns (#16047) 2024-12-17 04:46:31 +00:00
bevy_ui Implement FromStr for Val (#16926) 2024-12-24 02:51:13 +00:00
bevy_utils Add no_std support to bevy_ecs (#16758) 2024-12-17 21:40:36 +00:00
bevy_window impl EntityBorrow for more types (#16917) 2024-12-24 02:47:03 +00:00
bevy_winit Replace bevy_a11y::Focus with InputFocus (#16863) 2024-12-18 00:16:19 +00:00