Commit graph

5137 commits

Author SHA1 Message Date
Sludge
f0ff7fb544
Add and reflect Default impls for CSS grid types (#14443)
# Objective

- Some types here were not constructible via reflection, and some were
missing fairly obvious `Default` values.
- Some types used `#[reflect_value]` for some unstated reason, making
them opaque to reflection-based code.

## Solution

- Add and reflect some `Default` impls, and stop using
`#[reflect_value]`.
2024-07-22 21:39:59 +00:00
charlotte
abaea01e30
Fixup Msaa docs. (#14442)
Minor doc fixes missed in #14273
2024-07-22 21:37:25 +00:00
IceSentry
3faca1e549
Don't ignore draw errors (#13240)
# Objective

- It's possible to have errors in a draw command, but these errors are
ignored

## Solution

- Return a result with the error

## Changelog

Renamed `RenderCommandResult::Failure` to `RenderCommandResult::Skip`
Added a `reason` string parameter to `RenderCommandResult::Failure`

## Migration Guide
If you were using `RenderCommandResult::Failure` to just ignore an error
and retry later, use `RenderCommandResult::Skip` instead.

This wasn't intentional, but this PR should also help with
https://github.com/bevyengine/bevy/issues/12660 since we can turn a few
unwraps into error messages now.

---------

Co-authored-by: Charlotte McElwain <charlotte.c.mcelwain@gmail.com>
2024-07-22 19:22:30 +00:00
Ben Frankel
ee88d79d88
Simplify run conditions (#14441)
# Objective

Simplify Bevy-provided functions that return a condition-satisfying
closure instead of just being the condition.

## Solution

Become the condition.

## Testing

I did not test. Game jamming. Hopefully CI passes.

---

## Migration Guide

Some run conditions have been simplified.

```rust
// Before:
app.add_systems(Update, (
    system_0.run_if(run_once()),
    system_1.run_if(resource_changed_or_removed::<T>()),
    system_2.run_if(resource_removed::<T>()),
    system_3.run_if(on_event::<T>()),
    system_4.run_if(any_component_removed::<T>()),
));

// After:
app.add_systems(Update, (
    system_0.run_if(run_once),
    system_1.run_if(resource_changed_or_removed::<T>),
    system_2.run_if(resource_removed::<T>),
    system_3.run_if(on_event::<T>),
    system_4.run_if(any_component_removed::<T>),
));
```
2024-07-22 19:21:47 +00:00
BD103
cd497152bb
Fix error in bevy_ui when building without bevy_text (#14430)
# Objective

- `bevy_ui` does not build without the `bevy_text` feature due to
improper feature gating.
- Specifically, `MeasureArgs<'a>` had an unused lifetime `'a` without
`bevy_text` enabled. This is because it stores a reference to a
`cosmic_text::FontSystem`.
- This was caught by `flag-frenzy` in [this
run](https://github.com/TheBevyFlock/flag-frenzy/actions/runs/10024258523/job/27706132250).

## Solution

- Add a `PhantomData` to `MeasureArgs<'a>` in order to maintain its
lifetime argument.
- I also named it `font_system`, after the feature-gated argument that
actually needs a lifetime, for usability. Please comment if you have a
better solution!
- Move some unused imports to be behind the `bevy_text` feature gate.

## Testing

```bash
# Fails on main.
cargo check -p bevy_ui --no-default-features
# Succeeds on main.
cargo check -p bevy_ui --no-default-features -F bevy_text
```

---

## Migration Guide

**This is not a breaking change for users migrating from 0.14, since
`MeasureArgs` did not exist then.**

When the `bevy_text` feature is disabled for `bevy_ui`, the type of the
`MeasureArgs::font_system` field is now a `PhantomData` instead of being
removed entirely. This is in order to keep the lifetime parameter, even
though it is unused without text being enabled.
2024-07-22 19:19:10 +00:00
Hannes Karppila
93def2611b
Fix repeated animation transition bug (#14411)
# Objective

Fixes #13910

When a transition is over, the animation is stopped. There was a race
condition; if an animation was started while it also had an active
transition, the transition ending would then incorrectly stop the newly
added animation.

## Solution

When starting an animation, cancel any previous transition for the same
animation.

## Testing

The changes were tested manually, mainly by using the `animated_fox`
example. I also tested with changes from
https://github.com/bevyengine/bevy/pull/13909.

I'd like to have an unit test for this as well, but it seems quite
complex to do, as I'm not sure how I would detect an incorrectly paused
animation.

Reviewers can follow the instructions in #13910 to reproduce.

Tested on macos 14.4 (M3 processor) Should be platform-independent,
though.
2024-07-22 19:17:46 +00:00
Daniel Miller
692840274f
Added AstcBlock and AstcChannel to the forwarded wgpu types. (#14410)
Currently `TextureFormat::Astc` can't be programmatically constructed
without importing wgpu in addition to bevy.

# Objective

Allow programmatic construction of `TextureFormat::Astc` with no
additional imports required.

## Solution

Exported the two component enums `AstcBlock` and `AstcChannel` used in
`TextureFormat::Astc` construction.

## Testing

I did not test this, the change seemed pretty safe. :)
2024-07-22 19:14:14 +00:00
Sebastian J. Hamel
d88be59f92
feat: expose the default font bytes (#14406)
# Objective

- Enables use cases where third-party crates would want to use the
default font as well [see linebender's
use](https://github.com/linebender/bevy_vello/pull/66)

## Solution

- Uses `include_bytes` macro and make it `pub`

---------

Co-authored-by: Spencer C. Imbleau <spencer@imbleau.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-07-22 19:09:39 +00:00
John
d1f4262d7d
Only propagate transforms entities with GlobalTransforms. (#14384)
# Objective
Fixes a performance issue when you have 1000s of entities in a bevy
hierarchy without transforms.

This was prominently happening in `bevy_ecs_tilemap`.

## Solution

Filter out entities that don't have a global transform.

## Testing

CI
We should test some other way...

## Migration Guide

- To avoid surprising performance pitfalls, `Transform` /
`GlobalTransform` propagation is no longer performed down through
hierarchies where intermediate parent are missing a `GlobalTransform`.
To restore the previous behavior, add `GlobalTransform::default` to
intermediate entities.
2024-07-22 19:07:21 +00:00
Coder-Joe458
8f5345573c
Remove manual --cfg docsrs (#14376)
# Objective

- Fixes #14132 

## Solution

- Remove the cfg docsrs
2024-07-22 18:58:04 +00:00
Patrick Walton
d235d41af1
Fix the example regressions from packed growable buffers. (#14375)
The "uberbuffers" PR #14257 caused some examples to fail intermittently
for different reasons:

1. `morph_targets` could fail because vertex displacements for morph
targets are keyed off the vertex index. With buffer packing, the vertex
index can vary based on the position in the buffer, which caused the
morph targets to be potentially incorrect. The solution is to include
the first vertex index with the `MeshUniform` (and `MeshInputUniform` if
GPU preprocessing is in use), so that the shader can calculate the true
vertex index before performing the morph operation. This results in
wasted space in `MeshUniform`, which is unfortunate, but we'll soon be
filling in the padding with the ID of the material when bindless
textures land, so this had to happen sooner or later anyhow.

Including the vertex index in the `MeshInputUniform` caused an ordering
problem. The `MeshInputUniform` was created during the extraction phase,
before the allocations occurred, so the extraction logic didn't know
where the mesh vertex data was going to end up. The solution is to move
the `MeshInputUniform` creation (the `collect_meshes_for_gpu_building`
system) to after the allocations phase. This should be better for
parallelism anyhow, because it allows the extraction phase to finish
quicker. It's also something we'll have to do for bindless in any event.

2. The `lines` and `fog_volumes` examples could fail because their
custom drawing nodes weren't updated to supply the vertex and index
offsets in their `draw_indexed` and `draw` calls. This commit fixes this
oversight.

Fixes #14366.
2024-07-22 18:55:51 +00:00
Rostyslav Toch
d30391b583
Optimize transform propagation (#14373)
# Objective

- Optimize the `propagate_recursive` function in the transform system to
reduce CPU usage.
- Addresses performance bottleneck in transform propagation, especially
for scenes with complex hierarchies.

## Solution

- Avoided unnecessary cloning of `global_transform` when creating the
tuple in the `propagate_recursive` function.
- Used `as_ref()` method on `Mut<GlobalTransform>` when passing it to
the recursive call, avoiding an extra dereference.
- These changes significantly reduced the CPU usage of this function
from 4.91% to 1.16% of self function time.

## Testing

- Performance testing was conducted using the Hotspot GUI tool,
comparing CPU usage before and after the changes.
- `cargo run --release --example many_foxes`
- Tested on Fedora Linux.
---

## Showcase

Here are the PERF GUI results showing the improvement in CPU usage:

### Before

![image](https://github.com/user-attachments/assets/b5c52800-710b-4793-bf75-33e3eb1d2083)

### After

![image](https://github.com/user-attachments/assets/654a4feb-924c-41c8-8ff9-3a1027bd28b9)

As we can see, the CPU usage for the `propagate_recursive` function has
been reduced from 4.91% to 1.16%, resulting in a significant performance
improvement.

## Migration Guide

This change does not introduce any breaking changes. Users of the Bevy
engine will automatically benefit from this performance improvement
without needing to modify their code.
2024-07-22 18:53:16 +00:00
Sludge
4ea8c66321
Unignore Camera.target field for reflection (#14367)
# Objective

- The `RenderTarget` type wasn't being registered, and the `target`
field of `Camera` was marked as ignored, so it wasn't inspectable by
editors.

## Solution

- Remove `#[reflect(ignore)]` from the field
- I've also reordered the `Default` impl of `RenderTarget` because it
looked like it belonged to a different type
2024-07-22 18:46:40 +00:00
Al M.
e06f4d4083
Fix single keyframe animations. (#14344)
# Objective

For clips with more than one curve, only the first was being applied if
there is only one keyframe in it.

## Solution

Continue!
2024-07-22 18:44:27 +00:00
IQuick 143
420f7f72dc
Fast renormalize (#14316)
# Objective

- Addresses part of #14302 .

## Solution

- Add a fast_remormalize method to Dir2/Dir3/Dir3A and Rot2.

## Testing

- Added tests too

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-07-22 18:42:48 +00:00
charlotte
03fd1b46ef
Move Msaa to component (#14273)
Switches `Msaa` from being a globally configured resource to a per
camera view component.

Closes #7194

# Objective

Allow individual views to describe their own MSAA settings. For example,
when rendering to different windows or to different parts of the same
view.

## Solution

Make `Msaa` a component that is required on all camera bundles.

## Testing

Ran a variety of examples to ensure that nothing broke.

TODO:
- [ ] Make sure android still works per previous comment in
`extract_windows`.

---

## Migration Guide

`Msaa` is no longer configured as a global resource, and should be
specified on each spawned camera if a non-default setting is desired.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-07-22 18:28:23 +00:00
Sou1gh0st
462da1e49d
Fix incorrect function calls to hsv_to_rgb in render debug code. (#14260)
# Objective

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

## Solution

- correct the input parameters at these call sites.

## Testing

1. Use a 3D scene example with PBR lighting and shadows enabled, such as
the `shadow_caster_receiver` and `load_gltf` example, for testing.
2. Enable relevant shader defines in crates/bevy_pbr/src/pbr_material.rs
for the StandardMaterial.
```rust
impl Material for StandardMaterial {
    // ...
    fn specialize(
            _pipeline: &MaterialPipeline<Self>,
            descriptor: &mut RenderPipelineDescriptor,
            _layout: &MeshVertexBufferLayoutRef,
            key: MaterialPipelineKey<Self>,
        ) -> Result<(), SpecializedMeshPipelineError> {
            // ...
            // shader_defs.push("CLUSTERED_FORWARD_DEBUG_Z_SLICES".into());
            // shader_defs.push("CLUSTERED_FORWARD_DEBUG_CLUSTER_COHERENCY".into());
            shader_defs.push("DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES".into());
            // ...
    }
}
``` 

## Showcase
### CLUSTERED_FORWARD_DEBUG_Z_SLICES
- example: examples/3d/shadow_caster_receiver.rs

![Screenshot2024_07_10_143150](https://github.com/bevyengine/bevy/assets/6300263/fbd12712-5cb9-489d-a7d1-ed55f72fb234)

### CLUSTERED_FORWARD_DEBUG_CLUSTER_COHERENCY
- example: examples/3d/shadow_caster_receiver.rs

![Screenshot2024_07_10_143312](https://github.com/bevyengine/bevy/assets/6300263/8eca5d7a-27b6-4ff5-9f8d-d10b49b3f990)

### DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES
For this one, we need to use a large scene and modity the
`CascadeShadowConfigBuilder`, here is a simple patch for the `load_gltf`
example:
```
diff --git a/examples/3d/load_gltf.rs b/examples/3d/load_gltf.rs
index 358446238..9403aa288 100644
--- a/examples/3d/load_gltf.rs
+++ b/examples/3d/load_gltf.rs
@@ -18,7 +18,7 @@ fn main() {
 fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
     commands.spawn((
         Camera3dBundle {
-            transform: Transform::from_xyz(0.7, 0.7, 1.0)
+            transform: Transform::from_xyz(0.7, 0.7, 2.0)
                 .looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
             ..default()
         },
@@ -39,30 +39,40 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
         // We also adjusted the shadow map to be larger since we're
         // only using a single cascade.
         cascade_shadow_config: CascadeShadowConfigBuilder {
-            num_cascades: 1,
-            maximum_distance: 1.6,
+            num_cascades: 5,
+            maximum_distance: 20.0,
             ..default()
         }
         .into(),
         ..default()
     });
+
     commands.spawn(SceneBundle {
         scene: asset_server
             .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
         ..default()
     });
+
+    for i in 1..=10 {
+        commands.spawn(SceneBundle {
+            scene: asset_server
+                .load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
+            transform: Transform::from_xyz(i as f32 * 0.5, 0.0, i as f32 * -2.0),
+            ..default()
+        });
+    }
 }
 
 fn animate_light_direction(
     time: Res<Time>,
     mut query: Query<&mut Transform, With<DirectionalLight>>,
 ) {
-    for mut transform in &mut query {
-        transform.rotation = Quat::from_euler(
-            EulerRot::ZYX,
-            0.0,
-            time.elapsed_seconds() * PI / 5.0,
-            -FRAC_PI_4,
-        );
-    }
+    // for mut transform in &mut query {
+    //     transform.rotation = Quat::from_euler(
+    //         EulerRot::ZYX,
+    //         0.0,
+    //         time.elapsed_seconds() * PI / 5.0,
+    //         -FRAC_PI_4,
+    //     );
+    // }
 }
``` 

![Screenshot2024_07_10_145737](https://github.com/bevyengine/bevy/assets/6300263/c5c71894-f9f7-45fa-9b4f-598e324b42d0)

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
2024-07-22 18:25:54 +00:00
Peter Hayman
b8416b3043
Add some missing reflect attributes (#14259)
# Objective

- Some types are missing reflection attributes, which means we can't use
them in scene serialization etc.
- Effected types
   - `BorderRadius`
   - `AnimationTransitions`
   - `OnAdd`
   - `OnInsert`
   - `OnRemove`
- My use-case for `OnAdd` etc to derive reflect is 'Serializable
Observer Components'. Add the component, save the scene, then the
observer is re-added on scene load.

```rust
#[derive(Reflect)]
struct MySerializeableObserver<T: Event>(#[reflect(ignore)]PhantomData<T>);

impl<T: Event> Component for MySerializeableObserver<T> {
  const STORAGE_TYPE: StorageType  = StorageType::Table;
    fn register_component_hooks(hooks: &mut ComponentHooks) {
      hooks.on_add(|mut world, entity, _| {
        world
          .commands()
          .entity(entity)
          .observe(|_trigger: Trigger<T>| {
            println!("it triggered etc.");
          });
    });
  }
}
```

## Solution

- Add the missing traits

---
2024-07-22 18:24:10 +00:00
ickshonpe
453e0e4fc1
Prevent division by zero in HWBA to HSVA conversions (#14256)
# Problem

Division by zero in `crates/bevy_color/src/hsva.rs` when `blackness` is
`1`:

```rust
impl From<Hwba> for Hsva {
    fn from(
        Hwba {
            hue,
            whiteness,
            blackness,
            alpha,
        }: Hwba,
    ) -> Self {
        // Based on https://en.wikipedia.org/wiki/HWB_color_model#Conversion
        let value = 1. - blackness;
        let saturation = 1. - (whiteness / value);

        Hsva::new(hue, saturation, value, alpha)
    }
}
```

## Solution
With `Hsva` colors if the `value` component is set to `0.` the output
will be pure black regardless of the values of the `hue` or `saturation`
components.

So if `value` is `0`, we don't need to calculate a `saturation` value
and can just set it to `0`:

```rust
impl From<Hwba> for Hsva {
    fn from(
        Hwba {
            hue,
            whiteness,
            blackness,
            alpha,
        }: Hwba,
    ) -> Self {
        // Based on https://en.wikipedia.org/wiki/HWB_color_model#Conversion
        let value = 1. - blackness;
        let saturation = if value != 0. {
            1. - (whiteness / value)
        } else {
            0.
        };

        Hsva::new(hue, saturation, value, alpha)
    }
}

```

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-22 18:22:26 +00:00
Vic
bc36b4e561
implement DoubleEndedIterator for QueryManyIter (#14128)
# Objective

We currently cannot iterate from the back of `QueryManyIter`.

## Solution

Implement `DoubleEndedIterator` for `QueryManyIter` and add a
`fetch_next_back` method. These impls are bounded on the underlying
`entity_iter` implementing `DoubleEndedIterator`.

## Changelog

Added `DoubleEndedIterator` implementation for `QueryManyIter`.
Added the `fetch_next_back` method to `QueryManyIter`.
2024-07-22 18:21:42 +00:00
charlotte
08d3497d87
Fix breaking image 0.25.2 release. (#14421)
Deprecated item breaking ci:
https://github.com/image-rs/image/releases/tag/v0.25.2. See
https://github.com/bevyengine/bevy/actions/runs/10030764981/job/27720434072?pr=14419
for example.
2024-07-21 21:27:07 +00:00
Sunil Thunga
2158f3d91f
Using Cas instead of CAS #14341 (#14357)
# Objective

- Replacing CAS with Cas in CASPlugin
- Closes #14341

## Solution

- Simple replace

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: François Mockers <mockersf@gmail.com>
2024-07-20 18:12:24 +00:00
François Mockers
c0b35d07f3
fix building cargo_gltf with feature dds (#14360)
# Objective

- Building bevy_gltf with feature dds fails:
```
> cargo build -p bevy_gltf --features dds
   Compiling bevy_core_pipeline v0.15.0-dev (crates/bevy_core_pipeline)
error[E0061]: this function takes 7 arguments but 6 arguments were supplied
   --> crates/bevy_core_pipeline/src/tonemapping/mod.rs:442:5
    |
442 |     Image::from_buffer(
    |     ^^^^^^^^^^^^^^^^^^
...
445 |         bytes,
    |         ----- an argument of type `std::string::String` is missing
    |
note: associated function defined here
   --> crates/bevy_render/src/texture/image.rs:709:12
    |
709 |     pub fn from_buffer(
    |            ^^^^^^^^^^^
help: provide the argument
    |
442 |     Image::from_buffer(/* std::string::String */, bytes, image_type, CompressedImageFormats::NONE, false, image_sampler, RenderAssetUsages::RENDER_WORLD)
    |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For more information about this error, try `rustc --explain E0061`.
error: could not compile `bevy_core_pipeline` (lib) due to 1 previous error
```
- If you're fixing a specific issue, say "Fixes #X".

## Solution

- enable dds feature in bevy_core_pipeline

## Testing

- `cargo build -p bevy_gltf --features dds`
2024-07-20 17:55:25 +00:00
charlotte
3aa525885b
Set scissor on upscale to match camera viewport (#14287)
# Objective

When the user renders multiple cameras to the same output texture, it
can sometimes be confusing what `ClearColorConfig` is necessary for each
camera to avoid overwriting the previous camera's output. This is
particular true in cases where the user uses mixed HDR cameras, which
means that their scene is being rendered to different internal textures.

## Solution

When a view has a configured viewport, set the GPU scissor in the
upscaling node so we don't overwrite areas that were written to by other
cameras.

## Testing

Ran the `split_screen` example.
2024-07-20 16:45:04 +00:00
Sludge
c0cebfef45
Make Viewport::default() return a 1x1 viewport (#14372)
# Objective

- The current default viewport crashes bevy due to a wgpu validation
error, this PR fixes that
- Fixes https://github.com/bevyengine/bevy/issues/14355

## Solution

- `Viewport::default()` now returns a 1x1 viewport

## Testing

- I modified the `3d_viewport_to_world` example to use
`Viewport::default()`, and it works as expected (only the top-left pixel
is rendered)
2024-07-20 14:18:12 +00:00
Sou1gh0st
9da18cce2a
Add support for environment map transformation (#14290)
# Objective

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

## Solution

- Add a world space transformation for the environment sample direction.

## Testing

- I have tested the newly added `transform` field using the newly added
`rotate_environment_map` example.


https://github.com/user-attachments/assets/2de77c65-14bc-48ee-b76a-fb4e9782dbdb


## Migration Guide

- Since we have added a new filed to the `EnvironmentMapLight` struct,
users will need to include `..default()` or some rotation value in their
initialization code.
2024-07-19 15:00:50 +00:00
Abe
d8d49fdd13
Deprecate is_playing_animation (#14387)
# Objective

Fixes #14386

## Solution

- Added the `#[deprecate]` attribute to the `is_playing_animation`
function.

## Testing

The project successfully builds.

---

## Migration Guide

The user will just need to replace functions named
`is_playing_animation` with `animation_is_playing`.
2024-07-19 11:27:43 +00:00
Patrick Walton
2a6dd3e2e0
Make the GltfNode::children links actually point to children. (#14390)
Due to a bug in `load_gltf`, the `GltfNode::children` links of each node
actually point to the node itself, rather than to the node's children.
This commit fixes that bug.

Note that this didn't affect the scene hierarchy of the instantiated
glTF, only the hierarchy as present in the `GltfNode` assets. This is
likely why the bug was never noticed until now.
2024-07-19 11:24:06 +00:00
re0312
e5bf59d712
Recalibrated observe benchmark (#14381)
# Objective

- The event propagation benchmark is largely derived from
bevy_eventlistener. However, it doesn't accurately reflect performance
of bevy side, as our event bubble propagation is based on observer.


## Solution

- added several new benchmarks that focuse on observer itself rather
than event bubble
2024-07-18 18:25:33 +00:00
Lars Frost
dcbd30200e
Make names of closure systems changable (#14369)
# Objective

When using tracing or
[`bevy_mod_debugdump`](https://github.com/jakobhellermann/bevy_mod_debugdump),
the names of function systems produced by closures are either ambiguous
(like `game::mainapp::{closure}` when tracing) or too long
(`bevy_mod_debugdump` includes full type signature if no name given),
which makes debugging with tracing difficult.

## Solution
Add a function `with_name` to rename a system. The proposed API can be
used in the following way:
```rust
app
    .add_systems(Startup, IntoSystem::into_system(|name: SystemName| {
        println!("System name: {}", name.name().to_owned());
    }).with_name("print_test_system"));
```

## Testing
- There is a test in
`bevy_ecs::system:system_name::test_closure_system_name_regular_param`
2024-07-18 18:07:47 +00:00
Thierry Berger
26fc4c7198
Test for ambiguous system ordering in CI (#13950)
Progress towards https://github.com/bevyengine/bevy/issues/7386.

Following discussion
https://discord.com/channels/691052431525675048/1253260494538539048/1253387942311886960

This Pull Request adds an example to detect system order ambiguities,
and also asserts none exist.

A lot of schedules are ignored in ordered to have the test passing, we
should thrive to make them pass, but in other pull requests.

<details><summary>example output <b>summary</b>, without ignored
schedules</summary>
<p>

```txt
$ cargo run --example ambiguity_detection 2>&1 | grep -C 1 "pairs of syst"
2024-06-21T13:17:55.776585Z  WARN bevy_ecs::schedule::schedule: Schedule First has ambiguities.
1 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- bevy_time::time_system (in set TimeSystem) and bevy_ecs::event::event_update_system (in set EventUpdates)
--
2024-06-21T13:17:55.782265Z  WARN bevy_ecs::schedule::schedule: Schedule PreUpdate has ambiguities.
11 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- bevy_pbr::prepass::update_mesh_previous_global_transforms and bevy_asset::server::handle_internal_asset_events
--
2024-06-21T13:17:55.809516Z  WARN bevy_ecs::schedule::schedule: Schedule PostUpdate has ambiguities.
63 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- bevy_ui::accessibility::image_changed and bevy_ecs::schedule::executor::apply_deferred
--
2024-06-21T13:17:55.816287Z  WARN bevy_ecs::schedule::schedule: Schedule Last has ambiguities.
3 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- bevy_gizmos::update_gizmo_meshes<bevy_gizmos::aabb::AabbGizmoConfigGroup> (in set UpdateGizmoMeshes) and bevy_gizmos::update_gizmo_meshes<bevy_gizmos::light::LightGizmoConfigGroup> (in set UpdateGizmoMeshes)
--
2024-06-21T13:17:55.831074Z  WARN bevy_ecs::schedule::schedule: Schedule ExtractSchedule has ambiguities.
296 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- bevy_render::extract_component::extract_components<bevy_sprite::SpriteSource> and bevy_render::render_asset::extract_render_asset<bevy_sprite::mesh2d::material::PreparedMaterial2d<bevy_sprite::mesh2d::color_material::ColorMaterial>>
```

</p>
</details> 

To try locally: 
```sh
CI_TESTING_CONFIG="./.github/example-run/ambiguity_detection.ron" cargo run --example ambiguity_detection --features "bevy_ci_testing,trace,trace_chrome"
```

---------

Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-07-17 21:05:48 +00:00
Sludge
fa855f7974
Derive and reflect Debug for CameraRenderGraph (#14364)
# Objective

- `CameraRenderGraph` is not inspectable via reflection, but should be
(the name of the configured render graph should be visible in editors,
etc.)

## Solution

- Derive and reflect `Debug` for `CameraRenderGraph`
2024-07-17 19:41:31 +00:00
Matty
3484bd916f
Cyclic splines (#14106)
# Objective

Fill a gap in the functionality of our curve constructions by allowing
users to easily build cyclic curves from control data.

## Solution

Here I opted for something lightweight and discoverable. There is a new
`CyclicCubicGenerator` trait with a method `to_curve_cyclic` which uses
splines' control data to create curves that are cyclic. For now, its
signature is exactly like that of `CubicGenerator` — `to_curve_cyclic`
just yields a `CubicCurve`:
```rust
/// Implement this on cubic splines that can generate a cyclic cubic curve from their spline parameters.
///
/// This makes sense only when the control data can be interpreted cyclically.
pub trait CyclicCubicGenerator<P: VectorSpace> {
    /// Build a cyclic [`CubicCurve`] by computing the interpolation coefficients for each curve segment.
    fn to_curve_cyclic(&self) -> CubicCurve<P>;
}
```

This trait has been implemented for `CubicHermite`,
`CubicCardinalSpline`, `CubicBSpline`, and `LinearSpline`:

<img width="753" alt="Screenshot 2024-07-01 at 8 58 27 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/69ae0802-3b78-4fb9-b73a-6f842cf3b33c">
<img width="628" alt="Screenshot 2024-07-01 at 9 00 14 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/2992175a-a96c-40fc-b1a1-5206c3572cde">
<img width="606" alt="Screenshot 2024-07-01 at 8 59 36 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/9e99eb3a-dbe6-42da-886c-3d3e00410d03">
<img width="603" alt="Screenshot 2024-07-01 at 8 59 01 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/d037bc0c-396a-43af-ab5c-fad9a29417ef">

(Each type pictured respectively with the control points rendered as
green spheres; tangents not pictured in the case of the Hermite spline.)

These curves are all parametrized so that the output of `to_curve` and
the output of `to_curve_cyclic` are similar. For instance, in
`CubicCardinalSpline`, the first output segment is a curve segment
joining the first and second control points in each, although it is
constructed differently. In the other cases, the segments from
`to_curve` are a subset of those in `to_curve_cyclic`, with the new
segments appearing at the end.

## Testing

I rendered cyclic splines from control data and made sure they looked
reasonable. Existing tests are intact for splines where previous code
was modified. (Note that the coefficient computation for cyclic spline
segments is almost verbatim identical to that of their non-cyclic
counterparts.)

The Bezier benchmarks also look fine.

---

## Changelog

- Added `CyclicCubicGenerator` trait to `bevy_math::cubic_splines` for
creating cyclic curves from control data.
- Implemented `CyclicCubicGenerator` for `CubicHermite`,
`CubicCardinalSpline`, `CubicBSpline`, and `LinearSpline`.
- `bevy_math` now depends on `itertools`.

---

## Discussion

### Design decisions

The biggest thing here is just the approach taken in the first place:
namely, the cyclic constructions use new methods on the same old
structs. This choice was made to reduce friction and increase
discoverability but also because creating new ones just seemed
unnecessary: the underlying data would have been the same, so creating
something like "`CyclicCubicBSpline`" whose internally-held control data
is regarded as cyclic in nature doesn't really accomplish much — the end
result for the user is basically the same either way.

Similarly, I don't presently see a pressing need for `to_curve_cyclic`
to output something other than a `CubicCurve`, although changing this in
the future may be useful. See below.

A notable omission here is that `CyclicCubicGenerator` is not
implemented for `CubicBezier`. This is not a gap waiting to be filled —
`CubicBezier` just doesn't have enough data to join its start with its
end without just making up the requisite control points wholesale. In
all the cases where `CyclicCubicGenerator` has been implemented here,
the fashion in which the ends are connected is quite natural and follows
the semantics of the associated spline construction.

### Future direction

There are two main things here:
1. We should investigate whether we should do something similar for
NURBS. I just don't know that much about NURBS at the moment, so I
regarded this as out of scope for the PR.
2. We may eventually want to change the output type of
`CyclicCubicGenerator::to_curve_cyclic` to a type which reifies the
cyclic nature of the curve output. This wasn't done in this PR because
I'm unsure how much value a type-level guarantee of cyclicity actually
has, but if some useful features make sense only in the case of cyclic
curves, this might be worth pursuing.
2024-07-17 13:02:31 +00:00
Martín Maita
72e7a4fed2
Update trigger_observers to operate over slices of data (#14354)
# Objective

- Fixes #14333 

## Solution

- Updated `trigger_observers` signature to operate over a slice instead
of an `Iterator`.
- Updated calls to `trigger_observers` to match the new signature.

---

## Migration Guide

- TBD
2024-07-17 13:01:52 +00:00
Patrick Walton
bc34216929
Pack multiple vertex and index arrays together into growable buffers. (#14257)
This commit uses the [`offset-allocator`] crate to combine vertex and
index arrays from different meshes into single buffers. Since the
primary source of `wgpu` overhead is from validation and synchronization
when switching buffers, this significantly improves Bevy's rendering
performance on many scenes.

This patch is a more flexible version of #13218, which also used slabs.
Unlike #13218, which used slabs of a fixed size, this commit implements
slabs that start small and can grow. In addition to reducing memory
usage, supporting slab growth reduces the number of vertex and index
buffer switches that need to happen during rendering, leading to
improved performance. To prevent pathological fragmentation behavior,
slabs are capped to a maximum size, and mesh arrays that are too large
get their own dedicated slabs.

As an additional improvement over #13218, this commit allows the
application to customize all allocator heuristics. The
`MeshAllocatorSettings` resource contains values that adjust the minimum
and maximum slab sizes, the cutoff point at which meshes get their own
dedicated slabs, and the rate at which slabs grow. Hopefully-sensible
defaults have been chosen for each value.

Unfortunately, WebGL 2 doesn't support the *base vertex* feature, which
is necessary to pack vertex arrays from different meshes into the same
buffer. `wgpu` represents this restriction as the downlevel flag
`BASE_VERTEX`. This patch detects that bit and ensures that all vertex
buffers get dedicated slabs on that platform. Even on WebGL 2, though,
we can combine all *index* arrays into single buffers to reduce buffer
changes, and we do so.

The following measurements are on Bistro:

Overall frame time improves from 8.74 ms to 5.53 ms (1.58x speedup):
![Screenshot 2024-07-09
163521](https://github.com/bevyengine/bevy/assets/157897/5d83c824-c0ee-434c-bbaf-218ff7212c48)

Render system time improves from 6.57 ms to 3.54 ms (1.86x speedup):
![Screenshot 2024-07-09
163559](https://github.com/bevyengine/bevy/assets/157897/d94e2273-c3a0-496a-9f88-20d394129610)

Opaque pass time improves from 4.64 ms to 2.33 ms (1.99x speedup):
![Screenshot 2024-07-09
163536](https://github.com/bevyengine/bevy/assets/157897/e4ef6e48-d60e-44ae-9a71-b9a731c99d9a)

## Migration Guide

### Changed

* Vertex and index buffers for meshes may now be packed alongside other
buffers, for performance.
* `GpuMesh` has been renamed to `RenderMesh`, to reflect the fact that
it no longer directly stores handles to GPU objects.
* Because meshes no longer have their own vertex and index buffers, the
responsibility for the buffers has moved from `GpuMesh` (now called
`RenderMesh`) to the `MeshAllocator` resource. To access the vertex data
for a mesh, use `MeshAllocator::mesh_vertex_slice`. To access the index
data for a mesh, use `MeshAllocator::mesh_index_slice`.

[`offset-allocator`]: https://github.com/pcwalton/offset-allocator
2024-07-16 20:33:15 +00:00
Gino Valente
af865e76a3
bevy_reflect: Improve DynamicFunction ergonomics (#14201)
# Objective

Many functions can be converted to `DynamicFunction` using
`IntoFunction`. Unfortunately, we are limited by Rust itself and the
implementations are far from exhaustive. For example, we can't convert
functions with more than 16 arguments. Additionally, we can't handle
returns with lifetimes not tied to the lifetime of the first argument.

In such cases, users will have to create their `DynamicFunction`
manually.

Let's take the following function:

```rust
fn get(index: usize, list: &Vec<String>) -> &String {
    &list[index]
}
```

This function cannot be converted to a `DynamicFunction` via
`IntoFunction` due to the lifetime of the return value being tied to the
second argument. Therefore, we need to construct the `DynamicFunction`
manually:

```rust
DynamicFunction::new(
    |mut args, info| {
        let list = args
            .pop()
            .unwrap()
            .take_ref::<Vec<String>>(&info.args()[1])?;
        let index = args.pop().unwrap().take_owned::<usize>(&info.args()[0])?;
        Ok(Return::Ref(get(index, list)))
    },
    FunctionInfo::new()
        .with_name("get")
        .with_args(vec![
            ArgInfo:🆕:<usize>(0).with_name("index"),
            ArgInfo:🆕:<&Vec<String>>(1).with_name("list"),
        ])
        .with_return_info(ReturnInfo:🆕:<&String>()),
);
```

While still a small and straightforward snippet, there's a decent amount
going on here. There's a lot of room for improvements when it comes to
ergonomics and readability.

The goal of this PR is to address those issues.

## Solution

Improve the ergonomics and readability of manually created
`DynamicFunction`s.

Some of the major changes:
1. Removed the need for `&ArgInfo` when reifying arguments (i.e. the
`&info.args()[1]` calls)
2. Added additional `pop` methods on `ArgList` to handle both popping
and casting
3. Added `take` methods on `ArgList` for taking the arguments out in
order
4. Removed the need for `&FunctionInfo` in the internal closure (Change
1 made it no longer necessary)
5. Added methods to automatically handle generating `ArgInfo` and
`ReturnInfo`

With all these changes in place, we get something a lot nicer to both
write and look at:

```rust
DynamicFunction::new(
    |mut args| {
        let index = args.take::<usize>()?;
        let list = args.take::<&Vec<String>>()?;
        Ok(Return::Ref(get(index, list)))
    },
    FunctionInfo::new()
        .with_name("get")
        .with_arg::<usize>("index")
        .with_arg::<&Vec<String>>("list")
        .with_return::<&String>(),
);
```

Alternatively, to rely on type inference for taking arguments, you could
do:

```rust
DynamicFunction::new(
    |mut args| {
        let index = args.take_owned()?;
        let list = args.take_ref()?;
        Ok(Return::Ref(get(index, list)))
    },
    FunctionInfo::new()
        .with_name("get")
        .with_arg::<usize>("index")
        .with_arg::<&Vec<String>>("list")
        .with_return::<&String>(),
);
```

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

---

## Changelog

- Removed `&ArgInfo` argument from `FromArg::from_arg` trait method
- Removed `&ArgInfo` argument from `Arg::take_***` methods
- Added `ArgValue`
- `Arg` is now a struct containing an `ArgValue` and an argument `index`
- `Arg::take_***` methods now require `T` is also `TypePath`
- Added `Arg::new`, `Arg::index`, `Arg::value`, `Arg::take_value`, and
`Arg::take` methods
- Replaced `ArgId` in `ArgError` with just the argument `index`
- Added `ArgError::EmptyArgList`
- Renamed `ArgList::push` to `ArgList::push_arg`
- Added `ArgList::pop_arg`, `ArgList::pop_owned`, `ArgList::pop_ref`,
and `ArgList::pop_mut`
- Added `ArgList::take_arg`, `ArgList::take_owned`, `ArgList::take_ref`,
`ArgList::take_mut`, and `ArgList::take`
- `ArgList::pop` is now generic
- Renamed `FunctionError::InvalidArgCount` to
`FunctionError::ArgCountMismatch`
- The closure given to `DynamicFunction::new` no longer has a
`&FunctionInfo` argument
- Added `FunctionInfo::with_arg`
- Added `FunctionInfo::with_return`

## Internal Migration Guide

> [!important]
> Function reflection was introduced as part of the 0.15 dev cycle. This
migration guide was written for developers relying on `main` during this
cycle, and is not a breaking change coming from 0.14.

* The `FromArg::from_arg` trait method and the `Arg::take_***` methods
no longer take a `&ArgInfo` argument.
* What used to be `Arg` is now `ArgValue`. `Arg` is now a struct which
contains an `ArgValue`.
* `Arg::take_***` methods now require `T` is also `TypePath`
* Instances of `id: ArgId` in `ArgError` have been replaced with `index:
usize`
* `ArgList::push` is now `ArgList::push_arg`. It also takes the new
`ArgValue` type.
* `ArgList::pop` has become `ArgList::pop_arg` and now returns
`ArgValue`. `Arg::pop` now takes a generic type and downcasts to that
type. It's recommended to use `ArgList::take` and friends instead since
they allow removing the arguments from the list in the order they were
pushed (rather than reverse order).
* `FunctionError::InvalidArgCount` is now
`FunctionError::ArgCountMismatch`
* The closure given to `DynamicFunction::new` no longer has a
`&FunctionInfo` argument. This argument can be removed.
2024-07-16 13:01:52 +00:00
Steve Frampton
0e13b1ca5e
Added new method to Cone 3D primitive (#14325)
Reference to #14299.

# Objective
- Ensuring consistent practice of instantiating 3D primitive shapes in
Bevy.

## Solution

- Add `new` method, containing `radius` and `height` arguments, to Cone
3D primitive shape.

## Testing

- Instantiated cone using same values (radius is `2.` and height is
`5.`), using the current method and the added `new` method.
- Basic setup of Bevy Default Plugins and `3DCameraBundle`.


---

## Showcase

<details>
  <summary>Click to view showcase</summary>

```rust
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let new_cone = meshes.add(Cone::new(2., 5.));
    commands.spawn(PbrBundle {
        mesh: new_cone,
        ..default()
    });

    let old_cone = meshes.add(Cone {
        radius: 2.,
        height: 5.,
    });
    commands.spawn(PbrBundle {
        mesh: old_cone,
        material: materials.add(Color::WHITE),
        transform: Transform::from_xyz(10., 0., 0.),
        ..default()
    });

    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(20., 20., 20.).looking_at(Vec3::ZERO, Dir3::Y),
        ..default()
    });
}
```

</details>


![image](https://github.com/user-attachments/assets/267f8124-8734-4c20-8840-fcf35375a778)


- Pink Cone is created using the `new` method.
- Black Cone is created using the existing method.

## Migration Guide
- Addition of `new` method to the 3D primitive Cone struct.
2024-07-16 12:59:26 +00:00
Mike
cfcb56f5b9
Remove need for EventLoopProxy to be NonSend (#14198)
# Objective

- Continue to pare down the uses on NonSend resources in the engine. In
this case, EventLoopProxy used to be `!Sync`, but is now `Sync` in the
latest version of winit.

## Solution

- New type `EventLoopProxy` as `EventLoopProxyWrapper` to make it into a
normal resource.
- Update the `custom_user_event` example as it no longer needs to
indirectly access the `EventLoopProxy` through a static variable
anymore.

## Testing

- Ran the example. The resource exists just for users to use, so there
aren't any in engine uses for it currently.

---

## Changelog

- make EventLoopProxy into a regular resource. 

## Migration Guide

`EventLoopProxy` has been renamed to `EventLoopProxyWrapper` and is now
`Send`, making it an ordinary resource.

Before:
```rust
event_loop_system(event_loop: NonSend<EventLoopProxy<MyEvent>>) {
    event_loop.send_event(MyEvent);
}
```

After:
```rust
event_loop_system(event_loop: Res<EventLoopProxy<MyEvent>>) {
    event_loop.send_event(MyEvent);
}
```
2024-07-16 06:59:01 +00:00
Gino Valente
1042f09c2e
bevy_reflect: Add DynamicClosure and DynamicClosureMut (#14141)
# Objective

As mentioned in
[this](https://github.com/bevyengine/bevy/pull/13152#issuecomment-2198387297)
comment, creating a function registry (see #14098) is a bit difficult
due to the requirements of `DynamicFunction`. Internally, a
`DynamicFunction` contains a `Box<dyn FnMut>` (the function that reifies
reflected arguments and calls the actual function), which requires `&mut
self` in order to be called.

This means that users would require a mutable reference to the function
registry for it to be useful— which isn't great. And they can't clone
the `DynamicFunction` either because cloning an `FnMut` isn't really
feasible (wrapping it in an `Arc` would allow it to be cloned but we
wouldn't be able to call the clone since we need a mutable reference to
the `FnMut`, which we can't get with multiple `Arc`s still alive,
requiring us to also slap in a `Mutex`, which adds additional overhead).

And we don't want to just replace the `dyn FnMut` with `dyn Fn` as that
would prevent reflecting closures that mutate their environment.

Instead, we need to introduce a new type to split the requirements of
`DynamicFunction`.

## Solution

Introduce new types for representing closures.

Specifically, this PR introduces `DynamicClosure` and
`DynamicClosureMut`. Similar to how `IntoFunction` exists for
`DynamicFunction`, two new traits were introduced: `IntoClosure` and
`IntoClosureMut`.

Now `DynamicFunction` stores a `dyn Fn` with a `'static` lifetime.
`DynamicClosure` also uses a `dyn Fn` but has a lifetime, `'env`, tied
to its environment. `DynamicClosureMut` is most like the old
`DynamicFunction`, keeping the `dyn FnMut` and also typing its lifetime,
`'env`, to the environment

Here are some comparison tables:

|   | `DynamicFunction` | `DynamicClosure` | `DynamicClosureMut` |
| - | ----------------- | ---------------- | ------------------- |
| Callable with `&self` |  |  |  |
| Callable with `&mut self` |  |  |  |
| Allows for non-`'static` lifetimes |  |  |  |

|   | `IntoFunction` | `IntoClosure` | `IntoClosureMut` |
| - | -------------- | ------------- | ---------------- |
| Convert `fn` functions |  |  |  |
| Convert `fn` methods |  |  |  |
| Convert anonymous functions |  |  |  |
| Convert closures that capture immutable references |  |  |  |
| Convert closures that capture mutable references |  |  |  |
| Convert closures that capture owned values | [^1] |  |  |

[^1]: Due to limitations in Rust, `IntoFunction` can't be implemented
for just functions (unless we forced users to manually coerce them to
function pointers first). So closures that meet the trait requirements
_can technically_ be converted into a `DynamicFunction` as well. To both
future-proof and reduce confusion, though, we'll just pretend like this
isn't a thing.

```rust
let mut list: Vec<i32> = vec![1, 2, 3];

// `replace` is a closure that captures a mutable reference to `list`
let mut replace = |index: usize, value: i32| -> i32 {
  let old_value = list[index];
  list[index] = value;
  old_value
};

// Convert the closure into a dynamic closure using `IntoClosureMut::into_closure_mut`
let mut func: DynamicClosureMut = replace.into_closure_mut();

// Dynamically call the closure:
let args = ArgList::default().push_owned(1_usize).push_owned(-2_i32);
let value = func.call_once(args).unwrap().unwrap_owned();

// Check the result:
assert_eq!(value.take::<i32>().unwrap(), 2);
assert_eq!(list, vec![1, -2, 3]);
```

### `ReflectFn`/`ReflectFnMut`

To make extending the function reflection system easier (the blanket
impls for `IntoFunction`, `IntoClosure`, and `IntoClosureMut` are all
incredibly short), this PR generalizes callables with two new traits:
`ReflectFn` and `ReflectFnMut`.

These traits mimic `Fn` and `FnMut` but allow for being called via
reflection. In fact, their blanket implementations are identical save
for `ReflectFn` being implemented over `Fn` types and `ReflectFnMut`
being implemented over `FnMut` types.

And just as `Fn` is a subtrait of `FnMut`, `ReflectFn` is a subtrait of
`ReflectFnMut`. So anywhere that expects a `ReflectFnMut` can also be
given a `ReflectFn`.

To reiterate, these traits aren't 100% necessary. They were added in
purely for extensibility. If we decide to split things up differently or
add new traits/types in the future, then those changes should be much
simpler to implement.

### `TypedFunction`

Because of the split into `ReflectFn` and `ReflectFnMut`, we needed a
new way to access the function type information. This PR moves that
concept over into `TypedFunction`.

Much like `Typed`, this provides a way to access a function's
`FunctionInfo`.

By splitting this trait out, it helps to ensure the other traits are
focused on a single responsibility.

### Internal Macros

The original function PR (#13152) implemented `IntoFunction` using a
macro which was passed into an `all_tuples!` macro invocation. Because
we needed the same functionality for these new traits, this PR has
copy+pasted that code for `ReflectFn`, `ReflectFnMut`, and
`TypedFunction`— albeit with some differences between them.

Originally, I was going to try and macro-ify the impls and where clauses
such that we wouldn't have to straight up duplicate a lot of this logic.
However, aside from being more complex in general, autocomplete just
does not play nice with such heavily nested macros (tried in both
RustRover and VSCode). And both of those problems told me that it just
wasn't worth it: we need to ensure the crate is easily maintainable,
even at the cost of duplicating code.

So instead, I made sure to simplify the macro code by removing all
fully-qualified syntax and cutting the where clauses down to the bare
essentials, which helps to clean up a lot of the visual noise. I also
tried my best to document the macro logic in certain areas (I may even
add a bit more) to help with maintainability for future devs.

### Documentation

Documentation for this module was a bit difficult for me. So many of
these traits and types are very interconnected. And each trait/type has
subtle differences that make documenting it in a single place, like at
the module level, difficult to do cleanly. Describing the valid
signatures is also challenging to do well.

Hopefully what I have here is okay. I think I did an okay job, but let
me know if there any thoughts on ways to improve it. We can also move
such a task to a followup PR for more focused discussion.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

---

## Changelog

- Added `DynamicClosure` struct
- Added `DynamicClosureMut` struct
- Added `IntoClosure` trait
- Added `IntoClosureMut` trait
- Added `ReflectFn` trait
- Added `ReflectFnMut` trait
- Added `TypedFunction` trait
- `IntoFunction` now only works for standard Rust functions
- `IntoFunction` no longer takes a lifetime parameter
- `DynamicFunction::call` now only requires `&self`
- Removed `DynamicFunction::call_once`
- Changed the `IntoReturn::into_return` signature to include a where
clause

## Internal Migration Guide

> [!important]
> Function reflection was introduced as part of the 0.15 dev cycle. This
migration guide was written for developers relying on `main` during this
cycle, and is not a breaking change coming from 0.14.

### `IntoClosure`

`IntoFunction` now only works for standard Rust functions. Calling
`IntoFunction::into_function` on a closure that captures references to
its environment (either mutable or immutable), will no longer compile.

Instead, you will need to use either `IntoClosure::into_closure` to
create a `DynamicClosure` or `IntoClosureMut::into_closure_mut` to
create a `DynamicClosureMut`, depending on your needs:

```rust
let punct = String::from("!");
let print = |value: String| {
    println!("{value}{punct}");
};

// BEFORE
let func: DynamicFunction = print.into_function();

// AFTER
let func: DynamicClosure = print.into_closure();
```

### `IntoFunction` lifetime

Additionally, `IntoFunction` no longer takes a lifetime parameter as it
always expects a `'static` lifetime. Usages will need to remove any
lifetime parameters:

```rust
// BEFORE
fn execute<'env, F: IntoFunction<'env, Marker>, Marker>(f: F) {/* ... */}

// AFTER
fn execute<F: IntoFunction<Marker>, Marker>(f: F) {/* ... */}
```

### `IntoReturn`

`IntoReturn::into_return` now has a where clause. Any manual
implementors will need to add this where clause to their implementation.
2024-07-16 03:22:43 +00:00
Patrick Walton
20c6bcdba4
Allow volumetric fog to be localized to specific, optionally voxelized, regions. (#14099)
Currently, volumetric fog is global and affects the entire scene
uniformly. This is inadequate for many use cases, such as local smoke
effects. To address this problem, this commit introduces *fog volumes*,
which are axis-aligned bounding boxes (AABBs) that specify fog
parameters inside their boundaries. Such volumes can also specify a
*density texture*, a 3D texture of voxels that specifies the density of
the fog at each point.

To create a fog volume, add a `FogVolume` component to an entity (which
is included in the new `FogVolumeBundle` convenience bundle). Like light
probes, a fog volume is conceptually a 1×1×1 cube centered on the
origin; a transform can be used to position and resize this region. Many
of the fields on the existing `VolumetricFogSettings` have migrated to
the new `FogVolume` component. `VolumetricFogSettings` on a camera is
still needed to enable volumetric fog. However, by itself
`VolumetricFogSettings` is no longer sufficient to enable volumetric
fog; a `FogVolume` must be present. Applications that wish to retain the
old global fog behavior can simply surround the scene with a large fog
volume.

By way of implementation, this commit converts the volumetric fog shader
from a full-screen shader to one applied to a mesh. The strategy is
different depending on whether the camera is inside or outside the fog
volume. If the camera is inside the fog volume, the mesh is simply a
plane scaled to the viewport, effectively falling back to a full-screen
pass. If the camera is outside the fog volume, the mesh is a cube
transformed to coincide with the boundaries of the fog volume's AABB.
Importantly, in the latter case, only the front faces of the cuboid are
rendered. Instead of treating the boundaries of the fog as a sphere
centered on the camera position, as we did prior to this patch, we
raytrace the far planes of the AABB to determine the portion of each ray
contained within the fog volume. We then raymarch in shadow map space as
usual. If a density texture is present, we modulate the fixed density
value with the trilinearly-interpolated value from that texture.

Furthermore, this patch introduces optional jitter to fog volumes,
intended for use with TAA. This modifies the position of the ray from
frame to frame using interleaved gradient noise, in order to reduce
aliasing artifacts. Many implementations of volumetric fog in games use
this technique. Note that this patch makes no attempt to write a motion
vector; this is because when a view ray intersects multiple voxels
there's no single direction of motion. Consequently, fog volumes can
have ghosting artifacts, but because fog is "ghostly" by its nature,
these artifacts are less objectionable than they would be for opaque
objects.

A new example, `fog_volumes`, has been added. It demonstrates a single
fog volume containing a voxelized representation of the Stanford bunny.
The existing `volumetric_fog` example has been updated to use the new
local volumetrics API.

## Changelog

### Added

* Local `FogVolume`s are now supported, to localize fog to specific
regions. They can optionally have 3D density voxel textures for precise
control over the distribution of the fog.

### Changed

* `VolumetricFogSettings` on a camera no longer enables volumetric fog;
instead, it simply enables the processing of `FogVolume`s within the
scene.

## Migration Guide

* A `FogVolume` is now necessary in order to enable volumetric fog, in
addition to `VolumetricFogSettings` on the camera. Existing uses of
volumetric fog can be migrated by placing a large `FogVolume`
surrounding the scene.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2024-07-16 03:14:12 +00:00
Joseph
ee15be8549
Make Tasks functional on WASM (#13889)
# Objective

Right not bevy's task pool abstraction is kind of useless on wasm, since
it returns a `FakeTask` which can't be interacted with. This is only
good for fire-and-forget it tasks, and isn't even that useful since it's
just a thin wrapper around `wasm-bindgen-futures::spawn_local`

## Solution

Add a simple `Task<T>` handler type to wasm targets that allow waiting
for a task's output or periodically checking for its completion. This PR
aims to give the wasm version of these tasks feature parity with the
native, multi-threaded version of the task

## Testing

- Did you test these changes? *Not yet*

---------

Co-authored-by: Periwink <charlesbour@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-07-16 01:15:03 +00:00
BD103
c3057d4353
plugin_group! macro (adopted) (#14339)
# Objective

- Adopted from #11460.
- Closes #7332.
- The documentation for `DefaultPlugins` and `MinimalPlugins` frequently
goes out of date because it is not .

## Solution

- Create a macro, `plugin_group!`, to automatically create
`PluginGroup`s and document them.

## Testing

- Run `cargo-expand` on the generated code for `DefaultPlugins` and
`MinimalPlugins`.
- Try creating a custom plugin group with the macro.

---

## Showcase

- You can now define custom `PluginGroup`s using the `plugin_group!`
macro.

```rust
plugin_group! {
    /// My really cool plugic group!
    pub struct MyPluginGroup {
        physics:::PhysicsPlugin,
        rendering:::RenderingPlugin,
        ui:::UiPlugin,
    }
}
```

<details>
  <summary>Expanded output</summary>

```rust
/// My really cool plugic group!
///
/// - [`PhysicsPlugin`](physics::PhysicsPlugin)
/// - [`RenderingPlugin`](rendering::RenderingPlugin)
/// - [`UiPlugin`](ui::UiPlugin)
pub struct MyPluginGroup;
impl ::bevy_app::PluginGroup for MyPluginGroup {
    fn build(self) -> ::bevy_app::PluginGroupBuilder {
        let mut group = ::bevy_app::PluginGroupBuilder::start::<Self>();
        {
            const _: () = {
                const fn check_default<T: Default>() {}
                check_default::<physics::PhysicsPlugin>();
            };
            group = group.add(<physics::PhysicsPlugin>::default());
        }
        {
            const _: () = {
                const fn check_default<T: Default>() {}
                check_default::<rendering::RenderingPlugin>();
            };
            group = group.add(<rendering::RenderingPlugin>::default());
        }
        {
            const _: () = {
                const fn check_default<T: Default>() {}
                check_default::<ui::UiPlugin>();
            };
            group = group.add(<ui::UiPlugin>::default());
        }
        group
    }
}
```

</details>

---------

Co-authored-by: Doonv <58695417+doonv@users.noreply.github.com>
Co-authored-by: Mateusz Wachowiak <mateusz_wachowiak@outlook.com>
2024-07-16 01:14:33 +00:00
Lura
9a1a84dd22
Fix error/typo in SMAA shader (#14338)
# Objective

- Actually use the value assigned to `d_xz`, like in [the original SMAA
implementation](https://github.com/iryoku/smaa/blob/master/SMAA.hlsl#L960).
This not already being the case was likely a mistake when converting
from HLSL to WGSL

## Solution

- Use `d_xz.x` and `d_xz.y` instead of `d.x` and `d.z`

## Testing

- Quickly tested on Windows 11, `x86_64-pc-windows-gnu` `1.79.0` with
the latest NVIDIA drivers. App runs with SMAA enabled and everything
seems to work as intended
- I didn't observe any major visual difference between this and the
previous version, though this should be more correct as it matches the
original SMAA implementation
2024-07-15 23:40:39 +00:00
Jonathan Chan Kwan Yin
e66cd484a7
Add insert_by_id and try_insert_by_id to EntityCommands (#14283)
# Objective

- Allow queuing insertion of dynamic components to an existing entity

## Solution

- Add `insert_by_id<T: Send + 'static>(commands: &mut EntityCommands,
component_id: ComponentId, value: T)` and the `try_insert_by_id`
counterpart

## Testing

TODO

- Did you test these changes? If so, how?
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

## Alternatives

This PR is not feature-complete for dynamic components. In particular,
it
- only supports one component
- only supports adding components with a known, sized type

These were not implemented because doing so would require enhancing
`CommandQueue` to support pushing unsized commands (or equivalently,
pushing commands with a buffer of data). Even so, the cost would not be
transparent compared to the implementation in this PR, which simply
captures the `ComponentId` and `value: T` into the command closure and
can be easily memcpy'ed to the stack during execution. For example, to
efficiently pass `&[ComponentId]` from the caller to the world, we would
need to:

1. Update `CommandQueue.bytes` from `Vec<MaybeUninit<u8>>` to
`Vec<MaybeUninit<usize>>` so that it has the same alignment as
`ComponentId` (which probably needs to be made `#[repr(transparent)]`
too)
2. After pushing the Command metadata, push padding bytes until the vec
len is a multiple of `size_of::<usize>()`
3. Store `components.len()` in the data
4. memcpy the user-provided `&[ComponentId]` to `CommandQueue.bytes`
5. During execution, round up the data pointer behind the `Command` to
skip padding, then cast the pointer and consume it as a `&[ComponentId]`

The effort here seems unnecessarily high, unless someone else has such a
requirement. At least for the use case I am working with, I only need a
single known type, and if we need multiple components, we could always
enhance this function to accept a `[ComponentId; N]`.

I recommend enhancing the `Bundle` API in the long term to achieve this
goal more elegantly.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Felix Rath <felixm.rath@gmail.com>
2024-07-15 23:29:13 +00:00
BD103
5ea88895e9
Remove unused default feature from bevy_window (#14313)
# Objective

- Extracted from #14298.
- `bevy_window` has an empty `default` feature that does not enable
anything, which is equivalent to not having any default features.

## Solution

- Remove it :)
- This is technically a breaking change, but specifying `features =
["default"]` manually in `Cargo.toml` is highly discouraged, so the
impact is low.

---

## Migration Guide

`bevy_window` had an empty default feature flag that did not do
anything, so it was removed. You may have to remove any references to it
if you specified it manually.

```toml
# 0.14
[dependencies]
bevy_window = { version = "0.14", default-features = false, features = ["default"] }

# 0.15
[dependencies]
bevy_window = { version = "0.15", default-features = false }
```
2024-07-15 16:49:00 +00:00
Brezak
6522795889
Specify test group names in github summary for compile fail tests (#14330)
# Objective

The github action summary titles every compile test group as
`compile_fail_utils`.


![image](https://github.com/user-attachments/assets/9d00a113-6772-430c-8da9-bffe6a60a8f8)

## Solution

Manually specify group names for compile fail tests.

## Testing

- Wait for compile fail tests to run.
- Observe the generated summary.
2024-07-15 16:13:03 +00:00
SpecificProtagonist
d276525350
Allow non-static trigger targets (#14327)
# Objective

`TriggerTargets` can not be borrowed for use in `World::trigger_targets`

## Solution

Drop `'static` bound on `TriggerEvent`, keep it for `Command` impl.

## Testing

n/a
2024-07-15 16:10:57 +00:00
Joona Aalto
cf1b7fa4cc
Implement Bounded2d for Annulus (#14326)
# Objective

`Annulus` is missing `Bounded2d` even though the implementation is
trivial.

## Solution

Implement `Bounded2d` for `Annulus`.

## Testing

There is a basic test to verify that the produced bounding volumes are
correct.
2024-07-15 16:08:35 +00:00
Joona Aalto
36b521d069
Improve isometry docs (#14318)
# Objective

Fixes #14308.

#14269 added the `Isometry2d` and `Isometry3d` types, but they don't
have usage examples or much documentation on what the types actually
represent or what they may be useful for.

In addition, their module is public and the types are not re-exported at
the crate root, unlike all the other core math types like Glam's types,
direction types, and `Rot2`.

## Solution

Improve the documentation of `Isometry2d` and `Isometry3d`, explaining
what they represent and can be useful for, along with doc examples on
common high-level usage. I also made the way the types are exported
consistent with other core math types.

This does add some duplication, but I personally think having good docs
for this is valuable, and people are also less likely to look at the
module-level docs than type-level docs.
2024-07-15 16:05:33 +00:00
Torstein Grindvik
ee0a85766d
Clearer spatial bundle pub const docs (#14293)
# Objective

The docs on SpatialBundle's pub const constructors mention that one is
"visible" when it's actually inherited, which afaik means it's
conditional on its parent's visibility.

I feel it's more correct like this.

_Also I'm seeing how making a PR from github.dev works hopefully nothing
weird happens_
2024-07-15 16:03:09 +00:00
BD103
b6f61b3ac6
Fix bevy_window failing with serialize feature (#14298)
# Objective

- [`flag-frenzy`](https://github.com/TheBevyFlock/flag-frenzy) found an
issue where `bevy_window` would fail to build when its `serialize`
feature is enabled.
- See
[here](https://github.com/TheBevyFlock/flag-frenzy/actions/runs/9924187577/job/27415224405)
for the specific log.

## Solution

- Turns out it was failing because the `bevy_ecs/serialize` feature was
not enabled. This error can be fixed by adding the flag as a dependency.

## Testing

```bash
cargo check -p bevy_window -F serialize
# Or if you're very cool...
flag-frenzy --manifest-path path/to/bevy/Cargo.toml --config config -p bevy_window
```
2024-07-15 16:00:49 +00:00
masonk
d2bf052515
Clarify GlobalTransform::transform_point (#14292)
The existing doc comment for GlobalTransform::transform_point is
unclear, or, arguably, incorrect.
https://github.com/bevyengine/bevy/discussions/8501 also mentions this.

Additionally, a user reading the doc for transform_point might be
looking for one of the three other transforms that I mentioned in this
doc comment.

---------

Co-authored-by: Mason Kramer <mason@masonkramer.net>
Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2024-07-15 15:59:29 +00:00
Ben Frankel
7cb97852a5
Remove second generic from .add_before, .add_after (#14285)
# Objective

```rust
// Currently:
builder.add_after::<FooPlugin, _>(BarPlugin);
// After this PR:
builder.add_after::<FooPlugin>(BarPlugin);
```

This removes some weirdness and better parallels the rest of the
`PluginGroupBuilder` API.

## Solution

Define a helper method `type_id_of_val` to use in `.add_before` and
`.add_after` instead of `TypeId::of::<T>` (which requires the plugin
type to be nameable, preventing `impl Plugin` from being used).

## Testing

Ran `cargo run -p ci lints` successfully.

## Migration Guide

Removed second generic from `PluginGroupBuilder` methods: `add_before`
and `add_after`.

```rust
// Before:
DefaultPlugins
    .build()
    .add_before::<WindowPlugin, _>(FooPlugin)
    .add_after::<WindowPlugin, _>(BarPlugin)

// After:
DefaultPlugins
    .build()
    .add_before::<WindowPlugin>(FooPlugin)
    .add_after::<WindowPlugin>(BarPlugin)
```

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-07-15 15:58:14 +00:00
Sou1gh0st
65aae92127
Add support for skybox transformation (#14267)
# Objective

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

## Solution

- Add a view space transformation for the skybox

## Testing

- I have tested the newly added `transform` field using the `skybox`
example.
```
diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs
index beaf5b268..d16cbe988 100644
--- a/examples/3d/skybox.rs
+++ b/examples/3d/skybox.rs
@@ -81,6 +81,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
         Skybox {
             image: skybox_handle.clone(),
             brightness: 1000.0,
+            rotation: Quat::from_rotation_x(PI * -0.5),
         },
     ));
```
<img width="1280" alt="image"
src="https://github.com/bevyengine/bevy/assets/6300263/1230a608-58ea-492d-a811-90c54c3b43ef">


## Migration Guide
- Since we have added a new filed to the Skybox struct, users will need
to include `..Default::default()` or some rotation value in their
initialization code.
2024-07-15 15:53:20 +00:00
Alix Bott
a79df7b124
Fix overflow in RenderLayers::iter_layers (#14264)
# Objective

- Fixes overflow when calling `RenderLayers::iter_layers` on layers of
the form `k * 64 - 1`
- Causes a panic in debug mode, and an infinite iterator in release mode

## Solution

- Use `u64::checked_shr` instead of `>>=`

## Testing

- Added a test case for this: `render_layer_iter_no_overflow`
2024-07-15 15:50:36 +00:00
SpecificProtagonist
ab255aefc6
Implement FromIterator/IntoIterator for dynamic types (#14250)
# Objective

Implement FromIterator/IntoIterator for dynamic types where missing

Note:
- can't impl `IntoIterator` for `&Array` & co because of orphan rules
- `into_iter().collect()` is a no-op for `Vec`s because of
specialization

---

## Migration Guide

- Change `DynamicArray::from_vec` to `DynamicArray::from_iter`
2024-07-15 15:38:11 +00:00
Ben Frankel
18abe2186c
Fix inaccurate docs for Commands::spawn_empty (#14234)
# Objective

`Commands::spawn_empty` docs say that it queues a command to spawn an
entity, but it doesn't. It immediately reserves an `Entity` to be
spawned at the next flush point, which is possible because
`Entities::reserve_entity()` takes `&self` and no components are added
yet.

## Solution

Fix docs.
2024-07-15 15:32:20 +00:00
UkoeHB
c3320627ac
Clean up UiSystem system sets (#14228)
# Objective

- All UI systems should be in system sets that are easy to order around
in user code.

## Solution

- Add `UiSystem::Prepare` and `UiSystem::PostLayout` system sets to
capture floater systems.
- Adjust how UI systems are scheduled to align with the new sets.

This is *mostly* a pure refactor without any behavior/scheduling
changes. See migration guide.

## Testing

- Not tested, correctness by inspection.

---

## Migration Guide

`UiSystem` system set adjustments.
- The `UiSystem::Outline` system set is now strictly ordered after
`UiSystem::Layout`, rather than overlapping it.
2024-07-15 15:27:38 +00:00
Pixelstorm
0f7c548a4a
Component Lifecycle Hook & Observer Trigger for replaced values (#14212)
# Objective

Fixes #14202

## Solution

Add `on_replaced` component hook and `OnReplaced` observer trigger

## Testing

- Did you test these changes? If so, how?
  - Updated & added unit tests

---

## Changelog

- Added new `on_replaced` component hook and `OnReplaced` observer
trigger for performing cleanup on component values when they are
overwritten with `.insert()`
2024-07-15 15:24:15 +00:00
GT
e79f91fc45
Rename bevy_core::name::DebugName to bevy_core::name::NameOrEntity (#14211)
# Objective

- Fixes #14039

## Solution

- Rename.

## Testing

- CI

---

## Migration Guide

- Rename usages of `bevy_core::name::DebugName` to
`bevy_core::name::NameOrEntity`
2024-07-15 15:21:41 +00:00
MiniaczQ
bc72cedfe3
Make initial StateTransition run before PreStartup (#14208)
# Objective

- Fixes #14206 

## Solution

- Run initial `StateTransition` as a startup schedule before
`PreStartup`, instead of running it inside `Startup` as an exclusive
system.

Related discord discussion:

https://discord.com/channels/691052431525675048/692572690833473578/1259543775668207678

## Testing

Reproduction now works correctly:

```rs
use bevy::prelude::*;

#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
enum AppState {
    #[default]
    Menu,
    InGame,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<AppState>()
        .add_systems(Startup, setup)
        .add_systems(OnEnter(AppState::Menu), enter_menu_state)
        .run();
}

fn setup(mut next_state: ResMut<NextState<AppState>>) {
    next_state.set(AppState::Menu);
}

fn enter_menu_state() {
    println!("Entered menu state");
}
```


![image](https://github.com/bevyengine/bevy/assets/13040204/96d7a533-c439-4c0b-8f15-49f620903ce1)


---

## Changelog

- Initial `StateTransition` runs before `PreStartup` instead of inside
`Startup`.
2024-07-15 15:08:54 +00:00
JMS55
6e8d43a037
Faster MeshletMesh deserialization (#14193)
# Objective
- Using bincode to deserialize binary into a MeshletMesh is expensive
(~77ms for a 5mb file).

## Solution
- Write a custom deserializer using bytemuck's Pod types and slice
casting.
  - Total asset load time has gone from ~102ms to ~12ms.
- Change some types I never meant to be public to private and other misc
cleanup.

## Testing
- Ran the meshlet example and added timing spans to the asset loader.

---

## Changelog
- Improved `MeshletMesh` loading speed
- The `MeshletMesh` disk format has changed, and
`MESHLET_MESH_ASSET_VERSION` has been bumped
- `MeshletMesh` fields are now private
- Renamed `MeshletMeshSaverLoad` to `MeshletMeshSaverLoader`
- The `Meshlet`, `MeshletBoundingSpheres`, and `MeshletBoundingSphere`
types are now private
- Removed `MeshletMeshSaveOrLoadError::SerializationOrDeserialization`
- Added `MeshletMeshSaveOrLoadError::WrongFileType`

## Migration Guide
- Regenerate your `MeshletMesh` assets, as the disk format has changed,
and `MESHLET_MESH_ASSET_VERSION` has been bumped
- `MeshletMesh` fields are now private
- `MeshletMeshSaverLoad` is now named `MeshletMeshSaverLoader`
- The `Meshlet`, `MeshletBoundingSpheres`, and `MeshletBoundingSphere`
types are now private
- `MeshletMeshSaveOrLoadError::SerializationOrDeserialization` has been
removed
- Added `MeshletMeshSaveOrLoadError::WrongFileType`, match on this
variant if you match on `MeshletMeshSaveOrLoadError`
2024-07-15 15:06:02 +00:00
ickk
3dd4953b97
bevy_math: faster sphere sampling (#14168)
Uses fewer transcendental functions than the existing approach
2024-07-15 15:01:18 +00:00
Periwink
da997dd0ea
Allow observer systems to have outputs (#14159)
# Objective

Fixes https://github.com/bevyengine/bevy/issues/14157

## Solution

- Update the ObserverSystem traits to accept an `Out` parameter

## Testing

- Added a test where an observer system has a non-empty output which is
piped into another system

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-15 14:59:12 +00:00
daxpedda
e7271709b2
Expose Winit's KeyEvent::repeat in KeyboardInput (#14161)
# Objective

I would like to know if an event was emitted because of "key repeats" or
not.
Winit already exposes this information, but it isn't sent along by Bevy,
which this PR intends to address.

## Solution

Expose
[`winit::event::KeyEvent::repeat`](https://docs.rs/winit/0.30.3/winit/event/struct.KeyEvent.html#structfield.repeat)
in
[`bevy::input:⌨️:KeyboardInput`](https://docs.rs/bevy/0.14.0/bevy/input/keyboard/struct.KeyboardInput.html).

## Testing

Just hold any regular key down and only the first event should have
`KeyboardInput::repeat` set to `false`. Most OSs have "key repeat"
enabled by default.

---

## Changelog

- Added `KeyboardInput::repeat` signifying if this event was sent in
response to a "key repeat" event or not.
2024-07-15 14:52:33 +00:00
Dmytro Banin
bf53cf30c7
Align Scene::write_to_world_with to match DynamicScene::write_to_world_with (#13855)
# Objective

Fixes a regression in [previously merged but then reverted
pr](https://github.com/bevyengine/bevy/pull/13714) that aligns
lower-level `Scene` API with that in `DynamicScene`. Please look at the
original pr for more details.

The problem was `spawn_sync_internal` is used in `spawn_queued_scenes`.
Since instance creation was moved up a level we need to make sure we add
a specific instance to `SceneSpawner::spawned_instances` when using
`spawn_sync_internal` (just like we do for `DynamicScene`).

Please look at the last commit when reviewing.

## Testing

`alien_cake_addict` and `deferred_rendering` examples look as expected.

## Changelog

Changed `Scene::write_to_world_with` to take `entity_map` as an argument
and no longer return an `InstanceInfo`

## Migration Guide

`Scene::write_to_world_with` no longer returns an `InstanceInfo`. 

Before
```rust
scene.write_to_world_with(world, &registry)
```
After
```rust
let mut entity_map = EntityHashMap::default();
scene.write_to_world_with(world, &mut entity_map, &registry)
```
2024-07-15 14:04:09 +00:00
Jer
4340f7b7c6
add debug logging to ascertain the base path the asset server is using (#13820)
# Objective
Explicitly and exactly know what of the environment variables (if any)
are being used/not-used/found-not-found by the
`bevy_asset::io::file::get_base_path()`.

- Describe the objective or issue this PR addresses:
In a sufficiently complex project, with enough crates and such it _can_
be hard to know what the Asset Server is using as, what in the bevy
parlance is its 'base path', this change seems to be the lowest effort
to discovering that.

## Solution

- Added `debug!` logging to the `FileAssetReader::new()` call.

## Testing
See output by making a project and trying something like
`RUST_LOG=bevy_asset::io::file=debug cargo run`
- Ran Bevy's tests.

- How can other people (reviewers) test your changes?: Intentionally
mess with your `env` variables (BEVY_ASSET_ROOT and CARGO_MANIFEST_DIR,
scatter assets about and attempt to (without this change) locate where
it's going wrong.

- Is there anything specific they need to know?: I encountered this
issue in a rather large workspace with many many crates with multiple
nested asset directories.

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test? Linux.

---
2024-07-15 14:00:43 +00:00
Patrick Walton
fcda67e894
Start a built-in postprocessing stack, and implement chromatic aberration in it. (#13695)
This commit creates a new built-in postprocessing shader that's designed
to hold miscellaneous postprocessing effects, and starts it off with
chromatic aberration. Possible future effects include vignette, film
grain, and lens distortion.

[Chromatic aberration] is a common postprocessing effect that simulates
lenses that fail to focus all colors of light to a single point. It's
often used for impact effects and/or horror games. This patch uses the
technique from *Inside* ([Gjøl & Svendsen 2016]), which allows the
developer to customize the particular color pattern to achieve different
effects. Unity HDRP uses the same technique, while Unreal has a
hard-wired fixed color pattern.

A new example, `post_processing`, has been added, in order to
demonstrate the technique. The existing `post_processing` shader has
been renamed to `custom_post_processing`, for clarity.

[Chromatic aberration]:
https://en.wikipedia.org/wiki/Chromatic_aberration

[Gjøl & Svendsen 2016]:
https://github.com/playdeadgames/publications/blob/master/INSIDE/rendering_inside_gdc2016.pdf

![Screenshot 2024-06-04
180304](https://github.com/bevyengine/bevy/assets/157897/3631c64f-a615-44fe-91ca-7f04df0a54b2)

![Screenshot 2024-06-04
180743](https://github.com/bevyengine/bevy/assets/157897/ee055cbf-4314-49c5-8bfa-8d8a17bd52bb)

## Changelog

### Added

* Chromatic aberration is now available as a built-in postprocessing
effect. To use it, add `ChromaticAberration` to your camera.
2024-07-15 13:59:02 +00:00
Miles Silberling-Cook
ed2b8e0f35
Minimal Bubbling Observers (#13991)
# Objective

Add basic bubbling to observers, modeled off `bevy_eventlistener`.

## Solution

- Introduce a new `Traversal` trait for components which point to other
entities.
- Provide a default `TraverseNone: Traversal` component which cannot be
constructed.
- Implement `Traversal` for `Parent`.
- The `Event` trait now has an associated `Traversal` which defaults to
`TraverseNone`.
- Added a field `bubbling: &mut bool` to `Trigger` which can be used to
instruct the runner to bubble the event to the entity specified by the
event's traversal type.
- Added an associated constant `SHOULD_BUBBLE` to `Event` which
configures the default bubbling state.
- Added logic to wire this all up correctly.

Introducing the new associated information directly on `Event` (instead
of a new `BubblingEvent` trait) lets us dispatch both bubbling and
non-bubbling events through the same api.

## Testing

I have added several unit tests to cover the common bugs I identified
during development. Running the unit tests should be enough to validate
correctness. The changes effect unsafe portions of the code, but should
not change any of the safety assertions.

## Changelog

Observers can now bubble up the entity hierarchy! To create a bubbling
event, change your `Derive(Event)` to something like the following:

```rust
#[derive(Component)]
struct MyEvent;

impl Event for MyEvent {
    type Traverse = Parent; // This event will propagate up from child to parent.
    const AUTO_PROPAGATE: bool = true; // This event will propagate by default.
}
```

You can dispatch a bubbling event using the normal
`world.trigger_targets(MyEvent, entity)`.

Halting an event mid-bubble can be done using
`trigger.propagate(false)`. Events with `AUTO_PROPAGATE = false` will
not propagate by default, but you can enable it using
`trigger.propagate(true)`.

If there are multiple observers attached to a target, they will all be
triggered by bubbling. They all share a bubbling state, which can be
accessed mutably using `trigger.propagation_mut()` (`trigger.propagate`
is just sugar for this).

You can choose to implement `Traversal` for your own types, if you want
to bubble along a different structure than provided by `bevy_hierarchy`.
Implementers must be careful never to produce loops, because this will
cause bevy to hang.

## Migration Guide
+ Manual implementations of `Event` should add associated type `Traverse
= TraverseNone` and associated constant `AUTO_PROPAGATE = false`;
+ `Trigger::new` has new field `propagation: &mut Propagation` which
provides the bubbling state.
+ `ObserverRunner` now takes the same `&mut Propagation` as a final
parameter.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-07-15 13:39:41 +00:00
Gino Valente
aa241672e1
bevy_reflect: Nested TypeInfo getters (#13321)
# Objective

Right now, `TypeInfo` can be accessed directly from a type using either
`Typed::type_info` or `Reflect::get_represented_type_info`.

However, once that `TypeInfo` is accessed, any nested types must be
accessed via the `TypeRegistry`.

```rust
#[derive(Reflect)]
struct Foo {
  bar: usize
}

let registry = TypeRegistry::default();

let TypeInfo::Struct(type_info) = Foo::type_info() else {
  panic!("expected struct info");
};

let field = type_info.field("bar").unwrap();

let field_info = registry.get_type_info(field.type_id()).unwrap();
assert!(field_info.is::<usize>());;
```

## Solution

Enable nested types within a `TypeInfo` to be retrieved directly.

```rust
#[derive(Reflect)]
struct Foo {
  bar: usize
}

let TypeInfo::Struct(type_info) = Foo::type_info() else {
  panic!("expected struct info");
};

let field = type_info.field("bar").unwrap();

let field_info = field.type_info().unwrap();
assert!(field_info.is::<usize>());;
```

The particular implementation was chosen for two reasons.

Firstly, we can't just store `TypeInfo` inside another `TypeInfo`
directly. This is because some types are recursive and would result in a
deadlock when trying to create the `TypeInfo` (i.e. it has to create the
`TypeInfo` before it can use it, but it also needs the `TypeInfo` before
it can create it). Therefore, we must instead store the function so it
can be retrieved lazily.

I had considered also using a `OnceLock` or something to lazily cache
the info, but I figured we can look into optimizations later. The API
should remain the same with or without the `OnceLock`.

Secondly, a new wrapper trait had to be introduced: `MaybeTyped`. Like
`RegisterForReflection`, this trait is `#[doc(hidden)]` and only exists
so that we can properly handle dynamic type fields without requiring
them to implement `Typed`. We don't want dynamic types to implement
`Typed` due to the fact that it would make the return type
`Option<&'static TypeInfo>` for all types even though only the dynamic
types ever need to return `None` (see #6971 for details).

Users should never have to interact with this trait as it has a blanket
impl for all `Typed` types. And `Typed` is automatically implemented
when deriving `Reflect` (as it is required).

The one downside is we do need to return `Option<&'static TypeInfo>`
from all these new methods so that we can handle the dynamic cases. If
we didn't have to, we'd be able to get rid of the `Option` entirely. But
I think that's an okay tradeoff for this one part of the API, and keeps
the other APIs intact.

## Testing

This PR contains tests to verify everything works as expected. You can
test locally by running:

```
cargo test --package bevy_reflect
```

---

## Changelog

### Public Changes

- Added `ArrayInfo::item_info` method
- Added `NamedField::type_info` method
- Added `UnnamedField::type_info` method
- Added `ListInfo::item_info` method
- Added `MapInfo::key_info` method
- Added `MapInfo::value_info` method
- All active fields now have a `Typed` bound (remember that this is
automatically satisfied for all types that derive `Reflect`)

### Internal Changes

- Added `MaybeTyped` trait

## Migration Guide

All active fields for reflected types (including lists, maps, tuples,
etc.), must implement `Typed`. For the majority of users this won't have
any visible impact.

However, users implementing `Reflect` manually may need to update their
types to implement `Typed` if they weren't already.

Additionally, custom dynamic types will need to implement the new hidden
`MaybeTyped` trait.
2024-07-15 00:40:07 +00:00
IceSentry
8e67aef96a
Register VisibleMeshEntities (#14320)
# Objective

- A recent PR added this type but never registered it which breaks
loading some gltf

## Solution

- Register the type
2024-07-15 00:06:43 +00:00
Gino Valente
e512cb602c
bevy_reflect: TypeInfo casting methods (#13320)
# Objective

There are times when we might know the type of a `TypeInfo` ahead of
time. Or we may have already checked it one way or another.

In such cases, it's a bit cumbersome to have to pattern match every time
we want to access the nested info:

```rust
if let TypeInfo::List(info) = <Vec<i32>>::type_info() {
  // ...
} else {
  panic!("expected list info");
}
```

Ideally, there would be a way to simply perform the cast down to
`ListInfo` since we already know it will succeed.

Or even if we don't, perhaps we just want a cleaner way of exiting a
function early (i.e. with the `?` operator).

## Solution

Taking a bit from
[`mirror-mirror`](https://docs.rs/mirror-mirror/latest/mirror_mirror/struct.TypeDescriptor.html#implementations),
`TypeInfo` now has methods for attempting a cast into the variant's info
type.

```rust
let info = <Vec<i32>>::type_info().as_list().unwrap();
// ...
```

These new conversion methods return a `Result` where the error type is a
new `TypeInfoError` enum.

A `Result` was chosen as the return type over `Option` because if we do
choose to `unwrap` it, the error message will give us some indication of
what went wrong. In other words, it can truly replace those instances
where we were panicking in the `else` case.

### Open Questions

1. Should the error types instead be a struct? I chose an enum for
future-proofing, but right now it only has one error state.
Alternatively, we could make it a reflect-wide casting error so it could
be used for similar methods on `ReflectRef` and friends.
2. I was going to do it in a separate PR but should I just go ahead and
add similar methods to `ReflectRef`, `ReflectMut`, and `ReflectOwned`? 🤔
3. Should we name these `try_as_***` instead of `as_***` since they
return a `Result`?

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

---

## Changelog

### Added

- `TypeInfoError` enum
- `TypeInfo::kind` method
- `TypeInfo::as_struct` method
- `TypeInfo::as_tuple_struct` method
- `TypeInfo::as_tuple` method
- `TypeInfo::as_list` method
- `TypeInfo::as_array` method
- `TypeInfo::as_map` method
- `TypeInfo::as_enum` method
- `TypeInfo::as_value` method
- `VariantInfoError` enum
- `VariantInfo::variant_type` method
- `VariantInfo::as_unit_variant` method
- `VariantInfo::as_tuple_variant` method
- `VariantInfo::as_struct_variant` method
2024-07-14 20:10:31 +00:00
Joona Aalto
9f376df2d5
Add inverse_mul and inverse_transform_point for isometries (#14311)
# Objective

The isometry types added in #14269 support transforming other isometries
and points, as well as computing the inverse of an isometry using
`inverse`.

However, transformations like `iso1.inverse() * iso2` and `iso.inverse()
* point` can be optimized for single-shot cases using custom methods
that avoid an extra rotation operation.

## Solution

Add `inverse_mul` and `inverse_transform_point` for `Isometry2d` and
`Isometry3d`. Note that these methods are only faster when the isometry
can't be reused for multiple transformations.

## Testing

All of the methods have a test, similarly to the existing transformation
operations.
2024-07-14 19:53:40 +00:00
Joona Aalto
22b65b7256
Add Isometry2d::from_xy and Isometry3d::from_xyz (#14312)
# Objective

Creating isometry types with just a translation is a bit more verbose
than it needs to be for cases where you don't have an existing vector to
pass in.

```rust
let iso = Isometry3d::from_translation(Vec3::new(2.0, 1.0, -1.0));
```

This could be made more ergonomic with a method similar to
`Dir2::from_xy`, `Dir3::from_xyz`, and `Transform::from_xyz`:

```rust
let iso = Isometry3d::from_xyz(2.0, 1.0, -1.0);
```

## Solution

Add `Isometry2d::from_xy` and `Isometry3d::from_xyz`.
2024-07-14 19:53:30 +00:00
re0312
3b23aa0864
Fix prepass batch (#13943)
# Objective

- After #11804 , The queue_prepass_material_meshes function is now
executed in parallel with other queue_* systems. This optimization
introduced a potential issue where mesh_instance.should_batch() could
return false in queue_prepass_material_meshes due to an unset
material_bind_group_id.
2024-07-14 19:35:36 +00:00
re0312
36c6f29832
Lighting Should Only hold Vec<Entity> instead of TypeId<Vec<Entity>> (#14073)
# Objective
- After #13894, I noticed the performance of `many_lights `dropped from
120+ to 60+. I reviewed the PR but couldn't identify any mistakes. After
profiling, I discovered that `Hashmap::Clone `was very slow when its not
empty, causing `extract_light` to increase from 3ms to 8ms.
- Lighting only checks visibility for 3D Meshes. We don't need to
maintain a TypeIdMap for this, as it not only impacts performance
negatively but also reduces ergonomics.

## Solution

- use VisibleMeshEntities for lighint visibility checking.


## Performance
cargo run --release --example many_lights  --features bevy/trace_tracy 
name="bevy_pbr::light::check_point_light_mesh_visibility"}

![image](https://github.com/bevyengine/bevy/assets/45868716/8bad061a-f936-45a0-9bb9-4fbdaceec08b)

system{name="bevy_pbr::render::light::extract_lights"}

![image](https://github.com/bevyengine/bevy/assets/45868716/ca75b46c-b4ad-45d3-8c8d-66442447b753)


## Migration Guide

> now `SpotLightBundle` , `CascadesVisibleEntities `and
`CubemapVisibleEntities `use VisibleMeshEntities instead of
`VisibleEntities`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-14 17:00:54 +00:00
Matty
e13c72d8a4
Fix swapped docs for Rot2::rotation_to/from_y (#14307)
# Objective

Fixes #14301 

## Solution

Swap them so that they are no longer swapped.
2024-07-14 17:00:41 +00:00
MiniaczQ
b36b0230e6
Dirty fix for App hanging when windows are invisible on WindowsOS (#14155)
# Objective

- Fixes #14135 

## Solution

- If no windows are visible, app updates will run regardless of redraw
call result.

This a relatively dirty fix, a more robust solution is desired in the
long run:
https://github.com/bevyengine/bevy/issues/1343#issuecomment-770091684

https://discord.com/channels/691052431525675048/1253771396832821270/1258805997011730472
The solution would disconnect rendering from app updates.

## Testing

- `window_settings` now works

## Other platforms

Not a problem on Linux:
https://discord.com/channels/691052431525675048/692572690833473578/1259526650622640160
Not a problem on MacOS:
https://discord.com/channels/691052431525675048/692572690833473578/1259563986148659272
2024-07-14 16:47:28 +00:00
Periwink
17a77445e2
Add error message if states schedule missing (usually because StatesPlugin hasn't been added) (#14160)
# Objective

- Helps improve https://github.com/bevyengine/bevy/issues/14151

## Solution

- At least return an error message from the `Option::unwrap()` call when
we try to access the `StateTransition` schedule

---------

Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2024-07-14 15:56:16 +00:00
Gino Valente
99c9218b56
bevy_reflect: Feature-gate function reflection (#14174)
# Objective

Function reflection requires a lot of macro code generation in the form
of several `all_tuples!` invocations, as well as impls generated in the
`Reflect` derive macro.

Seeing as function reflection is currently a bit more niche, it makes
sense to gate it all behind a feature.

## Solution

Add a `functions` feature to `bevy_reflect`, which can be enabled in
Bevy using the `reflect_functions` feature.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```

That should ensure that everything still works with the feature
disabled.

To test with the feature on, you can run:

```
cargo test --package bevy_reflect --features functions
```

---

## Changelog

- Moved function reflection behind a Cargo feature
(`bevy/reflect_functions` and `bevy_reflect/functions`)
- Add `IntoFunction` export in `bevy_reflect::prelude`

## Internal Migration Guide

> [!important]
> Function reflection was introduced as part of the 0.15 dev cycle. This
migration guide was written for developers relying on `main` during this
cycle, and is not a breaking change coming from 0.14.

Function reflection is now gated behind a feature. To use function
reflection, enable the feature:
- If using `bevy_reflect` directly, enable the `functions` feature
- If using `bevy`, enable the `reflect_functions` feature
2024-07-14 15:55:31 +00:00
Matty
6c9ec88e54
Basic isometry types (#14269)
# Objective

Introduce isometry types for describing relative and absolute position
in mathematical contexts.

## Solution

For the time being, this is a very minimal implementation. This
implements the following faculties for two- and three-dimensional
isometry types:
- Identity transformations
- Creation from translations and/or rotations
- Inverses
- Multiplication (composition) of isometries with each other
- Application of isometries to points (as vectors)
- Conversion of isometries to affine transformations

There is obviously a lot more that could be added, so I erred on the
side of adding things that I knew would be useful, with the idea of
expanding this in the near future as needed.

(I also fixed some random doc problems in `bevy_math`.)

---

## Design

One point of interest here is the matter of if/when to use aligned
types. In the implementation of 3d isometries, I used `Vec3A` rather
than `Vec3` because it has no impact on size/alignment, but I'm still
not sure about that decision (although it is easily changed).

For 2d isometries — which are encoded by four floats — the idea of
shoving them into a single 128-bit buffer (`__m128` or whatever) sounds
kind of enticing, but it's more involved and would involve writing
unsafe code, so I didn't do that for now.

## Future work

- Expand the API to include shortcuts like `inverse_mul` and
`inverse_transform` for efficiency reasons.
- Include more convenience constructors and methods (e.g. `from_xy`,
`from_xyz`).
- Refactor `bevy_math::bounding` to use the isometry types.
- Add conversions to/from isometries for `Transform`/`GlobalTransform`
in `bevy_transform`.
2024-07-14 15:27:42 +00:00
Giacomo Stevanato
d7080369a7
Fix intra-doc links and make CI test them (#14076)
# Objective

- Bevy currently has lot of invalid intra-doc links, let's fix them!
- Also make CI test them, to avoid future regressions.
- Helps with #1983 (but doesn't fix it, as there could still be explicit
links to docs.rs that are broken)

## Solution

- Make `cargo r -p ci -- doc-check` check fail on warnings (could also
be changed to just some specific lints)
- Manually fix all the warnings (note that in some cases it was unclear
to me what the fix should have been, I'll try to highlight them in a
self-review)
2024-07-11 13:08:31 +00:00
Blake Bedford
2414311079
Fixed #14248 and other URL issues (#14276)
# Objective

Fixes #14248 and other URL issues.

## Solution

- Describe the solution used to achieve the objective above.
Removed the random #s in the URL. Led users to the wrong page. For
example, https://bevyengine.org/learn/errors/#b0003 takes users to
https://bevyengine.org/learn/errors/introduction, which is not the right
page. Removing the #s fixes it.

## Testing

- Did you test these changes? If so, how?
I pasted the URL into my address bar and it took me to the right place.

- Are there any parts that need more testing?
No
2024-07-11 12:01:49 +00:00
IQuick 143
291db3e755
fix: Possible NaN due to denormalised quaternions in AABB implementations for round shapes. (#14240)
# Objective

With an unlucky denormalised quaternion (or just a regular very
denormalised quaternion), it's possible to obtain NaN values for AABB's
in shapes which rely on an AABB for a disk.

## Solution

Add an additional `.max(Vec3::ZERO)` clamp to get rid of negative values
arising due to numerical errors.
Fixup some unnecessary calculations and improve variable names in
relevant code, aiming for consistency.

## Discussion

These two (nontrivial) lines of code are repeated at least 5 times,
maybe they could be their own method.
2024-07-10 16:00:19 +00:00
Matty
9af2ef740b
Make bevy_math::common_traits public (#14245)
# Objective

Fixes #14243 

## Solution

`bevy_math::common_traits` is now a public module.
2024-07-09 17:16:47 +00:00
Rob Parrett
3594c4f2f5
Fix doc list indentation (#14225)
# Objective

Fixes #14221

## Solution

Add indentation as suggested.

## Testing

Confirmed that
- This makes Clippy happy with rust beta
- Built docs visually look the same before/after
2024-07-09 01:21:54 +00:00
Bob Gardner
ec1aa48fc6
Created an EventMutator for when you want to mutate an event before reading (#13818)
# Objective

- Often in games you will want to create chains of systems that modify
some event. For example, a chain of damage systems that handle a
DamageEvent and modify the underlying value before the health system
finally consumes the event. Right now this requires either:

* Using a component added to the entity
* Consuming and refiring events

Neither is ideal when really all we want to do is read the events value,
modify it, and write it back.

## Solution

- Create an EventMutator class similar to EventReader but with ResMut<T>
and iterators that return &mut so that events can be mutated.

## Testing

- I replicated all the existing tests for EventReader to make sure
behavior was the same (I believe) and added a number of tests specific
to testing that 1) events can actually be mutated, and that 2)
EventReader sees changes from EventMutator for events it hasn't already
seen.

## Migration Guide

Users currently using `ManualEventReader` should use `EventCursor`
instead. `ManualEventReader` will be removed in Bevy 0.16. Additionally,
`Events::get_reader` has been replaced by `Events::get_cursor`.

Users currently directly accessing the `Events` resource for mutation
should move to `EventMutator` if possible.

---------

Co-authored-by: poopy <gonesbird@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-08 14:53:06 +00:00
github-actions[bot]
8df10d2713
Bump Version after Release (#14219)
Bump version after release
This PR has been auto-generated

Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2024-07-08 12:54:08 +00:00
François Mockers
1ebabcfe4a
fix typo processed_dir (#14220)
# Objective

- fix typo processed_dir
- unblock #14217 

## Solution

- fix typo processed_dir
2024-07-08 11:29:40 +00:00
SpecificProtagonist
7db5dc03f1
Fix state example urls (#14209)
Doc was still pointing to old location of state examples

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-08 01:19:05 +00:00
Torstein Grindvik
70c0223112
bevy_input: allow use without bevy_reflect (#14167)
# Objective

Allow use of `bevy_input` types without needing `bevy_reflect`.

## Solution

Make `bevy_reflect` within `bevy_input` optional. It's compiled in by
default.
Turn on reflect in dependencies as well when this feature is on.

## Testing

- Did you test these changes? If so, how?

I did a `cargo hack -p bevy_input --each-feature build`.

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-07-08 01:09:07 +00:00
Torstein Grindvik
faf3c175b8
bevy_core: make bevy_reflect optional (#14179)
# Objective

Allow use of `bevy_core` types without needing `bevy_reflect`.

## Solution

Make `bevy_reflect` within `bevy_core` optional. It's compiled in by
default.
Turn on reflect in dependencies as well when this feature is on.

## Testing

- Did you test these changes? If so, how?

I did a `cargo hack -p bevy_core--each-feature build`.


Similar PR: https://github.com/bevyengine/bevy/pull/14167

Discord context starts here:
https://discord.com/channels/691052431525675048/768253008416342076/1258814534651482163

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-07-08 01:09:04 +00:00
Litttle_fish
2d34226043
disable gpu preprocessing on android with Adreno 730 GPU and earilier (#14176)
# Objective

Fix #14146 

## Solution

Expansion of #13323 , excluded Adreno 730 and earlier.

## Testing

Tested on android device(Adreno 730) that used to crash
2024-07-08 01:07:03 +00:00
Jan Hohenheim
df80b99e69
Optimize unnecessary normalizations for Transform::local_{xyz} (#14171)
Note that `GlobalTransform` already does it like this for `right`,
`left`, etc. so I didn't have to touch that one
2024-07-08 01:05:09 +00:00
Mike
33ea3b9f7d
use Display for entity id in log_components (#14164)
# Objective

- Cleanup a doubled `Entity` in log components

```
// Before
2024-07-05T19:54:09.082773Z  INFO bevy_ecs::system::commands: Entity Entity { index: 2, generation: 1 }: ["bevy_transform::components::transform::Transform"]

// After
2024-07-05T19:54:09.082773Z  INFO bevy_ecs::system::commands: Entity 2v1: ["bevy_transform::components::transform::Transform"]
```

---------

Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-07-08 01:03:27 +00:00
Mike
91dd7e6f0f
add entity to error message (#14163)
# Objective

- There was a new warning added about having an unstyled child in the ui
hierarchy. Debugging the new error is pretty hard without any info about
which entity is.

## Solution

- Add the entity id to the warning.

```text
// Before
2024-07-05T19:40:59.904014Z  WARN bevy_ui::layout::ui_surface: Unstyled child in a UI entity hierarchy. You are using an entity without UI components as a child of an entity with UI components, results may be unexpected.

//After
2024-07-05T19:40:59.904014Z  WARN bevy_ui::layout::ui_surface: Unstyled child `3v1` in a UI entity hierarchy. You are using an entity without UI components as a child of an entity with UI components, results may be unexpected.
```

## Changelog

- add entity id to ui surface warning
2024-07-08 01:01:47 +00:00
Brandon Reinhart
02028d16b3
impl Reflect + Clone for StateScoped (#14156)
# Objective

- Expand the flexibilty of StateScoped by adding Reflect and Clone
- This lets StateScoped be used in Clone Bundles, for example

```rust
#[derive(Component, Reflect, Clone)]
pub struct StateScoped<S: States>(pub S);
```

Notes:
- States are already Clone.
- Type registration is up to the user, but this is commonly the case
with reflected generic types.

## Testing

- Ran the examples.
2024-07-08 01:00:04 +00:00
Brian Reavis
7273ffcd78
Fix crash when an asset load failure event is processed after asset drop (#14123)
# Objective

This PR fixes a crash that happens when an asset failure event is
processed after the asset has already been dropped.

```
2024-07-03T17:12:16.847178Z ERROR bevy_asset::server: Encountered HTTP status 404 when loading asset
thread 'main' panicked at bevy/crates/bevy_asset/src/server/info.rs:593:18:
```

## Solution

- Update `process_asset_fail` to match the graceful behavior in
`process_asset_load` (it does not assume the state still exists).

---

## Changelog

- Fixed a rare crash that happens when an asset failed event is
processed after the asset has been dropped.
2024-07-08 00:58:55 +00:00
Matty
900f50d77d
Uniform mesh sampling (#14071)
# Objective

Allow random sampling from the surfaces of triangle meshes.

## Solution

This has two parts.

Firstly, rendering meshes can now yield their collections of triangles
through a method `Mesh::triangles`. This has signature
```rust
pub fn triangles(&self) -> Result<Vec<Triangle3d>, MeshTrianglesError> { //... }
```

and fails in a variety of cases — the most obvious of these is that the
mesh must have either the `TriangleList` or `TriangleStrip` topology,
and the others correspond to malformed vertex or triangle-index data.

With that in hand, we have the second piece, which is
`UniformMeshSampler`, which is a `Vec3`-valued
[distribution](https://docs.rs/rand/latest/rand/distributions/trait.Distribution.html)
that samples uniformly from collections of triangles. It caches the
triangles' distribution of areas so that after its initial setup,
sampling is allocation-free. It is constructed via
`UniformMeshSampler::try_new`, which looks like this:
```rust
pub fn try_new<T: Into<Vec<Triangle3d>>>(triangles: T) -> Result<Self, ZeroAreaMeshError> { //... }
```

It fails if the collection of triangles has zero area. 

The sum of these parts means that you can sample random points from a
mesh as follows:
```rust
let triangles = my_mesh.triangles().unwrap();
let mut rng = StdRng::seed_from_u64(8765309);
let distribution = UniformMeshSampler::try_new(triangles).unwrap();
// 10000 random points from the surface of my_mesh:
let sample_points: Vec<Vec3> = distribution.sample_iter(&mut rng).take(10000).collect();
```

## Testing

Tested by instantiating meshes and sampling as demonstrated above.

---

## Changelog

- Added `Mesh::triangles` method to get a collection of triangles from a
mesh.
- Added `UniformMeshSampler` to `bevy_math::sampling`. This is a
distribution which allows random sampling over collections of triangles
(such as those provided through meshes).

---

## Discussion

### Design decisions

The main thing here was making sure to have a good separation between
the parts of this in `bevy_render` and in `bevy_math`. Getting the
triangles from a mesh seems like a reasonable step after adding
`Triangle3d` to `bevy_math`, so I decided to make all of the random
sampling operate at that level, with the fallible conversion to
triangles doing most of the work.

Notably, the sampler could be called something else that reflects that
its input is a collection of triangles, but if/when we add other kinds
of meshes to `bevy_math` (e.g. half-edge meshes), the fact that
`try_new` takes an `impl Into<Vec<Triangle3d>>` means that those meshes
just need to satisfy that trait bound in order to work immediately with
this sampling functionality. In that case, the result would just be
something like this:
```rust
let dist = UniformMeshSampler::try_new(mesh).unwrap();
```
I think this highlights that most of the friction is really just from
extracting data from `Mesh`.

It's maybe worth mentioning also that "collection of triangles"
(`Vec<Triangle3d>`) sits downstream of any other kind of triangle mesh,
since the topology connecting the triangles has been effectively erased,
which makes an `Into<Vec<Triangle3d>>` trait bound seem all the more
natural to me.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-08 00:57:08 +00:00
re0312
db19d2ee47
Optimize ui_layout_system (#14064)
# Objective

- Currently bevy's ui layout system could takes a long time.

## Solution

- cache `default_ui_camera `entity to avoid repetitive lookup


## Performance
cargo run --release --example many_buttons --features bevy/trace_tracy  


![image](https://github.com/bevyengine/bevy/assets/45868716/f8eda0b0-343d-4379-847f-f1636c38e5ec)
2024-07-08 00:48:35 +00:00