# Objective
Currently, only named structs can be used with the `SystemParam` derive macro.
## Solution
Remove the restriction. Tuple structs and unit structs are now supported.
---
## Changelog
+ Added support for tuple structs and unit structs to the `SystemParam` derive macro.
# Objective
Fixes#6862 (oh hey good catch @alice-i-cecile)
Bevy was failing to print events from `info!()` and friends to the console if the `trace_tracy` feature was enabled. It shouldn't be doing that.
## Solution
The problem was this per-layer filter that was added in #4320 to suppress a noisy per-frame event (which Tracy requires in order to properly close out a frame):
- The problem event's target was `"bevy_render::renderer"`, not `"tracy"`. - So, the filter wasn't specifically targeting the noisy event.
- Without a default, `tracing_subscriber::filter::Targets` will remove _everything_ that doesn't match an explicit target rule. - So, the filter _was_ silencing the noisy event, along with everything else.
This PR changes that filter to do what was probably intended in #4320: suppress ~any events more verbose than `ERROR` from `bevy_render::renderer`~ the one problematically noisy event, but allow anything else that already made it through the top-level filter_layer.
Also, adds a comment to clarify the intent of that filter, since it's otherwise a bit opaque and required some research.
---
## Changelog
Fixed a bug that hid console log messages when the `trace_tracy` feature was enabled.
The Camera link in the UiCameraConfig was not rendered properly by the documentation.
# Objective
- In the UiCameraConfig page (https://docs.rs/bevy/latest/bevy/prelude/struct.UiCameraConfig.html), a link to the Camera page (https://docs.rs/bevy/latest/bevy/render/camera/struct.Camera.html) is broken.
## Solution
- It seems that when using URL fragment specifiers, backtick should not be used. It might be an issue of rust itself. Replacing the URL fragment specifier `[`Camera`]: bevy_render:📷:Camera` with `[Camera]: bevy_render:📷:Camera` solves this.
# Objective
- `bevy_ptr::{Ptr, PtrMut, OwnedPtr}` wrap raw pointers and should be printable using pointer formatting.
## Solution
- Add a `core::fmt::Pointer` impl for `Ptr`, `PtrMut` and `OwnedPtr` based on the wrapped `NonNull` pointer.
---
## Changelog
- Added a `core::fmt::Pointer` impl to `Ptr`, `PtrMut` and `OwnedPtr`.
Co-authored-by: MrGunflame <mrgunflame@protonmail.com>
## Objective
Bevy UI uses a `MeasureFunc` that preserves the aspect ratio of text, not just images. This means that the extent of flex-items containing text may be calculated incorrectly depending on the ratio of the text size compared to the size of its containing node.
Fixes#6748
Related to #6724
with Bevy 0.9:
![Capture_cols_0 9](https://user-images.githubusercontent.com/27962798/205435999-386d3400-fe9b-475a-aab1-18e61c4c074f.PNG)
with this PR (accurately matching the behavior of Flexbox):
![Capture_fixed](https://user-images.githubusercontent.com/27962798/205436005-6bafbcc2-cd87-4eb7-b5c6-9dbcb30fc795.PNG)
## Solution
Only perform the aspect ratio calculations if the uinode contains an image.
## Changelog
* Added a field `preserve_aspect_ratio` to `CalculatedSize`
* The `MeasureFunc` only preserves the aspect ratio when `preserve_aspect_ratio` is true.
* `update_image_calculated_size_system` sets `preserve_aspect_ratio` to true for nodes with images.
# Objective
The `WgpuSettings` resource is only used during plugin build. Move it into the `RenderPlugin` struct.
Changing these settings requires re-initializing the render context, which is currently not supported.
If it is supported in the future it should probably be more explicit than changing a field on a resource, maybe something similar to the `CreateWindow` event.
## Migration Guide
```rust
// Before (0.9)
App::new()
.insert_resource(WgpuSettings { .. })
.add_plugins(DefaultPlugins)
// After (0.10)
App::new()
.add_plugins(DefaultPlugins.set(RenderPlugin {
wgpu_settings: WgpuSettings { .. },
}))
```
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Following #4402, extract systems run on the render world instead of the main world, and allow retained state operations on it's resources. We're currently extracting to `ExtractedJoints` and then copying it twice during Prepare. Once into `SkinnedMeshJoints` and again into the actual GPU buffer.
This makes #4902 obsolete.
## Solution
Cut out the middle copy and directly extract joints into `SkinnedMeshJoints` and remove `ExtractedJoints` entirely.
This also removes the per-frame allocation that is being made to send `ExtractedJoints` into the render world.
## Performance
On my local machine, this halves the time for `prepare_skinned _meshes` on `many_foxes` (195.75us -> 93.93us on average).
![image](https://user-images.githubusercontent.com/3137680/205427455-ab91a8a3-a6b0-4f0a-bd48-e54482c563b2.png)
---
## Changelog
Added: `BufferVec::truncate`
Added: `BufferVec::extend`
Changed: `SkinnedMeshJoints::build` now takes a `&mut BufferVec` instead of a `&mut Vec` as a parameter.
Removed: `ExtractedJoints`.
## Migration Guide
`ExtractedJoints` has been removed. Read the bound bones from `SkinnedMeshJoints` instead.
# Objective
Fix#1991. Allow users to have a bit more control over the creation and finalization of the threads in `TaskPool`.
## Solution
Add new methods to `TaskPoolBuilder` that expose callbacks that are called to initialize and finalize each thread in the `TaskPool`.
Unlike the proposed solution in #1991, the callback is argument-less. If an an identifier is needed, `std:🧵:current` should provide that information easily.
Added a unit test to ensure that they're being called correctly.
# Objective
- Dynamic scene builder can build scenes without components, if they didn't have any matching the type registry
- Those entities are not really useful in the final `DynamicScene`
## Solution
- Add a method `remove_empty_entities` that will remove empty entities. It's not called by default when calling `build`, I'm not sure if that's a good idea or not.
# Objective
There is currently no way to iterate over key/value pairs inside an `EntityMap`, which makes the usage of this struct very awkward. I couldn't think of a good reason why the `iter()` function should not be exposed, considering the interface already exposes `keys()` and `values()`, so I made this PR.
## Solution
Implement `iter()` for `EntityMap` in terms of its inner map type.
# Objective
Some settings were only applied in windowed mode.
Fix the issue in #6933
# Solution
Always apply the settings.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Remove a method with an unfortunate name and questionable usefulness.
Added in #4708
It doesn't make sense to me for us to provide a method to work around a limitation of closures when we can simply, *not* use a closure.
The limitation in this case is not being able to initialize a variable from inside a closure:
```rust
let child_id;
commands.spawn_empty().with_children(|parent| {
// Error: passing uninitalized variable to a closure.
child_id = parent.spawn_empty().id();
});
// Do something with child_id
```
The docs for `add_children` suggest the following:
```rust
let child_id = commands
.spawn_empty()
.add_children(|parent| parent.spawn_empty().id());
```
I would instead suggest using the following snippet.
```rust
let parent_id = commands.spawn_empty().id();
let child_id = commands.spawn_empty().set_parent(parent_id).id();
// To be fair, at the time of #4708 this would have been a bit more cumbersome since `set_parent` did not exist.
```
Using `add_children` gets more unwieldy when you also want the `parent_id`.
```rust
let parent_commands = commands.spawn_empty();
let parent_id = parent_commands.id();
let child_id = parent_commands.add_children(|parent| parent.spawn_empty().id());
```
### The name
I see why `add_children` is named that way, it's the non-builder variant of `with_children` so it kinda makes sense,
but now the method name situation for `add_child`, `add_children` and `push_children` is *rather* unfortunate.
Removing `add_children` and renaming `push_children` to `add_children` in one go is kinda bleh, but that way we end up with the matching methods `add_child` and `add_children`.
Another reason to rename `push_children` is that it's trying to mimick the `Vec` api naming but fails because `push` is for single elements. I guess it should have been `extend_children_from_slice`, but lets not name it that :)
### Questions
~~Should `push_children` be renamed in this PR? This would make the migration guide easier to deal with.~~
Let's do that later.
Does anyone know of a way to do a simple text/regex search through all the github repos for usage of `add_children`?
That way we can have a better idea of how this will affect users. My guess is that usage of `add_children` is quite rare.
## Migration Guide
The method `add_children` on `EntityCommands` was removed.
If you were using `add_children` over `with_children` to return data out of the closure you can use `set_parent` or `add_child` to avoid the closure instead.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
`AsBindGroup` can't be used as a trait object because of the constraint `Sized` and because of the associated function.
This is a problem for [`bevy_atmosphere`](https://github.com/JonahPlusPlus/bevy_atmosphere) because it needs to use a trait that depends on `AsBindGroup` as a trait object, for switching out different shaders at runtime. The current solution it employs is reimplementing the trait and derive macro into that trait, instead of constraining to `AsBindGroup`.
## Solution
Remove the `Sized` constraint from `AsBindGroup` and add the constraint `where Self: Sized` to the associated function `bind_group_layout`. Also change `PreparedBindGroup<T: AsBindGroup>` to `PreparedBindGroup<T>` and use it as `PreparedBindGroup<Self::Data>` instead of `PreparedBindGroup<Self>`.
This weakens the constraints, but increases the flexibility of `AsBindGroup`.
I'm not entirely sure why the `Sized` constraint was there, because it worked fine without it (maybe @cart wasn't aware of use cases for `AsBindGroup` as a trait object or this was just leftover from legacy code?).
---
## Changelog
- `AsBindGroup` can be used as a trait object.
# Objective
[Rust 1.66](https://blog.rust-lang.org/inside-rust/2022/12/12/1.66.0-prerelease.html) is coming in a few days, and bevy doesn't build with it.
Fix that.
## Solution
Replace output from a trybuild test, and fix a few new instances of `needless_borrow` and `unnecessary_cast` that are now caught.
## Note
Due to the trybuild test, this can't be merged until 1.66 is released.
# Objective
A separate `tracing` span for running a system's commands is created, even if the system doesn't have commands. This is adding extra measuring overhead (see #4892) where it's not needed.
## Solution
Move the span into `ParallelCommandState` and `CommandQueue`'s `SystemParamState::apply`. To get the right metadata for the span, a additional `&SystemMeta` parameter was added to `SystemParamState::apply`.
---
## Changelog
Added: `SystemMeta::name`
Changed: Systems without `Commands` and `ParallelCommands` will no longer show a "system_commands" span when profiling.
Changed: `SystemParamState::apply` now takes a `&SystemMeta` parameter in addition to the provided `&mut World`.
# Objective
Change detection can be spuriously triggered by setting a field to the same value as before. As a result, a common pattern is to write:
```rust
if *foo != value {
*foo = value;
}
```
This is confusing to read, and heavy on boilerplate.
Adopted from #5373, but untangled and rebased to current `bevy/main`.
## Solution
1. Add a method to the `DetectChanges` trait that implements this boilerplate when the appropriate trait bounds are met.
2. Document this minor footgun, and point users to it.
## Changelog
* added the `set_if_neq` method to avoid triggering change detection when the new and previous values are equal. This will work on both components and resources.
## Migration Guide
If you are manually checking if a component or resource's value is equal to its new value before setting it to avoid triggering change detection, migrate to the clearer and more convenient `set_if_neq` method.
## Context
Related to #2363 as it avoids triggering change detection, but not a complete solution (as it still requires triggering it when real changes are made).
Co-authored-by: Zoey <Dessix@Dessix.net>
# Objective
The following code:
```rs
use bevy::prelude::Image;
use image::{ DynamicImage, GenericImage, Rgba };
fn main() {
let mut dynamic_image = DynamicImage::new_rgb32f(1, 1);
dynamic_image.put_pixel(0, 0, Rgba([1, 1, 1, 1]));
let image = Image::from_dynamic(dynamic_image, false); // Panic!
println!("{image:?}");
}
```
Can cause an assertion failed:
```
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `16`,
right: `14`: Pixel data, size and format have to match', .../bevy_render-0.9.1/src/texture/image.rs:209:9
stack backtrace:
...
4: core::panicking::assert_failed<usize,usize>
at /rustc/897e37553bba8b42751c67658967889d11ecd120/library/core/src/panicking.rs:181
5: bevy_render::texture::image::Image::new
at .../bevy_render-0.9.1/src/texture/image.rs:209
6: bevy_render::texture::image::Image::from_dynamic
at .../bevy_render-0.9.1/src/texture/image_texture_conversion.rs:159
7: bevy_test::main
at ./src/main.rs:8
...
```
It seems to be cause by a copypasta in `crates/bevy_render/src/texture/image_texture_conversion.rs`. Let's fix it.
## Solution
```diff
// DynamicImage::ImageRgb32F(image) => {
- let a = u16::max_value();
+ let a = 1f32;
```
This will fix the conversion.
---
## Changelog
- Fixed the alpha channel of the `image::DynamicImage::ImageRgb32F` to `bevy_render::texture::Image` conversion in `bevy_render::texture::Image::from_dynamic()`.
# Objective
- https://github.com/bevyengine/bevy/pull/5364 Added a few features to the AsBindGroup derive, but if you don't know they exist they aren't documented anywhere.
## Solution
- Document the new arguments in the doc block for the derive.
# Objective
Speed up bundle insertion and spawning from a bundle.
## Solution
Use the same technique used in #6800 to remove the branch on storage type when writing components from a `Bundle` into storage.
- Add a `StorageType` argument to the closure on `Bundle::get_components`.
- Pass `C::Storage::STORAGE_TYPE` into that argument.
- Match on that argument instead of reading from a `Vec<StorageType>` in `BundleInfo`.
- Marked all implementations of `Bundle::get_components` as inline to encourage dead code elimination.
The `Vec<StorageType>` in `BundleInfo` was also removed as it's no longer needed. If users were reliant on this, they can either use the compile time constants or fetch the information from `Components`. Should save a rather negligible amount of memory.
## Performance
Microbenchmarks show a slight improvement to inserting components into existing entities, as well as spawning from a bundle. Ranging about 8-16% faster depending on the benchmark.
```
group main soft-constant-write-components
----- ---- ------------------------------
add_remove/sparse_set 1.08 1019.0±80.10µs ? ?/sec 1.00 944.6±66.86µs ? ?/sec
add_remove/table 1.07 1343.3±20.37µs ? ?/sec 1.00 1257.3±18.13µs ? ?/sec
add_remove_big/sparse_set 1.08 1132.4±263.10µs ? ?/sec 1.00 1050.8±240.74µs ? ?/sec
add_remove_big/table 1.02 2.6±0.05ms ? ?/sec 1.00 2.5±0.08ms ? ?/sec
get_or_spawn/batched 1.15 401.4±17.76µs ? ?/sec 1.00 349.3±11.26µs ? ?/sec
get_or_spawn/individual 1.13 732.1±43.35µs ? ?/sec 1.00 645.6±41.44µs ? ?/sec
insert_commands/insert 1.12 623.9±37.48µs ? ?/sec 1.00 557.4±34.99µs ? ?/sec
insert_commands/insert_batch 1.16 401.4±17.00µs ? ?/sec 1.00 347.4±12.87µs ? ?/sec
insert_simple/base 1.08 416.9±5.60µs ? ?/sec 1.00 385.2±4.14µs ? ?/sec
insert_simple/unbatched 1.06 934.5±44.58µs ? ?/sec 1.00 881.3±47.86µs ? ?/sec
spawn_commands/2000_entities 1.09 190.7±11.41µs ? ?/sec 1.00 174.7±9.15µs ? ?/sec
spawn_commands/4000_entities 1.10 386.5±25.33µs ? ?/sec 1.00 352.3±18.81µs ? ?/sec
spawn_commands/6000_entities 1.10 586.2±34.42µs ? ?/sec 1.00 535.3±27.25µs ? ?/sec
spawn_commands/8000_entities 1.08 778.5±45.15µs ? ?/sec 1.00 718.0±33.66µs ? ?/sec
spawn_world/10000_entities 1.04 1026.4±195.46µs ? ?/sec 1.00 985.8±253.37µs ? ?/sec
spawn_world/1000_entities 1.06 103.8±20.23µs ? ?/sec 1.00 97.6±18.22µs ? ?/sec
spawn_world/100_entities 1.15 11.4±4.25µs ? ?/sec 1.00 9.9±1.87µs ? ?/sec
spawn_world/10_entities 1.05 1030.8±229.78ns ? ?/sec 1.00 986.2±231.12ns ? ?/sec
spawn_world/1_entities 1.01 105.1±23.33ns ? ?/sec 1.00 104.6±31.84ns ? ?/sec
```
---
## Changelog
Changed: `Bundle::get_components` now takes a `FnMut(StorageType, OwningPtr)`. The provided storage type must be correct for the component being fetched.
# Objective
Partially address #3492.
## Solution
Document the remaining undocumented members of `bevy_utils` and set `warn(missing_docs)` on the crate level. Also enabled `clippy::undocumented_unsafe_blocks` as a warning on the crate to keep it in sync with `bevy_ecs`'s warnings.
# Objective
```rust
// makes clippy complain about 'taking a mutable reference to a `const` item'
let color = *Color::RED.set_a(0.5);
// Now you can do
let color = Color::RED.with_a(0.5);
```
## Changelog
Added `with_r`, `with_g`, `with_b`, and `with_a` to `Color`.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/6417
## Solution
- clear_trackers was not being called on the render world. This causes the removed components vecs to continuously grow. This PR adds clear trackers to the end of RenderStage::Cleanup
## Migration Guide
The call to `clear_trackers` in `App` has been moved from the schedule to App::update for the main world and calls to `clear_trackers` have been added for sub_apps in the same function. This was due to needing stronger guarantees. If clear_trackers isn't called on a world it can lead to memory leaks in `RemovedComponents`.
# Objective
* Implementing a custom `SystemParam` by hand requires implementing three traits -- four if it is read-only.
* The trait `SystemParamFetch<'w, 's>` is a workaround from before we had generic associated types, and is no longer necessary.
## Solution
* Combine the trait `SystemParamFetch` with `SystemParamState`.
* I decided to remove the `Fetch` name and keep the `State` name, since the former was consistently conflated with the latter.
* Replace the trait `ReadOnlySystemParamFetch` with `ReadOnlySystemParam`, which simplifies trait bounds in generic code.
---
## Changelog
- Removed the trait `SystemParamFetch`, moving its functionality to `SystemParamState`.
- Replaced the trait `ReadOnlySystemParamFetch` with `ReadOnlySystemParam`.
## Migration Guide
The trait `SystemParamFetch` has been removed, and its functionality has been transferred to `SystemParamState`.
```rust
// Before
impl SystemParamState for MyParamState {
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { ... }
}
impl<'w, 's> SystemParamFetch<'w, 's> for MyParamState {
type Item = MyParam<'w, 's>;
fn get_param(...) -> Self::Item;
}
// After
impl SystemParamState for MyParamState {
type Item<'w, 's> = MyParam<'w, 's>; // Generic associated types!
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { ... }
fn get_param<'w, 's>(...) -> Self::Item<'w, 's>;
}
```
The trait `ReadOnlySystemParamFetch` has been replaced with `ReadOnlySystemParam`.
```rust
// Before
unsafe impl ReadOnlySystemParamFetch for MyParamState {}
// After
unsafe impl<'w, 's> ReadOnlySystemParam for MyParam<'w, 's> {}
```
# Objective
It's not clear to users how to handle `!Sync` types as components and resources in the absence of engine level support for them.
## Solution
Added a section to `Component`'s and `Resource`'s type level docs on available options for making a type `Sync` when it holds `!Sync` fields, linking `bevy_utils::synccell::SyncCell` and the currently unstable `std::sync::Exclusive`.
Also added a compile_fail doctest that illustrates how to apply `SyncCell`. These will break when/if #6572 gets merged, at which point these docs should be updated.
# Objective
This is an adoption of #5792. Fixes#5791.
## Solution
Implemented all the required reflection traits for `VecDeque`, taking from `Vec`'s impls.
---
## Changelog
Added: `std::collections::VecDeque` now implements `Reflect` and all relevant traits.
Co-authored-by: james7132 <contact@jamessliu.com>
# Objective
- Get rid of giant match statement to get PixelInfo.
- This will allow for supporting any texture that is uncompressed, instead of people needing to PR in any textures that are supported in wgpu, but not bevy.
## Solution
- More conservative alternative to https://github.com/bevyengine/bevy/pull/6788, where we don't try to make some of the calculations correct for compressed types.
- Delete `PixelInfo` and get the pixel_size directly from wgpu. Data from wgpu is here: https://docs.rs/wgpu-types/0.14.0/src/wgpu_types/lib.rs.html#2359
- Panic if the texture is a compressed type. An integer byte size of a pixel is no longer a valid concept when talking about compressed textures.
- All internal usages use `pixel_size` and not `pixel_info` and are on uncompressed formats. Most of these usages are on either explicit texture formats or slightly indirectly through `TextureFormat::bevy_default()`. The other uses are in `TextureAtlas` and have other calculations that assumes the texture is uncompressed.
## Changelog
- remove `PixelInfo` and get `pixel_size` from wgpu
## Migration Guide
`PixelInfo` has been removed. `PixelInfo::components` is equivalent to `texture_format.describe().components`. `PixelInfo::type_size` can be gotten from `texture_format.describe().block_size/ texture_format.describe().components`. But note this can yield incorrect results for some texture types like Rg11b10Float.
# Objective
Adds a cylinder shape. Fixes#2282.
## Solution
- I added a custom cylinder shape, taken from [here](https://github.com/rparrett/typey_birb/blob/main/src/cylinder.rs) with permission from @rparrett.
- I also added the cylinder shape to the `3d_shapes` example scene.
---
## Changelog
- Added cylinder shape
Co-Authored-By: Rob Parrett <robparrett@gmail.com>
Co-Authored-By: davidhof <7483215+davidhof@users.noreply.github.com>
# Objective
Fixes#6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand #5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error.
## Solution
* Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``.
* Modified and added tests for these under examples in ``system_piping.rs``.
# Objective
- Make `AudioOutput` a `Resource`.
## Solution
- Do not store `OutputStream` in the struct.
- `mem::forget` `OutputStream`.
---
## Changelog
### Added
- `AudioOutput` is now a `Resource`.
## Migration Guide
- Use `Res<AudioOutput<Source>>` instead of `NonSend<AudioOutput<Source>>`. Same for `Mut` variants.
# Objective
Resolves#4597 (based on the work from #6056 and a refresh of #4147)
When using reflection, we may often end up in a scenario where we have a Dynamic representing a certain type. Unfortunately, we can't just call `MyType::from_reflect` as we do not have knowledge of the concrete type (`MyType`) at runtime.
Such scenarios happen when we call `Reflect::clone_value`, use the reflection deserializers, or create the Dynamic type ourselves.
## Solution
Add a `ReflectFromReflect` type data struct.
This struct allows us to easily convert Dynamic representations of our types into their respective concrete instances.
```rust
#[derive(Reflect, FromReflect)]
#[reflect(FromReflect)] // <- Register `ReflectFromReflect`
struct MyStruct(String);
let type_id = TypeId::of::<MyStruct>();
// Register our type
let mut registry = TypeRegistry::default();
registry.register::<MyStruct>();
// Create a concrete instance
let my_struct = MyStruct("Hello world".to_string());
// `Reflect::clone_value` will generate a `DynamicTupleStruct` for tuple struct types
let dynamic_value: Box<dyn Reflect> = my_struct.clone_value();
assert!(!dynamic_value.is::<MyStruct>());
// Get the `ReflectFromReflect` type data from the registry
let rfr: &ReflectFromReflect = registry
.get_type_data::<ReflectFromReflect>(type_id)
.unwrap();
// Call `FromReflect::from_reflect` on our Dynamic value
let concrete_value: Box<dyn Reflect> = rfr.from_reflect(&dynamic_value);
assert!(concrete_value.is::<MyStruct>());
```
### Why this PR?
###### Why now?
The three main reasons I closed#4147 were that:
1. Registering `ReflectFromReflect` is clunky (deriving `FromReflect` *and* registering `ReflectFromReflect`)
2. The ecosystem and Bevy itself didn't seem to pay much attention to deriving `FromReflect`
3. I didn't see a lot of desire from the community for such a feature
However, as time has passed it seems 2 and 3 are not really true anymore. Bevy is internally adding lots more `FromReflect` derives, which should make this feature all the more useful. Additionally, I have seen a growing number of people look for something like `ReflectFromReflect`.
I think 1 is still an issue, but not a horrible one. Plus it could be made much, much better using #6056. And I think splitting this feature out of #6056 could lead to #6056 being adopted sooner (or at least make the need more clear to users).
###### Why not just re-open #4147?
The main reason is so that this PR can garner more attention than simply re-opening the old one. This helps bring fresh eyes to the PR for potentially more perspectives/reviews.
---
## Changelog
* Added `ReflectFromReflect`
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
#6547 accidentally broke change detection for SparseSet components by using `Ticks::from_tick_cells` with the wrong argument order.
## Solution
Use the right argument order. Add a regression test.
# Objective
The window event types currently don't support reflection. This PR adds support to them (as requested [here](https://github.com/bevyengine/bevy/issues/6223#issuecomment-1273852329)).
## Solution
Implement `Reflect` + `FromReflect` for window event types. Relevant traits are also being reflected with `#[reflect(...)]` attributes.
Additionally, this PR derives `Reflect` + `FromReflect` for `WindowDescriptor` and the types it depends on so that `CreateWindow` events can be fully manipulated through reflection.
Finally, this PR adds `FromReflect` for `PathBuf` as a value type, which is needed for `FileDragAndDrop`.
This adds the "glam" feature to the `bevy_reflect` dependency for package `bevy_window`. Since `bevy_window` transitively depends on `glam` already, all this brings in are the reflection `impl`s.
## Open questions
Should `app.register_type::<PathBuf>();` be moved to `CorePlugin`? I added it to `WindowPlugin` because that's where it's used and `CorePlugin` doesn't seem to register all the missing std types, but it would also make sense in `CorePlugin` I believe since it's a commonly used type.
---
## Changelog
Added:
- Implemented `Reflect` + `FromReflect` for window events and related types. These types are automatically registered when adding the `WindowPlugin`.
# Objective
- Fixes#6841
- In some case, the number of maximum storage buffers is `u32::MAX` which doesn't fit in a `i32`
## Solution
- Add an option to have a `u32` in a `ShaderDefVal`
having `doc(hidden)` on the read only version of a generated mutable world query leads to docs on the readonly item having a dead link. It also makes it annoying to have nice docs for libraries attempting to expose derived `WorldQuery` structs as re-exporting the read only item does not cause it to appear in docs even though it would be intended for users to know about the read only world query and use it.
# Objective
Fixes#6866.
## Solution
Docs now should describe what the _front_, _first_, _back_, and _last_ elements are for an implementor of the `bevy::reflect::list::List` Trait. Further, the docs should describe how `bevy::reflect::list::List::push` and `bevy::reflect::list::List::pop` should act on these elements.
Co-authored-by: Linus Käll <linus.kall.business@gmail.com>
# Objective
Prevent future unsoundness that was seen in #6623.
## Solution
Newtype both indexes in `Archetype` and `Table` as `ArchetypeRow` and `TableRow`. This avoids weird numerical manipulation on the indices, and can be stored and treated opaquely. Also enforces the source and destination of where these indices at a type level.
---
## Changelog
Changed: `Archetype` indices and `Table` rows have been newtyped as `ArchetypeRow` and `TableRow`.
# Objective
`EntityRef::get` and friends all type erase calls to fetch the target components by using passing in the `TypeId` instead of using generics. This is forcing a lookup to `Components` to fetch the storage type. This adds an extra memory lookup and forces a runtime branch instead of allowing the compiler to optimize out the unused branch.
## Solution
Leverage `Component::Storage::STORAGE_TYPE` as a constant instead of fetching the metadata from `Components`.
## Performance
This has a near 2x speedup for all calls to `World::get`. Microbenchmark results from my local machine. `Query::get_component`, which uses `EntityRef::get` internally also show a slight speed up. This has closed the gap between `World::get` and `Query::get` for the same use case.
```
group entity-ref-generics main
----- ------------------- ----
query_get_component/50000_entities_sparse 1.00 890.6±40.42µs ? ?/sec 1.10 980.6±28.22µs ? ?/sec
query_get_component/50000_entities_table 1.00 968.5±73.73µs ? ?/sec 1.08 1048.8±31.76µs ? ?/sec
query_get_component_simple/system 1.00 703.2±4.37µs ? ?/sec 1.00 702.1±6.13µs ? ?/sec
query_get_component_simple/unchecked 1.02 855.8±8.98µs ? ?/sec 1.00 843.1±8.19µs ? ?/sec
world_get/50000_entities_sparse 1.00 202.3±3.15µs ? ?/sec 1.85 374.0±20.96µs ? ?/sec
world_get/50000_entities_table 1.00 193.0±1.78µs ? ?/sec 2.02 389.2±26.55µs ? ?/sec
world_query_get/50000_entities_sparse 1.01 162.4±2.23µs ? ?/sec 1.00 161.3±0.95µs ? ?/sec
world_query_get/50000_entities_table 1.00 199.9±0.63µs ? ?/sec 1.00 200.2±0.74µs ? ?/sec
```
This should also, by proxy, speed up the `ReflectComponent` APIs as most of those use `World::get` variants internally.
# Objective
- Fixes#3004
## Solution
- Replaced all the types with their fully quallified names
- Replaced all trait methods and inherent methods on dyn traits with their fully qualified names
- Made a new file `fq_std.rs` that contains structs corresponding to commonly used Structs and Traits from `std`. These structs are replaced by their respective fully qualified names when used inside `quote!`
# Objective
- Fixes#6711
## Solution
- Change the `path` function parameter of `dynamically_load_plugin` and `DynamicPluginExt::load_plugin` to a generic with `AsRef<OsStr>` bound
# Objective
`prepare_asset` for Image has an alternate path for texture creation that is used when the image is not compressed and does not contain mipmaps. This additional code path is unnecessary as `render_device.create_texture_with_data()` will handle both cases correctly.
## Solution
Use `render_device.create_texture_with_data()` in all cases.
Tested successfully with the following examples:
- load_gltf
- render_to_texture
- texture
- 3d_shapes
- sprite
- sprite_sheet
- array_texture
- shader_material_screenspace_texture
- skybox (though this already would use the `create_texture_with_data()` branch anyway)
# Objective
The methods `World::change_tick` and `World::read_change_tick` lack documentation and have confusingly similar behavior.
## Solution
Add documentation and clarify the distinction between the two functions.
The PR fixes the interface of `EventReader::clear`. Currently, the method consumes the reader, which makes it unusable.
## Changelog
- `EventReader::clear` now takes a mutable reference instead of consuming the event reader.
## Migration Guide
`EventReader::clear` now takes a mutable reference instead of consuming the event reader. This means that `clear` now needs explicit mutable access to the reader variable, which previously could have been omitted in some cases:
```rust
// Old (0.9)
fn clear_events(reader: EventReader<SomeEvent>) {
reader.clear();
}
// New (0.10)
fn clear_events(mut reader: EventReader<SomeEvent>) {
reader.clear();
}
```
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Fixes#6812.
## Solution
- Replaced `World::read_change_ticks` with `World::change_ticks` within `bevy_ecs` crate in places where `World` references were mutable.
---
# Objective
Partially addresses #5504. Allow users to get an `Iterator<Item = EntityRef<'a>>` over all entities in the `World`.
## Solution
Change `World::iter_entities` to return an iterator of `EntityRef` instead of `Entity`.
Not sure how to tackle making an `Iterator<Item = EntityMut<'_>>` without being horribly unsound. Might need to wait for `LendingIterator` to stabilize so we can ensure only one of them is valid at a given time.
---
## Changelog
Changed: `World::iter_entities` now returns an iterator of `EntityRef` instead of `Entity`.
# Objective
Currently, the `SystemParam` derive forces you to declare the lifetime parameters `<'w, 's>`, even if you don't use them.
If you don't follow this structure, the error message is quite nasty.
### Example (before):
```rust
#[derive(SystemParam)]
pub struct EventWriter<'w, 's, E: Event> {
events: ResMut<'w, Events<E>>,
// The derive forces us to declare the `'s` lifetime even though we don't use it,
// so we have to add this `PhantomData` to please rustc.
#[system_param(ignore)]
_marker: PhantomData<&'s ()>,
}
```
## Solution
* Allow the user to omit either lifetime.
* Emit a descriptive error if any lifetimes used are invalid.
### Example (after):
```rust
#[derive(SystemParam)]
pub struct EventWriter<'w, E: Event> {
events: ResMut<'w, Events<E>>,
}
```
---
## Changelog
* The `SystemParam` derive is now more flexible, allowing you to omit unused lifetime parameters.
Updates the requirements on [tracing-chrome](https://github.com/thoren-d/tracing-chrome) to permit the latest version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/thoren-d/tracing-chrome/releases">tracing-chrome's releases</a>.</em></p>
<blockquote>
<h2>Release v0.7.0</h2>
<ul>
<li>Add <code>start_new</code> to <code>FlushGuard</code>. You can now generate multiple traces in one run!</li>
<li>Clean up dependencies</li>
<li>Make events thread-scoped</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="8760d81206"><code>8760d81</code></a> Prepare for 0.7 (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/16">#16</a>)</li>
<li><a href="a30bfb78d2"><code>a30bfb7</code></a> Update documentation (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/15">#15</a>)</li>
<li><a href="3fe24ff44d"><code>3fe24ff</code></a> Save thread names for start_new (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/14">#14</a>)</li>
<li><a href="fa8a0ff8ba"><code>fa8a0ff</code></a> Adding "Start New" feature that allows a user to finalize writing to the (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/11">#11</a>)</li>
<li><a href="d3059d66b3"><code>d3059d6</code></a> Directly depend on crossbeam_channel (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/12">#12</a>)</li>
<li><a href="441dba5c21"><code>441dba5</code></a> change scope of instant events to thread (<a href="https://github-redirect.dependabot.com/thoren-d/tracing-chrome/issues/13">#13</a>)</li>
<li>See full diff in <a href="https://github.com/thoren-d/tracing-chrome/compare/v0.6.0...v0.7.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 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>
# Objective
Fixes#6827
## Solution
Use the `Color::rgba_linear` function instead of the `Color::rgba` function to correctly interpret colors from glTF files in the linear color space rather than the incorrect sRGB color space
# Objective
> Followup to [this](https://github.com/bevyengine/bevy/pull/6755#discussion_r1032671178) comment
Rearrange the impls in the `impls/std.rs` file.
The issue was that I had accidentally misplaced the impl for `Option<T>` and put it between the `Cow<'static, str>` impls. This is just a slight annoyance and readability issue.
## Solution
Move the `Option<T>` and `&'static Path` impls around to be more readable.
# Objective
The soundness of the ECS `World` partially relies on the correctness of the state of `Entities` stored within it. We're currently allowing users to (unsafely) mutate it, as well as readily construct it without using a `World`. While this is not strictly unsound so long as users (including `bevy_render`) safely use the APIs, it's a fairly easy path to unsoundness without much of a guard rail.
Addresses #3362 for `bevy_ecs::entity`. Incorporates the changes from #3985.
## Solution
Remove `Entities`'s `Default` implementation and force access to the type to only be through a properly constructed `World`.
Additional cleanup for other parts of `bevy_ecs::entity`:
- `Entity::index` and `Entity::generation` are no longer `pub(crate)`, opting to force the rest of bevy_ecs to use the public interface to access these values.
- `EntityMeta` is no longer `pub` and also not `pub(crate)` to attempt to cut down on updating `generation` without going through an `Entities` API. It's currently inaccessible except via the `pub(crate)` Vec on `Entities`, there was no way for an outside user to use it.
- Added `Entities::set`, an unsafe `pub(crate)` API for setting the location of an Entity (parallel to `Entities::get`) that replaces the internal case where we need to set the location of an entity when it's been spawned, moved, or despawned.
- `Entities::alloc_at_without_replacement` is only used in `World::get_or_spawn` within the first party crates, and I cannot find a public use of this API in any ecosystem crate that I've checked (via GitHub search).
- Attempted to document the few remaining undocumented public APIs in the module.
---
## Changelog
Removed: `Entities`'s `Default` implementation.
Removed: `EntityMeta`
Removed: `Entities::alloc_at_without_replacement` and `AllocAtWithoutReplacement`.
Co-authored-by: james7132 <contact@jamessliu.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Since #5900 3d examples fail in wasm
```
ERROR crates/bevy_render/src/render_resource/pipeline_cache.rs:660 failed to process shader: Unknown shader def: 'AVAILABLE_STORAGE_BUFFER_BINDINGS'
```
## Solution
- Fix it by always adding the shaderdef `AVAILABLE_STORAGE_BUFFER_BINDINGS` with the actual value, instead of 3 when 3 or more were available
# Objective
- Support textures in `Rgb9e5Ufloat` format.
## Solution
- Add `TextureFormatPixelInfo` for `Rgb9e5Ufloat`.
Tested this with a `Rgb9e5Ufloat` encoded KTX2 texture.
# Objective
- Every usage of `DrawFunctionsInternals::get_id()` was followed by a `.unwrap()`. which just adds boilerplate.
## Solution
- Introduce a fallible version of `DrawFunctionsInternals::get_id()` and use it where possible.
- I also took the opportunity to improve the error message a little in the case where it fails.
---
## Changelog
- Added `DrawFunctionsInternals::id()`
# Objective
Document `bevy_ecs::archetype` and and declutter the public documentation for the module by making types non-`pub`.
Addresses #3362 for `bevy_ecs::archetype`.
## Solution
- Add module level documentation.
- Add type and API level documentation for all public facing types.
- Make `ArchetypeId`, `ArchetypeGeneration`, and `ArchetypeComponentId` truly opaque IDs that are not publicly constructable.
- Make `AddBundle` non-pub, make `Edges::get_add_bundle` return a `Option<ArchetypeId>` and fork the existing function into `Edges::get_add_bundle_internal`.
- Remove `pub(crate)` on fields that have a corresponding pub accessor function.
- Removed the `Archetypes: Default` impl, opting for a `pub(crate) fn new` alternative instead.
---
## Changelog
Added: `ArchetypeGeneration` now implements `Ord` and `PartialOrd`.
Removed: `Archetypes`'s `Default` implementation.
Removed: `Archetype::new` and `Archetype::is_empty`.
Removed: `ArchetypeId::new` and `ArchetypeId::value`.
Removed: `ArchetypeGeneration::value`
Removed: `ArchetypeIdentity`.
Removed: `ArchetypeComponentId::new` and `ArchetypeComponentId::value`.
Removed: `AddBundle`. `Edges::get_add_bundle` now returns `Option<ArchetypeId>`
# Objective
- The documentation describing different ways to spawn an Entity is missing reference to "method" for "Spawn an entity with components".
## Solution
- Update the documentation to add the reference to `World::spawn`.
# Objective
* Fix#6668
* There is no need to panic when a parenting operation is redundant, as no invalid state is entered.
## Solution
Make `push_children` idempotent.
# Objective
One of the use-cases for the function `Entity::from_raw` is creating placeholder entity ids, which are meant to be overwritten later. If we use a constant for this instead of `from_raw`, it is more ergonomic and self-documenting.
## Solution
Add a constant that returns an entity ID with an index of `u32::MAX` and a generation of zero. Users are instructed to overwrite this value before using it.
# Objective
When a global tracing subscriber has already been set, `LogPlugin` panics with an error message explaining this. However, if a global logger has already been set, it simply panics on an unwrap.
#6426 mentiones the panic and has been fixed by unique plugins, but the panic can still occur if a logger has been set through different means or multiple apps are created, as in #4934. The solution to that specific case isn't clear; this PR only fixes the missing error message.
## Solution
- ~add error message to panic~
- turn into warning
# Objective
- Reduce confusion around uniform bindings in materials. I've seen multiple people on discord get confused by it because it uses a struct that is named the same in the rust code and the wgsl code, but doesn't contain the same data. Also, the only reason this works is mostly by chance because the memory happens to align correctly.
## Solution
- Remove the confusing parts of the doc
## Notes
It's not super clear in the diff why this causes confusion, but essentially, the rust code defines a `CustomMaterial` struct with a color and a texture, but in the wgsl code the struct with the same name only contains the color. People are confused by it because the struct in wgsl doesn't need to be there.
You _can_ have complex structs on each side and the macro will even combine it for you if you reuse a binding index, but as it is now, this example seems to confuse more than help people.
# Objective
Fixes#6739
## Solution
Implement the required traits. They cannot be implemented for `Path` directly, since it is a dynamically-sized type.
# Objective
Fixes#6642
In a way that doesn't create any breaking changes, as a possible way to fix the above in a patch release.
## Solution
Don't actually remove font atlases when `max_font_atlases` is exceeded. Add a warning instead.
Keep `TextError::ExceedMaxTextAtlases` and `TextSettings` as-is so we don't break anything.
This is a bit of a cop-out, but the problems revealed by #6642 seem very challenging to fix properly.
Maybe follow up later with something more like https://github.com/rparrett/bevy/commits/remove-max-font-atlases later, if this is the direction we want to go.
## Note
See previous attempt at a "simple fix" that only solved some of the issues: #6666
# Objective
> Part of #6573
When serializing a `DynamicScene` we end up treating almost all non-value types as though their type data doesn't exist. This is because when creating the `DynamicScene` we call `Reflect::clone_value` on the components, which generates a Dynamic type for all non-value types.
What this means is that the `glam` types are treated as though their `ReflectSerialize` registrations don't exist. However, the deserializer _does_ pick up the registration and attempts to use that instead. This results in the deserializer trying to operate on "malformed" data, causing this error:
```
WARN bevy_asset::asset_server: encountered an error while loading an asset: Expected float
```
## Solution
Ideally, we should better handle the serialization of possibly-Dynamic types. However, this runs into issues where the `ReflectSerialize` expects the concrete type and not a Dynamic representation, resulting in a panic:
0aa4147af6/crates/bevy_reflect/src/type_registry.rs (L402-L413)
Since glam types are so heavily used in Bevy (specifically in `Transform` and `GlobalTransform`), it makes sense to just a quick fix in that enables them to be used properly in scenes while a proper solution is found.
This PR simply removes all `ReflectSerialize` and `ReflectDeserialize` registrations from the glam types that are reflected as structs.
---
## Changelog
- Remove `ReflectSerialize` and `ReflectDeserialize` registrations from most glam types
## Migration Guide
This PR removes `ReflectSerialize` and `ReflectDeserialize` registrations from most glam types. This means any code relying on either of those type data existing for those glam types will need to not do that.
This also means that some serialized glam types will need to be updated. For example, here is `Affine3A`:
```rust
// BEFORE
(
"glam::f32::affine3a::Affine3A": (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0),
// AFTER
"glam::f32::affine3a::Affine3A": (
matrix3: (
x_axis: (
x: 1.0,
y: 0.0,
z: 0.0,
),
y_axis: (
x: 0.0,
y: 1.0,
z: 0.0,
),
z_axis: (
x: 0.0,
y: 0.0,
z: 1.0,
),
),
translation: (
x: 0.0,
y: 0.0,
z: 0.0,
),
)
)
```
# Objective
Many types in `bevy_render` implemented `Reflect` but were not registered.
## Solution
Register all types in `bevy_render` that impl `Reflect`.
This also registers additional dependent types (i.e. field types).
> Note: Adding these dependent types would not be needed using something like #5781😉
---
## Changelog
- Register missing `bevy_render` types in the `TypeRegistry`:
- `camera::RenderTarget`
- `globals::GlobalsUniform`
- `texture::Image`
- `view::ComputedVisibility`
- `view::Visibility`
- `view::VisibleEntities`
- Register additional dependent types:
- `view::ComputedVisibilityFlags`
- `Vec<Entity>`
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/6603
## Solution
- `Task`s will cancel when dropped, but wait until they return Pending before they actually get canceled. That means that if a task panics, it's possible for that error to get propagated to the scope and the scope gets dropped, while scoped tasks in other threads are still running. This is a big problem since scoped task can hold life-timed values that are dropped as the scope is dropped leading to UB.
---
## Changelog
- changed `Scope` to use `FallibleTask` and await the cancellation of all remaining tasks when it's dropped.
# Objective
- Reverts #5730.
- Fixes#6173, fixes#6596.
## Solution
Remove the warning entirely.
## Changelog
You will no longer be spammed about
> Missed 31 `bevy_input:🐭:MouseMotion` events. Consider
reading from the `EventReader` more often (generally the best
solution) or calling Events::update() less frequently
(normally this is called once per frame). This problem is most
likely due to run criteria/fixed timesteps or consuming events
conditionally. See the Events documentation for
more information.
when you miss events. These warnings were often (but not always) a false positive. You can still check this manually by using `ManualEventReader::missed_events`
# Objective
Remove an obscure and inconsistent bit of API.
Simplify the `WorldChildBuilder` code.
No idea why this even exists.
An example of the removed API:
```rust
world.spawn_empty().with_children(|parent| {
parent.spawn_empty();
parent.push_children(&[some_entity]); // Does *not* add children to the parent.
// It's actually identical to:
parent.spawn_empty().push_children(&[some_entity]);
});
world.spawn_empty().with_children(|parent| {
// This just panics.
parent.push_children(&[some_entity]);
});
```
This exists only on `WorldChildBuilder`; `ChildBuilder` does not have this API.
Yeet.
## Migration Guide
Hierarchy editing methods such as `with_children` and `push_children` have been removed from `WorldChildBuilder`.
You can edit the hierarchy via `EntityMut` instead.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Fixes#6713
Binary deserialization is failing for unit structs as well as structs with all ignored/skipped fields.
## Solution
Add a check for the number of possible fields in a struct before deserializing. If empty, don't attempt to deserialize any fields (as there will be none).
Note: ~~This does not apply to enums as they do not properly handle skipped fields (see #6721).~~ Enums still do not properly handle skipped fields, but I decided to include the logic for it anyways to account for `#[reflect(ignore)]`'d fields in the meantime.
---
## Changelog
- Fix bug where deserializing unit structs would fail for non-self-describing formats
# Objective
Consider the test
```rust
let cell = world.cell();
let _value_a = cell.resource_mut::<A>();
let _value_b = cell.resource_mut::<A>();
```
Currently, this will roughly execute
```rust
// first call
let value = unsafe {
self.world
.get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(value, archetype_component_id, self.access)))
// second call
let value = unsafe {
self.world
.get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(value, archetype_component_id, self.access)))
```
where `WorldBorrowMut::new` will panic if the resource is already borrowed.
This means, that `_value_a` will be created, the access checked (OK), then `value_b` will be created, and the access checked (`panic`).
For a moment, both `_value_a` and `_value_b` existed as `&mut T` to the same location, which is insta-UB as far as I understand it.
## Solution
Flip the order so that `WorldBorrowMut::new` first checks the access, _then_ fetches creates the value. To do that, we pass a `impl FnOnce() -> Mut<T>` instead of the `Mut<T>` directly:
```rust
let get_value = || unsafe {
self.world
.get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(get_value, archetype_component_id, self.access)))
```
# Objective
- shaders defs can now have a `bool` or `int` value
- `#if SHADER_DEF <operator> 3`
- ok if `SHADER_DEF` is defined, has the correct type and pass the comparison
- `==`, `!=`, `>=`, `>`, `<`, `<=` supported
- `#SHADER_DEF` or `#{SHADER_DEF}`
- will be replaced by the value in the shader code
---
## Migration Guide
- replace `shader_defs.push(String::from("NAME"));` by `shader_defs.push("NAME".into());`
- if you used shader def `NO_STORAGE_BUFFERS_SUPPORT`, check how `AVAILABLE_STORAGE_BUFFER_BINDINGS` is now used in Bevy default shaders
# Objective
`add_node_edge` and `add_slot_edge` are fallible methods, but are always used with `.unwrap()`.
`input_node` is often unwrapped as well.
This points to having an infallible behaviour as default, with an alternative fallible variant if needed.
Improves readability and ergonomics.
## Solution
- Change `add_node_edge` and `add_slot_edge` to panic on error.
- Change `input_node` to panic on `None`.
- Add `try_add_node_edge` and `try_add_slot_edge` in case fallible methods are needed.
- Add `get_input_node` to still be able to get an `Option`.
---
## Changelog
### Added
- `try_add_node_edge`
- `try_add_slot_edge`
- `get_input_node`
### Changed
- `add_node_edge` is now infallible (panics on error)
- `add_slot_edge` is now infallible (panics on error)
- `input_node` now panics on `None`
## Migration Guide
Remove `.unwrap()` from `add_node_edge` and `add_slot_edge`.
For cases where the error was handled, use `try_add_node_edge` and `try_add_slot_edge` instead.
Remove `.unwrap()` from `input_node`.
For cases where the option was handled, use `get_input_node` instead.
Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
# Objective
Fixes#4697. Hierarchical propagation of properties, currently only Transform -> GlobalTransform, can be a very expensive operation. Transform propagation is a strict dependency for anything positioned in world-space. In large worlds, this can take quite a bit of time, so limiting it to a single thread can result in poor CPU utilization as it bottlenecks the rest of the frame's systems.
## Solution
- Move transforms without a parent or a child (free-floating (Global)Transform) entities into a separate parallel system.
- Chunk the hierarchy based on the root entities and process it in parallel with `Query::par_for_each_mut`.
- Utilize the hierarchy's specific properties introduced in #4717 to allow for safe use of `Query::get_unchecked` on multiple threads. Assuming each child is unique in the hierarchy, it is impossible to have an aliased `&mut GlobalTransform` so long as we verify that the parent for a child is the same one propagated from.
---
## Changelog
Removed: `transform_propagate_system` is no longer `pub`.
Without this fix, piped systems containing exclusive systems fail to run, giving a runtime panic.
With this PR, running piped systems that contain exclusive systems now works.
## Explanation of the bug
This is because, unless overridden, the default implementation of `run` from the `System` trait simply calls `run_unsafe`. That is not valid for exclusive systems. They must always be called via `run`, as `run_unsafe` takes `&World` instead of `&mut World`.
Trivial reproduction example:
```rust
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_system(exclusive.pipe(another))
.run();
}
fn exclusive(_world: &mut World) {}
fn another() {}
```
If you run this, you will get a panic 'Cannot run exclusive systems with a shared World reference' and the backtrace shows how bevy (correctly) tries to call the `run` method (because the system is exclusive), but it is the implementation from the `System` trait (because `PipeSystem` does not have its own), which calls `run_unsafe` (incorrect):
- 3: <bevy_ecs::system::system_piping::PipeSystem<SystemA,SystemB> as bevy_ecs::system::system::System>::run_unsafe
- 4: bevy_ecs::system::system::System::run
# Objective
Allow more use cases where the user may benefit from both `ExtractComponentPlugin` _and_ `UniformComponentPlugin`.
## Solution
Add an associated type to `ExtractComponent` in order to allow specifying the output component (or bundle).
Make `extract_component` return an `Option<_>` such that components can be extracted only when needed.
What problem does this solve?
`ExtractComponentPlugin` allows extracting components, but currently the output type is the same as the input.
This means that use cases such as having a settings struct which turns into a uniform is awkward.
For example we might have:
```rust
struct MyStruct {
enabled: bool,
val: f32
}
struct MyStructUniform {
val: f32
}
```
With the new approach, we can extract `MyStruct` only when it is enabled, and turn it into its related uniform.
This chains well with `UniformComponentPlugin`.
The user may then:
```rust
app.add_plugin(ExtractComponentPlugin::<MyStruct>::default());
app.add_plugin(UniformComponentPlugin::<MyStructUniform>::default());
```
This then saves the user a fair amount of boilerplate.
## Changelog
### Changed
- `ExtractComponent` can specify output type, and outputting is optional.
Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
Add a method to rotate a transform to point towards a direction.
Also updated the docs to link to `forward` and `up` instead of mentioning local negative `Z` and local `Y`.
Unfortunately, links to methods don't work in rust-analyzer :(
Co-authored-by: Devil Ira <justthecooldude@gmail.com>
# Objective
Latest Release, "bevy 0.9" move the FrameCount updater into RenderPlugin, it leads to user who only run app with Core/Minimal Plugin cannot get the right number of FrameCount, it always return 0.
As for use cases like a server app, we don't want to add render dependencies to the app.
More detail in #6656
## Solution
- Move the `update_frame_count` into CorePlugin
# Objective
This add a ctor to `Box` to aid the creation of non-centred boxes. The PR adopts @rezural's work on PR #3322, taking into account the feedback on that PR from @james7132.
## Solution
`Box::from_corners()` creates a `Box` from two opposing corners and automatically determines the min and max extents to ensure that the `Box` is well-formed.
Co-authored-by: rezural <rezural@protonmail.com>
# Objective
- Bevy should be usable to create 'overlay' type apps, where the input is not captured by Bevy, but passed down/into a target app, or to allow passive displays/widgets etc.
## Solution
- the `winit:🪟:Window` already has a `set_cursor_hittest()` which basically does this for mouse input events, so I've exposed it (trying to copy the style laid out in the existing wrappings, and added a simple demo.
---
## Changelog
- Added `hittest` to `WindowAttributes`
- Added the `hittest`'s setters/getters
- Modified the `WindowBuilder`
- Modifed the `WindowDescriptor`'s `Default` impl.
- Added an example `cargo run --example fallthrough`
# Objective
Fixes#4884. `ComponentTicks` stores both added and changed ticks contiguously in the same 8 bytes. This is convenient when passing around both together, but causes half the bytes fetched from memory for the purposes of change detection to effectively go unused. This is inefficient when most queries (no filter, mutating *something*) only write out to the changed ticks.
## Solution
Split the storage for change detection ticks into two separate `Vec`s inside `Column`. Fetch only what is needed during iteration.
This also potentially also removes one blocker from autovectorization of dense queries.
EDIT: This is confirmed to enable autovectorization of dense queries in `for_each` and `par_for_each` where possible. Unfortunately `iter` has other blockers that prevent it.
### TODO
- [x] Microbenchmark
- [x] Check if this allows query iteration to autovectorize simple loops.
- [x] Clean up all of the spurious tuples now littered throughout the API
### Open Questions
- ~~Is `Mut::is_added` absolutely necessary? Can we not just use `Added` or `ChangeTrackers`?~~ It's optimized out if unused.
- ~~Does the fetch of the added ticks get optimized out if not used?~~ Yes it is.
---
## Changelog
Added: `Tick`, a wrapper around a single change detection tick.
Added: `Column::get_added_ticks`
Added: `Column::get_column_ticks`
Added: `SparseSet::get_added_ticks`
Added: `SparseSet::get_column_ticks`
Changed: `Column` now stores added and changed ticks separately internally.
Changed: Most APIs returning `&UnsafeCell<ComponentTicks>` now returns `TickCells` instead, which contains two separate `&UnsafeCell<Tick>` for either component ticks.
Changed: `Query::for_each(_mut)`, `Query::par_for_each(_mut)` will now leverage autovectorization to speed up query iteration where possible.
## Migration Guide
TODO
# Objective
Fix#6453.
## Solution
Use the solution mentioned in the issue by catching the unwind and dropping the error. Wrap the `executor.try_tick` calls with `std::catch::unwind`.
Ideally this would be moved outside of the hot loop, but the mut ref to the `spawned` future is not `UnwindSafe`.
This PR only addresses the bug, we can address the perf issues (should there be any) later.
# Objective
Fix#5149
## Solution
Instead of returning the **total count** of elements in the `QueryIter` in
`size_hint`, we return the **count of remaining elements**. This
Fixes#5149 even when #5148 gets merged.
- https://github.com/bevyengine/bevy/issues/5149
- https://github.com/bevyengine/bevy/pull/5148
---
## Changelog
- Fix partially consumed `QueryIter` and `QueryCombinationIter` having invalid `size_hint`
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
# Objective
Make core pipeline graphic nodes, including `BloomNode`, `FxaaNode`, `TonemappingNode` and `UpscalingNode` public.
This will allow users to construct their own render graphs with these build-in nodes.
## Solution
Make them public.
Also put node names into bevy's core namespace (`core_2d::graph::node`, `core_3d::graph::node`) which makes them consistent.
# Objective
Fix android touch events being flipped. Only removed test for android, don't have ios device to test with. Tested with emulator and physical device.
## Solution
Remove check, no longer needed with coordinate change in 0.9
# Objective
Delete `ImageMode`. It doesn't do anything except mislead people into thinking it controls the aspect ratio of images somehow.
Fixes#3933 and #6637
## Solution
Delete `ImageMode`
## Changelog
Removes the `ImageMode` enum.
Removes the `image_mode` field from `ImageBundle`
Removes the `With<ImageMode>` query filter from `image_node_system`
Renames `image_node_system` to` update_image_calculated_size_system`
# Objective
Fixes#6661
## Solution
Make `SceneSpawner::spawn_dynamic` return `InstanceId` like other functions there.
---
## Changelog
Make `SceneSpawner::spawn_dynamic` return `InstanceId` instead of `()`.
When I was upgrading to 0.9 noticed there were some changes to the timer, mainly the `TimerMode`. When switching from the old `is_repeating()` and `set_repeating()` to the new `mode()` and `set_mode()` noticed the docs still had the old description.
# Objective
BlobVec currently relies on a scratch piece of memory allocated at initialization to make a temporary copy of a component when using `swap_remove_and_{forget/drop}`. This is potentially suboptimal as it writes to a, well-known, but random part of memory instead of using the stack.
## Solution
As the `FIXME` in the file states, replace `swap_scratch` with a call to `swap_nonoverlapping::<u8>`. The swapped last entry is returned as a `OwnedPtr`.
In theory, this should be faster as the temporary swap is allocated on the stack, `swap_nonoverlapping` allows for easier vectorization for bigger types, and the same memory is used between the swap and the returned `OwnedPtr`.
# Objective
* Enable `Res` and `Query` parameter mutual exclusion
* Required for https://github.com/bevyengine/bevy/pull/5080
The `FilteredAccessSet::get_conflicts` methods didn't work properly with
`Res` and `ResMut` parameters. Because those added their access by using
the `combined_access_mut` method and directly modifying the global
access state of the FilteredAccessSet. This caused an inconsistency,
because get_conflicts assumes that ALL added access have a corresponding
`FilteredAccess` added to the `filtered_accesses` field.
In practice, that means that SystemParam that adds their access through
the `Access` returned by `combined_access_mut` and the ones that add
their access using the `add` method lived in two different universes. As
a result, they could never be mutually exclusive.
## Solution
This commit fixes it by removing the `combined_access_mut` method. This
ensures that the `combined_access` field of FilteredAccessSet is always
updated consistently with the addition of a filter. When checking for
filtered access, it is now possible to account for `Res` and `ResMut`
invalid access. This is currently not needed, but might be in the
future.
We add the `add_unfiltered_{read,write}` methods to replace previous
usages of `combined_access_mut`.
We also add improved Debug implementations on FixedBitSet so that their
meaning is much clearer in debug output.
---
## Changelog
* Fix `Res` and `Query` parameter never being mutually exclusive.
## Migration Guide
Note: this mostly changes ECS internals, but since the API is public, it is technically breaking:
* Removed `FilteredAccessSet::combined_access_mut`
* Replace _immutable_ usage of those by `combined_access`
* For _mutable_ usages, use the new `add_unfiltered_{read,write}` methods instead of `combined_access_mut` followed by `add_{read,write}`
# Objective
Make core types in ECS smaller. The column sparse set in Tables is never updated after creation.
## Solution
Create `ImmutableSparseSet` which removes the capacity fields in the backing vec's and the APIs for inserting or removing elements. Drops the size of the sparse set by 3 usizes (24 bytes on 64-bit systems)
## Followup
~~After #4809, Archetype's component SparseSet should be replaced with it.~~ This has been done.
---
## Changelog
Removed: `Table::component_capacity`
## Migration Guide
`Table::component_capacity()` has been removed as Tables do not support adding/removing columns after construction.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Archetype is a deceptively large type in memory. It stores metadata about which components are in which storage in multiple locations, which is only used when creating new Archetypes while moving entities.
## Solution
Remove the redundant `Box<[ComponentId]>`s and iterate over the sparse set of component metadata instead. Reduces Archetype's size by 4 usizes (32 bytes on 64-bit systems), as well as the additional allocations for holding these slices.
It'd seem like there's a downside that the origin archetype has it's component metadata iterated over twice when creating a new archetype, but this change also removes the extra `Vec<ArchetypeComponentId>` allocations when creating a new archetype which may amortize out to a net gain here. This change likely negatively impacts creating new archetypes with a large number of components, but that's a cost mitigated by the fact that these archetypal relationships are cached in Edges and is incurred only once for each edge created.
## Additional Context
There are several other in-flight PRs that shrink Archetype:
- #4800 merges the entities and rows Vecs together (shaves off 24 bytes per archetype)
- #4809 removes unique_components and moves it to it's own dedicated storage (shaves off 72 bytes per archetype)
---
## Changelog
Changed: `Archetype::table_components` and `Archetype::sparse_set_components` return iterators instead of slices. `Archetype::new` requires iterators instead of parallel slices/vecs.
## Migration Guide
Do I still need to do this? I really hope people were not relying on the public facing APIs changed here.
# Objective
`ComputedVisibility` could afford to be smaller/faster. Optimizing the size and performance of operations on the component will positively benefit almost all extraction systems.
This was listed as one of the potential pieces of future work for #5310.
## Solution
Merge both internal booleans into a single `u8` bitflag field. Rely on bitmasks to evaluate local, hierarchical, and general visibility.
Pros:
- `ComputedVisibility::is_visible` should be a single bitmask test instead of two.
- `ComputedVisibility` is now only 1 byte. Should be able to fit 100% more per cache line when using dense iteration.
Cons:
- Harder to read.
- Setting individual values inside `ComputedVisiblity` require bitmask mutations.
This should be a non-breaking change. No public API was changed. The only publicly visible effect is that `ComputedVisibility` is now 1 byte instead of 2.
# Objective
Fixes#6594
## Solution
- `New` function for `Size` is now a `const` function :)
## Changelog
- `New` function for `Size` is now a `const` function
## Migration Guide
- Nothing has been changed
# Objective
In bevy 0.8 you could list all resources using `world.archetypes().resource().components()`. As far as I can tell the resource archetype has been replaced with the `Resources` storage, and it would be nice if it could be used to iterate over all resource component IDs as well.
## Solution
- add `fn Resources::iter(&self) -> impl Iterator<Item = (ComponentId, &ResourceData)>`
# Objective
- Derive Clone and Debug for `AssetPlugin`
- Make it possible to log asset server settings
- And get an owned instance if wrapping `AssetPlugin` in another plugin. See: 129224ef72/src/web_asset_plugin.rs (L45)
# Objective
> Part of #6573
`Children` was not being properly deserialized in scenes. This was due to a missing registration on `SmallVec<[Entity; 8]>`, which is used by `Children`.
## Solution
Register `SmallVec<[Entity; 8]>`.
---
## Changelog
- Registered `SmallVec<[Entity; 8]>`
# Objective
Fixes#6030, making ``serde`` optional.
## Solution
This was solved by making a ``serialize`` feature that can activate ``serde``, which is now optional.
When ``serialize`` is deactivated, the ``Plugin`` implementation for ``ScenePlugin`` does nothing.
Co-authored-by: Linus Käll <linus.kall.business@gmail.com>
# Objective
Currently, `Ptr` and `PtrMut` can only be constructed via unsafe code. This means that downgrading a reference to an untyped pointer is very cumbersome, despite being a very simple operation.
## Solution
Define conversions for easily and safely constructing untyped pointers. This is the non-owned counterpart to `OwningPtr::make`.
Before:
```rust
let ptr = unsafe { PtrMut::new(NonNull::from(&mut value).cast()) };
```
After:
```rust
let ptr = PtrMut::from(&mut value);
```
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
I needed a window which is always on top, to create a overlay app.
## Solution
expose the `always_on_top` property of winit in bevy's `WindowDescriptor` as a boolean flag
---
## Changelog
### Added
- add `WindowDescriptor.always_on_top` which configures a window to stay on top.
# Objective
`ScalingMode::Auto` for cameras only targets min_height and min_width, or as the docs say it `Use minimal possible viewport size while keeping the aspect ratio.`
But there is no ScalingMode that targets max_height and Max_width or `Use maximal possible viewport size while keeping the aspect ratio.`
## Solution
Added `ScalingMode::AutoMax` that does the exact opposite of `ScalingMode::Auto`
---
## Changelog
Renamed `ScalingMode::Auto` to `ScalingMode::AutoMin`.
## Migration Guide
just rename `ScalingMode::Auto` to `ScalingMode::AutoMin` if you are using it.
Co-authored-by: Lixou <82600264+DasLixou@users.noreply.github.com>
Add a method to get the focused window.
Use this instead of `WindowFocused` events in `close_on_esc`.
Seems that the OS/window manager might not always send focused events on application startup.
Sadly, not a fix for #5646.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Fixes #3225, Allow for flippable UI Images
## Solution
Add flip_x and flip_y fields to UiImage, and swap the UV coordinates accordingly in ui_prepare_nodes.
## Changelog
* Changes UiImage to a struct with texture, flip_x, and flip_y fields.
* Adds flip_x and flip_y fields to ExtractedUiNode.
* Changes extract_uinodes to extract the flip_x and flip_y values from UiImage.
* Changes prepare_uinodes to swap the UV coordinates as required.
* Changes UiImage derefs to texture field accesses.
# Objective
Fixes#6615.
`BlobVec` does not respect alignment for zero-sized types, which results in UB whenever a ZST with alignment other than 1 is used in the world.
## Solution
Add the fn `bevy_ptr::dangling_with_align`.
---
## Changelog
+ Added the function `dangling_with_align` to `bevy_ptr`, which creates a well-aligned dangling pointer to a type whose alignment is not known at compile time.
# Objective
- Implements removal of entries from a `dyn Map`
- Fixes#6563
## Solution
- Adds a `remove` method to the `Map` trait which takes in a `&dyn Reflect` key and returns the value removed if it was present.
---
## Changelog
- Added `Map::remove`
## Migration Guide
- Implementors of `Map` will need to implement the `remove` method.
Co-authored-by: radiish <thesethskigamer@gmail.com>
# Objective
The [documentation for `ButtonSettingsError`](https://docs.rs/bevy/0.9.0/bevy/input/gamepad/enum.ButtonSettingsError.html) incorrectly describes the valid range of values as `0.0..=2.0`, probably because it was copied from `AxisSettingsError`. The actual range, as seen in the functions that return it and in its own `thiserror` description, is `0.0..=1.0`.
## Solution
Update the doc comments to reflect the correct range.
Co-authored-by: Sol Toder <ajaxgb@gmail.com>
# Objective
Fix#6548. Most of these methods were already made `const` in #5688. `Entity::to_bits` is the only one that remained.
## Solution
Make it const.
# Objective
- Fix#3606
- Fix#4579
- Fix#3380
## Solution
When running on a Linux machine with some AMD or Intel device, when calling
`surface.get_current_texture()`, ignore `wgpu::SurfaceError::Timeout` errors.
## Alternative
An alternative solution found in the `wgpu` examples is:
```rust
let frame = surface
.get_current_texture()
.or_else(|_| {
render_device.configure_surface(surface, &swap_chain_descriptor);
surface.get_current_texture()
})
.expect("Error reconfiguring surface");
window.swap_chain_texture = Some(TextureView::from(frame));
```
See: <94ce76391b/wgpu/examples/framework.rs (L362-L370)>
Veloren [handles the Timeout error the way this PR proposes to handle it](https://github.com/gfx-rs/wgpu/issues/1218#issuecomment-1092056971).
The reason I went with this PR's solution is that `configure_surface` seems to be quite an expensive operation, and it would run every frame with the wgpu framework solution, despite the fact it works perfectly fine without `configure_surface`.
I know this looks super hacky with the linux-specific line and the AMD check, but my understanding is that the `Timeout` occurrence is specific to a quirk of some AMD drivers on linux, and if otherwise met should be considered a bug.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Closes#5262
- Fix color banding caused by quantization.
## Solution
- Adds dithering to the tonemapping node from #3425.
- This is inspired by Godot's default "debanding" shader: https://gist.github.com/belzecue/
- Unlike Godot:
- debanding happens after tonemapping. My understanding is that this is preferred, because we are running the debanding at the last moment before quantization (`[f32, f32, f32, f32]` -> `f32`). This ensures we aren't biasing the dithering strength by applying it in a different (linear) color space.
- This code instead uses and reference the origin source, Valve at GDC 2015
![Screenshot from 2022-11-10 13-44-46](https://user-images.githubusercontent.com/2632925/201218880-70f4cdab-a1ed-44de-a88c-8759e77197f1.png)
![Screenshot from 2022-11-10 13-41-11](https://user-images.githubusercontent.com/2632925/201218883-72393352-b162-41da-88bb-6e54a1e26853.png)
## Additional Notes
Real time rendering to standard dynamic range outputs is limited to 8 bits of depth per color channel. Internally we keep everything in full 32-bit precision (`vec4<f32>`) inside passes and 16-bit between passes until the image is ready to be displayed, at which point the GPU implicitly converts our `vec4<f32>` into a single 32bit value per pixel, with each channel (rgba) getting 8 of those 32 bits.
### The Problem
8 bits of color depth is simply not enough precision to make each step invisible - we only have 256 values per channel! Human vision can perceive steps in luma to about 14 bits of precision. When drawing a very slight gradient, the transition between steps become visible because with a gradient, neighboring pixels will all jump to the next "step" of precision at the same time.
### The Solution
One solution is to simply output in HDR - more bits of color data means the transition between bands will become smaller. However, not everyone has hardware that supports 10+ bit color depth. Additionally, 10 bit color doesn't even fully solve the issue, banding will result in coherent bands on shallow gradients, but the steps will be harder to perceive.
The solution in this PR adds noise to the signal before it is "quantized" or resampled from 32 to 8 bits. Done naively, it's easy to add unneeded noise to the image. To ensure dithering is correct and absolutely minimal, noise is adding *within* one step of the output color depth. When converting from the 32bit to 8bit signal, the value is rounded to the nearest 8 bit value (0 - 255). Banding occurs around the transition from one value to the next, let's say from 50-51. Dithering will never add more than +/-0.5 bits of noise, so the pixels near this transition might round to 50 instead of 51 but will never round more than one step. This means that the output image won't have excess variance:
- in a gradient from 49 to 51, there will be a step between each band at 49, 50, and 51.
- Done correctly, the modified image of this gradient will never have a adjacent pixels more than one step (0-255) from each other.
- I.e. when scanning across the gradient you should expect to see:
```
|-band-| |-band-| |-band-|
Baseline: 49 49 49 50 50 50 51 51 51
Dithered: 49 50 49 50 50 51 50 51 51
Dithered (wrong): 49 50 51 49 50 51 49 51 50
```
![Screenshot from 2022-11-10 14-12-36](https://user-images.githubusercontent.com/2632925/201219075-ab3f46be-d4e9-4869-b66b-a92e1706f49e.png)
![Screenshot from 2022-11-10 14-11-48](https://user-images.githubusercontent.com/2632925/201219079-ec5d2add-817d-487a-8fc1-84569c9cda73.png)
You can see from above how correct dithering "fuzzes" the transition between bands to reduce distinct steps in color, without adding excess noise.
### HDR
The previous section (and this PR) assumes the final output is to an 8-bit texture, however this is not always the case. When Bevy adds HDR support, the dithering code will need to take the per-channel depth into account instead of assuming it to be 0-255. Edit: I talked with Rob about this and it seems like the current solution is okay. We may need to revisit once we have actual HDR final image output.
---
## Changelog
### Added
- All pipelines now support deband dithering. This is enabled by default in 3D, and can be toggled in the `Tonemapping` component in camera bundles. Banding is a graphical artifact created when the rendered image is crunched from high precision (f32 per color channel) down to the final output (u8 per channel in SDR). This results in subtle gradients becoming blocky due to the reduced color precision. Deband dithering applies a small amount of noise to the signal before it is "crunched", which breaks up the hard edges of blocks (bands) of color. Note that this does not add excess noise to the image, as the amount of noise is less than a single step of a color channel - just enough to break up the transition between color blocks in a gradient.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- Make the many foxes not unnecessarily bright. Broken since #5666.
- Fixes#6528
## Solution
- In #5666 normalisation of normals was moved from the fragment stage to the vertex stage. However, it was not added to the vertex stage for skinned normals. The many foxes are skinned and their skinned normals were not unit normals. which made them brighter. Normalising the skinned normals fixes this.
---
## Changelog
- Fixed: Non-unit length skinned normals are now normalized.
This reverts commit 8429b6d6ca as discussed in #6522.
I tested that the game_menu example works as it should.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Attempting to build `bevy_tasks` produces the following error:
```
error[E0599]: no method named `is_finished` found for struct `async_executor::Task` in the current scope
--> /[...]]/bevy/crates/bevy_tasks/src/task.rs:51:16
|
51 | self.0.is_finished()
| ^^^^^^^^^^^ method not found in `async_executor::Task<T>`
```
It looks like this was introduced along with `Task::is_finished`, which delegates to `async_task::Task::is_finished`. However, the latter was only introduced in `async-task` 4.2.0; `bevy_tasks` does not explicitly depend on `async-task` but on `async-executor` ^1.3.0, which in turn depends on `async-task` ^4.0.0.
## Solution
Add an explicit dependency on `async-task` ^4.2.0.
# Objective
Copy `send_event` and friends from `World` to `WorldCell`.
Clean up `bevy_winit` using `WorldCell::send_event`.
## Changelog
Added `send_event`, `send_event_default`, and `send_event_batch` to `WorldCell`.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
- it would be useful to inspect these structs using reflection
## Solution
- derive and register reflect
- Note that `#[reflect(Component)]` requires `Default` (or `FromWorld`) until #6060, so I implemented `Default` for `Tonemapping` with `is_enabled: false`
# Objective
The `load_internal_asset` macro is helpful when creating rendering plugins, but it doesn't support load binary assets (like those compiled as spir-v).
## Solution
Add a `load_internal_binary_asset` macro that use `include_bytes!`.
# Objective
Fixes#5393
## Solution
- Add padding to `GlobalsUniform` / `Globals` to make it 16-byte aligned.
Still not super clear on whether this is a `naga` thing or an `encase` thing or what. But now that we're offering `globals` up to users and #5393 is not just breaking an example, maybe we should do this sort of workaround?
* Move the despawn debug log from `World::despawn` to `EntityMut::despawn`.
* Move the despawn non-existent warning log from `Commands::despawn` to `World::despawn`.
This should make logging consistent regardless of which of the three `despawn` methods is used.
Co-authored-by: devil-ira <justthecooldude@gmail.com>