Commit graph

4490 commits

Author SHA1 Message Date
Cameron
01649f13e2
Refactor App and SubApp internals for better separation (#9202)
# Objective

This is a necessary precursor to #9122 (this was split from that PR to
reduce the amount of code to review all at once).

Moving `!Send` resource ownership to `App` will make it unambiguously
`!Send`. `SubApp` must be `Send`, so it can't wrap `App`.

## Solution

Refactor `App` and `SubApp` to not have a recursive relationship. Since
`SubApp` no longer wraps `App`, once `!Send` resources are moved out of
`World` and into `App`, `SubApp` will become unambiguously `Send`.

There could be less code duplication between `App` and `SubApp`, but
that would break `App` method chaining.

## Changelog

- `SubApp` no longer wraps `App`.
- `App` fields are no longer publicly accessible.
- `App` can no longer be converted into a `SubApp`.
- Various methods now return references to a `SubApp` instead of an
`App`.
## Migration Guide

- To construct a sub-app, use `SubApp::new()`. `App` can no longer
convert into `SubApp`.
- If you implemented a trait for `App`, you may want to implement it for
`SubApp` as well.
- If you're accessing `app.world` directly, you now have to use
`app.world()` and `app.world_mut()`.
- `App::sub_app` now returns `&SubApp`.
- `App::sub_app_mut`  now returns `&mut SubApp`.
- `App::get_sub_app` now returns `Option<&SubApp>.`
- `App::get_sub_app_mut` now returns `Option<&mut SubApp>.`
2024-03-31 03:16:10 +00:00
Eero Lehtinen
70c69cdd51
Fix crash on Linux Nvidia 550 driver (#12542)
# Objective

Fix crashing on Linux with latest stable Nvidia 550 driver when
resizing. The crash happens at startup with some setups.

Fixes #12199

I think this would be nice to get into 0.13.1

## Solution

Ignore `wgpu::SurfaceError::Outdated` always on this platform+driver.

It looks like Nvidia considered the previous behaviour of not returning
this error a bug:
"Fixed a bug where vkAcquireNextImageKHR() was not returning
VK_ERROR_OUT_OF_DATE_KHR when it should with WSI X11 swapchains"
(https://www.nvidia.com/Download/driverResults.aspx/218826/en-us/)

What I gather from this is that the surface was outdated on previous
drivers too, but they just didn't report it as an error. So behaviour
shouldn't change.

In the issue conversation we experimented with calling `continue` when
this error happens, but I found that it results in some small issues
like bevy_egui scale not updating with the window sometimes. Just doing
nothing seems to work better.

## Changelog

- Fixed crashing on Linux with Nvidia 550 driver when resizing the
window

## Migration Guide

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-30 23:10:54 +00:00
BeastLe9enD
eb44db4437
Add AsyncSeek trait to Reader to be able to seek inside asset loaders (#12547)
# Objective

For some asset loaders, it can be useful not to read the entire asset
file and just read a specific region of a file. For this, we need a way
to seek at a specific position inside the file

## Solution

I added support for `AsyncSeek` to `Reader`. In my case, I want to only
read a part of a file, and for that I need to seek to a specific point.

## Migration Guide

Every custom reader (which previously only needed the `AsyncRead` trait
implemented) now also needs to implement the `AsyncSeek` trait to add
the seek capability.
2024-03-30 22:26:30 +00:00
Fpgu
cdecd39e31
Remove InstanceId when Scene Despawn (#12778)
# Objective

- Fix #12746
- When users despawn a scene, the `InstanceId` within `spawned_scenes`
and `spawned_dynamic_scenes` is not removed, causing a potential memory
leak

## Solution

- `spawned_scenes` field was never used, and I removed it
- Add a component remove hook for `Handle<DynamicScene>`, and when the
`Handle<DynamicScene>` component is removed, delete the corresponding
`InstanceId` from `spawned_dynamic_scenes`
2024-03-30 22:16:49 +00:00
Verte
97f0555cb0
Remove VectorSpace impl on Quat (#12796)
- Fixes #[12762](https://github.com/bevyengine/bevy/issues/12762).

## Migration Guide

- `Quat` no longer implements `VectorSpace` as unit quaternions don't
actually form proper vector spaces. If you're absolutely certain that
what you're doing is correct, convert the `Quat` into a `Vec4` and
perform the operations before converting back.
2024-03-30 17:18:52 +00:00
James Liu
286bc8cce5
Store only the IDs needed for Query iteration (#12476)
# Objective
Other than the exposed functions for reading matched tables and
archetypes, a `QueryState` does not actually need both internal Vecs for
storing matched archetypes and tables. In practice, it will only use one
of the two depending on if it uses dense or archetypal iteration.

Same vein as #12474. The goal is to reduce the memory overhead of using
queries, which Bevy itself, ecosystem plugins, and end users are already
fairly liberally using.

## Solution
Add `StorageId`, which is a union over `TableId` and `ArchetypeId`, and
store only one of the two at runtime. Read the slice as if it was one ID
depending on whether the query is dense or not.

This follows in the same vein as #5085; however, this one directly
impacts heap memory usage at runtime, while #5085 primarily targeted
transient pointers that might not actually exist at runtime.

---

## Changelog
Changed: `QueryState::matched_tables` now returns an iterator instead of
a reference to a slice.
Changed: `QueryState::matched_archetypes` now returns an iterator
instead of a reference to a slice.

## Migration Guide
`QueryState::matched_tables` and `QueryState::matched_archetypes` does
not return a reference to a slice, but an iterator instead. You may need
to use iterator combinators or collect them into a Vec to use it as a
slice.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-30 10:15:55 +00:00
James Liu
24030d2a0c
Vectorize reset_view_visibility (#12797)
# Objective
Speed up CPU-side rendering.

## Solution
Use `QueryIter::for_each` and `Mut::bypass_change_detection` to minimize
the total amount of data being written and allow autovectorization to
speed up iteration.

## Performance
Tested against the default `many_cubes`, this results in greater than
15x speed up: 281us -> 18.4us.

![image](https://github.com/bevyengine/bevy/assets/3137680/18369285-843e-4eb6-9716-c99c6f5ea4e2)

As `ViewVisibility::HIDDEN` just wraps false, this is likely just
degenerating into `memset(0)`s on the tables.
2024-03-30 08:28:16 +00:00
Patrick Walton
4dadebd9c4
Improve performance by binning together opaque items instead of sorting them. (#12453)
Today, we sort all entities added to all phases, even the phases that
don't strictly need sorting, such as the opaque and shadow phases. This
results in a performance loss because our `PhaseItem`s are rather large
in memory, so sorting is slow. Additionally, determining the boundaries
of batches is an O(n) process.

This commit makes Bevy instead applicable place phase items into *bins*
keyed by *bin keys*, which have the invariant that everything in the
same bin is potentially batchable. This makes determining batch
boundaries O(1), because everything in the same bin can be batched.
Instead of sorting each entity, we now sort only the bin keys. This
drops the sorting time to near-zero on workloads with few bins like
`many_cubes --no-frustum-culling`. Memory usage is improved too, with
batch boundaries and dynamic indices now implicit instead of explicit.
The improved memory usage results in a significant win even on
unbatchable workloads like `many_cubes --no-frustum-culling
--vary-material-data-per-instance`, presumably due to cache effects.

Not all phases can be binned; some, such as transparent and transmissive
phases, must still be sorted. To handle this, this commit splits
`PhaseItem` into `BinnedPhaseItem` and `SortedPhaseItem`. Most of the
logic that today deals with `PhaseItem`s has been moved to
`SortedPhaseItem`. `BinnedPhaseItem` has the new logic.

Frame time results (in ms/frame) are as follows:

| Benchmark                | `binning` | `main`  | Speedup |
| ------------------------ | --------- | ------- | ------- |
| `many_cubes -nfc -vpi` | 232.179     | 312.123   | 34.43%  |
| `many_cubes -nfc`        | 25.874 | 30.117 | 16.40%  |
| `many_foxes`             | 3.276 | 3.515 | 7.30%   |

(`-nfc` is short for `--no-frustum-culling`; `-vpi` is short for
`--vary-per-instance`.)

---

## Changelog

### Changed

* Render phases have been split into binned and sorted phases. Binned
phases, such as the common opaque phase, achieve improved CPU
performance by avoiding the sorting step.

## Migration Guide

- `PhaseItem` has been split into `BinnedPhaseItem` and
`SortedPhaseItem`. If your code has custom `PhaseItem`s, you will need
to migrate them to one of these two types. `SortedPhaseItem` requires
the fewest code changes, but you may want to pick `BinnedPhaseItem` if
your phase doesn't require sorting, as that enables higher performance.

## Tracy graphs

`many-cubes --no-frustum-culling`, `main` branch:
<img width="1064" alt="Screenshot 2024-03-12 180037"
src="https://github.com/bevyengine/bevy/assets/157897/e1180ce8-8e89-46d2-85e3-f59f72109a55">

`many-cubes --no-frustum-culling`, this branch:
<img width="1064" alt="Screenshot 2024-03-12 180011"
src="https://github.com/bevyengine/bevy/assets/157897/0899f036-6075-44c5-a972-44d95895f46c">

You can see that `batch_and_prepare_binned_render_phase` is a much
smaller fraction of the time. Zooming in on that function, with yellow
being this branch and red being `main`, we see:

<img width="1064" alt="Screenshot 2024-03-12 175832"
src="https://github.com/bevyengine/bevy/assets/157897/0dfc8d3f-49f4-496e-8825-a66e64d356d0">

The binning happens in `queue_material_meshes`. Again with yellow being
this branch and red being `main`:
<img width="1064" alt="Screenshot 2024-03-12 175755"
src="https://github.com/bevyengine/bevy/assets/157897/b9b20dc1-11c8-400c-a6cc-1c2e09c1bb96">

We can see that there is a small regression in `queue_material_meshes`
performance, but it's not nearly enough to outweigh the large gains in
`batch_and_prepare_binned_render_phase`.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-30 02:55:02 +00:00
Patrick Walton
5b746d2b19
Pack the StandardMaterialKey into a single scalar instead of a structure. (#12783)
This commit changes the `StandardMaterialKey` to be based on a set of
bitflags instead of a structure. We hash it every frame for every mesh,
and `#[derive(Hash)]` doesn't generate particularly efficient code for
large structures full of small types. Packing it into a single `u64`
therefore results in a roughly 10% speedup in `queue_material_meshes` on
`many_cubes --no-frustum-culling`.

![Screenshot 2024-03-29
075124](https://github.com/bevyengine/bevy/assets/157897/78afcab6-b616-489b-8243-da9a117f606c)
2024-03-29 18:34:27 +00:00
Martin Svanberg
fee824413f
Support wireframes for 2D meshes (#12135)
# Objective

Wireframes are currently supported for 3D meshes using the
`WireframePlugin` in `bevy_pbr`. This PR adds the same functionality for
2D meshes.

Closes #5881.

## Solution

Since there's no easy way to share material implementations between 2D,
3D, and UI, this is mostly a straight copy and rename from the original
plugin into `bevy_sprite`.

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/3961616/7aca156f-448a-4c7e-89b8-0a72c5919769">

---

## Changelog

- Added `Wireframe2dPlugin` and related types to support 2D wireframes.
- Added an example to demonstrate how to use 2D wireframes

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2024-03-29 18:34:04 +00:00
UkoeHB
5357e15966
Add Clone to WinitSettings (#12787)
# Objective

- Allow cloning `WinitSettings`. I use this in
[bevy_worldswap](https://github.com/UkoeHB/bevy_worldswap) when
synchronizing secondary app window state.

## Solution

- Add `Clone` to `WinitSettings`.

---

## Changelog

- Added `Clone` to `WinitSettings`.
2024-03-29 17:24:11 +00:00
UkoeHB
61b4b38ad0
Move accessibility setup to accessibility module (#12784)
# Objective

- Reduce the size of `create_windows` and isolate accessibility setup
logic.

## Solution

- Move accessibility setup for new windows to the `accessibility`
module.

## Comments

This is a small refactor, no behavior changes.
2024-03-29 16:02:25 +00:00
s-puig
7363268ea8
Fix ambiguities causing a crash (#12780)
# Objective

- Disabling some plugins causes a crash due to ambiguities relying in
feature flags and not checking if both plugins are enabled causing code
like this to crash:

`app.add_plugins(DefaultPlugins.build().disable::<AnimationPlugin>())`

## Solution

- Check if plugins were added before ambiguities.
- Move bevy_gizmos ambiguities from bevy_internal to bevy_gizmos since
they already depend on them.
2024-03-29 16:00:13 +00:00
James Liu
a6e37e7a2a
Add QueryState::contains, document complexity, and make as_nop pub(crate) (#12776)
# Objective
Fixes #12752. Fixes #12750. Document the runtime complexity of all of
the `O(1)` operations on the individual APIs.

## Solution

  * Mirror `Query::contains` onto `QueryState::contains`
  * Make `QueryState::as_nop` pub(crate)
  * Make `NopWorldQuery` pub(crate)
  * Document all of the O(1) operations on Query and QueryState.
2024-03-29 14:49:43 +00:00
James Liu
476e296561
Implement Clone for ManualEventReader (#12777)
# Objective
Fix #12764.

## Solution
Implement Clone for the type.
2024-03-29 14:49:13 +00:00
James Liu
e62a01f403
Make PersistentGpuBufferable a safe trait (#12744)
# Objective
Fixes #12727. All parts that `PersistentGpuBuffer` interact with should
be 100% safe both on the CPU and the GPU: `Queue::write_buffer_with`
zeroes out the slice being written to and when uploading to the GPU, and
all slice writes are bounds checked on the CPU side.

## Solution
Make `PersistentGpuBufferable` a safe trait. Enforce it's correct
implementation via assertions. Re-enable `forbid(unsafe_code)` on
`bevy_pbr`.
2024-03-29 13:14:34 +00:00
Charles Bournhonesque
afff818e5c
Update the Children component of the parent entity when a scene gets deleted (#12710)
# Objective

- A scene usually gets created using the `SceneBundle` or
`DynamicSceneBundle`. This means that the scene's entities get added as
children of the root entity (the entity on which the `SceneBundle` gets
added)
- When the scene gets deleted using the `SceneSpawner`, the scene's
entities are deleted, but the `Children` component of the root entity
doesn't get updated. This means that the hierarchy becomes unsound, with
Children linking to non-existing components.

## Solution

- Update the `despawn_sync` logic to also update the `Children` from any
parents of the scene, if there are any
- Adds a test where a Scene gets despawned and checks for dangling
Children references on the parent. The test fails on `main` but works
here.

## Alternative implementations

- One option could be to add a `parent: Option<Entity>` on the
[InstanceInfo](df15cd7dcc/crates/bevy_scene/src/scene_spawner.rs (L27))
struct that tracks if the SceneInstance was added as a child of a root
entity
2024-03-29 13:13:32 +00:00
Matty
bcdb20d4f3
Fix Triangle2d/Triangle3d interior sampling to correctly follow triangle (#12766)
# Objective

When I wrote #12747 I neglected to translate random samples from
triangles back to the point where they originated, so they would be
sampled near the origin instead of at the actual triangle location.

## Solution

Translate by the first vertex location so that the samples follow the
actual triangle.
2024-03-29 13:10:23 +00:00
James Liu
741803d8c9
Implement QueryData for &Archetype and EntityLocation (#12398)
# Objective
Fixes #12392, fixes #12393, and fixes #11387. Implement QueryData for
Archetype and EntityLocation.

## Solution
Add impls for both of the types.

---

## Changelog
Added: `&Archetype` now implements `QueryData`
Added: `EntityLocation` now implements `QueryData`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-29 06:41:01 +00:00
Martín Maita
1b7837c0b2
Update image requirement from 0.24 to 0.25 (#12458)
# Objective

- Closes https://github.com/bevyengine/bevy/pull/12415

## Solution

- Refactored code that was changed/deprecated in `image` 0.25.
- Please review this PR carefully since I'm just making the changes
without any context or deep knowledge of the module.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-29 06:40:09 +00:00
James Liu
f0de7620b0
Fix unhandled null characters in Android logs (#12743)
# Objective
Fix #12728. Fix unsoundnesss from unhandled null characters in Android
logs.

## Solution
Use `CString` instead of using formatted Strings. Properly document the
safety invariants of the FFI call.
2024-03-29 03:04:46 +00:00
Gabriel Kwong
d8383fb535
Move PanicHandlerPlugin into bevy_app (#12640)
# Objective

- Move `PanicHandlerPlugin` into `bevy_app`
- Fixes #12603 .

## Solution

- I moved the `bevy_panic_handler` into `bevy_app`
- Copy pasted `bevy_panic_handler`'s lib.rs into a separate module in
`bevy_app` as a `panic_handler.rs` module file and added the
`PanicHandlerPlugin` in lib.rs of `bevy_app`
- added the dependency into `cargo.toml` 

## Review notes

- I probably want some feedback if I imported App and Plugin correctly
in `panic_handler.rs` line 10 and 11.
- As of yet I have not deleted `bevy_panic_handler` crate, wanted to get
a check if I added it correctly.
- Once validated that my move was correct, I'll probably have to remove
the panic handler find default plugins which I probably need some help
to find.
- And then remove bevy panic_handler and making sure ci passes.
- This is my first issue for contributing to bevy so let me know if I am
doing anything wrong.


## tools context
- rust is 1.76 version
- Windows 11

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-29 02:04:56 +00:00
UkoeHB
c971b45361
Clean up WinitWindows::remove_window (#12749)
# Objective

- Avoid unbounded HashMap growth for opening/closing windows.

## Solution

- Remove map entry in `WinitWindows::remove_window`.

## Migration Guide

- `WinitWindows::get_window_entity` now returns `None` after a window is
closed, instead of a dead entity.

---

## Comments

The comment this PR replaces was added in
https://github.com/bevyengine/bevy/pull/3575. Since `get_window_entity`
now returns an `Entity` instead of a `WindowId`, this no longer seems
useful. Note that `get_window_entity` is only used
[here](56bcbb0975/crates/bevy_winit/src/lib.rs (L436)),
immediately followed by a warning if the entity returned doesn't exist.
2024-03-29 01:37:13 +00:00
Remi Godin
c223fbb4c8
updated audio_source.rs documentation (#12765)
# Objective
- Fixes #12677 

## Solution
Updated documentation to make it explicit that enabling the appropriate
optional features is required to use the supported audio file format, as
well as provided link to the Bevy docs listing the optional features.

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-28 19:10:09 +00:00
Testare
1619d42e78
Add Debug to Has Query type (#12722)
# Objective

Pretty minor change to add `Debug` to `Has`.

This is helpful for users (Like me) who have the
[`missing_debug_implementations`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/builtin/static.MISSING_DEBUG_IMPLEMENTATIONS.html)
lint turned on.

## Solution

Simple `#[derive(Debug)]`

## Changelog
* Has now implemented `Debug`
2024-03-28 18:31:50 +00:00
andriyDev
77de9a5beb
Allow converting mutable handle borrows to AssetId. (#12759)
## Problem

- A mutable borrow of a handle cannot be directly turned into an AssetId
with `.into()`. You must do a reborrow `&*my_handle`.

## Solution

- Add an impl for From<&mut Handle> to AssetId and UntypedAssetId.
2024-03-28 15:53:26 +00:00
Matty
f924b4d9ef
Move Point out of cubic splines module and expand it (#12747)
# Objective

Previously, the `Point` trait, which abstracts all of the operations of
a real vector space, was sitting in the submodule of `bevy_math` for
cubic splines. However, the trait has broader applications than merely
cubic splines, and we should use it when possible to avoid code
duplication when performing vector operations.

## Solution

`Point` has been moved into a new submodule in `bevy_math` named
`common_traits`. Furthermore, it has been renamed to `VectorSpace`,
which is more descriptive, and an additional trait `NormedVectorSpace`
has been introduced to expand the API to cover situations involving
geometry in addition to algebra. Additionally, `VectorSpace` itself now
requires a `ZERO` constant and `Neg`. It also supports a `lerp` function
as an automatic trait method.

Here is what that looks like:
```rust
/// A type that supports the mathematical operations of a real vector space, irrespective of dimension.
/// In particular, this means that the implementing type supports:
/// - Scalar multiplication and division on the right by elements of `f32`
/// - Negation
/// - Addition and subtraction
/// - Zero
///
/// Within the limitations of floating point arithmetic, all the following are required to hold:
/// - (Associativity of addition) For all `u, v, w: Self`, `(u + v) + w == u + (v + w)`.
/// - (Commutativity of addition) For all `u, v: Self`, `u + v == v + u`.
/// - (Additive identity) For all `v: Self`, `v + Self::ZERO == v`.
/// - (Additive inverse) For all `v: Self`, `v - v == v + (-v) == Self::ZERO`.
/// - (Compatibility of multiplication) For all `a, b: f32`, `v: Self`, `v * (a * b) == (v * a) * b`.
/// - (Multiplicative identity) For all `v: Self`, `v * 1.0 == v`.
/// - (Distributivity for vector addition) For all `a: f32`, `u, v: Self`, `(u + v) * a == u * a + v * a`.
/// - (Distributivity for scalar addition) For all `a, b: f32`, `v: Self`, `v * (a + b) == v * a + v * b`.
///
/// Note that, because implementing types use floating point arithmetic, they are not required to actually
/// implement `PartialEq` or `Eq`.
pub trait VectorSpace:
    Mul<f32, Output = Self>
    + Div<f32, Output = Self>
    + Add<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Neg
    + Default
    + Debug
    + Clone
    + Copy
{
    /// The zero vector, which is the identity of addition for the vector space type.
    const ZERO: Self;

    /// Perform vector space linear interpolation between this element and another, based
    /// on the parameter `t`. When `t` is `0`, `self` is recovered. When `t` is `1`, `rhs`
    /// is recovered.
    ///
    /// Note that the value of `t` is not clamped by this function, so interpolating outside
    /// of the interval `[0,1]` is allowed.
    #[inline]
    fn lerp(&self, rhs: Self, t: f32) -> Self {
        *self * (1. - t) + rhs * t
    }
}
```
```rust
/// A type that supports the operations of a normed vector space; i.e. a norm operation in addition
/// to those of [`VectorSpace`]. Specifically, the implementor must guarantee that the following
/// relationships hold, within the limitations of floating point arithmetic:
/// - (Nonnegativity) For all `v: Self`, `v.norm() >= 0.0`.
/// - (Positive definiteness) For all `v: Self`, `v.norm() == 0.0` implies `v == Self::ZERO`.
/// - (Absolute homogeneity) For all `c: f32`, `v: Self`, `(v * c).norm() == v.norm() * c.abs()`.
/// - (Triangle inequality) For all `v, w: Self`, `(v + w).norm() <= v.norm() + w.norm()`.
///
/// Note that, because implementing types use floating point arithmetic, they are not required to actually
/// implement `PartialEq` or `Eq`.
pub trait NormedVectorSpace: VectorSpace {
    /// The size of this element. The return value should always be nonnegative.
    fn norm(self) -> f32;

    /// The squared norm of this element. Computing this is often faster than computing
    /// [`NormedVectorSpace::norm`].
    #[inline]
    fn norm_squared(self) -> f32 {
        self.norm() * self.norm()
    }

    /// The distance between this element and another, as determined by the norm.
    #[inline]
    fn distance(self, rhs: Self) -> f32 {
        (rhs - self).norm()
    }

    /// The squared distance between this element and another, as determined by the norm. Note that
    /// this is often faster to compute in practice than [`NormedVectorSpace::distance`].
    #[inline]
    fn distance_squared(self, rhs: Self) -> f32 {
        (rhs - self).norm_squared()
    }
}
```

Furthermore, this PR also demonstrates the use of the
`NormedVectorSpace` combined API to implement `ShapeSample` for
`Triangle2d` and `Triangle3d` simultaneously. Such deduplication is one
of the drivers for developing these APIs.

---

## Changelog

- `Point` from `cubic_splines` becomes `VectorSpace`, exported as
`bevy::math::VectorSpace`.
- `VectorSpace` requires `Neg` and `VectorSpace::ZERO` in addition to
its existing prerequisites.
- Introduced public traits `bevy::math::NormedVectorSpace` for generic
geometry tasks involving vectors.
- Implemented `ShapeSample` for `Triangle2d` and `Triangle3d`.

## Migration Guide

Since `Point` no longer exists, any projects using it must switch to
`bevy::math::VectorSpace`. Additionally, third-party implementations of
this trait now require the `Neg` trait; the constant `VectorSpace::ZERO`
must be provided as well.

---

## Discussion

### Design considerations

Originally, the `NormedVectorSpace::norm` method was part of a separate
trait `Normed`. However, I think that was probably too broad and, more
importantly, the semantics of having it in `NormedVectorSpace` are much
clearer.

As it currently stands, the API exposed here is pretty minimal, and
there is definitely a lot more that we could do, but there are more
questions to answer along the way. As a silly example, we could
implement `NormedVectorSpace::length` as an alias for
`NormedVectorSpace::norm`, but this overlaps with methods in all of the
glam types, so we would want to make sure that the implementations are
effectively identical (for what it's worth, I think they are already).

### Future directions

One example of something that could belong in the `NormedVectorSpace`
API is normalization. Actually, such a thing previously existed on this
branch before I decided to shelve it because of concerns with namespace
collision. It looked like this:
```rust
/// This element, but normalized to norm 1 if possible. Returns an error when the reciprocal of
/// the element's norm is not finite.
#[inline]
#[must_use]
fn normalize(&self) -> Result<Self, NonNormalizableError> {
    let reciprocal = 1.0 / self.norm();
    if reciprocal.is_finite() {
        Ok(*self * reciprocal)
    } else {
        Err(NonNormalizableError { reciprocal })
    }
}

/// An error indicating that an element of a [`NormedVectorSpace`] was non-normalizable due to having 
/// non-finite norm-reciprocal.
#[derive(Debug, Error)]
#[error("Element with norm reciprocal {reciprocal} cannot be normalized")]
pub struct NonNormalizableError {
    reciprocal: f32
}
```

With this kind of thing in hand, it might be worth considering
eventually making the passage from vectors to directions fully generic
by employing a wrapper type. (Of course, for our concrete types, we
would leave the existing names in place as aliases.) That is, something
like:
```rust
pub struct NormOne<T>
where T: NormedVectorSpace { //... }
```

Utterly separately, the reason that I implemented `ShapeSample` for
`Triangle2d`/`Triangle3d` was to prototype uniform sampling of abstract
meshes, so that's also a future direction.

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-03-28 13:40:26 +00:00
Charles Bournhonesque
760c645de1
Fix TypeRegistry use in dynamic scene (#12715)
Adopted from and closes https://github.com/bevyengine/bevy/pull/9914 by
@djeedai


# Objective
Fix the use of `TypeRegistry` instead of `TypeRegistryArc` in dynamic
scene and its serializer.

Rename `DynamicScene::serialize_ron()` into `serialize()` to highlight
the fact this is not about serializing to RON specifically, but rather
about serializing to the official Bevy scene format (`.scn` /
`.scn.ron`) which the `SceneLoader` can deserialize (and which happens
to be based in RON, but that not the object here). Also make the link
with the documentation of `SceneLoader` so users understand the full
serializing cycle of a Bevy dynamic scene.

Document `SceneSerializer` with an example showing how to serialize to a
custom format (here: RON), which is easily transposed to serializing
into any other format.

Fixes #9520
 
## Changelog
### Changed
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. ([SceneSerializer
needlessly uses specifically
&TypeRegistryArc #9520](https://github.com/bevyengine/bevy/issues/9520))
* `DynamicScene::serialize_ron()` was renamed to `serialize()`.
 
## Migration Guide
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. You can upgrade by
getting the former from the latter with `TypeRegistryArc::read()`,
_e.g._
  ```diff
    let registry_arc: TypeRegistryArc = [...];
  - let serializer = SceneSerializer(&scene, &registry_arc);
  + let registry = registry_arc.read();
  + let serializer = SceneSerializer(&scene, &registry);
  ```
* Rename `DynamicScene::serialize_ron()` to `serialize()`.

---------

Co-authored-by: Jerome Humbert <djeedai@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-28 03:09:31 +00:00
mamekoro
6840f95d62
Implement From<Vec2> for AspectRatio (#12754)
# Objective
Since it is common to store a pair of width and height as `Vec2`, it
would be useful to have an easy way to instantiate `AspectRatio` from
`Vec2`.

## Solution
Add `impl From<Vec2> for AspectRatio`.

---

## Changelog
- Added `impl From<Vec2> for AspectRatio`
2024-03-27 22:32:31 +00:00
Vitaliy Sapronenko
c38e2d037d
Math tests fix (#12748)
# Objective

Fixes `cargo test -p bevy_math` as in #12729.

## Solution

As described in
[message](https://github.com/bevyengine/bevy/issues/12729#issuecomment-2022197944)
Added workaround `bevy_math = { path = ".", version = "0.14.0-dev",
features = ["approx"] }` to `bevy_math`'s `dev-dependencies`

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-03-27 20:48:20 +00:00
Jacques Schutte
4508077297
Move FloatOrd into bevy_math (#12732)
# Objective

- Fixes #12712

## Solution

- Move the `float_ord.rs` file to `bevy_math`
- Change any `bevy_utils::FloatOrd` statements to `bevy_math::FloatOrd`

---

## Changelog

- Moved `FloatOrd` from `bevy_utils` to `bevy_math`

## Migration Guide

- References to `bevy_utils::FloatOrd` should be changed to
`bevy_math::FloatOrd`
2024-03-27 18:30:11 +00:00
James Liu
56bcbb0975
Forbid unsafe in most crates in the engine (#12684)
# Objective
Resolves #3824. `unsafe` code should be the exception, not the norm in
Rust. It's obviously needed for various use cases as it's interfacing
with platforms and essentially running the borrow checker at runtime in
the ECS, but the touted benefits of Bevy is that we are able to heavily
leverage Rust's safety, and we should be holding ourselves accountable
to that by minimizing our unsafe footprint.

## Solution
Deny `unsafe_code` workspace wide. Add explicit exceptions for the
following crates, and forbid it in almost all of the others.

* bevy_ecs - Obvious given how much unsafe is needed to achieve
performant results
* bevy_ptr - Works with raw pointers, even more low level than bevy_ecs.
 * bevy_render - due to needing to integrate with wgpu
 * bevy_window - due to needing to integrate with raw_window_handle
* bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved
into bevy_ecs instead of made publicly usable.
 * bevy_reflect - Required for the unsafe type casting it's doing.
 * bevy_transform - for the parallel transform propagation
 * bevy_gizmos  - For the SystemParam impls it has.
* bevy_assets - To support reflection. Might not be required, not 100%
sure yet.
* bevy_mikktspace - due to being a conversion from a C library. Pending
safe rewrite.
* bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading
nature.

Several uses of unsafe were rewritten, as they did not need to be using
them:

* bevy_text - a case of `Option::unchecked` could be rewritten as a
normal for loop and match instead of an iterator.
* bevy_color - the Pod/Zeroable implementations were replaceable with
bytemuck's derive macros.
2024-03-27 03:30:08 +00:00
Kanabenki
025e8e639c
Fix Ord and PartialOrd differing for FloatOrd and optimize implementation (#12711)
# Objective

- `FloatOrd` currently has a different comparison behavior between its
derived `PartialOrd` impl and manually implemented `Ord` impl (The
[`Ord` doc](https://doc.rust-lang.org/std/cmp/trait.Ord.html) says this
is a logic error). This might be a problem for some `std`
containers/algorithms if they rely on both matching, and a footgun for
Bevy users.

## Solution

- Replace the `PartialEq` and `Ord` impls of `FloatOrd` with some
equivalent ones producing [better
assembly.](https://godbolt.org/z/jaWbjnMKx)
- Manually derive `PartialOrd` with the same behavior as `Ord`,
implement the comparison operators.
- Add some tests.

I first tried using a match-based implementation similar to the
`PartialOrd` impl [of the
std](https://doc.rust-lang.org/src/core/cmp.rs.html#1457) (with added
NaN ordering) but I couldn't get it to produce non-branching assembly.
The current implementation is based on [the one from the `ordered_float`
crate](3641f59e31/src/lib.rs (L121)),
adapted since it uses a different ordering. Should this be mentionned
somewhere in the code?

---

## Changelog

### Fixed

- `FloatOrd` now uses the same ordering for its `PartialOrd` and `Ord`
implementations.

## Migration Guide

- If you were depending on the `PartialOrd` behaviour of `FloatOrd`, it
has changed from matching `f32` to matching `FloatOrd`'s `Ord` ordering,
never returning `None`.
2024-03-27 00:26:56 +00:00
Gino Valente
0265436fff
bevy_reflect: Rename UntypedReflectDeserializer to ReflectDeserializer (#12721)
# Objective

We have `ReflectSerializer` and `TypedReflectSerializer`. The former is
the one users will most often use since the latter takes a bit more
effort to deserialize.

However, our deserializers are named `UntypedReflectDeserializer` and
`TypedReflectDeserializer`. There is no obvious indication that
`UntypedReflectDeserializer` must be used with `ReflectSerializer` since
the names don't quite match up.

## Solution

Rename `UntypedReflectDeserializer` back to `ReflectDeserializer`
(initially changed as part of #5723).

Also update the docs for both deserializers (as they were pretty out of
date) and include doc examples.

I also updated the docs for the serializers, too, just so that
everything is consistent.

---

## Changelog

- Renamed `UntypedReflectDeserializer` to `ReflectDeserializer`
- Updated docs for `ReflectDeserializer`, `TypedReflectDeserializer`,
`ReflectSerializer`, and `TypedReflectSerializer`

## Migration Guide

`UntypedReflectDeserializer` has been renamed to `ReflectDeserializer`.
Usages will need to be updated accordingly.

```diff
- let reflect_deserializer = UntypedReflectDeserializer::new(&registry);
+ let reflect_deserializer = ReflectDeserializer::new(&registry);
```
2024-03-26 19:58:29 +00:00
Mateusz Wachowiak
e6b5f0574e
rename debug_overlay to ui_debug_overlay in bevy_dev_tools (#12737)
# Objective

- Be more explicit in the name of the module for the ui debug overlay
- Avoid confusion and possible overlap with new overlays

## Solution

- Rename `debug_overlay` to `ui_debug_overlay`
2024-03-26 19:40:55 +00:00
Charles Bournhonesque
b7ab1466c7
Add entity id to hierarchy propagation error message (#12733)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/12731


## Solution

- Use the `Name` component if present, else default to `Entity 0v1`
instead of `An entity`
2024-03-26 15:20:21 +00:00
James Liu
a0f492b2dd
Fix CI for wasm atomics (#12730)
# Objective
CI is currently broken because of `DiagnosticsRecorder` not being Send
and Sync as required by Resource.

## Solution
Wrap `DiagnosticsRecorder` internally with a `WgpuWrapper`.
2024-03-26 14:26:21 +00:00
Jakub Marcowski
31d91466b4
Add Annulus primitive to bevy_math::primitives (#12706)
# Objective

- #10572

There is no 2D primitive available for the common shape of an annulus
(ring).

## Solution

This PR introduces a new type to the existing math primitives:

- `Annulus`: the region between two concentric circles

---

## Changelog

### Added

- `Annulus` primitive to the `bevy_math` crate
- `Annulus` tests (`diameter`, `thickness`, `area`, `perimeter` and
`closest_point` methods)

---------

Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-03-25 23:13:14 +00:00
mamekoro
cb9789bc35
Remove unnecessary executable flags from Rust source files (#12707)
# Objective
I found that some .rs files are unnecessarily executable.

Rust source files may start with a shebang-like statement `#!`, so let's
make sure they are not executable just in case.

Here is the result of the `find` commend that lists executable .rs files
as of main branch `86bd648`.
```console
$ find -name \*.rs -type f -executable
./crates/bevy_gizmos/src/lib.rs
./crates/bevy_tasks/src/lib.rs
./crates/bevy_time/src/lib.rs
./crates/bevy_transform/src/lib.rs
./src/lib.rs
```

It appears that the permissions of those files were originally 644, but
were unexpectedly changed to 755 by commit
52e3f2007b.

## Solution
Make them not executable by using this command;
`find -name \*.rs -type f -executable -exec chmod --verbose a-x -- {}
\+`
2024-03-25 20:03:55 +00:00
Brett Striker
b2b302bdfd
Restore pre 0.13.1 Root Node Layout behavior (#12698)
# Objective

Fix the regression for Root Node's Layout behavior introduced in
https://github.com/bevyengine/bevy/pull/12268

- Add regression test for Root Node Layout's behaving as they did before
0.13.1
- Restore pre 0.13.1 Root Node Layout behavior (fixes
https://github.com/bevyengine/bevy/issues/12624)

## Solution

This implements [@nicoburns suggestion
](https://discord.com/channels/691052431525675048/743663673393938453/1221593626476548146),
where instead of adding the camera to the taffy node tree, we revert
back to adding a new "parent" node for each root node while maintaining
their relationship with the camera.

> If you can do the ecs change detection to move the node to the correct
Taffy instance for the camera then you should also be able to move it to
a `Vec` of root nodes for that camera.

---

## Changelog

Fixed https://github.com/bevyengine/bevy/issues/12624 - Restores pre
0.13.1 Root Node Layout behavior

## Migration Guide

If you were affected by the 0.13.1 regression and added `position_type:
Absolute` to all your root nodes you might be able to reclaim some LOC
by removing them now that the 0.13 behavior is restored.
2024-03-25 19:11:50 +00:00
notmd
0b623e283e
fix: correctly handle UI outline scale (#12568)
# Objective

- The UI outline in the new dev tools does not handle scale correctly
when the scale is not 1. It looks like the `GlobalTransform` already
handles `scale`. Fix #12566
- To reproduce make sure your screen scale is not 1 and run `cargo run
--example ui --features bevy/bevy_dev_tools`
- I'm not really familiar with Bevy UI internal so please review this
carefully.

## Solution
- Dont apply `window_scale` when calculating `LayoutRect` scale
---
#### Question about UI Node with custom scale: 
- How do we expect the outline when the UI Node is spawn with custom
transform
Eg: `Transform::from_scale(Vec3::splat(1.5))`. Related discussion in
Discord
https://discord.com/channels/691052431525675048/743663673393938453/1219575406986788864

Before

![image](https://github.com/bevyengine/bevy/assets/33456881/10a0bd72-d3ce-4d23-803b-2c458a3a34d7)
After 

![image](https://github.com/bevyengine/bevy/assets/33456881/5bb34d71-2d4c-4fb3-9782-abc450ac7c00)
2024-03-25 19:10:58 +00:00
Lynn
97a5059535
Gizmo line styles (#12394)
# Objective

- Adds line styles to bevy gizmos, suggestion of #9400 
- Currently solid and dotted lines are implemented but this can easily
be extended to support dashed lines as well if that is wanted.

## Solution

- Adds the enum `GizmoLineStyle` and uses it in each `GizmoConfig` to
configure the style of the line.
- Each "dot" in a dotted line has the same width and height as the
`line_width` of the corresponding line.

---

## Changelog

- Added `GizmoLineStyle` to `bevy_gizmos`
- Added a `line_style: GizmoLineStyle ` attribute to `GizmoConfig`
- Updated the `lines.wgsl` shader and the pipelines accordingly.

## Migration Guide

- Any manually created `GizmoConfig` must now include the `line_style`
attribute

## Additional information
Some pretty pictures :)

This is the 3d_gizmos example with/without `line_perspective`:
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 53"
src="https://github.com/bevyengine/bevy/assets/62256001/b1b97311-e78d-4de3-8dfe-9e48a35bb27d">
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 39"
src="https://github.com/bevyengine/bevy/assets/62256001/50ee8ecb-5290-484d-ba36-7fd028374f7f">

And the 2d example:
<img width="1440" alt="Screenshot 2024-03-09 at 23 25 06"
src="https://github.com/bevyengine/bevy/assets/62256001/4452168f-d605-4333-bfa5-5461d268b132">

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-03-25 19:10:45 +00:00
Ian Kettlewell
b35974010b
Get Bevy building for WebAssembly with multithreading (#12205)
# Objective

This gets Bevy building on Wasm when the `atomics` flag is enabled. This
does not yet multithread Bevy itself, but it allows Bevy users to use a
crate like `wasm_thread` to spawn their own threads and manually
parallelize work. This is a first step towards resolving #4078 . Also
fixes #9304.

This provides a foothold so that Bevy contributors can begin to think
about multithreaded Wasm's constraints and Bevy can work towards changes
to get the engine itself multithreaded.

Some flags need to be set on the Rust compiler when compiling for Wasm
multithreading. Here's what my build script looks like, with the correct
flags set, to test out Bevy examples on web:

```bash
set -e
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals' \
     cargo build --example breakout --target wasm32-unknown-unknown -Z build-std=std,panic_abort --release
 wasm-bindgen --out-name wasm_example \
   --out-dir examples/wasm/target \
   --target web target/wasm32-unknown-unknown/release/examples/breakout.wasm
 devserver --header Cross-Origin-Opener-Policy='same-origin' --header Cross-Origin-Embedder-Policy='require-corp' --path examples/wasm
```

A few notes:

1. `cpal` crashes immediately when the `atomics` flag is set. That is
patched in https://github.com/RustAudio/cpal/pull/837, but not yet in
the latest crates.io release.

That can be temporarily worked around by patching Cpal like so:
```toml
[patch.crates-io]
cpal = { git = "https://github.com/RustAudio/cpal" }
```

2. When testing out `wasm_thread` you need to enable the `es_modules`
feature.

## Solution

The largest obstacle to compiling Bevy with `atomics` on web is that
`wgpu` types are _not_ Send and Sync. Longer term Bevy will need an
approach to handle that, but in the near term Bevy is already configured
to be single-threaded on web.

Therefor it is enough to wrap `wgpu` types in a
`send_wrapper::SendWrapper` that _is_ Send / Sync, but panics if
accessed off the `wgpu` thread.

---

## Changelog

- `wgpu` types that are not `Send` are wrapped in
`send_wrapper::SendWrapper` on Wasm + 'atomics'
- CommandBuffers are not generated in parallel on Wasm + 'atomics'

## Questions
- Bevy should probably add CI checks to make sure this doesn't regress.
Should that go in this PR or a separate PR? **Edit:** Added checks to
build Wasm with atomics

---------

Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: daxpedda <daxpedda@gmail.com>
Co-authored-by: François <francois.mockers@vleue.com>
2024-03-25 19:10:18 +00:00
Michael Allwright
320033150e
Fix fetching assets in Web Workers (#12134)
# Objective

This PR fixes #12125

## Solution

The logic in this PR was borrowed from gloo-net and essentially probes
the global Javascript context to see if we are in a window or a worker
before calling `fetch_with_str`.

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-03-25 19:09:30 +00:00
Tygyh
e9343b052f
Support calculating normals for indexed meshes (#11654)
# Objective

- Finish #3987

## Solution

- Rebase and fix typo.

Co-authored-by: Robert Bragg <robert@sixbynine.org>
2024-03-25 19:09:24 +00:00
JMS55
4f20faaa43
Meshlet rendering (initial feature) (#10164)
# Objective
- Implements a more efficient, GPU-driven
(https://github.com/bevyengine/bevy/issues/1342) rendering pipeline
based on meshlets.
- Meshes are split into small clusters of triangles called meshlets,
each of which acts as a mini index buffer into the larger mesh data.
Meshlets can be compressed, streamed, culled, and batched much more
efficiently than monolithic meshes.


![image](https://github.com/bevyengine/bevy/assets/47158642/cb2aaad0-7a9a-4e14-93b0-15d4e895b26a)

![image](https://github.com/bevyengine/bevy/assets/47158642/7534035b-1eb7-4278-9b99-5322e4401715)

# Misc
* Future work: https://github.com/bevyengine/bevy/issues/11518
* Nanite reference:
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
Two pass occlusion culling explained very well:
https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501

---------

Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
2024-03-25 19:08:27 +00:00
James Liu
f096ad4155
Set the logo and favicon for all of Bevy's published crates (#12696)
# Objective
Currently the built docs only shows the logo and favicon for the top
level `bevy` crate. This makes views like
https://docs.rs/bevy_ecs/latest/bevy_ecs/ look potentially unrelated to
the project at first glance.

## Solution
Reproduce the docs attributes for every crate that Bevy publishes.

Ideally this would be done with some workspace level Cargo.toml control,
but AFAICT, such support does not exist.
2024-03-25 18:52:50 +00:00
TheBigCheese
86bd648570
Added an init_bundle method to World (#12573)
# Objective
Make it easy to get the ids of all the components in a bundle (and
initialise any components not yet initialised). This is fairly similar
to the `Bundle::get_component_ids()` method added in the observers PR
however that will return none for any non-initialised components. This
is exactly the API space covered by `Bundle::component_ids()` however
that isn't possible to call outside of `bevy_ecs` as it requires `&mut
Components` and `&mut Storages`.

## Solution
Added `World.init_bundle<B: Bundle>()` which similarly to
`init_component` and `init_resource`, initialises all components in the
bundle and returns a vector of their component ids.

---

## Changelog
Added the method `init_bundle` to `World` as a counterpart to
`init_component` and `init_resource`.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-24 23:48:51 +00:00
JMS55
93b4c6c9a2
Add iOS to synchronous_pipeline_compilation docs (#12694)
iOS uses Metal, so it has the same limitation as macOS, presumably.
2024-03-24 22:01:55 +00:00
Pietro
99d9cc1e49
fix: make WebGPU shader work again (#12683)
# Objective

- Fixes WebGPU UI shader.

<img width="505" alt="image"
src="https://github.com/bevyengine/bevy/assets/106191044/0ae30234-0aae-4f02-95f2-dfb3657d8e67">


## Solution

- Renames a variable to avoid naming conflict.
2024-03-24 10:29:39 +00:00