Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add curve utilities to create curves interpolating/easing between two values #14788

Merged
merged 32 commits into from
Oct 2, 2024

Conversation

RobWalt
Copy link
Contributor

@RobWalt RobWalt commented Aug 16, 2024

Objective

Citing @mweatherley

There is a lot of shortfall for simple cases— e.g., we should have library functions for making a curve connecting two points, eased versions of that, and so on.

Solution

This PR implements

  • a simple Easing trait which is implemented for all impl Curve<f32> types. We can't really guarantee that these curves have unit interval domain, which some people would probably expect, but it is documented that this isn't the case for these types and we redirect to EasingCurve which is used for that purpose
  • an EasingCurve struct, which is used to interpolate between two values start and end using a impl Easing curve where the curve will be guaranteed to be reparametrized
  • a LinearCurve which linearly interpolates between two values start and end
  • a CubicBezierCurve which interpolates between start and end values using a CubicSegment
  • a StepCurve which interpolates between start and end with an step-function with n steps
  • an ElasticCurve which interpolates between start and end with spring like behavior where the elasticity of the spring is configurable
  • some FunctionCurve easing curves for different popular functions including: quadratic_ease_in, quadratic_ease_out, smoothstep, identity

Testing

  • there are a few new tests for all of these in the main module

@mweatherley mweatherley self-requested a review August 16, 2024 20:57
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
@alice-i-cecile alice-i-cecile added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Math Fundamental domain-agnostic mathematical operations S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Aug 16, 2024
@alice-i-cecile alice-i-cecile added this to the 0.15 milestone Aug 16, 2024
@alice-i-cecile alice-i-cecile added the D-Straightforward Simple bug fixes and API improvements, docs, test and examples label Aug 16, 2024
@IQuick143
Copy link
Contributor

Sorry if the comments seem mean! I appreciate the PR even though I nitpicked it a lot.
I'm not necessarily saying stuff should be changed, but I think these suggestions are worth giving a ponder.

@RobWalt RobWalt changed the title add line_curve, easing_curve and easing functions add curve utilities to create curves interpolating/easing between two values Aug 17, 2024
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@NthTensor NthTensor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, first off thanks! You're one of the first people I've seen to start doing stuff with curves, and I think you're doing great. Really appreciate it.

In the discord, @mweatherley suggested that we might want something more like the following

fn eased_curve_between<T>(start: T, end: T, easing: impl Curve<f32>) -> impl Curve<T>
where
    T: VectorSpace 
{
    let span = end - start;
    easing.map(|x| (x * span) + start)
}

Then we define a set of concrete easing curves (like these) which pass through (0, 0) and (1, 1).

We could even define a marker trait which has this invariant in it's docs as a contract.

trait EasingCurve: Curve<f32> {};

However, I don't see anything wrong with the current implementation and I do think it's in a merge-able state pretty much. So if you'd prefer, we can marge and refactor the api as follow-up.

@RobWalt
Copy link
Contributor Author

RobWalt commented Aug 19, 2024

Hey, first off thanks! You're one of the first people I've seen to start doing stuff with curves, and I think you're doing great. Really appreciate it.

In the discord, @mweatherley suggested that we might want something more like the following

fn eased_curve_between<T>(start: T, end: T, easing: impl Curve<f32>) -> impl Curve<T>
where
    T: VectorSpace 
{
    let span = end - start;
    easing.map(|x| (x * span) + start)
}

Then we define a set of concrete easing curves (like these) which pass through (0, 0) and (1, 1).

We could even define a marker trait which has this invariant in it's docs as a contract.

trait EasingCurve: Curve<f32> {};

However, I don't see anything wrong with the current implementation and I do think it's in a merge-able state pretty much. So if you'd prefer, we can marge and refactor the api as follow-up.

Thanks for the review comment. That makes sense! Nevertheless I think that #14788 (comment) is also pretty valid. So I'd rather create a new struct EasingCurve which handles this without the impl Curve<Foo> part. I'll go back to the implementing board! 👷🏼

@IQuick143 IQuick143 self-requested a review August 20, 2024 06:54
@RobWalt RobWalt force-pushed the more-curve-constructors branch 2 times, most recently from 58ba8cf to cff9622 Compare August 21, 2024 07:34
Copy link
Contributor

@NthTensor NthTensor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Co-Authored-By: Miles Silberling-Cook <NthTensor@users.noreply.github.com>
@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-Animation Make things move and change over time M-Needs-Release-Note Work that should be called out in the blog due to impact and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Sep 30, 2024
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple and lovely. @RobWalt when you have a chance, I'd appreciate merge conflict resolution here :)

crates/bevy_math/src/curve/easing.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/easing.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/easing.rs Outdated Show resolved Hide resolved
crates/bevy_math/src/curve/easing.rs Outdated Show resolved Hide resolved
@mweatherley mweatherley added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Oct 1, 2024
Co-authored-by: Matty <weatherleymatthew@gmail.com>
@alice-i-cecile
Copy link
Member

This will be merged before the 0.15 release candidate, but I'll give you a bit of time to clean up those nits if you have the chance.

Co-authored-by: Matty <weatherleymatthew@gmail.com>
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Oct 2, 2024
Merged via the queue into bevyengine:main with commit 59db6f9 Oct 2, 2024
26 checks passed
robtfm pushed a commit to robtfm/bevy that referenced this pull request Oct 4, 2024
… values (bevyengine#14788)

# Objective

Citing @mweatherley 

> There is a lot of shortfall for simple cases— e.g., we should have
library functions for making a curve connecting two points, eased
versions of that, and so on.

## Solution

This PR implements

- a simple `Easing` trait which is implemented for all `impl Curve<f32>`
types. We can't really guarantee that these curves have unit interval
domain, which some people would probably expect, but it is documented
that this isn't the case for these types and we redirect to
`EasingCurve` which is used for that purpose
- an `EasingCurve` struct, which is used to interpolate between two
values `start` and `end` using a `impl Easing` curve where the curve
will be guaranteed to be reparametrized
- a `LinearCurve` which linearly interpolates between two values `start`
and `end`
- a `CubicBezierCurve` which interpolates between `start` and `end`
values using a `CubicSegment`
- a `StepCurve` which interpolates between `start` and `end` with an
step-function with `n` steps
- an `ElasticCurve` which interpolates between `start` and `end` with
spring like behavior where the elasticity of the spring is configurable
- some `FunctionCurve` easing curves for different popular functions
including: `quadratic_ease_in`, `quadratic_ease_out`, `smoothstep`,
`identity`

## Testing

- there are a few new tests for all of these in the main module

---------

Co-authored-by: eckz <567737+eckz@users.noreply.github.com>
Co-authored-by: Miles Silberling-Cook <NthTensor@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Matty <weatherleymatthew@gmail.com>
github-merge-queue bot pushed a commit that referenced this pull request Oct 7, 2024
# Objective

- Followup for #14788 
- Support most usual ease function

## Solution

- Use the crate
[`interpolation`](https://docs.rs/interpolation/0.3.0/interpolation/trait.Ease.html)
which has them all
- it's already used by bevy_easings, bevy_tweening, be_tween,
bevy_tweening_captured, bevy_enoki, kayak_ui in the Bevy ecosystem for
various easing/tweening/interpolation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Animation Make things move and change over time A-Math Fundamental domain-agnostic mathematical operations C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples M-Needs-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants