Commit Graph

350 Commits

Author SHA1 Message Date
François Mockers
383b351045 chore: Release 2025-05-31 00:18:34 +02:00
Innokentiy Popov
92cda8b0bb Fix rotate_by implementation for Aabb2d (#19015)
# Objective

Fixes #18969 

## Solution

Also updated `Aabb3d` implementation for consistency.

## Testing

Added tests for `Aabb2d` and `Aabb3d` to verify correct rotation
behavior for angles greater than 90 degrees.
2025-05-30 22:59:09 +02:00
François Mockers
e9418b3845 Release 0.16.0 2025-04-21 23:14:00 +02:00
François Mockers
608f902d1a Release 0.16.0-rc.5 2025-04-15 09:11:38 +02:00
Matty Weatherley
ea15c85977 Expose the output curve type in with_derivative (#18826)
# Objective

I was wrong about how RPITIT works when I wrote this stuff initially,
and in order to actually give people access to all the traits
implemented by the output (e.g. Debug and so on) it's important to
expose the real output type, even if it makes the trait uglier and less
comprehensible. (☹️)

## Solution

Expose the curve output type of the `CurveWithDerivative` trait and its
double-derivative companion. I also added a bunch of trait derives to
`WithDerivative<T>`, since I think that was just an oversight.
2025-04-14 22:46:29 +02:00
François Mockers
c4b3d75b46 Release 0.16.0-rc.4 2025-04-11 09:12:55 +02:00
François Mockers
bdfd7a3443 Release 0.16.0-rc.3 2025-03-31 23:07:43 +02:00
Zachary Harrold
a2b14983f4 Upgrade to Glam 0.29.3 and Simplify Feature Gating (#18638)
- Fixes #18397
- Supersedes #18474
- Simplifies 0.16 migration

- Upgrade to Glam 0.29.3, which has backported the `nostd-libm` feature.
- Expose a similar feature in `bevy_math` and enable it in
`bevy_internal`, allowing `bevy_math`, `bevy_input`, and
`bevy_transform` to be unconditional dependencies again.

- CI

---

- This includes `libm` as a dependency, but this was already the case in
the common scenario where `rand` or many other features were enabled.
Considering `libm` is an official Rust crate, it's a very low-risk
dependency to unconditionally include.
- For users who do not want `libm` included, simply import Bevy's
subcrates directly, since `bevy_math/nostd-libm` will not be enabled.
- I know we are _very_ late in the RC cycle for 0.16, but this has a
substantial impact on the usability of `bevy` that I consider worth
including.
2025-03-31 22:36:16 +02:00
François Mockers
1f44b56310 Release 0.16.0-rc.2 2025-03-26 19:18:20 +01:00
Joona Aalto
bdf6f3d5f1 Add no_std compatible ceil method (#18498)
# Objective


[`f32::ceil`](https://doc.rust-lang.org/std/primitive.f32.html#method.ceil)
is not available in `core`. We have `floor` in `bevy_math::ops`, but no
equivalent for `floor`.

## Solution

Add `ops::ceil` for `no_std` compatibility.
2025-03-25 22:59:04 +01:00
François Mockers
920515adab Release 0.16.0-rc.1 2025-03-18 21:48:22 +01:00
Gino Valente
9b32e09551
bevy_reflect: Add clone registrations project-wide (#18307)
# Objective

Now that #13432 has been merged, it's important we update our reflected
types to properly opt into this feature. If we do not, then this could
cause issues for users downstream who want to make use of
reflection-based cloning.

## Solution

This PR is broken into 4 commits:

1. Add `#[reflect(Clone)]` on all types marked `#[reflect(opaque)]` that
are also `Clone`. This is mandatory as these types would otherwise cause
the cloning operation to fail for any type that contains it at any
depth.
2. Update the reflection example to suggest adding `#[reflect(Clone)]`
on opaque types.
3. Add `#[reflect(clone)]` attributes on all fields marked
`#[reflect(ignore)]` that are also `Clone`. This prevents the ignored
field from causing the cloning operation to fail.
   
Note that some of the types that contain these fields are also `Clone`,
and thus can be marked `#[reflect(Clone)]`. This makes the
`#[reflect(clone)]` attribute redundant. However, I think it's safer to
keep it marked in the case that the `Clone` impl/derive is ever removed.
I'm open to removing them, though, if people disagree.
4. Finally, I added `#[reflect(Clone)]` on all types that are also
`Clone`. While not strictly necessary, it enables us to reduce the
generated output since we can just call `Clone::clone` directly instead
of calling `PartialReflect::reflect_clone` on each variant/field. It
also means we benefit from any optimizations or customizations made in
the `Clone` impl, including directly dereferencing `Copy` values and
increasing reference counters.

Along with that change I also took the liberty of adding any missing
registrations that I saw could be applied to the type as well, such as
`Default`, `PartialEq`, and `Hash`. There were hundreds of these to
edit, though, so it's possible I missed quite a few.

That last commit is **_massive_**. There were nearly 700 types to
update. So it's recommended to review the first three before moving onto
that last one.

Additionally, I can break the last commit off into its own PR or into
smaller PRs, but I figured this would be the easiest way of doing it
(and in a timely manner since I unfortunately don't have as much time as
I used to for code contributions).

## Testing

You can test locally with a `cargo check`:

```
cargo check --workspace --all-features
```
2025-03-17 18:32:35 +00:00
Lynn
f245490e4a
implement Bounded2d for ConvexPolygon (#18286)
# Objective

- Implement `Bounded2d` for `ConvexPolygon`
2025-03-13 16:35:52 +00:00
Matty Weatherley
84463e60e1
Implement Serialize/Deserialize/PartialEq for bounding primitives (#18281)
# Objective

Probably just because of an oversight, bounding primitives like `Aabb3d`
did not implement `Serialize`/`Deserialize` with the `serialize` feature
enabled, so the goal of this PR is to fill the gap.

## Solution

Derive it conditionally, just like we do for everything else. Also added
in `PartialEq`, just because I touched the files.

## Testing

Compiled with different feature combinations.
2025-03-12 21:38:29 +00:00
Cyrill Schenkel
8570af1d96
Add print_stdout and print_stderr lints (#17446) (#18233)
# Objective

- Prevent usage of `println!`, `eprintln!` and the like because they
require `std`
- Fixes #17446

## Solution

- Enable the `print_stdout` and `print_stderr` clippy lints
- Replace all `println!` and `eprintln!` occurrences with `log::*` where
applicable or alternatively ignore the warnings

## Testing

- Run `cargo clippy --workspace` to ensure that there are no warnings
relating to printing to `stdout` or `stderr`
2025-03-11 19:35:48 +00:00
Joona Aalto
9f6d628c48
Improve Segment2d/Segment3d API and docs (#18206)
# Objective

#17404 reworked the `Segment2d` and `Segment3d` types to be defined by
two endpoints rather than a direction and half-length. However, the API
is still very minimal and limited, and documentation is inconsistent and
outdated.

## Solution

Add the following helper methods for `Segment2d` and `Segment3d`:

- `from_scaled_direction`
- `from_ray_and_length`
- `length_squared`
- `direction`
- `try_direction`
- `scaled_direction`
- `transformed`
- `reversed`

`Segment2d` has a few 2D-specific methods:

- `left_normal`
- `try_left_normal`
- `scaled_left_normal`
- `right_normal`
- `try_right_normal`
- `scaled_right_normal`

There are now also `From` implementations for converting `[Vec2; 2]` and
`(Vec2, Vec2)` to a `Segment2d`, and similarly for 3D.

I have also updated documentation to be more accurate and consistent,
and simplified a few methods.

---

## Prior Art

Parry's
[`Segment`](https://docs.rs/parry2d/latest/parry2d/shape/struct.Segment.html)
type has a lot of similar methods, though my implementation is a bit
more comprehensive. A lot of these methods can be useful for various
geometry algorithms.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Greeble <166992735+greeble-dev@users.noreply.github.com>
2025-03-09 20:21:31 +00:00
dependabot[bot]
cf18c346d8
Update itertools requirement from 0.13 to 0.14 (#18128)
Updates the requirements on
[itertools](https://github.com/rust-itertools/itertools) to permit the
latest version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md">itertools's
changelog</a>.</em></p>
<blockquote>
<h2>0.14.0</h2>
<h3>Breaking</h3>
<ul>
<li>Increased MSRV to 1.63.0 (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/960">#960</a>)</li>
<li>Removed generic parameter from <code>cons_tuples</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/988">#988</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li>Added <code>array_combinations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/991">#991</a>)</li>
<li>Added <code>k_smallest_relaxed</code> and variants (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/925">#925</a>)</li>
<li>Added <code>next_array</code> and <code>collect_array</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/560">#560</a>)</li>
<li>Implemented <code>DoubleEndedIterator</code> for
<code>FilterOk</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/948">#948</a>)</li>
<li>Implemented <code>DoubleEndedIterator</code> for
<code>FilterMapOk</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/950">#950</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Allow <code>Q: ?Sized</code> in <code>Itertools::contains</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/971">#971</a>)</li>
<li>Improved hygiene of <code>chain!</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/943">#943</a>)</li>
<li>Improved <code>into_group_map_by</code> documentation (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/1000">#1000</a>)</li>
<li>Improved <code>tree_reduce</code> documentation (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/955">#955</a>)</li>
<li>Improved discoverability of <code>merge_join_by</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/966">#966</a>)</li>
<li>Improved discoverability of <code>take_while_inclusive</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/972">#972</a>)</li>
<li>Improved documentation of <code>find_or_last</code> and
<code>find_or_first</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/984">#984</a>)</li>
<li>Prevented exponentially large type sizes in
<code>tuple_combinations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/945">#945</a>)</li>
<li>Added <code>track_caller</code> attr for <code>asser_equal</code>
(<a
href="https://redirect.github.com/rust-itertools/itertools/issues/976">#976</a>)</li>
</ul>
<h3>Notable Internal Changes</h3>
<ul>
<li>Fixed clippy lints (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/956">#956</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/987">#987</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/1008">#1008</a>)</li>
<li>Addressed warnings within doctests (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/964">#964</a>)</li>
<li>CI: Run most tests with miri (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/961">#961</a>)</li>
<li>CI: Speed up &quot;cargo-semver-checks&quot; action (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/938">#938</a>)</li>
<li>Changed an instance of <code>default_features</code> in
<code>Cargo.toml</code> to <code>default-features</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/985">#985</a>)</li>
</ul>
<h2>0.13.0</h2>
<h3>Breaking</h3>
<ul>
<li>Removed implementation of <code>DoubleEndedIterator</code> for
<code>ConsTuples</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/853">#853</a>)</li>
<li>Made <code>MultiProduct</code> fused and fixed on an empty iterator
(<a
href="https://redirect.github.com/rust-itertools/itertools/issues/835">#835</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/834">#834</a>)</li>
<li>Changed <code>iproduct!</code> to return tuples for maxi one
iterator too (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/870">#870</a>)</li>
<li>Changed <code>PutBack::put_back</code> to return the old value (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/880">#880</a>)</li>
<li>Removed deprecated <code>repeat_call, Itertools::{foreach, step,
map_results, fold_results}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/878">#878</a>)</li>
<li>Removed <code>TakeWhileInclusive::new</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/912">#912</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li>Added <code>Itertools::{smallest_by, smallest_by_key, largest,
largest_by, largest_by_key}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/654">#654</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/885">#885</a>)</li>
<li>Added <code>Itertools::tail</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/899">#899</a>)</li>
<li>Implemented <code>DoubleEndedIterator</code> for
<code>ProcessResults</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/910">#910</a>)</li>
<li>Implemented <code>Debug</code> for <code>FormatWith</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/931">#931</a>)</li>
<li>Added <code>Itertools::get</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/891">#891</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Deprecated <code>Itertools::group_by</code> (renamed
<code>chunk_by</code>) (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/866">#866</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/879">#879</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a015a68315"><code>a015a68</code></a>
Add <code>next_array</code> and <code>collect_array</code></li>
<li><a
href="a1213e1c81"><code>a1213e1</code></a>
Prepare v0.14.0 release</li>
<li><a
href="ff0c942b2e"><code>ff0c942</code></a>
fix clippy lints</li>
<li><a
href="f80883b8e0"><code>f80883b</code></a>
Fix into_group_map_by documentation errors</li>
<li><a
href="b793238ff1"><code>b793238</code></a>
Add track_caller for asser_equal</li>
<li><a
href="5d4056b643"><code>5d4056b</code></a>
<code>default_features</code> is deprecated - switch it to
<code>default-features</code></li>
<li><a
href="a447b68960"><code>a447b68</code></a>
doc for added trait</li>
<li><a
href="d0479b0807"><code>d0479b0</code></a>
&quot;nitpicks&quot;</li>
<li><a
href="35c78ce0bc"><code>35c78ce</code></a>
IndexMut -&gt; BorrowMut&lt;slice&gt;</li>
<li><a
href="deb53ba210"><code>deb53ba</code></a>
refactored to share code</li>
<li>Additional commits viewable in <a
href="https://github.com/rust-itertools/itertools/compare/v0.13.0...v0.14.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-03 19:36:29 +00:00
Ruslan Baynazarov
c7531074bc
Improve cubic segment bezier functionality (#17645)
# Objective

- Fixes #17642

## Solution

- Implemented method `new_bezier(points: [P; 4]) -> Self` for
`CubicSegment<P>`
- Old implementation of `new_bezier` is now `new_bezier_easing(p1: impl
Into<Vec2>, p2: impl Into<Vec2>) -> Self` (**breaking change**)
- ~~added method `new_bezier_with_anchor`, which can make a bezier curve
between two points with one control anchor~~
- added methods `iter_positions`, `iter_velocities`,
`iter_accelerations`, the same as in `CubicCurve` (**copied code,
potentially can be reduced)**
- bezier creation logic is moved from `CubicCurve` to `CubicSegment`,
removing the unneeded allocation

## Testing

- Did you test these changes? If so, how?
  - Run tests inside `crates/bevy_math/`
  - Tested the functionality in my project
- Are there any parts that need more testing?
  - Did not run `cargo test` on the whole bevy directory because of OOM
- Performance improvements are expected when creating `CubicCurve` with
`new_bezier` and `new_bezier_easing`, but not tested
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
  - Use in any code that works created `CubicCurve::new_bezier`
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - I don't think relevant

---

## Showcase

```rust
// Imagine a car goes towards a local target

// Create a simple `CubicSegment`, without using heap
let planned_path = CubicSegment::new_bezier([
    car_pos,
    car_pos + car_dir * turn_radius,
    target_point - target_dir * turn_radius,
    target_point,
]);

// Check if the planned path itersect other entities
for pos in planned_path.iter_positions(8) {
   // do some collision checks
}
```

## Migration Guide

> This section is optional. If there are no breaking changes, you can
delete this section.

- Replace `CubicCurve::new_bezier` with `CubicCurve::new_bezier_easing`
2025-02-26 20:36:54 +00:00
Chanceler Shaffer
cb628516d1
Add core Error to InvalidDirectionError (#17820)
# Objective

Fixes #17761 

## Solution
- Added core error to InvalidDirectionError

## Testing

- Did you test these changes? If so, how?
- An added test that pulls in anyhow as a dev dependency to ensure the
conversion is accounted for in creation via From
- Are there any parts that need more testing?
  - I'm unsure but probably not due to being a trivial change 
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- I did not try a fully built version of Bevy. Relied purely on tests.
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - Only windows

---------

Co-authored-by: Chanceler Shaffer <cshaffer2@lululemon.com>
Co-authored-by: Chanceler Shaffer <chancelershaffer@lululemon.com>
2025-02-24 21:04:22 +00:00
Zachary Harrold
5241e09671
Upgrade to Rust Edition 2024 (#17967)
# Objective

- Fixes #17960

## Solution

- Followed the [edition upgrade
guide](https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html)

## Testing

- CI

---

## Summary of Changes

### Documentation Indentation

When using lists in documentation, proper indentation is now linted for.
This means subsequent lines within the same list item must start at the
same indentation level as the item.

```rust
/* Valid */
/// - Item 1
///   Run-on sentence.
/// - Item 2
struct Foo;

/* Invalid */
/// - Item 1
///     Run-on sentence.
/// - Item 2
struct Foo;
```

### Implicit `!` to `()` Conversion

`!` (the never return type, returned by `panic!`, etc.) no longer
implicitly converts to `()`. This is particularly painful for systems
with `todo!` or `panic!` statements, as they will no longer be functions
returning `()` (or `Result<()>`), making them invalid systems for
functions like `add_systems`. The ideal fix would be to accept functions
returning `!` (or rather, _not_ returning), but this is blocked on the
[stabilisation of the `!` type
itself](https://doc.rust-lang.org/std/primitive.never.html), which is
not done.

The "simple" fix would be to add an explicit `-> ()` to system
signatures (e.g., `|| { todo!() }` becomes `|| -> () { todo!() }`).
However, this is _also_ banned, as there is an existing lint which (IMO,
incorrectly) marks this as an unnecessary annotation.

So, the "fix" (read: workaround) is to put these kinds of `|| -> ! { ...
}` closuers into variables and give the variable an explicit type (e.g.,
`fn()`).

```rust
// Valid
let system: fn() = || todo!("Not implemented yet!");
app.add_systems(..., system);

// Invalid
app.add_systems(..., || todo!("Not implemented yet!"));
```

### Temporary Variable Lifetimes

The order in which temporary variables are dropped has changed. The
simple fix here is _usually_ to just assign temporaries to a named
variable before use.

### `gen` is a keyword

We can no longer use the name `gen` as it is reserved for a future
generator syntax. This involved replacing uses of the name `gen` with
`r#gen` (the raw-identifier syntax).

### Formatting has changed

Use statements have had the order of imports changed, causing a
substantial +/-3,000 diff when applied. For now, I have opted-out of
this change by amending `rustfmt.toml`

```toml
style_edition = "2021"
```

This preserves the original formatting for now, reducing the size of
this PR. It would be a simple followup to update this to 2024 and run
`cargo fmt`.

### New `use<>` Opt-Out Syntax

Lifetimes are now implicitly included in RPIT types. There was a handful
of instances where it needed to be added to satisfy the borrow checker,
but there may be more cases where it _should_ be added to avoid
breakages in user code.

### `MyUnitStruct { .. }` is an invalid pattern

Previously, you could match against unit structs (and unit enum
variants) with a `{ .. }` destructuring. This is no longer valid.

### Pretty much every use of `ref` and `mut` are gone

Pattern binding has changed to the point where these terms are largely
unused now. They still serve a purpose, but it is far more niche now.

### `iter::repeat(...).take(...)` is bad

New lint recommends using the more explicit `iter::repeat_n(..., ...)`
instead.

## Migration Guide

The lifetimes of functions using return-position impl-trait (RPIT) are
likely _more_ conservative than they had been previously. If you
encounter lifetime issues with such a function, please create an issue
to investigate the addition of `+ use<...>`.

## Notes

- Check the individual commits for a clearer breakdown for what
_actually_ changed.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2025-02-24 03:54:47 +00:00
RobWalt
aa8793f6b4
Add ways to configure EasingFunction::Steps via new StepConfig (#17752)
# Objective

- In #17743, attention was raised to the fact that we supported an
unusual kind of step easing function. The author of the fix kindly
provided some links to standards used in CSS. It would be desirable to
support generally agreed upon standards so this PR here tries to
implement an extra configuration option of the step easing function
- Resolve #17744

## Solution

- Introduce `StepConfig`
- `StepConfig` can configure both the number of steps and the jumping
behavior of the function
- `StepConfig` replaces the raw `usize` parameter of the
`EasingFunction::Steps(usize)` construct.
- `StepConfig`s default jumping behavior is `end`, so in that way it
follows #17743

## Testing

- I added a new test per `JumpAt` jumping behavior. These tests
replicate the visuals that can be found at
https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function/steps#description

## Migration Guide

- `EasingFunction::Steps` now uses a `StepConfig` instead of a raw
`usize`. You can replicate the previous behavior by replaceing
`EasingFunction::Steps(10)` with
`EasingFunction::Steps(StepConfig::new(10))`.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-02-11 22:19:01 +00:00
Greeble
71b22397da
Expand EasingCurve documentation (#17778)
# Objective

- Expand the documentation for `EasingCurve`.
- I suspect this might have avoided the confusion in
https://github.com/bevyengine/bevy/pull/17711.
- Also add a shortcut for simple cases.

## Solution

- Added various examples and extra context.
- Implemented `Curve<T>` for `EaseFunction`.
- This means `EasingCurve::new(0.0, 1.0, EaseFunction::X)` can be
shortened to `EaseFunction::X`.
    - In some cases this will be a minor performance improvement.
    - Added test to confirm they're the same.
- ~~Added some benchmarks for bonus points.~~


## Side Notes

- I would have liked to rename `EaseFunction` to `EaseFn` for brevity,
but that would be a breaking change and maybe controversial.
    - Also suspect `EasingCurve` should be `EaseCurve`, but say la vee.
- Benchmarks show that calling `EaseFunction::Smoothstep` is still
slower than calling `smoothstep` directly.
- I think this is because the compiler refuses to inline
`EaseFunction::eval`.
- I don't see any good solution - might need a whole different
interface.

## Testing

```sh
cargo test --package bevy_math

cargo doc --package bevy_math
./target/doc/bevy_math/curve/easing/struct.EasingCurve.html

cargo bench --package benches --bench math -- easing
```
2025-02-10 22:37:27 +00:00
François Mockers
4fe57767fc
make bevy math publishable (#17727)
# Objective

- bevy_math fails to publish because of the self dev-dependency
- it's used to enable the `approx` feature in tests

## Solution

- Don't specify a version in the dev-dependency. dependencies without a
version are ignored by cargo when publishing
- Gate all the tests that depend on the `approx` feature so that it
doesn't fail to compile when not enabled
- Also gate an import that wasn't used without `bevy_reflect`

## Testing

- with at least cargo 1.84: `cargo package -p bevy_math`
- `cd target/package/bevy_math_* && cargo test`
2025-02-10 22:15:53 +00:00
François Mockers
7400e7adfd
Cleanup publish process (#17728)
# Objective

- publish script copy the license files to all subcrates, meaning that
all publish are dirty. this breaks git verification of crates
- the order and list of crates to publish is manually maintained,
leading to error. cargo 1.84 is more strict and the list is currently
wrong

## Solution

- duplicate all the licenses to all crates and remove the
`--allow-dirty` flag
- instead of a manual list of crates, get it from `cargo package
--workspace`
- remove the `--no-verify` flag to... verify more things?
2025-02-09 17:46:19 +00:00
Rob Parrett
f3d8eb8956
Fix rounding in steps easing function (#17743)
# Objective

While working on #17742, I noticed that the `Steps` easing function
looked a bit suspicious.


![image](https://github.com/user-attachments/assets/be8f07e4-2079-461f-8c23-56d4b689aed9)

Comparing to the options available in
[css](https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function/steps#description):


![image](https://github.com/user-attachments/assets/2c351519-c87f-483f-b5ff-63a9ee7b7b51)

It is "off the charts," so probably not what users are expecting.

## Solution

Use `floor` when rounding to match the default behavior (jump-end, top
right) in css.

<img width="100" alt="image"
src="https://github.com/user-attachments/assets/1ec46270-72f2-4227-87e4-03de881548ab"
/>


## Testing

I had to modify an existing test that was testing against the old
behavior. This function and test were introduced in #14788 and I didn't
see any discussion about the rounding there.

`cargo run --example easing_functions`

## Migration Guide

<!-- Note to editors: this should be adjusted if 17744 is addressed, and
possibly combined with the notes from the PR that fixes it. -->

`EaseFunction::Steps` now behaves like css's default, "jump-end." If you
were relying on the old behavior, we plan on providing it. See
https://github.com/bevyengine/bevy/issues/17744.
2025-02-08 18:33:46 +00:00
SpecificProtagonist
7c2d54c93f
EaseFunction svg graphs in doc (#17461)
# Objective

The docs of `EaseFunction` don't visualize the different functions,
requiring you to check out the Bevy repo and running the
`easing_function` example.

## Solution

- Add tool to generate suitable svg graphs. This only needs to be re-run
when adding new ease functions.
- works with all themes
- also add missing easing functions to example.

---

## Showcase

![Graphs](https://i.imgur.com/V2oTEUq.png)

---------

Co-authored-by: François Mockers <mockersf@gmail.com>
2025-02-08 09:52:39 +00:00
RobWalt
a893c5d572
feat: impl Ease for Isometry[2/3]d (#17545)
# Objective

- We kind of missed out on implementing the `Ease` trait for some
objects like `Isometry2D` and `Isometry3D` even though it makes sense
and isn't that hard
- Fixes #17539

## Testing

- wrote some minimal tests
- ~~noticed that quat easing isn't working as expected yet~~ I just
confused degrees and radians once again 🙈
2025-02-02 15:07:35 +00:00
Sigma-dev
7c8da1c05d
Reworked Segment types into their cartesian forms (#17404)
# Objective

Segment2d and Segment3d are currently hard to work with because unlike
many other primary shapes, they are bound to the origin.
The objective of this PR is to allow these segments to exist anywhere in
cartesian space, making them much more useful in a variety of contexts.

## Solution

Reworking the existing segment type's internal fields and methods to
allow them to exist anywhere in cartesian space.
I have done both reworks for 2d and 3d segments but I was unsure if I
should just have it all here or not so feel free to tell me how I should
proceed, for now I have only pushed Segment2d changes.

As I am not a very seasoned contributor, this first implementation is
very likely sloppy and will need some additional work from my end, I am
open to all criticisms and willing to work to get this to bevy's
standards.

## Testing

I am not very familiar with the standards of testing. Of course my
changes had to pass the thorough existing tests for primitive shapes.
I also checked the gizmo 2d shapes intersection example and everything
looked fine.

I did add a few utility methods to the types that have no tests yet. I
am willing to implement some if it is deemed necessary

## Migration Guide

The segment type constructors changed so if someone previously created a
Segment2d with a direction and length they would now need to use the
`from_direction` constructor

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2025-01-19 03:54:45 +00:00
MichiRecRoom
26bb0b40d2
Move #![warn(clippy::allow_attributes, clippy::allow_attributes_without_reason)] to the workspace Cargo.toml (#17374)
# Objective
Fixes https://github.com/bevyengine/bevy/issues/17111

## Solution
Move `#![warn(clippy::allow_attributes,
clippy::allow_attributes_without_reason)]` to the workspace `Cargo.toml`

## Testing
Lots of CI testing, and local testing too.

---------

Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
2025-01-15 01:14:58 +00:00
MichiRecRoom
447108b2a4
Downgrade clippy::allow_attributes and clippy::allow_attributes_without_reason to warn (#17320)
# Objective
I realized that setting these to `deny` may have been a little
aggressive - especially since we upgrade warnings to denies in CI.

## Solution
Downgrades these lints to `warn`, so that compiles can work locally. CI
will still treat these as denies.
2025-01-12 05:28:26 +00:00
Rob Parrett
b77e3ef33a
Fix a few typos (#17292)
# Objective

Stumbled upon a `from <-> form` transposition while reviewing a PR,
thought it was interesting, and went down a bit of a rabbit hole.

## Solution

Fix em
2025-01-10 22:48:30 +00:00
Alice Cecile
aa09b6601d
Add basic directional (gamepad) navigation for UI (and non-UI) (#17102)
# Objective

While directional navigation is helpful for UI in general for
accessibility reasons, it is *especially* valuable for a game engine,
where menus may be navigated primarily or exclusively through the use of
a game controller.

Thumb-stick powered cursor-based navigation can work as a fallback, but
is generally a pretty poor user experience. We can do better!

## Prior art

Within Bevy, https://github.com/nicopap/ui-navigation and
https://github.com/rparrett/bevy-alt-ui-navigation-lite exist to solve
this same problem. This isn't yet a complete replacement for that
ecosystem, but hopefully we'll be there for 0.16.

## Solution

UI navigation is complicated, and the right tradeoffs will vary based on
the project and even the individual scene.

We're starting with something simple and flexible, hooking into the
existing `InputFocus` resource, and storing a manually constructed graph
of entities to explore in a `DirectionalNavigationMap` resource. The
developer experience won't be great (so much wiring to do!), but the
tools are all there for a great user experience.

We could have chosen to represent these linkages via component-flavored
not-quite-relations. This would be useful for inspectors, and would give
us automatic cleanup when the entities were despawned, but seriously
complicates the developer experience when building and checking this
API. For now, we're doing a dumb "entity graph in a resource" thing and
`remove` helpers. Once relations are added, we can re-evaluate.

I've decided to use a `CompassOctant` as our key for the possible paths.
This should give users a reasonable amount of precise control without
being fiddly, and playing reasonably nicely with arrow-key navigation.
This design lets us store the set of entities that we're connected to as
a 8-byte array (yay Entity-niching). In theory, this is maybe nicer than
the double indirection of two hashmaps. but if this ends up being slow
we should create benchmarks.

To make this work more pleasant, I've added a few utilities to the
`CompassOctant` type: converting to and from usize, and adding a helper
to find the 180 degrees opposite direction. These have been mirrored
onto `CompassQuadrant` for consistency: they should be generally useful
for game logic.

## Future work

This is a relatively complex initiative! In the hopes of easing review
and avoiding merge conflicts, I've opted to split this work into
bite-sized chunks.

Before 0.16, I'd like to have:

- An example demonstrating gamepad and tab-based navigation in a
realistic game menu
- Helpers to convert axis-based inputs into compass quadrants / octants
- Tools to check the listed graph desiderata
- A helper to build a graph from a grid of entities
- A tool to automatically build a graph given a supplied UI layout

One day, it would be sweet if:

- We had an example demonstrating how to use focus navigation in a
non-UI scene to cycle between game objects
- Standard actions for tab-style and directional navigation with a
first-party bevy_actions integration
- We had a visual debugging tool to display these navigation graphs for
QC purposes
- There was a built-in way to go "up a level" by cancelling the current
action
- The navigation graph is built completely out of relations

## Testing

- tests for the new `CompassQuadrant` / `CompassOctant` methods
- tests for the new directional navigation module

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2025-01-06 18:51:44 +00:00
MichiRecRoom
21c1b6a1e8
Update all previously-merged #![deny(clippy::allow_attributes, clippy::allow_attributes_without_reason)] attributes to include a reason field pointing to the tracking issue (#17136)
# Objective
Ensure the deny lint attributes added as a result of #17111 point to the
tracking issue.

## Solution
Change all existing instances of:
```rust
#![deny(clippy::allow_attributes, clippy::allow_attributes_without_reason)]
```
to
```rust
#![deny(
    clippy::allow_attributes,
    clippy::allow_attributes_without_reason,
    reason = "See #17111; To be removed once all crates are in-line with these attributes"
)]
```

## Testing
N/A
2025-01-06 05:40:08 +00:00
github-actions[bot]
573b980685
Bump Version after Release (#17176)
Bump version after release
This PR has been auto-generated

---------

Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-01-06 00:04:44 +00:00
Benjamin Brienen
7112d5594e
Remove all deprecated code (#16338)
# Objective

Release cycle things

## Solution

Delete items deprecated in 0.15 and migrate bevy itself.

## Testing

CI
2025-01-05 20:33:39 +00:00
Rob Parrett
651b22f31f
Update typos (#17126)
# Objective

Use the latest version of `typos` and fix the typos that it now detects

# Additional Info

By the way, `typos` has a "low priority typo suggestions issue" where we
can throw typos we find that `typos` doesn't catch.

(This link may go stale) https://github.com/crate-ci/typos/issues/1200
2025-01-03 17:44:26 +00:00
Zachary Harrold
0403948aa2
Remove Implicit std Prelude from no_std Crates (#17086)
# Background

In `no_std` compatible crates, there is often an `std` feature which
will allow access to the standard library. Currently, with the `std`
feature _enabled_, the
[`std::prelude`](https://doc.rust-lang.org/std/prelude/index.html) is
implicitly imported in all modules. With the feature _disabled_, instead
the [`core::prelude`](https://doc.rust-lang.org/core/prelude/index.html)
is implicitly imported. This creates a subtle and pervasive issue where
`alloc` items _may_ be implicitly included (if `std` is enabled), or
must be explicitly included (if `std` is not enabled).

# Objective

- Make the implicit imports for `no_std` crates consistent regardless of
what features are/not enabled.

## Solution

- Replace the `cfg_attr` "double negative" `no_std` attribute with
conditional compilation to _include_ `std` as an external crate.
```rust
// Before
#![cfg_attr(not(feature = "std"), no_std)]

// After
#![no_std]

#[cfg(feature = "std")]
extern crate std;
```
- Fix imports that are currently broken but are only now visible with
the above fix.

## Testing

- CI

## Notes

I had previously used the "double negative" version of `no_std` based on
general consensus that it was "cleaner" within the Rust embedded
community. However, this implicit prelude issue likely was considered
when forming this consensus. I believe the reason why is the items most
affected by this issue are provided by the `alloc` crate, which is
rarely used within embedded but extensively used within Bevy.
2025-01-03 01:58:43 +00:00
MichiRecRoom
e2248afb3e
bevy_math: Apply #[deny(clippy::allow_attributes, clippy::allow_attributes_without_reason)] (#17091)
# Objective
We want to deny the following lints:
* `clippy::allow_attributes` - Because there's no reason to
`#[allow(...)]` an attribute if it wouldn't lint against anything; you
should always use `#[expect(...)]`
* `clippy::allow_attributes_without_reason` - Because documenting the
reason for allowing/expecting a lint is always good

## Solution
Set the `clippy::allow_attributes` and
`clippy::allow_attributes_without_reason` lints to `deny`, and bring
`bevy_math` in line with the new restrictions.

No code changes have been made - except if a lint that was previously
`allow(...)`'d could be removed via small code changes. For example,
`unused_variables` can be handled by adding a `_` to the beginning of a
field's name.

## Testing
I ran `cargo clippy`, and received no errors.

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2025-01-02 18:47:36 +00:00
Zachary Harrold
5f42c9ab6d
Fix no_std CI Warnings and WASM Compatibility (#17049)
# Objective

- Resolve several warnings encountered when compiling for `no_std`
around `dead_code`
- Fix compatibility with `wasm32-unknown-unknown` when using `no_std`
(identified by Sachymetsu on
[Discord](https://discord.com/channels/691052431525675048/692572690833473578/1323365426901549097))

## Solution

- Removed some unused imports
- Added `allow(dead_code)` for certain private items when compiling on
`no_std`
- Fixed `bevy_app` and `bevy_tasks` compatibility with WASM when
compiling without `std` by appropriately importing `Box` and feature
gating panic unwinding

## Testing

- CI
2024-12-30 23:01:27 +00:00
Vic
b78efd339d
Simplify sort/max_by calls (#17048)
# Objective

Some sort calls and `Ord` impls are unnecessarily complex.

## Solution

Rewrite the "match on cmp, if equal do another cmp" as either a
comparison on tuples, or `Ordering::then_with`, depending on whether the
compare keys need construction.

`sort_by` -> `sort_by_key` when symmetrical. Do the same for
`min_by`/`max_by`.

Note that `total_cmp` can only work with `sort_by`, and not on tuples.

When sorting collected query results that contain
`Entity`/`MainEntity`/`RenderEntity` in their `QueryData`, with that
`Entity` in the sort key:
stable -> unstable sort (all queried entities are unique)

If key construction is not simple, switch to `sort_by_cached_key` when
possible.

Sorts that are only performed to discover the maximal element are
replaced by `max_by_key`.

Dedicated comparison functions and structs are removed where simple.

Derive `PartialOrd`/`Ord` when useful.

Misc. closure style inconsistencies.

## Testing
- Existing tests.
2024-12-30 22:59:36 +00:00
Zachary Harrold
46af46695b
Add no_std support to bevy_input (#16995)
# Objective

- Contributes to #15460

## Solution

- Added the following features:
  - `std` (default)
  - `smol_str` (default)
  - `portable-atomic`
  - `critical-section`
  - `libm`
- Fixed an existing issue where `bevy_reflect` wasn't properly feature
gated.

## Testing

- CI

## Notes

- There were some minor issues with `bevy_math` and `bevy_ecs` noticed
in this PR which I have also resolved here. I can split these out if
desired, but I've left them here for now as they're very small changes
and I don't consider this PR itself to be very controversial.
- `libm`, `portable-atomic`, and `critical-section` are shortcuts to
enable the relevant features in dependencies, making the usage of this
crate on atomically challenged platforms possible and simpler.
- `smol_str` is gated as it doesn't support atomically challenged
platforms (e.g., Raspberry Pi Pico). I have an issue and a
[PR](https://github.com/rust-analyzer/smol_str/pull/91) to discuss this
upstream.
2024-12-29 22:46:30 +00:00
Benjamin Brienen
8c34f00deb
Fix msrvs (#17012)
# Objective

The rust-versions are out of date.
Fixes #17008

## Solution

Update the values

Cherry-picked from #17006 in case it is controversial

## Testing

Validated locally and in #17006

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-12-29 20:00:19 +00:00
Matty Weatherley
97909df6c0
Refactor non-core Curve methods into extension traits (#16930)
# Objective

The way `Curve` presently achieves dyn-compatibility involves shoving
`Self: Sized` bounds on a bunch of methods to forbid them from appearing
in vtables. (This is called *explicit non-dispatchability*.) The `Curve`
trait probably also just has way too many methods on its own.

In the past, using extension traits instead to achieve similar
functionality has been discussed. The upshot is that this would allow
the "core" of the curve trait, on which all the automatic methods rely,
to live in a very simple dyn-compatible trait, while other functionality
is implemented by extensions. For instance, `dyn Curve<T>` cannot use
the `Sized` methods, but `Box<dyn Curve<T>>` is `Sized`, hence would
automatically implement the extension trait, containing the methods
which are currently non-dispatchable.

Other motivations for this include modularity and code organization: the
`Curve` trait itself has grown quite large with the addition of numerous
adaptors, and refactoring it to demonstrate the separation of
functionality that is already present makes a lot of sense. Furthermore,
resampling behavior in particular is dependent on special traits that
may be mimicked or analogized in user-space, and creating extension
traits to achieve similar behavior in user-space is something we ought
to encourage by example.

## Solution

`Curve` now contains only `domain` and the `sample` methods. 

`CurveExt` has been created, and it contains all adaptors, along with
the other sampling convenience methods (`samples`, `sample_iter`, etc.).
It is implemented for all `C` where `C: Curve<T> + Sized`.

`CurveResampleExt` has been created, and it contains all resampling
methods. It is implemented for all `C` where `C: Curve<T> + ?Sized`.

## Testing

It compiles and `cargo doc` succeeds.

---

## Future work

- Consider writing extension traits for resampling curves in related
domains (e.g. resampling for `Curve<T>` where `T: Animatable` into an
`AnimatableKeyframeCurve`).
- `CurveExt` might be further broken down to separate the adaptor and
sampling methods.

---

## Migration Guide

`Curve` has been refactored so that much of its functionality is now in
extension traits. Adaptors such as `map`, `reparametrize`, `reverse`,
and so on now require importing `CurveExt`, while the resampling methods
`resample_*` require importing `CurveResampleExt`. Both of these new
traits are exported through `bevy::math::curve` and through
`bevy::math::prelude`.
2024-12-29 19:26:49 +00:00
Benjamin Brienen
64efd08e13
Prefer Display over Debug (#16112)
# Objective

Fixes #16104

## Solution

I removed all instances of `:?` and put them back one by one where it
caused an error.

I removed some bevy_utils helper functions that were only used in 2
places and don't add value. See: #11478

## Testing

CI should catch the mistakes

## Migration Guide

`bevy::utils::{dbg,info,warn,error}` were removed. Use
`bevy::utils::tracing::{debug,info,warn,error}` instead.

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
2024-12-27 00:40:06 +00:00
Matty Weatherley
43d5472fda
Easing curves for tuples (#16945)
# Objective

Make it so that users can ease between tuples of easeable values. 

## Solution

Use `variadics_please`'s `all_tuples_enumerated` macro to generate code
that creates these trait implementations. For two elements, the result
looks like this:
```rust
impl<T0: Ease, T1: Ease> Ease for (T0, T1) {
    fn interpolating_curve_unbounded(start: Self, end: Self) -> impl Curve<Self> {
        let curve_tuple = (
            <T0 as Ease>::interpolating_curve_unbounded(start.0, end.0),
            <T1 as Ease>::interpolating_curve_unbounded(start.1, end.1),
        );
        FunctionCurve::new(Interval::EVERYWHERE, move |t| {
            (
                curve_tuple.0.sample_unchecked(t),
                curve_tuple.1.sample_unchecked(t),
            )
        })
    }
}
```

## Testing

It compiles, and I futzed about with some manual examples, which seem to
work as expected.

---

## Showcase

Easing curves now support easing tuples of values that can themselves be
eased. For example:
```rust
// Easing between two `(Vec3, Quat)` values:
let easing_curve = EasingCurve::new(
    (vec3(0.0, 0.0, 0.0), Quat::from_rotation_z(-FRAC_PI_2)),
    (vec3(1.0, 1.0, 1.0), Quat::from_rotation_z(FRAC_PI_2)),
    EaseFunction::ExponentialInOut
);
```
2024-12-24 18:06:08 +00:00
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
Matty Weatherley
35e0b5be00
Make bevy_reflect feature of bevy_math non-default (#16938)
# Objective

bevy_reflect is a big part of bevy_math's dependency footprint, and is
often not useful when using bevy_math standalone (as I often do). The
goal with this PR is to avoid pulling in those dependencies by default
without compromising the usability of bevy_math types within Bevy
proper.

## Solution

`bevy_reflect` has been removed from default features of `bevy_math`.
However, the feature is enabled by `bevy_internal`, so that
`bevy_reflect` is enabled when `bevy_math` is used through `bevy`.

Philosophically, if there were a feature flag toggling reflection on
`bevy` globally, then whether `bevy_math` enabled `bevy_reflect` itself
would depend on that, but that doesn't exist for the time being.

## Testing

It compiles :)

## Migration Guide

`bevy_reflect` has been made a non-default feature of `bevy_math`. (It
is still enabled when `bevy_math` is used through `bevy`.) You may need
to enable this feature if you are using `bevy_math` on its own and
desire for the types it exports to implement `Reflect` and other
reflection traits.
2024-12-24 03:09:36 +00:00
Matty Weatherley
ee9bea1ba9
Use variadics_please to implement StableInterpolate on tuples. (#16931)
# Objective

Now that `variadics_please` has a 1.1 release, we can re-implement the
original solution.

## Solution

Copy-paste the code from the [original
PR](https://github.com/bevyengine/bevy/pull/15931) branch :)
2024-12-24 02:53:43 +00:00
scottmcm
450b939c1f
Fix EaseFunction::Exponential* to exactly hit (0, 0) and (1, 1) (#16910)
And add a bunch of tests to show that all the monotonic easing functions
have roughly the expected shape.

# Objective

The `EaseFunction::Exponential*` variants aren't actually smooth as
currently implemented, because they jump by about 1‰ at the
start/end/both.

- Fixes #16676
- Subsumes #16675

## Solution

This PR slightly tweaks the shifting and scaling of all three variants
to ensure they hit (0, 0) and (1, 1) exactly while gradually
transitioning between them.

Graph demonstration of the new easing function definitions:
<https://www.desmos.com/calculator/qoc5raus2z>

![desmos-graph](https://github.com/user-attachments/assets/c87e9fe5-47d9-4407-9c94-80135eef5908)
(Yes, they look completely identical to the previous ones at that scale.
[Here's a zoomed-in
comparison](https://www.desmos.com/calculator/ken6nk89of) between the
old and the new if you prefer.)

The approach taken was to keep the core 2¹⁰ᵗ shape, but to [ask
WolframAlpha](https://www.wolframalpha.com/input?i=solve+over+the+reals%3A+pow%282%2C+10-A%29+-+pow%282%2C+-A%29%3D+1)
what scaling factor to use such that f(1)-f(0)=1, then shift the curve
down so that goes from zero to one instead of ¹/₁₀₂₃ to ¹⁰²⁴/₁₀₂₃.

## Testing

I've included in this PR a bunch of general tests for all monotonic
easing functions to ensure they hit (0, 0) to (1, 1), that the InOut
functions hit (½, ½), and that they have the expected convexity.

You can also see by inspection that the difference is small. The change
for `exponential_in` is from `exp2(10 * t - 10)` to `exp2(10 * t -
9.99859…) - 0.0009775171…`.

The problem for `exponential_in(0)` is also simple to see without a
calculator: 2⁻¹⁰ is obviously not zero, but with the new definition
`exp2(-LOG2_1023) - FRAC_1_1023` => `1/(exp2(LOG2_1023)) - FRAC_1_1023`
=> `FRAC_1_1023 - FRAC_1_1023` => `0`.


---

## Migration Guide

This release of bevy slightly tweaked the definitions of
`EaseFunction::ExponentialIn`, `EaseFunction::ExponentialOut`, and
`EaseFunction::ExponentialInOut`. The previous definitions had small
discontinuities, while the new ones are slightly rescaled to be
continuous. For the output values that changed, that change was less
than 0.001, so visually you might not even notice the difference.

However, if you depended on them for determinism, you'll need to define
your own curves with the previous definitions.

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-12-24 02:44:04 +00:00
Matty Weatherley
ac1faf073f
f32 -> Rot2 in bounding volume docs (#16848)
This is the correct rotation type :)
2024-12-17 00:12:49 +00:00