# Objective
Making work with `Indices` struct easier. Currently when building
indices in some quick-and-dirty code we need to do matches and handle
enum variants.
## Solution
`Indices::push` utility which works transparently with `U16` and `U32`
variants.
## Testing
Unit test added.
# Objective
Built-in observers & events should be `Reflect` so that components that
interact with them can be serialized in scenes. This is a similar pr to
#14259.
## Objective
Be able to depend on the crate for the types without bringing in
`smol-hyper` and other http dependencies.
## Solution
Create a new `HTTP` feature that is enabled by default.
# Objective
Make UI rendering optional.
Quite a few people have been experimenting with using Bevy UI for layout
and interaction but replacing the rendering with `bevy_prototype_lyon`
or whatever. It's awkward to do though as there is no way to disable the
existing UI rendering requiring users to create their own custom node
bundles and components. Also, you can't replace the UI's shader and a
number of other things.
This PR makes the setup and initialization of UI rendering for the
RenderApp optional. Then you can do whatever you want by replacing
`build_ui_render` with your own function. For instance, one that loads a
custom shader.
The UI layout and interaction components are still updated as normal.
## Solution
Add a field `enable_rendering` to `UiPlugin`.
Only call `build_ui_render` and initialize the `UiPipeline` if
`enable_rendering` is false.
I thought about implementing a "bevy_ui_render" feature but suspect
everything is too tightly coupled atm and it would be very fragile.
Similar to the struggles with the "bevy_text" feature but worse.
---
## Changelog
`UiPlugin`
* Added a bool field `enable_rendering`.
* Only calls `build_ui_render` and initializes the `UiPipeline` if
`enable_rendering` is true.
## Migration Guide
`UiPlugin` has a new field `enable_rendering`. If set to false, the UI's
rendering systems won't be added to the `RenderApp` and no UI elements
will be drawn. The layout and interaction components will still be
updated as normal.
# Objective
Adding a `WinitPlugin` to a `MinimalPlugins` setup is a bit tricky and
confusing due to having a terrible error message and no examples in the
repo.
## Solution
Document what you need to add.
# Objective
- Progress towards #15918
- Add tests for 3d
## Solution
- Add tests that cover lights, bloom, gltf and animation
- Removed examples `contributors` and `load_gltf` as they don't
contribute additional checks to CI
## Testing
- `CI_TESTING_CONFIG=.github/example-run/testbed_3d.ron cargo run
--example testbed_3d --features "bevy_ci_testing"`
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/15871
(Camera is done in #15946)
## Solution
- Do the same as #15904 for other extraction systems
- Added missing `SyncComponentPlugin` for DOF, TAA, and SSAO
(According to the
[documentation](https://dev-docs.bevyengine.org/bevy/render/sync_component/struct.SyncComponentPlugin.html),
this plugin "needs to be added for manual extraction implementations."
We may need to check this is done.)
## Testing
Modified example locally to add toggles if not exist.
- [x] DOF - toggling DOF component and perspective in `depth_of_field`
example
- [x] TAA - toggling `Camera.is_active` and TAA component
- [x] clusters - not entirely sure, toggling `Camera.is_active` in
`many_lights` example (no crash/glitch even without this PR)
- [x] previous_view - toggling `Camera.is_active` in `skybox` (no
crash/glitch even without this PR)
- [x] lights - toggling `Visibility` of `DirectionalLight` in `lighting`
example
- [x] SSAO - toggling `Camera.is_active` and SSAO component in `ssao`
example
- [x] default UI camera view - toggling `Camera.is_active` (nop without
#15946 because UI defaults to some camera even if `DefaultCameraView` is
not there)
- [x] volumetric fog - toggling existence of volumetric light. Looks
like optimization, no change in behavior/visuals
# Objective
Switch to retained render world causes the extracted cameras in render
world to not be removed until camera in main world is despawned. When
extracting data from main world inactive cameras are skipped. Therefore
camera that was active and became inactive has a retained
`ExtractedCamera` component from previous frames (when it was active)
and is processed the same way as if it were active (there is no `active`
field on `ExtractedCamera`). This breakes switching between cameras in
`render_primitives` example.
Fixes#15822
## Solution
Fix it by removing `ExtractedCamera` and related components from
inactive cameras.
Note that despawning inactive camera seems to be bad option because they
are spawned using `SyncToRenderWorld` component.
## Testing
Switching camera in `render_primitives` example now works correctly.
---------
Co-authored-by: akimakinai <105044389+akimakinai@users.noreply.github.com>
# Objective
- The depth test was only using the final depth but it should be testing
each fragments
- Fully transparent fragments should not be added to the list
## Solution
- Test each fragment after sorting
## Testing
before:
TODO
after:
TODO
# Objective
The Custom Material GLSL shader example has an old version of the camera
view uniform structure.
This PR updates the example GLSL custom material shader to have the
latest structure.
## Solution
I was running into issues using the camera world position (it wasn't
changing) and someone in discord pointed me to the source of truth.
`crates/bevy_render/src/view/view.wgsl`
After using this latest uniform structure in my project I'm now able to
work with the camera position in my shader.
## Testing
I tested this change by running the example with:
```bash
cargo run --features shader_format_glsl --example shader_material_glsl
```
<img width="1392" alt="image"
src="https://github.com/user-attachments/assets/39fc82ec-ff3b-4864-ad73-05f3a25db483">
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Fixes#15995
## Solution
Corrects a mistake made during the example migration in #15591.
`AnimationControl` was meant to be on the parent, not the child. So the
query in `update_ui` was no longer matching.
## Testing
`cargo run --example animation_masks`
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/13552
## Solution
- Thanks for the guidance from @DGriffin91, the current solution is to
transmit the light_map through the emissive channel to avoid increasing
the bandwidth of deferred shading.
- <del>Store lightmap sample result into G-Buffer and pass them into the
`Deferred Lighting Pipeline`, therefore we can get the correct indirect
lighting via the `apply_pbr_lighting` function.</del>
- <del>The original G-Buffer lacks storage for lightmap data, therefore
a new buffer is added. We can only use Rgba16Uint here due to the
32-byte limit on the render targets.</del>
## Testing
- Need to test all the examples that contains a prepass, with both the
forward and deferred rendering mode.
- I have tested the ones below.
- `lightmaps` (adjust the code based on the issue and check the
rendering result)
- `transmission` (it contains a prepass)
- `ssr` (it also uses the G-Bufffer)
- `meshlet` (forward and deferred)
- `pbr`
## Showcase
By updating the `lightmaps` example to use deferred rendering, this pull
request enables correct rendering result of the Cornell Box.
```
diff --git a/examples/3d/lightmaps.rs b/examples/3d/lightmaps.rs
index 564a3162b..11a748fba 100644
--- a/examples/3d/lightmaps.rs
+++ b/examples/3d/lightmaps.rs
@@ -1,12 +1,14 @@
//! Rendering a scene with baked lightmaps.
-use bevy::pbr::Lightmap;
+use bevy::core_pipeline::prepass::DeferredPrepass;
+use bevy::pbr::{DefaultOpaqueRendererMethod, Lightmap};
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(AmbientLight::NONE)
+ .insert_resource(DefaultOpaqueRendererMethod::deferred())
.add_systems(Startup, setup)
.add_systems(Update, add_lightmaps_to_meshes)
.run();
@@ -19,10 +21,12 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
..default()
});
- commands.spawn(Camera3dBundle {
- transform: Transform::from_xyz(-278.0, 273.0, 800.0),
- ..default()
- });
+ commands
+ .spawn(Camera3dBundle {
+ transform: Transform::from_xyz(-278.0, 273.0, 800.0),
+ ..default()
+ })
+ .insert(DeferredPrepass);
}
fn add_lightmaps_to_meshes(
```
<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/17fd3367-61cc-4c23-b956-e7cfc751af3c">
## Emissive Issue
**The emissive light object appears incorrectly rendered because the
alpha channel of emission is set to 1 in deferred rendering and 0 in
forward rendering, leading to different emissive light result. Could
this be a bug?**
```wgsl
// pbr_deferred_functions.wgsl - pbr_input_from_deferred_gbuffer
let emissive = rgb9e5::rgb9e5_to_vec3_(gbuffer.g);
if ((pbr.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) {
pbr.material.base_color = vec4(emissive, 1.0);
pbr.material.emissive = vec4(vec3(0.0), 1.0);
} else {
pbr.material.base_color = vec4(pow(base_rough.rgb, vec3(2.2)), 1.0);
pbr.material.emissive = vec4(emissive, 1.0);
}
// pbr_functions.wgsl - apply_pbr_lighting
emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a);
```
---------
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
# Objective
Continue improving the user experience of our UI Node API in the
direction specified by [Bevy's Next Generation Scene / UI
System](https://github.com/bevyengine/bevy/discussions/14437)
## Solution
As specified in the document above, merge `Style` fields into `Node`,
and move "computed Node fields" into `ComputedNode` (I chose this name
over something like `ComputedNodeLayout` because it currently contains
more than just layout info. If we want to break this up / rename these
concepts, lets do that in a separate PR). `Style` has been removed.
This accomplishes a number of goals:
## Ergonomics wins
Specifying both `Node` and `Style` is now no longer required for
non-default styles
Before:
```rust
commands.spawn((
Node::default(),
Style {
width: Val::Px(100.),
..default()
},
));
```
After:
```rust
commands.spawn(Node {
width: Val::Px(100.),
..default()
});
```
## Conceptual clarity
`Style` was never a comprehensive "style sheet". It only defined "core"
style properties that all `Nodes` shared. Any "styled property" that
couldn't fit that mold had to be in a separate component. A "real" style
system would style properties _across_ components (`Node`, `Button`,
etc). We have plans to build a true style system (see the doc linked
above).
By moving the `Style` fields to `Node`, we fully embrace `Node` as the
driving concept and remove the "style system" confusion.
## Next Steps
* Consider identifying and splitting out "style properties that aren't
core to Node". This should not happen for Bevy 0.15.
---
## Migration Guide
Move any fields set on `Style` into `Node` and replace all `Style`
component usage with `Node`.
Before:
```rust
commands.spawn((
Node::default(),
Style {
width: Val::Px(100.),
..default()
},
));
```
After:
```rust
commands.spawn(Node {
width: Val::Px(100.),
..default()
});
```
For any usage of the "computed node properties" that used to live on
`Node`, use `ComputedNode` instead:
Before:
```rust
fn system(nodes: Query<&Node>) {
for node in &nodes {
let computed_size = node.size();
}
}
```
After:
```rust
fn system(computed_nodes: Query<&ComputedNode>) {
for computed_node in &computed_nodes {
let computed_size = computed_node.size();
}
}
```
# Objective
Fixes#15976
## Solution
I haven't been following the recent camera changes but on a whim I
inverted the scale and it restored the old behavior.
It seems that a similar inversion was done when migrating the
`pixel_grid_snap` example in #15976.
## Testing
`cargo run --example pbr`
Resolves#15968. Since this feature never worked, and enabling it in the
`image` crate requires system dependencies, we've decided that it's best
to just remove it and let other plugin crates offer support for it as
needed.
## Migration Guide
AVIF images are no longer supported. They never really worked, and
require system dependencies (libdav1d) to work correctly, so, it's
better to simply offer this support via an unofficial plugin instead as
needed. The corresponding types have been removed from Bevy to account
for this.
# Objective
Fixes#15791.
As raised in #11022, scaling orthographic cameras is confusing! In Bevy
0.14, there were multiple completely redundant ways to do this, and no
clear guidance on which to use.
As a result, #15075 removed the `scale` field from
`OrthographicProjection` completely, solving the redundancy issue.
However, this resulted in an unintuitive API and a painful migration, as
discussed in #15791. Users simply want to change a single parameter to
zoom, rather than deal with the irrelevant details of how the camera is
being scaled.
## Solution
This PR reverts #15075, and takes an alternate, more nuanced approach to
the redundancy problem. `ScalingMode::WindowSize` was by far the biggest
offender. This was the default variant, and stored a float that was
*fully* redundant to setting `scale`.
All of the other variants contained meaningful semantic information and
had an intuitive scale. I could have made these unitless, storing an
aspect ratio, but this would have been a worse API and resulted in a
pointlessly painful migration.
In the course of this work I've also:
- improved the documentation to explain that you should just set `scale`
to zoom cameras
- swapped to named fields for all of the variants in `ScalingMode` for
more clarity about the parameter meanings
- substantially improved the `projection_zoom` example
- removed the footgunny `Mul` and `Div` impls for `ScalingMode`,
especially since these no longer have the intended effect on
`ScalingMode::WindowSize`.
- removed a rounding step because this is now redundant 🎉
## Testing
I've tested these changes as part of my work in the `projection_zoom`
example, and things seem to work fine.
## Migration Guide
`ScalingMode` has been refactored for clarity, especially on how to zoom
orthographic cameras and their projections:
- `ScalingMode::WindowSize` no longer stores a float, and acts as if its
value was 1. Divide your camera's scale by any previous value to achieve
identical results.
- `ScalingMode::FixedVertical` and `FixedHorizontal` now use named
fields.
---------
Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
# Objective
Adjust instruction text in some newer examples to match the [example
visual
guidelines](https://bevyengine.org/learn/contribute/helping-out/creating-examples/#visual-guidelines).
## Solution
Move text 12px from edge of screen
## Testing
```
cargo run --example alter_mesh
cargo run --example alter_sprite
cargo run --example camera_orbit
cargo run --example projection_zoom
cargo run --example irradiance_volumes
cargo run --example log_layers_ecs
cargo run --example multi_asset_sync
cargo run --example multiple_windows
cargo run --example order_independent_transparency
```
## Additional information
This isn't comprehensive, just the most trivial cases. I'll double check
my notes and probably follow up with an issue to look into visual
guidelines for a few other examples.
# Objective
- Fixes#15963
## Solution
- Implement `TryFrom<Polygon<N> for ConvexPolygon<N>`
- Implement `From<ConvexPolygon<N>> for Polygon<N>`
- Remove `pub` from `vertices`
- Add `ConvexPolygon::vertices()` to get read only access to the
vertices of a convex polygon.
# Objective
As discussed in #15341, ghost nodes are a contentious and experimental
feature. In the interest of enabling ecosystem experimentation, we've
decided to keep them in Bevy 0.15.
That said, we don't use them internally, and don't expect third-party
crates to support them. If the experimentation returns a negative result
(they aren't very useful, an alternative design is preferred etc) they
will be removed.
We should clearly communicate this status to users, and make sure that
users don't use ghost nodes in their projects without a very clear
understanding of what they're getting themselves into.
## Solution
To make life easy for users (and Bevy), `GhostNode` and all associated
helpers remain public and are always available.
However, actually constructing these requires enabling a feature flag
that's clearly marked as experimental. To do so, I've added a
meaningless private field.
When the feature flag is enabled, our constructs (`new` and `default`)
can be used. I've added a `new` constructor, which should be preferred
over `Default::default` as that can be readily deprecated, allowing us
to prompt users to swap over to the much nicer `GhostNode` syntax once
this is a unit struct again.
Full credit: this was mostly @cart's design: I'm just implementing it!
## Testing
I've run the ghost_nodes example and it fails to compile without the
feature flag. With the feature flag, it works fine :)
---------
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Fixes#15834
## Migration Guide
The APIs of `Time`, `Timer` and `Stopwatch` have been cleaned up for
consistency with each other and the standard library's `Duration` type.
The following methods have been renamed:
- `Stowatch::paused` -> `Stopwatch::is_paused`
- `Time::elapsed_seconds` -> `Time::elasped_secs` (including `_f64` and
`_wrapped` variants)
# Objective
- UI materials reserve too much capacity in a vec: for every node in the
transparent phase, it reserves enough memory to store all the nodes
- Update #10437
## Solution
- Only reserve extra memory if there's not enough
- Only reserve the needed memory, not more
# Objective
- Make progress for #15918
- Start with 2d
## Solution
- Remove screenshots for existing examples as they're not deterministic
- Create new "testbed" example category, with a 2d one to start
## Testing
- Run `CI_TESTING_CONFIG=.github/example-run/testbed_2d.ron cargo run
--example testbed_2d --features "bevy_ci_testing"`
- ???
- Check the screenshots
# Objective
In `queue_shadows`, the `UiBoxShadows` option is unwrapped incorrectly
which results in the number of shadow samples being set to
`u32::default()` instead of `UiBoxShadows::default()` if the camera
entity doesn't have the component.
## Solution
Just use `unwrap_or_default` directly without `map`.
# Objective
Remove `bevy-ui`'s non-functional "bevy_text" feature.
Fixes#15900
## Solution
Remove all the "bevy_text" cfg gates.
I tried to fix it at first but couldn't figure it out. I'll happily
withdraw this in favour of another PR that gets the feature gate
working.
# Objective
`TextFont` and `TextColor` is not registered in the app type registry
and serializing a scene with a a `Text2d` doesn't save the color and
font of the text entity.
## Solution
register `TextFont` and `TextColor` in the type registry
# Objective
In PR #15812 ImageLoader was moved from bevy_render to bevy_image but a
reference to old path was left in a meta file used by `asset_settings`
example. This resulted in one of sprites used by this example to not be
displayed.
Fixes#15932
## Solution
Correct the loader reference in the meta file used by `asset_settings`
example (I've found no other meta files referencing this loader).
## Testing
I've run `bevy_assets` example. It now displays 3 sprites (as expected)
and outputs no errors.
## Migration Guide
This PR obviously requires no migration guide as this is just a bug-fix,
but I believe that #15812 should mention that meta files needs updating.
Proposal:
* Asset loader name must be updated in `.meta` files for images.
Change: `loader: "bevy_render::texture::image_loader::ImageLoader",`
to: `loader: "bevy_image::image_loader::ImageLoader",`
It will fix the following error: ``no `AssetLoader` found with the name
'bevy_render::texture::image_loader::ImageLoader``
# Objective
Limited implementation of the CSS property `overflow-clip-margin`
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-margin
Allows you to control the visible area for clipped content when using
overfllow-clip, -hidden, or -scroll and expand it with a margin.
Based on #15442Fixes#15468
## Solution
Adds a new field to Style: `overflow_clip_margin: OverflowClipMargin`.
The field is ignored unless overflow-clip, -hidden or -scroll is set on
at least one axis.
`OverflowClipMargin` has these associated constructor functions:
```
pub const fn content_box() -> Self;
pub const fn padding_box() -> Self;
pub const fn border_box() -> Self;
```
You can also use the method `with_margin` to increases the size of the
visible area:
```
commands
.spawn(NodeBundle {
style: Style {
width: Val::Px(100.),
height: Val::Px(100.),
padding: UiRect::all(Val::Px(20.)),
border: UiRect::all(Val::Px(5.)),
overflow: Overflow::clip(),
overflow_clip_margin: OverflowClipMargin::border_box().with_margin(25.),
..Default::default()
},
border_color: Color::BLACK.into(),
background_color: GRAY.into(),
..Default::default()
})
```
`with_margin` expects a length in logical pixels, negative values are
clamped to zero.
## Notes
* To keep this PR as simple as possible I omitted responsive margin
values support. This could be added in a follow up if we want it.
* CSS also supports a `margin-box` option but we don't have access to
the margin values in `Node` so it's probably not feasible to implement
atm.
## Testing
```cargo run --example overflow_clip_margin```
<img width="396" alt="overflow-clip-margin" src="https://github.com/user-attachments/assets/07b51cd6-a565-4451-87a0-fa079429b04b">
## Migration Guide
Style has a new field `OverflowClipMargin`. It allows users to set the visible area for clipped content when using overflow-clip, -hidden, or -scroll and expand it with a margin.
There are three associated constructor functions `content_box`, `padding_box` and `border_box`:
* `content_box`: elements painted outside of the content box area (the innermost part of the node excluding the padding and border) of the node are clipped. This is the new default behaviour.
* `padding_box`: elements painted outside outside of the padding area of the node are clipped.
* `border_box`: elements painted outside of the bounds of the node are clipped. This matches the behaviour from Bevy 0.14.
There is also a `with_margin` method that increases the size of the visible area by the given number in logical pixels, negative margin values are clamped to zero.
`OverflowClipMargin` is ignored unless overflow-clip, -hidden or -scroll is also set on at least one axis of the UI node.
---------
Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
# Objective
- This is a followup to #15812.
## Solution
I just deleted the `COUNT` const and replaced it. I didn't realize for
loops are not const yet, so improving the other const variables is not
obvious.
Note: `slice::len` has been const since Rust 1.39, so we're not relying
on a brand new feature or anything.
## Testing
- It builds!
# Objective
On HEAD, `bevy_color` does not compile on its own with `--all-features`
enabled. This PR fixes that.
## Solution
- Added the `curve` feature on `bevy_math` to `bevy_color`.
- Added the `serialize` feature on `bevy_math` to
`bevy_color/serialize`.
## Testing
- Compiled with `cargo b -p bevy_color --all-features` on HEAD and on
this PR: it fails to compile on HEAD but compiles with this PR.
# Objective
- Fix bug where `cargo run -p ci` fails due to differing implementations
for default values between `Default` trait and `argh`
- Automatically install target via `rustup` to make first-run simpler.
## Solution
The command will now attempt to install the target via `rustup` by
default, which will provide a cleaner error message if a malformed
target is passed. It will also avoid confusion when people attempt to
use this tool for the first time without the target already installed.
I've added a flag, --skip-install, to disable the attempted installation
just-in-case. (e.g., maybe rustup isn't in their path but cargo is?).
Also fixed a bug where the default value for `target` was different
between the `Default` trait and `argh`, causing `cargo run -p ci` to
fail.
## Testing
- CI
- Subcommand ran directly
## Notes
This issue was originally discovered by @targrub (on Discord):
> Unfortunately, running `cargo run -p ci` still gives that same error
as I initially reported (though `cargo run -p ci --
compile-check-no-std` succeeds). This is after having run `rustup target
add x86_64-unknown-none`.
# Objective
- `C: ExtractComponent` inserts `C::Out` instead of `C`, so we need to
remove `C::Out`. cc #15904.
## Solution
- `C` -> `C::Out`
## Testing
- CAS has `<ContrastAdaptiveSharpening as ExtractComponent>::Out =
(DenoiseCas, CasUniform)`. Setting its strength to zero correctly
removes the effect after this change.
# Objective
Add an example for the new drag move and drag resize introduced by PR
#15674 and fix#15734.
## Solution
I created an example that allows the user to exercise drag move and drag
resize separately. The user can also choose what direction the resize
works in.
![Screenshot 2024-10-10 at 4 06
43 AM](https://github.com/user-attachments/assets/1da558ab-a80f-49af-8b7d-bb635b0f038f)
### Name
The example is called `window_drag_move`. Happy to have that
bikeshedded.
### Contentious Refactor?
This PR removed the `ResizeDirection` enumeration in favor of using
`CompassOctant` which had the same variants. Perhaps this is
contentious.
### Unsafe?
In PR #15674 I mentioned that `start_drag_move()` and
`start_drag_resize()`'s requirement to only be called in the presence of
a left-click looks like a compiler-unenforceable contract that can cause
intermittent panics when not observed, so perhaps the functions should
be marked them unsafe. **I have not made that change** here since I
didn't see a clear consensus on that.
## Testing
I exercised this on x86 macOS. However, winit for macOS does not support
drag resize. It reports a good error when `start_drag_resize()` is
called. I'd like to see it tested on Windows and Linux.
---
## Showcase
Example window_drag_move shows how to drag or resize a window without
decoration.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Make `StableInterpolate` "just work" on tuples whose parts are each
`StableInterpolate` types. These types arise notably through
`Curve::zip` (or just through explicit mapping of a similar form). It
would otherwise be kind of frustrating to stumble upon such a thing and
then realize that, e.g., automatic resampling just doesn't work, even
though there is a very "obvious" way to do it.
## Solution
Infer `StableInterpolate` on tuples of up to size 11. I can make that
number bigger, if desired. Unfortunately, I don't think that our
standard "fake variadics" tools actually work for this; the anonymous
field accessors of tuples are `:tt` for purposes of macro expansion,
which means that you can't simplify away the identifiers by doing
something clever like using recursion (which would work if they were
`:expr`). Maybe someone who knows some incredibly dark magic could chime
in with a better solution.
The expanded impls look like this:
```rust
impl<
T0: StableInterpolate,
T1: StableInterpolate,
T2: StableInterpolate,
T3: StableInterpolate,
T4: StableInterpolate,
> StableInterpolate for (T0, T1, T2, T3, T4)
{
fn interpolate_stable(&self, other: &Self, t: f32) -> Self {
(
<T0 as StableInterpolate>::interpolate_stable(&self.0, &other.0, t),
<T1 as StableInterpolate>::interpolate_stable(&self.1, &other.1, t),
<T2 as StableInterpolate>::interpolate_stable(&self.2, &other.2, t),
<T3 as StableInterpolate>::interpolate_stable(&self.3, &other.3, t),
<T4 as StableInterpolate>::interpolate_stable(&self.4, &other.4, t),
)
}
}
```
## Testing
Expanded macros; it compiles.
## Future
Make a version of the fake variadics workflow that supports this kind of
thing.
# Objective
Closes#15799.
Many rendering people and maintainers are in favor of reverting default
mesh materials added in #15524, especially as the migration to required
component is already large and heavily breaking.
## Solution
Revert default mesh materials, and adjust docs accordingly.
- Remove `extract_default_materials`
- Remove `clear_material_instances`, and move the logic back into
`extract_mesh_materials`
- Remove `HasMaterial2d` and `HasMaterial3d`
- Change default material handles back to pink instead of white
- 2D uses `Color::srgb(1.0, 0.0, 1.0)`, while 3D uses `Color::srgb(1.0,
0.0, 0.5)`. Not sure if this is intended.
There is now no indication at all about missing materials for `Mesh2d`
and `Mesh3d`. Having a mesh without a material renders nothing.
## Testing
I ran `2d_shapes`, `mesh2d_manual`, and `3d_shapes`, with and without
mesh material components.
# Objective
- Make the example deterministic when run with CI, so that the
[screenshot
comparison](https://thebevyflock.github.io/bevy-example-runner/) is
stable
- Preserve the "truly random on each run" behavior so that every page
load in the example showcase shows a different contributor first
## Solution
- Fall back to the static default contributor list in CI
- Store contributors in a `Vec` so that we can show repeats of the
fallback contributor list, giving the appearance of lots of overlapping
contributors in CI
- Use a shared seeded RNG throughout the app
- Give contributor birds a `z` value so that their depth is stable
- Remove the shuffle, which was redundant because contributors are first
collected into a hashmap
- `chain` the systems so that the physics is deterministic from run to
run
## Testing
```bash
echo '(setup: (fixed_frame_time: Some(0.05)), events: [(100, Screenshot), (500, AppExit)])' > config.ron
CI_TESTING_CONFIG=config.ron cargo run --example contributors --features=bevy_ci_testing
mv screenshot-100.png screenshot-100-a.png
CI_TESTING_CONFIG=config.ron cargo run --example contributors --features=bevy_ci_testing
diff screenshot-100.png screenshot-100-a.png
```
## Alternatives
I'd also be fine with removing this example from the list of examples
that gets screenshot-tested in CI. Coverage from other 2d examples is
probably adequate.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Fixes#15730.
## Solution
As part of #15586, we made a constant to store all the supported image
formats. However since the `ImageFormat` does actually include Hdr and
OpenExr, it also included the `"hdr"` and `"exr"` file extensions. These
are supported by separate loaders though: `HdrTextureLoader` and
`ExrTextureLoader`. This led to a warning about duplicate asset loaders.
Therefore, instead of having the constant for `ImageFormat`, I made the
constant just for `ImageLoader`. This lets us correctly remove `"hdr"`
and `"exr"` from the image formats supported by `ImageLoader`, returning
us to having a single asset loader for every image format.
Note: we could have just removed `hdr` and `exr` from
`ImageFormat::SUPPORTED_FILE_EXTENSIONS`, but this would be very
confusing. Then the list of `ImageFormat`s would not match the list of
supported formats!
## Testing
- I ran the `sprite` example and got no warning! I also replaced the
sprite in that example with an HDR file and everything worked as
expected.
See #15924 for more details
close#15924
from the issue, this code panic:
```rust
use bevy::time::Stopwatch;
use std::time::Duration;
fn main() {
let second = Duration::from_secs(1);
let mut stopwatch = Stopwatch::new();
// lot of time has passed... or a timer with Duration::MAX that was artificially set has "finished":
// timer.set_elapsed(timer.remaining());
stopwatch.set_elapsed(Duration::MAX);
// panic
stopwatch.tick(second);
let mut stopwatch = Stopwatch::new();
stopwatch.set_elapsed(Duration::MAX - second);
// this doesnt panic as its still one off the max
stopwatch.tick(second);
// this panic
stopwatch.tick(second);
}
```
with this PR changes, the code now doesn't panic.
have a good day !