Commit graph

5898 commits

Author SHA1 Message Date
Alice Cecile
a2fc9de16d
Add RenderSet::FinalCleanup for World::clear_entities (#14764)
# Objective

`World::clear_entities` is ambiguous with all of the other systems in
`RenderSet::Cleanup` because it access `&mut World`.

## Solution

I've added another system set variant, and made sure that this runs
after everything else.
 
## Testing

The `ambiguity_detection` example

## Migration Guide

`World::clear_entities` is now part of `RenderSet::PostCleanup` rather
than `RenderSet::Cleanup`. Your cleanup systems should likely stay in
`RenderSet::Cleanup`.

## Additional context

Spotted when working on #7386: this was responsible for a large number
of ambiguities.

This should be removed if / when #14449 is merged: there's no need to
call `clear_entities` at all if the rendering world is retained!
2024-08-15 18:48:43 +00:00
Brian Reavis
ac29bdfc86
Fix pass_span drop panic obscuring transparent 2d render errors (#14758)
# Objective

When an item in the transparent 2d phase fails to render, bevy crashes
with _"PassSpanScope::end was never called"_ instead of outputting the
actual error to the console. This PR fixes this so that phase errors are
output to the console. It also makes bevy not crash.

```
thread '<unnamed>' panicked at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/diagnostic/mod.rs:157:9:
PassSpanScope::end was never called
stack backtrace:
   0: rust_begin_unwind
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/panicking.rs:72:14
   2: <bevy_render::diagnostic::PassSpanGuard<R,P> as core::ops::drop::Drop>::drop
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/diagnostic/mod.rs:157:9
   3: core::ptr::drop_in_place<bevy_render::diagnostic::PassSpanGuard<core::option::Option<alloc::sync::Arc<bevy_render::diagnostic::internal::DiagnosticsRecorder>>,bevy_render::render_phase::draw_state::TrackedRenderPass>>
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ptr/mod.rs:514:1
   4: <bevy_core_pipeline::core_2d::main_transparent_pass_2d_node::MainTransparentPass2dNode as bevy_render::render_graph::node::ViewNode>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_core_pipeline/src/core_2d/main_transparent_pass_2d_node.rs:75:9
   5: <bevy_render::render_graph::node::ViewNodeRunner<T> as bevy_render::render_graph::node::Node>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/render_graph/node.rs:406:9
   6: bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:226:21
   7: bevy_render::renderer::graph_runner::RenderGraphRunner::run_graph
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:233:21
   8: bevy_render::renderer::graph_runner::RenderGraphRunner::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/graph_runner.rs:81:9
   9: bevy_render::renderer::render_system
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_render/src/renderer/mod.rs:40:15
  10: core::ops::function::FnMut::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:166:5
  11: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:294:13
  12: <Func as bevy_ecs::system::exclusive_function_system::ExclusiveSystemParamFunction<fn(F0) .> Out>>::run::call_inner
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:229:21
  13: <Func as bevy_ecs::system::exclusive_function_system::ExclusiveSystemParamFunction<fn(F0) .> Out>>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:232:17
  14: <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run::{{closure}}
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:124:23
  15: bevy_ecs::world::World::last_change_tick_scope
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/world/mod.rs:2383:9
  16: <bevy_ecs::system::exclusive_function_system::ExclusiveFunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run
             at /Users/brianreavis/Repositories/project/bevy/crates/bevy_ecs/src/system/exclusive_function_system.rs:116:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

## Solution

Matched the behavior of the other render phases ([like
here](9ca5540b75/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs (L98-L101)))
2024-08-15 18:41:01 +00:00
Giacomo Stevanato
e9e9e5e15d
Add query reborrowing (#14690)
# Objective

- Sometimes some method or function takes an owned `Query`, but we don't
want to give up ours;
- transmuting it technically a solution, but it more costly than
necessary.
- Make query iterators more flexible
- this would allow the equivalent of
`slice::split_first`/`slice::split_first_mut` for query iterators
  - helps with requests like #14685

## Solution

- Add a way for reborrowing queries, that is going from a `&'a mut
Query<'w, 's, D, F>` to a `Query<'a, 's, D, F>`:
- this is safe because the original query will be borrowed while the new
query exists and thus no aliased access can happen;
- it's basically the equivalent of going from `&'short mut &'long mut T`
to `&'short mut T` the the compiler automatically implements.
- Add a way for getting the remainder of a query iterator:
- this is interesting also because the original iterator keeps its
position, which was not possible before;
- this in turn requires a way to reborrow query fetches, which I had to
add to `WorldQuery`.

## Showcase

- You can now reborrow a `Query`, getting an equivalent `Query` with a
shorter lifetime. Previously this was possible for read-only queries by
using `Query::to_readonly`, now it's possible for mutable queries too;
- You can now separately iterate over the remainder of `QueryIter`.

## Migration Guide

- `WorldQuery` now has an additional `shrink_fetch` method you have to
implement if you were implementing `WorldQuery` manually.
2024-08-15 17:38:56 +00:00
callym
9d5837769c
Add Reflect derive to bevy_a11y::Focus (#14763)
Closes #14727
2024-08-15 17:33:20 +00:00
Alice Cecile
dbf0d7071e
Don't ask for ResMut in queue_view_auto_exposure_pipelines (#14762)
This was creating a spurious ambiguity: `PipelineCache` uses interior
mutability.

Spotted as part of #7386.
2024-08-15 17:15:31 +00:00
callym
ad5e8355b5
Remove Component derive for DepthOfFieldMode (#14761)
Fixes #14592
2024-08-15 17:14:49 +00:00
Chris Russell
340c749d16
Remove redundant ArchetypeComponentId lookup in Res and ResMut (#14691)
# Objective

`Res` and `ResMut` perform redundant lookups of the resource storage,
first to initialize the `ArchetypeComponentId` and then to retrieve it.

## Solution

Use the `archetype_component_id` returned from
`initialize_resource_internal` to avoid an extra lookup and `unwrap()`.
2024-08-15 16:12:03 +00:00
robtfm
9ca5540b75
apply finished animations (#14743)
# Objective

fix #14742

## Solution

the issue arises because "finished" animations (where current time >=
last keyframe time) are not applied at all.
when transitioning from a finished animation to another later-indexed
anim, the transition kind-of works because the finished anim is skipped,
then the new anim is applied with a lower weight (weight / total_weight)
when transitioning from a finished animation to another earlier-indexed
anim, the transition is instant as the new anim is applied with 1.0 (as
weight == total_weight for the first applied), then the finished
animation is skipped.

to fix this we can always apply every animation based on the nearest 2
keyframes, and clamp the interpolation between them to [0,1].

pros:
- finished animations can be transitioned out of correctly
- blended animations where some curves have a last-keyframe before the
end of the animation will blend properly
- animations will actually finish on their last keyframe, rather than a
fraction of a render-frame before the end

cons:
- we have to re-apply finished animations every frame whether it's
necessary or not. i can't see a way to avoid this.
2024-08-15 15:10:23 +00:00
TotalKrill
6adf31babf
hooking up observers and clicking for ui node (#14695)
Makes the newly merged picking usable for UI elements. 

currently it both triggers the events, as well as sends them as throught
commands.trigger_targets. We should probably figure out if this is
needed for them all.

# Objective

Hooks up obserers and picking for a very simple example

## Solution

upstreamed the UI picking backend from bevy_mod_picking

## Testing

tested with the new example picking/simple_picking.rs


---

---------

Co-authored-by: Lixou <82600264+DasLixou@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-15 14:43:55 +00:00
Chris Russell
0ea46663b0
Use map_unchanged in reflection instead of creating a Mut manually. (#14692)
# Objective

The code to create `ReflectComponent` and `ReflectResource` instances
manually constructs a `Mut<dyn Reflect>` by copying everything but
`value`. That can be done more concisely and better respecting
encapsulation by calling the `map_unchanged()` method.

## Solution

Use `map_unchanged` instead of creating a `Mut` manually.

---------

Co-authored-by: radiish <cb.setho@gmail.com>
2024-08-15 14:26:57 +00:00
Ben Frankel
d849941dac
Add entity .trigger() methods (#14752)
# Objective

Fix https://github.com/bevyengine/bevy/issues/14233.

## Solution

Add `EntityCommands::trigger` and `EntityWorldMut::trigger`.

## Testing

- Not tested.
2024-08-15 14:16:06 +00:00
eckz
a44278aee6
Making DynamicEnum::is_dynamic() return true (#14732)
# Objective

- Right now `DynamicEnum::is_dynamic()` is returning `false`. I don't
think this was expected, since the rest of `Dynamic*` types return
`true`.

## Solution

- Making `DynamicEnum::is_dynamic()` return true

## Testing

- Added an extra unit test to verify that `.is_dynamic()` returns
`true`.
2024-08-15 14:10:52 +00:00
IceSentry
9de25ad330
Add AlphaMask2d phase (#14724)
# Objective

- Bevy now supports an opaque phase for mesh2d, but it's very common for
2d textures to have a transparent alpha channel.

## Solution

- Add an alpha mask phase identical to the one in 3d. It will do the
alpha masking in the shader before drawing the mesh.
- Uses the BinnedRenderPhase
- Since it's an opaque draw it also correctly writes to depth

## Testing

- Tested the mes2d_alpha_mode example and the bevymark example with
alpha mask mode enabled

---

## Showcase


![image](https://github.com/user-attachments/assets/9e5e4561-d0a7-4aa3-b049-d4b1247d5ed4)

The white logo on the right is rendered with alpha mask enabled.

Running the bevymark example I can get 65fps for 120k mesh2d all using
alpha mask.

## Notes

This is one more step for mesh2d improvements
https://github.com/bevyengine/bevy/issues/13265

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-08-15 14:10:37 +00:00
re0312
3bd039e821
Skip empty archetype/table (#14749)
# Objective

- As sander commneted on discord
[link](https://discord.com/channels/691052431525675048/749335865876021248/1273414144091230228),

![image](https://github.com/user-attachments/assets/62f2b6f3-1aaf-49d9-bafa-bf62b83b10be)





## Performance

![image](https://github.com/user-attachments/assets/11122940-1547-42ae-9576-0e1a93fd9f5f)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
2024-08-15 14:07:20 +00:00
Ben Frankel
6da2305e49
Add Command and co. to prelude (#14751)
# Objective

Make it easier to write and work with custom `Command`s and
`EntityCommand`s. See
https://discord.com/channels/691052431525675048/692572690833473578/1273030340235100214
for (brief) context.

## Solution

Re-export `Command`, `EntityCommand`, and `EntityCommands` in the
`bevy_ecs::prelude`, where `Commands` is already re-exported.
2024-08-15 13:33:32 +00:00
Christian Hughes
7d3068e6c3
Fix world borrow for DeferredWorld::query (#14744)
# Objective

As is, calling
[`DeferredWorld::query`](https://docs.rs/bevy/latest/bevy/ecs/world/struct.DeferredWorld.html#method.query)
requires you to first `reborrow()` the world in order to use it at all.

Simple reproduction:
```rust
fn test<'w>(mut world: DeferredWorld<'w>, mut state: QueryState<(), ()>) {
    let query = world.query(&mut state);
    // let query = world.reborrow().query(&mut state); // << Required
}
```

Error message:
```
error[E0597]: `world` does not live long enough
    |
444 | fn test<'w>(mut world: DeferredWorld<'w>, mut state: QueryState<(), ()>) {
    |         --  --------- binding `world` declared here
    |         |
    |         lifetime `'w` defined here
445 |     let query = world.query(&mut state);
    |                 ^^^^^------------------
    |                 |
    |                 borrowed value does not live long enough
    |                 argument requires that `world` is borrowed for `'w`
446 | }
    |  - `world` dropped here while still borrowed

```

## Solution

Fix the world borrow lifetime on the `query` method, which now correctly
allows the above usage.
2024-08-14 18:59:19 +00:00
eckz
46e8c6b662
Consistency between Wireframe2d and Wireframe (#14720)
# Objective

- Wireframe plugins have inconsistencies between 3D and 2D versions.
This PR addresses the following
  - 2d version uses `Srgba` for colors, 3d version uses `Color`.

  
## Solution

- This PR brings consistency by doing the following change
  - `Wireframe2d` now uses `Color` instead of `Srgba`

## Testing

- `wireframe_2d` and `wireframe` examples were verified and they work as
before.

---

## Migration Guide

- `Wireframe2dConfig`.`default_color` type is now `Color` instead of
`Srgba`. Use `.into()` to convert between them.
- `Wireframe2dColor`.`color` type is now `Color` instead of `Srgba`. Use
`.into()` to convert between them.
2024-08-13 18:57:47 +00:00
Josiah Putman
882973a528
Expose max_mip_dimension and uv_offset in BloomSettings. (#14512)
# Objective

By default, Bevy's bloom effect shows square artifacts on small bright
particles due to a low max mip resolution. This PR makes this
configurable via BloomSettings so users can customize these parameters
instead of having them in private module constants.

## Solution

Expose max_mip_dimension and uv_offset in BloomSettings.

## Testing

I tested these changes by running the Bloom 2D / 3D examples.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-13 15:01:42 +00:00
Gino Valente
6183b56b5d
bevy_reflect: Reflect remote types (#6042)
# Objective

The goal with this PR is to allow the use of types that don't implement
`Reflect` within the reflection API.

Rust's [orphan
rule](https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type)
prevents implementing a trait on an external type when neither type nor
trait are owned by the implementor. This means that if a crate,
`cool_rust_lib`, defines a type, `Foo`, then a user cannot use it with
reflection. What this means is that we have to ignore it most of the
time:

```rust
#[derive(Reflect)]
struct SomeStruct {
  #[reflect(ignore)]
  data: cool_rust_lib::Foo
}
```

Obviously, it's impossible to implement `Reflect` on `Foo`. But does it
*have* to be?

Most of reflection doesn't deal with concrete types— it's almost all
using `dyn Reflect`. And being very metadata-driven, it should
theoretically be possible. I mean,
[`serde`](https://serde.rs/remote-derive.html) does it.

## Solution

> Special thanks to @danielhenrymantilla for their help reviewing this
PR and offering wisdom wrt safety.

Taking a page out of `serde`'s book, this PR adds the ability to easily
use "remote types" with reflection. In this context, a "remote type" is
the external type for which we have no ability to implement `Reflect`.

This adds the `#[reflect_remote(...)]` attribute macro, which is used to
generate "remote type wrappers". All you have to do is define the
wrapper exactly the same as the remote type's definition:

```rust
// Pretend this is our external crate
mod cool_rust_lib {
  #[derive(Default)]
  struct Foo {
    pub value: String
  }
}

#[reflect_remote(cool_rust_lib::Foo)]
struct FooWrapper {
  pub value: String
}
```

> **Note:** All fields in the external type *must* be public. This could
be addressed with a separate getter/setter attribute either in this PR
or in another one.

The macro takes this user-defined item and transforms it into a newtype
wrapper around the external type, marking it as `#[repr(transparent)]`.
The fields/variants defined by the user are simply used to build out the
reflection impls.

Additionally, it generates an implementation of the new trait,
`ReflectRemote`, which helps prevent accidental misuses of this API.

Therefore, the output generated by the macro would look something like:

```rust
#[repr(transparent)]
struct FooWrapper(pub cool_rust_lib::Foo);

impl ReflectRemote for FooWrapper {
  type Remote = cool_rust_lib::Foo;

  // transmutation methods...
}

// reflection impls...
// these will acknowledge and make use of the `value` field
```

Internally, the reflection API will pass around the `FooWrapper` and
[transmute](https://doc.rust-lang.org/std/mem/fn.transmute.html) it
where necessary. All we have to do is then tell `Reflect` to do that. So
rather than ignoring the field, we tell `Reflect` to use our wrapper
using the `#[reflect(remote = ...)]` field attribute:

```rust
#[derive(Reflect)]
struct SomeStruct {
  #[reflect(remote = FooWrapper)]
  data: cool_rust_lib::Foo
}
```

#### Other Macros & Type Data

Because this macro consumes the defined item and generates a new one, we
can't just put our macros anywhere. All macros that should be passed to
the generated struct need to come *below* this macro. For example, to
derive `Default` and register its associated type data:

```rust
//  GOOD
#[reflect_remote(cool_rust_lib::Foo)]
#[derive(Default)]
#[reflect(Default)]
struct FooWrapper {
  pub value: String
}

//  BAD
#[derive(Default)]
#[reflect_remote(cool_rust_lib::Foo)]
#[reflect(Default)]
struct FooWrapper {
  pub value: String
}
```

#### Generics

Generics are forwarded to the generated struct as well. They should also
be defined in the same order:

```rust
#[reflect_remote(RemoteGeneric<'a, T1, T2>)]
struct GenericWrapper<'a, T1, T2> {
  pub foo: &'a T1,
  pub bar: &'a T2,
}
```

> Naming does *not* need to match the original definition's. Only order
matters here.

> Also note that the code above is just a demonstration and doesn't
actually compile since we'd need to enforce certain bounds (e.g. `T1:
Reflect`, `'a: 'static`, etc.)

#### Nesting

And, yes, you can nest remote types:

```rust
#[reflect_remote(RemoteOuter)]
struct OuterWrapper {
  #[reflect(remote = InnerWrapper)]
  pub inner: RemoteInner
}

#[reflect_remote(RemoteInner)]
struct InnerWrapper(usize);
```

#### Assertions

This macro will also generate some compile-time assertions to ensure
that the correct types are used. It's important we catch this early so
users don't have to wait for something to panic. And it also helps keep
our `unsafe` a little safer.

For example, a wrapper definition that does not match its corresponding
remote type will result in an error:

```rust
mod external_crate {
  pub struct TheirStruct(pub u32);
}

#[reflect_remote(external_crate::TheirStruct)]
struct MyStruct(pub String); // ERROR: expected type `u32` but found `String`
```

<details>
<summary>Generated Assertion</summary>

```rust
const _: () = {
  #[allow(non_snake_case)]
  #[allow(unused_variables)]
  #[allow(unused_assignments)]
  #[allow(unreachable_patterns)]
  #[allow(clippy::multiple_bound_locations)]
  fn assert_wrapper_definition_matches_remote_type(
    mut __remote__: external_crate::TheirStruct,
  ) {
    __remote__.0 = (|| -> ::core::option::Option<String> { None })().unwrap();
  }
};
```

</details>

Additionally, using the incorrect type in a `#[reflect(remote = ...)]`
attribute should result in an error:

```rust
mod external_crate {
  pub struct TheirFoo(pub u32);
  pub struct TheirBar(pub i32);
}

#[reflect_remote(external_crate::TheirFoo)]
struct MyFoo(pub u32);

#[reflect_remote(external_crate::TheirBar)]
struct MyBar(pub i32);

#[derive(Reflect)]
struct MyStruct {
  #[reflect(remote = MyBar)] // ERROR: expected type `TheirFoo` but found struct `TheirBar`
  foo: external_crate::TheirFoo
}
```

<details>
<summary>Generated Assertion</summary>

```rust
const _: () = {
    struct RemoteFieldAssertions;
    impl RemoteFieldAssertions {
        #[allow(non_snake_case)]
        #[allow(clippy::multiple_bound_locations)]
        fn assert__foo__is_valid_remote() {
            let _: <MyBar as bevy_reflect::ReflectRemote>::Remote = (|| -> ::core::option::Option<external_crate::TheirFoo> {
              None
            })().unwrap();
        }
    }
};
```

</details>

### Discussion

There are a couple points that I think still need discussion or
validation.

- [x] 1. `Any` shenanigans

~~If we wanted to downcast our remote type from a `dyn Reflect`, we'd
have to first downcast to the wrapper then extract the inner type. This
PR has a [commit](b840db9f74cb6d357f951cb11b150d46bac89ee2) that
addresses this by making all the `Reflect::*any` methods return the
inner type rather than the wrapper type. This allows us to downcast
directly to our remote type.~~

~~However, I'm not sure if this is something we want to do. For
unknowing users, it could be confusing and seemingly inconsistent. Is it
worth keeping? Or should this behavior be removed?~~

I think this should be fine. The remote wrapper is an implementation
detail and users should not need to downcast to the wrapper type. Feel
free to let me know if there are other opinions on this though!

- [x] 2. Implementing `Deref/DerefMut` and `From`

~~We don't currently do this, but should we implement other traits on
the generated transparent struct? We could implement `Deref`/`DerefMut`
to easily access the inner type. And we could implement `From` for
easier conversion between the two types (e.g. `T: Into<Foo>`).~~ As
mentioned in the comments, we probably don't need to do this. Again, the
remote wrapper is an implementation detail, and should generally not be
used directly.
     
- [x] 3. ~~Should we define a getter/setter field attribute in this PR
as well or leave it for a future one?~~ I think this should be saved for
a future PR

- [ ] 4. Any foreseeable issues with this implementation?

#### Alternatives

One alternative to defining our own `ReflectRemote` would be to use
[bytemuck's
`TransparentWrapper`](https://docs.rs/bytemuck/1.13.1/bytemuck/trait.TransparentWrapper.html)
(as suggested by @danielhenrymantilla).

This is definitely a viable option, as `ReflectRemote` is pretty much
the same thing as `TransparentWrapper`. However, the cost would be
bringing in a new crate— though, it is already in use in a few other
sub-crates like bevy_render.

I think we're okay just defining `ReflectRemote` ourselves, but we can
go the bytemuck route if we'd prefer offloading that work to another
crate.

---

## Changelog

* Added the `#[reflect_remote(...)]` attribute macro to allow `Reflect`
to be used on remote types
* Added `ReflectRemote` trait for ensuring proper remote wrapper usage
2024-08-12 19:12:53 +00:00
Tau Gärtli
aab1f8e435
Use #[doc(fake_variadic)] to improve docs readability (#14703)
# Objective

- Fixes #14697

## Solution

This PR modifies the existing `all_tuples!` macro to optionally accept a
`#[doc(fake_variadic)]` attribute in its input. If the attribute is
present, each invocation of the impl macro gets the correct attributes
(i.e. the first impl receives `#[doc(fake_variadic)]` while the other
impls are hidden using `#[doc(hidden)]`.
Impls for the empty tuple (unit type) are left untouched (that's what
the [standard
library](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html#impl-PartialEq-for-())
and
[serde](https://docs.rs/serde/latest/serde/trait.Serialize.html#impl-Serialize-for-())
do).

To work around https://github.com/rust-lang/cargo/issues/8811 and to get
impls on re-exports to correctly show up as variadic, `--cfg docsrs_dep`
is passed when building the docs for the toplevel `bevy` crate.

`#[doc(fake_variadic)]` only works on tuples and fn pointers, so impls
for structs like `AnyOf<(T1, T2, ..., Tn)>` are unchanged.

## Testing

I built the docs locally using `RUSTDOCFLAGS='--cfg docsrs'
RUSTFLAGS='--cfg docsrs_dep' cargo +nightly doc --no-deps --workspace`
and checked the documentation page of a trait both in its original crate
and the re-exported version in `bevy`.
The description should correctly mention for how many tuple items the
trait is implemented.

I added `rustc-args` for docs.rs to the `bevy` crate, I hope there
aren't any other notable crates that re-export `#[doc(fake_variadic)]`
traits.

---

## Showcase

`bevy_ecs::query::QueryData`:
<img width="1015" alt="Screenshot 2024-08-12 at 16 41 28"
src="https://github.com/user-attachments/assets/d40136ed-6731-475f-91a0-9df255cd24e3">

`bevy::ecs::query::QueryData` (re-export):
<img width="1005" alt="Screenshot 2024-08-12 at 16 42 57"
src="https://github.com/user-attachments/assets/71d44cf0-0ab0-48b0-9a51-5ce332594e12">

## Original Description

<details>

Resolves #14697

Submitting as a draft for now, very WIP.

Unfortunately, the docs don't show the variadics nicely when looking at
reexported items.
For example:

`bevy_ecs::bundle::Bundle` correctly shows the variadic impl:

![image](https://github.com/user-attachments/assets/90bf8af1-1d1f-4714-9143-cdd3d0199998)

while `bevy::ecs::bundle::Bundle` (the reexport) shows all the impls
(not good):

![image](https://github.com/user-attachments/assets/439c428e-f712-465b-bec2-481f7bf5870b)

Built using `RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --workspace
--no-deps` (`--no-deps` because of wgpu-core).

Maybe I missed something or this is a limitation in the *totally not
private* `#[doc(fake_variadic)]` thingy. In any case I desperately need
some sleep now :))

</details>
2024-08-12 18:54:33 +00:00
radiish
6ab8767d3b
reflect: implement the unique reflect rfc (#7207)
# Objective

- Implements the [Unique Reflect
RFC](https://github.com/nicopap/rfcs/blob/bevy-reflect-api/rfcs/56-better-reflect.md).

## Solution

- Implements the RFC.
- This implementation differs in some ways from the RFC:
- In the RFC, it was suggested `Reflect: Any` but `PartialReflect:
?Any`. During initial implementation I tried this, but we assume the
`PartialReflect: 'static` in a lot of places and the changes required
crept out of the scope of this PR.
- `PartialReflect::try_into_reflect` originally returned `Option<Box<dyn
Reflect>>` but i changed this to `Result<Box<dyn Reflect>, Box<dyn
PartialReflect>>` since the method takes by value and otherwise there
would be no way to recover the type. `as_full` and `as_full_mut` both
still return `Option<&(mut) dyn Reflect>`.

---

## Changelog

- Added `PartialReflect`.
- `Reflect` is now a subtrait of `PartialReflect`.
- Moved most methods on `Reflect` to the new `PartialReflect`.
- Added `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect}`.
- Added `PartialReflect::{try_as_reflect, try_as_reflect_mut,
try_into_reflect}`.
- Added `<dyn PartialReflect>::{try_downcast_ref, try_downcast_mut,
try_downcast, try_take}` supplementing the methods on `dyn Reflect`.

## Migration Guide

- Most instances of `dyn Reflect` should be changed to `dyn
PartialReflect` which is less restrictive, however trait bounds should
generally stay as `T: Reflect`.
- The new `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect, try_as_reflect, try_as_reflect_mut,
try_into_reflect}` methods as well as `Reflect::{as_reflect,
as_reflect_mut, into_reflect}` will need to be implemented for manual
implementors of `Reflect`.

## Future Work

- This PR is designed to be followed up by another "Unique Reflect Phase
2" that addresses the following points:
- Investigate making serialization revolve around `Reflect` instead of
`PartialReflect`.
- [Remove the `try_*` methods on `dyn PartialReflect` since they are
stop
gaps](https://github.com/bevyengine/bevy/pull/7207#discussion_r1083476050).
- Investigate usages like `ReflectComponent`. In the places they
currently use `PartialReflect`, should they be changed to use `Reflect`?
- Merging this opens the door to lots of reflection features we haven't
been able to implement.
- We could re-add [the `Reflectable`
trait](8e3488c880/crates/bevy_reflect/src/reflect.rs (L337-L342))
and make `FromReflect` a requirement to improve [`FromReflect`
ergonomics](https://github.com/bevyengine/rfcs/pull/59). This is
currently not possible because dynamic types cannot sensibly be
`FromReflect`.
  - Since this is an alternative to #5772, #5781 would be made cleaner.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-08-12 17:01:41 +00:00
callym
7b81ae7e40
Update WGPU to version 22 (#14401)
Upgrading to WGPU 22.

Needs `naga_oil` to upgrade first, I've got a fork that compiles but
fails tests, so until that's fixed and the crate is officially
updated/released this will be blocked.

---------

Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
2024-08-12 16:55:18 +00:00
re0312
032fd486c7
View filter for batch_and_prepare_render_phase (#14713)
# Objective
- batch_and_prepare_render_phase will iterate all living entities ,which
potentially causes a lot of unnecessary look up
- from
https://github.com/bevyengine/bevy/pull/14449#issuecomment-2282876034

## Solution

- added View filter
2024-08-12 16:15:54 +00:00
Matty
61a1530c56
Make bevy_math's libm feature use libm for all f32methods with unspecified precision (#14693)
# Objective

Closes #14474

Previously, the `libm` feature of bevy_math would just pass the same
feature flag down to glam. However, bevy_math itself had many uses of
floating-point arithmetic with unspecified precision. For example,
`f32::sin_cos` and `f32::powi` have unspecified precision, which means
that the exact details of their output are not guaranteed to be stable
across different systems and/or versions of Rust. This means that users
of bevy_math could observe slightly different behavior on different
systems if these methods were used.

The goal of this PR is to make it so that the `libm` feature flag
actually guarantees some degree of determinacy within bevy_math itself
by switching to the libm versions of these functions when the `libm`
feature is enabled.

## Solution

bevy_math now has an internal module `bevy_math::ops`, which re-exports
either the standard versions of the operations or the libm versions
depending on whether the `libm` feature is enabled. For example,
`ops::sin` compiles to `f32::sin` without the `libm` feature and to
`libm::sinf` with it.

This approach has a small shortfall, which is that `f32::powi` (integer
powers of floating point numbers) does not have an equivalent in `libm`.
On the other hand, this method is only used for squaring and cubing
numbers in bevy_math. Accordingly, this deficit is covered by the
introduction of a trait `ops::FloatPow`:
```rust
pub(crate) trait FloatPow {
    fn squared(self) -> Self;
    fn cubed(self) -> Self;
}
```

Next, each current usage of the unspecified-precision methods has been
replaced by its equivalent in `ops`, so that when `libm` is enabled, the
libm version is used instead. The exception, of course, is that
`.powi(2)`/`.powi(3)` have been replaced with `.squared()`/`.cubed()`.

Finally, the usage of the plain `f32` methods with unspecified precision
is now linted out of bevy_math (and hence disallowed in CI). For
example, using `f32::sin` within bevy_math produces a warning that tells
the user to use the `ops::sin` version instead.

## Testing

Ran existing tests. It would be nice to check some benchmarks on NURBS
things once #14677 merges. I'm happy to wait until then if the rest of
this PR is fine.

---

## Discussion

In the future, it might make sense to actually expose `bevy_math::ops`
as public if any downstream Bevy crates want to provide similar
determinacy guarantees. For now, it's all just `pub(crate)`.

This PR also only covers `f32`. If we find ourselves using `f64`
internally in parts of bevy_math for better robustness, we could extend
the module and lints to cover the `f64` versions easily enough.

I don't know how feasible it is, but it would also be nice if we could
standardize the bevy_math tests with the `libm` feature in CI, since
their success is currently platform-dependent (e.g. 8 of them fail on my
machine when run locally).

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-08-12 16:13:36 +00:00
databasedav
c8d30edf1a
add SystemIdMarker Component to enable filtering for SystemId Entitys (#14584)
# Objective

Enables writing queries like `Query<Entity, With<SystemIdMarker>>` to
filter `Entity`s that are, or are not (with `Without`), `SystemId`s.

## Solution

Simple unit struct `SystemIdMarker` added during
`World::register_boxed_system`; `World::remove_system` already despawns
the entity, removing the marker.

## Testing

No tests, but happy to write some with direction.

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-12 16:11:06 +00:00
databasedav
c3111bebb8
document using ObserverState as filter for Observer Entitys (#14669)
# Objective

~~Enables writing queries like `Query<Entity, With<ObserverMarker>>` to
filter `Entity`s that are, or are not (with `Without`), `Observer`s.~~

~~`Observer` version of [similar
PR](https://github.com/bevyengine/bevy/pull/14584) for `SystemId`s.~~

just adding a line to the docs :)

## Solution

~~Simple unit struct `ObserverMarker` added in `Observer`'s `.on_add`
component hook.~~

## Testing

No tests, but happy to write some with direction.
2024-08-12 16:07:03 +00:00
Sarthak Singh
2c4ef37b76
Changed Mesh::attributes* functions to return MeshVertexAttribute (#14394)
# Objective

Fixes #14365 

## Migration Guide

- When using the iterator returned by `Mesh::attributes` or
`Mesh::attributes_mut` the first value of the tuple is not the
`MeshVertexAttribute` instead of `MeshVertexAttributeId`. To access the
`MeshVertexAttributeId` use the `MeshVertexAttribute.id` field.

Signed-off-by: Sarthak Singh <sarthak.singh99@gmail.com>
2024-08-12 15:54:28 +00:00
Eero Lehtinen
47c4e3084a
Add custom cursors (#14284)
# Objective

- Add custom images as cursors
- Fixes #9557 

## Solution

- Change cursor type to accommodate both native and image cursors
- I don't really like this solution because I couldn't use
`Handle<Image>` directly. I would need to import `bevy_assets` and that
causes a circular dependency. Alternatively we could use winit's
`CustomCursor` smart pointers, but that seems hard because the event
loop is needed to create those and is not easily accessable for users.
So now I need to copy around rgba buffers which is sad.
- I use a cache because especially on the web creating cursor images is
really slow
- Sorry to #14196 for yoinking, I just wanted to make a quick solution
for myself and thought that I should probably share it too.

Update:
- Now uses `Handle<Image>`, reads rgba data in `bevy_render` and uses
resources to send the data to `bevy_winit`, where the final cursors are
created.

## Testing

- Added example which works fine at least on Linux Wayland (winit side
has been tested with all platforms).
- I haven't tested if the url cursor works.

## Migration Guide

- `CursorIcon` is no longer a field in `Window`, but a separate
component can be inserted to a window entity. It has been changed to an
enum that can hold custom images in addition to system icons.
- `Cursor` is renamed to `CursorOptions` and `cursor` field of `Window`
is renamed to `cursor_options`
- `CursorIcon` is renamed to `SystemCursorIcon`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-08-12 15:49:03 +00:00
Chris Russell
d4ec80d5d2
Support more kinds of system params in buildable systems. (#14050)
# Objective

Support more kinds of system params in buildable systems, such as a
`ParamSet` or `Vec` containing buildable params or tuples of buildable
params.

## Solution

Replace the `BuildableSystemParam` trait with `SystemParamBuilder` to
make it easier to compose builders. Provide implementations for existing
buildable params, plus tuples, `ParamSet`, and `Vec`.

## Examples

```rust
// ParamSet of tuple: 
let system = (ParamSetBuilder((
    QueryParamBuilder::new(|builder| { builder.with::<B>(); }),
    QueryParamBuilder::new(|builder| { builder.with::<C>(); }),
)),)
    .build_state(&mut world)
    .build_system(|mut params: ParamSet<(Query<&mut A>, Query<&mut A>)>| {
        params.p0().iter().count() + params.p1().iter().count()
    });
	
// ParamSet of Vec:
let system = (ParamSetBuilder(vec![
    QueryParamBuilder::new_box(|builder| { builder.with::<B>(); }),
    QueryParamBuilder::new_box(|builder| { builder.with::<C>(); }),
]),)
    .build_state(&mut world)
    .build_system(|mut params: ParamSet<Vec<Query<&mut A>>>| {
        let mut count = 0;
        params.for_each(|mut query| count += query.iter_mut().count());
        count
    });
```

## Migration Guide

The API for `SystemBuilder` has changed. Instead of constructing a
builder with a world and then adding params, you first create a tuple of
param builders and then supply the world.

```rust
// Before
let system = SystemBuilder::<()>::new(&mut world)
    .local::<u64>()
    .builder::<Local<u64>>(|x| *x = 10)
    .builder::<Query<&A>>(|builder| { builder.with::<B>(); })
    .build(system);

// After
let system = (
    ParamBuilder,
    LocalBuilder(10),
    QueryParamBuilder::new(|builder| { builder.with::<B>(); }),
)
    .build_state(&mut world)
    .build_system(system);
```

## Possible Future Work

Here are a few possible follow-up changes. I coded them up to prove that
this API can support them, but they aren't necessary for this PR.

* chescock/bevy#1
* chescock/bevy#2
* chescock/bevy#3
2024-08-12 15:45:35 +00:00
IceSentry
9d6a4fbc85
Use BinnedRenderPhase for Opaque2d (#13091)
Based on top of #12982  and #13069 

# Objective

- Opaque2d was implemented with SortedRenderPhase but BinnedRenderPhase
should be much faster

## Solution

- Implement BinnedRenderPhase for Opaque2d

## Notes

While testing this PR, before the change I had ~14 fps in bevymark with
100k entities. After this change I get ~71 fps, compared to using
sprites where I only get ~63 fps. This means that after this PR mesh2d
with opaque meshes will be faster than the sprite path. This is not a 1
to 1 comparison since sprites do alpha blending.
2024-08-12 15:38:24 +00:00
Christian Hughes
7f658cabf7
Replace UnsafeCell<World> usage with UnsafeWorldCell in CombinatorSystem (#14706)
# Objective

Replace usage of `UnsafeCell<World>` with our standard `UnsafeWorldCell`
that seemed to have been missed.

## Solution

Do just that.
2024-08-11 13:58:10 +00:00
TotalKrill
3e10fd8534
Mod picking upstream 2 (#14686)
Ci fixed  version of: #14541 

Upstream the remainder of bevy_picking_core and all of
bevy_picking_input.

This work is intentionally nonfunctional and has minimal changes, but
does compile. More work is necessary to replace bevy_eventlistener with
propagating observers.

This work is being coordinated as part of "bevy_mod_picking upstream"
working group. Come say hi on discord!

---------

Co-authored-by: Miles Silberling-Cook <nth.tensor@gmail.com>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
2024-08-09 23:16:37 +00:00
re0312
e490b919df
inline iter_combinations (#14680)
# Objective
- fix #14679 
- bevy's performance highly depends on compiler optimization,inline hot
function could greatly help compiler to optimize our program
2024-08-09 17:44:37 +00:00
Matty
23e87270df
A Curve trait for general interoperation — Part I (#14630)
# Objective

This PR implements part of the [Curve
RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/80-curve-trait.md).
See that document for motivation, objectives, etc.

## Solution

For purposes of reviewability, this PR excludes the entire part of the
RFC related to taking multiple samples, resampling, and interpolation
generally. (This means the entire `cores` submodule is also excluded.)
On the other hand, the entire `Interval` type and all of the functional
`Curve` adaptors are included.

## Testing

Test modules are included and can be run locally (but they are also
included in CI).

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-09 14:19:44 +00:00
re0312
66bf160ec5
Explicit using clone_from (#14670)
# Objective

- after #14502 ,explicit using clone_from should has better performance
because it could reuse the resources to avoid unnecessary allocations.
2024-08-09 14:17:13 +00:00
AFKessen
e14f3cf402
Fix 3D Gizmo webgpu rendering (#14653)
# Objective

The changes made in https://github.com/bevyengine/bevy/pull/12252
introduced an previously fixed bug in webgpu rendering.

## Solution

This fix is based on https://github.com/bevyengine/bevy/pull/8910 and
applies the same vertex buffer layout assignment for the LineGizmo
Pipeline.

## Testing

- Tested the 3D Gizmo example in webgpu and webgl environments

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-09 02:55:56 +00:00
Gino Valente
297c0a3954
bevy_reflect: Add DynamicSet to dynamic_types example (#14665)
# Objective

The `dynamic_types` example was missing a reference to the newly added
`DynamicSet` type.

## Solution

Add `DynamicSet` to the `dynamic_types` example.

For parity with the other dynamic types, I also implemented
`FromIterator<T: Reflect>`, `FromIterator<Box<dyn Reflect>>`, and
`IntoIterator for &DynamicSet`.

## Testing

You can run the example locally:

```
cargo run --example dynamic_types
```
2024-08-08 22:26:18 +00:00
Gino Valente
aeef1c0f20
bevy_reflect: Update internal docs regarding anonymous function type names (#14666)
# Objective

As pointed out by @SkiFire13 on
[Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1270624366119485441),
I was incorrect in #14641 regarding the type name of anonymous
functions. I had stated that they will return something like `fn(i32,
i32) -> i32`, but this is wrong. They actually behave like closures
(despite not technically being closures) and return something more like
`foo::bar::{{closure}}`.

This isn't a major issue because the reasoning behind #14641 still
stands. However, the internal documentation should probably be updated
so future contributors don't believe the lies I left behind.

## Solution

Updated the internal documentation for `create_info` to reflect the
actual type name of an anonymous function.

In that same module, I also added a test for function pointers and
updated all tests to include sanity checks for the `std::any::type_name`
of each category of callable.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```
2024-08-08 22:01:42 +00:00
Gino Valente
3f47273b72
bevy_state: Make reflect module public (#14667)
# Objective

CI is
[failing](https://github.com/bevyengine/bevy/actions/runs/10308658332/job/28536587448)
due to certain methods not being used.

## Solution

Make the `reflect` module public so that these warnings go away and so
that the `pub` items in these modules can be used.

## Testing

CI should pass.
2024-08-08 20:15:38 +00:00
eckz
8c2e70b744
Adding Reflect data types for States and FreelyMutableState. (#14643)
# Objective

- While developing a debug tool I saw the gap where it was not possible
to get all existing states from a World using reflection.
- This PR allows to iterate over all `States` types that exist in a
world, and modify them in case they implement `FreelyMutableState`.
- Two new methods are available on `App` and `SubApp` as helper to
register the data types:
  -  `register_state_reflect` and `register_mutable_state_reflect`

## Solution

- Two new data types are added:
- `ReflectState`: Allows to extract the current value of a state from
the World.
- `ReflectFreelyMutableState`: Allows to set the next state in a world,
similar to call `NextState::set`.
- There is no distinction between `States`, `SubStates` and
`ComputedStates`:
- `States` can register both `ReflectState` and
`ReflectFreelyMutableState`.
- `SubStates` can register both `ReflectState` and
`ReflectFreelyMutableState`.
  -  `ComputedStates` can register only `ReflectState` .

## Testing

- Added tests inside the `bevy_state` crate.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-08-08 00:07:00 +00:00
charlotte
994312ac6d
Fix TAA on camera with viewport (#14582)
# Objective

Closes #14526 

## Solution

The history texture was being created incorrectly with the viewport size
rather than target size. When viewport < target, this meant that the
render attachments would differer in size which causes a wgpu validation
error.

## Testing

Example in linked issue works.
2024-08-07 23:59:38 +00:00
Gino Valente
a0cc636ea3
bevy_reflect: Anonymous function parsing (#14641)
# Objective

### TL;DR

#14098 added the `FunctionRegistry` but had some last minute
complications due to anonymous functions. It ended up going with a
"required name" approach to ensure anonymous functions would always have
a name.

However, this approach isn't ideal for named functions since, by
definition, they will always have a name.

Therefore, this PR aims to modify function reflection such that we can
make function registration easier for named functions, while still
allowing anonymous functions to be registered as well.

### Context

Function registration (#14098) ran into a little problem: anonymous
functions.

Anonymous functions, including function pointers, have very non-unique
type names. For example, the anonymous function `|a: i32, b: i32| a + b`
has the type name of `fn(i32, i32) -> i32`. This obviously means we'd
conflict with another function like `|a: i32, b: i32| a - b`.

The solution that #14098 landed on was to always require a name during
function registration.

The downside with this is that named functions (e.g. `fn add(a: i32, b:
i32) -> i32 { a + b }`) had to redundantly provide a name. Additionally,
manually constructed `DynamicFunction`s also ran into this ergonomics
issue.

I don't entirely know how the function registry will be used, but I have
a strong suspicion that most of its registrations will either be named
functions or manually constructed `DynamicFunction`s, with anonymous
functions only being used here and there for quick prototyping or adding
small functionality.

Why then should the API prioritize the anonymous function use case by
always requiring a name during registration?

#### Telling Functions Apart

Rust doesn't provide a lot of out-of-the-box tools for reflecting
functions. One of the biggest hurdles in attempting to solve the problem
outlined above would be to somehow tell the different kinds of functions
apart.

Let's briefly recap on the categories of functions in Rust:

| Category           | Example                                   |
| ------------------ | ----------------------------------------- |
| Named function     | `fn add(a: i32, b: i32) -> i32 { a + b }` |
| Closure            | `\|a: i32\| a + captured_variable`          |
| Anonymous function | `\|a: i32, b: i32\| a + b`                  |
| Function pointer   | `fn(i32, i32) -> i32`                     |

My first thought was to try and differentiate these categories based on
their size. However, we can see that this doesn't quite work:

| Category           | `size_of` |
| ------------------ | --------- |
| Named function     | 0         |
| Closure            | 0+        |
| Anonymous function | 0         |
| Function pointer   | 8         |

Not only does this not tell anonymous functions from named ones, but it
struggles with pretty much all of them.

My second then was to differentiate based on type name:

| Category           | `type_name`             |
| ------------------ | ----------------------- |
| Named function     | `foo::bar::baz`         |
| Closure            | `foo::bar::{{closure}}` |
| Anonymous function | `fn() -> String`        |
| Function pointer   | `fn() -> String`        |

This is much better. While it can't distinguish between function
pointers and anonymous functions, this doesn't matter too much since we
only care about whether we can _name_ the function.

So why didn't we implement this in #14098?

#### Relying on `type_name`

While this solution was known about while working on #14098, it was left
out from that PR due to it being potentially controversial.

The [docs](https://doc.rust-lang.org/stable/std/any/fn.type_name.html)
for `std::any::type_name` state:

> The returned string must not be considered to be a unique identifier
of a type as multiple types may map to the same type name. Similarly,
there is no guarantee that all parts of a type will appear in the
returned string: for example, lifetime specifiers are currently not
included. In addition, the output may change between versions of the
compiler.

So that's it then? We can't use `type_name`?

Well, this statement isn't so much a rule as it is a guideline. And Bevy
is no stranger to bending the rules to make things work or to improve
ergonomics. Remember that before `TypePath`, Bevy's scene system was
entirely dependent on `type_name`. Not to mention that `type_name` is
being used as a key into both the `TypeRegistry` and the
`FunctionRegistry`.

Bevy's practices aside, can we reliably use `type_name` for this?

My answer would be "yes".

Anonymous functions are anonymous. They have no name. There's nothing
Rust could do to give them a name apart from generating a random string
of characters. But remember that this is a diagnostic tool, it doesn't
make sense to obfuscate the type by randomizing the output. So changing
it to be anything other than what it is now is very unlikely.

The only changes that I could potentially see happening are:

1. Closures replace `{{closure}}` with the name of their variable
2. Lifetimes are included in the output

I don't think the first is likely to happen, but if it does then it
actually works out in our favor: closures are now named!

The second point is probably the likeliest. However, adding lifetimes
doesn't mean we can't still rely on `type_name` to determine whether or
not a function is named. So we should be okay in this case as well.

## Solution

Parse the `type_name` of the function in the `TypedFunction` impl to
determine if the function is named or anonymous.

This once again makes `FunctionInfo::name` optional. For manual
constructions of `DynamicFunction`, `FunctionInfo::named` or
``FunctionInfo::anonymous` can be used.

The `FunctionRegistry` API has also been reworked to account for this
change.

`FunctionRegistry::register` no longer takes a name and instead takes it
from the supplied function, returning a
`FunctionRegistrationError::MissingName` error if the name is `None`.
This also doubles as a replacement for the old
`FunctionRegistry::register_dynamic` method, which has been removed.

To handle anonymous functions, a `FunctionRegistry::register_with_name`
method has been added. This works in the same way
`FunctionRegistry::register` used to work before this PR.

The overwriting methods have been updated in a similar manner, with
modifications to `FunctionRegistry::overwrite_registration`, the removal
of `FunctionRegistry::overwrite_registration_dynamic`, and the addition
of `FunctionRegistry::overwrite_registration_with_name`.

This PR also updates the methods on `App` in a similar way:
`App::register_function` no longer requires a name argument and
`App::register_function_with_name` has been added to handle anonymous
functions (and eventually closures).

## Testing

You can run the tests locally by running:

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

---

## 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.

> [!note]
> This list is not exhaustive. It only contains some of the most
important changes.

`FunctionRegistry::register` no longer requires a name string for named
functions. Anonymous functions, however, need to be registered using
`FunctionRegistry::register_with_name`.

```rust
// BEFORE
registry
  .register(std::any::type_name_of_val(&foo), foo)?
  .register("bar", || println!("Hello world!"));

// AFTER
registry
  .register(foo)?
  .register_with_name("bar", || println!("Hello world!"));
```

`FunctionInfo::name` is now optional. Anonymous functions and closures
will now have their name set to `None` by default. Additionally,
`FunctionInfo::new` has been renamed to `FunctionInfo::named`.
2024-08-07 03:11:08 +00:00
IceSentry
5abc32ceda
Add 2d opaque phase with depth buffer (#13069)
This PR is based on top of #12982

# Objective

- Mesh2d currently only has an alpha blended phase. Most sprites don't
need transparency though.
- For some 2d games it can be useful to have a 2d depth buffer

## Solution

- Add an opaque phase to render Mesh2d that don't need transparency
- This phase currently uses the `SortedRenderPhase` to make it easier to
implement based on the already existing transparent phase. A follow up
PR will switch this to `BinnedRenderPhase`.
- Add a 2d depth buffer
- Use that depth buffer in the transparent phase to make sure that
sprites and transparent mesh2d are displayed correctly

## Testing

I added the mesh2d_transforms example that layers many opaque and
transparent mesh2d to make sure they all get displayed correctly. I also
confirmed it works with sprites by modifying that example locally.

---

## Changelog

- Added `AlphaMode2d`
- Added `Opaque2d` render phase
- Camera2d now have a `ViewDepthTexture` component

## Migration Guide

- `ColorMaterial` now contains `AlphaMode2d`. To keep previous
behaviour, use `AlphaMode::BLEND`. If you know your sprite is opaque,
use `AlphaMode::OPAQUE`

## Follow up PRs

- See tracking issue: #13265

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2024-08-07 00:22:09 +00:00
Periwink
2334638556
Fix access conflicts for resources (#14635)
# Objective

- I made a mistake when fixing the merge conflicts here:
https://github.com/bevyengine/bevy/pull/14579#discussion_r1705377452

It wasn't caught because there's no easy way to trigger access conflicts
with resources without triggering them with components first.
2024-08-06 14:35:41 +00:00
Lubba64
8e20a3e313
Fix gizmos regression (#14633)
# Objective

- Fixes #14142

## Solution

- Make sure a regression test is written on this case that fails for the
current code base but works with the suggested patch linked in the
aforementioned issue. After this is confirmed to be working, apply the
patch.

## Testing

- Run the regression test in both contexts, outputs were as expected.
2024-08-06 14:00:32 +00:00
Zhixing Zhang
5fd0661c15
Making bevy_render an optional dependency for bevy_gizmos (#14448)
# Objective

This PR makes `bevy_render` an optional dependency for `bevy_gizmos`,
thereby allowing `bevy_gizmos` to be used with alternative rendering
backend.

Previously `bevy_gizmos` assumes that one of `bevy_pbr` or `bevy_sprite`
will be enabled. Here we introduced a new feature named `bevy_render`
which disables all rendering-related code paths. An alternative renderer
will then take the `LineGizmo` assets (made public in this PR) and issue
draw calls on their own. A new field `config_ty` was added to
`LineGizmo` to help looking up the related configuration info.

---

## Migration Guide
No user-visible changes needed from the users.
2024-08-06 13:09:10 +00:00
Periwink
e85c072372
Fix soudness issue with Conflicts involving read_all and write_all (#14579)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/14575
- There is a soundness issue because we use `conflicts()` to check for
system ambiguities + soundness issues. However since the current
conflicts is a `Vec<T>`, we cannot express conflicts where there is no
specific `ComponentId` at fault. For example `q1: Query<EntityMut>, q2:
Query<EntityMut>`
There was a TODO to handle the `write_all` case but it was never
resolved


## Solution

- Introduce an `AccessConflict` enum that is either a list of specific
ids that are conflicting or `All` if all component ids are conflicting

## Testing

- Introduced a new unit test to check for the `EntityMut` case

## Migration guide

The `get_conflicts` method of `Access` now returns an `AccessConflict`
enum instead of simply a `Vec` of `ComponentId`s that are causing the
access conflict. This can be useful in cases where there are no
particular `ComponentId`s conflicting, but instead **all** of them are;
for example `fn system(q1: Query<EntityMut>, q2: Query<EntityRef>)`
2024-08-06 10:55:31 +00:00
charlotte
3360b45153
Expose winit's MonitorHandle (#13669)
# Objective

Adds a new `Monitor` component representing a winit `MonitorHandle` that
can be used to spawn new windows and check for system monitor
information.

Closes #12955.

## Solution

For every winit event, check available monitors and spawn them into the
world as components.

## Testing

TODO:
- [x] Test plugging in and unplugging monitor during app runtime
- [x] Test spawning a window on a second monitor by entity id
- [ ] Since this touches winit, test all platforms

---

## Changelog

- Adds a new `Monitor` component that can be queried for information
about available system monitors.

## Migration Guide

- `WindowMode` variants now take a `MonitorSelection`, which can be set
to `MonitorSelection::Primary` to mirror the old behavior.

---------

Co-authored-by: Pascal Hertleif <pascal@technocreatives.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2024-08-06 10:54:37 +00:00
Lubba64
897625c899
Add Reflect to OnReplace (#14620)
# Objective

- Fixes #14337 

## Solution

- Add a `cfg_attr` that derives `Refect` for this type. 

## Testing

- I am going to make sure the tests pass on this PR before requesting
review, If more testing is necessary let me know some good action steps
to take.
2024-08-06 01:31:13 +00:00
Gino Valente
0caeaa2ca9
bevy_reflect: Update serde tests for Set (#14616)
# Objective

Support for reflecting set-like types (e.g. `HashSet`) was added in
#13014. However, we didn't add any serialization tests to verify that
serialization works as expected.

## Solution

Update the serde tests.

## Testing

You can test locally by running:

```
cargo test --package bevy_reflect
```
2024-08-06 01:29:15 +00:00
Robert Walter
70a18d26e2
Glam 0.28 update - adopted (#14613)
Basically it's https://github.com/bevyengine/bevy/pull/13792 with the
bumped versions of `encase` and `hexasphere`.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-06 01:28:00 +00:00
Christian Hughes
039bf90817
Improve documentation on Update vs FixedUpdate schedule dichotomy (#14600)
# Objective

When looking at documentation for the `Update` schedule, its not
entirely obvious that developers should actually be using the
`FixedUpdate` schedule for most of their game logic. We should directly
cross-link between the two, and give examples of which systems to put in
which schedules.

## Solution

Do just that.
2024-08-06 01:26:37 +00:00
Periwink
3a664b052d
Separate component and resource access (#14561)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/13139
- Fixes https://github.com/bevyengine/bevy/issues/7255
- Separates component from resource access so that we can correctly
handles edge cases like the issue above
- Inspired from https://github.com/bevyengine/bevy/pull/14472

## Solution

- Update access to have `component` fields and `resource` fields

## Testing

- Added some unit tests
2024-08-06 01:19:39 +00:00
Lixou
0d0f77a7ab
Add invert_winding for triangle list meshes (#14555)
# Objective

Implements #14547 

## Solution

Add a function `invert_winding` for `Mesh` that inverts the winding for
`LineList`, `LineStrip`, `TriangleList` and `TriangleStrip`.

## Testing

Tests added

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Alix Bott <bott.alix@gmail.com>
2024-08-06 01:16:43 +00:00
barsoosayque
5f2570eb4c
Export glTF skins as a Gltf struct (#14343)
# Objective

- Make skin data of glTF meshes available for users, so it would be
possible to create skinned meshes without spawning a scene.
- I believe it contributes to
https://github.com/bevyengine/bevy/issues/13681 ?

## Solution

- Add a new `GltfSkin`, representing skin data from a glTF file, new
member `skin` to `GltfNode` and both `skins` + `named_skins` to `Gltf`
(a la meshes/nodes).
- Rewrite glTF nodes resolution as an iterator which sorts nodes by
their dependencies (nodes without dependencies first). So when we create
`GltfNodes` with their associated `GltfSkin` while iterating, their
dependencies already have been loaded.
- Make a distinction between `GltfSkin` and
`SkinnedMeshInverseBindposes` in assets: prior to this PR,
`GltfAssetLabel::Skin(n)` was responsible not for a skin, but for one of
skin's components. Now `GltfAssetLabel::InverseBindMatrices(n)` will map
to `SkinnedMeshInverseBindposes`, and `GltfAssetLabel::Skin(n)` will map
to `GltfSkin`.

## Testing

- New test `skin_node` does just that; it tests whether or not
`GltfSkin` was loaded properly.

## Migration Guide

- Change `GltfAssetLabel::Skin(..)` to
`GltfAssetLabel::InverseBindMatrices(..)`.
2024-08-06 01:14:42 +00:00
Gino Valente
df61117850
bevy_reflect: Function registry (#14098)
# Objective

#13152 added support for reflecting functions. Now, we need a way to
register those functions such that they may be accessed anywhere within
the ECS.

## Solution

Added a `FunctionRegistry` type similar to `TypeRegistry`.

This allows a function to be registered and retrieved by name.

```rust
fn foo() -> i32 {
    123
}

let mut registry = FunctionRegistry::default();
registry.register("my_function", foo);

let function = registry.get_mut("my_function").unwrap();
let value = function.call(ArgList::new()).unwrap().unwrap_owned();
assert_eq!(value.downcast_ref::<i32>(), Some(&123));
```

Additionally, I added an `AppFunctionRegistry` resource which wraps a
`FunctionRegistryArc`. Functions can be registered into this resource
using `App::register_function` or by getting a mutable reference to the
resource itself.

### Limitations

#### `Send + Sync`

In order to get this registry to work across threads, it needs to be
`Send + Sync`. This means that `DynamicFunction` needs to be `Send +
Sync`, which means that its internal function also needs to be `Send +
Sync`.

In most cases, this won't be an issue because standard Rust functions
(the type most likely to be registered) are always `Send + Sync`.
Additionally, closures tend to be `Send + Sync` as well, granted they
don't capture any `!Send` or `!Sync` variables.

This PR adds this `Send + Sync` requirement, but as mentioned above, it
hopefully shouldn't be too big of an issue.

#### Closures

Unfortunately, closures can't be registered yet. This will likely be
explored and added in a followup PR.

### Future Work

Besides addressing the limitations listed above, another thing we could
look into is improving the lookup of registered functions. One aspect is
in the performance of hashing strings. The other is in the developer
experience of having to call `std::any::type_name_of_val` to get the
name of their function (assuming they didn't give it a custom name).

## Testing

You can run the tests locally with:

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

---

## Changelog

- Added `FunctionRegistry`
- Added `AppFunctionRegistry` (a `Resource` available from `bevy_ecs`)
- Added `FunctionRegistryArc`
- Added `FunctionRegistrationError`
- Added `reflect_functions` feature to `bevy_ecs` and `bevy_app`
- `FunctionInfo` is no longer `Default`
- `DynamicFunction` now requires its wrapped function be `Send + Sync`

## 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.

`DynamicFunction` (both those created manually and those created with
`IntoFunction`), now require `Send + Sync`. All standard Rust functions
should meet that requirement. Closures, on the other hand, may not if
they capture any `!Send` or `!Sync` variables from its environment.
2024-08-06 01:09:48 +00:00
Periwink
ec4cf024f8
Add a ComponentIndex and update QueryState creation/update to use it (#13460)
# Objective

To implement relations we will need to add a `ComponentIndex`, which is
a map from a Component to the list of archetypes that contain this
component.
One of the reasons is that with fragmenting relations the number of
archetypes will explode, so it will become inefficient to create and
update the query caches by iterating through the list of all archetypes.

In this PR, we introduce the `ComponentIndex`, and we update the
`QueryState` to make use of it:
- if a query has at least 1 required component (i.e. something other
than `()`, `Entity` or `Option<>`, etc.): for each of the required
components we find the list of archetypes that contain it (using the
ComponentIndex). Then, we select the smallest list among these. This
gives a small subset of archetypes to iterate through compared with
iterating through all new archetypes
- if it doesn't, then we keep using the current approach of iterating
through all new archetypes


# Implementation
- This breaks query iteration order, in the sense that we are not
guaranteed anymore to return results in the order in which the
archetypes were created. I think this should be fine because this wasn't
an explicit bevy guarantee so users should not be relying on this. I
updated a bunch of unit tests that were failing because of this.

- I had an issue with the borrow checker because iterating the list of
potential archetypes requires access to `&state.component_access`, which
was conflicting with the calls to
```
  if state.new_archetype_internal(archetype) {
      state.update_archetype_component_access(archetype, access);
  }
```
which need a mutable access to the state.

The solution I chose was to introduce a `QueryStateView` which is a
temporary view into the `QueryState` which enables a "split-borrows"
kind of approach. It is described in detail in this blog post:
https://smallcultfollowing.com/babysteps/blog/2018/11/01/after-nll-interprocedural-conflicts/

# Test

The unit tests pass.

Benchmark results:
```
❯ critcmp main pr
group                                  main                                   pr
-----                                  ----                                   --
iter_fragmented/base                   1.00   342.2±25.45ns        ? ?/sec    1.02   347.5±16.24ns        ? ?/sec
iter_fragmented/foreach                1.04   165.4±11.29ns        ? ?/sec    1.00    159.5±4.27ns        ? ?/sec
iter_fragmented/foreach_wide           1.03      3.3±0.04µs        ? ?/sec    1.00      3.2±0.06µs        ? ?/sec
iter_fragmented/wide                   1.03      3.1±0.06µs        ? ?/sec    1.00      3.0±0.08µs        ? ?/sec
iter_fragmented_sparse/base            1.00      6.5±0.14ns        ? ?/sec    1.02      6.6±0.08ns        ? ?/sec
iter_fragmented_sparse/foreach         1.00      6.3±0.08ns        ? ?/sec    1.04      6.6±0.08ns        ? ?/sec
iter_fragmented_sparse/foreach_wide    1.00     43.8±0.15ns        ? ?/sec    1.02     44.6±0.53ns        ? ?/sec
iter_fragmented_sparse/wide            1.00     29.8±0.44ns        ? ?/sec    1.00     29.8±0.26ns        ? ?/sec
iter_simple/base                       1.00      8.2±0.10µs        ? ?/sec    1.00      8.2±0.09µs        ? ?/sec
iter_simple/foreach                    1.00      3.8±0.02µs        ? ?/sec    1.02      3.9±0.03µs        ? ?/sec
iter_simple/foreach_sparse_set         1.00     19.0±0.26µs        ? ?/sec    1.01     19.3±0.16µs        ? ?/sec
iter_simple/foreach_wide               1.00     17.8±0.24µs        ? ?/sec    1.00     17.9±0.31µs        ? ?/sec
iter_simple/foreach_wide_sparse_set    1.06     95.6±6.23µs        ? ?/sec    1.00     90.6±0.59µs        ? ?/sec
iter_simple/sparse_set                 1.00     19.3±1.63µs        ? ?/sec    1.01     19.5±0.29µs        ? ?/sec
iter_simple/system                     1.00      8.1±0.10µs        ? ?/sec    1.00      8.1±0.09µs        ? ?/sec
iter_simple/wide                       1.05     37.7±2.53µs        ? ?/sec    1.00     35.8±0.57µs        ? ?/sec
iter_simple/wide_sparse_set            1.00     95.7±1.62µs        ? ?/sec    1.00     95.9±0.76µs        ? ?/sec
par_iter_simple/with_0_fragment        1.04     35.0±2.51µs        ? ?/sec    1.00     33.7±0.49µs        ? ?/sec
par_iter_simple/with_1000_fragment     1.00     50.4±2.52µs        ? ?/sec    1.01     51.0±3.84µs        ? ?/sec
par_iter_simple/with_100_fragment      1.02     40.3±2.23µs        ? ?/sec    1.00     39.5±1.32µs        ? ?/sec
par_iter_simple/with_10_fragment       1.14     38.8±7.79µs        ? ?/sec    1.00     34.0±0.78µs        ? ?/sec
```
2024-08-06 00:57:15 +00:00
Giacomo Stevanato
68ec6f4f50
Make QueryState::transmute&co validate the world of the &Components used (#14631)
# Objective

- Fix #14629

## Solution

- Make `QueryState::transmute`, `QueryState::transmute_filtered`,
`QueryState::join` and `QueryState::join_filtered` take a `impl
Into<UnsafeWorldCell>` instead of a `&Components` and validate their
`WorldId`

## Migration Guide

- `QueryState::transmute`, `QueryState::transmute_filtered`,
`QueryState::join` and `QueryState::join_filtered` now take a `impl
Into<UnsafeWorldCell>` instead of a `&Components`

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-08-05 22:39:31 +00:00
Rob Parrett
e164e5a873
Add link to with_children in with_child doc (#14604)
# Objective

Discourage users from using `with_child` for spawning multiple children.

## Solution

Add link to `with_children` in docs for `with_child`.
2024-08-04 13:36:52 +00:00
Ben Frankel
9b254aab1e
Explicitly order CameraUpdateSystem before UiSystem::Prepare (#14609)
# Objective

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

May also fix https://github.com/bevyengine/bevy/issues/14255, needs
verification.

## Solution

Explicitly order `CameraUpdateSystem` before `UiSystem::Prepare`, so
that when the window resizes, `camera_system` will update the `Camera`'s
viewport size before `ui_layout_system` also reacts to the window resize
and tries to read the new `Camera` viewport size to set UI node sizes
accordingly.

## Testing

I tested that explicitly ordering `CameraUpdateSystem` _after_ triggers
the buggy behavior, and explicitly ordering it _before_ does not trigger
the buggy behavior or crash the app (which also demonstrates that the
system sets are ambiguous).

---

## Migration Guide

`CameraUpdateSystem` is now explicitly ordered before
`UiSystem::Prepare` instead of being ambiguous with it.
2024-08-04 13:34:51 +00:00
radiish
4b20d822e9
update hashbrown to 0.14.2 (#14603)
# Objective

- We previously had a dependency in `bevy_utils`, `hashbrown = 0.14`,
and used the `hashbrown::hash_table` api, which was introduced in
`0.14.2`.

## Solution

- Bump `hashbrown` to `0.14.2`

## Testing

- Now compiles with the minimum declared `hashbrown` version.

---
2024-08-04 13:23:28 +00:00
re0312
8235daaea0
Opportunistically use dense iteration for archetypal iteration (#14049)
# Objective
- currently, bevy employs sparse iteration if any of the target
components in the query are stored in a sparse set. it may lead to
increased cache misses in some cases, potentially impacting performance.
- partial fixes #12381 

## Solution

- use dense iteration when an archetype and its table have the same
entity count.
- to avoid introducing complicate unsafe noise, this pr only implement
for `for_each ` style iteration.
- added a benchmark to test performance for hybrid iteration.


## Performance


![image](https://github.com/bevyengine/bevy/assets/45868716/5cce13cf-6ff2-4861-9576-e75edc63bd46)

nearly 2x win in specific scenarios, and no performance degradation in
other test cases.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Christian Hughes <9044780+ItsDoot@users.noreply.github.com>
2024-08-02 21:18:15 +00:00
Lixou
7c80ae7313
Add depth_ndc_to_view_z for cpu-side (#14590)
# Objective

I want to get the visual depth (after view proj matrix stuff) of the
object beneath my cursor.
Even when having a write-back of the depth texture, you would still need
to convert the NDC depth to a logical value.

## Solution

This is done on shader-side by [this
function](e6261b0f5f/crates/bevy_pbr/src/render/view_transformations.wgsl (L151)),
which I ported over to the cpu-side.

I also added `world_to_viewport_with_depth` to get a `Vec3` instead of
`Vec2`.

---

If anyone knows a smarter solution to get the visual depth instead of
going `screen -> viewport ray -> screen`, please let me know :>
2024-08-02 15:37:29 +00:00
Rob Parrett
5b29402cc8
Add with_child to simplify spawning when there will only be one child (#14594)
# Objective

This idea came up in the context of a hypothetical "text sections as
entities" where text sections are children of a text bundle.

```rust
commands
    .spawn(TextBundle::default())
    .with_children(|parent} {
        parent.spawn(TextSection::from("Hello"));
    });
```

This is a bit cumbersome (but powerful and probably the way things are
headed). [`bsn!`](https://github.com/bevyengine/bevy/discussions/14437)
will eventually make this nicer, but in the mean time, this might
improve ergonomics for the common case where there is only one
`TextSection`.

## Solution

Add a `with_child` method to the `BuildChildren` trait that spawns a
single bundle and adds it as a child to the entity.

```rust
commands
    .spawn(TextBundle::default())
    .with_child(TextSection::from("Hello"));
```

## Testing

I added some tests, and modified the `button` example to use the new
method.

If any potential co-authors want to improve the tests, that would be
great.

## Alternatives

- Some sort of macro. See
https://github.com/tigregalis/bevy_spans_ent/blob/main/examples/macro.rs#L20.
I don't love this, personally, and it would probably be obsoleted by
`bsn!`.
- Wait for `bsn!`
- Add `with_children_batch` that takes an `Into<Iterator>` of bundles.
  ```rust
  with_children_batch(vec![TextSection::from("Hello")])
  ```
This is maybe not as useful as it sounds -- it only works with
homogeneous bundles, so no marker components or styles.
- If this doesn't seem valuable, doing nothing is cool with me.
2024-08-02 15:37:15 +00:00
Lixou
4c2cef2223
Reflection for DepthOfFieldSettings (#14588)
# Objective

I can't mutate the dof settings via tools like `bevy_inspector_egui`

## Solution

Add `Reflect` for `DepthOfFieldSettings` and `DepthOfFieldMode`
2024-08-02 15:36:39 +00:00
Joona Aalto
e6261b0f5f
Add Dir2::from_xy_unchecked and Dir3::from_xyz_unchecked (#14587)
# Objective

Bevy's direction types have `new` and `new_unchecked` constructors, but
no unchecked variant for the `Dir2::from_xy` and `Dir3::from_xyz`
methods.

For me, this has several times lead to constructing directions like
this, in cases where the components of the direction are already known
to be normalized:

```rust
let normal = Dir2::new_unchecked(Vec2::new(-ray.direction.x.signum(), 0.0));
```

```rust
segment.direction =
    Dir2::new_unchecked(Vec2::new(-segment.direction.x, segment.direction.y));
```

For consistency and ergonomics, it would be nice to have unchecked
variants of `Dir2::from_xy` and `Dir3::from_xyz`:

```rust
let normal = Dir2::from_xy_unchecked(-ray.direction.x.signum(), 0.0);
```

```rust
segment.direction = Dir2::from_xy_unchecked(-segment.direction.x, segment.direction.y);
```

## Solution

Add `Dir2::from_xy_unchecked` and `Dir3::from_xyz_unchecked`.
2024-08-02 13:10:13 +00:00
James O'Brien
b98d15f278
Skip batching for phase items from other pipelines (#14296)
# Objective

- Fix #14295

## Solution

- Early out when `GFBD::get_index_and_compare_data` returns None.

## Testing

- Tested on a selection of examples including `many_foxes` and
`3d_shapes`.
- Resolved the original issue in `bevy_vector_shapes`.
2024-08-02 00:15:42 +00:00
JJJimbo1
56c9d4489b
fix asymmetrical 9-slicing (#14148)
# Objective

Fixes #14147.

## Solution

Modify the slicing checks and algorithm to fully allow asymmetrical
textures to work.
Some opinionated code cleanup.

## Testing

Tested using the ui_texture_slice example and a custom asymmetrical
texture.

Before:

![asymmetrical_texture_slice_before](https://github.com/bevyengine/bevy/assets/88861660/00dafce1-904a-41ac-b5d9-faaf087b0681)

After:

![asymmetrical_texture_slice_after](https://github.com/bevyengine/bevy/assets/88861660/f3d742f3-6157-4d35-b383-aee4b8f6e7d0)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-08-01 20:03:23 +00:00
Brian Reavis
4c4a6c4506
Don’t prepare lights (and shadow map textures) for 2D cameras (#14574)
# Objective

When running the Metal debugger I noticed that 2D cameras have shadow
map textures from `bevy_pbr` built for them. For a 2560x1440 2D camera,
this PR saves about 40mb of texture memory.


![image](https://github.com/user-attachments/assets/925e9392-2721-41bb-83e9-25c84fd563cd)


![image](https://github.com/user-attachments/assets/0cc3c0a9-cbf7-431c-b444-952c28d4e9d0)


## Solution

- Added `With<Camera3d>` filter to the appropriate view queries.

## Testing

- This is a trivial fix (the examples still work)
2024-08-01 19:29:18 +00:00
Brezak
0c7df881e7
Properly handle repeated window close requests (#14573)
# Objective

Spamming the window close button on window may trigger a panic.

```
thread 'main' panicked at <Bevy repo>\crates\bevy_ecs\src\system\commands\mod.rs:1320:13:
error[B0003]: Could not insert a bundle (of type `bevy_window:🪟:ClosingWindow`) for entity 0v1#4294967296 because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `bevy_window::system::close_when_requested`!
2024-08-01T15:00:29.742612Z  WARN bevy_ecs::world::command_queue: CommandQueue has un-applied commands being dropped. Did you forget to call SystemState::apply?
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\bevy.exe` (exit code: 101)
```

## Solution

Don't panic when trying to insert the `ClosingWindow` component into a
entity.

## Testing

Found and tested on windows. I haven't checked if this bug happens on
linux or macos.
For testing I ran this code:

```rust
use std::{thread, time::Duration};

use bevy::prelude::*;

fn lag() {
    thread::sleep(Duration::from_millis(300));
}

fn main() -> AppExit {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, lag)
        .run()
}
```

Then spammed the window close button. The panic no longer occurs.
2024-08-01 16:15:28 +00:00
SpecificProtagonist
0685d2da4d
B0003: Print caller (#14556)
# Objective

B0003 indicates that you tried to act upon a nonexistant entity, but
does not mention where the error occured:
```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

## Solution

Include caller location:

```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: src/main.rs:18:11: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

Open question: What should the exact message format be?

## Testing

None, this doesn't change any logic.
2024-08-01 00:14:48 +00:00
Guillaume Gomez
0e86675177
Add freebsd support for sysinfo (#14553)
I'm not sure if bevy works on FreeBSD or not. But in case it does,
better allow `sysinfo` to be used as well if users want.
2024-07-31 21:41:40 +00:00
Jan Hohenheim
6f7c554daa
Fix common capitalization errors in documentation (#14562)
WASM -> Wasm
MacOS -> macOS

Nothing important, just something that annoyed me for a while :)
2024-07-31 21:16:05 +00:00
Lixou
20264d0810
Make AnimationPlayer::start and ::play work accordingly to documentation (#14546)
# Objective

While scrolling through the animation crate, I was confused by the docs
and code for the two methods. One does nothing for resetting an
animation, the other just resets the weights for whatever reason.

## Solution

Made the functions work accordingly to their documentation.
`start` now replays the animation.
And `play` doesn't reset the weight anymore. I have no clue why it
should. `play` is there to don't do anything to an already existing
animation.

## Testing

I tested the current 0.14 code with bevy playground in the Animated Fox
exampled and changed it such that on pressing space, either `play` or
`start` would be called. Neither changed anything.
I then inlined the function for start there and it restarted the
animation, so it should work.

---

## Migration Guide

`AnimationPlayer::start` now correspondingly to its docs restarts a
running animation.
`AnimationPlayer::play` doesn't reset the weight anymore.
2024-07-31 14:07:53 +00:00
Guillaume Gomez
68dc7a8b8b
Update sysinfo version to 0.31.0 (#14551)
This release will likely remove a few dependencies in bevy since you
only need the `system` feature.
2024-07-31 14:06:52 +00:00
Rich Churcher
e579622a65
time_system is ambiguous_with event_update_system (#14544)
# Objective

Resolve possible ambiguity detection panic between `time_system` and
`event_update_system`.

Fixes #14524

## Solution

Sets `.ambiguous_with(event_update_system)` on `time_system`. This is
slightly new territory for me, so please treat with scepticism.

## Testing

As described in the issue, added
```
        .configure_schedules(ScheduleBuildSettings {
            ambiguity_detection: LogLevel::Error,
            ..default()
        })
```
to the `time` example and ran it.
2024-07-31 12:13:17 +00:00
Zeenobit
023e0e5bde
Fix Entity Debug Format (#14539)
# Objective

Fixes #12139

## Solution

See this comment on original issue for my proposal:
https://github.com/bevyengine/bevy/issues/12139#issuecomment-2241915791

This PR is an implementation of this proposal.

I modified the implementation of `fmt::Debug` to instead display
`0v0#12345` to ensure entity index, generation, and raw bits are all
present in the output for debug purposes while still keeping log message
concise.

`fmt::Display` remains as is (`0v0`) to offer an even shorter output.

To me, this is the most non-intrusive fix for this issue.

## Testing

Add `fn entity_debug` test

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-31 01:36:41 +00:00
BD103
399219a2c7
Fix rust beta lints (#14537)
# Objective

- Fixes #14517.

## Solution

- Replace two instances of `map()` with `inspect()`.
- `#[allow(dead_code)]` on `Bundle` derive macro tests.

## Testing

You need to install the beta toolchain, since these lints are not stable
yet.

```bash
cargo +beta clippy --workspace
cargo +beta test --workspace
```
2024-07-31 01:27:26 +00:00
Robin KAY
3d1c9ca87f
Change SceneInstanceReady to trigger an observer. (#13859)
# Objective

The `SceneInstanceReady` event would be more ergonomic (and potentially
efficient) if it could be delivered to listeners attached to the scene
entities becoming ready rather than into a World-global queue.

This is an evolution of @Shatur's work in #9313.

## Solution

The scene spawner is changed to trigger observers on the scene entity
when it is ready rather than enqueue an event with `EventWriter`.

This addresses the two outstanding feature requests mentioned on #2218,
that i) the events should be "scoped" in some way and ii) that the
`InstanceId` should be included in the event.

## Testing

Modified the `scene_spawner::tests::event` test to use the new
mechanism.

---

## Changelog

- Changed `SceneInstanceReady` to trigger an entity observer rather than
be written to an event queue.
- Changed `SceneInstanceReady` to carry the `InstanceId` of the scene.

## Migration Guide

If you have a system which read `SceneInstanceReady` events:

> ```fn ready_system(ready_events: EventReader<'_, '_,
SceneInstanceReady>) {```

It must be rewritten as an observer:

> ```commands.observe(|trigger: Trigger<SceneInstanceReady>| {```

Or, if you were expecting the event in relation to a specific entity or
entities, as an entity observer:

> ```commands.entity(entity).observe(|trigger:
Trigger<SceneInstanceReady>| {```
2024-07-30 21:23:48 +00:00
s-puig
ba09f35474
Fix UI texture atlas with offset (#13620)
# Objective

- Fixes #11219 

## Solution

- Scaling calculations use texture dimensions instead of layout
dimensions.

## Testing

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

All UI examples look fine.

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?

Example in #11219

## Migration Guide

```diff
let ui_node = ExtractedUiNode {
                    stack_index,
                    transform,
                    color,
                    rect,
                    image,
-                   atlas_size: Some(atlas_size * scale_factor),      
+                   atlas_scaling: Some(Vec2::splat(scale_factor)),
                    clip,
                    flip_x,
                    flip_y,
                    camera_entity,
                    border,
                    border_radius,
                    node_type,
                },
```

```diff
let computed_slices = ComputedTextureSlices {
    slices,
-    image_size,
}
```
2024-07-30 15:31:58 +00:00
BD103
d722fef23d
Remove deprecated bevy_dynamic_plugin (#14534)
# Objective

- Dynamic plugins were deprecated in #13080 due to being unsound. The
plan was to deprecate them in 0.14 and remove them in 0.15.

## Solution

- Remove all dynamic plugin functionality.
- Update documentation to reflect this change.

---

## Migration Guide

Dynamic plugins were deprecated in 0.14 for being unsound, and they have
now been fully removed. Please consider using the alternatives listed in
the `bevy_dynamic_plugin` crate documentation, or worst-case scenario
you may copy the code from 0.14.
2024-07-30 15:31:08 +00:00
Aevyrie
9575b20d31
Track source location in change detection (#14034)
# Objective

- Make it possible to know *what* changed your component or resource.
- Common need when debugging, when you want to know the last code
location that mutated a value in the ECS.
- This feature would be very useful for the editor alongside system
stepping.

## Solution

- Adds the caller location to column data.
- Mutations now `track_caller` all the way up to the public API.
- Commands that invoke these functions immediately call
`Location::caller`, and pass this into the functions, instead of the
functions themselves attempting to get the caller. This would not work
for commands which are deferred, as the commands are executed by the
scheduler, not the user's code.

## Testing

- The `component_change_detection` example now shows where the component
was mutated:

```
2024-07-28T06:57:48.946022Z  INFO component_change_detection: Entity { index: 1, generation: 1 }: New value: MyComponent(0.0)
2024-07-28T06:57:49.004371Z  INFO component_change_detection: Entity { index: 1, generation: 1 }: New value: MyComponent(1.0)
2024-07-28T06:57:49.012738Z  WARN component_change_detection: Change detected!
        -> value: Ref(MyComponent(1.0))
        -> added: false
        -> changed: true
        -> changed by: examples/ecs/component_change_detection.rs:36:23
```

- It's also possible to inspect change location from a debugger:
<img width="608" alt="image"
src="https://github.com/user-attachments/assets/c90ecc7a-0462-457a-80ae-42e7f5d346b4">


---

## Changelog

- Added source locations to ECS change detection behind the
`track_change_detection` flag.

## Migration Guide

- Added `changed_by` field to many internal ECS functions used with
change detection when the `track_change_detection` feature flag is
enabled. Use Location::caller() to provide the source of the function
call.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-30 12:02:38 +00:00
Rostyslav Toch
455c1bfbe8
Optimize cloning for Access-related structs (#14502)
# Objective

Optimize the cloning process for Access-related structs in the ECS
system, specifically targeting the `clone_from` method.

Previously, profiling showed that 1% of CPU time was spent in
`FixedBitSet`'s `drop_in_place`, due to the default `clone_from`
implementation:

```rust
fn clone_from(&mut self, source: &Self) {
    *self = source.clone()
}
```

This implementation causes unnecessary allocations and deallocations.
However, [FixedBitSet provides a more optimized clone_from
method](https://github.com/petgraph/fixedbitset/blob/master/src/lib.rs#L1445-L1465)
that avoids these allocations and utilizes SIMD instructions for better
performance.

This PR aims to leverage the optimized clone_from method of FixedBitSet
and implement custom clone_from methods for Access-related structs to
take full advantage of this optimization. By doing so, we expect to
significantly reduce CPU time spent on cloning operations and improve
overall system performance.



![image](https://github.com/user-attachments/assets/7526a5c5-c75b-4a9a-b8d2-891f64fd553b)


## Solution

- Implemented custom `clone` and `clone_from` methods for `Access`,
`FilteredAccess`, `AccessFilters`, and `FilteredAccessSet` structs.
- Removed `#[derive(Clone)]` and manually implemented `Clone` trait to
use optimized `clone_from` method from `FixedBitSet`.
- Added unit tests for cloning and `clone_from` methods to ensure
correctness.

## Testing

- Conducted performance testing comparing the original and optimized
versions.
- Measured CPU time consumption for the `clone_from` method:
  - Original version: 1.34% of CPU time
  - Optimized version: 0.338% of CPU time
- Compared FPS before and after the changes (results may vary depending
on the run):

Before optimization:
```
2024-07-28T12:49:11.864019Z  INFO bevy diagnostic: fps        :  213.489463   (avg 214.502488)
2024-07-28T12:49:11.864037Z  INFO bevy diagnostic: frame_time :    4.704746ms (avg 4.682251ms)
2024-07-28T12:49:11.864042Z  INFO bevy diagnostic: frame_count: 7947.000000   (avg 7887.500000)
```


![image](https://github.com/user-attachments/assets/7865a365-0569-4b46-814a-964779d90973)

After optimization:
```
2024-07-28T12:29:42.705738Z  INFO bevy diagnostic: fps        :  220.273721   (avg 220.912227)
2024-07-28T12:29:42.705762Z  INFO bevy diagnostic: frame_time :    4.559127ms (avg 4.544905ms)
2024-07-28T12:29:42.705769Z  INFO bevy diagnostic: frame_count: 7596.000000   (avg 7536.500000)
```


![image](https://github.com/user-attachments/assets/8dd96908-86d0-4850-8e29-f80176a005d6)

---

Reviewers can test these changes by running `cargo run --release
--example ssr`
2024-07-29 23:48:21 +00:00
Tamás Kiss
396153ae59
fix issue with phantom ui node children (#14490)
# Objective

The `ui_layout_system` relies on change detection to sync parent-child
relation to taffy. The children need to by synced before node removal to
avoid trying to set deleted nodes as children (due to how the different
queries collect entities). This however may leave nodes that were
removed set as children to other nodes in special cases.

Fixes #11385

## Solution

The solution is simply to re-sync the changed children after the nodes
are removed.

## Testing

Tested with `sickle_ui` where docking zone highlights would end up
glitched when docking was done in a certain manner:
- run the `docking_zone_splits` example
- pop out a tab from the top
- dock the floating panel in the center right
- grab another tab and try to hover the original static docking zone:
the highlight is semi-stuck
- (NOTE: sometimes it worked even without the fix due to scheduling
order not producing the bugged query results)

After the fix, the issue is no longer present.

NOTE: The performance impact should be minimal, as the child sync relies
on change detection. The change detection was also the reason the parent
nodes remained "stuck" with the phantom children if no other update were
done to them.
2024-07-29 23:42:56 +00:00
Rich Churcher
23cb0f9c54
Add note on StatesPlugin requirement for state code (#14489)
# Objective

Clarify that `StatesPlugin` is a prerequisite for state code.

Closes #14329 .

Edit: am I missing a way to link `DefaultPlugins` correctly other than
using the URL? I guess I expected to be able to refer to it with
`bevy::prelude::DefaultPlugins` or some such 🤔
2024-07-29 23:41:14 +00:00
Matty
601cf6b9e5
Refactor Bounded2d/Bounded3d to use isometries (#14485)
# Objective

Previously, this area of bevy_math used raw translation and rotations to
encode isometries, which did not exist earlier. The goal of this PR is
to make the codebase of bevy_math more harmonious by using actual
isometries (`Isometry2d`/`Isometry3d`) in these places instead — this
will hopefully make the interfaces more digestible for end-users, in
addition to facilitating conversions.

For instance, together with the addition of #14478, this means that a
bounding box for a collider with an isometric `Transform` can be
computed as
```rust
collider.aabb_3d(collider_transform.to_isometry())
```
instead of using manual destructuring. 

## Solution

- The traits `Bounded2d` and `Bounded3d` now use `Isometry2d` and
`Isometry3d` (respectively) instead of `translation` and `rotation`
parameters; e.g.:
  ```rust
  /// A trait with methods that return 3D bounding volumes for a shape.
  pub trait Bounded3d {
/// Get an axis-aligned bounding box for the shape translated and
rotated by the given isometry.
      fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d;
/// Get a bounding sphere for the shape translated and rotated by the
given isometry.
      fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere;
  }
  ```
- Similarly, the `from_point_cloud` constructors for axis-aligned
bounding boxes and bounding circles/spheres now take isometries instead
of separate `translation` and `rotation`; e.g.:
  ```rust
/// Computes the smallest [`Aabb3d`] containing the given set of points,
/// transformed by the rotation and translation of the given isometry.
    ///
    /// # Panics
    ///
    /// Panics if the given set of points is empty.
    #[inline(always)]
    pub fn from_point_cloud(
        isometry: Isometry3d,
        points: impl Iterator<Item = impl Into<Vec3A>>,
    ) -> Aabb3d { //... }
  ```

This has a couple additional results:
1. The end-user no longer interacts directly with `Into<Vec3A>` or
`Into<Rot2>` parameters; these conversions all happen earlier now,
inside the isometry types.
2. Similarly, almost all intermediate `Vec3 -> Vec3A` conversions have
been eliminated from the `Bounded3d` implementations for primitives.
This probably has some performance benefit, but I have not measured it
as of now.

## Testing

Existing unit tests help ensure that nothing has been broken in the
refactor.

---

## Migration Guide

The `Bounded2d` and `Bounded3d` traits now take `Isometry2d` and
`Isometry3d` parameters (respectively) instead of separate translation
and rotation arguments. Existing calls to `aabb_2d`, `bounding_circle`,
`aabb_3d`, and `bounding_sphere` will have to be changed to use
isometries instead. A straightforward conversion is to refactor just by
calling `Isometry2d/3d::new`, as follows:
```rust
// Old:
let aabb = my_shape.aabb_2d(my_translation, my_rotation);

// New:
let aabb = my_shape.aabb_2d(Isometry2d::new(my_translation, my_rotation));
```

However, if the old translation and rotation are 3d
translation/rotations originating from a `Transform` or
`GlobalTransform`, then `to_isometry` may be used instead. For example:
```rust
// Old:
let bounding_sphere = my_shape.bounding_sphere(shape_transform.translation, shape_transform.rotation);

// New:
let bounding_sphere = my_shape.bounding_sphere(shape_transform.to_isometry());
```

This discussion also applies to the `from_point_cloud` construction
method of `Aabb2d`/`BoundingCircle`/`Aabb3d`/`BoundingSphere`, which has
similarly been altered to use isometries.
2024-07-29 23:37:02 +00:00
TheDudeFromCI
7573b3c765
Added serialize flag to bevy_math dep of bevy_ui (#14450)
# Objective

When depending on the `bevy_ui` crate specifically and using the
`serialize` feature flag, the compilation fails due to `bevy_math` not
having the serialize flag enabled.

## Solution

Added the `serialize` flag to the `bevy_math` dependency when using that
flag on `bevy_ui`.

## Testing

Tested by adding `bevy_math = { version = "0.14", features =
["serialize"] }` on a small Bevy library to ensure compilation was
successful.
2024-07-29 23:34:07 +00:00
recatek
87b63af864
bevy_reflect: Adding support for Atomic values (#14419)
Fixes #14418

Note that this does not add AtomicPtr, which would need its own special
casing support, just the regular value types.
Also, I was forced to be opinionated about which Ordering to use, so I
chose SeqCst as the strictest by default.
2024-07-29 23:33:18 +00:00
Matty
74cecb27bb
Disallow empty cubic and rational curves (#14382)
# Objective

Previously, our cubic spline constructors would produce
`CubicCurve`/`RationalCurve` output with no data when they themselves
didn't hold enough control points to produce a well-formed curve.
Attempting to sample the resulting empty "curves" (e.g. by calling
`CubicCurve::position`) would crash the program (😓).

The objectives of this PR are: 
1. Ensure that the curve output of `bevy_math`'s spline constructions
are never invalid as data.
2. Provide a type-level guarantee that `CubicCurve` and `RationalCurve`
actually function as curves.

## Solution

This has a few pieces. Firstly, the curve generator traits
`CubicGenerator`, `CyclicCubicGenerator`, and `RationalGenerator` are
now fallible — they have associated error types, and the
curve-generation functions are allowed to fail:
```rust
/// Implement this on cubic splines that can generate a cubic curve from their spline parameters.
pub trait CubicGenerator<P: VectorSpace> {
    /// An error type indicating why construction might fail.
    type Error;

    /// Build a [`CubicCurve`] by computing the interpolation coefficients for each curve segment.
    fn to_curve(&self) -> Result<CubicCurve<P>, Self::Error>;
}
```

All existing spline constructions use this together with errors that
indicate when they didn't have the right control data and provide curves
which have at least one segment whenever they return an `Ok` variant.

Next, `CubicCurve` and `RationalCurve` have been blessed with a
guarantee that their internal array of segments (`segments`) is never
empty. In particular, this field is no longer public, so that invalid
curves cannot be built using struct instantiation syntax. To compensate
for this shortfall for users (in particular library authors who might
want to implement their own generators), there is a new method
`from_segments` on these for constructing a curve from a list of
segments, failing if the list is empty:
```rust
/// Create a new curve from a collection of segments. If the collection of segments is empty,
/// a curve cannot be built and `None` will be returned instead.
pub fn from_segments(segments: impl Into<Vec<CubicSegment<P>>>) -> Option<Self> { //... }
```

All existing methods on `CyclicCurve` and `CubicCurve` maintain the
invariant, so the direct construction of invalid values by users is
impossible.

## Testing

Run unit tests from `bevy_math::cubic_splines`. Additionally, run the
`cubic_splines` example and try to get it to crash using small numbers
of control points: it uses the fallible constructors directly, so if
invalid data is ever constructed, it is basically guaranteed to crash.

---

## Migration Guide

The `to_curve` method on Bevy's cubic splines is now fallible (returning
a `Result`), meaning that any existing calls will need to be updated by
handling the possibility of an error variant.

Similarly, any custom implementation of `CubicGenerator` or
`RationalGenerator` will need to be amended to include an `Error` type
and be made fallible itself.

Finally, the fields of `CubicCurve` and `RationalCurve` are now private,
so any direct constructions of these structs from segments will need to
be replaced with the new `CubicCurve::from_segments` and
`RationalCurve::from_segments` methods.

---

## Design

The main thing to justify here is the choice for the curve internals to
remain the same. After all, if they were able to cause crashes in the
first place, it's worth wondering why safeguards weren't put in place on
the types themselves to prevent that.

My view on this is that the problem was really that the internals of
these methods implicitly relied on the assumption that the value they
were operating on was *actually a curve*, when this wasn't actually
guaranteed. Now, it's possible to make a bunch of small changes inside
the curve struct methods to account for that, but I think that's worse
than just guaranteeing that the data is valid upstream — sampling is
about as hot a code path as we're going to get in this area, and hitting
an additional branch every time it happens just to check that the struct
contains valid data is probably a waste of resources.

Another way of phrasing this is that even if we're only interested in
solving the crashes, the curve's validity needs to be checked at some
point, and it's almost certainly better to do this once at the point of
construction than every time the curve is sampled.

In cases where the control data is supplied dynamically, users would
already have to deal with empty curve outputs basically not working.
Anecdotally, I ran into this while writing the `cubic_splines` example,
and I think the diff illustrates the improvement pretty nicely — the
code no longer has to anticipate whether the output will be good or not;
it just has to handle the `Result`.

The cost of all this, of course, is that we have to guarantee that the
new invariant is actually maintained whenever we extend the API.
However, for the most part, I don't expect users to want to do much
surgery on the internals of their curves anyway.
2024-07-29 23:25:14 +00:00
Giacomo Stevanato
7de271f992
Add FilteredAccess::empty and simplify the implementatin of update_component_access for AnyOf/Or (#14352)
# Objective

- The implementation of `update_component_access` for `AnyOf`/`Or` is
kinda weird due to special casing the first filter, let's simplify it;
- Fundamentally we want to fold/reduce the various filters using an OR
operation, however in order to do a proper fold we need a neutral
element for the initial accumulator, which for OR is FALSE. However we
didn't have a way to create a `FilteredAccess` value corresponding to
FALSE and thus the only option was reducing, which special cases the
first element as being the initial accumulator.

This is an alternative to https://github.com/bevyengine/bevy/pull/14026

## Solution

- Introduce `FilteredAccess::empty` as a way to create a
`FilteredAccess` corresponding to the logical proposition FALSE;
- Use it as the initial accumulator for the above operations, allowing
to handle all the elements to fold in the same way.

---

## Migration Guide

- The behaviour of `AnyOf<()>` and `Or<()>` has been changed to match no
archetypes rather than all archetypes to naturally match the
corresponding logical operation. Consider replacing them with `()`
instead.
2024-07-29 23:20:06 +00:00
Giacomo Stevanato
71c5f1e3e4
Generate links to definition in source code pages on docs.rs and dev-docs.bevyengine.org (#12965)
# Objective

- Fix issue #2611

## Solution

- Add `--generate-link-to-definition` to all the `rustdoc-args` arrays
in the `Cargo.toml`s (for docs.rs)
- Add `--generate-link-to-definition` to the `RUSTDOCFLAGS` environment
variable in the docs workflow (for dev-docs.bevyengine.org)
- Document all the workspace crates in the docs workflow (needed because
otherwise only the source code of the `bevy` package will be included,
making the argument useless)
- I think this also fixes #3662, since it fixes the bug on
dev-docs.bevyengine.org, while on docs.rs it has been fixed for a while
on their side.

---

## Changelog

- The source code viewer on docs.rs now includes links to the
definitions.
2024-07-29 23:10:16 +00:00
JMS55
29e9f0a7f9
Correct minimum range-alloc version (#14420)
Fixes https://github.com/bevyengine/bevy/issues/14417

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-29 22:11:29 +00:00
Giacomo Stevanato
59a33e6e14
Fix bevy_render's image dependency version (#14505)
# Objective

- `bevy_render` depends on `image 0.25` but uses `image::ImageReader`
which was added only in `image 0.25.2`
- users that have `image 0.25` in their `Cargo.lock` and update to the
latest `bevy_render` may thus get a compilation due to this (at least I
did)

## Solution

- Properly set the correct minimum version of `image` that `bevy_render`
depends on.
2024-07-28 15:48:51 +00:00
Giacomo Stevanato
bc80b95257
Don't debug SystemId's entity field twice (#14499)
# Objective

- `SystemId`'s `Debug` implementation includes its `entity` field twice.
- This was likely an oversight in #11019, since before that PR the
second field was the `PhantomData` one.

## Solution

- Only include it once

Alternatively, this could be changed to match the struct representation
of `SystemId`, thus instructing the formatter to print a named struct
and including the `PhantomData` field.
2024-07-27 16:15:39 +00:00
thatchedroof
4f5b8ca08c
Fix typo in World::observe (#14492)
# Objective

- Fix a typo in the documentation for `World::observe`

## Solution

- Change `Spawn` to `Spawns` and `it's` to `its`
2024-07-27 13:55:44 +00:00
Brian Reavis
724fe49c73
Fix TextureCache memory leak and add is_empty() method (#14480)
# Objective

Fix a memory leak in `TextureCache` caused by the internal HashMap never
having unused entries cleared.

This isn't a giant memory leak, given the unused entries are simply
empty vectors. Though, if someone goes and resizes a window a bunch, it
can lead to hundreds/thousands of TextureDescriptor keys adding up in
the hashmap – which isn't ideal.

## Solution

- Only retain hashmap entries that still have textures.
- I also added an `is_empty()` method to `TextureCache`, which is useful
for 3rd-party higher-level caches that might have individual caches by
view entity or texture type, for example.

## Testing

- Verified the examples still work (this is a trivial change)
2024-07-27 13:16:27 +00:00
BD103
e49527e34d
Fix bevy_winit not building with serialize feature (#14469)
# Objective

- `bevy_winit` fails to build with just the `serialize` feature.
- Caught by [`flag-frenzy`](https://github.com/TheBevyFlock/flag-frenzy)
in [this
run](https://github.com/TheBevyFlock/flag-frenzy/actions/runs/10087486444/job/27891723948),
using the new, nuanced configuration system!

## Solution

- It was failing because `bevy_winit` did not pass the `serialize` flag
to two of its dependencies: `bevy_input` and `bevy_window`.
- To fix this, add these crates to the feature flag.

## Testing

```bash
# On Linux, you must also specify a backend: `x11` or `wayland`.
# You can do this with `-F serialize,x11`, etc.
cargo check -p bevy_winit --no-default-features -F serialize
```
2024-07-26 22:05:36 +00:00
NiseVoid
a8003b4496
Handle 0 height in prepare_bloom_textures (#14423)
# Objective

- Fix a confusing panic when the viewport width is non-zero and the
height is 0, `prepare_bloom_textures` tries to create a `4294967295x1`
texture.

## Solution

- Avoid dividing by zero
- Apps still crash after this, but now on a more reasonable error about
the zero-size viewport

## Testing

- I isolated and tested the math. A height of 0 sets `mip_height_ratio`
to `inf`, causing the width to explode if it isn't also 0
2024-07-26 21:53:36 +00:00
BD103
ee4ed231da
Fix bevy_gltf PBR features not enabling corresponding bevy_pbr flags (#14486)
# Objective

- `bevy_gltf` does not build with only the
`pbr_multi_layer_material_textures` or `pbr_anisotropy_texture`
features.
- Caught by [`flag-frenzy`](https://github.com/TheBevyFlock/flag-frenzy)
in [this
run](https://github.com/TheBevyFlock/flag-frenzy/actions/runs/10087486444/job/27891723948).

## Solution

- This error was due to the feature not enabling the corresponding
feature in `bevy_pbr`. Adding these flags as a dependency fixes this
error.

## Testing

The following commands fail on `main`, but pass with this PR:

```bash
cargo check -p bevy_gltf --no-default-features -F pbr_multi_layer_material_textures
cargo check -p bevy_gltf --no-default-features -F pbr_anisotropy_texture
```
2024-07-26 17:11:38 +00:00
Brian Reavis
c1fedc2e2d
Made ViewUniform fields public (#14482)
# Objective

- Made `ViewUniform` fields public so that 3rd-parties can create this
uniform. This is useful for custom pipelines that use custom views (e.g.
views buffered by a particular amount, for example).
2024-07-26 17:11:29 +00:00
Sludge
1edec4d890
Remove #[cfg] from the From impls of TextSection (#14439)
# Objective

- Not including bevy's default font shouldn't result in code not
compiling anymore.
- Games may want to load their own default font into the default
`Handle<Font>` and not include bevy's default font, but still use these
convenience impls (https://github.com/bevyengine/bevy/issues/12192
currently makes this a bit inconvenient, but it does work).

## Solution

- Include these impls unconditionally.
- Slightly expand the comment on the `font` field to indicate that a
custom font can be used to override the default font.
- (drive-by: add `#[reflect(Default)]` on `TextSection`, since it was
missing a way to construct it via reflection)
2024-07-26 17:11:12 +00:00
radiish
6dbc8b8f6f
ptr: allow Ptr and PtrMut construction for references to values of ?Sized types (#14479)
# Objective

- Currently `bevy_ptr::{Ptr, PtrMut}` have `From` implementations from
references.
- These implementations impose an implicit `Sized` bound so `bevy_ptr`
types cannot be created from references to slices and trait objects.
- I ran into this trying to use `Ptr<'static>` as an untyped `&'static
dyn Any`, and [had to work around
it](f32b41512c/src/registry.rs (L214-L219)).

## Solution

- Relax the `Sized` bound on the relevant `From` implementations.
2024-07-25 23:14:16 +00:00
Brian Reavis
438217035d
Don’t prepare 2D view bind groups for 3D cameras (#14481)
# Objective

- Before this fix, the view query in `prepare_mesh2d_view_bind_groups`
matched all views – leading to 2D view bind groups being prepared for 3D
cameras.

## Solution

- Added `With<Camera2d>` to the views query.

## Testing

- Verified the examples still work.
2024-07-25 20:37:54 +00:00
Matty
5aa998dc07
Conversions for Isometry3d ⟷ Transform/GlobalTransform (#14478)
# Objective

Allow interoperation between `Isometry3d` and the transform types from
bevy_transform. At least in the short term, the primary goal is to allow
the extraction of isometries from transform components by users.

## Solution

- Add explicit `from_isometry`/`to_isometry` methods to `Transform`.
- Add explicit `from_isometry`/`to_isometry` methods to
`GlobalTransform`. The former is hidden (primarily for internal use),
and the latter has the caveats originating in
[`Affine3A::to_scale_rotation_translation`](https://docs.rs/glam/latest/glam/f32/struct.Affine3A.html#method.to_scale_rotation_translation).
- Implement the `TransformPoint` trait for `Isometry3d`.
2024-07-25 20:23:32 +00:00
Ben Frankel
e7e10f2c0f
Fix hue mixing for Lcha and Oklcha (#14468)
# Objective

Fix erroneous hue mixing in `Lcha` and `Oklcha`. Purple + Red == Green
is the current behavior.

## Solution

Use `crate::color_ops::lerp_hue` to handle the wrap-around at 360
degrees, the same way that `Hsla`, `Hsva`, and `Hwba` do it.

## Testing

Game jamming, but tested that the workaround below produces
correct-looking colors in my jam game.
2024-07-25 19:44:18 +00:00
Robert Walter
52a2a3b146
Dedicated Reflect implementation for Set-like things (#13014)
# Objective

I just wanted to inspect `HashSet`s in `bevy-inspector-egui` but I
noticed that it didn't work for some reason. A few minutes later I found
myself looking into the bevy reflect impls noticing that `HashSet`s have
been covered only rudimentary up until now.

## Solution

I'm not sure if this is overkill (especially the first bullet), but
here's a list of the changes:

- created a whole new trait and enum variants for `ReflectRef` and the
like called `Set`
- mostly oriented myself at the `Map` trait and made the necessary
changes until RA was happy
- create macro `impl_reflect_for_hashset!` and call it on `std::HashSet`
and `hashbrown::HashSet`

Extra notes:

- no `get_mut` or `get_mut_at` mirroring the `std::HashSet`
- `insert[_boxed]` and `remove` return `bool` mirroring `std::HashSet`,
additionally that bool is reflect as I thought that would be how we
handle things in bevy reflect, but I'm not sure on this
- ser/de are handled via `SeqAccess`
- I'm not sure about the general deduplication property of this impl of
`Set` that is generally expected? I'm also not sure yet if `Map` does
provide this. This mainly refers to the `Dynamic[...]` structs
- I'm not sure if there are other methods missing from the `trait`, I
felt like `contains` or the set-operations (union/diff/...) could've
been helpful, but I wanted to get out the bare minimum for feedback
first

---

## Changelog

### Added
- `Set` trait for `bevy_reflect`

### Changed
- `std::collections::HashSet` and `bevy_utils::hashbrown::HashSet` now
implement a more complete set of reflect functionalities instead of
"just" `reflect_value`
- `TypeInfo` contains a new variant `Set` that contains `SetInfo`
- `ReflectKind` contains a new variant `Set`
- `ReflectRef` contains a new variant `Set`
- `ReflectMut` contains a new variant `Set`
- `ReflectOwned` contains a new variant `Set`

## Migration Guide

- The new `Set` variants on the enums listed in the change section
should probably be considered by people working with this level of the
lib
### Help wanted! 

I'm not sure if this change is able to break code. From my understanding
it shouldn't since we just add functionality but I'm not sure yet if
theres anything missing from my impl that would be normally provided by
`impl_reflect_value!`
2024-07-24 19:43:26 +00:00
Blake Bedford
eabb58aa04
Add BorderRadius field to ImageBundle (#14457)
# Objective

- Fixes #14453

## Solution

- Added BorderRadius to ImageBundle

## Testing

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

- Tested on a random picture I found in the examples and it added a
border radius.

- Are there any parts that need more testing?

- I don't fink so.

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?

- Apply a border radius to a random picture.
2024-07-24 18:41:26 +00:00
Dmytro Banin
e9e29d61c6
Add intradoc links for observer triggers (#14458)
# Objective

When using observers you might want to know what the difference is
between `OnAdd` vs `OnReplace` vs `OnInsert` etc. It's not obvious where
to look (`component_hooks.rs`). Added intradoc links for easier
disambiguation.
2024-07-24 18:41:23 +00:00
Joseph
218f78157d
Require &mut self for World::increment_change_tick (#14459)
# Objective

The method `World::increment_change_tick` currently takes `&self` as the
method receiver, which is semantically strange. Even though the interior
mutability is sound, the existence of this method is strange since we
tend to think of `&World` as being a read-only snapshot of a world, not
an aliasable reference to a world with mutability. For those purposes,
we have `UnsafeWorldCell`.

## Solution

Change the method signature to take `&mut self`. Use exclusive access to
remove the need for atomic adds, which makes the method slightly more
efficient. Redirect users to [`UnsafeWorldCell::increment_change_tick`]
if they need to increment the world's change tick from an aliased
context.

In practice I don't think there will be many breakages, if any. In cases
where you need to call `increment_change_tick`, you usually already have
either `&mut World` or `UnsafeWorldCell`.

---

## Migration Guide

The method `World::increment_change_tick` now requires `&mut self`
instead of `&self`. If you need to call this method but do not have
mutable access to the world, consider using
`world.as_unsafe_world_cell_readonly().increment_change_tick()`, which
does the same thing, but is less efficient than the method on `World`
due to requiring atomic synchronization.

```rust
fn my_system(world: &World) {
    // Before
    world.increment_change_tick();

    // After
    world.as_unsafe_world_cell_readonly().increment_change_tick();
}
```
2024-07-24 12:42:28 +00:00
Felix Rath
abceebebba
feat: Add World::get_reflect() and World::get_reflect_mut() (#14416)
# Objective

Sometimes one wants to retrieve a `&dyn Reflect` for an entity's
component, which so far required multiple, non-obvious steps and
`unsafe`-code.
The docs for
[`MutUntyped`](https://docs.rs/bevy/latest/bevy/ecs/change_detection/struct.MutUntyped.html#method.map_unchanged)
contain an example of the unsafe part.

## Solution

This PR adds the two methods:

```rust
// immutable variant
World::get_reflect(&self, entity: Entity, type_id: TypeId) -> Result<&dyn Reflect, GetComponentReflectError>

// mutable variant
World::get_reflect_mut(&mut self, entity: Entity, type_id: TypeId) -> Result<Mut<'_, dyn Reflect>, GetComponentReflectError>
```

which take care of the necessary steps, check required invariants etc.,
and contain the unsafety so the caller doesn't have to deal with it.

## Testing

- Did you test these changes? If so, how?
- Added tests and a doc test, also (successfully) ran `cargo run -p ci`.
- Are there any parts that need more testing?
- Could add tests for each individual error variant, but it's not
required imo.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Run `cargo test --doc --package bevy_ecs --all-features --
world::World::get_reflect --show-output` for the doctest
- Run `cargo test --package bevy_ecs --lib --all-features --
world::tests::reflect_tests --show-output` for the unittests
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - Don't think it's relevant, but tested on 64bit linux (only).

---

## Showcase

Copy of the doctest example which gives a good overview of what this
enables:

```rust
use bevy_ecs::prelude::*;
use bevy_reflect::Reflect;
use std::any::TypeId;

// define a `Component` and derive `Reflect` for it
#[derive(Component, Reflect)]
struct MyComponent;

// create a `World` for this example
let mut world = World::new();

// Note: This is usually handled by `App::register_type()`, but this example can not use `App`.
world.init_resource::<AppTypeRegistry>();
world.get_resource_mut::<AppTypeRegistry>().unwrap().write().register::<MyComponent>();

// spawn an entity with a `MyComponent`
let entity = world.spawn(MyComponent).id();

// retrieve a reflected reference to the entity's `MyComponent`
let comp_reflected: &dyn Reflect = world.get_reflect(entity, TypeId::of::<MyComponent>()).unwrap();

// make sure we got the expected type
assert!(comp_reflected.is::<MyComponent>());
```

## Migration Guide

No breaking changes, but users can use the new methods if they did it
manually before.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-23 16:57:54 +00:00
Shane Celis
8a79185880
feature: Derive Hash for KeyboardInput. (#14263)
# Objective

Derive `Hash` for `KeyboardInput`.

## Problem

I was [writing code](https://github.com/joshka/bevy_ratatui/pull/13) to
take `crossterm` events and republish them as bevy input events. One
scenario requires I check if the same key press was happening
repeatedly; in a regular terminal we don't get key released events, so I
was simulating them.

I was surprised to find that I couldn't put `KeyboardInput` into a
`HashSet`.

## Work Around

My work around was to add a new type that implemented Hash.

```rust
#[derive(Deref, DerefMut, PartialEq, Eq)]
struct KeyInput(KeyboardInput);

impl Hash for KeyInput {
    fn hash<H>(&self, state: &mut H)
    where
        H: Hasher,
    {
        self.key_code.hash(state);
        self.logical_key.hash(state);
        self.state.hash(state);
        self.window.hash(state);
    }
}
```

## Solution

A better solution since all members of `KeyboardInput` implement `Hash`
is to have it derive `Hash` as well.

## Testing

My newtype solution works for its purpose.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-07-23 12:29:15 +00:00
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
Jenya705
330911f1bf
Component Hook functions as attributes for Component derive macro (#14005)
# Objective

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

## Solution

Added 3 new attributes to the `Component` macro.

## Testing

Added `component_hook_order_spawn_despawn_with_macro_hooks`, that makes
the same as `component_hook_order_spawn_despawn` but uses a struct, that
defines it's hooks with the `Component` macro.

---

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-08 00:46:00 +00:00
François Mockers
c994c15d5e
EmptyPathStream is only used in android/wasm32 (#14200)
# Objective

- `EmptyPathStream` is only used in android and wasm32
- This now makes rust nightly warn

## Solution

- flag the struct to only be present when needed
- also change how `MorphTargetNames` is used because that makes rust
happier?
2024-07-07 19:54:53 +00:00
daxpedda
ea2a7e5552
Send SceneInstanceReady when spawning any kind of scene (#11741)
# Objective

- Emit an event regardless of scene type (`Scene` and `DynamicScene`).
- Also send the `InstanceId` along.

Follow-up to #11002.
Fixes #2218.

## Solution

- Send `SceneInstanceReady` regardless of scene type.
- Make `SceneInstanceReady::parent` `Option`al.
- Add `SceneInstanceReady::id`.

---

## Changelog

### Changed

- `SceneInstanceReady` is now sent for `Scene` as well.
`SceneInstanceReady::parent` is an `Option` and
`SceneInstanceReady::id`, an `InstanceId`, is added to identify the
corresponding `Scene`.

## Migration Guide

- `SceneInstanceReady { parent: Entity }` is now `SceneInstanceReady {
id: InstanceId, parent: Option<Entity> }`.
2024-07-06 14:00:39 +00:00
BD103
1ceb45540b
Remove unused type parameter in Parallel::drain() (#14178)
# Objective

- `Parallel::drain()` has an unused type parameter `B` than can be
removed.
- Caught [on
Discord](https://discord.com/channels/691052431525675048/692572690833473578/1259004180560085003)
by Andrew, thanks!

## Solution

- Remove it! :)

## Testing

- `Parallel::drain()` should still function exactly the same.

---

## Changelog

- Removed unused type parameter in `Parallel::drain()`.

## Migration Guide

The type parameter of `Parallel::drain()` was unused, so it is now
removed. If you were manually specifying it, you can remove the bounds.

```rust
// 0.14
// Create a `Parallel` and give it a value.
let mut parallel: Parallel<Vec<u8>> = Parallel::default();
*parallel.borrow_local_mut() = vec![1, 2, 3];

for v in parallel.drain::<u8>() {
    // ...
}

// 0.15
let mut parallel: Parallel<Vec<u8>> = Parallel::default();
*parallel.borrow_local_mut() = vec![1, 2, 3];

// Remove the type parameter.
for v in parallel.drain() {
    // ...
}
```
2024-07-06 13:29:29 +00:00
Gino Valente
09d86bfb96
bevy_reflect: Re-enable reflection compile fail tests (#14165)
# Objective

Looks like I accidentally disabled the reflection compile fail tests in
#13152. These should be re-enabled.

## Solution

Re-enable reflection compile fail tests.

## Testing

CI should pass. You can also test locally by navigating to
`crates/bevy_reflect/compile_fail/` and running:

```
cargo test --target-dir ../../../target
```
2024-07-05 20:49:03 +00:00
NWPlayer123
c6a89c2187
impl Debug for ExtendedMaterial (#14140)
# Objective

Both `Material` and `MaterialExtension` (base and extension) can derive
Debug, so there's no reason to not allow `ExtendedMaterial` to derive it

## Solution

- Describe the solution used to achieve the objective above.
Add `Debug` to the list of derived traits

## Testing

- Did you test these changes? If so, how?
I compiled my test project on latest commit, making sure it actually
compiles
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
Create an ExtendedMaterial instance, try to `println!("{:?}",
material);`

Co-authored-by: NWPlayer123 <NWPlayer123@users.noreply.github.com>
2024-07-04 23:59:48 +00:00
TotalKrill
5986d5d309
Cosmic text (#10193)
# Replace ab_glyph with the more capable cosmic-text

Fixes #7616.

Cosmic-text is a more mature text-rendering library that handles scripts
and ligatures better than ab_glyph, it can also handle system fonts
which can be implemented in bevy in the future

Rebase of https://github.com/bevyengine/bevy/pull/8808

## Changelog

Replaces text renderer ab_glyph with cosmic-text

The definition of the font size has changed with the migration to cosmic
text. The behavior is now consistent with other platforms (e.g. the
web), where the font size in pixels measures the height of the font (the
distance between the top of the highest ascender and the bottom of the
lowest descender). Font sizes in your app need to be rescaled to
approximately 1.2x smaller; for example, if you were using a font size
of 60.0, you should now use a font size of 50.0.

## Migration guide

- `Text2dBounds` has been replaced with `TextBounds`, and it now accepts
`Option`s to the bounds, instead of using `f32::INFINITY` to inidicate
lack of bounds
- Textsizes should be changed, dividing the current size with 1.2 will
result in the same size as before.
- `TextSettings` struct is removed
- Feature `subpixel_alignment` has been removed since cosmic-text
already does this automatically
- TextBundles and things rendering texts requires the `CosmicBuffer`
Component on them as well

## Suggested followups:

- TextPipeline: reconstruct byte indices for keeping track of eventual
cursors in text input
- TextPipeline: (future work) split text entities into section entities
- TextPipeline: (future work) text editing
- Support line height as an option. Unitless `1.2` is the default used
in browsers (1.2x font size).
- Support System Fonts and font families
- Example showing of animated text styles. Eg. throbbing hyperlinks

---------

Co-authored-by: tigregalis <anak.harimau@gmail.com>
Co-authored-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: sam edelsten <samedelsten1@gmail.com>
Co-authored-by: Dimchikkk <velo.app1@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-07-04 20:41:08 +00:00
re0312
1c2f687202
Skip extract UiImage When its texture is default (#14122)
# Objective

- After #14017 , I noticed that the drawcall increased 10x in the
`many_buttons`, causing the `UIPassNode `to increase from 1.5ms to 6ms.
This is because our UI batching is very fragile.

## Solution

- skip extract UiImage when its texture is default


## Performance 
many_buttons UiPassNode

![image](https://github.com/bevyengine/bevy/assets/45868716/9295d958-8c3f-469c-a7e0-d1e90db4dfb7)
2024-07-03 20:54:11 +00:00
re0312
2893fc3e8b
Using simple approx round up in ui_layout_system (#14079)
# Objective

- built-in `f32::round `is slow 
- splits from #14064 
## Solution

- using a simple floor instead of round

## Testing

- I am not an expert on floating-point values, but I enumerated all f32
values to test for potential errors compared to the previous function.
[rust
playground](https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=0d8ed5604499e7bd9c61ce57d47e8c06)

three cases where the behavior differs between the new and previous
functions:
| value  |  previous | new  |  
|---|---|---|
|  [-0.5,0) |  -0 | +0  |   
|  0.49999997  | 0  |  1 |   
| +-8388609 |  8388609   | 8388610  |   

## Performance


![image](https://github.com/bevyengine/bevy/assets/45868716/1910f342-e55b-4f5c-851c-24a142d5c72e)
2024-07-03 12:48:34 +00:00
Gagnus
a47b91cccc
Added feature switch to default Standard Material's new anisotropy texture to off (#14048)
# Objective

- Standard Material is starting to run out of samplers (currently uses
13 with no additional features off, I think in 0.13 it was 12).
- This change adds a new feature switch, modelled on the other ones
which add features to Standard Material, to turn off the new anisotropy
feature by default.

## Solution

- feature + texture define

## Testing

- Anisotropy example still works fine
- Other samples work fine
- Standard Material now takes 12 samplers by default on my Mac instead
of 13

## Migration Guide

- Add feature pbr_anisotropy_texture if you are using that texture in
any standard materials.

---------

Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
2024-07-02 18:02:05 +00:00
Vic
7e0d262d77
use associated type bounds in QueryManyIter and QueryIter::sort() (#14107)
# Objective

The bounds for query iterators are quite intimidating.

## Solution

With Rust 1.79, [associated type
bounds](https://github.com/rust-lang/rust/pull/122055/) stabilized,
which can simplify the bounds slightly.
2024-07-02 13:39:22 +00:00
Mincong Lu
ce5254e3ec
Added get_main_animation for AnimationTransitions (#14104)
# Objective

Added a getter for the main animation of `AnimationTransitions`.

## Solution

Added `get_main_animation` for `AnimationTransitions`.
2024-07-02 13:28:42 +00:00
Vic
1d907c5668
add missing mention of sort_unstable_by_key in QuerySortedIter docs (#14108)
# Objective

There is a missing mention of `sort_unstable_by_key` in the
`QuerySortedIter` docs.

## Solution

Add it.
2024-07-02 13:27:21 +00:00
Jan Hohenheim
7aaf440fbf
Fix push_children inserting a Children component even when no children are supplied (#14109)
# Objective

The Bevy API around manipulating hierarchies removes `Children` if the
operation results in an entity having no children. This means that
`Children` is guaranteed to hold actual children. However, the following
code unexpectedly inserts empty `Children`:

```rust
commands.entity(entity).with_children(|_| {});
```

This was discovered by @Jondolf:
https://discord.com/channels/691052431525675048/1124043933886976171/1257660865625325800

## Solution

- `with_children` is now a noop when no children were passed

## Testing

- Added a regression test
2024-07-02 13:27:02 +00:00
Joseph
5876352206
Optimize common usages of AssetReader (#14082)
# Objective

The `AssetReader` trait allows customizing the behavior of fetching
bytes for an `AssetPath`, and expects implementors to return `dyn
AsyncRead + AsyncSeek`. This gives implementors of `AssetLoader` great
flexibility to tightly integrate their asset loading behavior with the
asynchronous task system.

However, almost all implementors of `AssetLoader` don't use the async
functionality at all, and just call `AsyncReadExt::read_to_end(&mut
Vec<u8>)`. This is incredibly inefficient, as this method repeatedly
calls `poll_read` on the trait object, filling the vector 32 bytes at a
time. At my work we have assets that are hundreds of megabytes which
makes this a meaningful overhead.

## Solution

Turn the `Reader` type alias into an actual trait, with a provided
method `read_to_end`. This provided method should be more efficient than
the existing extension method, as the compiler will know the underlying
type of `Reader` when generating this function, which removes the
repeated dynamic dispatches and allows the compiler to make further
optimizations after inlining. Individual implementors are able to
override the provided implementation -- for simple asset readers that
just copy bytes from one buffer to another, this allows removing a large
amount of overhead from the provided implementation.

Now that `Reader` is an actual trait, I also improved the ergonomics for
implementing `AssetReader`. Currently, implementors are expected to box
their reader and return it as a trait object, which adds unnecessary
boilerplate to implementations. This PR changes that trait method to
return a pseudo trait alias, which allows implementors to return `impl
Reader` instead of `Box<dyn Reader>`. Now, the boilerplate for boxing
occurs in `ErasedAssetReader`.

## Testing

I made identical changes to my company's fork of bevy. Our app, which
makes heavy use of `read_to_end` for asset loading, still worked
properly after this. I am not aware if we have a more systematic way of
testing asset loading for correctness.

---

## Migration Guide

The trait method `bevy_asset::io::AssetReader::read` (and `read_meta`)
now return an opaque type instead of a boxed trait object. Implementors
of these methods should change the type signatures appropriately

```rust
impl AssetReader for MyReader {
    // Before
    async fn read<'a>(&'a self, path: &'a Path) -> Result<Box<Reader<'a>>, AssetReaderError> {
        let reader = // construct a reader
        Box::new(reader) as Box<Reader<'a>>
    }

    // After
    async fn read<'a>(&'a self, path: &'a Path) -> Result<impl Reader + 'a, AssetReaderError> {
        // create a reader
    }
}
```

`bevy::asset::io::Reader` is now a trait, rather than a type alias for a
trait object. Implementors of `AssetLoader::load` will need to adjust
the method signature accordingly

```rust
impl AssetLoader for MyLoader {
    async fn load<'a>(
        &'a self,
        // Before:
        reader: &'a mut bevy::asset::io::Reader,
        // After:
        reader: &'a mut dyn bevy::asset::io::Reader,
        _: &'a Self::Settings,
        load_context: &'a mut LoadContext<'_>,
    ) -> Result<Self::Asset, Self::Error> {
}
```

Additionally, implementors of `AssetReader` that return a type
implementing `futures_io::AsyncRead` and `AsyncSeek` might need to
explicitly implement `bevy::asset::io::Reader` for that type.

```rust
impl bevy::asset::io::Reader for MyAsyncReadAndSeek {}
```
2024-07-01 19:59:42 +00:00
Lee-Orr
bd7dcd3f6d
deregister events (#14083)
# Objective

Add ability to de-register events from the EventRegistry (and the
associated World).

The initial reasoning relates to retaining support for Event hot
reloading in `dexterous_developer`.

## Solution

Add a `deregister_events<T: Event>(&mut world)` method to the
`EventRegistry` struct.

## Testing

Added an automated test that verifies the event registry adds and
removes `Events<T>` from the world.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-07-01 16:18:14 +00:00
Lura
856b39d821
Apply Clippy lints regarding lazy evaluation and closures (#14015)
# Objective

- Lazily evaluate
[default](https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_or_default)~~/[or](https://rust-lang.github.io/rust-clippy/master/index.html#/or_fun_call)~~
values where it makes sense
  - ~~`unwrap_or(foo())` -> `unwrap_or_else(|| foo())`~~
  - `unwrap_or(Default::default())` -> `unwrap_or_default()`
  - etc.
- Avoid creating [redundant
closures](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure),
even for [method
calls](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure_for_method_calls)
  - `map(|something| something.into())` -> `map(Into:into)`

## Solution

- Apply Clippy lints:
-
~~[or_fun_call](https://rust-lang.github.io/rust-clippy/master/index.html#/or_fun_call)~~
-
[unwrap_or_default](https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_or_default)
-
[redundant_closure_for_method_calls](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure_for_method_calls)
([redundant
closures](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure)
is already enabled)

## Testing

- Tested on Windows 11 (`stable-x86_64-pc-windows-gnu`, 1.79.0)
- Bevy compiles without errors or warnings and examples seem to work as
intended
  - `cargo clippy` 
  - `cargo run -p ci -- compile` 

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-01 15:54:40 +00:00
Joseph
9055fc1d68
Clarify the difference between default render layers and none render layers (#14075)
# Objective

It's not always obvious what the default value for `RenderLayers`
represents. It is documented, but since it's an implementation of a
trait method the documentation may or may not be shown depending on the
IDE.

## Solution

Add documentation to the `none` method that explicitly calls out the
difference.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-01 14:47:13 +00:00
BD103
f7bc0a01dd
Bump accesskit to 0.16 (#14091)
Also bumps `accesskit_winit` to 0.22 and fixes one breaking change.

# Objective

- `accesskit` has been updated recently to 0.16!

## Solution

- Update `accesskit`, as well as `accesskit_winit`.
- [`accesskit`
changelog](552032c839/common/CHANGELOG.md (0160-2024-06-29))
- [`accesskit_winit`
changelog](552032c839/platforms/winit/CHANGELOG.md (0220-2024-06-29))
- Fix one breaking change where `Role::StaticText` has been renamed to
`Role::Label`.

## Testing

- The test suite should cover most things.
- It would be good to test this with an example, but I don't know how.

---

## Changelog

- Update `accesskit` to 0.16 and `accesskit_winit` to 0.22.

## Migration Guide

`accesskit`'s `Role::StaticText` variant has been renamed to
`Role::Label`.
2024-07-01 14:42:40 +00:00
BD103
b389e7baba
Bump rodio to 0.19 (#14090)
# Objective

- Though Rodio will eventually be replaced with Kira for `bevy_audio`,
we should not let it languish.

## Solution

- Bump Rodio to 0.19.
- This is [the
changelog](27f2b42406/CHANGELOG.md (version-0190-2024-06-29)).
No apparent breaking changes, only 1 feature and 1 fix.

## Testing

- Run an example that uses audio, on both native and WASM.

---

## Changelog

- Bumped Rodio to 0.19.
2024-07-01 14:41:49 +00:00
Al M
ace4eaaf0e
Merge BuildWorldChildren and BuildChildren traits. (#14052)
# Objective

The `BuildChildren` and `BuildWorldChildren` traits are mostly
identical, so I decided to try and merge them. I'm not sure of the
history, maybe they were added before GATs existed.

## Solution

- Add an associated type to `BuildChildren` which reflects the prior
differences between the `BuildChildren` and `BuildWorldChildren` traits.
- Add `ChildBuild` trait that is the bounds for
`BuildChildren::Builder`, with impls for `ChildBuilder` and
`WorldChildBuilder`.
- Remove `BuildWorldChildren` trait and replace it with an impl of
`BuildChildren` for `EntityWorldMut`.

## Testing

I ran several of the examples that use entity hierarchies, mainly UI.

---

## Changelog

n/a

## Migration Guide

n/a
2024-07-01 14:29:39 +00:00
Aztro
6dcff2bfe8
Mouse input accumulation (#14044)
# Objective

- Add the `AccumulatedMouseMotion` and `AccumulatedMouseScroll`
resources to make it simpler to track mouse motion/scroll changes
- Closes #13915

## Solution

- Created two resources, `AccumulatedMouseMotion` and
`AccumulatedMouseScroll`, and a method that tracks the `MouseMotion` and
`MouseWheel` events and accumulates their deltas every frame.
- Also modified the mouse input example to show how to use the
resources.

## Testing

- Tested the changes by modifying an existing example to use the newly
added resources, and moving/scrolling my trackpad around a ton.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-07-01 14:27:21 +00:00
Sarthak Singh
f607be8777
Handle Ctrl+C in the terminal properly (#14001)
# Objective

Fixes #13995.

## Solution

Override the default `Ctrl+C` handler with one that sends `AppExit`
event to every app with `TerminalCtrlCHandlerPlugin`.

## Testing

Tested by running the `3d_scene` example and hitting `Ctrl+C` in the
terminal.

---

## Changelog

Handles `Ctrl+C` in the terminal gracefully.

## Migration Guide

If you are overriding the `Ctrl+C` handler then you should call
`TerminalCtrlCHandlerPlugin::gracefully_exit` from your handler. It will
tell the app to exit.
2024-07-01 14:08:42 +00:00
Mikhail Novikov
cb4fe4ea9e
Make gLTF node children Handle instead of objects (#13707)
Part of #13681 

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](https://github.com/bevyengine/bevy/pull/13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
2024-07-01 14:05:16 +00:00
Joseph
64bc811815
Support operations for render layers and fix equality comparisons (#13310)
# Objective

Allow combining render layers with a more-ergonomic syntax than
`RenderLayers::from_iter(a.iter().chain(b.iter()))`.

## Solution

Add the `or` operation (and corresponding `const` method) to allow
computing the union of a set of render layers. While we're here, also
added `and` and `xor` operations. Someone might find them useful

## Testing

Added a simple unit test.
2024-07-01 13:55:25 +00:00
Gino Valente
276dd04001
bevy_reflect: Function reflection (#13152)
# Objective

We're able to reflect types sooooooo... why not functions?

The goal of this PR is to make functions callable within a dynamic
context, where type information is not readily available at compile
time.

For example, if we have a function:

```rust
fn add(left: i32, right: i32) -> i32 {
  left + right
}
```

And two `Reflect` values we've already validated are `i32` types:

```rust
let left: Box<dyn Reflect> = Box::new(2_i32);
let right: Box<dyn Reflect> = Box::new(2_i32);
```

We should be able to call `add` with these values:

```rust
// ?????
let result: Box<dyn Reflect> = add.call_dynamic(left, right);
```

And ideally this wouldn't just work for functions, but methods and
closures too!

Right now, users have two options:

1. Manually parse the reflected data and call the function themselves
2. Rely on registered type data to handle the conversions for them

For a small function like `add`, this isn't too bad. But what about for
more complex functions? What about for many functions?

At worst, this process is error-prone. At best, it's simply tedious.

And this is assuming we know the function at compile time. What if we
want to accept a function dynamically and call it with our own
arguments?

It would be much nicer if `bevy_reflect` could alleviate some of the
problems here.

## Solution

Added function reflection!

This adds a `DynamicFunction` type to wrap a function dynamically. This
can be called with an `ArgList`, which is a dynamic list of
`Reflect`-containing `Arg` arguments. It returns a `FunctionResult`
which indicates whether or not the function call succeeded, returning a
`Reflect`-containing `Return` type if it did succeed.

Many functions can be converted into this `DynamicFunction` type thanks
to the `IntoFunction` trait.

Taking our previous `add` example, this might look something like
(explicit types added for readability):

```rust
fn add(left: i32, right: i32) -> i32 {
  left + right
}

let mut function: DynamicFunction = add.into_function();
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
let result: Return = function.call(args).unwrap();
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```

And it also works on closures:

```rust
let add = |left: i32, right: i32| left + right;

let mut function: DynamicFunction = add.into_function();
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
let result: Return = function.call(args).unwrap();
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```

As well as methods:

```rust
#[derive(Reflect)]
struct Foo(i32);

impl Foo {
  fn add(&mut self, value: i32) {
    self.0 += value;
  }
}

let mut foo = Foo(2);

let mut function: DynamicFunction = Foo::add.into_function();
let args: ArgList = ArgList::new().push_mut(&mut foo).push_owned(2_i32);
function.call(args).unwrap();
assert_eq!(foo.0, 4);
```

### Limitations

While this does cover many functions, it is far from a perfect system
and has quite a few limitations. Here are a few of the limitations when
using `IntoFunction`:

1. The lifetime of the return value is only tied to the lifetime of the
first argument (useful for methods). This means you can't have a
function like `(a: i32, b: &i32) -> &i32` without creating the
`DynamicFunction` manually.
2. Only 15 arguments are currently supported. If the first argument is a
(mutable) reference, this number increases to 16.
3. Manual implementations of `Reflect` will need to implement the new
`FromArg`, `GetOwnership`, and `IntoReturn` traits in order to be used
as arguments/return types.

And some limitations of `DynamicFunction` itself:

1. All arguments share the same lifetime, or rather, they will shrink to
the shortest lifetime.
2. Closures that capture their environment may need to have their
`DynamicFunction` dropped before accessing those variables again (there
is a `DynamicFunction::call_once` to make this a bit easier)
3. All arguments and return types must implement `Reflect`. While not a
big surprise coming from `bevy_reflect`, this implementation could
actually still work by swapping `Reflect` out with `Any`. Of course,
that makes working with the arguments and return values a bit harder.
4. Generic functions are not supported (unless they have been manually
monomorphized)

And general, reflection gotchas:

1. `&str` does not implement `Reflect`. Rather, `&'static str`
implements `Reflect` (the same is true for `&Path` and similar types).
This means that `&'static str` is considered an "owned" value for the
sake of generating arguments. Additionally, arguments and return types
containing `&str` will assume it's `&'static str`, which is almost never
the desired behavior. In these cases, the only solution (I believe) is
to use `&String` instead.

### Followup Work

This PR is the first of two PRs I intend to work on. The second PR will
aim to integrate this new function reflection system into the existing
reflection traits and `TypeInfo`. The goal would be to register and call
a reflected type's methods dynamically.

I chose not to do that in this PR since the diff is already quite large.
I also want the discussion for both PRs to be focused on their own
implementation.

Another followup I'd like to do is investigate allowing common container
types as a return type, such as `Option<&[mut] T>` and `Result<&[mut] T,
E>`. This would allow even more functions to opt into this system. I
chose to not include it in this one, though, for the same reasoning as
previously mentioned.

### Alternatives

One alternative I had considered was adding a macro to convert any
function into a reflection-based counterpart. The idea would be that a
struct that wraps the function would be created and users could specify
which arguments and return values should be `Reflect`. It could then be
called via a new `Function` trait.

I think that could still work, but it will be a fair bit more involved,
requiring some slightly more complex parsing. And it of course is a bit
more work for the user, since they need to create the type via macro
invocation.

It also makes registering these functions onto a type a bit more
complicated (depending on how it's implemented).

For now, I think this is a fairly simple, yet powerful solution that
provides the least amount of friction for users.

---

## Showcase

Bevy now adds support for storing and calling functions dynamically
using reflection!

```rust
// 1. Take a standard Rust function
fn add(left: i32, right: i32) -> i32 {
  left + right
}

// 2. Convert it into a type-erased `DynamicFunction` using the `IntoFunction` trait
let mut function: DynamicFunction = add.into_function();
// 3. Define your arguments from reflected values
let args: ArgList = ArgList::new().push_owned(2_i32).push_owned(2_i32);
// 4. Call the function with your arguments
let result: Return = function.call(args).unwrap();
// 5. Extract the return value
let value: Box<dyn Reflect> = result.unwrap_owned();
assert_eq!(value.take::<i32>().unwrap(), 4);
```

## Changelog

#### TL;DR

- Added support for function reflection
- Added a new `Function Reflection` example:
ba727898f2/examples/reflection/function_reflection.rs (L1-L157)

#### Details

Added the following items:

- `ArgError` enum
- `ArgId` enum
- `ArgInfo` struct
- `ArgList` struct
- `Arg` enum
- `DynamicFunction` struct
- `FromArg` trait (derived with `derive(Reflect)`)
- `FunctionError` enum
- `FunctionInfo` struct
- `FunctionResult` alias
- `GetOwnership` trait (derived with `derive(Reflect)`)
- `IntoFunction` trait (with blanket implementation)
- `IntoReturn` trait (derived with `derive(Reflect)`)
- `Ownership` enum
- `ReturnInfo` struct
- `Return` enum

---------

Co-authored-by: Periwink <charlesbour@gmail.com>
2024-07-01 13:49:08 +00:00
Aevyrie
a1545dd3a6
Fix compile failure in WASM without wgpu backend (#14081)
# Objective

- When no wgpu backend is selected, there should be a clear explanation.
- Fix a regression in 0.14 when not using default features. I hit this
compile failure when trying to build bevy_framepace for 0.14.0-rc.4
```
error[E0432]: unresolved import `crate::core_3d::DEPTH_TEXTURE_SAMPLING_SUPPORTED`
  --> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/dof/mod.rs:59:19
   |
59 |         Camera3d, DEPTH_TEXTURE_SAMPLING_SUPPORTED,
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `DEPTH_TEXTURE_SAMPLING_SUPPORTED` in `core_3d`
   |
note: found an item that was configured out
  --> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/core_3d/mod.rs:53:11
   |
53 | pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = false;
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: found an item that was configured out
  --> /Users/aevyrie/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_core_pipeline-0.14.0-rc.4/src/core_3d/mod.rs:63:11
   |
63 | pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = true;
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

## Solution

- Ensure that `DEPTH_TEXTURE_SAMPLING_SUPPORTED` is either `true` or
`false`, it shouldn't be completely missing.

## Testing

- Building on WASM without default features, which now seemingly no
longer includes webgl, will panic on startup with a message saying that
no wgpu backend was selected. This is much more helpful than the compile
time failure:
```
No wgpu backend feature that is implemented for the target platform was enabled
```
- I can see an argument for making this a compile time failure, however
the current failure mode is very confusing for novice users, and
provides no clues for how to fix it. If we want this to fail at compile
time, we should do it in a way that fails with a helpful message,
similar to what this PR acheives.
2024-06-30 22:58:43 +00:00
François Mockers
8a7d3ce461
don't put previous skin/morph in the morphed_skinned_mesh_layout (#14065)
# Objective

- Fixes #14059
- `morphed_skinned_mesh_layout` is the same as
`morphed_skinned_motion_mesh_layout` but shouldn't have the skin / morph
from previous frame, as they're used for motion

## Solution

- Remove the extra entries

## Testing

- Run with the glTF file reproducing #14059, it works
2024-06-29 01:03:51 +00:00
Brian Reavis
e69e28fe74
Made Material2dBindGroupId instantiable (#14053)
# Objective / Solution

Make it possible to construct `Material2dBindGroupId` for custom 2D
material pipelines by making the inner field public.

---

The 3D variant (`MaterialBindGroupId`) had this done in
e79b9b62ce
2024-06-29 00:41:15 +00:00
Periwink
6573887d5c
Fix error in AnyOf (#14027)
# Objective

- Fixes a correctness error introduced in
https://github.com/bevyengine/bevy/pull/14013 ...

## Solution

I've been playing around a lot of with the access code and I realized
that I introduced a soundness error when trying to simplify the code.
When we have a `Or<(With<A>, With<B>)>` filter, we cannot call
```
  let mut intermediate = FilteredAccess::default();
  $name::update_component_access($name, &mut intermediate);
  _new_access.append_or(&intermediate);
```
because that's just equivalent to adding the new components as `Or`
clauses.
For example if the existing `filter_sets` was `vec![With<C>]`, we would
then get `vec![With<C>, With<A>, With<B>]` which translates to `A or B
or C`.
Instead what we want is `(A and B) or (A and C)`, so we need to have
each new OR clause compose with the existing access like so:
```
let mut intermediate = _access.clone();
// if we previously had a With<C> in the filter_set, this will become `With<C> AND With<A>`
$name::update_component_access($name, &mut intermediate);
_new_access.append_or(&intermediate);
```

## Testing

- Added a unit test that is broken in main, but passes in this PR
2024-06-27 20:20:50 +00:00
Tamás Kiss
edca8707c8
add PartialEq to Outline (#14055)
# Objective

`sickle_ui` needs `PartialEq` on components to turn them into animatable
style attributes.

## Solution

All properties of Outline is already `PartialEq`, add derive on
`Outline` as well.

## Testing

- used `sickle_ui` to test if it can be made animatable
2024-06-27 20:03:07 +00:00
Patrick Walton
44db8b7fac
Allow phase items not associated with meshes to be binned. (#14029)
As reported in #14004, many third-party plugins, such as Hanabi, enqueue
entities that don't have meshes into render phases. However, the
introduction of indirect mode added a dependency on mesh-specific data,
breaking this workflow. This is because GPU preprocessing requires that
the render phases manage indirect draw parameters, which don't apply to
objects that aren't meshes. The existing code skips over binned entities
that don't have indirect draw parameters, which causes the rendering to
be skipped for such objects.

To support this workflow, this commit adds a new field,
`non_mesh_items`, to `BinnedRenderPhase`. This field contains a simple
list of (bin key, entity) pairs. After drawing batchable and unbatchable
objects, the non-mesh items are drawn one after another. Bevy itself
doesn't enqueue any items into this list; it exists solely for the
application and/or plugins to use.

Additionally, this commit switches the asset ID in the standard bin keys
to be an untyped asset ID rather than that of a mesh. This allows more
flexibility, allowing bins to be keyed off any type of asset.

This patch adds a new example, `custom_phase_item`, which simultaneously
serves to demonstrate how to use this new feature and to act as a
regression test so this doesn't break again.

Fixes #14004.

## Changelog

### Added

* `BinnedRenderPhase` now contains a `non_mesh_items` field for plugins
to add custom items to.
2024-06-27 16:13:03 +00:00
Chris Russell
1baa1a11b7
Add missing StaticSystemParam::queue implementation. (#14051)
# Objective

`StaticSystemParam` should delegate all `SystemParam` methods to the
inner param, but it looks like it was missed when the new `queue()`
method was added in #10839.

## Solution

Implement `StaticSystemParam::queue()` to delegate to the inner param.
2024-06-27 15:47:22 +00:00
Vic
e813326c87
add missing sort_unstable_by_key to QueryIter (#14040)
# Objective

`QueryIter::sort_unstable_by_key` is missing.

## Solution

Add `QueryIter::sort_unstable_by_key`.

## Testing

Added the new method to existing test.

## Changelog

Added `QueryIter::sort_unstable_by_key`.
2024-06-27 15:46:19 +00:00
Arseny Kapoulkine
9148847589
Fix incorrect computation of mips for cluster occlusion lookup (#14042)
The comment was incorrect - we are already looking at the pyramid
texture so we do not need to transform the size in any way. Doing that
resulted in a mip that was too fine to be selected in certain cases,
which resulted in a 2x2 pixel footprint not actually fully covering the
cluster sphere - sometimes this could lead to a non-conservative depth
value being computed which resulted in the cluster being marked as
invisible incorrectly.
2024-06-27 05:57:01 +00:00
Arseny Kapoulkine
4cd188568a
Improve MeshletMesh::from_mesh performance further (#14038)
This change updates meshopt-rs to 0.3 to take advantage of the newly
added sparse simplification mode: by default, simplifier assumes that
the entire mesh is simplified and runs a set of calculations that are
O(vertex count), but in our case we simplify many small mesh subsets
which is inefficient.

Sparse mode instead assumes that the simplified subset is only using a
portion of the vertex buffer, and optimizes accordingly. This changes
the meaning of the error (as it becomes relative to the subset, in our
case a meshlet group); to ensure consistent error selection, we also use
the ErrorAbsolute mode which allows us to operate in mesh coordinate
space.

Additionally, meshopt 0.3 runs optimizeMeshlet automatically as part of
`build_meshlets` so we no longer need to call it ourselves.

This reduces the time to build meshlet representation for Stanford Bunny
mesh from ~1.65s to ~0.45s (3.7x) in optimized builds.
2024-06-27 00:06:22 +00:00
François Mockers
3a04d38832
only run one update per frame drawn (#14023)
# Objective

- Fixes #13965 

## Solution

- Don't run multiple updates for a single frame
2024-06-26 20:23:17 +00:00
Martin Svanberg
0ee9827ba2
Fix typo in CPU adapter warning (#14037)
An annoying typo slipped through in #13780
2024-06-26 18:37:34 +00:00
Al M
57ac8f5211
impl BuildChildrenTransformExt for EntityWorldMut (#14022)
# Objective

Implement `BuildChildrenTransformExt` for `EntityWorldMut`, which is
useful when working directly with a mutable `World` ref.

## Solution

I realize this isn't the most optimal implementation in that it doesn't
reuse the existing entity location for the child, but it is terse and
reuses the existing code. I can address that if needed.

## Testing

I only tested locally. There are no tests for `set_parent_in_place` and
`remove_parent_in_place` currently, but I can add some.

---

## Changelog

`BuildChildrenTransformExt` implemented for `EntityWorldMut`.
2024-06-26 14:59:20 +00:00
Joseph
2b7d54b300
Emit a warning if the result of EntityCommand::with_entity is not used (#14028)
# Objective

When using combinators such as `EntityCommand::with_entity` to build
commands, it can be easy to forget to apply that command, leading to
dead code. In many cases this doesn't even lead to an unused variable
warning, which can make these mistakes difficult to track down

## Solution

Annotate the method with `#[must_use]`

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-26 13:54:55 +00:00
re0312
a3f91a28fc
Refactor check_light_mesh_visibility for performance #2 (#13906)
# Objective

- Second part of #13900 
- based on #13905 

## Solution

- check_dir_light_mesh_visibility defers setting the entity's
`ViewVisibility `so that Bevy can schedule it to run in parallel with
`check_point_light_mesh_visibility`.

- Reduce HashMap lookups for directional light checking as much as
possible

- Use `par_iter `to parallelize the checking process within each system.

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-06-26 12:48:15 +00:00
Joseph
a4c621a127
Use an opaque type for EntityCommand::with_entity (#11210)
# Objective

The trait method `with_entity` is used to add an `EntityCommand` to the
command queue. Currently this method returns `WithEntity<C>` which pairs
a command with an `Entity`. By replacing this explicit type with an
opaque type, implementors can override this default implementation by
returning a custom command or closure that does the same thing with a
lower memory footprint.

# Solution

Return an opaque type from the method. As a bonus this file is now
cleaner without the `WithEntity` boilerplate
2024-06-26 12:47:46 +00:00
Martin Svanberg
0ae7afbcad
Print warning when using llvmpipe (#13780)
# Objective

Numerous people have been confused that Bevy runs slowly, when the
reason is that the `llvmpipe` software rendered is being used.

## Solution

Printing a warning could reduce the confusion.
2024-06-26 12:44:48 +00:00
François Mockers
19d078c609
don't crash without features bevy_pbr, ktx2, zstd (#14020)
# Objective

- Fixes #13728 

## Solution

- add a new feature `smaa_luts`. if enables, it also enables `ktx2` and
`zstd`. if not, it doesn't load the files but use placeholders instead
- adds all the resources needed in the same places that system that uses
them are added.
2024-06-26 03:08:23 +00:00
Periwink
8308ad08a2
AnyOf soundness fix (#14013)
# Objective
Fixes https://github.com/bevyengine/bevy/issues/13993 
PR inspired by https://github.com/bevyengine/bevy/pull/14007 to
accomplish the same thing, but maybe in a clearer fashion.

@Gingeh feel free to take my changes and add them to your PR, I don't
want to steal any credit

---------

Co-authored-by: Gingeh <39150378+Gingeh@users.noreply.github.com>
Co-authored-by: Bob Gardner <rgardner@inworld.ai>
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2024-06-25 23:54:50 +00:00
Alice Cecile
336fddb101
Make default behavior for BackgroundColor and BorderColor more intuitive (#14017)
# Objective

In Bevy 0.13, `BackgroundColor` simply tinted the image of any
`UiImage`. This was confusing: in every other case (e.g. Text), this
added a solid square behind the element. #11165 changed this, but
removed `BackgroundColor` from `ImageBundle` to avoid confusion, since
the semantic meaning had changed.

However, this resulted in a serious UX downgrade / inconsistency, as
this behavior was no longer part of the bundle (unlike for `TextBundle`
or `NodeBundle`), leaving users with a relatively frustrating upgrade
path.

Additionally, adding both `BackgroundColor` and `UiImage` resulted in a
bizarre effect, where the background color was seemingly ignored as it
was covered by a solid white placeholder image.

Fixes #13969.

## Solution

Per @viridia's design:

> - if you don't specify a background color, it's transparent.
> - if you don't specify an image color, it's white (because it's a
multiplier).
> - if you don't specify an image, no image is drawn.
> - if you specify both a background color and an image color, they are
independent.
> - the background color is drawn behind the image (in whatever pixels
are transparent)

As laid out by @benfrankel, this involves:

1. Changing the default `UiImage` to use a transparent texture but a
pure white tint.
2. Adding `UiImage::solid_color` to quickly set placeholder images.
3. Changing the default `BorderColor` and `BackgroundColor` to
transparent.
4. Removing the default overrides for these values in the other assorted
UI bundles.
5. Adding `BackgroundColor` back to `ImageBundle` and `ButtonBundle`.
6. Adding a 1x1 `Image::transparent`, which can be accessed from
`Assets<Image>` via the `TRANSPARENT_IMAGE_HANDLE` constant.

Huge thanks to everyone who helped out with the design in the linked
issue and [the Discord
thread](https://discord.com/channels/691052431525675048/1255209923890118697/1255209999278280844):
this was very much a joint design.

@cart helped me figure out how to set the UiImage's default texture to a
transparent 1x1 image, which is a much nicer fix.

## Testing

I've checked the examples modified by this PR, and the `ui` example as
well just to be sure.

## Migration Guide

- `BackgroundColor` no longer tints the color of images in `ImageBundle`
or `ButtonBundle`. Set `UiImage::color` to tint images instead.
- The default texture for `UiImage` is now a transparent white square.
Use `UiImage::solid_color` to quickly draw debug images.
- The default value for `BackgroundColor` and `BorderColor` is now
transparent. Set the color to white manually to return to previous
behavior.
2024-06-25 21:50:41 +00:00
re0312
dbffb41e50
Remove unnecessary compute for rotation interpolation (#14019)
# Objective

- `slerp` has a built-in short path check. And quaternions are ensured
to be normalized during loading .

## Solution
- remove it 

## Testing
`many_foxes ` in single thread

![image](https://github.com/bevyengine/bevy/assets/45868716/a7e74050-e202-4adb-9179-82a87263c300)
2024-06-25 21:14:37 +00:00
JMS55
d8b45ca136
Fix MeshletMesh material system ordering (#14016)
# Objective
- Fixes #13811 (probably, I lost my test code...)

## Solution
- Turns out that Queue and PrepareAssets are _not_ ordered. We should
probably either rethink our system sets (again), or improve the
documentation here. For reference, I've included the current ordering
below.
- The `prepare_meshlet_meshes_X` systems need to run after
`prepare_assets::<PreparedMaterial<M>>`, and have also been moved to
QueueMeshes.

```rust
schedule.configure_sets(
    (
        ExtractCommands,
        ManageViews,
        Queue,
        PhaseSort,
        Prepare,
        Render,
        Cleanup,
    )
        .chain(),
);

schedule.configure_sets((ExtractCommands, PrepareAssets, Prepare).chain());
schedule.configure_sets(QueueMeshes.in_set(Queue).after(prepare_assets::<GpuMesh>));
schedule.configure_sets(
    (PrepareResources, PrepareResourcesFlush, PrepareBindGroups)
        .chain()
        .in_set(Prepare),
);
```

## Testing
- Ambiguity checker to make sure I don't have ambiguous system ordering
2024-06-25 18:17:52 +00:00
Alice Cecile
52e5ad5da7
Don't show .to_bits in Display impl for Entity (#14011)
# Objective

#12469 changed the `Debug` impl for `Entity`, making sure it's actually
accurate for debugging. To ensure that its can still be readily logged
in error messages and inspectors, this PR added a more concise and
human-friendly `Display` impl.

However, users found this form too verbose: the `to_bits` information
was unhelpful and too long. Fixes #13980.

## Solution

- Don't include `Entity::to_bits` in the `Display` implementation for
`Entity`. This information can readily be accessed and logged for users
who need it.
- Also clean up the implementation of `Display` for `DebugName`,
introduced in https://github.com/bevyengine/bevy/pull/13760, to simply
use the new `Display` impl (since this was the desired format there).

## Testing

I've updated an existing test to verify the output of `Entity::display`.

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-06-25 17:08:24 +00:00
Bob Gardner
4c3b4a445d
Mark events as read during EventReader::par_read (#13836)
# Objective

- Fix issue #13821  

## Solution

- Rewrote the test to ensure that it actually tests the functionality
correctly. Then made the par_read function correctly change the values
of self.reader.last_event_count.

## Testing

- Rewrote the test for par_read to run the system schedule twice,
checking the output each time

---------

Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2024-06-25 15:36:06 +00:00
Sou1gh0st
f51a306b30
feat(bevy_app): expose an API to perform updates for a specific sub-app. (#14009)
# Objective

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

## Solution

- Expose an API to perform updates for a specific sub-app, so we can
avoid mutable borrow the app twice.

## Testing

- I have tested the API by modifying the code in the `many_lights`
example with the following changes:
```rust
impl Plugin for LogVisibleLights {
    fn build(&self, app: &mut App) {
        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
            return;
        };

        render_app.add_systems(Render, print_visible_light_count.in_set(RenderSet::Prepare));
    }

    fn finish(&self, app: &mut App) {
        app.update_sub_app_by_label(RenderApp);
    }
}
```

---

## Changelog
- add the `update_sub_app_by_label` API to `App` and `SubApps`.

---------

Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
2024-06-25 14:04:31 +00:00
Gagnus
1df811e6a5
Add Display implementation to DebugName. (#13760)
# Objective

- When writing "in game" debugging tools, quite often you need the name
of an entity (for example an entity tree). DebugName is the usual way of
doing that.
- A recent change to Entity's Debug implementation meant it was no
longer a minimal {index}v{generation} but instead a more verbose auto
generated Debug.
- This made DebugName's Debug implementation also verbose

## Solution

- I changed DebugName to derive Debug automatically and added a new
(preferred) Display implementation for it which is the preferred name
for an entity. If the entity has a Name component its the contents of
that, otherwise it is {index}v{generation} (though this does not use
Display of the Entity as that is more verbose than this).

## Testing

- I've added a new test in name.rs which tests the Display
implementation for DebugName by using to_string.

---

## Migration Guide

- In code which uses DebugName you should now use the Display
implementation rather than the Debug implementation (ie {} instead of
{:?} if you were printing it out).

---------

Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Andres O. Vela <andresovela@users.noreply.github.com>
2024-06-25 12:58:53 +00:00
Wuketuke
2d30ae437c
improved error message when forgetting to call system apply function … (#13975)
fixes #13944
I literally just added `Did you forget to call SystemState::apply?` to
the error message. I tested it with the code snipped from the Issue and
yeah it works
2024-06-25 12:27:15 +00:00
Caleb Yates
82fd3df719
Document use of NO_COLOR in LogPlugin (#13984)
# Objective
Fixes #13982

## Solution
~~Adds a new field to `bevy_log::LogPlugin`: `ansi: bool`~~
Documents the use of `std::env::set_var("NO_COLOR", "1");` to disable
colour output in terminals.

## Testing
Yes, all tests passed when I ran `cargo run -p ci -- test` and `cargo
run -p ci -- lints`

I have only tested the code on my Mac, though I doubt this change would
have any affect on other platforms.

---
2024-06-24 21:04:55 +00:00
Michael "Scott" McBee
d48ebdf641
Have WindowPosition::Centered take scale_factor_override into account (#13949)
# Objective

Fixes #8916 

My game has a low resolution pixel art style, and I use
`.with_scale_factor_override()` to make the window larger.
`WindowPosition::Centered` doesn't work for me.

## Solution

If `scale_factor_override` is set, use that over `monitor.scale_factor`

## Testing

Tested on Windows 11 with an Nvidia GPU:

### Main

![image](https://github.com/bevyengine/bevy/assets/3324533/5f9ae90e-b65a-48d9-b601-117df8f08a28)

### This PR

![image](https://github.com/bevyengine/bevy/assets/3324533/cd860611-7b6a-4ae5-b690-28d9ba8ea6ad)
2024-06-24 20:56:46 +00:00
Christian Hughes
3a82d6784b
Add a test asserting that reflected cloning a Handle increments strong count (#13961)
# Objective

Closes #5943. Seems like Assets v2 solved this one.

## Solution

Added a test to confirm that using `Reflect::clone_value` and then
`FromReflect::from_reflect` on a `Handle<T>` both increment the strong
count.

## Testing

A new test was added to confirm behavior.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-06-24 20:54:54 +00:00
Tamás Kiss
87fa69bd7e
fix panic: invalid SlotMap key used (#13990)
# Objective

Tight, in-frame generation, re-parenting, despawning, etc., UI
operations could sometime lead taffy to panic (invalid SlotMap key used)
when an entity with an invalid state later despawned.

Fixes #12403 

## Solution

Move the `remove_entities` call after children updates.

## Testing

`sickle_ui` had a case that always caused the panic. Tested before this
change, after this change, and before the change again to make sure the
error is there without the fix. The fix worked. Test steps and used
commit described in issue #12403.

I have also ran every bevy UI example, though none of them deal with
entity re-parenting or removal. No regression detected on them.

Tested on Windows only.
2024-06-24 20:47:44 +00:00
JMS55
158ccc6d6a
Fix meshlet interactions with regular shading passes (#13816)
* Fixes https://github.com/bevyengine/bevy/issues/13813
* Fixes https://github.com/bevyengine/bevy/issues/13810

Tested a combined scene with both regular meshes and meshlet meshes
with:
* Regular forward setup
* Forward + normal/motion vector prepasses
* Deferred (with depth prepass since that's required) 
* Deferred + depth/normal/motion vector prepasses

Still broken:
* Using meshlet meshes rendering in deferred and regular meshes
rendering in forward + depth/normal prepass. I don't know how to fix
this at the moment, so for now I've just add instructions to not mix
them.
2024-06-21 19:06:08 +00:00
Carter Anderson
0daa6c510b
Make Observer::with_event (and other variants) unsafe (#13954)
# Objective

`with_event` will result in unsafe casting of event data of the given
type to the type expected by the Observer system. This is inherently
unsafe.

## Solution

Flag `Observer::with_event` and `ObserverDescriptor::with_events` as
unsafe. This will not affect normal workflows as `with_event` is
intended for very specific (largely internal) use cases.

This _should_ be backported to 0.14 before release.

---

## Changelog

- `Observer::with_event` is now unsafe.
- Rename `ObserverDescriptor::with_triggers` to
`ObserverDescriptor::with_events` and make it unsafe.
2024-06-21 18:31:01 +00:00
François Mockers
841df150cc
apply window scale to window size when creating it (#13967)
# Objective

- Fixes #13702
- When creating a new window, its scale was changed to match the one
returned by winit, but its size was not which resulted in an incorrect
size until the event with the correct size was received, at least 1
frame later

## Solution

- Apply the window scale to its size when creating it
2024-06-21 18:04:57 +00:00
Shane Celis
e72f4ef9e9
bug: Don't panic. Warn on missing file_watcher path. (new branch) (#13902)
I updated my 'main' branch, which accidentally closed the original PR
#13747. I'm reopening the this from an actual branch on my repo like I
should have done in the first place. Here's the original info from the
first PR:

* * *

# Problem

The `file_watcher` feature panics if the file_watcher's path "assets" is
not present. I stumbled upon this behavior when I was actually testing
against `embedded_watcher`. I had no "assets" directory and didn't need
one for [my project](https://github.com/shanecelis/bevy_plane_cut).

```text
$ cargo run --example simple; # Runs fine.
$ cargo run --example simple --feature embedded_watcher; # Panics
thread 'main' panicked at /Users/shane/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_asset-0.14.0-rc.2/src/io/source.rs:503:21:
Failed to create file watcher from path "assets", Error { kind: PathNotFound, paths: ["/Users/shane/Projects/bevy_plane_cut/assets"] }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

# Opinion

If a project runs without panicing, then adding the `file_watcher`
feature shouldn't cause it to panic.

# Suggested Solution

This PR suggests if the "assets" path does not exist, emit a warning
stating that the file watcher could not be created and why. All other
errors will be treated as before with a panic and a message.

```text
$ cargo run --example simple --feature embedded_watcher; # Panics
2024-06-08T08:55:11.385249Z  WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-08T08:55:11.385291Z  WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider enabling the `file_watcher` feature.
```

The second warning is new and I'd prefer it didn't emit under this
condition, but I'll wait to see whether this is actually regarded as a
bug.

# Testing

No tests added. Compiled against my project and it demonstrated the
suggested behavior.

* * *

I changed the second warning to the following when the `file_watcher`
feature is present. When it's not present, it uses the same warning as
before.

```
024-06-09T01:22:16.880619Z  WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-09T01:22:16.880660Z  WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider adding an "assets" directory.
```
2024-06-21 13:10:57 +00:00
Rob Parrett
e46e246581
Fix a few "repeated word" typos (#13955)
# Objective

Stumbled on one of these and went digging for more

## Solution

```diff
- word word
+ word
```
2024-06-20 21:35:20 +00:00
Octorine
dcb191bb18
Updated descriptions for some geometric primitives to include more detail (#13937)
This is an attempt to address issue #13725, which was about the
geometric primitives in the bevy_math crate lacking some detail in the
docs.

# Objective

Fixes #13725

## Solution

Added details to the docstrings. Mostly this consisted of specifying
that the primitives are centered on the origin, or describing how
they're defined (e.g., a circle is the set of all points some distance
from the origin).

## Testing

No testing, since the only changes were to docs.
2024-06-20 12:16:27 +00:00
charlotte
8635a0f916
Correctly check physical size when updating winit (#13942)
Fixes #13701

After `winit` upgrade to `0.31`, windows were no longer correctly
resizing. This appears to just have been a simple mistake, where the new
physical size was being sourced from the `winit` window rather than on
the incoming `Window` component.

## Testing

Tested on macOS, but I'm curious whether this was also broken on other
platforms.
2024-06-20 11:22:47 +00:00
Alessio Marchi
2f9c42bb33
feat: add insert_after and insert_startup_before (#13941)
# Objective

Fixes #13866 

## Solution

Add `insert_before` in **FixedMainScheduleOrder** and
**MainScheduleOrder**, add `insert_startup_before` in
**MainScheduleOrder**, applying the same logic as `insert_after`, except
for parameters naming and insertion index.
2024-06-20 01:02:16 +00:00
Arseny Kapoulkine
6eec73a9a5
Make meshlet processing deterministic (#13913)
This is a followup to https://github.com/bevyengine/bevy/pull/13904
based on the discussion there, and switches two HashMaps that used
meshlet ids as keys to Vec.

In addition to a small further performance boost for `from_mesh` (1.66s
=> 1.60s), this makes processing deterministic modulo threading issues
wrt CRT rand described in the linked PR. This is valuable for debugging,
as you can visually or programmatically inspect the meshlet distribution
before/after making changes that should not change the output, whereas
previously every asset rebuild would change the meshlet structure.

Tested with https://github.com/bevyengine/bevy/pull/13431; after this
change, the visual output of meshlets is consistent between asset
rebuilds, and the MD5 of the output GLB file does not change either,
which was not the case before.
2024-06-20 00:58:43 +00:00
NiseVoid
38c8dc27c7
Use u32 for resolution/subdivision in primitive meshing (#13930)
# Objective

- Make primitive meshing behavior consisten across platforms
- Avoid using sizes bigger than `u32` since these aren't even supported
for meshes

## Solution

- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields

---

## Changelog

- Change resolutions in primitive mesh builders from `usize` to `u32`

## Migration Guide

- All primitive mesh builders now take `u32` instead of `usize` for
their resolution/subdivision/segment counts
2024-06-20 00:58:21 +00:00
MiniaczQ
31af724944
Move StateTransitionSteps registration to states plugin (#13939)
# Objective

Fixes #13920

## Solution

As described in the issue.

## Testing

Moved a custom transition plugin in example before any of the app-state
methods.
2024-06-20 00:57:40 +00:00
Christian Hughes
ee2487a6e2
Change World::inspect_entity to return an Iterator instead of Vec (#13934)
# Objective

Fixes #13933.

## Solution

Changed the return type.

## Testing

Fixed and reused the pre-existing tests for `inspect_entity`.

---

## Migration Guide

- `World::inspect_entity` now returns an `Iterator` instead of a `Vec`.
If you need a `Vec`, immediately collect the iterator:
`world.inspect_entity(entity).collect<Vec<_>>()`
2024-06-19 21:06:35 +00:00
Ben Frankel
e34ecf2f86
Fix typo in ComponentId docs: of -> or (#13932)
# Objective

Fix a typo. Single-character PR :)
2024-06-19 18:51:47 +00:00
Alessio Marchi
5bab161386
docs(bevy_state): fix broken links in init_state and insert_state (#13929)
# Objective

Fixes #13845 

## Solution

Fix inline docs links inside `init_state` and `insert_state`. 

## Testing

- Did you test these changes? If so, how?
Manually checked on `cargo doc` and  `rust-analyzer lsp`.
2024-06-19 17:38:00 +00:00
Shane Celis
6df0e9b37d
bug: Fix 9-slice textures with asymmetric borders. (#13921)
# Objective

Fix a 9-slice asymmetric border issue that
[QueenOfSquiggles](https://blobfox.coffee/@queenofsquiggles/112639035165575222)
found. Here's the behavior before:

<img width="340" alt="the-bug"
src="https://github.com/bevyengine/bevy/assets/54390/81ff1847-b2ea-4578-9fd0-af6ee96c5438">

## Solution

Here's the behavior with the fix.

<img width="327" alt="the-fix"
src="https://github.com/bevyengine/bevy/assets/54390/33a4e3f0-b6a8-448e-9654-1197218ea11d">


## Testing

I used QueenOfSquiggles
[repo](https://github.com/QueenOfSquiggles/my-bevy-learning-project) to
exercise the code. I manually went through a number of variations of the
border and caught a few other issues after the first pass. I added some
code to create random borders and though they often looked funny there
weren't any gaps like before.

### Unit Tests

I did add some tests to `slicer.rs` mostly as an exploratory programming
exercise. So they currently act as a limited, incomplete,
"golden-file"-ish approach. Perhaps they're not worth keeping.

In order to write the tests, I did add a `PartialEq` derive for
`TextureSlice`.

I only tested these changes on macOS.

---

## Changelog

Make 9-slice textures work with asymmetric borders.
2024-06-19 17:30:18 +00:00
NiseVoid
eddb006a8a
Use u32 for all resolution/subdivision fields in bevy_gizmos (#13927)
# Objective

- Make gizmos behavior consistent across platforms

## Solution

- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields

---

## Changelog

- Change resolutions in gizmos from `usize` to  `u32`

## Migration Guide

- All gizmos now take `u32` instead of `usize` for their
resolution/subdivision/segment counts
2024-06-19 17:28:10 +00:00
NiseVoid
524dce7505
Use a well defined type for sides in RegularPolygon (#13837)
# Objective

- Primitives should not use poorly defined types like `usize`,
especially since they are serializable

## Solution

- Use `u32` instead of `usize`
- The generic array types do not need to be changed because this size is
not actually stored or serialized anywhere

---

## Migration Guide

- `RegularPolygon` now uses `u32` instead of `usize` for the number of
sides
2024-06-19 15:43:40 +00:00
Luc
45a5f66c9d
Improve error handling for log filter (#13897)
# Objective
This PR aims to improve error handling for log filters.

Closes #13850

## Solution
I changed the parsing of LogPlugin its filter to lossy, so that it
prints the directives with an error but does not skip them. I decided on
letting it gracefully handle the error instead of panicking to be
consistent with the parsing from an environment variable that it tries
to do before parsing it from the LogPlugin filter.

If the user decides to specify the filter by an environment variable, it
would silently fail and default to the LogPlugin filter value. It now
prints an error before defaulting to the LogPlugin filter value.

Unfortunately, I could not try and loosely set the filter from the
environment variable because the `tracing-subscriber` module does not
expose the function it uses to get the environment variable, and I would
rather not copy its code. We may want to check if the maintainers are
open to exposing the method.


## Testing
Consider the following bevy app, where the second of the 3 filters is
invalid:
```
use bevy::{log::LogPlugin, prelude::*};

fn main() {
    App::new().add_plugins(DefaultPlugins
        .set(LogPlugin {
            filter: "wgpu=error,my_package=invalid_log_level,naga=warn".into(),
            ..default()
        })
    ).run();
}
```
In the previous situation, it would panic with a non-descriptive error:
"called `Result::unwrap()` on an `Err` value: ParseError { kind:
Other(None) }", while only 1 of the 3 filters is invalid. When running
`cargo run`, it will now use the two valid filters and print an error on
the invalid filter.
> ignoring `my_package=invalid_log_level`: invalid filter directive

This error comes from `tracing-subscriber` and cannot be altered as far
as I can see.

To test setting the log filter through an environment variable, you can
use `RUST_LOG="wgpu=error,my_package=invalid_log_level,naga=warn" cargo
run` to run your app. In the previous situation it would silently fail
and use the LogPlugin filter. It will now print an error before using
the LogPlugin filter.
> LogPlugin failed to parse filter from env: invalid filter directive


## Changelog
- Added warning when using invalid filter in the RUST_LOG environment
variable
- Prevent the app from panicking when setting an invalid LogPlugin
filter

---------

Co-authored-by: Luc Drenth <luc.drenth@ing.com>
2024-06-19 13:46:03 +00:00
Yoh Deadfall
0a003eaa98
Fixed a link to Blender's mikktspace docs (#13924)
# Objective

- The old link doesn't work since the page was moved to the archive.
2024-06-19 12:37:10 +00:00
Jenya705
6b2d4834e9
IntoSystemConfigs::chain_ignore_deferred's return type fix (#13919)
# Objective

Fixes #13917 

## Solution

Changed `IntoSystemSetConfigs::chain_ignore_deferred`'s return type from
`SystemConfigs` to `SystemSetConfigs`

## Testing

Tried to run the `ecs_guide` example, where `chain` method is replaced
by `chain_ignore_deferred` method

---
2024-06-18 22:21:58 +00:00
dav-wolff
1b0475f234
Fix typo in Query::single_mut docs (#13916)
# Objective

- Fix a typo in documentation for `Query::single_mut`

## Solution

- Change `item` to `items`

## Testing

- I built the documentation and it looked fine.
- Since this only affects a doc comment, no further testing should be
necessary.

---

## Changelog

> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.

- Fixed a typo in the documentation for Query.
2024-06-18 19:55:37 +00:00
BD103
c37e81b34a
Specify units in AmbientLight::brightness docs (#13297)
# Objective

- Fixes #11933.
- Related: #12280.

## Solution

- Specify that, after applying `AmbientLight`, the resulting units are
in cd/m^2.
- This is based on [@fintelia's
comment](https://github.com/bevyengine/bevy/issues/11933#issuecomment-1995427587),
and will need to be verified.

---

## Changelog

- Specified units for `AmbientLight`'s `brightness` field.
2024-06-18 11:20:10 +00:00
Arseny Kapoulkine
001cc147c6
Improve MeshletMesh::from_mesh performance (#13904)
This change reworks `find_connected_meshlets` to scale more linearly
with the mesh size, which significantly reduces the cost of building
meshlet representations. As a small extra complexity reduction, it moves
`simplify_scale` call out of the loop so that it's called once (it only
depends on the vertex data => is safe to cache).

The new implementation of connectivity analysis builds edge=>meshlet
list data structure, which allows us to only iterate through
`tuple_combinations` of a (usually) small list. There is still some
redundancy as if two meshlets share two edges, they will be represented
in the meshlet lists twice, but it's overall much faster.

Since the hash traversal is non-deterministic, to keep this part of the
algorithm deterministic for reproducible results we sort the output
adjacency lists.

Overall this reduces the time to process bunny mesh from ~4.2s to ~1.7s
when using release; in unoptimized builds the delta is even more
significant.

This was tested by using https://github.com/bevyengine/bevy/pull/13431
and:

a) comparing the result of `find_connected_meshlets` using old and new
code; they are equal in all steps of the clustering process
b) comparing the rendered result of the old code vs new code *after*
making the rest of the algorithm deterministic: right now the loop that
iterates through the result of `group_meshlets()` call executes in
different order between program runs. This is orthogonal to this change
and can be fixed separately.

Note: a future change can shrink the processing time further from ~1.7s
to ~0.4s with a small diff but that requires an update to meshopt crate
which is pending in https://github.com/gwihlidal/meshopt-rs/pull/42.
This change is independent.
2024-06-18 08:29:17 +00:00
re0312
91cd84fea7
Refactor check_light_mesh_visibility for performance #1 (#13905)
# Objective

- first part of #13900 

## Solution

- split `check_light_mesh_visibility `into
`check_dir_light_mesh_visibility `and
`check_point_light_mesh_visibility` for better review
2024-06-18 03:22:54 +00:00
re0312
41ad4e98de
Reuse VisibleEntities in check_light_mesh_visibilty (#13894)
# Objective

- After #12582 , Bevy split visibleEntities into a TypeIdMap for
different types of entities, but the behavior in
`check_light_mesh_visibility `simply calls HashMap::clear(), which will
reallocate memory every frame.


## Testing
cargo run --release --example many_cubes --features bevy/trace_tracy --
--shadows
~10% win in `check_light_mesh_visibilty`

![image](https://github.com/bevyengine/bevy/assets/45868716/1bf4deef-bab2-4e5f-9f60-bea8b7e33e3e)
2024-06-17 22:37:50 +00:00
Gino Valente
53910e07ae
bevy_reflect: Improve reflection serialization error messages (#13867)
# Objective

The error messages that appear when a value cannot be serialized or
deserialized via reflection could be slightly improved.

When one of these operations fails, some users are confused about how to
resolve the issue. I've spoken with a few who didn't know they could
register `ReflectSerialize` themselves. We should try to clarify this to
some degree in the error messages.

## Solution

Add some more detail to the error messages.

For example, replacing this:

```
Type 'core::ops::RangeInclusive<f32>' did not register ReflectSerialize
```

with this:

```
Type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`
```

I also added a separate error message if the type was not registered in
the type registry at all:

```
Type `core::ops::RangeInclusive<f32>` is not registered in the type registry
```

## Testing

You can test locally by running:

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

---

## Changelog

- Added error message for missing type registration when serializing
reflect data
- Changed error message for missing `ReflectSerialize` registration when
serializing reflect data
- Changed error message for missing `ReflectDeserialize` registration
when deserializing reflect data
2024-06-17 18:13:46 +00:00
Jan Hohenheim
6273227e09
Fix lints introduced in Rust beta 1.80 (#13899)
Resolves #13895

Mostly just involves being more explicit about which parts of the docs
belong to a list and which begin a new paragraph.
- found a few docs that were malformed because of exactly this, so I
fixed that by introducing a paragraph
- added indentation to nearly all multiline lists
- fixed a few minor typos
- added `#[allow(dead_code)]` to types that are needed to test
annotations but are never constructed
([here](https://github.com/bevyengine/bevy/pull/13899/files#diff-b02b63604e569c8577c491e7a2030d456886d8f6716eeccd46b11df8aac75dafR1514)
and
[here](https://github.com/bevyengine/bevy/pull/13899/files#diff-b02b63604e569c8577c491e7a2030d456886d8f6716eeccd46b11df8aac75dafR1523))
- verified that  `cargo +beta run -p ci -- lints` passes
- verified that `cargo +beta run -p ci -- test` passes
2024-06-17 17:22:01 +00:00
Ľubomír Kurčák
4b3246af40
Add cross gizmos (#13883)
# Objective

Add `cross` and `cross_2d` gizmos in accordance with #13868.

## Solution

Extend `Gizmos` to provide these functions.

## Testing

Tested in `2d_gizmos` and `3d_gizmos` examples, and external projects.


![image](https://github.com/bevyengine/bevy/assets/29227697/d13067e1-d7eb-46c5-9b73-6c2d70417889)


![image](https://github.com/bevyengine/bevy/assets/29227697/0a8eba48-fbb3-4b3e-abe1-4e250222f94b)
2024-06-17 15:45:32 +00:00
long_long_float
47f58ac6c5
Fix parameter name of all_tuples's document (#13896)
# Objective

I got little confused by the document of `all_tuples!` because type
names of the parameter `T` and extracted names `Pn` are difference.

## Solution

I fixed type names of the document.
2024-06-17 15:17:24 +00:00
James O'Brien
335dcf96a2
Update observer archetype flags for sparse components (#13886)
# Objective

- Fixes #13885 

## Solution

- Update the flags correctly on archetype creation

## Testing

- Added `observer_order_insert_remove_sparse` to catch regressions.
2024-06-17 15:15:30 +00:00
Josh Matthews
8626ad05bc
Update accesskit and accesskit_winit (#13841)
Updates the requirements on
[accesskit](https://github.com/AccessKit/accesskit) to permit the latest
version.
- [Release notes](https://github.com/AccessKit/accesskit/releases)
-
[Changelog](https://github.com/AccessKit/accesskit/blob/main/release-please-config.json)
-
[Commits](https://github.com/AccessKit/accesskit/compare/accesskit-v0.14.0...accesskit-v0.15.0)

---
updated-dependencies:
- dependency-name: accesskit dependency-type: direct:production ...

Adopted from #13787.

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-17 15:08:53 +00:00
Mincong Lu
c75610e2b2
Made some things in bevy_render Debug. (#13830)
# Objective

Some items in `bevy_render` do not implement `Debug`.

## Solution

Made them derive `Debug`.
2024-06-17 15:04:20 +00:00
Brezak
16e02e1889
Use a unstable sort to sort component ids in bevy_ecs (#13789)
# Objective

While writing code for the `bevy_ecs` I noticed we were using a
unnecessarily stable sort to sort component ids

## Solution

- Sort component ids with a unstable sort
- Comb the bevy_ecs crate for any other obvious inefficiencies.
- Don't clone component vectors when inserting an archetype.

## Testing

I ran `cargo test -p bevy_ecs`. Everything else I leave to CI.

## Profiling

I measured about a 1% speed increase when spawning entities directly
into a world. Since the difference is so small (and might just be noise)
I didn't bother to figure out which of change if any made the biggest
difference.
<details>
<summary> Tracy data </summary>
Yellow is this PR. Red is the commit I branched from.


![image](https://github.com/bevyengine/bevy/assets/59848927/f1a5c95d-a882-4dfb-ac07-dd2922273b91)

</details>

<details>
<summary>Methodology</summary>
I created a system that spawn a 1000 entities each with the same 30
components each frame, and then I measured it's run time. The unusually
high number of components was chosen because the standard library [will
use a insertion sort for slices under 20
elements](0de24a5177/library/core/src/slice/sort.rs (L1048-L1049)).
This holds for both stable and unstable sorts.
</details>
2024-06-17 14:56:19 +00:00
hut
92ac77867d
Fix phantom key presses in winit on focus change (#13299) (#13696)
# Objective

Fixes #13299

On Linux/X11, changing focus into a winit window will produce winit
KeyboardInput events with a "is_synthetic=true" flag that are not
intended to be used. Bevy erroneously passes them on to the user,
resulting in phantom key presses.

## Solution

This patch properly filters out winit KeyboardInput events with
"is_synthetic=true".

For example, pressing Alt+Tab to focus a bevy winit window results in a
permanently stuck Tab key until the user presses Tab once again to
produce a winit KeyboardInput release event. The Tab key press event
that causes this problem is "synthetic", should not be used according to
the winit devs, and simply ignoring it fixes this problem.

Synthetic key **releases** are still evaluated though, as they are
essential for correct release key handling. For example, if the user
binds the key combination Alt+1 to the action "move the window to
workspace 1", places the bevy game in workspace 2, focuses the game and
presses Alt+1, then the key release event for the "1" key will be
synthetic. If we would filter out all synthetic keys, the bevy game
would think that the 1 key remains pressed forever, until the user
manually presses+releases the key again inside bevy.

Reference:
https://docs.rs/winit/0.30.0/winit/event/enum.WindowEvent.html#variant.KeyboardInput.field.is_synthetic
Relevant discussion: https://github.com/rust-windowing/winit/issues/3543

## Testing

Tested with the "keyboard_input_events" example. Entering/exiting the
window with various keys, as well as changing its workspace, produces
the correct press/release events.
2024-06-17 14:49:16 +00:00
amy universe
836b6c4409
fix typo (#13880)
# Objective

"wtate" an off-by-one typo in the winit_config.rs file

## Solution

"state"
2024-06-16 18:59:51 +00:00
Kristoffer Søholm
cde610577d
Make time_system public (#13879)
# Objective

If `time_system` isn't public you cannot order systems relative to it in
the `TimeSystem` set.

## Solution

Make it public
2024-06-16 18:07:41 +00:00
MiniaczQ
90894a1910
Warn about missing StatesPlugin when installing states (#13877)
# Objective

- Fixes #13874

## Solution

- Confirm that the `StatesPlugin` is installed when trying to add
states.
- Skipped for state scoped entities, since those will warn about missing
states.
2024-06-16 17:36:24 +00:00
Lee-Orr
f69117331b
remove inaccurate warning from in_state (#13862)
# Objective
Fixes #13854

## Solution
Removed the inaccurate warning. This was done for a few reasons:

- States not existing is now a valid "state" (for lack of a better term)
- Other run conditions don't provide an equivalent warning
2024-06-16 16:06:45 +00:00
Torstein Grindvik
8b25ef3328
Allow bevy_color use without bevy_reflect support (#13870)
# Objective

Allow the use of color definitions from Bevy in other contexts than pure
Bevy apps, e.g. outside ECS use.
In those cases it's nice to not have more dependencies than you need.

## Solution

Hide use of reflection behind a feature flag.
Defaults to on.

## Points to consider

1. This was straightforward _except_ for the
`crates/bevy_color/src/lib.rs` change where I removed `Reflect` as a
bound. That is awkward to have feature gated since features should be
additive. If the bound was added as part of the feature flag, the result
would be _more_ restrictive, and _disable_ impls which did not have the
impl. On the other hand having the reflect bound there unconditionally
would defeat the purpose of the PR. I opted to remove the bound since it
seems overly restrictive anyway.
2. It's possible to hide `encase` and `bytemuck` behind the new feature
flag too (or a separate one). I'm thinking if `bevy-support` is not
desired then it's unlikely that the user has need of those.

---------

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-06-16 15:47:30 +00:00
François Mockers
d8f42608f9
text position: use size instead of bounds (#13858)
# Objective

- #13846 introduced a bug where text not bound was not displayed

## Solution

- bounds are infinite
- use computed size instead, that already should be using the available
bounds
2024-06-16 15:07:31 +00:00
Miles Silberling-Cook
aaccbe88aa
Upstream CorePlugin from bevy_mod_picking (#13677)
# Objective

This is the first of a series of PRs intended to begin the upstreaming
process for `bevy_mod_picking`. The purpose of this PR is to:
+ Create the new `bevy_picking` crate
+ Upstream `CorePlugin` as `PickingPlugin`
+ Upstream the core pointer and backend abstractions.

This code has been ported verbatim from the corresponding files in
[bevy_picking_core](https://github.com/aevyrie/bevy_mod_picking/tree/main/crates/bevy_picking_core/src)
with a few tiny naming and docs tweaks.

The work here is only an initial foothold to get the up-streaming
process started in earnest. We can do refactoring and improvements once
this is in-tree.

---------

Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-15 11:59:57 +00:00
James O'Brien
eb3c81374a
Generalised ECS reactivity with Observers (#10839)
# Objective

- Provide an expressive way to register dynamic behavior in response to
ECS changes that is consistent with existing bevy types and traits as to
provide a smooth user experience.
- Provide a mechanism for immediate changes in response to events during
command application in order to facilitate improved query caching on the
path to relations.

## Solution

- A new fundamental ECS construct, the `Observer`; inspired by flec's
observers but adapted to better fit bevy's access patterns and rust's
type system.

---

## Examples
There are 3 main ways to register observers. The first is a "component
observer" that looks like this:
```rust
world.observe(|trigger: Trigger<OnAdd, Transform>, query: Query<&Transform>| {
    let transform = query.get(trigger.entity()).unwrap();
});
```
The above code will spawn a new entity representing the observer that
will run it's callback whenever the `Transform` component is added to an
entity. This is a system-like function that supports dependency
injection for all the standard bevy types: `Query`, `Res`, `Commands`
etc. It also has a `Trigger` parameter that provides information about
the trigger such as the target entity, and the event being triggered.
Importantly these systems run during command application which is key
for their future use to keep ECS internals up to date. There are similar
events for `OnInsert` and `OnRemove`, and this will be expanded with
things such as `ArchetypeCreated`, `TableEmpty` etc. in follow up PRs.

Another way to register an observer is an "entity observer" that looks
like this:
```rust
world.entity_mut(entity).observe(|trigger: Trigger<Resize>| {
    // ...
});
```
Entity observers run whenever an event of their type is triggered
targeting that specific entity. This type of observer will de-spawn
itself if the entity (or entities) it is observing is ever de-spawned so
as to not leave dangling observers.

Entity observers can also be spawned from deferred contexts such as
other observers, systems, or hooks using commands:
```rust
commands.entity(entity).observe(|trigger: Trigger<Resize>| {
    // ...
});
```

Observers are not limited to in built event types, they can be used with
any type that implements `Event` (which has been extended to implement
Component). This means events can also carry data:

```rust
#[derive(Event)]
struct Resize { x: u32, y: u32 }

commands.entity(entity).observe(|trigger: Trigger<Resize>, query: Query<&mut Size>| {
    let event = trigger.event();
    // ...
});

// Will trigger the observer when commands are applied.
commands.trigger_targets(Resize { x: 10, y: 10 }, entity);
```

You can also trigger events that target more than one entity at a time:

```rust
commands.trigger_targets(Resize { x: 10, y: 10 }, [e1, e2]);
```

Additionally, Observers don't _need_ entity targets:

```rust
app.observe(|trigger: Trigger<Quit>| {
})

commands.trigger(Quit);
```

In these cases, `trigger.entity()` will be a placeholder.

Observers are actually just normal entities with an `ObserverState` and
`Observer` component! The `observe()` functions above are just shorthand
for:

```rust
world.spawn(Observer::new(|trigger: Trigger<Resize>| {});
```

This will spawn the `Observer` system and use an `on_add` hook to add
the `ObserverState` component.

Dynamic components and trigger types are also fully supported allowing
for runtime defined trigger types.

## Possible Follow-ups
1. Deprecate `RemovedComponents`, observers should fulfill all use cases
while being more flexible and performant.
2. Queries as entities: Swap queries to entities and begin using
observers listening to archetype creation triggers to keep their caches
in sync, this allows unification of `ObserverState` and `QueryState` as
well as unlocking several API improvements for `Query` and the
management of `QueryState`.
3. Trigger bubbling: For some UI use cases in particular users are
likely to want some form of bubbling for entity observers, this is
trivial to implement naively but ideally this includes an acceleration
structure to cache hierarchy traversals.
4. All kinds of other in-built trigger types.
5. Optimization; in order to not bloat the complexity of the PR I have
kept the implementation straightforward, there are several areas where
performance can be improved. The focus for this PR is to get the
behavior implemented and not incur a performance cost for users who
don't use observers.

I am leaving each of these to follow up PR's in order to keep each of
them reviewable as this already includes significant changes.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-06-15 01:33:26 +00:00
MiniaczQ
1a1b22ede8
Restore overwrite capabilities of insert_state (#13848)
# Objective

- Fixes #13844
- Warn user when initializing state multiple times

## Solution

- `insert_state` will overwrite previously initialized state value,
reset transition events and re-insert it's own transition event.
- `init_state`, `add_sub_state`, `add_computed_state` are idempotent, so
calling them multiple times will emit a warning.

## Testing

- 2 tests confirming overwrite works.
- Given the example from #13844
```rs
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_state(AppState::A)
        .insert_state(AppState::B)
        .add_systems(OnEnter(AppState::A), setup_a)
        .add_systems(OnEnter(AppState::B), setup_b)
        .add_systems(OnExit(AppState::A), cleanup_a)
        .add_systems(OnExit(AppState::B), cleanup_b)
        .run();
}

#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
enum AppState {
    A,
    B,
}

fn setup_a() {
    info!("setting up A");
}

fn setup_b() {
    info!("setting up B");
}

fn cleanup_a() {
    info!("cleaning up A");
}

fn cleanup_b() {
    info!("cleaning up B");
}
```

We get the following result:
```
INFO states: setting up B
```
which matches our expectations.
2024-06-14 22:22:59 +00:00
Kristoffer Søholm
1395e3672c
Fix is_plugin_added::<Self>() being true during build (#13817)
# Objective

Fixes #13815 

## Solution

Move insertion of the plugin name to after build is called.

## Testing

I added a regression test

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-06-14 19:37:03 +00:00
robtfm
01971f210e
fix non-exact text h-alignment (#13846)
# Objective

when a parent container is auto-sized, text alignments `Center` and
`Right` don't align to the center and right properly. fix it

## Solution

ab_glyph positions return +/- values from an anchor point. we currently
transform them to positive values from the min-x of the glyphs, and then
offset from the left of the bounds. instead, we can keep the negative
values as ab_glyph intended and offset from the left/middle/right of the
bounds as appropriate.

## Testing

texts with align left, center, right, all contained in the purple boxes:
before (0.14.0-rc.2):
![Screenshot 2024-06-14
165456](https://github.com/bevyengine/bevy/assets/50659922/90fb73b0-d8bd-4ae8-abf3-7106eafc93ba)

after:

![Screenshot 2024-06-14
164449](https://github.com/bevyengine/bevy/assets/50659922/0a75ff09-b51d-4fbe-a491-b655a145c08b)

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

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

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());

    for (left, justify) in [
        (100.0, JustifyText::Left),
        (500.0, JustifyText::Center),
        (900.0, JustifyText::Right),
    ] {
        commands
        // container
        .spawn(NodeBundle {
            style: Style {
                flex_direction: FlexDirection::Column,
                position_type: PositionType::Absolute,
                left: Val::Px(left),
                top: Val::Px(100.0),
                width: Val::Px(300.0),
                ..Default::default()
            },
            ..Default::default()
        })
        .with_children(|commands| {
            commands.spawn(NodeBundle{
                style: Style {
                    flex_direction: FlexDirection::Row,
                    height: Val::Px(75.0),
                    ..Default::default()
                },
                background_color: Color::srgb(1.0, 0.0, 1.0).into(),
                ..Default::default()
            }).with_children(|commands| {
                // a div that reduces the available size
                commands.spawn(NodeBundle {
                    style: Style {
                        width: Val::Px(75.0),
                        ..Default::default()
                    },
                    background_color: Color::srgb(0.0, 1.0, 0.0).into(),
                    ..Default::default()
                });

                // text with width=auto, but actual size will not be what it expcets due to the sibling div above
                commands.spawn(TextBundle {
                    text: Text::from_section("Some text that wraps onto a second line", Default::default()).with_justify(justify),
                    style: Style {
                        align_self: AlignSelf::Center,
                        ..Default::default()
                    },
                    ..Default::default()
                });
            });
        });
    }
}
```
2024-06-14 19:14:42 +00:00
Elabajaba
2825ac8a8e
Wgpu 0.20 (#13186)
Currently blocked on https://github.com/gfx-rs/wgpu/issues/5774

# Objective

Update to wgpu 0.20

## Solution

Update to wgpu 0.20 and naga_oil 0.14.

## Testing

Tested a few different examples on linux (vulkan, webgl2, webgpu) and
windows (dx12 + vulkan) and they worked.

---

## Changelog

- Updated to wgpu 0.20. Note that we don't currently support wgpu's new
pipeline overridable constants, as they don't work on web currently and
need some more changes to naga_oil (and are somewhat redundant with
naga_oil's shader defs). See wgpu's changelog for more
https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#v0200-2024-04-28

## Migration Guide

TODO

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2024-06-14 18:39:31 +00:00
Mike
004ba585b2
reduce the antialias strength (#13814)
# Objective

- Fixes #13807

## Solution

- Before this pr we antialiased between 0.5 and -0.5. This pr changes
things to antialias between 0.25 and -0.25. I tried slightly larger
ranges, but the edge between the boxes still showed. I'm not 100% sure
this is the correct solution, but from what I could find the range you
use is more art than science.

## Testing

- Ran rounded_borders example, the code in the linked issue, and the
testing example from #12702.

---

## Changelog

- reduce antialiasing in ui shader.
2024-06-14 18:36:15 +00:00
Nionidh
ba198151a4
Add missing plugins to doc of DefaultPlugins (#13833)
StatesPlugin and GizmoPlugin were missing from the doc comment of
DefaultPlugins. I am not sure whether this was for a reason, but i just
stumbled over it and it seemed off...

## Testing

I'm not sure how to test these changes?
2024-06-14 18:03:04 +00:00
Alice Cecile
2cffd14923
Ensure that events are updated even when using a bare-bones Bevy App (#13808)
# Objective

As discovered in
https://github.com/Leafwing-Studios/leafwing-input-manager/issues/538,
there appears to be some real weirdness going on in how event updates
are processed between Bevy 0.13 and Bevy 0.14.

To identify the cause and prevent regression, I've added tests to
validate the intended behavior.
My initial suspicion was that this would be fixed by
https://github.com/bevyengine/bevy/pull/13762, but that doesn't seem to
be the case.

Instead, events appear to never be updated at all when using `bevy_app`
by itself. This is part of the problem resolved by
https://github.com/bevyengine/bevy/pull/11528, and introduced by
https://github.com/bevyengine/bevy/pull/10077.

After some investigation, it appears that `signal_event_update_system`
is never added using a bare-bones `App`, and so event updates are always
skipped.

This can be worked around by adding your own copy to a
later-in-the-frame schedule, but that's not a very good fix.

## Solution

Ensure that if we're not using a `FixedUpdate` schedule, events are
always updated every frame.

To do this, I've modified the logic of `event_update_condition` and
`event_update_system` to clearly and correctly differentiate between the
two cases: where we're waiting for a "you should update now" signal and
where we simply don't care.

To encode this, I've added the `ShouldUpdateEvents` enum, replacing a
simple `bool` in `EventRegistry`'s `needs_update` field.

Now, both tests pass as expected, without having to manually add a
system!

## Testing

I've written two parallel unit tests to cover the intended behavior:

1. Test that `iter_current_update_events` works as expected in
`bevy_ecs`.
2. Test that `iter_current_update_events` works as expected in
`bevy_app`

I've also added a test to verify that event updating works correctly in
the presence of a fixed main schedule, and a second test to verify that
fixed updating works at all to help future authors narrow down failures.

## Outstanding

- [x] figure out why the `bevy_app` version of this test fails but the
`bevy_ecs` version does not
- [x] figure out why `EventRegistry::run_updates` isn't working properly
- [x] figure out why `EventRegistry::run_updates` is never getting
called
- [x] figure out why `event_update_condition` is always returning false
- [x] figure out why `EventRegistry::needs_update` is always false
- [x] verify that the problem is a missing `signal_events_update_system`

---------

Co-authored-by: Mike <mike.hsu@gmail.com>
2024-06-12 14:28:51 +00:00
CatThingy
f23c686fcf
Fix minor typos in query join docs (#13812)
# Objective

- Correct typos in docs for `Query::join`'s docs

## Solution

- Fix them

Co-authored-by: François Mockers <mockersf@gmail.com>
2024-06-11 23:24:53 +00:00
Mike
07a85676b3
Revert "constrain WorldQuery::init_state argument to ComponentInitial… (#13804)
…izer (#13442)"

This reverts commit 5cfb063d4a.

- This PR broke bevy-trait-query, which needs to be able to write a
resource in init_state. See #13798 for more details.
- Note this doesn't fix everything as transmutes for bevy-trait-query
will still be broken,. But the current usage in that crate is UB, so we
need to find another solution.
2024-06-11 22:54:42 +00:00
Alice Cecile
d659a1f7d5
Revert "Make FOG_ENABLED a shader_def instead of material flag (#13783)" (#13803)
This reverts commit 3ced49f672.

Relevant to https://github.com/bevyengine/bevy/issues/13802. This wasn't
done quite right and partially broke fog.

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-06-10 23:25:16 +00:00
Bob Gardner
2ccdae7489
Split event.rs into a full module. (#13801)
# Objective

- Split the bevy_ecs::events module so it's easier to work with

## Solution

- Split the event.rs file across multiple files, made sure all tests
passed, and exports from the module were the same as previous

## Testing

- All automated tests pass.
2024-06-10 21:45:01 +00:00
Brezak
d803adff09
Add from_color to StandardMaterial and ColorMaterial (#13791)
# Objective

Closes #13738

## Solution

Added `from_color` to materials that would support it. Didn't add
`from_color` to `WireframeMaterial` as it doesn't seem we expect users
to be constructing them themselves.

## Testing

None

---

## Changelog

### Added

- `from_color` to `StandardMaterial` so you can construct this material
from any color type.
- `from_color` to `ColorMaterial` so you can construct this material
from any color type.
2024-06-10 21:25:31 +00:00
Alice Cecile
54010cc07e
Revert Align Scene::write_to_world_with to match DynamicScene::write_to_world_with (#13800)
# Objective

- https://github.com/bevyengine/bevy/pull/13714 broke scenes pretty
seriously
- Fixes https://github.com/bevyengine/bevy/issues/13796

## Solution

Revert it. We can redo this PR once the behavior is fixed.

Co-authored-by: Dmytro Banin <dima_banin@hotmail.com>
2024-06-10 21:14:11 +00:00
JMS55
fd30e0c67d
Fix meshlet vertex attribute interpolation (#13775)
# Objective

- Mikktspace requires that we normalize world normals/tangents _before_
interpolation across vertices, and then do _not_ normalize after. I had
it backwards.
- We do not (am not supposed to?) need a second set of barycentrics for
motion vectors. If you think about the typical raster pipeline, in the
vertex shader we calculate previous_world_position, and then it gets
interpolated using the current triangle's barycentrics.

## Solution

- Fix normal/tangent processing 
- Reuse barycentrics for motion vector calculations
- Not implementing this for 0.14, but long term I aim to remove explicit
vertex tangents and calculate them in the shader on the fly.

## Testing

- I tested out some of the normal maps we have in repo. Didn't seem to
make a difference, but mikktspace is all about correctness across
various baking tools. I probably just didn't have any of the ones that
would cause it to break.
- Didn't test motion vectors as there's a known bug with the depth
buffer and meshlets that I'm waiting on the render graph rewrite to fix.
2024-06-10 20:18:43 +00:00
Brezak
f187d9c5fc
Poll system information in separate tasks (#13693)
# Objective

Reading system information severely slows down the update loop.
Fixes #12848.

## Solution

Read system info in a separate thread.

## Testing

- Open the scene 3d example
- Add `FrameTimeDiagnosticsPlugin`, `SystemInformationDiagnosticsPlugin`
and `LogDiagnosticsPlugin` to the app.
- Add this system to the update schedule to disable Vsync on the main
window
```rust
fn change_window_mode(mut windows: Query<&mut Window, Added<Window>>) {
    for mut window in &mut windows {
        window.present_mode = PresentMode::AutoNoVsync;
    }
}
```
- Read the fps values in the console before and after this PR.

On my PC I went from around 50 fps to around 1150 fps.

---

## Changelog

### Changed

- The `SystemInformationDiagnosticsPlugin` now reads system data
separate of the update cycle.

### Added 

- The `EXPECTED_SYSTEM_INFORMATION_INTERVAL` constant which defines how
often we read system diagnostic data.

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2024-06-10 19:06:22 +00:00
Chris Juchem
49661b99fe
Remove extra call to clear_trackers (#13762)
Fixes #13758.

# Objective

Calling `update` on the main app already calls `clear_trackers`. Calling
it again in `SubApps::update` caused RemovedCompenet Events to be
cleared earlier than they should be.

## Solution

- Don't call clear_trackers an extra time.

## Testing

I manually tested the fix with this unit test: 
```
#[cfg(test)]
mod test {
    use crate::core::{FrameCount, FrameCountPlugin};
    use crate::prelude::*;

    #[test]
    fn test_next_frame_removal() {
        #[derive(Component)]
        struct Foo;

        #[derive(Resource)]
        struct RemovedCount(usize);

        let mut app = App::new();
        app.add_plugins(FrameCountPlugin);
        app.add_systems(Startup, |mut commands: Commands| {
            for _ in 0..100 {
                commands.spawn(Foo);
            }
            commands.insert_resource(RemovedCount(0));
        });

        app.add_systems(First, |counter: Res<FrameCount>| {
            println!("Frame {}:", counter.0)
        });

        fn detector_system(
            mut removals: RemovedComponents<Foo>,
            foos: Query<Entity, With<Foo>>,
            mut removed_c: ResMut<RemovedCount>,
        ) {
            for e in removals.read() {
                println!("  Detected removed Foo component for {e:?}");
                removed_c.0 += 1;
            }
            let c = foos.iter().count();
            println!("  Total Foos: {}", c);
            assert_eq!(c + removed_c.0, 100);
        }
        fn deleter_system(foos: Query<Entity, With<Foo>>, mut commands: Commands) {
            foos.iter().next().map(|e| {
                commands.entity(e).remove::<Foo>();
            });
        }
        app.add_systems(Update, (detector_system, deleter_system).chain());

        app.update();
        app.update();
        app.update();
        app.update();
    }
}
```
2024-06-10 18:06:05 +00:00
Wuketuke
2c5959a29d
Added an illustration to the compass direction docs (issue 13664) (#13788)
i based the design on @mgi388 in the discussion about the issue.
i added the illustration in such a way that it shows up when you hover
your mouse over the type, i hope this is what was meant by the issue
no unit tests were added bc obviously

Fixes #13664
2024-06-10 17:31:11 +00:00
Periwink
93f3432400
Update serialize flag for bevy_ecs (#13740)
# Objective

There were some issues with the `serialize` feature:
- `bevy_app` had a `serialize` feature and a dependency on `serde` even
there is no usage of serde at all inside `bevy_app`
- the `bevy_app/serialize` feature enabled `bevy_ecs/serde`, which is
strange
- `bevy_internal/serialize` did not enable `bevy_app/serialize` so there
was no way of serializing an Entity in bevy 0.14

## Solution

- Remove `serde` and `bevy_app/serialize` 
- Add a `serialize` flag on `bevy_ecs` that enables `serde`
- ` bevy_internal/serialize` now enables `bevy_ecs/serialize`
2024-06-10 16:37:59 +00:00
T.J. Given
70a38ab1f6
Re-name and Extend Run Conditions API (#13784)
# Objective

- My attempt at fulfilling #13629.

## Solution

Renames the `and_then` / `or_else` run condition methods to `and` /
`or`, respectively.

Extends the run conditions API to include a suite of binary logical
operators:
- `and`
- `or`
- `nand`
- `nor`
- `xor`
- `xnor`

## Testing

- Did you test these changes? If so, how?
- The test **run_condition_combinators** was extended to include the
added run condition combinators. A **double_counter** system was added
to test for combinators running on even count cycles.

- Are there any parts that need more testing?
- I'm not too sure how I feel about the "counter" style of testing but I
wanted to keep it consistent. If it's just a unit test I would prefer
simply to just assert `true` == _combinator output_ or `false` ==
_combinator output_ .

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Nothing too specific. The added methods should be equivalent to the
logical operators they are analogous to (`&&` , `||`, `^`, `!`).

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
    - Should not be relevant, I'm using Windows.

## Changelog

- What changed as a result of this PR?
    - The run conditions API.

- If applicable, organize changes under "Added", "Changed", or "Fixed"
sub-headings
    - Changed:
        - `and_then` run condition combinator renamed to simply `and`
        - `or_else` run condition combinator renamed to simply `or`
    - Added:
        - `nand` run condition combinator.
        - `nor` run condition combinator.
        - `xor` run condition combinator.
        - `xnor` run condition combinator.

## Migration Guide

- The `and_then` run condition method has been replaced with the `and`
run condition method.
- The `or_else` run condition method has been replaced with the `or` run
condition method.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Andres O. Vela <andresovela@users.noreply.github.com>
2024-06-10 13:41:56 +00:00
IceSentry
5134272dc9
Make FOG_ENABLED a shader_def instead of material flag (#13783)
# Objective

- If the fog is disabled it still generates a useless branch which can
hurt performance

## Solution

- Make the flag a shader_def instead

## Testing

- I tested enabling/disabling fog works as expected per-material in the
fog example
- I also tested that scenes that don't add the FogSettings resource
still work correctly

## Review notes

I'm not sure how to handle the removed material flag. Right now I just
commented it out and added a not to reuse it instead of creating a new
one.
2024-06-10 13:26:43 +00:00
Lee-Orr
7ec301c48d
fix docs around StateTransition and remove references to `apply_sta… (#13772)
The documentation for the `State` resource still referenced the use of
`apply_state_transition` to manually force a state transition to occur,
and the question around how to force transitions had come up a few times
on discord.

This is a docs-only change, that does the following:
- Properly references `StateTransition` in the `MainSchedule` docs
- replace the explanations for applying `NextState` with ones that
explain the `StateTransition` schedule, and mentions the possibility of
calling it manually
- Add an example of calling `StateTransition` manually in the docs for
the state transition schedule itself.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-10 13:23:14 +00:00
Isaïe
2356276afd
Clarify error message due to missing shader file (#13766)
# Objective

The error printed-out due to a missing shader file was confusing; This
PR changes the error message.

Fixes #13644 

## Solution

I replaced the confusing wording (`... shader is not loaded yet`) with a
clear explanation (`... shader could not be loaded`)

## Testing

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

removing `assets/shaders/game_of_life.wgsl` & running its associated
example now produces the following error:

```
thread '<unnamed>' panicked at examples/shader/compute_shader_game_of_life.rs:233:25:
Initializing assets/shaders/game_of_life.wgsl:
Pipeline could not be compiled because the following shader could not be loaded: AssetId<bevy_render::render_resource::shader::Shader>{ index: 0, generation: 0}
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_render::renderer::render_system`!
```

I don't think there are any tests expecting the previous error message,
so this change should not break anything.

> Are there any parts that need more testing?

If there was an intent behind the original message, this might need more
attention.

> How can other people (reviewers) test your changes? Is there anything
specific they need to know?

One should be able to preview the changes by running any example after
deleting/renaming their associated shader(s).

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

N/A
2024-06-10 13:15:54 +00:00
MiniaczQ
6d0b7504a2
Add more granular system sets for state transition schedule ordering (#13763)
# Objective

Fixes #13711 

## Solution

Introduce smaller, generic system sets for each schedule variant, which
are ordered against other generic variants:
- `ExitSchedules<S>` - For `OnExit` schedules, runs from leaf states to
root states.
- `TransitionSchedules<S>` - For `OnTransition` schedules, runs in
arbitrary order.
- `EnterSchedules<S>` - For `OnEnter` schedules, runs from root states
to leaf states.

Also unified `ApplyStateTransition<S>` schedule which works in basically
the same way, just for internals.

## Testing

- One test that tests schedule execution order

---------

Co-authored-by: Lee-Orr <lee-orr@users.noreply.github.com>
2024-06-10 13:13:58 +00:00
JMS55
50ee483665
Meshlet misc (#13761)
- Copy module docs so that they show up in the re-export
- Change meshlet_id to cluster_id in the debug visualization
- Small doc tweaks
2024-06-10 13:06:08 +00:00
Gagnus
298b01f10d
Adds back in way to convert color to u8 array, implemented for the two RGB color types, also renames Color::linear to Color::to_linear. (#13759)
# Objective

One thing missing from the new Color implementation in 0.14 is the
ability to easily convert to a u8 representation of the rgb color.

(note this is a redo of PR https://github.com/bevyengine/bevy/pull/13739
as I needed to move the source branch

## Solution

I have added to_u8_array and to_u8_array_no_alpha to a new trait called
ColorToPacked to mirror the f32 conversions in ColorToComponents and
implemented the new trait for Srgba and LinearRgba.
To go with those I also added matching from_u8... functions and
converted a couple of cases that used ad-hoc implementations of that
conversion to use these.
After discussion on Discord of the experience of using the API I renamed
Color::linear to Color::to_linear, as without that it looks like a
constructor (like Color::rgb).
I also added to_srgba which is the other commonly converted to type of
color (for UI and 2D) to match to_linear.
Removed a redundant extra implementation of to_f32_array for LinearColor
as it is also supplied in ColorToComponents (I'm surprised that's
allowed?)

## Testing

Ran all tests and manually tested.
Added to_and_from_u8 to linear_rgba::tests

## Changelog

visible change is Color::linear becomes Color::to_linear.

---------

Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
2024-06-10 13:03:46 +00:00
JMS55
c50a4d8821
Remove unused mip_bias parameter from apply_normal_mapping (#13752)
Mip bias is no longer used here
2024-06-10 13:00:34 +00:00
Joseph
0dfdd87248
Improve error handling for AssetServer::add_async (#13745)
# Objective

The method `AssetServer::add_async` (added in
https://github.com/bevyengine/bevy/pull/13700) requires a future that
returns an `AssetLoadError` error, which was a bit of an oversight on my
part, as that type of error only really makes sense in the context of
bevy's own asset loader -- returning it from user-defined futures isn't
very useful.

## Solution

Allow passing custom error types to `add_async`, which get cast into a
trait object matching the form of `AssetLoader::load`. If merged before
the next release this will not be a breaking change
2024-06-10 12:56:21 +00:00
Matty
a569b35c18
Stable interpolation and smooth following (#13741)
# Objective

Partially address #13408 

Rework of #13613

Unify the very nice forms of interpolation specifically present in
`bevy_math` under a shared trait upon which further behavior can be
based.

The ideas in this PR were prompted by [Lerp smoothing is broken by Freya
Holmer](https://www.youtube.com/watch?v=LSNQuFEDOyQ).

## Solution

There is a new trait `StableInterpolate` in `bevy_math::common_traits`
which enshrines a quite-specific notion of interpolation with a lot of
guarantees:
```rust
/// A type with a natural interpolation that provides strong subdivision guarantees.
///
/// Although the only required method is `interpolate_stable`, many things are expected of it:
///
/// 1. The notion of interpolation should follow naturally from the semantics of the type, so
///    that inferring the interpolation mode from the type alone is sensible.
///
/// 2. The interpolation recovers something equivalent to the starting value at `t = 0.0`
///    and likewise with the ending value at `t = 1.0`.
///
/// 3. Importantly, the interpolation must be *subdivision-stable*: for any interpolation curve
///    between two (unnamed) values and any parameter-value pairs `(t0, p)` and `(t1, q)`, the
///    interpolation curve between `p` and `q` must be the *linear* reparametrization of the original
///    interpolation curve restricted to the interval `[t0, t1]`.
///
/// The last of these conditions is very strong and indicates something like constant speed. It
/// is called "subdivision stability" because it guarantees that breaking up the interpolation
/// into segments and joining them back together has no effect.
///
/// Here is a diagram depicting it:
/// ```text
/// top curve = u.interpolate_stable(v, t)
///
///              t0 => p   t1 => q    
///   |-------------|---------|-------------|
/// 0 => u         /           \          1 => v
///              /               \
///            /                   \
///          /        linear         \
///        /     reparametrization     \
///      /   t = t0 * (1 - s) + t1 * s   \
///    /                                   \
///   |-------------------------------------|
/// 0 => p                                1 => q
///
/// bottom curve = p.interpolate_stable(q, s)
/// ```
///
/// Note that some common forms of interpolation do not satisfy this criterion. For example,
/// [`Quat::lerp`] and [`Rot2::nlerp`] are not subdivision-stable.
///
/// Furthermore, this is not to be used as a general trait for abstract interpolation.
/// Consumers rely on the strong guarantees in order for behavior based on this trait to be
/// well-behaved.
///
/// [`Quat::lerp`]: crate::Quat::lerp
/// [`Rot2::nlerp`]: crate::Rot2::nlerp
pub trait StableInterpolate: Clone {
    /// Interpolate between this value and the `other` given value using the parameter `t`.
    /// Note that the parameter `t` is not necessarily clamped to lie between `0` and `1`.
    /// When `t = 0.0`, `self` is recovered, while `other` is recovered at `t = 1.0`,
    /// with intermediate values lying between the two.
    fn interpolate_stable(&self, other: &Self, t: f32) -> Self;
}
```

This trait has a blanket implementation over `NormedVectorSpace`, where
`lerp` is used, along with implementations for `Rot2`, `Quat`, and the
direction types using variants of `slerp`. Other areas may choose to
implement this trait in order to hook into its functionality, but the
stringent requirements must actually be met.

This trait bears no direct relationship with `bevy_animation`'s
`Animatable` trait, although they may choose to use `interpolate_stable`
in their trait implementations if they wish, as both traits involve
type-inferred interpolations of the same kind. `StableInterpolate` is
not a supertrait of `Animatable` for a couple reasons:
1. Notions of interpolation in animation are generally going to be much
more general than those allowed under these constraints.
2. Laying out these generalized interpolation notions is the domain of
`bevy_animation` rather than of `bevy_math`. (Consider also that
inferring interpolation from types is not universally desirable.)

Similarly, this is not implemented on `bevy_color`'s color types,
although their current mixing behavior does meet the conditions of the
trait.

As an aside, the subdivision-stability condition is of interest
specifically for the [Curve
RFC](https://github.com/bevyengine/rfcs/pull/80), where it also ensures
a kind of stability for subsampling.

Importantly, this trait ensures that the "smooth following" behavior
defined in this PR behaves predictably:
```rust
    /// Smoothly nudge this value towards the `target` at a given decay rate. The `decay_rate`
    /// parameter controls how fast the distance between `self` and `target` decays relative to
    /// the units of `delta`; the intended usage is for `decay_rate` to generally remain fixed,
    /// while `delta` is something like `delta_time` from an updating system. This produces a
    /// smooth following of the target that is independent of framerate.
    ///
    /// More specifically, when this is called repeatedly, the result is that the distance between
    /// `self` and a fixed `target` attenuates exponentially, with the rate of this exponential
    /// decay given by `decay_rate`.
    ///
    /// For example, at `decay_rate = 0.0`, this has no effect.
    /// At `decay_rate = f32::INFINITY`, `self` immediately snaps to `target`.
    /// In general, higher rates mean that `self` moves more quickly towards `target`.
    ///
    /// # Example
    /// ```
    /// # use bevy_math::{Vec3, StableInterpolate};
    /// # let delta_time: f32 = 1.0 / 60.0;
    /// let mut object_position: Vec3 = Vec3::ZERO;
    /// let target_position: Vec3 = Vec3::new(2.0, 3.0, 5.0);
    /// // Decay rate of ln(10) => after 1 second, remaining distance is 1/10th
    /// let decay_rate = f32::ln(10.0);
    /// // Calling this repeatedly will move `object_position` towards `target_position`:
    /// object_position.smooth_nudge(&target_position, decay_rate, delta_time);
    /// ```
    fn smooth_nudge(&mut self, target: &Self, decay_rate: f32, delta: f32) {
        self.interpolate_stable_assign(target, 1.0 - f32::exp(-decay_rate * delta));
    }
```

As the documentation indicates, the intention is for this to be called
in game update systems, and `delta` would be something like
`Time::delta_seconds` in Bevy, allowing positions, orientations, and so
on to smoothly follow a target. A new example, `smooth_follow`,
demonstrates a basic implementation of this, with a sphere smoothly
following a sharply moving target:


https://github.com/bevyengine/bevy/assets/2975848/7124b28b-6361-47e3-acf7-d1578ebd0347


## Testing

Tested by running the example with various parameters.
2024-06-10 12:50:59 +00:00
Lynn
1196186257
Add segments to ExtrusionBuilder (#13719)
# Objective

- Add support for `segments` for extrusion-meshes, akin to what is
possible with cylinders

## Solution

- Added a `.segments(segments: usize)` function to `ExtrusionBuilder`.
- Implemented support for segments in the meshing algorithm.
- If you set `.segments(0)`, the meshing will fail, just like it does
with cylinders.

## Additional information

Here is a wireframe of some extrusions with 1, 2, 3, etc. segments:

![image_2024-06-06_233205114](https://github.com/bevyengine/bevy/assets/62256001/358081e2-172d-407b-8bdb-9cda88eb4664)

---------

Co-authored-by: Lynn Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
2024-06-10 12:50:29 +00:00
Dmytro Banin
1f61c26d2e
Align Scene::write_to_world_with to match DynamicScene::write_to_world_with (#13714)
# Objective

`Scene` and `DynamicScene` work with `InstanceInfo` at different levels
of abstraction
- `Scene::write_to_world_with` returns an `InstanceInfo` whereas
`DynamicScene::write_to_world_with` returns `()`. Instances are created
one level higher at the `SceneSpawner` API level.
- `DynamicScene::write_to_world_with` takes the `entity_map` as an
argument whereas the `Scene` version is less flexible and creates a new
one for you. No reason this needs to be the case.

## Solution

I propose changing `Scene::write_to_world_with` to match the API we have
for `DynamicScene`. Returning the `InstanceInfo` as we do today just
seems like a leaky abstraction - it's only used in
`spawn_sync_internal`. Being able to pass in an entity_map gives you
more flexibility with how you write entities to a world.

This also moves `InstanceInfo` out of `Scene` which is cleaner
conceptually. If someone wants to work with instances then they should
work with `SceneSpawner` - I see `write_to_world_with` as a lower-level
API to be used with exclusive world access.

## Testing

Code is just shifting things around.

## 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-06-10 12:39:35 +00:00
Jan Hohenheim
1b9edd0e5b
Fix minor doc typo (#13776)
Don't think any description is needed, just happened to stumble on this
while reading up on how to use `Stopwatch` :)
2024-06-10 07:15:38 +00:00
Niklas Eicker
69d7da9b37
Let init_non_send_resource require FromWorld instead of Default (#13779)
# Objective

- Let `init_non_send_resource` take `FromWorld` values again, not only
`Default`
- This reverts an unintended breaking change introduced in #9202

## Solution

- The resource initialized with `init_non_send_resource` requires
`FromWorld` again
2024-06-10 07:10:52 +00:00
thebluefish
7c9c6ff27f
Fix EntityCommands::despawn docs (#13774)
# Objective

The `EntityCommands::despawn` method was previously changed from
panicking behavior to a warning, but the docs continue to state that it
panics.

## Solution

- Removed panic section, copied warning blurb from `World::despawn`
- Adds a similar warning blurb to
`DespawnRecursiveExt::despawn_recursive` and
`DespawnRecursiveExt::despawn_descendants`
2024-06-09 17:59:19 +00:00
Chris Biscardi
b9e67bc3c3
view.inverse_clip_from_world should be world_from_clip (#13756)
As per the other changes in
https://github.com/bevyengine/bevy/pull/13489
`view.inverse_clip_from_world` should be `world_from_clip`.



# Objective

fixes #13749

## Solution

Modified lines.wgsl to use the right name as the current name does not
exist.

## Testing

I ran the 3d_gizmos example and pressed "p".

![screenshot-2024-06-08-at-13 21
22@2x](https://github.com/bevyengine/bevy/assets/551247/b8bfd3db-8273-4606-9dae-040764339883)

![screenshot-2024-06-08-at-13 21
26@2x](https://github.com/bevyengine/bevy/assets/551247/2619f1ae-ce83-44d7-a9fc-07e686950887)
2024-06-09 14:40:14 +00:00
Vitaliy Sapronenko
e9a3a0d694
Clear messed up feature flag on AppExitStates impl (#13737)
# Objective

- In #13649 additional method had been added to AppExitStates, but there
feature gate left for method in implementation for App at refactoring
stage.
- Fixes #13733 .

## Solution

- Removed the feature gate.

## Testing

- Ran reproducing example from #13733 with no compilation errors
2024-06-09 13:49:03 +00:00
charlotte
7b14b8c015
13743 app exit hang (#13744)
Fixes #13743.

---------

Co-authored-by: Brezak <bezak.adam@proton.me>
2024-06-08 21:42:01 +00:00
Zachary Harrold
3bfc427666
Add mappings to EntityMapper (#13727)
# Objective

- Fixes #13703

## Solution

- Added `mappings` to the `EntityMapper` trait, which returns an
iterator over currently tracked `Entity` to `Entity` mappings.
- Added `DynEntityMapper` as an [object
safe](https://doc.rust-lang.org/reference/items/traits.html#object-safety)
alternative to `EntityMapper`.
- Added `assert_object_safe` as a helper for ensuring traits are object
safe.

## Testing

- Added new unit test `entity_mapper_iteration` which tests the
`SceneEntityMapper` implementation of `EntityMapper::mappings`.
- Added unit tests to ensure `DynEntityMapper`, `DynEq` and `DynHash`
are object safe.
- Passed CI on my Windows 10 development environment

---

## Changelog

- Added `mappings` to `EntityMapper` trait.

## Migration Guide

- If you are implementing `EntityMapper` yourself, you can use the below
as a stub implementation:

```rust
fn mappings(&self) -> impl Iterator<Item = (Entity, Entity)> {
    unimplemented!()
}
```

- If you were using `EntityMapper` as a trait object (`dyn
EntityMapper`), instead use `dyn DynEntityMapper` and its associated
methods.

## Notes

- The original issue proposed returning a `Vec` from `EntityMapper`
instead of an `impl Iterator` to preserve its object safety. This is a
simpler option, but also forces an allocation where it isn't strictly
needed. I've opted for this split into `DynEntityMapper` and
`EntityMapper` as it's been done several times across Bevy already, and
provides maximum flexibility to users.
- `assert_object_safe` is an empty function, since the assertion
actually happens once you try to use a `dyn T` for some trait `T`. I
have still added this function to clearly document what object safety is
within Bevy, and to create a standard way to communicate that a given
trait must be object safe.
- Other traits should have tests added to ensure object safety, but I've
left those off to avoid cluttering this PR further.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-08 12:52:23 +00:00
Jerome Humbert
d38d8a148a
Uncouple DynamicTextureAtlasBuilder from assets (#13717)
# Objective

Remove some unnecessary coupling between `DynamicTextureAtlasBuilder`
and `bevy_asset`.

## Solution

Remove the dependency of `DynamicTextureAtlasBuilder::add_texture` to
`bevy_asset`, by directly passing the `Image` of the atlas to mutate,
instead of passing separate `Assets<Image>` and `Handle<Image>` for the
function to do the lookup by itself. The lookup can be done from the
caller, and this allows using the builder in contexts where the `Image`
is not stored inside `Assets`.

Clean-up a bit the font atlas files by introducing a `PlacedGlyph` type
storing the `GlyphId` and its `SubpixelOffset`, which were otherwise
always both passed as function parameters and the pair used as key in
hash maps.

## Testing

There's no change in behavior.

---

## Changelog

- Added a `PlacedGlyph` type aggregating a `GlyphId` and a
`SubpixelOffset`. That type is now used as parameter in a few text atlas
APIs, instead of passing individual values.

## Migration Guide

- Replace the `glyph_id` and `subpixel_offset` of a few text atlas APIs
by a single `place_glyph: PlacedGlyph` parameter trivially combining the
two.
2024-06-08 12:38:03 +00:00
Mincong Lu
651f3d08d7
Make the component types of the new animation players clonable. (#13736)
# Objective

Some use cases might require holding onto the previous state of the
animation player for change detection.

## Solution

Added `clone` and `copy` implementation to most animation types. 
Added optimized `clone_from` implementations for the specific use case
of holding a `PreviousAnimationPlayer` component.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-07 21:51:24 +00:00
Wuketuke
d45bcfd043
improved the error message by insert_boxed (issue #13646) (again) (#13706)
previously I worked on fixing issue #13646, back when the error message
did not include the type at all.
But that error message had room for improvement, so I included the
feedback of @alice-i-cecile and @MrGVSV.
The error message will now read `the given key (of type
bevy_reflect::tests::Foo) does not support hashing` or 'the given key
(of type bevy_reflect::DynamicStruct) does not support hashing' in case
of a dynamic struct that represents a hashable struct

i also added a new unit test for this new behaviour
(`reflect_map_no_hash_dynamic`).
Fixes #13646 (again)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-06-07 20:56:16 +00:00
François Mockers
b17292f9d1
rename the crate bevy_state_macros_official back to its original name (#13732)
# Objective

- Thanks to the original author we can now use the original name

## Solution

- Use it
2024-06-07 12:49:21 +00:00
François Mockers
98bc5ff8c4
Update crate metadata for bevy state (#13722)
# Objective

- crate metadata for bevy_state has been copied from bevy_ecs

## Solution

- Update it
2024-06-07 01:54:53 +00:00
François Mockers
401234a5fb
rename bevy_state_macros to bevy_state_macros_official (#13721)
# Objective

- `bevy_state_macros` is a new crate added in the 0.14
- it already exists outside of the bevy org:
https://crates.io/crates/bevy_state_macros

## Solution

- Rename the crate
2024-06-06 22:18:05 +00:00
charlotte
027f8e21ec
Allow mix of hdr and non-hdr cameras to same render target (#13419)
Changes:
- Track whether an output texture has been written to yet and only clear
it on the first write.
- Use `ClearColorConfig` on `CameraOutputMode` instead of a raw
`LoadOp`.
- Track whether a output texture has been seen when specializing the
upscaling pipeline and use alpha blending for extra cameras rendering to
that texture that do not specify an explicit blend mode.

Fixes #6754

## Testing

Tested against provided test case in issue:

![image](https://github.com/bevyengine/bevy/assets/10366310/d066f069-87fb-4249-a4d9-b6cb1751971b)

---

## Changelog

- Allow cameras rendering to the same output texture with mixed hdr to
work correctly.

## Migration Guide

- - Change `CameraOutputMode` to use `ClearColorConfig` instead of
`LoadOp`.
2024-06-06 20:55:05 +00:00
Rob Parrett
cca0f79022
Fix links to Transform in Transform and GlobalTransform docs (#13704)
# Objective

All the links that should go to the `Transform` type in the `Transform`
and `GlobalTransform` docs currently go to the `transform` example
instead.

## Solution

Fix collision of link labels in `Transform` and `GlobalTransform` docs.
2024-06-06 20:06:54 +00:00
Brandon Reinhart
3122c87702
Provide more information when a filewatcher failure is hit. (#13715)
A naked unwrap led to an opaque error that can be hit when using the
embedded filewatcher.

I've changed this an unwrap_or_else panic! with the error message
providing more details about the failed operation.

A better solution would be to print an error! and not panic...

This was tested with the asset_processing example.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-06 19:20:07 +00:00
IceSentry
f7ae277025
Use TBN in apply_normal_mapping in pbr_prepass (#13716)
# Objective

- apply_normal_mapping was changed to use TBN but the pbr_prepass was
not updated for that change

## Solution

- Update the pbr_prepass to correctly apply normal mapping
2024-06-06 19:04:30 +00:00
JMS55
175e146228
Misc meshlet changes (#13705)
* Rename cull_meshlets -> cull_clusters
* Rename meshlet_visible -> cluster_visible
* Add an if statement around meshlet_second_pass_candidates writes,
maybe a small bit of performance.
2024-06-06 17:10:07 +00:00
Mincong Lu
31be32ff10
Made Mesh::merge take a reference of Mesh. (#13710)
# Objective

`Mesh::merge` does not need ownership of the right hand side mesh.

## Solution

Made `Mesh::merge` take a reference.

## Testing

Modified existing tests.

---

## Changelog

Made `Mesh::merge` take a reference.


## Migration Guide

* `Mesh::merge` now take a reference of a mesh instead of an owned mesh.
2024-06-06 11:57:10 +00:00
Joseph
9389de5c71
Allow loading assets with custom async behavior (#13700)
# Objective

Currently, bevy supports custom asset loading via `AssetServer:;add`,
which allows you to add arbitrary assets to the asset system and returns
a handle to it. However this only works for assets that have already
been fully loaded. If your loading logic involves any async, you need to
wait until the asset is done loading before adding it to the server.
This is problematic, as the `Handle` does not get allocated until the
very end, which makes it very difficult to use and defeats the value of
having handles for asynchronously-loaded assets.

## Solution

Add the method `AssetServer::add_async`. This has the same behavior as
`AssetServer::add`, only it accepts a future instead of a fully loaded
asset.

## Testing

I added an identical method to my company's fork of bevy, which works in
our app. I'm not quite sure how to go about adding an actual unit test
for asset loading behvior, but I will note that `AssetServer::add` also
does not appear to have any tests.

---

## Changelog

+ Added `AssetServer::add_async`, which allows adding assets with custom
asynchronous loading behavior to the `AssetServer`
2024-06-06 00:21:59 +00:00
François Mockers
3d9b1e4025
make UI text rendering camera driven (#13697)
# Objective

- Fixes #13687 

## Solution

- Text rendering in UI is still dependent on the `PrimaryWIndow`
- implements #10559 for text rendering

There are other parts of UI that are still `PrimaryWindow` dependent, if
the changes here are OK I'll apply them everywhere.
I'm not a fan of the `EntityHashMap` here to hold the scale factors, but
it seems the quick and easy fix

## Testing

- Run example `multiple_windows` on a screen with a scale factor
different than 1, close the primary window
2024-06-06 00:20:50 +00:00
Mikhail Novikov
52215ce072
Add labels to Gltf Node and Mesh assets (#13558)
# Objective

Add labels to GltfNode and GltfMesh - they are missing from the assets
even though they are need if one wants to write a custom Gltf spawning
logic.

Eg AnimationPlayer relies on Name component of the node entities to
control the animation. There is no way to actually get names of the gltf
nodes, thus you can't manually spawn subtree from the scene and animate
it.

## Solution

- Add label field and make use of existing label creation logic to store
it there.

## Testing

- Ran all tests
- Fixed tests for node_hierarchy to use lable now

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-06-05 23:10:33 +00:00
Ricky Taylor
9a123cd3a7
Avoid a panic when loading labelled assets (#13506)
# Objective

- Fixes #10820.

## Solution

- Check that the asset ID to be inserted is still being managed.
- Since this route is only used by `AssetServer`-tracked handles, if the
`infos` map no longer contains the asset ID, all handles must have been
dropped. In this case, since nobody can be watching for the result,
we're safe to bail out. This avoids the panic when inserting the asset,
because when the handles are dropped, its slot in `Assets<A>` is
poisoned.
- Someone may be waiting for a labelled asset rather than the main
asset, these are handled with separate calls to `process_asset_load`, so
shouldn't cause any issues.
- Removed the workaround keeping asset info alive after the handle has
died, since we should no longer be trying to operate on any assets once
their handles have been dropped.

## Testing

- I added a `break` in `handle_internal_asset_events`
(`crates/bevy_asset/src/server/mod.rs` on line 1152). I don't believe
this should affect correctness, only efficiency, since it is effectively
only allowing one asset event to be handled per frame. This causes
examples like `animated_fox` to produce the issue fairly frequently.
- I wrote a small program which called `AssetServer::reload` and could
trigger it too.

---

## Changelog
- Fixed an issue which could cause a panic when loading an asset which
was no longer referenced.

---

## Remaining Work

~This needs more testing. I don't yet have a complete project that
reliably crashes without changes to bevy.~ We have at least one vote of
confidence so far from @Testare who had a project broken by this bug.

@cart, (sorry for the ping), I believe you added the code which delays
`remove_dropped`. Was there any other reason `track_assets` needed to
keep the dropped assets alive?
2024-06-05 23:04:52 +00:00
Alice Cecile
2165f2218f
Rename Rotation2d to Rot2 (#13694)
# Objective

- `Rotation2d` is a very long name for a commonly used type.

## Solution

- Rename it to `Rot2` to match `glam`'s naming convention (e.g. `Vec2`)

I ran a poll, and `Rot2` was the favorite of the candidate names.

This is not actually a breaking change, since `Rotation2d` has not been
shipped yet.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-06-05 21:51:13 +00:00
Wuketuke
2eb9d5cc38
hashing error in bevy_reflect now includes the type (bevyengine#13646) (#13691)
# Objective
If you try to add an object to the hashmap that is not capable of
hashing, the program panics. For easier debugging, the type for that
object should be included in the error message.

Fixes #13646.

## Solution
initially i tried calling std::any::type_name_of_val. this had the
problem that it would print something like dyn Box<dyn Reflect>, not
helpful. But since these objects all implement Reflect, i used
Reflect::type_path() instead. Previously, the error message was part of
a constant called HASH_ERROR. i changed that to a macro called
hash_error to print the type of that object more easily

## Testing
i adapted the unit test reflect_map_no_hash to expect the type in that
panic aswell

since this is my first contribution, please let me know if i have done
everything properly
2024-06-05 19:41:23 +00:00
Lynn
fb3a560a1c
Allow Bounded3d implementations for custom primitives (#13688)
# Objective

- Due to coherency, it was previously not possible to implement
`Bounded3d` for `Extrusion<MyCustomPrimitive>`. This PR fixes that.

## Solution

- Added a new trait `BoundedExtrusion: Primitive2d + Bounded2d` which
provides functions for bounding boxes and spheres of extrusions of 2D
primitives.
- Changed all implementations of `Bounded3d for Extrusion<T>` to
`BoundedExtrusion for T`
- Implemented `Bounded3d for Extrusion<T: BoundedExtrusion>`
- Removed the `extrusion_bounding_box` and `extrusion_bounding_sphere`
functions and used them as default implementations in `BoundedExtrusion`

## Testing

- This PR does not change any implementations

---------

Co-authored-by: Lynn Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
Co-authored-by: Matty <weatherleymatthew@gmail.com>
2024-06-05 19:40:02 +00:00
François Mockers
519abbca11
make sure windows are dropped on main thread (#13686)
# Objective

- On macOS, closing a window by respawning its entity freezes

## Solution

- `WindowWrapper` is keeping an `Arc` of the window, to be able to
access it from the rendering thread. Winit windows are closed when they
are dropped. This need to happen on the main thread on macOS
- Dropping it as soon as the window is closed means the last remaining
`Arc` will be in the rendering thread
- This PR keeps the `Arc` for one frame in the rendering thread before
actually dropping it
2024-06-05 18:13:59 +00:00
Matty
38d3833c83
Allow creation of random Rotation2d (#13684)
# Objective

Fill the gap in this functionality by implementing it for `Rotation2d`.
We have this already for `Quat` in addition to the direction types.

## Solution

`bevy_math::sampling` now contains an implementation of
`Distribution<Rotation2d>` for `Standard`, along with the associated
convenience implementation `Rotation2d: FromRng`, which allows syntax
like this for creating a random rotation:
```rust
// With `FromRng`:
let rotation = Rotation2d::from_rng(rng);
// With `rand::random`:
let another_rotation: Rotation2d = random();
// With `Rng::gen`:
let yet_another_rotation: Rotation2d = rng.gen();
```

I also cleaned up the documentation a little bit, seeding the `Rng`s
instead of building them from entropy, along with adding a handful of
inline directives.
2024-06-05 17:16:51 +00:00
Lukas Chodosevičius
2b20af6b79
Skip tonemapping in case it is none (#13679)
# Objective
Skip unnecessary blit then tonemapping is set to none.

## Testing
Only tested locally on our app.

## Changelog

Changed tonemapping not to execute in case it is set to none.

Co-authored-by: Lukas Chodosevicius <lukaschodosevicius@Lukass-MacBook-Pro.local>
2024-06-05 11:32:46 +00:00
mike
bd6acc6119
flush key_input cache when Bevy loses focus (Adopted) (#13678)
This was adopted from #12878. I rebased the changes resolved the
following merge conflicts:

- moved over the changes originally done in bevy_winit/src/lib.rs's
`handle_winit_event` into bevy_winit/src/state.rs's `window_event`
function
- moved WinitEvent::KeyboardFocusLost event forwarding originally done
in bevy_winit/src/winit_event.rs to the equivalent in
bevy_winit/src/state.rs

Tested this by following the modified keyboard_input example from the
original PR.

First, I verified I could reproduce the issue without the changes. Then,
after applying the changes, I verified that when I Alt+Tabbed away from
the running example that the log showed I released Alt and when I tabbed
back it didn't behave like Alt was stuck.

 
 The following is from the original pull request by @gavlig 
 
 # Objective
 
This helps avoiding stuck key presses after switching from and back to
Bevy window. Key press event gets stuck because window loses focus
before receiving a key release event thus we end up with false positive
in ButtonInput.
 ## Solution
 
 I saw two ways to fix this:
 
     1. add bevy_window as dependency and read WindowFocus events
 
     2. add a KeyboardFocusLost event specifically for this.
 
 
I chose the latter because adding another dependency felt wrong, but if
that is more preferable changing this pr won't be a problem. Also if
someone sees another way please let me know.
 
To test the bug use this small modification over
examples/keyboard_input.rs: (it will work only if you have Alt-Tab
combination for switching between windows in your OS, otherwise change
AltLeft accordingly)
 
 ```
 //! Demonstrates handling a key press/release.
 
 use bevy::{prelude::*, input:⌨️:KeyboardInput};
 
 fn main() {
     App::new()
         .add_plugins(DefaultPlugins)
         .add_systems(Update, keyboard_input_system)
         .run();
 }
 
 /// This system prints 'Alt' key state
fn keyboard_input_system(keyboard_input: Res<ButtonInput<KeyCode>>, mut
keyboard_input_events: EventReader<KeyboardInput>) {
     for event in keyboard_input_events.read() {
         info!("{:?}", event);
     }
 
     if keyboard_input.pressed(KeyCode::AltLeft) {
         info!("'Alt' currently pressed");
     }
 
     if keyboard_input.just_pressed(KeyCode::AltLeft) {
         info!("'Alt' just pressed");
     }
     if keyboard_input.just_released(KeyCode::AltLeft) {
         info!("'Alt' just released");
     }
 }
 ```
 
Here i made a quick video with demo of the fix:
https://youtu.be/qTvUCk4IHvo In first part i press Alt and Alt+Tab to
switch back and forth from example app, logs will indicate that too. In
second part I applied fix and you'll see that Alt will no longer be
pressed when window gets unfocused
 ## Migration Guide
 
 `WinitEvent` has a new enum variant: `WinitEvent::KeyboardFocusLost`.

Co-authored-by: gavlig <gavlig@gmail.com>
2024-06-05 02:06:47 +00:00
Lynn
8e4e840a19
Meshable extrusions - Part 2 (#13676)
# Objective

- Implement `Extrudable` for all meshbuilders of shapes that have been
added after #13478 was created

## Solution

- Implemented meshing for extrusions of `CircularSector`,
`CircularSegment` and `Rhombus`

## Testing

- The correctness of these was confirmed visually.

## Additional information

Here is an image of what they look like :)

![Screenshot 2024-06-04
230633](https://github.com/bevyengine/bevy/assets/62256001/d9cca0ba-30ea-4c48-8ae2-007b469739d7)

Co-authored-by: Lynn Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
2024-06-04 21:53:06 +00:00
Brezak
1fdddf8992
Forward exit codes in default app runner (#13674)
# Objective

The default app runner fabricates exit codes loosing useful info in the
process.

## Solution

- Make run_once extract the correct exit code from app.
- Add a test to confirm it works.

## Testing

- Run the `runner_returns_correct_exit_code` test.
- Rejoice when it succeeds.
2024-06-04 21:40:40 +00:00
Lynn
fd82ef8956
Meshable extrusions (#13478)
# Objective

- Implement `Meshable` for `Extrusion<T>`

## Solution

- `Meshable` requires `Meshable::Output: MeshBuilder` now. This means
that all `some_primitive.mesh()` calls now return a `MeshBuilder`. These
were added for primitives that did not have one prior to this.
- A new trait `Extrudable: MeshBuilder` has been added. This trait
allows you to specify the indices of the perimeter of the mesh created
by this `MeshBuilder` and whether they are to be shaded smooth or flat.
- `Extrusion<P: Primitive2d + Meshable>` is now `Meshable` aswell. The
associated `MeshBuilder` is `ExtrusionMeshBuilder` which is generic over
`P` and uses the `MeshBuilder` of its baseshape internally.
- `ExtrusionMeshBuilder` exposes the configuration functions of its
base-shapes builder.
- Updated the `3d_shapes` example to include `Extrusion`s

## Migration Guide

- Depending on the context, you may need to explicitly call
`.mesh().build()` on primitives where you have previously called
`.mesh()`
- The `Output` type of custom `Meshable` implementations must now derive
`MeshBuilder`.

## Additional information
- The extrusions UVs are done so that 
- the front face (`+Z`) is in the area between `(0, 0)` and `(0.5,
0.5)`,
- the back face (`-Z`) is in the area between `(0.5, 0)` and `(1, 0.5)`
- the mantle is in the area between `(0, 0.5)` and `(1, 1)`. Each
`PerimeterSegment` you specified in the `Extrudable` implementation will
be allocated an equal portion of this area.
- The UVs of the base shape are scaled to be in the front/back area so
whatever method of filling the full UV-space the base shape used is how
these areas will be filled.

Here is an example of what that looks like on a capsule:


https://github.com/bevyengine/bevy/assets/62256001/425ad288-fbbc-4634-9d3f-5e846cdce85f

This is the texture used:

![extrusion
uvs](https://github.com/bevyengine/bevy/assets/62256001/4e54e421-bfda-44b9-8571-412525cebddf)

The `3d_shapes` example now looks like this:


![image_2024-05-22_235915753](https://github.com/bevyengine/bevy/assets/62256001/3d8bc86d-9ed1-47f2-899a-27aac0a265dd)

---------

Co-authored-by: Lynn Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
Co-authored-by: Matty <weatherleymatthew@gmail.com>
Co-authored-by: Matty <2975848+mweatherley@users.noreply.github.com>
2024-06-04 17:27:32 +00:00
Lynn
5e1c841f4e
Extrusion bounded (#13346)
# Objective

- Implement `Bounded3d` for some `Extrusion<T>`
- Provide methods to calculate `Aabb3d`s and `BoundingSphere`s for any
extrusion with a `Bounded2d` base shape

## Solution

- Implemented `Bounded3d` for all 2D `bevy_math` primitives with the
exception of `Plane2d`. As far as I can see, `Plane2d` is pretty much a
line? and I think it is very unintuitive to extrude a plane and get a
plane as a result.
- Add `extrusion_bounding_box` and `extrusion_bounding_sphere`. These
are not always used internally since there are faster methods for
specific extrusions. Both of them produce the optimal result within
precision limits though.

## Testing

- Bounds for extrusions are tested within the same module. All unique
implementations are tested.
- The correctness was validated visually aswell.

---------

Co-authored-by: Raphael Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-06-04 17:25:12 +00:00
Patrick Walton
ace4c6023b
Implement subpixel morphological antialiasing, or SMAA. (#13423)
This commit implements a large subset of [*subpixel morphological
antialiasing*], better known as SMAA. SMAA is a 2011 antialiasing
technique that detects jaggies in an aliased image and smooths them out.
Despite its age, it's been a continual staple of games for over a
decade. Four quality presets are available: *low*, *medium*, *high*, and
*ultra*. I set the default to *high*, on account of modern GPUs being
significantly faster than they were in 2011.

Like the already-implemented FXAA, SMAA works on an unaliased image.
Unlike FXAA, it requires three passes: (1) edge detection; (2) blending
weight calculation; (3) neighborhood blending. Each of the first two
passes writes an intermediate texture for use by the next pass. The
first pass also writes to a stencil buffer in order to dramatically
reduce the number of pixels that the second pass has to examine. Also
unlike FXAA, two built-in lookup textures are required; I bundle them
into the library in compressed KTX2 format.

The [reference implementation of SMAA] is in HLSL, with abundant use of
preprocessor macros to achieve GLSL compatibility. Unfortunately, the
reference implementation predates WGSL by over a decade, so I had to
translate the HLSL to WGSL manually. As much as was reasonably possible
without sacrificing readability, I tried to translate line by line,
preserving comments, both to aid reviewing and to allow patches to the
HLSL to more easily apply to the WGSL. Most of SMAA's features are
supported, but in the interests of making this patch somewhat less huge,
I skipped a few of the more exotic ones:

* The temporal variant is currently unsupported. This is and has been
used in shipping games, so supporting temporal SMAA would be useful
follow-up work. It would, however, require some significant work on TAA
to ensure compatibility, so I opted to skip it in this patch.

* Depth- and chroma-based edge detection are unimplemented; only luma
is. Depth is lower-quality, but faster; chroma is higher-quality, but
slower. Luma is the suggested default edge detection algorithm. (Note
that depth-based edge detection wouldn't work on WebGL 2 anyway, because
of the Naga bug whereby depth sampling is miscompiled in GLSL. This is
the same bug that prevents depth of field from working on that
platform.)

* Predicated thresholding is currently unsupported.

* My implementation is incompatible with SSAA and MSAA, unlike the
original; MSAA must be turned off to use SMAA in Bevy. I believe this
feature was rarely used in practice.

The `anti_aliasing` example has been updated to allow experimentation
with and testing of the different SMAA quality presets. Along the way, I
refactored the example's help text rendering code a bit to eliminate
code repetition.

SMAA is fully supported on WebGL 2.

Fixes #9819.

[*subpixel morphological antialiasing*]: https://www.iryoku.com/smaa/

[reference implementation of SMAA]: https://github.com/iryoku/smaa

## Changelog

### Added

* Subpixel morphological antialiasing, or SMAA, is now available. To use
it, add the `SmaaSettings` component to your `Camera`.

![Screenshot 2024-05-18
134311](https://github.com/bevyengine/bevy/assets/157897/ffbd611c-1b32-4491-b2e2-e410688852ee)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-04 17:07:34 +00:00
IceSentry
d0e1b43402
Add binding() helper function to BufferVec (#13667)
# Objective

- Other render resources have a convenient `.binding()` helper function
to get the binding to the resource

## Solution

- Add the same thing to `BufferVec`, `RawBufferVec`, and
`UninitBufferVec`
2024-06-04 15:36:08 +00:00
Mason Boeman
2b6bfdb5ea
Add dynamic slice based variants of get_many_entities methods (#13584)
# Objective

Add slice based variants of existing `get_many_entities` functions on
`World`. This allows for a collection of entries to be looked up mutably
or immutably instead of requiring a compile time constant number.

## Solution

We just take slices and return Vectors.

the following functions have been added:
- `get_many_entities_dynamic`
- `get_many_entities_dynamic_mut`
- `get_many_entities_from_set_mut`

## Testing

- Doc tests, which pass when run through Miri
2024-06-04 15:29:51 +00:00
Matty
39609f1708
Dir2 -> Rotation2d conversions (#13670)
# Objective

Filling a hole in the API: Previously, there was no particularly
ergonomic way to go from, e.g., a pair of directions to the rotation
that links them.

## Solution

We introduce a small suite of API methods to `Dir2` to address this:
```rust
/// Get the rotation that rotates this direction to `other`.
pub fn rotation_to(self, other: Self) -> Rotation2d { //... }

/// Get the rotation that rotates `other` to this direction.
pub fn rotation_from(self, other: Self) -> Rotation2d { //... }

/// Get the rotation that rotates the X-axis to this direction.
pub fn rotation_from_x(self) -> Rotation2d { //... }

/// Get the rotation that rotates this direction to the X-axis.
pub fn rotation_to_x(self) -> Rotation2d { //... }

/// Get the rotation that rotates this direction to the Y-axis.
pub fn rotation_from_y(self) -> Rotation2d { //... }

/// Get the rotation that rotates the Y-axis to this direction.
pub fn rotation_to_y(self) -> Rotation2d { //... }
```

I also removed some language from the `Rotation2d` docs that is
misleading: the radian and angle conversion functions are already clear
about which angles they spit out, and `Rotation2d` itself doesn't have
any bounds on angles or anything.
2024-06-04 14:44:29 +00:00
MiniaczQ
49338245ea
Generalize StateTransitionEvent<S> to allow identity transitions (#13579)
# Objective

This PR addresses one of the issues from [discord state
discussion](https://discord.com/channels/691052431525675048/1237949214017716356).
Same-state transitions can be desirable, so there should exist a hook
for them.

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

## Solution

- Allow `StateTransitionEvent<S>` to contain identity transitions.
- Ignore identity transitions at schedule running level (`OnExit`,
`OnTransition`, `OnEnter`).
- Propagate identity transitions through `SubStates` and
`ComputedStates`.
- Add example about registering custom transition schedules.

## Changelog

- `StateTransitionEvent<S>` can be emitted with same `exited` and
`entered` state.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-04 14:23:24 +00:00
François Mockers
df57850310
rename touchpad to gesture, and add new gestures (#13660)
# Objective

- With the recent winit update, touchpad specific events can also be
triggered on mobile

## Solution

- Rename them to gestures and add support for the new ones

## Testing

- Tested on the mobile example on iOS


https://github.com/bevyengine/bevy/assets/8672791/da4ed23f-ff0a-41b2-9dcd-726e8546bef2


## Migration Guide

- `TouchpadMagnify` has been renamed to `PinchGesture`
- `TouchpadRotate` has been renamed to `RotationGesture `

---------

Co-authored-by: mike <ramirezmike2@gmail.com>
2024-06-04 12:44:25 +00:00
MiniaczQ
58a0c1336c
Move utilities from examples to bevy_state and add concept of state-scoped entities (#13649)
# Objective

Move `StateScoped` and `log_transitions` to `bevy_state`, since they're
useful for end users.

Addresses #12852, although not in the way the issue had in mind.

## Solution

- Added `bevy_hierarchy` to default features of `bevy_state`.
- Move `log_transitions` to `transitions` module.
- Move `StateScoped` to `state_scoped` module, gated behind
`bevy_hierarchy` feature.
- Refreshed implementation.
- Added `enable_state_coped_entities<S: States>()` to add required
machinery to `App` for clearing state-scoped entities.


## Changelog

- Added `log_transitions` for displaying state transitions.
- Added `StateScoped` for binding entity lifetime to state and app
`enable_state_coped_entities` to register cleaning behavior.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-06-04 11:44:34 +00:00
Patrick Walton
ad6872275f
Rename "point light" to "clusterable object" in cluster contexts. (#13654)
We want to use the clustering infrastructure for light probes and decals
as well, not just point lights. This patch builds on top of #13640 and
performs the rename.

To make this series easier to review, this patch makes no code changes.
Only identifiers and comments are modified.

## Migration Guide

* In the PBR shaders, `point_lights` is now known as
`clusterable_objects`, `PointLight` is now known as `ClusterableObject`,
and `cluster_light_index_lists` is now known as
`clusterable_object_index_lists`.
2024-06-04 11:01:13 +00:00
Rob Parrett
ab2add64fa
Fix a few typos (#13404)
# Objective

Fix a few typos I spotted while looking over #13347

## Solution

Fix em
2024-06-04 00:51:03 +00:00
Alice Cecile
ec7b3490f6
Add on_unimplemented Diagnostics to Most Public Traits (#13347) (#13662)
# Objective

- #13414 did not have the intended effect.
- #13404 is still blocked

## Solution

- Re-adds #13347.

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Co-authored-by: Jamie Ridding <Themayu@users.noreply.github.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-06-04 00:31:34 +00:00
Bennett Lambert
37cc8ea33b
Add axes_2d gizmo. (#12334)
# Objective

This PR addresses #12222 (Fixes #12222). Simple addition to add a 2D
axes gizmo.

## Solution

- Add a new method axes_2d which takes a transform and a case length and
then draws two arrows in the XY plane.

The only thing I'm not sure about here is taking a 3D transform as an
argument. It says in the transform comments that for 2D the z-axis is
used for ordering, so I figured I'd keep it that way?

---

## Changelog

- Add method axes_2d.
- Update arrow_2d to also calculate the tip length depending on arrow
length as in arrow.
- Add axes_2d to examples 2d_gizmos.

---------

Co-authored-by: Ben Lambert <bennett-spencer.lambert@pierer-innovation.com>
2024-06-04 00:02:38 +00:00
Kxie
1b6bc2c240
document need to update Aabb in Mesh::(with_)insert_attribute (#13349)
# Objective

solves #12475 for functions `Mesh::insert_attribute` and
`Mesh::with_inserted_attribute`.

## Solution

added references to Aabb and suggest solutions in doc strings

## Testing

ran cargo docs, links work.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-06-03 23:46:31 +00:00
Patrick Walton
df8ccb8735
Implement PBR anisotropy per KHR_materials_anisotropy. (#13450)
This commit implements support for physically-based anisotropy in Bevy's
`StandardMaterial`, following the specification for the
[`KHR_materials_anisotropy`] glTF extension.

[*Anisotropy*] (not to be confused with [anisotropic filtering]) is a
PBR feature that allows roughness to vary along the tangent and
bitangent directions of a mesh. In effect, this causes the specular
light to stretch out into lines instead of a round lobe. This is useful
for modeling brushed metal, hair, and similar surfaces. Support for
anisotropy is a common feature in major game and graphics engines;
Unity, Unreal, Godot, three.js, and Blender all support it to varying
degrees.

Two new parameters have been added to `StandardMaterial`:
`anisotropy_strength` and `anisotropy_rotation`. Anisotropy strength,
which ranges from 0 to 1, represents how much the roughness differs
between the tangent and the bitangent of the mesh. In effect, it
controls how stretched the specular highlight is. Anisotropy rotation
allows the roughness direction to differ from the tangent of the model.

In addition to these two fixed parameters, an *anisotropy texture* can
be supplied. Such a texture should be a 3-channel RGB texture, where the
red and green values specify a direction vector using the same
conventions as a normal map ([0, 1] color values map to [-1, 1] vector
values), and the the blue value represents the strength. This matches
the format that the [`KHR_materials_anisotropy`] specification requires.
Such textures should be loaded as linear and not sRGB. Note that this
texture does consume one additional texture binding in the standard
material shader.

The glTF loader has been updated to properly parse the
`KHR_materials_anisotropy` extension.

A new example, `anisotropy`, has been added. This example loads and
displays the barn lamp example from the [`glTF-Sample-Assets`]
repository. Note that the textures were rather large, so I shrunk them
down and converted them to a mixture of JPEG and KTX2 format, in the
interests of saving space in the Bevy repository.

[*Anisotropy*]:
https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel

[anisotropic filtering]:
https://en.wikipedia.org/wiki/Anisotropic_filtering

[`KHR_materials_anisotropy`]:
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md

[`glTF-Sample-Assets`]:
https://github.com/KhronosGroup/glTF-Sample-Assets/

## Changelog

### Added

* Physically-based anisotropy is now available for materials, which
enhances the look of surfaces such as brushed metal or hair. glTF scenes
can use the new feature with the `KHR_materials_anisotropy` extension.

## Screenshots

With anisotropy:
![Screenshot 2024-05-20
233414](https://github.com/bevyengine/bevy/assets/157897/379f1e42-24e9-40b6-a430-f7d1479d0335)

Without anisotropy:
![Screenshot 2024-05-20
233420](https://github.com/bevyengine/bevy/assets/157897/aa220f05-b8e7-417c-9671-b242d4bf9fc4)
2024-06-03 23:46:06 +00:00
dependabot[bot]
257fec996f
Update ruzstd requirement from 0.6.0 to 0.7.0 (#13642)
Updates the requirements on
[ruzstd](https://github.com/KillingSpark/zstd-rs) to permit the latest
version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/KillingSpark/zstd-rs/releases">ruzstd's
releases</a>.</em></p>
<blockquote>
<h2>Optimizations, Documentation and slight API changes</h2>
<ul>
<li>Few slight performance optimizations</li>
<li>Big documentation contribution</li>
<li><code>StreamingDecoder</code> now has API to get to the contained
<code>impl Read</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/KillingSpark/zstd-rs/blob/master/Changelog.md">ruzstd's
changelog</a>.</em></p>
<blockquote>
<h1>After 0.7.0</h1>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="101df3eac0"><code>101df3e</code></a>
bump version to 0.7.0</li>
<li><a
href="c7ad34bc1c"><code>c7ad34b</code></a>
fix doc on reverse bitreader</li>
<li><a
href="cd73dffe15"><code>cd73dff</code></a>
changelog</li>
<li><a
href="944b391c30"><code>944b391</code></a>
don't return errors on too large requests on a reversed bitreader (<a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/58">#58</a>)</li>
<li><a
href="53e7b1a600"><code>53e7b1a</code></a>
fix doc comments for clippy</li>
<li><a
href="16fee8cd45"><code>16fee8c</code></a>
Implement accessors for inner reader on StreamDecoder (<a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/62">#62</a>)</li>
<li><a
href="0b9607324e"><code>0b96073</code></a>
Add documentation throughout the codebase. (<a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/61">#61</a>)</li>
<li><a
href="5265c12c8c"><code>5265c12</code></a>
remove derive_more (<a
href="https://redirect.github.com/KillingSpark/zstd-rs/issues/60">#60</a>)</li>
<li><a
href="88f7a41677"><code>88f7a41</code></a>
use core instead of std</li>
<li><a
href="2ee37fdf5b"><code>2ee37fd</code></a>
optimize the copying done in the ringbuffer</li>
<li>Additional commits viewable in <a
href="https://github.com/KillingSpark/zstd-rs/compare/v0.6.0...v0.7.0">compare
view</a></li>
</ul>
</details>
<br />


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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-03 19:58:37 +00:00
Bob Gardner
0db9fc92cd
Added CompassQuadrant and CompassOctant as per #13647 (#13653)
# Objective

Implements #13647 

## Solution

Created two enums, CompassQuadrant and CompassOctant inside compass.rs
with impls To and From Dir2. Used dir.to_angle().to_degrees() and
matched against the resulting value. I could have skipped to_degrees()
and matched against the radian value, but I thought this was more
readable. I'm probably wrong lol.

## Testing

Tested various dirs to compass variations.

---

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-03 19:46:50 +00:00
Ricky Taylor
9b9d3d81cb
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492

## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.

## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.

---

## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.

## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
Brandon Reinhart
7570c9f3d2
Map entities from a resource when written to the world. (#13650)
# Objective

- Fix #10958 by performing entity mapping on the entities inside of
resources.

## Solution

- Resources can reflect(MapEntitiesResource) and impl MapEntities to get
access to the mapper during the world insert of the scene.

## Testing

- A test resource_entity_map_maps_entities confirms the desired
behavior.

## Changelog

- Added reflect(MapEntitiesResource) for mapping entities on Resources
in a DynamicScene.

fixes 10958
2024-06-03 16:33:24 +00:00
Gonçalo Rica Pais da Silva
36f2542f63
feat: Reflection implementations on Identifier (#13648)
# Objective

- Follow-up on some changes in #11498
- Unblock using `Identifier` to replace `ComponentId` internals.

## Solution

- Implement the same `Reflect` impls from `Entity` onto `Identifier` as
they share same/similar purposes,

## Testing

- No compile errors. Currently `Identifier` has no serialization impls,
so there's no need to test a serialization/deserialization roundtrip to
ensure correctness.

---

## Changelog

### Added

- Reflection implementations on `Identifier`.
2024-06-03 16:33:14 +00:00
Lynn
e6a0f75a63
More gizmos builders (#13261)
# Objective

- Add GizmoBuilders for some primitives as discussed in #13233

## Solution

- `gizmos.primitive_2d(CIRCLE)` and `gizmos.primitive_2d(ELLIPSE)` now
return `Ellipse2dBuilder` aswell.
- `gizmos.primitive_3d(SPHERE)` and `gizmos.sphere()` now return the
same `SphereBuilder`.
- the `.circle_segments` method on the `SphereBuilder` that used to be
returned by `.sphere()` is now called `.segments`
  - the sphere primitive gizmo now matches the `gizmos.sphere` gizmo
- `gizmos.primitive_2d(ANNULUS)` now returns a `Annulus2dBuilder`
allowing the configuration of the `segments`
- gizmos cylinders and capsules now have only 1 line per axis, similar
to `gizmos.sphere`

## Migration Guide

- Some `gizmos.primitive_nd` methods now return some or different
builders. You may need to adjust types and match statements
- Replace any calls to `circle_segments()` with `.segments()`

---------

Co-authored-by: Raphael Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
2024-06-03 16:10:14 +00:00
Alice Cecile
cca4fc76de
Add compass direction constants to Dir2 (#13636)
# Objective

When working on `leafwing-input-manager` and in my games, I've found
these compass directions to be both clear and useful when attempting to
describe angles in 2 dimensions.

This was directly used when mapping gamepad inputs into 4-way movement
as a virtual dpad, and I expect other uses are common in games.

## Solution

- Add constants corresponding to the 4 cardinal and 4 semi-cardinal
directions.

## Testing

- I've validated the quadrants of each of the directions through
self-review.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-06-03 15:14:13 +00:00
Patrick Walton
5c74c17c24
Move clustering-related types and functions into their own module. (#13640)
As a prerequisite for decals and clustering of light probes, we want
clustering to operate on objects other than lights. (Currently, it only
operates on point and spot lights.) This necessitates a large
refactoring, so I'm splitting it up into small steps.

The first such step is to separate clustering from lighting by moving
clustering-related types and functions out of lighting and into their
own module subtree within the `bevy_pbr` crate. (Ultimately, we may want
to move it to `bevy_render`, but that requires more work and can be a
followup.)

No code changes have been made other than adjusting import lists and
moving code. This is to make this code easy to review. Ultimately, I
want to rename "light" to "clusterable object" in most cases, but doing
that at the same time as moving the code would make reviewing harder. So
instead I'm moving the code first and will follow this up with renaming.

## Migration Guide

* Clustering-related types and functions (e.g.
`assign_lights_to_clusters`) have moved under `bevy_pbr::cluster`, in
preparation for the ability to cluster objects other than lights.
2024-06-03 15:05:48 +00:00
IceSentry
bb51635481
Add subdivisions to PlaneMeshBuilder (#13580)
# Objective

- Plane subdivision was removed without providing an alternative

## Solution

- Add subdivision to the PlaneMeshBuilder

---

## Migration Guide

If you were using `Plane` `subdivisions`, you now need to use
`Plane3d::default().mesh().subdivisions(10)`

fixes https://github.com/bevyengine/bevy/issues/13258
2024-06-03 13:57:07 +00:00
Ben Frankel
52ace67f0e
Clean up substate code a bit (#13638)
# Objective

Small substate code cleanup.

1. Format closure arguments inside macros.
2. Replace `match bool` blocks with `if-else` blocks.
3. Replace `match` block in substate macro with the same one-liner as in
the non-macro version.
2024-06-03 13:49:00 +00:00
MiniaczQ
25f7a29a2f
Move state installation methods from bevy_app to bevy_state (#13637)
# Objective

After separating `bevy_states`, state installation methods like
`init_state` were kept in `bevy_app` under the `bevy_state` feature
flag.
This is problematic, because `bevy_state` is not a core module,
`bevy_app` is, yet it depends on `bevy_state`.
This causes practical problems like the inability to use
`bevy_hierarchy` inside `bevy_state`, because of circular dependencies.

## Solution

- `bevy_state` now has a `bevy_app` feature flag, which gates the new
`AppStateExt` trait.
All previous state installation methods were moved to this trait.
It's implemented for both `SubApp` and `App`.

## Changelog

- All state related app methods are now in `AppExtStates` trait in
`bevy_state`.
- Added `StatesPlugin` which is in `DefaultPlugins` when `bevy_state` is
enabled.

## Migration Guide

`App::init_state` is now provided by the
`bevy_state::app::AppExtStates;` trait: import it if you need this
method and are not blob-importing the `bevy` prelude.
2024-06-03 13:47:08 +00:00
Dmytro Banin
7307d76fb3
Make SceneEntityMapper constructor/destructor public (#13630)
# Objective

`SceneEntityMapper` seems like it could be generally useful.

## Solution

Allow end users to call `SceneEntityMapper::new` and
`SceneEntityMapper::finish`.
2024-06-03 13:37:53 +00:00
Kornel
159b9a9091
Extra info on Image debug assertions (#13628)
Small message change that helps fix invalid slice lengths given to
`Image::new_fill`.
2024-06-03 13:35:33 +00:00
Félix Lescaudey de Maneville
190d032ae4
Additional options to mesh primitives (#13605)
# Objective

Add new options to some primitives, like anchoring for Cones and
cylinders and custom angle ranges for Torus.
I think these kind of options are useful, but I would understand that
these addition feel overkill

## Solution

Add 

## Testing

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

> I used the new options in the `3d_shapes` example with various
parameters and got the expected results

## Changelog

- Added `caps` bool option to toggle cylinder circle caps
- Added `angle_range` f32 range option non full torus shapes
- Added `anchor` enum option for cylinders, with either `Top`,
`Midpoint` or `Bottom`
- Added `anchor` enum option for cones, with either `Tip`, `Midpoint` or
`Base`
- **BREAKING** `TorusMeshBuilder` is no longer `Copy` due to
`RangeInclusive`, we can use a `(f32, f32)` if we want it to be `Copy`
2024-06-03 13:27:11 +00:00
Periwink
223a54629c
Add Hash for Tick (#13525)
# Objective

- There are some situations (networking) where storing `Tick` as a key
in a hashmap is useful
2024-06-03 13:19:00 +00:00
Mark Moissette
d26900a9ea
add handling of all missing gltf extras: scene, mesh & materials (#13453)
# Objective

- fixes #4823 

## Solution

As outlined in the discussion in the linked issue as the best current
solution, this PR adds specific GltfExtras for
 - scenes 
 - meshes
 - materials

- As it is , it is not a breaking change, I hesitated to rename the
current "GltfExtras" component to "PrimitiveGltfExtras", but that would
result in a breaking change and might be a bit confusing as to what
"primitive" that refers to.
 

## Testing

- I included a bare-bones example & asset (exported gltf file from
Blender) with gltf extras at all the relevant levels : scene, mesh,
material

---

## Changelog
- adds "SceneGltfExtras" injected at the scene level if any
- adds "MeshGltfExtras", injected at the mesh level if any
- adds "MaterialGltfExtras", injected at the mesh level if any: ie if a
mesh has a material that has gltf extras, the component will be injected
there.
2024-06-03 13:16:38 +00:00
Pietro
061bee7e3c
fix: upgrade to winit v0.30 (#13366)
# Objective

- Upgrade winit to v0.30
- Fixes https://github.com/bevyengine/bevy/issues/13331

## Solution

This is a rewrite/adaptation of the new trait system described and
implemented in `winit` v0.30.

## Migration Guide

The custom UserEvent is now renamed as WakeUp, used to wake up the loop
if anything happens outside the app (a new
[custom_user_event](https://github.com/bevyengine/bevy/pull/13366/files#diff-2de8c0a8d3028d0059a3d80ae31b2bbc1cde2595ce2d317ea378fe3e0cf6ef2d)
shows this behavior.

The internal `UpdateState` has been removed and replaced internally by
the AppLifecycle. When changed, the AppLifecycle is sent as an event.

The `UpdateMode` now accepts only two values: `Continuous` and
`Reactive`, but the latter exposes 3 new properties to enable reactive
to device, user or window events. The previous `UpdateMode::Reactive` is
now equivalent to `UpdateMode::reactive()`, while
`UpdateMode::ReactiveLowPower` to `UpdateMode::reactive_low_power()`.

The `ApplicationLifecycle` has been renamed as `AppLifecycle`, and now
contains the possible values of the application state inside the event
loop:
* `Idle`: the loop has not started yet
* `Running` (previously called `Started`): the loop is running
* `WillSuspend`: the loop is going to be suspended
* `Suspended`: the loop is suspended
* `WillResume`: the loop is going to be resumed

Note: the `Resumed` state has been removed since the resumed app is just
running.

Finally, now that `winit` enables this, it extends the `WinitPlugin` to
support custom events.

## Test platforms

- [x] Windows
- [x] MacOs
- [x] Linux (x11)
- [x] Linux (Wayland)
- [x] Android
- [x] iOS
- [x] WASM/WebGPU
- [x] WASM/WebGL2

## Outstanding issues / regressions

- [ ] iOS: build failed in CI
   - blocking, but may just be flakiness
- [x] Cross-platform: when the window is maximised, changes in the scale
factor don't apply, to make them apply one has to make the window
smaller again. (Re-maximising keeps the updated scale factor)
    - non-blocking, but good to fix
- [ ] Android: it's pretty easy to quickly open and close the app and
then the music keeps playing when suspended.
    - non-blocking but worrying
- [ ]  Web: the application will hang when switching tabs
- Not new, duplicate of https://github.com/bevyengine/bevy/issues/13486
- [ ] Cross-platform?: Screenshot failure, `ERROR present_frames:
wgpu_core::present: No work has been submitted for this frame before`
taking the first screenshot, but after pressing space
    - non-blocking, but good to fix

---------

Co-authored-by: François <francois.mockers@vleue.com>
2024-06-03 13:06:48 +00:00
Vitaliy Sapronenko
44c8cc66c4
Improvement of AssetServer::load documentation to help find a way to load from file with hash in filename (#13272)
# Objective

- Fixes #13192 .
- It is not possible to specify the path of the file and the subasset in
it in one string slice, if there is a hash in the file name, because
hash is separator between filename and subasset, so they must be
separated explicitly

## Solution

- Improved documentation for AssetServer::load.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-06-03 12:54:29 +00:00
s-puig
21b3666abf
More idiomatic texture atlas builder (#13238)
# Objective

- TextureAtlasBuilder has some non-idiomatic methods.

## Solution

- Refactor non-idiomatic methods

---

## Changelog

- Renamed `TextureAtlasBuilder::finish()` to
`TextureAtlasBuilder::build()`
- Builder methods return `&mut Self` instead of `Self`

## Migration Guide

```diff
- let mut texture_atlas_builder = TextureAtlasBuilder::default().padding(UVec2::default()).format(..);
+ let mut texture_atlas_builder = TextureAtlasBuilder::default();
+ texture_atlas_builder.padding(UVec2::default()).format(..);

- let (texture_atlas_layout, texture) = texture_atlas_builder.finish().unwrap();
+ let (texture_atlas_layout, texture) = texture_atlas_builder.build().unwrap();
```
2024-06-03 12:43:50 +00:00
JMS55
5536079945
Meshlet single pass depth downsampling (SPD) (#13003)
# Objective
- Using multiple raster passes to generate the depth pyramid is
extremely slow
- Pulling data from the source image is the largest bottleneck, it's
important to sample in a cache-aware pattern
- Barriers and pipeline drain between the raster passes is the second
largest bottleneck
- Each separate RenderPass on the CPU is _really_ expensive

## Solution
- Port [FidelityFX SPD](https://gpuopen.com/fidelityfx-spd) to WGSL,
replacing meshlet's existing multiple raster passes with a ~~single~~
two compute dispatches. Lack of coherent buffers means we have to do the
the last 64x64 tile from mip 7+ in a separate dispatch to ensure the mip
6 writes were flushed :(
- Workgroup shared memory version only at the moment, as the subgroup
operation is blocked by our upgrade to wgpu 0.20 #13186
- Don't enforce a power-of-2 depth pyramid texture size, simply scaling
by 0.5 is fine
2024-06-03 12:41:14 +00:00
Aevyrie
b45786df41
Add Skybox Motion Vectors (#13617)
# Objective

- Add motion vector support to the skybox
- This fixes the last remaining "gap" to complete the motion blur
feature

## Solution

- Add a pipeline for the skybox to write motion vectors to the prepass

## Testing

- Used examples to test motion vectors using motion blur


https://github.com/bevyengine/bevy/assets/2632925/74c0778a-7e77-4e68-8111-05791e4bfdd2

---------

Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-06-02 16:09:28 +00:00
BD103
7d3fcd5067
Update to rodio 0.18 (#13612)
# Objective

- Adopted from #13528.
- `rodio` released 0.18! While we are working on migrating away from it
and towards `kira`, it is still good to keep our dependencies
up-to-date.

## Solution

- Update `Cargo.toml` to depend on `rodio` 0.18.
- #13528 was failing because it didn't update `rodio` for
`wasm32-unknown-unknown` too.

## Testing

- The CI should catch any errors here, but you can also run an audio
example if you want like `spatial_audio_2d`.

---

## Changelog

- Updated `rodio` to 0.18.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-02 14:25:51 +00:00
MiniaczQ
07aa9e5641
Combine transition systems of Substates (#13626)
# Objective

Prerequisite to #13579.
Combine separate `Substates` transition systems to centralize transition
logic and exert more control over it.

## Solution

Originally the transition happened in 2 stages:
- `apply_state_transition` in `ManualTransitions` handled `NextState`,
- closure system in `DependentTransitions` handled parent-related
changes, insertion and deletion of the substate.

Now:
- Both transitions are processed in a single closure system during
`DependentTransitions`.
- Since `Substates` no longer use `ManualTransitions`, it's been renamed
to `RootTransitions`. Only root states use it.
- When `Substates` state comes into existence, it will try to initialize
from `NextState` and fallback to `should_exist` result.
- Remove `apply_state_transition` from public API.

Consequentially, removed the possibility of multiple
`StateTransitionEvent`s when both transition systems fire in a single
frame.

## Changelog

- Renamed `ManualTransitions` to `RootTransitions`.
- `Substates` will initialize their value with `NextState` if available
and fallback to `should_exist` result.

## Migration Guide

- `apply_state_transition` is no longer publicly available, run the
`StateTransition` schedule instead.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-02 13:36:44 +00:00
Giacomo Stevanato
09fb6b4820
Use correct minimal version of meshopt (#13551)
# Objective

- The current version of the `meshopt` dependency is incorrect, as
`bevy_pbr` uses features introduced in `meshopt` `0.2.1`
- This causes errors like this when only `meshopt` `0.2` is present in
`Cargo.lock`:
    ```
error[E0432]: unresolved imports
`meshopt::ffi::meshopt_optimizeMeshlet`, `meshopt::simplify_scale`
	  --> crates\bevy_pbr\src\meshlet\from_mesh.rs:10:27
	   |
	10 |     ffi::{meshopt_Bounds, meshopt_optimizeMeshlet},
	   |                           ^^^^^^^^^^^^^^^^^^^^^^^
	   |                           no `meshopt_optimizeMeshlet` in `ffi`
| help: a similar name exists in the module: `meshopt_optimizeOverdraw`
11 | simplify, simplify_scale, Meshlets, SimplifyOptions,
VertexDataAdapter,
	   |               ^^^^^^^^^^^^^^ no `simplify_scale` in the root
    ```

## Solution

- Specify the actual minimum version of `meshopt` that `bevy_pbr`
requires
2024-06-02 00:56:29 +00:00
MiniaczQ
5cb4808026
Simplify state transitions (#13616)
# Objective

Prerequisite to #13579.
Make state transition schedule running simpler.

## Solution

- Remove `should_run_transition` which read the latest event and
fake-fire an event for the startup transitions (e.g. startup
`OnEnter()`).
- Account for startup event, by actually emitting an event when adding
states to `App`.
- Replace `should_run_transition` with `last_transition`, which is a
light wrapper over `EventReader::read().last()`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-01 21:00:38 +00:00
Olle Lukowski
4b996c75ab
Implemented GizmoPrimitive2d for Arc2d, CircularSegment, CircularSector, and make arc_2d use counter-clockwise angle. (#13610)
# Objective

Fixes #13606.
Also Fixes #13614.

## Solution

Added the missing trait impls, and made `gizmos.arc_2d()` work with a
counter-clockwise angle.
## Testing

- Updated the render_primitives example, and it works.
2024-06-01 12:30:34 +00:00
Torstein Grindvik
178959b53a
Allow bevy_transform to be used as a barebones dependency (#13533)
# Objective

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

Allow using the `bevy_transform` crate for its definitions of
`Transform` (and `GlobalTransform`) which are re-usable in many
contexts, including ones where other parts of Bevy (ECS, reflection,
etc.) are not necessarily needed or wanted due to the big dependency
tree.

## Solution

Introduce a feature flag "bevy-support" in the `bevy_transform` crate
which makes the dependency tree small when default features are off.

## Testing

Both `cargo b` and `cargo b --no-default-features` builds.

The dependency tree **before**:

```text
bevy_transform v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_transform)
├── bevy_app v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_app)
│   ├── bevy_derive v0.14.0-dev (proc-macro) (/home/togr/repos/bevy/crates/bevy_derive)
│   │   ├── bevy_macro_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_macro_utils)
│   │   │   ├── proc-macro2 v1.0.83
│   │   │   │   └── unicode-ident v1.0.12
│   │   │   ├── quote v1.0.36
│   │   │   │   └── proc-macro2 v1.0.83 (*)
│   │   │   ├── syn v2.0.65
│   │   │   │   ├── proc-macro2 v1.0.83 (*)
│   │   │   │   ├── quote v1.0.36 (*)
│   │   │   │   └── unicode-ident v1.0.12
│   │   │   └── toml_edit v0.22.13
│   │   │       ├── indexmap v2.2.6
│   │   │       │   ├── equivalent v1.0.1
│   │   │       │   └── hashbrown v0.14.5
│   │   │       ├── toml_datetime v0.6.6
│   │   │       └── winnow v0.6.8
│   │   ├── quote v1.0.36 (*)
│   │   └── syn v2.0.65 (*)
│   ├── bevy_ecs v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ecs)
│   │   ├── bevy_ecs_macros v0.14.0-dev (proc-macro) (/home/togr/repos/bevy/crates/bevy_ecs/macros)
│   │   │   ├── bevy_macro_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_macro_utils) (*)
│   │   │   ├── proc-macro2 v1.0.83 (*)
│   │   │   ├── quote v1.0.36 (*)
│   │   │   └── syn v2.0.65 (*)
│   │   ├── bevy_ptr v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ptr)
│   │   ├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect)
│   │   │   ├── bevy_math v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_math)
│   │   │   │   ├── approx v0.5.1
│   │   │   │   │   └── num-traits v0.2.19
│   │   │   │   │       [build-dependencies]
│   │   │   │   │       └── autocfg v1.3.0
│   │   │   │   ├── glam v0.27.0
│   │   │   │   │   ├── approx v0.5.1 (*)
│   │   │   │   │   ├── bytemuck v1.16.0
│   │   │   │   │   ├── rand v0.8.5
│   │   │   │   │   │   └── rand_core v0.6.4
│   │   │   │   │   └── serde v1.0.202
│   │   │   │   │       └── serde_derive v1.0.202 (proc-macro)
│   │   │   │   │           ├── proc-macro2 v1.0.83 (*)
│   │   │   │   │           ├── quote v1.0.36 (*)
│   │   │   │   │           └── syn v2.0.65 (*)
│   │   │   │   ├── rand v0.8.5 (*)
│   │   │   │   ├── serde v1.0.202 (*)
│   │   │   │   ├── smallvec v1.13.2
│   │   │   │   └── thiserror v1.0.61
│   │   │   │       └── thiserror-impl v1.0.61 (proc-macro)
│   │   │   │           ├── proc-macro2 v1.0.83 (*)
│   │   │   │           ├── quote v1.0.36 (*)
│   │   │   │           └── syn v2.0.65 (*)
│   │   │   ├── bevy_ptr v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ptr)
│   │   │   ├── bevy_reflect_derive v0.14.0-dev (proc-macro) (/home/togr/repos/bevy/crates/bevy_reflect/derive)
│   │   │   │   ├── bevy_macro_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_macro_utils) (*)
│   │   │   │   ├── proc-macro2 v1.0.83 (*)
│   │   │   │   ├── quote v1.0.36 (*)
│   │   │   │   ├── syn v2.0.65 (*)
│   │   │   │   └── uuid v1.8.0
│   │   │   │       └── getrandom v0.2.15
│   │   │   │           ├── cfg-if v1.0.0
│   │   │   │           └── libc v0.2.155
│   │   │   ├── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils)
│   │   │   │   ├── ahash v0.8.11
│   │   │   │   │   ├── cfg-if v1.0.0
│   │   │   │   │   ├── getrandom v0.2.15 (*)
│   │   │   │   │   ├── once_cell v1.19.0
│   │   │   │   │   └── zerocopy v0.7.34
│   │   │   │   │   [build-dependencies]
│   │   │   │   │   └── version_check v0.9.4
│   │   │   │   ├── bevy_utils_proc_macros v0.14.0-dev (proc-macro) (/home/togr/repos/bevy/crates/bevy_utils/macros)
│   │   │   │   │   ├── proc-macro2 v1.0.83 (*)
│   │   │   │   │   ├── quote v1.0.36 (*)
│   │   │   │   │   └── syn v2.0.65 (*)
│   │   │   │   ├── hashbrown v0.14.5
│   │   │   │   │   ├── ahash v0.8.11 (*)
│   │   │   │   │   ├── allocator-api2 v0.2.18
│   │   │   │   │   └── serde v1.0.202 (*)
│   │   │   │   ├── thread_local v1.1.8
│   │   │   │   │   ├── cfg-if v1.0.0
│   │   │   │   │   └── once_cell v1.19.0
│   │   │   │   ├── tracing v0.1.40
│   │   │   │   │   ├── pin-project-lite v0.2.14
│   │   │   │   │   └── tracing-core v0.1.32
│   │   │   │   │       └── once_cell v1.19.0
│   │   │   │   └── web-time v0.2.4
│   │   │   ├── downcast-rs v1.2.1
│   │   │   ├── erased-serde v0.4.5
│   │   │   │   ├── serde v1.0.202 (*)
│   │   │   │   └── typeid v1.0.0
│   │   │   ├── glam v0.27.0 (*)
│   │   │   ├── serde v1.0.202 (*)
│   │   │   ├── smallvec v1.13.2
│   │   │   ├── smol_str v0.2.2
│   │   │   └── thiserror v1.0.61 (*)
│   │   ├── bevy_tasks v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_tasks)
│   │   │   ├── async-executor v1.11.0
│   │   │   │   ├── async-task v4.7.1
│   │   │   │   ├── concurrent-queue v2.5.0
│   │   │   │   │   └── crossbeam-utils v0.8.20
│   │   │   │   ├── fastrand v2.1.0
│   │   │   │   ├── futures-lite v2.3.0
│   │   │   │   │   ├── fastrand v2.1.0
│   │   │   │   │   ├── futures-core v0.3.30
│   │   │   │   │   ├── futures-io v0.3.30
│   │   │   │   │   ├── parking v2.2.0
│   │   │   │   │   └── pin-project-lite v0.2.14
│   │   │   │   └── slab v0.4.9
│   │   │   │       [build-dependencies]
│   │   │   │       └── autocfg v1.3.0
│   │   │   └── futures-lite v2.3.0 (*)
│   │   ├── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils) (*)
│   │   ├── bitflags v2.5.0
│   │   ├── concurrent-queue v2.5.0 (*)
│   │   ├── fixedbitset v0.5.7
│   │   ├── nonmax v0.5.5
│   │   ├── petgraph v0.6.5
│   │   │   ├── fixedbitset v0.4.2
│   │   │   └── indexmap v2.2.6 (*)
│   │   └── thiserror v1.0.61 (*)
│   ├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect) (*)
│   ├── bevy_state v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_state)
│   │   ├── bevy_ecs v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ecs) (*)
│   │   ├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect) (*)
│   │   ├── bevy_state_macros v0.14.0-dev (proc-macro) (/home/togr/repos/bevy/crates/bevy_state/macros)
│   │   │   ├── bevy_macro_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_macro_utils) (*)
│   │   │   ├── proc-macro2 v1.0.83 (*)
│   │   │   ├── quote v1.0.36 (*)
│   │   │   └── syn v2.0.65 (*)
│   │   └── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils) (*)
│   ├── bevy_tasks v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_tasks) (*)
│   ├── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils) (*)
│   ├── downcast-rs v1.2.1
│   └── thiserror v1.0.61 (*)
├── bevy_ecs v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ecs) (*)
├── bevy_hierarchy v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_hierarchy)
│   ├── bevy_app v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_app) (*)
│   ├── bevy_core v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_core)
│   │   ├── bevy_app v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_app) (*)
│   │   ├── bevy_ecs v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ecs) (*)
│   │   ├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect) (*)
│   │   ├── bevy_tasks v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_tasks) (*)
│   │   ├── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils) (*)
│   │   └── uuid v1.8.0
│   ├── bevy_ecs v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_ecs) (*)
│   ├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect) (*)
│   ├── bevy_utils v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_utils) (*)
│   └── smallvec v1.13.2
├── bevy_math v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_math) (*)
├── bevy_reflect v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_reflect) (*)
└── thiserror v1.0.61 (*)
```

The dependency tree **after** (no default features):

```text
bevy_transform v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_transform)
├── bevy_math v0.14.0-dev (/home/togr/repos/bevy/crates/bevy_math)
│   ├── approx v0.5.1
│   │   └── num-traits v0.2.19
│   │       [build-dependencies]
│   │       └── autocfg v1.3.0
│   ├── glam v0.27.0
│   │   ├── approx v0.5.1 (*)
│   │   ├── bytemuck v1.16.0
│   │   └── rand v0.8.5
│   │       └── rand_core v0.6.4
│   ├── rand v0.8.5 (*)
│   ├── smallvec v1.13.2
│   └── thiserror v1.0.61
│       └── thiserror-impl v1.0.61 (proc-macro)
│           ├── proc-macro2 v1.0.83
│           │   └── unicode-ident v1.0.12
│           ├── quote v1.0.36
│           │   └── proc-macro2 v1.0.83 (*)
│           └── syn v2.0.65
│               ├── proc-macro2 v1.0.83 (*)
│               ├── quote v1.0.36 (*)
│               └── unicode-ident v1.0.12
└── thiserror v1.0.61 (*)
```

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-06-01 11:34:49 +00:00
François Mockers
5559632977
glTF labels: add enum to avoid misspelling and keep up-to-date list documented (#13586)
# Objective

- Followup to #13548
- It added a list of all possible labels to documentation. This seems
hard to keep up and doesn't stop people from making spelling mistake

## Solution

- Add an enum that can create all the labels possible, and encourage its
use rather than manually typed labels

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-05-31 23:25:57 +00:00
François Mockers
ce46d52536
unload unused images that are RenderAssetUsages::RENDER_WORLD (#13609)
# Objective

- Fixes #13500
- Images that are `RenderAssetUsages::RENDER_WORLD` don't free their
memory when they are no longer used

## Solution

- Remove their bind group when the handles are unused
2024-05-31 17:13:29 +00:00
Patrick Walton
be053b1d7c
Implement motion vectors and TAA for skinned meshes and meshes with morph targets. (#13572)
This is a revamped equivalent to #9902, though it shares none of the
code. It handles all special cases that I've tested correctly.

The overall technique consists of double-buffering the joint matrix and
morph weights buffers, as most of the previous attempts to solve this
problem did. The process is generally straightforward. Note that, to
avoid regressing the ability of mesh extraction, skin extraction, and
morph target extraction to run in parallel, I had to add a new system to
rendering, `set_mesh_motion_vector_flags`. The comment there explains
the details; it generally runs very quickly.

I've tested this with modified versions of the `animated_fox`,
`morph_targets`, and `many_foxes` examples that add TAA, and the patch
works. To avoid bloating those examples, I didn't add switches for TAA
to them.

Addresses points (1) and (2) of #8423.

## Changelog

### Fixed

* Motion vectors, and therefore TAA, are now supported for meshes with
skins and/or morph targets.
2024-05-31 17:02:28 +00:00
Dmytro Banin
42d80375db
Add ability to clear all components on an entity via EntityWorldMut (#13588)
# Objective

Adds capability to clear all components on an entity without de-spawning
said entity.

## Testing

The function calls `remove_by_id` on every component in the entity
archetype - wasn't sure if it's worth going out of our way to create a
test for this considering `remove_by_id` is already unit tested.

---

## Changelog

Added `clear` function to `EntityWorldMut` which removes all components
on an entity.

## Migration Guide

N/A

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-31 16:42:03 +00:00
Martín Maita
f237cf2441
Updates default Text font size to 24px (#13603)
# Objective

- The default font size is too small to be useful in examples or for
debug text.
- Fixes #13587

## Solution

- Updated the default font size value in `TextStyle` from 12px to 24px.
- Resorted to Text defaults in examples to use the default font size in
most of them.

## Testing

- WIP

---

## Migration Guide

- The default font size has been increased to 24px from 12px. Make sure
you set the font to the appropriate values in places you were using
`Default` text style.
2024-05-31 16:41:27 +00:00
Torstein Grindvik
76d12fa2b3
bevy_transform split up to allow feature gate modularity (#13599)
# Objective

Part of https://github.com/bevyengine/bevy/issues/13529
Helps https://github.com/bevyengine/bevy/pull/13533

Splitting up `bevy_transform` makes it easier to selectively include or
exclude parts of it in such a way that it's possible to include only a
small part with a small dependency tree.

## Solution

Make the crate more modular.

---------

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-05-31 16:40:36 +00:00
charlotte
0f03e1d46e
Fix docs for RenderLayers (#13604)
Doc fixup, closes #13598
2024-05-31 15:42:08 +00:00
MiniaczQ
912f77b2fe
Unify transition names to exited and entered (#13594)
# Objective

Unifies the naming convention between `StateTransitionEvent<S>` and
transition schedules.

## Migration Guide

- `StateTransitionEvent<S>` and `OnTransition<S>` schedule had their
fields renamed to `exited` and `entered` to match schedules.
2024-05-31 15:20:01 +00:00
IceSentry
ea283c1dea
Add some missing reflect for volumetric fog types (#13592)
# Objective

- While experimenting with it I realized it's not reflectable

## Solution

- Add missing Reflect derive
2024-05-31 10:20:15 +00:00
Alix Bott
31955cc78b
Add ImageFormatSetting::Guess to image loader (#13575)
# Objective

- Allow using image assets that don't have an extensions and whose
format is unknown. This is useful for loading images from arbitrary HTTP
URLs.

## Solution

- This PR adds a new variant to `ImageFormatSetting` called `Guess`. The
loader will use `image::guess_format` to deduce the format based on the
content of the file.

## Testing

- I locally removed the extension of bevy_bird_dark, and ran a modified
version of the `sprite` example:
```rust
//! Displays a single [`Sprite`], created from an image.

use bevy::{
    prelude::*,
    render::texture::{ImageFormatSetting, ImageLoaderSettings},
};

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

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2dBundle::default());
    commands.spawn(SpriteBundle {
        texture: asset_server
            .load_with_settings("branding/bevy_bird_dark", |s: &mut ImageLoaderSettings| {
                s.format = ImageFormatSetting::Guess
            }),
        ..default()
    });
}

```

## Changelog

### Added

`ImageFormatSetting::Guess` to automatically guess the format of an
image asset from its content.

Co-authored-by: François Mockers <mockersf@gmail.com>
2024-05-30 23:57:22 +00:00
Alice Cecile
61af3d231b
Update docs for NextState (#13578)
# Objective

Fixes #13577.

## Solution

Explain how the resource works now.

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-30 19:51:02 +00:00
Nico Burns
a3e60d39b7
Fix image measure function to apply inherent aspect ratio to style sizes (#13555)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/13155
- fixes https://github.com/bevyengine/bevy/issues/13517
- Supercedes https://github.com/bevyengine/bevy/pull/13381
- Requires https://github.com/DioxusLabs/taffy/pull/661

## Solution

- Taffy has been updated to:
    - Apply size styles to absolutely positioned children
    - Pass the node's `Style` through to the measure function
- Bevy's image measure function has been updated to make use of this
style information

## Notes

- This is currently using a git version of Taffy. If this is tested as
fixing the issue then we can turn that into a Taffy 0.5 release (this
would be the only change between Taffy 0.4 and Taffy 0.5 so upgrading is
not expected to be an issue)
- This implementation may not be completely correct. I would have
preferred to extend Taffy's gentest infrastructure to handle images and
used that to nail down the correct behaviour. But I don't have time for
that atm so we'll have to iterate on this in future. This PR at least
puts that under Bevy's control.

## Testing

- I manually tested the game_menu_example (from
https://github.com/bevyengine/bevy/issues/13155)
- More testing is probably merited

---

## Changelog

No changelog should be required as it fixes a regression on `main` that
was not present in bevy 0.13. The changelog for "Taffy upgrade" may want
to be changed from 0.4 to 0.5 if this change gets merged.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-05-30 18:37:39 +00:00
Vic
5cfb063d4a
constrain WorldQuery::init_state argument to ComponentInitializer (#13442)
# Objective

In #13343, `WorldQuery::get_state` was constrained from `&World` as the
argument to `&Components`, but `WorldQuery::init_state` hasn't yet been
changed from `&mut World` to match.

Fixes #13358

## Solution

Create a wrapper around `&mut Components` and `&mut Storages` that can
be obtained from `&mut World` with a `component_initializer` method.
This new `ComponentInitializer` re-exposes the API on `&mut Components`
minus the `&mut Storages` parameter where it was present. For the
`&Components` API, it simply derefs to its `components` field.

## Changelog

### Added
The `World::component_initializer` method.
The `ComponentInitializer` struct that re-exposes `Components` API.
### Changed
`WorldQuery::init_state` now takes `&mut ComponentInitializer` instead
of `&mut World`.

## Migration Guide
Instead of passing `&mut World` to `WorldQuery::init_state` directly,
pass in a mutable reference to the struct returned from
`World::component_initializer`.
2024-05-30 14:47:22 +00:00
François Mockers
e208fb70f5
disable gpu preprocessing on android with Adreno 6xx GPU (#13323)
# Objective

- Fixes #13038 

## Solution

- Disable gpu preprocessing when feature
`SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING` is not
available

## Testing

- Tested on android device that used to crash
2024-05-30 14:33:27 +00:00
Aevyrie
16fe7e64cc
Fix: Motion blur should sample onscreen fragments with no depth (#13573)
# Objective

- Motion blur does not currently work with skyboxes or anything else
that does not write to depth.

## Solution

- When computing blur, include fragments with no depth, as long as they
are onscreen.

## Testing

- Tested with the examples - the motion_blur example uncovered a bug
with this fix, where offscreen pixels where now being sampled and
causing artifacts.
- Attached example showing the skybox being sampled in the blur (note
the feathering on edges):



https://github.com/bevyengine/bevy/assets/2632925/fc14b0c1-2394-46a5-a2b9-a859efcd23ef
2024-05-30 13:52:47 +00:00
Aevyrie
c566ae7155
Run motion blur before TAA to reduce artifacts (#13574)
# Objective

- Reduce edge artifacts and noise in motion blur with TAA.

## Solution

- Reorder's motion blur and TAA, so TAA is run after motion blur.

## Testing

- Tested with built in examples, as well as some external test scenes.

Before:


![image](https://github.com/bevyengine/bevy/assets/2632925/5522b749-9235-4b11-b560-c35350ab4b92)


![image](https://github.com/bevyengine/bevy/assets/2632925/e675aa0d-de0d-4833-9c33-ba7b3cd79955)


After:


![image](https://github.com/bevyengine/bevy/assets/2632925/97261093-1b8e-41ab-840f-f999a4e15a6d)


![image](https://github.com/bevyengine/bevy/assets/2632925/70215d8f-2ec7-4835-9e2d-ccead8972a5e)
2024-05-30 13:52:02 +00:00
Lynn
32a44e14e6
Implement ShapeSample for Extrusion<T> (#13567)
# Objective

- Implement `ShapeSample` for `Extrusion<T>`
2024-05-30 12:08:28 +00:00
François Mockers
4065098586
Fix UI in WebGPU: call textureSample from outside the if (#13546)
# Objective

- since #13523, UI is broken in WebGPU

```
Compilation log for [Invalid ShaderModule (unlabeled)]:
1 error(s) generated while compiling the shader:
:108:27 error: 'textureSample' must only be called from uniform control flow
    let texture_color_1 = textureSample(sprite_texture, sprite_sampler, in_2.uv);
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:151:19 note: called by 'draw_background' from 'fragment'
        let _e5 = draw_background(in);
                  ^^^^^^^^^^^^^^^^^^^

:147:5 note: control flow depends on possibly non-uniform value
    if _e3 {
    ^^

:146:23 note: parameter 'in' of 'fragment' may be non-uniform
    let _e3 = enabled(in.flags, BORDER);
```


## Solution

- call `textureSample` from outside the if. both branches are using the
same parameters
2024-05-29 23:03:57 +00:00
Alice Cecile
9d74e16821
Set the default target exposure to the minimum value, not 0 (#13562)
# Objective

- In particularly dark scenes, auto-exposure would lead to an unexpected
darkening of the view.
- Fixes #13446.

## Solution

The average luminance should default to something else than 0.0 instead,
when there are no samples. We set it to `settings.min_log_lum`.

## Testing

I was able to reproduce the problem on the `auto_exposure` example by
setting the point light intensity to 2000 and looking into the
right-hand corner. There was a sudden darkening.

Now, the discontinuity is gone.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
2024-05-29 22:37:42 +00:00
Lynn
4e72bf4751
Clarify cone position (#13568)
# Objective

- Fixes #10616

## Solution

- Added docs describing the center as being the midpoint between the tip
and the center of its base.
2024-05-29 20:19:58 +00:00
IceSentry
29d6575e22
Add docs to bevy_gltf about loading parts of a Gltf asset (#13548)
# Objective

- The Gltf loader has a ton of features to load parts of an asset that
are essentially undocumented.

## Solution

- Add some docs to explain some of those features
- The docs is definitely inspired by the bevy cheatbook page on the
subject but it goes in a lot less details

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-05-28 22:45:22 +00:00
Patrick Walton
05288ffa32
Generalize component reflection to operate on FilteredEntityRef and FilteredEntityMut, not EntityRef and EntityMut. (#13549)
Currently, either an `EntityRef` or `EntityMut` is required in order to
reflect a component on an entity. This can, however, be generalized to
`FilteredEntityRef` and `FilteredEntityMut`, which are versions of
`EntityRef` and `EntityMut` that restrict the components that can be
accessed. This is useful because dynamic queries yield
`FilteredEntityRef` and `FilteredEntityMut` rows when iterated over.

This commit changes `ReflectComponent::contains()`,
`ReflectComponent::reflect()`, and `ReflectComponent::reflect_mut()` to
take an `Into<FilteredEntityRef>` (in the case of `contains()` and
`reflect()`) and `Into<FilteredEntityMut>` (in the case of
`reflect_mut()`). Fortunately, `EntityRef` and `EntityMut` already
implement the corresponding trait, so nothing else has to be done to the
public API. Note that in order to implement
`ReflectComponent::reflect_mut()` properly, an additional method
`FilteredEntityMut::into_mut()` was required, to match the one on
`EntityMut`.

I ran into this when attempting to implement `QUERY` in the Bevy Remote
Protocol when trying to iterate over rows of dynamic queries and fetch
the associated components without unsafe code. There were other
potential ways to work around this problem, but they required either
reimplementing the query logic myself instead of using regular Bevy
queries or storing entity IDs and then issuing another query to fetch
the associated `EntityRef`. Both of these seemed worse than just
improving the `reflect()` function.

## Migration Guide

* `ReflectComponent::contains`, `ReflectComponent::reflect`, and
`ReflectComponent::reflect_mut` now take `FilteredEntityRef` (in the
case of `contains()` and `reflect()`) and `FilteredEntityMut` (in the
case of `reflect_mut()`) parameters. `FilteredEntityRef` and
`FilteredEntityMut` have very similar APIs to `EntityRef` and
`EntityMut` respectively, but optionally restrict the components that
can be accessed.
2024-05-28 14:02:09 +00:00
Giacomo Stevanato
d98d6d8d00
Fix unsoundness in FilteredEntity{Ref,Mut} various get methods (#13554)
# Objective

- `FilteredEntity{Ref,Mut}` various `get` methods never checked that the
given component was present on the entity, only the access allowed
reading/writing them, which is always the case when it is constructed
from a `EntityRef`/`EntityMut`/`EntityWorldMut` (and I guess can also
happen with queries containing `Option<T>` that get transmuted).
- In those cases the various `get` methods were calling
`debug_checked_unwrap` on `None`s, which is UB when debug assertions are
not enabled;
- The goal is thus to fix this soundness issue.

## Solution

- Don't call `debug_checked_unwrap` on those `None` and instead
`flatten` them.

## Testing

- This PR includes regression tests for each combination of
`FilteredEntityRef`/`FilteredEntityMut` and component
present/not-present. The two tests for the not-present cases fail on
`main` but success with this PR changes.
2024-05-28 14:01:23 +00:00
James O'Brien
bc102d41de
Refactor command application for more consistency (#13249)
# Objective

- Prevent the case where a hook/observer is triggered but the source
entity/component no longer exists

## Solution

- Re-order command application such that all hooks/observers that are
notified will run before any have a chance to invalidate the result.

## Testing
Updated relevant tests in `bevy_ecs`, all other tests pass.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: Mike Hsu <mike.hsu@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-28 12:17:57 +00:00
arcashka
cdc605cc48
add tonemapping LUT bindings for sprite and mesh2d pipelines (#13262)
Fixes #13118
If you use `Sprite` or `Mesh2d` and create `Camera` with
* hdr=false
* any tonemapper

You would get
```
wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `sprite_pipeline`
    Error matching ShaderStages(FRAGMENT) shader requirements against the pipeline
    Shader global ResourceBinding { group: 0, binding: 19 } is not available in the pipeline layout
    Binding is missing from the pipeline layout
```
Because of missing tonemapping LUT bindings 

## Solution
Add missing bindings for tonemapping LUT's to `SpritePipeline` &
`Mesh2dPipeline`

## Testing
I checked that
* `tonemapping`
* `color_grading`
* `sprite_animations`
* `2d_shapes`
* `meshlet`
* `deferred_rendering`
examples are still working

2d cases I checked with this code:
```
use bevy::{
    color::palettes::css::PURPLE, core_pipeline::tonemapping::Tonemapping, prelude::*,
    sprite::MaterialMesh2dBundle,
};

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

fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
    asset_server: Res<AssetServer>,
) {
    commands.spawn(Camera2dBundle {
        camera: Camera {
            hdr: false,
            ..default()
        },
        tonemapping: Tonemapping::BlenderFilmic,
        ..default()
    });
    commands.spawn(MaterialMesh2dBundle {
        mesh: meshes.add(Rectangle::default()).into(),
        transform: Transform::default().with_scale(Vec3::splat(128.)),
        material: materials.add(Color::from(PURPLE)),
        ..default()
    });

    commands.spawn(SpriteBundle {
        texture: asset_server.load("asd.png"),
        ..default()
    });
}

fn toggle_tonemapping_method(
    keys: Res<ButtonInput<KeyCode>>,
    mut tonemapping: Query<&mut Tonemapping>,
) {
    let mut method = tonemapping.single_mut();

    if keys.just_pressed(KeyCode::Digit1) {
        *method = Tonemapping::None;
    } else if keys.just_pressed(KeyCode::Digit2) {
        *method = Tonemapping::Reinhard;
    } else if keys.just_pressed(KeyCode::Digit3) {
        *method = Tonemapping::ReinhardLuminance;
    } else if keys.just_pressed(KeyCode::Digit4) {
        *method = Tonemapping::AcesFitted;
    } else if keys.just_pressed(KeyCode::Digit5) {
        *method = Tonemapping::AgX;
    } else if keys.just_pressed(KeyCode::Digit6) {
        *method = Tonemapping::SomewhatBoringDisplayTransform;
    } else if keys.just_pressed(KeyCode::Digit7) {
        *method = Tonemapping::TonyMcMapface;
    } else if keys.just_pressed(KeyCode::Digit8) {
        *method = Tonemapping::BlenderFilmic;
    }
}
```
---

## Changelog
Fix the bug which led to the crash when user uses any tonemapper without
hdr for rendering sprites and 2d meshes.
2024-05-28 12:09:26 +00:00
GitGhillie
f45eddfe82
Set ambient_intensity to 0.0 in volumetric_fog example, correct doc comment (#13531)
# Objective

- Fixes #13521

## Solution

Set `ambient_intensity` to 0.0 in volumetric_fog example.

I chose setting it explicitly over changing the default in order to make
it clear that this needs to be set depending on whether you have an
`EnvironmentMapLight`. See documentation for `ambient_intensity` and
related members.

## Testing

- Run the volumetric_fog example and notice how the light shown in
#13521 is not there anymore, as expected.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-28 10:55:29 +00:00
François Mockers
2e8abee14a
use ssr dynamic offset in volumetric fog bind group (#13544)
# Objective

- #13418 broke volumetric fog

```
wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(2, 4, Metal)>`
    In a set_bind_group command
      note: bind group = `mesh_view_bind_group`
    Bind group 0 expects 5 dynamic offsets. However 4 dynamic offsets were provided.
```

## Solution

- add ssr offset to volumetric fog bind group
2024-05-27 21:47:16 +00:00
François Mockers
901d71b81c
fix rounded borders on buttons (#13541)
# Objective

- #13523 introduced a new bug on rounded corners in UI on buttons
- there are artefacts outside of the border, and the text in buttons is
more gray than it should be
- example `color_grading`:

<img width="1280" alt="Screenshot 2024-05-27 at 22 19 13"
src="https://github.com/bevyengine/bevy/assets/8672791/fbb6a8ba-2096-4fcc-9c94-3764e9d16d2f">

## Solution

- Clamp alpha to be between 0.0 and 1.0

<img width="1280" alt="Screenshot 2024-05-27 at 22 18 19"
src="https://github.com/bevyengine/bevy/assets/8672791/295d8e16-30eb-40cc-8d61-4995fca6dded">
2024-05-27 21:46:56 +00:00
Christian Hughes D
8684db139a
Fix bevy_app not compiling without default features (#13532)
# Objective

Fix #13530 (just realized creating an issue was unnecessary since it's a
super simple fix)

## Solution

Add a cfg feature attribute

## Testing

Compiles fine now
2024-05-27 21:22:03 +00:00
Olle Lukowski
d7fc20c484
Implemented Reflect for (almost) all bevy_math types (#13537)
# Objective

Fixes #13535.

## Solution

I implemented `Reflect` for close to all math types now, except for some
types that it would cause issues (like some boxed types).

## Testing

- Everything seems to still build, will await CI though.
---

## Changelog

- Made close to all math types implement `Reflect`.
2024-05-27 18:18:10 +00:00
Mike
cef31ffdd9
Fix various bugs with UI rounded borders (#13523)
# Objective

- Fixes #13503 
- Fix other various bugs I noticed while debugging above issue.

## Solution

- Change the antialiasing(AA) method. It was using fwidth which is the
derivative between pixels, but there were a lot of artifacts being added
from this. So just use the sdf value. This aa method probably isn't as
smooth looking, but better than having artifacts. Below is a
visualization of the fwidth.

![image](https://github.com/bevyengine/bevy/assets/2180432/4e475ad0-c9d0-4a40-af39-5f4422a78392)
- Use the internal sdf for drawing the background instead of the
external sdf and extract the border for these type of nodes. This fixed
2 bugs, one with the background coloring the AA pixels on the edge of
rounded borders. And also allows for the border to use a transparent
color.
- Don't extract borders if all the widths are zero.

## Testing

- played a bunch with the example in the linked issue.
This PR:

![image](https://github.com/bevyengine/bevy/assets/2180432/d7797e0e-e348-4daa-8646-554dc2032523)
Main:

![image](https://github.com/bevyengine/bevy/assets/2180432/4d46c17e-a12d-4e20-aaef-0ffc950cefe2)

- ran the `borders` and `rounded_borders` examples

---

## Changelog

- Fixed various antialiasing issues to do with rounded ui borders.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
2024-05-27 17:42:13 +00:00
dependabot[bot]
8e7b58496c
Update itertools requirement from 0.12 to 0.13 (#13526)
Updates the requirements on
[itertools](https://github.com/rust-itertools/itertools) to permit the
latest version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md">itertools's
changelog</a>.</em></p>
<blockquote>
<h2>0.13.0</h2>
<h3>Breaking</h3>
<ul>
<li>Removed implementation of <code>DoubleEndedIterator</code> for
<code>ConsTuples</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/853">#853</a>)</li>
<li>Made <code>MultiProduct</code> fused and fixed on an empty iterator
(<a
href="https://redirect.github.com/rust-itertools/itertools/issues/835">#835</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/834">#834</a>)</li>
<li>Changed <code>iproduct!</code> to return tuples for maxi one
iterator too (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/870">#870</a>)</li>
<li>Changed <code>PutBack::put_back</code> to return the old value (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/880">#880</a>)</li>
<li>Removed deprecated <code>repeat_call, Itertools::{foreach, step,
map_results, fold_results}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/878">#878</a>)</li>
<li>Removed <code>TakeWhileInclusive::new</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/912">#912</a>)</li>
</ul>
<h3>Added</h3>
<ul>
<li>Added <code>Itertools::{smallest_by, smallest_by_key, largest,
largest_by, largest_by_key}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/654">#654</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/885">#885</a>)</li>
<li>Added <code>Itertools::tail</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/899">#899</a>)</li>
<li>Implemented <code>DoubleEndedIterator</code> for
<code>ProcessResults</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/910">#910</a>)</li>
<li>Implemented <code>Debug</code> for <code>FormatWith</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/931">#931</a>)</li>
<li>Added <code>Itertools::get</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/891">#891</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Deprecated <code>Itertools::group_by</code> (renamed
<code>chunk_by</code>) (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/866">#866</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/879">#879</a>)</li>
<li>Deprecated <code>unfold</code> (use <code>std::iter::from_fn</code>
instead) (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/871">#871</a>)</li>
<li>Optimized <code>GroupingMapBy</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/873">#873</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/876">#876</a>)</li>
<li>Relaxed <code>Fn</code> bounds to <code>FnMut</code> in
<code>diff_with, Itertools::into_group_map_by</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/886">#886</a>)</li>
<li>Relaxed <code>Debug/Clone</code> bounds for <code>MapInto</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/889">#889</a>)</li>
<li>Documented the <code>use_alloc</code> feature (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/887">#887</a>)</li>
<li>Optimized <code>Itertools::set_from</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/888">#888</a>)</li>
<li>Removed badges in <code>README.md</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/890">#890</a>)</li>
<li>Added &quot;no-std&quot; categories in <code>Cargo.toml</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/894">#894</a>)</li>
<li>Fixed <code>Itertools::k_smallest</code> on short unfused iterators
(<a
href="https://redirect.github.com/rust-itertools/itertools/issues/900">#900</a>)</li>
<li>Deprecated <code>Itertools::tree_fold1</code> (renamed
<code>tree_reduce</code>) (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/895">#895</a>)</li>
<li>Deprecated <code>GroupingMap::fold_first</code> (renamed
<code>reduce</code>) (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/902">#902</a>)</li>
<li>Fixed <code>Itertools::k_smallest(0)</code> to consume the iterator,
optimized <code>Itertools::k_smallest(1)</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/909">#909</a>)</li>
<li>Specialized <code>Combinations::nth</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/914">#914</a>)</li>
<li>Specialized <code>MergeBy::fold</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/920">#920</a>)</li>
<li>Specialized <code>CombinationsWithReplacement::nth</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/923">#923</a>)</li>
<li>Specialized <code>FlattenOk::{fold, rfold}</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/927">#927</a>)</li>
<li>Specialized <code>Powerset::nth</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/924">#924</a>)</li>
<li>Documentation fixes (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/882">#882</a>,
<a
href="https://redirect.github.com/rust-itertools/itertools/issues/936">#936</a>)</li>
<li>Fixed <code>assert_equal</code> for iterators longer than
<code>i32::MAX</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/932">#932</a>)</li>
<li>Updated the <code>must_use</code> message of non-lazy
<code>KMergeBy</code> and <code>TupleCombinations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/939">#939</a>)</li>
</ul>
<h3>Notable Internal Changes</h3>
<ul>
<li>Tested iterator laziness (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/792">#792</a>)</li>
<li>Created <code>CONTRIBUTING.md</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/767">#767</a>)</li>
</ul>
<h2>0.12.1</h2>
<h3>Added</h3>
<ul>
<li>Documented iteration order guarantee for
<code>Itertools::[tuple_]combinations</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/822">#822</a>)</li>
<li>Documented possible panic in <code>iterate</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/842">#842</a>)</li>
<li>Implemented <code>Clone</code> and <code>Debug</code> for
<code>Diff</code> (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/845">#845</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d5084d15e9"><code>d5084d1</code></a>
Prepare v0.13.0 release (<a
href="https://redirect.github.com/rust-itertools/itertools/issues/937">#937</a>)</li>
<li><a
href="d7c99d55da"><code>d7c99d5</code></a>
<code>TupleCombinations</code> is not lazy but must be used
nonetheless</li>
<li><a
href="074c7fcc07"><code>074c7fc</code></a>
<code>KMergeBy</code> is not lazy but must be used nonetheless</li>
<li><a
href="2ad9e07ae8"><code>2ad9e07</code></a>
<code>assert_equal</code>: fix
<code>clippy::default_numeric_fallback</code></li>
<li><a
href="0d4efc8432"><code>0d4efc8</code></a>
Remove free function <code>get</code></li>
<li><a
href="05cc0ee256"><code>05cc0ee</code></a>
<code>get(s..=usize::MAX)</code> should be fine when <code>s !=
0</code></li>
<li><a
href="3c16f14baa"><code>3c16f14</code></a>
<code>get</code>: when is it ESI and/or DEI</li>
<li><a
href="4dd6ba0e7c"><code>4dd6ba0</code></a>
<code>get</code>: panics if the range includes
<code>usize::MAX</code></li>
<li><a
href="7a9ce56fc5"><code>7a9ce56</code></a>
<code>get(r: Range)</code> as <code>Skip\&lt;Take&gt;</code></li>
<li><a
href="f676f2f964"><code>f676f2f</code></a>
Remove the unspecified check about
<code>.get(exhausted_range_inclusive)</code></li>
<li>Additional commits viewable in <a
href="https://github.com/rust-itertools/itertools/compare/v0.12.0...v0.13.0">compare
view</a></li>
</ul>
</details>
<br />


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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-27 16:35:52 +00:00
Olle Lukowski
8c7f73ab81
Move bevy_math Reflect impls (#13520)
# Objective

Fixes #13456 

## Solution

Moved `bevy_math`'s `Reflect` impls from `bevy_reflect` to `bevy_math`.


### Quick note
I accidentally used the same commit message while resolving a merge
conflict (first time I had to resolve a conflict). Sorry about that.
2024-05-27 14:15:22 +00:00
Olle Lukowski
cf4baf8fbf
Make gizmos take primitives by ref (#13534)
# Objective

Fixes #13427.

## Solution

I changed the traits, and updated all usages.

## Testing

The `render_primitives` example still works perfectly.

---

## Changelog

- Made `gizmos.primitive_2d()` and `gizmos.primitive_3d()` take the
primitives by ref.

## Migration Guide

- Any usages of `gizmos.primitive_2d()` and/or `gizmos.primitive_3d()`
need to be updated to pass the primitive in by reference.
2024-05-27 13:48:47 +00:00
Patrick Walton
f398674e51
Implement opt-in sharp screen-space reflections for the deferred renderer, with improved raymarching code. (#13418)
This commit, a revamp of #12959, implements screen-space reflections
(SSR), which approximate real-time reflections based on raymarching
through the depth buffer and copying samples from the final rendered
frame. This patch is a relatively minimal implementation of SSR, so as
to provide a flexible base on which to customize and build in the
future. However, it's based on the production-quality [raymarching code
by Tomasz
Stachowiak](https://gist.github.com/h3r2tic/9c8356bdaefbe80b1a22ae0aaee192db).

For a general basic overview of screen-space reflections, see
[1](https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html).
The raymarching shader uses the basic algorithm of tracing forward in
large steps, refining that trace in smaller increments via binary
search, and then using the secant method. No temporal filtering or
roughness blurring, is performed at all; for this reason, SSR currently
only operates on very shiny surfaces. No acceleration via the
hierarchical Z-buffer is implemented (though note that
https://github.com/bevyengine/bevy/pull/12899 will add the
infrastructure for this). Reflections are traced at full resolution,
which is often considered slow. All of these improvements and more can
be follow-ups.

SSR is built on top of the deferred renderer and is currently only
supported in that mode. Forward screen-space reflections are possible
albeit uncommon (though e.g. *Doom Eternal* uses them); however, they
require tracing from the previous frame, which would add complexity.
This patch leaves the door open to implementing SSR in the forward
rendering path but doesn't itself have such an implementation.
Screen-space reflections aren't supported in WebGL 2, because they
require sampling from the depth buffer, which Naga can't do because of a
bug (`sampler2DShadow` is incorrectly generated instead of `sampler2D`;
this is the same reason why depth of field is disabled on that
platform).

To add screen-space reflections to a camera, use the
`ScreenSpaceReflectionsBundle` bundle or the
`ScreenSpaceReflectionsSettings` component. In addition to
`ScreenSpaceReflectionsSettings`, `DepthPrepass` and `DeferredPrepass`
must also be present for the reflections to show up. The
`ScreenSpaceReflectionsSettings` component contains several settings
that artists can tweak, and also comes with sensible defaults.

A new example, `ssr`, has been added. It's loosely based on the
[three.js ocean
sample](https://threejs.org/examples/webgl_shaders_ocean.html), but all
the assets are original. Note that the three.js demo has no screen-space
reflections and instead renders a mirror world. In contrast to #12959,
this demo tests not only a cube but also a more complex model (the
flight helmet).

## Changelog

### Added

* Screen-space reflections can be enabled for very smooth surfaces by
adding the `ScreenSpaceReflections` component to a camera. Deferred
rendering must be enabled for the reflections to appear.

![Screenshot 2024-05-18
143555](https://github.com/bevyengine/bevy/assets/157897/b8675b39-8a89-433e-a34e-1b9ee1233267)

![Screenshot 2024-05-18
143606](https://github.com/bevyengine/bevy/assets/157897/cc9e1cd0-9951-464a-9a08-e589210e5606)
2024-05-27 13:43:40 +00:00
BD103
b0409f63d5
Refactor ci_testing and separate it from DevToolsPlugin (#13513)
# Objective

- We use
[`ci_testing`](https://dev-docs.bevyengine.org/bevy/dev_tools/ci_testing/index.html)
to specify per-example configuration on when to take a screenshot, when
to exit, etc.
- In the future more features may be added, such as #13512. To support
this growth, `ci_testing` should be easier to read and maintain.

## Solution

- Convert `ci_testing.rs` into the folder `ci_testing`, splitting the
configuration and systems into `ci_testing/config.rs` and
`ci_testing/systems.rs`.
- Convert `setup_app` into the plugin `CiTestingPlugin`. This new plugin
is added to both `DefaultPlugins` and `MinimalPlugins`.
- Remove `DevToolsPlugin` from `MinimalPlugins`, since it was only used
for CI testing.
- Clean up some code, add many comments, and add a few unit tests.

## Testing

The most important part is that this still passes all of the CI
validation checks (merge queue), since that is when it will be used the
most. I don't think I changed any behavior, so it should operate the
same.

You can also test it locally using:

```shell
# Run the breakout example, enabling `bevy_ci_testing` and loading the configuration used in CI.
CI_TESTING_CONFIG=".github/example-run/breakout.ron" cargo r --example breakout -F bevy_ci_testing
```

---

## Changelog

- Added `CiTestingPlugin`, which is split off from `DevToolsPlugin`.
- Removed `DevToolsPlugin` from `MinimalPlugins`.

## Migration Guide

Hi maintainers! I believe `DevToolsPlugin` was added within the same
release as this PR, so I don't think a migration guide is needed.

`DevToolsPlugin` is no longer included in `MinimalPlugins`, so you will
need to remove it manually.

```rust
// Before
App::new()
    .add_plugins(MinimalPlugins)
    .run();

// After
App::new()
    .add_plugins(MinimalPlugins)
    .add_plugins(DevToolsPlugin)
    .run();
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-05-26 22:32:36 +00:00
Salvador Carvalhinho
7d843e0c08
Implement Rhombus 2D primitive. (#13501)
# Objective

- Create a new 2D primitive, Rhombus, also knows as "Diamond Shape"
- Simplify the creation and handling of isometric projections
- Extend Bevy's arsenal of 2D primitives

## Testing

- New unit tests created in bevy_math/ primitives and bev_math/ bounding
- Tested translations, rotations, wireframe, bounding sphere, aabb and
creation parameters

---------

Co-authored-by: Luís Figueiredo <luispcfigueiredo@tecnico.ulisboa.pt>
2024-05-26 15:27:57 +00:00
robtfm
037f37e4d6
add glsl feature for bevy_pbr (#13516)
# Objective

in bevy_pbr we check for `shader_format_glsl` before using binding
arrays due to a naga->glsl limitation. but the feature is currently only
enabled for the bevy_render crate.

fix #13232

## Solution

enable the feature for bevy_pbr too.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-26 14:37:24 +00:00
Daniel Miller
1d29f8e6f6
Added a Grey trait, and implementations on baked-in colors. Fixes #13206 (#13237)
Added a Grey trait to allow colors to create a generic "grey" color.

This currently assumes the color spaces follow the same gradient, which
I'm pretty sure isn't true, but it should make a "grey-ish" color
relative to the provided intensity.

# Objective

- Implements #13206 

## Solution

- A small `Grey` trait was added and implemented for the common color
kinds.

## Testing

- Currently untested, unit tests exposed the non-linear relation between
colors. I am debating adding an example to show this, as I have no idea
what color space represents what relation of grey, and I figure others
may be similarly confused.

## Changelog

- The `Grey` trait was added, and the corresponding `grey` 

## BREAKING CHANGES

The const qualifier for LinearRGBA::gray was removed (the symbol still
exists via a trait, it's just not const anymore)
2024-05-26 12:53:50 +00:00
Joona Aalto
383314ef62
Add meshing for ConicalFrustum (#11819)
# Objective

The `ConicalFrustum` primitive should support meshing.

## Solution

Implement meshing for the `ConicalFrustum` primitive. The implementation
is nearly identical to `Cylinder` meshing, but supports two radii.

The default conical frustum is equivalent to a cone with a height of 1
and a radius of 0.5, truncated at half-height.


![kuva](https://github.com/bevyengine/bevy/assets/57632562/b4cab136-ff55-4056-b818-1218e4f38845)
2024-05-25 21:56:09 +00:00
Matty
3561467f5a
Add Triangle3d / Tetrahedron to render_primitives example (#13504)
# Objective

This is just cleanup; we've got some more renderable gizmos and
primitives now that hadn't been added to this example, so let's add
them.

## Solution

In the `render_primitives` example:
- Added `Triangle3d` mesh
- Wrote `primitive_3d` gizmo impl for `Triangle3d` and added the gizmo
- Added `Tetrahedron` mesh and gizmo

I also made the 2d triangle bigger, since it was really small.

## Testing

You can just run the example to see that everything turned out all
right.

## Other

Feel free to let me know if there are other primitives that I missed;
I'm happy to tack them onto this PR.
2024-05-25 13:20:58 +00:00
François Mockers
0ec634763e
fix emissive value in StandardMaterial after swith to LinearRgba (#13502)
# Objective

- #13352 broke bloom in 3d

## Solution

- Use the correct value for `emissive` in `StandardMaterial`. It's
computed just above but unused

d87505899f/crates/bevy_pbr/src/pbr_material.rs (L975-L976)

## Testing

- Run example `bloom_3d`
2024-05-25 01:53:47 +00:00
Periwink
d87505899f
Update render graph docs (#13495)
# Objective

I'm reading some of the rendering code for the first time; and using
this opportunity to flesh out some docs for the parts that I did not
understand.
rather than a questionable design choice is not a breaking change.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-05-24 21:57:08 +00:00
Periwink
b2b356f462
add Debug for ptr types (#13498)
# Objective

- I wanted to store a Ptr in a struct of mine that has a
`#[derive(Debug)]` and I noticed that the Ptrs don't implement Debug,
even though the underlying `NonNull<u8>` does

## Solution

- Add `#[derive(Debug)]`
2024-05-24 21:25:11 +00:00
andristarr
44c0325ecd
Emissive is now LinearRgba on StandardMaterial (#13352)
StandardMaterial stores a LinearRgba instead of a Color for emissive

Fixes #13212
2024-05-24 17:23:35 +00:00
Ben Harper
ec01c2dc45
New circular primitives: Arc2d, CircularSector, CircularSegment (#13482)
# Objective

Adopted #11748

## Solution

I've rebased on main to fix the merge conflicts. ~~Not quite ready to
merge yet~~

* Clippy is happy and the tests are passing, but...
* ~~The new shapes in `examples/2d/2d_shapes.rs` don't look right at
all~~ Never mind, looks like radians and degrees just got mixed up at
some point?
* I have updated one doc comment based on a review in the original PR.

---------

Co-authored-by: Alexis "spectria" Horizon <spectria.limina@gmail.com>
Co-authored-by: Alexis "spectria" Horizon <118812919+spectria-limina@users.noreply.github.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Ben Harper <ben@tukom.org>
2024-05-23 16:12:46 +00:00
Vitaliy Sapronenko
da1e6e63ff
Mention of Vec normalization for Dir::new (#13483)
# Objective

- Fixes #13429 .

## Solution

- Improved docs for methods `new`, `new_and_length` of `Dir2`, `Dir3`,
`Dir3A`.
2024-05-23 15:20:21 +00:00
Ben Harper
bd5148e0f5
Add triangle_math tests and fix Triangle3d::bounding_sphere bug (#13467)
# Objective

Adopted #12659.

Resolved the merge conflicts on #12659;

* I merged the `triangle_tests` added by this PR and by #13020.
* I moved the [commented out
code](https://github.com/bevyengine/bevy/pull/12659#discussion_r1536640427)
from the original PR into a separate test with `#[should_panic]`.

---------

Co-authored-by: Vitor Falcao <vitorfhc@protonmail.com>
Co-authored-by: Ben Harper <ben@tukom.org>
2024-05-23 15:03:00 +00:00
Mincong Lu
1d950e6195
Allow AssetServer::load to acquire a guard item. (#13051)
# Objective

Supercedes #12881 . Added a simple implementation that allows the user
to react to multiple asset loads both synchronously and asynchronously.

## Solution

Added `load_acquire`, that holds an item and drops it when loading is
finished or failed.

When used synchronously 

Hold an `Arc<()>`, check for `Arc::strong_count() == 1` when all loading
completed.

When used asynchronously 

Hold a `SemaphoreGuard`, await on `acquire_all` for completion.

This implementation has more freedom than the original in my opinion.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-05-23 13:28:29 +00:00
Ricky Taylor
efcb6d6c11
Make LoadContext use the builder pattern for loading dependent assets (#13465)
# Objective
- Fixes #13445.

## Solution
- Removes all `load_` methods from `LoadContext`.
- Introduces `fn loader()` which returns a builder.

## Testing
- I've tested with `cargo test --package=bevy_asset` and run the two
relevant examples (`asset_processing` & `asset_decompression`).

---

## Changelog
- Replaced all `load_` methods on `LoadContext` with the new `loader()`
pattern.

## Migration Guide
- Several LoadContext method calls will need to be updated:
- `load_context.load_with_settings(path, settings)` =>
`load_context.loader().with_settings(settings).load(path)`
- `load_context.load_untyped(path)` =>
`load_context.loader().untyped().load(path)`
- `load_context.load_direct(path)` =>
`load_context.loader().direct().load(path)`
- `load_context.load_direct_untyped(path)` =>
`load_context.loader().direct().untyped().load(path)`
- `load_context.load_direct_with_settings(path, settings)` =>
`load_context.loader().with_settings(settings).direct().load(path)`
- `load_context.load_direct_with_reader(reader, path)` =>
`load_context.loader().direct().with_reader(reader).load(path)`
- `load_context.load_direct_with_reader_and_settings(reader, path,
settings)` =>
`load_context.loader().with_settings(settings).direct().with_reader(reader).load(path)`
- `load_context.load_direct_untyped_with_reader(reader, path)` =>
`load_context.loader().direct().with_reader(reader).untyped().load(path)`

---

CC @alice-i-cecile / @bushrat011899 

Examples:
```rust
load_context.loader()
    .with_asset_type::<A>()
    .with_asset_type_id(TypeId::of::<A>())
    .with_settings(|mut settings| { settings.key = value; })
    // Then, for a Handle<A>:
    .load::<A>()
    // Or, for a Handle<LoadedUntypedAsset>:
    .untyped()
    .load()
    // Or, to load an `A` directly:
    .direct()
    .load::<A>()
    .await
    // Or, to load an `ErasedLoadedAsset` directly:
    .direct()
    .untyped()
    .load()
    .await
```
2024-05-22 23:35:41 +00:00
Gino Valente
faf003fc9d
bevy_reflect: enum_utility cleanup (#13424)
# Objective

The `enum_utility` module contains the `get_variant_constructors`
function, which is used to generate token streams for constructing
enums. It's used for the `FromReflect::from_reflect` implementation and
the `Reflect::try_apply` implementation.

Due to the complexity of enums, this function is understandably a little
messy and difficult to extend.

## Solution

Clean up the `enum_utility` module.

Now "clean" is a bit subjective. I believe my solution is "cleaner" in
that the logic to generate the tokens are strictly coupled with the
intended usage. Because of this, `try_apply` is also no longer strictly
coupled with `from_reflect`.

This makes it easier to extend with new functionality, which is
something I'm doing in a future unrelated PR that I have based off this
one.

## Testing

There shouldn't be any testing required other than ensuring that the
project still builds and that CI passes.
2024-05-22 21:18:57 +00:00
Vic
c4cedb12c8
simple Debug impls for query iterators (#13476)
# Objective

The current query iterators cannot be used in positions with a `Debug`
bound.
F.e. when they are packaged in `Result` in the error position, `expect`
cannot be called on them.
Required for `QueryManyIter::entities_all_unique` in #13477.

## Solution

Add simple `Debug` impls that print the query iterator names.

## Changelog

`QueryIter`, `QueryManyIter`, `QueryCombinationIter`, and
`QuerySortedIter` now implement `Debug`.
2024-05-22 18:56:09 +00:00
Alice Cecile
dda7a744cf
Further improve docs for component hooks (#13475)
# Objective

While reviewing the other open hooks-related PRs, I found that the docs
on the `ComponentHooks` struct itself didn't give enough information
about how and why the feature could be used.

## Solution

1. Clean up the docs to add additional context.
2. Add a doc test demonstrating simple usage.

## Testing

The doc test passes locally.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-22 18:04:56 +00:00
Olle Lukowski
1ec5cdf3f2
Optimize the values for EMPTY rect. (#13470)
I am unsure if this needs changing, so let me know if I need to change
anything else.

# Objective

Fixes #13461.

## Solution

I applied the changes as suggested in the issue, and updated the doc
comments accordingly

## Testing

I don't think this needs too much testing, but there are no `cargo test`
failures.
2024-05-22 13:34:23 +00:00
Matty
5dbd827728
Annulus sampling (#13471)
# Objective

Add random sampling for the `Annulus` primitive. This is part of ongoing
work to bring the various `bevy_math` primitives to feature parity.

## Solution

`Annulus` implements `ShapeSample`. Boundary sampling is implemented in
the obvious way, and interior sampling works exactly as in the
implementation for `Circle`, using the fact that the square of the
radius should be taken uniformly from between r^2 and R^2, where r and R
are the inner and outer radii respectively.

## Testing

I generated a bunch of random points and rendered them. Here's 1000
points on the interior of the default annulus:
<img width="1440" alt="Screenshot 2024-05-22 at 8 01 34 AM"
src="https://github.com/bevyengine/bevy/assets/2975848/19c31bb0-edba-477f-b247-2b12d854afae">

This looks kind of weird around the edges, but I verified that they're
all actually inside the annulus, so I assume it has to do with the fact
that the rendered circles have some radius.
2024-05-22 13:13:04 +00:00
Matty
d2ef88f5e8
Add Distribution access methods for ShapeSample trait (#13315)
Stolen from #12835. 

# Objective

Sometimes you want to sample a whole bunch of points from a shape
instead of just one. You can write your own loop to do this, but it's
really more idiomatic to use a `rand`
[`Distribution`](https://docs.rs/rand/latest/rand/distributions/trait.Distribution.html)
with the `sample_iter` method. Distributions also support other useful
things like mapping, and they are suitable as generic items for
consumption by other APIs.

## Solution

`ShapeSample` has been given two new automatic trait methods,
`interior_dist` and `boundary_dist`. They both have similar signatures
(recall that `Output` is the output type for `ShapeSample`):
```rust
fn interior_dist(self) -> impl Distribution<Self::Output>
where Self: Sized { //... }
```

These have default implementations which are powered by wrapper structs
`InteriorOf` and `BoundaryOf` that actually implement `Distribution` —
the implementations effectively just call `ShapeSample::sample_interior`
and `ShapeSample::sample_boundary` on the contained type.

The upshot is that this allows iteration as follows:
```rust
// Get an iterator over boundary points of a rectangle:
let rectangle = Rectangle::new(1.0, 2.0);
let boundary_iter = rectangle.boundary_dist().sample_iter(rng);
// Collect a bunch of boundary points at once:
let boundary_pts: Vec<Vec2> = boundary_iter.take(1000).collect();
```

Alternatively, you can use `InteriorOf`/`BoundaryOf` explicitly to
similar effect:
```rust
let boundary_pts: Vec<Vec2> = BoundaryOf(rectangle).sample_iter(rng).take(1000).collect();
```

---

## Changelog

- Added `InteriorOf` and `BoundaryOf` distribution wrapper structs in
`bevy_math::sampling::shape_sampling`.
- Added `interior_dist` and `boundary_dist` automatic trait methods to
`ShapeSample`.
- Made `shape_sampling` module public with explanatory documentation.

---

## Discussion

### Design choices

The main point of interest here is just the choice of `impl
Distribution` instead of explicitly using `InteriorOf`/`BoundaryOf`
return types for `interior_dist` and `boundary_dist`. The reason for
this choice is that it allows future optimizations for repeated sampling
— for example, instead of just wrapping the base type,
`interior_dist`/`boundary_dist` could construct auxiliary data that is
held over between sampling operations.
2024-05-22 12:38:08 +00:00
Matty
c7f7d906ca
Tetrahedron mesh (#13463)
# Objective

Allow the `Tetrahedron` primitive to be used for mesh generation. This
is part of ongoing work to bring unify the capabilities of `bevy_math`
primitives.

## Solution

`Tetrahedron` implements `Meshable`. Essentially, each face is just
meshed as a `Triangle3d`, but first there is an inversion step when the
signed volume of the tetrahedron is negative to ensure that the faces
all actually point outward.

## Testing

I loaded up some examples and hackily exchanged existing meshes with the
new one to see that it works as expected.
2024-05-22 12:22:11 +00:00
Ida "Iyes
60afec2a00
Fix 2D looking blurry at odd window sizes (#13440)
# Objective

This is a long-standing bug that I have experienced since many versions
of Bevy ago, possibly forever. Today I finally wanted to report it, but
the fix was so easy that I just went and fixed it. :)

The problem is that 2D graphics looks blurry at odd-sized window
resolutions. This is with the **default** 2D camera configuration! The
issue will also manifest itself with any Orthographic Projection with
`ScalingMode::WindowSize` where the viewport origin is not at one of the
corners, such as the default where the origin point is at the center.

The issue happens because the Bevy orthographic projection origin point
is specified as a fraction to be multiplied by the size. For example,
the default (origin at center) is `(0.5, 0.5)`. When this value is
multiplied by the window size, it can result in fractional values for
the actual origin of the projection, thus placing the camera "between
pixels" and misaligning the entire pixel grid.

With the default value, this happens at odd-numbered window resolutions.
It is very easy to reproduce the issue by running any Bevy 2D app with a
resizable window, and slowly resizing the window pixel by pixel. As you
move the mouse to resize the window, you can see how the 2D graphics
inside the window alternate between "crisp, blurry, crisp, blurry, ...".
If you change the projection's origin to be at the corner (say, `(0.0,
0.0)`) and run the app again, the graphics always looks crisp,
regardless of window size.

Here are screenshots from **before** this PR, to illustrate the issue:

Even window size:

![Screenshot_20240520_165304](https://github.com/bevyengine/bevy/assets/40234599/52619281-cf5f-490e-b85e-22bc5f9af737)

Odd window size:

![Screenshot_20240520_165320](https://github.com/bevyengine/bevy/assets/40234599/27a3624c-f39e-4493-ade9-ca3533802083)


## Solution

The solution is easy: just round the computed origin values for the
projection.

To make it work reliably for the general case, I decided to:
- Only do it for `ScalingMode::WindowSize`, as it doesn't make sense for
other scaling modes.
- Round to the nearest multiple of the pixel scale, if it is not 1.0.
This ensures the "pixels" stay aligned even if scaled.

## Testing

I ran Bevy's examples as well as my own projects to ensure things look
correct. I set different values for the pixel scale to test the rounding
behavior and played around with resizing the window to verify that
everything is consistent.

---

## Changelog

Fixed:
- Orthographic projection now rounds the origin point if computed from
screen pixels, so that 2D graphics do not appear blurry at odd window
sizes.
2024-05-22 02:59:40 +00:00
James O'Brien
182fe3292e
Implement a SystemBuilder for building SystemParams (#13123)
# Objective

- Implement a general purpose mechanism for building `SystemParam`.
- Unblock the usage of dynamic queries in regular systems.

## Solution

- Implement a `SystemBuilder` type.

## Examples
Here are some simple test cases for the builder:
```rust
fn local_system(local: Local<u64>) -> u64 {
    *local
}

fn query_system(query: Query<()>) -> usize {
    query.iter().count()
}

fn multi_param_system(a: Local<u64>, b: Local<u64>) -> u64 {
    *a + *b + 1
}

#[test]
fn local_builder() {
    let mut world = World::new();

    let system = SystemBuilder::<()>::new(&mut world)
        .builder::<Local<u64>>(|x| *x = 10)
        .build(local_system);

    let result = world.run_system_once(system);
    assert_eq!(result, 10);
}

#[test]
fn query_builder() {
    let mut world = World::new();

    world.spawn(A);
    world.spawn_empty();

    let system = SystemBuilder::<()>::new(&mut world)
        .builder::<Query<()>>(|query| {
            query.with::<A>();
        })
        .build(query_system);

    let result = world.run_system_once(system);
    assert_eq!(result, 1);
}

#[test]
fn multi_param_builder() {
    let mut world = World::new();

    world.spawn(A);
    world.spawn_empty();

    let system = SystemBuilder::<()>::new(&mut world)
        .param::<Local<u64>>()
        .param::<Local<u64>>()
        .build(multi_param_system);

    let result = world.run_system_once(system);
    assert_eq!(result, 1);
}
```
This will be expanded as this PR is iterated.
2024-05-22 00:58:37 +00:00
Patrick Walton
a785e3c20d
Fix UI elements randomly not appearing after #13277. (#13462)
We invoked the `extract_default_ui_camera_view` system twice: once for
2D cameras and once for 3D cameras. This was fine before moving to
resources for render phases, but, after the move to resources, the first
thing such systems do is to clear out all the entities-to-be-rendered
from the previous frame. So, if the scheduler happened to run
`extract_default_ui_camera_view::<Camera2d>` first, then all the UI
elements that it queued would be overwritten by the
`extract_default_ui_camera_view::<Camera3d>` system, or vice versa. The
ordering dependence is the reason why this problem was intermittent.

This commit fixes the problem by merging the two systems into one
systems, using an `Or` query filter.

## Migration Guide

* The `bevy_ui::render::extract_default_ui_camera_view` system is no
longer parameterized over the specific type of camera and is hard-wired
to either `Camera2d` or `Camera3d` components.
2024-05-21 22:06:25 +00:00
SpecificProtagonist
6c95d54652
Fix doc for Added, Changed (#13458)
# Objective

Fixes #13426

## Solution

Correct documentation to describe current behavior

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-21 21:23:24 +00:00
Vitaliy Sapronenko
151e198d94
Add slerp function for Dir2, Dir3, Dir3A (#13451)
# Objective

- Fixes #13407 .

## Solution

- Used Quat and Rotation2d.

## Testing

- Added tests based on 0°, 30°, 45°, 60° and 90° angles
2024-05-21 21:13:32 +00:00
Martín Maita
f9da5eecf2
Rename Rect inset() method to inflate() (#13452)
# Objective

- Fixes #13092.

## Solution

- Renamed the `inset()` method in `Rect`, `IRect` and `URect` to
`inflate()`.
- Added `EMPTY` constants to all `Rect` variants, represented by corners
with the maximum numerical values for each kind.

---

## Migration Guide

- Replace `Rect::inset()`, `IRect::inset()` and `URect::inset()` calls
with `inflate()`.
2024-05-21 20:53:55 +00:00
Lynn
9ef9f3b3a4
Inconsistent segments/resolution naming (#13438)
# Objective

- Fixes #13412

## Solution

- Renamed `segments` in `bevy_gizmos` to `resolution` and adjusted
examples

## Migration Guide

- When working with gizmos, replace all calls to `.segments(...)` with
`.resolution(...)`
2024-05-21 18:42:59 +00:00
Matty
b7ec19bb2d
Tetrahedron sampling (#13430)
# Objective

Add interior and boundary sampling for the `Tetrahedron` primitive. This
is part of ongoing work to bring the primitives to parity with each
other in terms of their capabilities.

## Solution

`Tetrahedron` implements the `ShapeSample` trait. To support this, there
is a new public method `Tetrahedron::faces` which gets the faces of a
tetrahedron as `Triangle3d`s. There are more sophisticated ideas for
getting the faces we might want to consider in the future (e.g.
adjusting according to the orientation), but this method gives the most
mathematically straightforward answer, giving the faces the orientation
induced by the tetrahedron itself.
2024-05-21 18:40:03 +00:00
Vic
399fd23797
implement the full set of sort methods on QueryIter (#13417)
# Objective

Currently, a query iterator can be collected into a `Vec` and sorted,
but this can be quite unwieldy, especially when many `Component`s are
involved. The `itertools` crate helps somewhat, but the need to write a
closure over all of `QueryData`
can sometimes hurt ergonomics, anywhere from slightly to strongly. A key
extraction function only partially helps, as `sort_by_key` does not
allow returning non-`Copy` data. `sort_by` does not suffer from the
`Copy` restriction, but now the user has to write out a `cmp` function
over two `QueryData::Item`s when it could have just been handled by the
`Ord` impl for the key.
`sort` requires the entire `Iterator` Item to be `Ord`, which is rarely
usable without manual helper functionality. If the user wants to hide
away unused components with a `..` range, they need to track item tuple
order across their function. Mutable `QueryData` can also introduce
further complexity.
Additionally, sometimes users solely include `Component`s /`Entity` to
guarantee iteration order.

For a user to write a function to abstract away repeated sorts over
various `QueryData` types they use would require reaching for the
`all_tuples!` macro, and continue tracking tuple order afterwards.

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

## Solution

Custom sort methods on `QueryIter`, which take a query lens as a generic
argument, like `transmute_lens` in `Query`.
This allows users to choose what part of their queries they pass to
their sort function calls, serving as a kind of "key extraction
function" before the sort call. F.e. allowing users to implement `Ord`
for a Component, then call `query.iter().sort::<OrdComponent>()`

This works independent of mutability in `QueryData`, `QueryData` tuple
order, or the underlying `iter/iter_mut` call.
Non-`Copy` components could also be used this way, an internal
`Arc<usize>` being an example.
If `Ord` impls on components do not suffice, other sort methods can be
used. Notably useful when combined with `EntityRef` or `EntityMut`.
Another boon from using underlying `transmute` functionality, is that
with the [allowed
transmutes](http://dev-docs.bevyengine.org/bevy/ecs/prelude/struct.Query.html#allowed-transmutes),
it is possible to sort a `Query` with `Entity` even if it wasn't
included in the original `Query`.
The additional generic parameter on the methods other than `sort` and
`sort_unstable` currently cannot be removed due to Rust limitations,
however their types can be inferred.

The new methods do not conflict with the `itertools` sort methods, as
those use the "sorted" prefix.

This is implemented barely touching existing code. That change to
existing code being that `QueryIter` now holds on to the reference to
`UnsafeWorldCell` that is used to initialize it.
A lens query is constructed with `Entity` attached at the end, sorted,
and turned into an iterator. The iterator maps away the lens query,
leaving only an iterator of `Entity`, which is used by `QuerySortedIter`
to retrieve the actual items.
`QuerySortedIter` resembles a combination of `QueryManyIter` and
`QueryIter`, but it uses an entity list that is guaranteed to contain
unique entities, and implements `ExactSizeIterator`,
`DoubleEndedIterator`, `FusedIterator` regardless of mutability or
filter kind (archetypal/non-archetypal).

The sort methods are not allowed to be called after `next`, and will
panic otherwise. This is checked using `QueryIterationCursor` state,
which is unique on initialization. Empty queries are an exception to
this, as they do not return any item in the first place.
That is because tracking how many iterations have already passed would
require regressing either normal query iteration a slight bit, or sorted
iteration by a lot. Besides, that would not be the intended use of these
methods.

## Testing

To ensure that `next` being called before `sort` results in a panic, I
added some tests. I also test that empty `QueryIter`s do not exhibit
this restriction.

The query sorts test checks for equivalence to the underlying sorts.
This change requires that `Query<(Entity, Entity)>` remains legal, if
that is not already guaranteed, which is also ensured by the
aforementioned test.

## Next Steps

Implement the set of sort methods for `QueryManyIter` as well.
- This will mostly work the same, other than needing to return a new
`QuerySortedManyIter` to account for iteration
over lists of entities that are not guaranteed to be unique. This new
query iterator will need a bit of internal restructuring
to allow for double-ended mutable iteration, while not regressing
read-only iteration.

The implementations for each pair of 
- `sort`, `sort_unstable`, 
- `sort_by`, sort_unstable_by, 
- `sort_by_key,` `sort_by_cached_key`

are the same aside from the panic message and the sort call, so they
could be merged with an inner function.
That would require the use of higher-ranked trait bounds on
`WorldQuery::Item<'1>`, and is unclear to me whether it is currently
doable.

Iteration in QuerySortedIter might have space for improvement.
When sorting by `Entity`, an `(Entity, Entity)` lens `QueryData` is
constructed, is that worth remedying?
When table sorts are implemented, a fast path could be introduced to
these sort methods.

## Future Possibilities

Implementing `Ord` for EntityLocation might be useful.
Some papercuts in ergonomics can be improved by future Rust features:
- The additional generic parameter aside from the query lens can be
removed once this feature is stable:
    `Fn -> impl Trait` (`impl Trait` in `Fn` trait return position)
- With type parameter defaults, the query lens generic can be defaulted
to `QueryData::Item`, allowing the sort methods
to look and behave like `slice::sort` when no query lens is specified.
- With TAIT, the iterator generic on `QuerySortedIter` and thus the huge
visible `impl Iterator` type in the sort function
   signatures can be removed. 
- With specialization, the bound on `L` could be relaxed to `QueryData`
when the underlying iterator is mutable.

## Changelog

Added `sort`, `sort_unstable`, `sort_by`, `sort_unstable_by`,
`sort_by_key`, `sort_by_cached_key` to `QueryIter`.
2024-05-21 18:35:19 +00:00
Ricky Taylor
26df1c1179
Add more load_direct implementations (#13415)
# Objective
- Introduce variants of `LoadContext::load_direct` which allow picking
asset type & configuring settings.
- Fixes #12963.

## Solution
- Implements `ErasedLoadedAsset::downcast` and adds some accessors to
`LoadedAsset<A>`.
- Changes `load_direct`/`load_direct_with_reader` to be typed, and
introduces `load_direct_untyped`/`load_direct_untyped_with_reader`.
- Introduces `load_direct_with_settings` and
`load_direct_with_reader_and_settings`.

## Testing
- I've run cargo test and played with the examples which use
`load_direct`.
- I also extended the `asset_processing` example to use the new typed
version of `load_direct` and use `load_direct_with_settings`.

---

## Changelog
- Introduced new `load_direct` methods in `LoadContext` to allow
specifying type & settings

## Migration Guide
- `LoadContext::load_direct` has been renamed to
`LoadContext::load_direct_untyped`. You may find the new `load_direct`
is more appropriate for your use case (and the migration may only be
moving one type parameter).
- `LoadContext::load_direct_with_reader` has been renamed to
`LoadContext::load_direct_untyped_with_reader`.

---

This might not be an obvious win as a solution because it introduces
quite a few new `load_direct` alternatives - but it does follow the
existing pattern pretty well. I'm very open to alternatives.
😅
2024-05-21 18:32:00 +00:00
Lynn
2857eb6b9d
Fix normals during mesh scaling (#13380)
# Objective

- Fixes scaling normals and tangents of meshes

## Solution

- When scaling a mesh by `Vec3::new(1., 1., -1.)`, the normals should be
flipped along the Z-axis. For example a normal of `Vec3::new(0., 0.,
1.)` should become `Vec3::new(0., 0., -1.)` after scaling. This is
achieved by multiplying the normal by the reciprocal of the scale,
cheking for infinity and normalizing. Before, the normal was multiplied
by a covector of the scale, which is incorrect for normals.
- Tangents need to be multiplied by the `scale`, not its reciprocal as
before

---------

Co-authored-by: vero <11307157+atlv24@users.noreply.github.com>
2024-05-21 18:28:03 +00:00
Patrick Walton
9da0b2a0ec
Make render phases render world resources instead of components. (#13277)
This commit makes us stop using the render world ECS for
`BinnedRenderPhase` and `SortedRenderPhase` and instead use resources
with `EntityHashMap`s inside. There are three reasons to do this:

1. We can use `clear()` to clear out the render phase collections
instead of recreating the components from scratch, allowing us to reuse
allocations.

2. This is a prerequisite for retained bins, because components can't be
retained from frame to frame in the render world, but resources can.

3. We want to move away from storing anything in components in the
render world ECS, and this is a step in that direction.

This patch results in a small performance benefit, due to point (1)
above.

## Changelog

### Changed

* The `BinnedRenderPhase` and `SortedRenderPhase` render world
components have been replaced with `ViewBinnedRenderPhases` and
`ViewSortedRenderPhases` resources.

## Migration Guide

* The `BinnedRenderPhase` and `SortedRenderPhase` render world
components have been replaced with `ViewBinnedRenderPhases` and
`ViewSortedRenderPhases` resources. Instead of querying for the
components, look the camera entity up in the
`ViewBinnedRenderPhases`/`ViewSortedRenderPhases` tables.
2024-05-21 18:23:04 +00:00
BD103
53f4c38e7b
Fix lints on beta Rust (#13444)
# Objective

- Fixes #13437!

## Solution

- Use `f32::INFINITY` instead of `std::f32::INFINITY`.

## Testing

```shell
cargo +beta clippy --workspace --all-targets --all-features -- -Dwarnings
```
2024-05-20 20:40:59 +00:00
BD103
2940636e0a
Deprecate dynamic plugins (#13080)
# Objective

- The current implementation for dynamic plugins is unsound. Please see
#11969 for background and justification.
- Closes #11969 and closes #13073.

## Solution

- Deprecate all dynamic plugin items for Bevy 0.14, with plans to remove
them for Bevy 0.15.

## Discussion

One thing I want to make clear is that I'm not opposed to dynamic
plugins _in general_. I think they can be handy, especially for DLC and
modding, but I think the current system is the wrong approach. It's too
much of a footgun for the meager benefit is provides.

---

## Changelog

- Deprecated the current dynamic plugin system.
- Dynamic plugins will be removed in Bevy 0.15. For now you can continue
using them by marking your code with `#[allow(deprecated)]`.

## Migration Guide

If possible, remove all usage of dynamic plugins.

```rust
// Old
#[derive(DynamicPlugin)]
pub struct MyPlugin;

App::new()
    .load_plugin("path/to/plugin")
    .run();

// New
pub struct MyPlugin;

App::new()
    .add_plugins(MyPlugin)
    .run();
```

If you are unable to do that, you may temporarily silence the
deprecation warnings.

```rust
#[allow(deprecated)]
```

Please note that the current dynamic plugin system will be removed by
the next major Bevy release, so you will have to migrate eventually. You
may be interested in these safer alternatives:

- [Bevy Assets - Scripting]: Scripting and modding libraries for Bevy
- [Bevy Assets - Development tools]: Hot reloading and other development
functionality
- [`stabby`]: Stable Rust ABI

[Bevy Assets - Scripting]: https://bevyengine.org/assets/#scripting
[Bevy Assets - Development tools]:
https://bevyengine.org/assets/#development-tools
[`stabby`]: https://github.com/ZettaScaleLabs/stabby
2024-05-20 20:01:28 +00:00
Spooky Th Ghost
612e77ef78
Adds doc note that Timer and Stopwatch must be progressed manually (#13441)
# Objective
- Fix #13421 

## Solution

- Add an explicit note at the root of each struct that they must be
ticked manually

## Testing

- Generated the docs and the changes look good
---

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: Matty <weatherleymatthew@gmail.com>
2024-05-20 19:46:25 +00:00
Gino Valente
5db52663b3
bevy_reflect: Custom attributes (#11659)
# Objective

As work on the editor starts to ramp up, it might be nice to start
allowing types to specify custom attributes. These can be used to
provide certain functionality to fields, such as ranges or controlling
how data is displayed.

A good example of this can be seen in
[`bevy-inspector-egui`](https://github.com/jakobhellermann/bevy-inspector-egui)
with its
[`InspectorOptions`](https://docs.rs/bevy-inspector-egui/0.22.1/bevy_inspector_egui/struct.InspectorOptions.html):

```rust
#[derive(Reflect, Default, InspectorOptions)]
#[reflect(InspectorOptions)]
struct Slider {
    #[inspector(min = 0.0, max = 1.0)]
    value: f32,
}
```

Normally, as demonstrated in the example above, these attributes are
handled by a derive macro and stored in a corresponding `TypeData`
struct (i.e. `ReflectInspectorOptions`).

Ideally, we would have a good way of defining this directly via
reflection so that users don't need to create and manage a whole proc
macro just to allow these sorts of attributes.

And note that this doesn't have to just be for inspectors and editors.
It can be used for things done purely on the code side of things.

## Solution

Create a new method for storing attributes on fields via the `Reflect`
derive.

These custom attributes are stored in type info (e.g. `NamedField`,
`StructInfo`, etc.).

```rust
#[derive(Reflect)]
struct Slider {
    #[reflect(@0.0..=1.0)]
    value: f64,
}

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

let field = info.field("value").unwrap();

let range = field.get_attribute::<RangeInclusive<f64>>().unwrap();
assert_eq!(*range, 0.0..=1.0);
```

## TODO

- [x] ~~Bikeshed syntax~~ Went with a type-based approach, prefixed by
`@` for ease of parsing and flexibility
- [x] Add support for custom struct/tuple struct field attributes
- [x] Add support for custom enum variant field attributes
- [x] ~~Add support for custom enum variant attributes (maybe?)~~ ~~Will
require a larger refactor. Can be saved for a future PR if we really
want it.~~ Actually, we apparently still have support for variant
attributes despite not using them, so it was pretty easy to add lol.
- [x] Add support for custom container attributes
- [x] Allow custom attributes to store any reflectable value (not just
`Lit`)
- [x] ~~Store attributes in registry~~ This PR used to store these in
attributes in the registry, however, it has since switched over to
storing them in type info
- [x] Add example

## Bikeshedding

> [!note]
> This section was made for the old method of handling custom
attributes, which stored them by name (i.e. `some_attribute = 123`). The
PR has shifted away from that, to a more type-safe approach.
>
> This section has been left for reference.

There are a number of ways we can syntactically handle custom
attributes. Feel free to leave a comment on your preferred one! Ideally
we want one that is clear, readable, and concise since these will
potentially see _a lot_ of use.

Below is a small, non-exhaustive list of them. Note that the
`skip_serializing` reflection attribute is added to demonstrate how each
case plays with existing reflection attributes.

<details>
<summary>List</summary>

##### 1. `@(name = value)`

> The `@` was chosen to make them stand out from other attributes and
because the "at" symbol is a subtle pneumonic for "attribute". Of
course, other symbols could be used (e.g. `$`, `#`, etc.).

```rust
#[derive(Reflect)]
struct Slider {
    #[reflect(@(min = 0.0, max = 1.0), skip_serializing)]
    #[[reflect(@(bevy_editor::hint = "Range: 0.0 to 1.0"))]
    value: f32,
}
```

##### 2. `@name = value`

> This is my personal favorite.

```rust
#[derive(Reflect)]
struct Slider {
    #[reflect(@min = 0.0, @max = 1.0, skip_serializing)]
    #[[reflect(@bevy_editor::hint = "Range: 0.0 to 1.0")]
    value: f32,
}
```

##### 3. `custom_attr(name = value)`

> `custom_attr` can be anything. Other possibilities include `with` or
`tag`.

```rust
#[derive(Reflect)]
struct Slider {
    #[reflect(custom_attr(min = 0.0, max = 1.0), skip_serializing)]
    #[[reflect(custom_attr(bevy_editor::hint = "Range: 0.0 to 1.0"))]
    value: f32,
}
```

##### 4. `reflect_attr(name = value)`

```rust
#[derive(Reflect)]
struct Slider {
    #[reflect(skip_serializing)]
    #[reflect_attr(min = 0.0, max = 1.0)]
    #[[reflect_attr(bevy_editor::hint = "Range: 0.0 to 1.0")]
    value: f32,
}
```

</details>

---

## Changelog

- Added support for custom attributes on reflected types (i.e.
`#[reflect(@Foo::new("bar")]`)
2024-05-20 19:30:21 +00:00
IceSentry
bf2aced279
Remove another .view_layouts (#13410)
I forgot to save that file when submitting #13394 😅
2024-05-19 00:08:27 +00:00
Patrick Walton
846757cb38
Make the prepass shader compile when lightmaps are present. (#13402)
Commit 3f5a090b1b added a reference to
`STANDARD_MATERIAL_FLAGS_BASE_COLOR_UV_BIT`, a nonexistent identifier,
in the alpha discard portion of the prepass shader. Moreover, the logic
didn't make sense to me. I think the code was trying to choose between
the two UV sets depending on which is present, so I made it do that.

I noticed this when trying Bistro with #13277. I'm not sure why this
issue didn't manifest itself before, but it's clearly a bug, so here's a
fix. We should probably merge this before 0.14.
2024-05-18 22:28:31 +00:00
François Mockers
a55e0e31e8
fix normals computation for gltf (#13396)
# Objective

- some gltf files are broken since #13333 

```
thread 'IO Task Pool (2)' panicked at crates/bevy_render/src/mesh/mesh/mod.rs:581:9:
`compute_flat_normals` can't work on indexed geometry. Consider calling either `Mesh::compute_smooth_normals` or `Mesh::duplicate_vertices` followed by `Mesh::compute_flat_normals`.
```

- test with example `custom_gltf_vertex_attribute` or
`gltf_skinned_mesh`


## Solution

- Call the wrapper function for normals that will either call
`compute_flat_normals` or `compute_smooth_normals` as appropriate

## Testing

- Ran the two examples mentioned above
2024-05-18 12:07:27 +00:00
Lynn
450a9202d0
Common MeshBuilder trait (#13411)
# Objective

- All `ShapeMeshBuilder`s have some methods/implementations in common.
These are `fn build(&self) -> Mesh` and this implementation:
```rust
impl From<ShapeMeshBuilder> for Mesh { 
    fn from(builder: ShapeMeshBuilder) -> { 
        builder.build() 
    } 
}
``` 

- For the sake of consistency, these can be moved into a shared trait

## Solution

- Add `trait MeshBuilder` containing a `fn build(&self) -> Mesh` and
implementing `MeshBuilder for ShapeMeshBuilder`
- Implement `From<T: MeshBuilder> for Mesh`

## Migration Guide

- When calling `.build()` you need to import
`bevy_render::mesh::primitives::MeshBuilder`
2024-05-18 11:58:11 +00:00
Alice Cecile
ee6dfd35c9
Revert "Add on_unimplemented Diagnostics to Most Public Traits" (#13413)
# Objective

- Rust 1.78 breaks all Android support, see
https://github.com/bevyengine/bevy/issues/13331
- We should not bump the MSRV to 1.78 until that's resolved in #13366.

## Solution

- Temporarily revert https://github.com/bevyengine/bevy/pull/13347

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-17 17:00:43 +00:00
Johannes Hackel
1fcf6a444f
Add emissive_exposure_weight to the StandardMaterial (#13350)
# Objective

- The emissive color gets multiplied by the camera exposure value. But
this cancels out almost any emissive effect.
- Fixes #13133
- Closes PR #13337 

## Solution
- Add emissive_exposure_weight to the StandardMaterial
- In the shader this value is stored in the alpha channel of the
emissive color.
- This value defines how much the exposure influences the emissive
color.
- It's equal to Google's Filament:
https://google.github.io/filament/Materials.html#emissive

4f021583f1/shaders/src/shading_lit.fs (L287)

## Testing

- The result of
[EmissiveStrengthTest](https://github.com/KhronosGroup/glTF-Sample-Models/tree/main/2.0/EmissiveStrengthTest)
with the default value of 0.0:

without bloom:

![emissive_fix](https://github.com/bevyengine/bevy/assets/688816/8f8c131a-464a-4d7b-a9e4-4e28d679ee5d)

with bloom:

![emissive_fix_bloom](https://github.com/bevyengine/bevy/assets/688816/89f200ee-3bd5-4daa-bf64-8999b56df3fa)
2024-05-17 13:49:53 +00:00
Zachary Harrold
11f0a2dcde
Add on_unimplemented Diagnostics to Most Public Traits (#13347)
# Objective

- Fixes #12377

## Solution

Added simple `#[diagnostic::on_unimplemented(...)]` attributes to some
critical public traits providing a more approachable initial error
message. Where appropriate, a `note` is added indicating that a `derive`
macro is available.

## Examples

<details>
<summary>Examples hidden for brevity</summary>

Below is a collection of examples showing the new error messages
produced by this change. In general, messages will start with a more
Bevy-centric error message (e.g., _`MyComponent` is not a `Component`_),
and a note directing the user to an available derive macro where
appropriate.

### Missing `#[derive(Resource)]`

<details>
<summary>Example Code</summary>

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

struct MyResource;

fn main() {
    App::new()
        .insert_resource(MyResource)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `MyResource` is not a `Resource`
   --> examples/app/empty.rs:7:26
    |
7   |         .insert_resource(MyResource)
    |          --------------- ^^^^^^^^^^ invalid `Resource`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `Resource` is not implemented for `MyResource`       
    = note: consider annotating `MyResource` with `#[derive(Resource)]`    
    = help: the following other types implement trait `Resource`:
              AccessibilityRequested
              ManageAccessibilityUpdates
              bevy::bevy_a11y::Focus
              DiagnosticsStore
              FrameCount
              bevy::prelude::State<S>
              SystemInfo
              bevy::prelude::Axis<T>
            and 141 others
note: required by a bound in `bevy::prelude::App::insert_resource`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:419:31
    |
419 |     pub fn insert_resource<R: Resource>(&mut self, resource: R) -> &mut Self {
    |                               ^^^^^^^^ required by this bound in `App::insert_resource`
```

</details>

### Putting A `QueryData` in a `QueryFilter` Slot

<details>
<summary>Example Code</summary>

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

#[derive(Component)]
struct A;

#[derive(Component)]
struct B;

fn my_system(_query: Query<&A, &B>) {}

fn main() {
    App::new()
        .add_systems(Update, my_system)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `&B` is not a valid `Query` filter
   --> examples/app/empty.rs:9:22
    |
9   | fn my_system(_query: Query<&A, &B>) {}
    |                      ^^^^^^^^^^^^^ invalid `Query` filter
    |
    = help: the trait `QueryFilter` is not implemented for `&B`
    = help: the following other types implement trait `QueryFilter`:
              With<T>
              Without<T>
              bevy::prelude::Or<()>
              bevy::prelude::Or<(F0,)>
              bevy::prelude::Or<(F0, F1)>
              bevy::prelude::Or<(F0, F1, F2)>
              bevy::prelude::Or<(F0, F1, F2, F3)>
              bevy::prelude::Or<(F0, F1, F2, F3, F4)>
            and 28 others
note: required by a bound in `bevy::prelude::Query`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\query.rs:349:51
    |
349 | pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> {
    |                                                   ^^^^^^^^^^^ required by this bound in `Query`
```

</details>

### Missing `#[derive(Component)]`

<details>
<summary>Example Code</summary>

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

struct A;

fn my_system(mut commands: Commands) {
    commands.spawn(A);
}

fn main() {
    App::new()
        .add_systems(Startup, my_system)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `A` is not a `Bundle`
   --> examples/app/empty.rs:6:20
    |
6   |     commands.spawn(A);
    |              ----- ^ invalid `Bundle`
    |              |
    |              required by a bound introduced by this call
    |
    = help: the trait `bevy::prelude::Component` is not implemented for `A`, which is required by `A: Bundle`
    = note: consider annotating `A` with `#[derive(Component)]` or `#[derive(Bundle)]`
    = help: the following other types implement trait `Bundle`:
              TransformBundle
              SceneBundle
              DynamicSceneBundle
              AudioSourceBundle<Source>
              SpriteBundle
              SpriteSheetBundle
              Text2dBundle
              MaterialMesh2dBundle<M>
            and 34 others
    = note: required for `A` to implement `Bundle`
note: required by a bound in `bevy::prelude::Commands::<'w, 's>::spawn`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\commands\mod.rs:243:21
    |
243 |     pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands {
    |                     ^^^^^^ required by this bound in `Commands::<'w, 's>::spawn`
```

</details>

### Missing `#[derive(Asset)]`

<details>
<summary>Example Code</summary>

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

struct A;

fn main() {
    App::new()
        .init_asset::<A>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `A` is not an `Asset`
   --> examples/app/empty.rs:7:23
    |
7   |         .init_asset::<A>()
    |          ----------   ^ invalid `Asset`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `Asset` is not implemented for `A`
    = note: consider annotating `A` with `#[derive(Asset)]`
    = help: the following other types implement trait `Asset`:
              Font
              AnimationGraph
              DynamicScene
              Scene
              AudioSource
              Pitch
              bevy::bevy_gltf::Gltf
              GltfNode
            and 17 others
note: required by a bound in `init_asset`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_asset\src\lib.rs:307:22
    |
307 |     fn init_asset<A: Asset>(&mut self) -> &mut Self;
    |                      ^^^^^ required by this bound in `AssetApp::init_asset`
```

</details>

### Mismatched Input and Output on System Piping

<details>
<summary>Example Code</summary>

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

fn producer() -> u32 {
    123
}

fn consumer(_: In<u16>) {}

fn main() {
    App::new()
        .add_systems(Update, producer.pipe(consumer))
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `fn(bevy::prelude::In<u16>) {consumer}` is not a valid system with input `u32` and output `_`
   --> examples/app/empty.rs:11:44
    |
11  |         .add_systems(Update, producer.pipe(consumer))
    |                                       ---- ^^^^^^^^ invalid system
    |                                       |
    |                                       required by a bound introduced by this call
    |
    = help: the trait `bevy::prelude::IntoSystem<u32, _, _>` is not implemented for fn item `fn(bevy::prelude::In<u16>) {consumer}`
    = note: expecting a system which consumes `u32` and produces `_`
note: required by a bound in `pipe`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_ecs\src\system\mod.rs:168:12
    |
166 |     fn pipe<B, Final, MarkerB>(self, system: B) -> PipeSystem<Self::System, B::System>
    |        ---- required by a bound in this associated function
167 |     where
168 |         B: IntoSystem<Out, Final, MarkerB>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `IntoSystem::pipe`
```

</details>

### Missing Reflection

<details>
<summary>Example Code</summary>

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

#[derive(Component)]
struct MyComponent;

fn main() {
    App::new()
        .register_type::<MyComponent>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `MyComponent` does not provide type registration information
   --> examples/app/empty.rs:8:26
    |
8   |         .register_type::<MyComponent>()
    |          -------------   ^^^^^^^^^^^ the trait `GetTypeRegistration` is not implemented for `MyComponent`
    |          |
    |          required by a bound introduced by this call
    |
    = note: consider annotating `MyComponent` with `#[derive(Reflect)]`
    = help: the following other types implement trait `GetTypeRegistration`:
              bool
              char
              isize
              i8
              i16
              i32
              i64
              i128
            and 443 others
note: required by a bound in `bevy::prelude::App::register_type`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:619:29
    |
619 |     pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::register_type`
```

</details>

### Missing `#[derive(States)]` Implementation

<details>
<summary>Example Code</summary>

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

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

fn main() {
    App::new()
        .init_state::<AppState>()
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: the trait bound `AppState: FreelyMutableState` is not satisfied
   --> examples/app/empty.rs:15:23
    |
15  |         .init_state::<AppState>()
    |          ----------   ^^^^^^^^ the trait `FreelyMutableState` is not implemented for `AppState`
    |          |
    |          required by a bound introduced by this call
    |
    = note: consider annotating `AppState` with `#[derive(States)]`
note: required by a bound in `bevy::prelude::App::init_state`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:282:26
    |
282 |     pub fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
    |                          ^^^^^^^^^^^^^^^^^^ required by this bound in `App::init_state`
```

</details>

### Adding a `System` with Unhandled Output

<details>
<summary>Example Code</summary>

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

fn producer() -> u32 {
    123
}

fn main() {
    App::new()
        .add_systems(Update, consumer)
        .run();
}
```

</details>

<details>
<summary>Error Generated</summary>

```error
error[E0277]: `fn() -> u32 {producer}` does not describe a valid system configuration
   --> examples/app/empty.rs:9:30
    |
9   |         .add_systems(Update, producer)
    |          -----------         ^^^^^^^^ invalid system configuration
    |          |
    |          required by a bound introduced by this call
    |
    = help: the trait `IntoSystem<(), (), _>` is not implemented for fn item `fn() -> u32 {producer}`, which is required by `fn() -> u32 {producer}: IntoSystemConfigs<_>`
    = help: the following other types implement trait `IntoSystemConfigs<Marker>`:
              <Box<(dyn bevy::prelude::System<In = (), Out = ()> + 'static)> as IntoSystemConfigs<()>>
              <NodeConfigs<Box<(dyn bevy::prelude::System<In = (), Out = ()> + 'static)>> as IntoSystemConfigs<()>>
              <(S0,) as IntoSystemConfigs<(SystemConfigTupleMarker, P0)>>
              <(S0, S1) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1)>>
              <(S0, S1, S2) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2)>>
              <(S0, S1, S2, S3) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3)>>
              <(S0, S1, S2, S3, S4) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4)>>
              <(S0, S1, S2, S3, S4, S5) as IntoSystemConfigs<(SystemConfigTupleMarker, P0, P1, P2, P3, P4, P5)>>
            and 14 others
    = note: required for `fn() -> u32 {producer}` to implement `IntoSystemConfigs<_>`
note: required by a bound in `bevy::prelude::App::add_systems`
   --> C:\Users\Zac\Documents\GitHub\bevy\crates\bevy_app\src\app.rs:342:23
    |
339 |     pub fn add_systems<M>(
    |            ----------- required by a bound in this associated function
...
342 |         systems: impl IntoSystemConfigs<M>,
    |                       ^^^^^^^^^^^^^^^^^^^^ required by this bound in `App::add_systems`
```

</details>
</details>

## Testing

CI passed locally.

## Migration Guide

Upgrade to version 1.78 (or higher) of Rust.

## Future Work

- Currently, hints are not supported in this diagnostic. Ideally,
suggestions like _"consider using ..."_ would be in a hint rather than a
note, but that is the best option for now.
- System chaining and other `all_tuples!(...)`-based traits have bad
error messages due to the slightly different error message format.

---------

Co-authored-by: Jamie Ridding <Themayu@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-05-17 00:49:05 +00:00
IceSentry
aa907d5437
Remove unnecessary .view_layouts (#13394)
# Objective

- The volumetric fog PR originally needed to be modified to use
`.view_layouts` but that was changed in another PR. The merge with main
still kept those around.

## Solution

- Remove them because they aren't necessary
2024-05-16 19:12:36 +00:00
Ben Harper
be03ba1b68
Add reflect impls for bevy_math curve structs (#13348)
# Objective

Fixes #13189

## Solution

To add the reflect impls I needed to make all the struct fields pub. I
don't think there's any harm for these types, but just a note for
review.

---------

Co-authored-by: Ben Harper <ben@tukom.org>
2024-05-16 17:59:56 +00:00
Patrick Walton
19bfa41768
Implement volumetric fog and volumetric lighting, also known as light shafts or god rays. (#13057)
This commit implements a more physically-accurate, but slower, form of
fog than the `bevy_pbr::fog` module does. Notably, this *volumetric fog*
allows for light beams from directional lights to shine through,
creating what is known as *light shafts* or *god rays*.

To add volumetric fog to a scene, add `VolumetricFogSettings` to the
camera, and add `VolumetricLight` to directional lights that you wish to
be volumetric. `VolumetricFogSettings` has numerous settings that allow
you to define the accuracy of the simulation, as well as the look of the
fog. Currently, only interaction with directional lights that have
shadow maps is supported. Note that the overhead of the effect scales
directly with the number of directional lights in use, so apply
`VolumetricLight` sparingly for the best results.

The overall algorithm, which is implemented as a postprocessing effect,
is a combination of the techniques described in [Scratchapixel] and
[this blog post]. It uses raymarching in screen space, transformed into
shadow map space for sampling and combined with physically-based
modeling of absorption and scattering. Bevy employs the widely-used
[Henyey-Greenstein phase function] to model asymmetry; this essentially
allows light shafts to fade into and out of existence as the user views
them.

Volumetric rendering is a huge subject, and I deliberately kept the
scope of this commit small. Possible follow-ups include:

1. Raymarching at a lower resolution.

2. A post-processing blur (especially useful when combined with (1)).

3. Supporting point lights and spot lights.

4. Supporting lights with no shadow maps.

5. Supporting irradiance volumes and reflection probes.

6. Voxel components that reuse the volumetric fog code to create voxel
shapes.

7. *Horizon: Zero Dawn*-style clouds.

These are all useful, but out of scope of this patch for now, to keep
things tidy and easy to review.

A new example, `volumetric_fog`, has been added to demonstrate the
effect.

## Changelog

### Added

* A new component, `VolumetricFog`, is available, to allow for a more
physically-accurate, but more resource-intensive, form of fog.

* A new component, `VolumetricLight`, can be placed on directional
lights to make them interact with `VolumetricFog`. Notably, this allows
such lights to emit light shafts/god rays.

![Screenshot 2024-04-21
162808](https://github.com/bevyengine/bevy/assets/157897/7a1fc81d-eed5-4735-9419-286c496391a9)

![Screenshot 2024-04-21
132005](https://github.com/bevyengine/bevy/assets/157897/e6d3b5ca-8f59-488d-a3de-15e95aaf4995)

[Scratchapixel]:
https://www.scratchapixel.com/lessons/3d-basic-rendering/volume-rendering-for-developers/intro-volume-rendering.html

[this blog post]: https://www.alexandre-pestana.com/volumetric-lights/

[Henyey-Greenstein phase function]:
https://www.pbr-book.org/4ed/Volume_Scattering/Phase_Functions#TheHenyeyndashGreensteinPhaseFunction
2024-05-16 17:13:18 +00:00
charlotte
4c3b7679ec
#12502 Remove limit on RenderLayers. (#13317)
# Objective

Remove the limit of `RenderLayer` by using a growable mask using
`SmallVec`.

Changes adopted from @UkoeHB's initial PR here
https://github.com/bevyengine/bevy/pull/12502 that contained additional
changes related to propagating render layers.

Changes

## Solution

The main thing needed to unblock this is removing `RenderLayers` from
our shader code. This primarily affects `DirectionalLight`. We are now
computing a `skip` field on the CPU that is then used to skip the light
in the shader.

## Testing

Checked a variety of examples and did a quick benchmark on `many_cubes`.
There were some existing problems identified during the development of
the original pr (see:
https://discord.com/channels/691052431525675048/1220477928605749340/1221190112939872347).
This PR shouldn't change any existing behavior besides removing the
layer limit (sans the comment in migration about `all` layers no longer
being possible).

---

## Changelog

Removed the limit on `RenderLayers` by using a growable bitset that only
allocates when layers greater than 64 are used.

## Migration Guide

- `RenderLayers::all()` no longer exists. Entities expecting to be
visible on all layers, e.g. lights, should compute the active layers
that are in use.

---------

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2024-05-16 16:15:47 +00:00
Lynn
05e2552a68
Add Rounded box gizmos (#11948)
# Objective

- Implement rounded cuboids and rectangles, suggestion of #9400 

## Solution

- Added `Gizmos::rounded_cuboid`, `Gizmos::rounded_rect` and
`Gizmos::rounded_rect_2d`.
- All of these return builders that allow configuring of the corner/edge
radius using `.corner_radius(...)` or `.edge_radius(...)` as well as the
line segments of each arc using `.arc_segments(...)`.

---

## Changelog

- Added a new `rounded_box` module to `bevy_gizmos` containing all of
the above methods and builders.
- Updated the examples `2d_gizmos` and `3d_gizmos`

## Additional information

The 3d example now looks like this:

<img width="1440" alt="Screenshot 2024-02-28 at 01 47 28"
src="https://github.com/bevyengine/bevy/assets/62256001/654e30ca-c091-4f14-a402-90138e95c71b">

And this is the updated 2d example showcasing negative corner radius:

<img width="1440" alt="Screenshot 2024-02-28 at 01 59 37"
src="https://github.com/bevyengine/bevy/assets/62256001/3904697a-5462-4ee7-abd9-3e893ca07082">
<img width="1440" alt="Screenshot 2024-02-28 at 01 59 47"
src="https://github.com/bevyengine/bevy/assets/62256001/a8892cfd-3aad-4c0c-87eb-559c17c8864c">

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: James Gayfer <10660608+jgayfer@users.noreply.github.com>
2024-05-16 16:13:49 +00:00
Adith Ramachandran
65e62ba5eb
Revert "Support calculating normals for indexed meshes" (#12716) and add support for calculating smooth normals (#13333)
# Objective

- Refactor the changes merged in #11654 to compute flat normals for
indexed meshes instead of smooth normals.
- Fixes #12716 

## Solution

- Partially revert the changes in #11654 to compute flat normals for
both indexed and unindexed meshes in `compute_flat_normals`
- Create a new method, `compute_smooth_normals`, that computes smooth
normals for indexed meshes
- Create a new method, `compute_normals`, that computes smooth normals
for indexed meshes and flat normals for unindexed meshes by default. Use
this new method instead of `compute_flat_normals`.

## Testing

- Run the example with and without the changes to ensure that the
results are identical.
2024-05-16 14:54:35 +00:00
Johannes Hackel
1efa578ffb
Fix transmission by setting the correct value for transmissive_lighting_input.F_ab (#13379)
# Objective

- The clearcoat PR #13031 had a small typo which broke transmission
- Fixes #13284

## Solution

- Set transmissive_lighting_input.F_ab to the correct value


![transmission_fix](https://github.com/bevyengine/bevy/assets/688816/92158117-de3a-4fa5-8af8-dcbd1d5eee04)
2024-05-16 14:33:32 +00:00
Xzihnago
eba8744a70
Add Debug derive for ScreenSpaceAmbientOcclusionSettings struct (#13387)
# Objective

To streamline the code which utilizes `Debug` in user's struct like
`GraphicsSettings`. This addition aims to enhance code simplicity and
readability.

## Solution

Add `Debug` derive for `ScreenSpaceAmbientOcclusionSettings` struct.

## Testing

Should have no impact.
2024-05-16 11:29:34 +00:00
IceSentry
d9993a8092
Enable depth of field on webgpu (#13374)
# Objective

- Depth of field is currently disabled on any wasm targets, but the bug
it's trying to avoid is only an issue in webgl.

## Solution

- Enable dof when compiling for webgpu
- I also remove the msaa check because sampling a depth texture doesn't
work with or without msaa in webgl
- Unfortunately, Bokeh seems to be broken when using webgpu, so default
to Gaussian instead to make sure the defaults have the broadest platform
support

## Testing

- I added dof to the 3d_shapes example and compiled it to webgpu to
confirm it works
- I also tried compiling to webgl to confirm things still works and dof
isn't rendered.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-05-16 06:48:28 +00:00
IcyLeave6109
f61c55fd90
Allow shapes to be constructed with zero values (#13365)
# Objective

Fixes #13332.

## Solution

The assertion `circumradius >= 0.0` to allow zero.

Are there any other shapes that need to be allowed to be constructed
with zero?

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-05-16 02:22:50 +00:00
Pietro
d17fb160b0
Fix ClearColor in 2d pipelines (#13378)
# Objective

- Fixes #13377
- Fixes https://github.com/bevyengine/bevy/issues/13383

## Solution

- Even if the number of renderables is empty, the transparent phase need
to run to set the clear color.

## Testing

- Tested on the `clear_color` example
2024-05-15 20:36:02 +00:00
floppyhammer
8da4fcb616
Fix UI border artifacts caused by incorrect blending (#12725)
Fixes https://github.com/bevyengine/bevy/issues/12702.

Co-authored-by: François Mockers <mockersf@gmail.com>
2024-05-15 18:50:30 +00:00
JMS55
debcf3fb1d
Misc asset code quality and docs (#13382)
* Fix a doc comment for AssetSources
* Move some complicated generics to a where clause and write out T ->
Transformer fully
2024-05-15 18:49:04 +00:00
Csányi István
f91fd322b7
Skip redundant mesh_position_local_to_world call in vertex prepass shader (#13158)
# Objective

Optimize vertex prepass shader maybe?
Make it consistent with the base vertex shader

## Solution

`mesh_position_local_to_clip` just calls `mesh_position_local_to_world`
and then `position_world_to_clip`
since `out.world_position` is getting calculated anyway a few lines
below, just move it up and use it's output to calculate `out.position`.

It is the same as in the base vertex shader (`mesh.wgsl`).

Note: I have no idea if there is a reason that it was this way. I'm not
an expert, just noticed this inconsistency while messing with custom
shaders.
2024-05-14 16:31:58 +00:00
Jamie Ridding
dcf24dfd6b
Implement WorldQuery and QueryData on Mut. (#13338)
# Objective

Provides a `WorldQuery` implementation on `Mut<T>` that forwards to the
implementation on `&mut T`, and give users a way to opt-in to change
detection in auto-generated `QueryData::ReadOnly` types.

Fixes #13329.

## Solution

I implemented `WorldQuery` on `Mut<'w, T>` as a forwarding
implementation to `&mut T`, setting the `QueryData::ReadOnly` associated
type to `Ref<'w, T>`. This provides users the ability to explicitly
opt-in to change detection in the read-only forms of queries.

## Testing

A documentation test was added to `Mut` showcasing the new
functionality.

---

## Changelog

### Added

- Added an implementation of `WorldQuery` and `QueryData` on
`bevy_ecs::change_detection::Mut`.
2024-05-14 12:38:31 +00:00
Zachary Harrold
6482a036cb
Implement Color Operations for Color (#13285)
# Objective

- Fixes #13214

## Solution

Delegates to internal type when possible, otherwise uses
`ChosenColorSpace` as an intermediary. This _will_ double convert, but
this is considered an acceptable compromise since use of specific colour
types in performance critical colour operations is already encouraged.

`ChosenColorSpace` is `Oklcha` since it's perceptually uniform while
supporting all required operations, and in my opinion is the "best" for
this task. Using different spaces for different operations will make
documenting this double-conversion behaviour more challenging.

## Testing

Changes straightforward enough to not require testing beyond current CI
in my opinion.

---

## Changelog

- Implemented the following traits for `Color`:
  - `Luminance`
  - `Hue`
  - `Mix`
  - `EuclideanDistance`
  - `ClampColor`
- Added documentation to `Color` explaining the behaviour of these
operations (possible conversion, etc.)
2024-05-14 10:15:47 +00:00
Griffin
519ed5de42
Apply uv transform in the prepass (#13250)
# Objective

- The UV transform was applied in the main pass but not the prepass.

## Solution

- Apply the UV transform in the prepass.

## Testing

- The normals in my scene now look correct when using the prepass.
2024-05-13 22:33:09 +00:00
Vic
0eb4bb6bab
constrain WorldQuery::get_state to only use &Components (#13343)
# Objective

Passing `&World` in the `WorldQuery::get_state` method is unnecessary,
as all implementations of this method in the engine either only access
`Components` in `&World`, or do nothing with it.
It can introduce UB by necessitating the creation of a `&World` from a
`UnsafeWorldCell`.
This currently happens in `Query::transmute_lens`, which obtains a
`&World` from the internal `UnsafeWorldCell` solely to pass to
`get_state`. `Query::join` suffers from the same issue.
Other cases of UB come from allowing implementors of `WorldQuery` to
freely access `&World`, like in the `bevy-trait-query` crate, where a
[reference to a resource is
obtained](0c0e7dd646/src/lib.rs (L445))
inside of
[`get_state`](0c0e7dd646/src/one.rs (L245)),
potentially aliasing with a `ResMut` parameter in the same system.

`WorldQuery::init_state` currently requires `&mut World`, which doesn't
suffer from these issues.
But that too can be changed to receive a wrapper around `&mut
Components` and `&mut Storages` for consistency in a follow-up PR.

## Solution

Replace the `&World` parameter in `get_state` with `&Components`.

## Changelog

 `WorldQuery::get_state` now takes `&Components` instead of `&World`.
The `transmute`, `transmute_filtered`, `join` and `join_filtered`
methods on `QueryState` now similarly take `&Components` instead of
`&World`.

## Migration Guide

Users of `WorldQuery::get_state` or `transmute`, `transmute_filtered`,
`join` and `join_filtered` methods on `QueryState` now need to pass
`&Components` instead of `&World`.
`&Components` can be trivially obtained from either `components` method
on `&World` or `UnsafeWorldCell`.
For implementors of `WorldQuery::get_state` that were accessing more
than the `Components` inside `&World` and its methods, this is no longer
allowed.
2024-05-13 21:00:01 +00:00
JoshValjosh
2037b880ac
Add docs for PointLight (#13355)
Fixes #13106
2024-05-13 18:55:36 +00:00
Brezak
cbda71c2b3
Determine msrv for every standalone bevy_* crate. (#13211)
# Objective

As was pointed out in #13183, `bevy_mikktspace` is missing it's msrv
from it `Cargo.toml`. This promted me to check the msrv of every
`bevy_*` crate. Closes #13183.

## Solution

- Call `cargo check` with different rust versions on every bevy crate
until it doesn't complain.
- Write down the rust version `cargo check` started working.

## Testing

- Install `cargo-msrv`.
- Run `cargo msrv verify`.
- Rejoice.

---

## Changelog

Every published bevy crate now specifies a MSRV. If your rust toolchain
isn't at least version `1.77.0` You'll likely not be able to compile
most of bevy.

## Migration Guide

If your rust toolchain is bellow version`1.77.0, update.
2024-05-13 18:26:41 +00:00
Patrick Walton
df31b808c3
Implement fast depth of field as a postprocessing effect. (#13009)
This commit implements the [depth of field] effect, simulating the blur
of objects out of focus of the virtual lens. Either the [hexagonal
bokeh] effect or a faster Gaussian blur may be used. In both cases, the
implementation is a simple separable two-pass convolution. This is not
the most physically-accurate real-time bokeh technique that exists;
Unreal Engine has [a more accurate implementation] of "cinematic depth
of field" from 2018. However, it's simple, and most engines provide
something similar as a fast option, often called "mobile" depth of
field.

The general approach is outlined in [a blog post from 2017]. We take
advantage of the fact that both Gaussian blurs and hexagonal bokeh blurs
are *separable*. This means that their 2D kernels can be reduced to a
small number of 1D kernels applied one after another, asymptotically
reducing the amount of work that has to be done. Gaussian blurs can be
accomplished by blurring horizontally and then vertically, while
hexagonal bokeh blurs can be done with a vertical blur plus a diagonal
blur, plus two diagonal blurs. In both cases, only two passes are
needed. Bokeh requires the first pass to have a second render target and
requires two subpasses in the second pass, which decreases its
performance relative to the Gaussian blur.

The bokeh blur is generally more aesthetically pleasing than the
Gaussian blur, as it simulates the effect of a camera more accurately.
The shape of the bokeh circles are determined by the number of blades of
the aperture. In our case, we use a hexagon, which is usually considered
specific to lower-quality cameras. (This is a downside of the fast
hexagon approach compared to the higher-quality approaches.) The blur
amount is generally specified by the [f-number], which we use to compute
the focal length from the film size and FOV. By default, we simulate
standard cinematic cameras of f/1 and [Super 35]. The developer can
customize these values as desired.

A new example has been added to demonstrate depth of field. It allows
customization of the mode (Gaussian vs. bokeh), focal distance and
f-numbers. The test scene is inspired by a [blog post on depth of field
in Unity]; however, the effect is implemented in a completely different
way from that blog post, and all the assets (textures, etc.) are
original.

Bokeh depth of field:
![Screenshot 2024-04-17
152535](https://github.com/bevyengine/bevy/assets/157897/702f0008-1c8a-4cf3-b077-4110f8c46584)

Gaussian depth of field:
![Screenshot 2024-04-17
152542](https://github.com/bevyengine/bevy/assets/157897/f4ece47a-520e-4483-a92d-f4fa760795d3)

No depth of field:
![Screenshot 2024-04-17
152547](https://github.com/bevyengine/bevy/assets/157897/9444e6aa-fcae-446c-b66b-89469f1a1325)

[depth of field]: https://en.wikipedia.org/wiki/Depth_of_field

[hexagonal bokeh]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[a more accurate implementation]:
https://epicgames.ent.box.com/s/s86j70iamxvsuu6j35pilypficznec04

[a blog post from 2017]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[f-number]: https://en.wikipedia.org/wiki/F-number

[Super 35]: https://en.wikipedia.org/wiki/Super_35

[blog post on depth of field in Unity]:
https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/

## Changelog

### Added

* A depth of field postprocessing effect is now available, to simulate
objects being out of focus of the camera. To use it, add
`DepthOfFieldSettings` to an entity containing a `Camera3d` component.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
2024-05-13 18:23:56 +00:00
Johannes Hackel
3f5a090b1b
Add UV channel selection to StandardMaterial (#13200)
# Objective

- The StandardMaterial always uses ATTRIBUTE_UV_0 for each texture
except lightmap. This is not flexible enough for a lot of gltf Files.
- Fixes #12496
- Fixes #13086
- Fixes #13122
- Closes #13153

## Solution

- The StandardMaterial gets extended for each texture by an UvChannel
enum. It defaults to Uv0 but can also be set to Uv1.
- The gltf loader now handles the texcoord information. If the texcoord
is not supported it creates a warning.
- It uses StandardMaterial shader defs to define which attribute to use.

## Testing

This fixes #12496 for example:

![wall_fixed](https://github.com/bevyengine/bevy/assets/688816/bc37c9e1-72ba-4e59-b092-5ee10dade603)

For testing of all kind of textures I used the TextureTransformMultiTest
from
https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/TextureTransformMultiTest
Its purpose is to test multiple texture transfroms but it is also a good
test for different texcoords.
It also shows the issue with emission #13133.

Before:

![TextureTransformMultiTest_main](https://github.com/bevyengine/bevy/assets/688816/aa701d04-5a3f-4df1-a65f-fc770ab6f4ab)

After:

![TextureTransformMultiTest_texcoord](https://github.com/bevyengine/bevy/assets/688816/c3f91943-b830-4068-990f-e4f2c97771ee)
2024-05-13 18:23:09 +00:00
Joona Aalto
ac1f135e20
Add meshing for Cone (#11820)
# Objective

The `Cone` primitive should support meshing.

## Solution

Implement meshing for the `Cone` primitive. The default cone has a
height of 1 and a base radius of 0.5, and is centered at the origin.

An issue with cone meshes is that the tip does not really have a normal
that works, even with duplicated vertices. This PR uses only a single
vertex for the tip, with a normal of zero; this results in an "invalid"
normal that gets ignored by the fragment shader. This seems to be the
only approach we have for perfectly smooth cones. For discussion on the
topic, see #10298 and #5891.

Another thing to note is that the cone uses polar coordinates for the
UVs:

<img
src="https://github.com/bevyengine/bevy/assets/57632562/e101ded9-110a-4ac4-a98d-f1e4d740a24a"
alt="cone" width="400" />

This way, textures are applied as if looking at the cone from above:

<img
src="https://github.com/bevyengine/bevy/assets/57632562/8dea00f1-a283-4bc4-9676-91e8d4adb07a"
alt="texture" width="200" />

<img
src="https://github.com/bevyengine/bevy/assets/57632562/d9d1b5e6-a8ba-4690-b599-904dd85777a1"
alt="cone" width="200" />
2024-05-13 18:00:59 +00:00
moonlightaria
1a3549a916
State example (#13322)
# Objective
adopted from #10716
adds example for updating state

---------

Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-13 13:03:42 +00:00
Bram Buurlage
bfc13383e0
Fix incorrect workgroupBarrier and OOB array access in auto_exposure (#13283)
This commit fixes two issues in auto_exposure.wgsl:
* A `storageBarrier()` was incorrectly used where a `workgroupBarrier()`
should be used instead;
* Resetting the `histogram_shared` array would write beyond the 64th
index, which is out of bounds.

## Solution

The first issue is fixed by using the appropriate workgroupBarrier
instead;
The second issue is fixed by adding a range check before setting
`histogram_shared[local_invocation_index] = 0u`.

## Testing

These changes were tested using the Xcode metal profiler, and I could
not find any noticable change in compute shader performance.
2024-05-12 23:24:58 +00:00
IcyLeave6109
de7ff295e1
Make bevy_time optionally depend on bevy_reflect (#13263)
# Objective

Fixes #13246.
2024-05-12 23:19:07 +00:00
François Mockers
173db7726f
remove unused warnings in release (#13344)
# Objective

- When building for release, there are "unused" warnings:
```
warning: unused import: `bevy_utils::warn_once`
  --> crates/bevy_pbr/src/render/mesh_view_bindings.rs:32:5
   |
32 | use bevy_utils::warn_once;
   |     ^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

warning: unused variable: `texture_count`
   --> crates/bevy_pbr/src/render/mesh_view_bindings.rs:371:17
    |
371 |             let texture_count: usize = entries
    |                 ^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_texture_count`
    |
    = note: `#[warn(unused_variables)]` on by default
```

## Solution

- Gate the import and definition by the same cfg as their uses
2024-05-12 22:30:34 +00:00
ickshonpe
be217ab037
Add doc comments explaining the different behaviours of alignment and Anchor with text_2d (#8022)
# Objective
Add an explanation of the differences between `alignment` and `Anchor`
to the `Text2dBundle` docs.

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2024-05-12 21:42:04 +00:00
Periwink
ded5d523bd
Improve tracing layer customization (#13159)
# Objective

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

The current tracing customization option (the `update_subscriber` field)
was basically unusable because it provides a `dyn Subscriber` and most
layers require a `Subscriber` that also implements `for<'a>
LookupSpan<'a, Data=Data<'a>>`, so it was impossible to add a layer on
top of the `dyn Subscriber`.

This PR provides an alternative way of adding additional tracing layers
to the LogPlugin by instead creating an `Option<Layer>`.

This is enough for most situations because `Option<Layer>` and
`Vec<Layer>` both implement `Layer`.

## Solution

- Replace the `update_subscriber` field of `LogPlugin` with a
`custom_layer` field which is function pointer returning an
`Option<BoxedLayer>`
- Update the examples to showcase that this works:
  - with multiple additional layers
- with Layers that were previously problematic, such as
`bevy::log::tracing_subscriber::fmt::layer().with_file(true)` (mentioned
in the issue)
  
Note that in the example this results in duplicate logs, since we have
our own layer on top of the default `fmt_layer` added in the LogPlugin;
maybe in the future we might want to provide a single one? Or to let the
user customize the default `fmt_layer` ? I still think this change is an
improvement upon the previous solution, which was basically broken.

---

## Changelog

> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.

- The `LogPlugin`'s `update_subscriber` field has been replaced with
`custom_layer` to allow the user to flexibly add a `tracing::Layer` to
the layer stack

## Migration Guide

- The `LogPlugin`'s `update_subscriber` field has been replaced with
`custom_layer`

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-05-12 21:16:56 +00:00
Rob Parrett
2fd432c463
Fix motion blur on wasm (#13099)
# Objective

Fixes #13097 and other issues preventing the motion blur example from
working on wasm

## Solution

- Use a vec2 for padding
- Fix error initializing the `MotionBlur` struct on wasm+webgl2
- Disable MSAA on wasm+webgl2
- Fix `GlobalsUniform` padding getting added on the shader side for
webgpu builds

## Notes

The motion blur example now runs, but with artifacts. In addition to the
obvious black artifacts, the motion blur or dithering seem to just look
worse in a way I can't really describe. That may be expected.

```
AdapterInfo { name: "ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max, Unspecified Version)", vendor: 4203, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Gl }
```
<img width="1276" alt="Screenshot 2024-04-25 at 6 51 21 AM"
src="https://github.com/bevyengine/bevy/assets/200550/65401d4f-92fe-454b-9dbc-a2d89d3ad963">
2024-05-12 21:03:36 +00:00
Sean Sullivan
a4597a9c14
bevy_asset: Add missing web-sys feature and cleanup unused ones (#13281)
# Objective

- **Describe the objective or issue this PR addresses.**

`bevy_asset` includes code
[here](4350ad0bd1/crates/bevy_asset/src/io/wasm.rs (L61))
that references `web_sys::WorkerGlobalScope`. However, `bevy_asset` does
not enable this feature, see
[here](4350ad0bd1/crates/bevy_asset/Cargo.toml (L50)).
Running examples does not catch this problem because the feature is
implicitly included by `wgpu` when `bevy_render` is also a dependency,
see
[bevy_render](4350ad0bd1/crates/bevy_render/Cargo.toml (L73-L80))
and
[wgpu](3b6112d45d/wgpu/Cargo.toml (L201)).
This results in compile errors for environments that are not using
`bevy_render`.

To reproduce the problem, try to build the crate individually for wasm
targets by running `cargo build -p bevy_asset --target
wasm32-unknown-unknown`.

Running `cargo tree -e features --target wasm32-unknown-unknown` helped
diagnose the issue.

## Solution

- **Describe the solution used to achieve the objective above.**

This PR adds the `WorkerGlobalScope` feature to the `web-sys` portion of
`bevy_asset`'s `Cargo.toml`.

It also seems to be the case that `bevy_asset` no longer needs the
`Request` feature, since no code for `Request` is present anymore. I
confirmed that building the crate individually for wasm succeeds without
the feature, so that change is also included here.

This is a little off-topic, but the repository would probably benefit
from some automation around these types of changes, but I'm not sure
what would work there. For example, building each crate individually for
some key targets would work, but is...well, a lot. Happy to follow up if
there is agreement on a good direction.

## Testing

- **Did you test these changes? If so, how?**
- **How can other people (reviewers) test your changes? Is there
anything specific they need to know?**

Building the crate individually for wasm by running `cargo build -p
bevy_asset --target wasm32-unknown-unknown`.

- **Are there any parts that need more testing?**

I don't believe so.
2024-05-12 20:53:59 +00:00
Ben Harper
6f641e9f9b
Add copy, clone, and debug derives to cubic spline structs (#13293)
# Objective

Fixes #13190

---------

Co-authored-by: Ben Harper <ben@tukom.org>
2024-05-12 20:48:08 +00:00
charlotte
dc0fdd6ad9
Ensure clean exit (#13236)
# Objective

Fixes two issues related to #13208.

First, we ensure render resources for a window are always dropped first
to ensure that the `winit::Window` always drops on the main thread when
it is removed from `WinitWindows`. Previously, changes in #12978 caused
the window to drop in the render world, causing issues.

We accomplish this by delaying despawning the window by a frame by
inserting a marker component `ClosingWindow` that indicates the window
has been requested to close and is in the process of closing. The render
world now responds to the equivalent `WindowClosing` event rather than
`WindowCloseed` which now fires after the render resources are
guarunteed to be cleaned up.

Secondly, fixing the above caused (revealed?) that additional events
were being delivered to the the event loop handler after exit had
already been requested: in my testing `RedrawRequested` and
`LoopExiting`. This caused errors to be reported try to send an exit
event on the close channel. There are two options here:
- Guard the handler so no additional events are delivered once the app
is exiting. I ~considered this but worried it might be confusing or bug
prone if in the future someone wants to handle `LoopExiting` or some
other event to clean-up while exiting.~ We are now taking this approach.
- Only send an exit signal if we are not already exiting. ~It doesn't
appear to cause any problems to handle the extra events so this seems
safer.~
 
Fixing this also appears to have fixed #13231.

Fixes #10260.

## Testing

Tested on mac only.

---

## Changelog

### Added
- A `WindowClosing` event has been added that indicates the window will
be despawned on the next frame.

### Changed
- Windows now close a frame after their exit has been requested.

## Migration Guide
- Ensure custom exit logic does not rely on the app exiting the same
frame as a window is closed.
2024-05-12 15:56:01 +00:00
rmsthebest
278380394f
Avoid bevy_reflect::List::iter wrapping in release mode (#13271)
# Objective
Fixes  #13230

## Solution
Uses solution described in  #13230
They mention a worry about adding a branch, but I'm not sure there is
one.

This code
```Rust
#[no_mangle]
pub fn next_if_some(num: i32, b: Option<bool>) -> i32 {
    num + b.is_some() as i32
}
```
produces this assembly with opt-level 3
```asm
next_if_some:
        xor     eax, eax
        cmp     sil, 2
        setne   al
        add     eax, edi
        ret
```

## Testing
Added test from #13230, tagged it as ignore as it is only useful in
release mode and very slow if you accidentally invoke it in debug mode.

---

## Changelog
Iterationg of ListIter will no longer overflow and wrap around

## Migration Guide
2024-05-12 15:01:05 +00:00
François Mockers
443ce9a62b
gizmos: take normal of normal on plane 3d before rotation (#13326)
# Objective

- Example `render_primitives` is painful to look at for the plane in 3d,
the gizmo seems to have extra rotations


https://github.com/bevyengine/bevy/assets/8672791/08509624-14ac-4f00-a758-9a14233ef1a9

## Solution

- Take the normal of the normal before rotation, then rotate it

## Testing

- Run the example, rotations are more in sync


https://github.com/bevyengine/bevy/assets/8672791/91c26ce4-4b7b-4575-ba32-7c32026e4596
2024-05-11 19:32:31 +00:00
Zachary Harrold
dcb8a13b22
Remove ClampColor (#13307)
# Objective

- Fixes #12543

## Solution

- Removed `ClampColor`

## Testing

- CI Passed

---

## Migration Guide

Manually clamp the various colour components yourself if this behaviour
is still required.

```rust
fn clamped_srgba(color: Srgba) -> Srgba {
    Srgba {
        red: color.red.clamp(0., 1.),
        green: color.green.clamp(0., 1.),
        blue: color.blue.clamp(0., 1.),
        alpha: color.alpha.clamp(0., 1.),
    }
}
```
2024-05-10 13:15:56 +00:00
Sean Sullivan
4b61bbe4e1
bevy_core: Derive useful traits on FrameCount (#13291)
# Objective

I am emboldened by my last small PR and am here with another.

- **Describe the objective or issue this PR addresses.**

It would be nice if `FrameCount` could be used by downstream plugins
that want to use frame data. The example that I have in mind is
[`leafwing_input_playback`](https://github.com/Leafwing-Studios/leafwing_input_playback/issues/29)
which has a [duplicate implementation of
`FrameCount`](https://github.com/Leafwing-Studios/leafwing_input_playback/blob/main/src/frame_counting.rs#L9-L37)
used in several structs which rely on those derives (or otherwise the
higher-level structs would have to implement these traits manually).
That crate, using `FrameCount`, tracks input frames and timestamps and
enables various playback modes.

I am aware that bevy org refrains from deriving lots of unnecessary
stuff on bevy types to avoid compile time creep. It is worth mentioning
the (equally reasonable) alternative that downstream crates _should_
implement some `FrameCount` themselves if they want special behavior
from it.

## Solution

- **Describe the solution used to achieve the objective above.**

I added derives for `PartialEq, Eq, PartialOrd, Ord` and implementations
for `serde::{Deserialize, Serialize}` to `FrameCount`.

## Testing

Manually confirmed that the serde implementation works, but that's all.
Let me know if I should do more here.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-10 10:00:08 +00:00
Matty
4da11fda77
Add AXES iterators for Dir types (#13305)
# Objective

Sometimes it's nice to iterate over all the coordinate axes using
something like `Vec3::AXES`. This was not available for the
corresponding `Dir` types and now it is.

## Solution

We already have things like `Dir2::X`, `Dir3::Z` and so on, so I just
threw them in an array like the vector types do it. I also slightly
refactored the sphere gizmo code to use `Dir3::AXES` and operate on
directions instead of using `Dir3::new_unchecked`.

## Testing

I looked at the sphere in the `3d_gizmos` example and it seems to work,
so I assume I didn't break anything.
2024-05-09 23:30:44 +00:00
Gino Valente
705c144259
bevy_reflect: Remove ContainerAttributes::merge (#13303)
# Objective

Unblocks #11659.

Currently the `Reflect` derive macro has to go through a merge process
for each `#[reflect]`/`#[reflet_value]` attribute encountered on a
container type.

Not only is this a bit inefficient, but it also has a soft requirement
that we can compare attributes such that an error can be thrown on
duplicates, invalid states, etc.

While working on #11659 this proved to be challenging due to the fact
that `syn` types don't implement `PartialEq` or `Hash` without enabling
the `extra-traits` feature.

Ideally, we wouldn't have to enable another feature just to accommodate
this one use case.

## Solution

Removed `ContainerAttributes::merge`.

This was a fairly simple change as we could just have the parsing
functions take `&mut self` instead of returning `Self`.

## Testing

CI should build as there should be no user-facing change.
2024-05-09 18:17:54 +00:00
Lee-Orr
42ba9dfaea
Separate state crate (#13216)
# Objective

Extracts the state mechanisms into a new crate called "bevy_state".

This comes with a few goals:

- state wasn't really an inherent machinery of the ecs system, and so
keeping it within bevy_ecs felt forced
- by mixing it in with bevy_ecs, the maintainability of our more robust
state system was significantly compromised

moving state into a new crate makes it easier to encapsulate as it's own
feature, and easier to read and understand since it's no longer a
single, massive file.

## Solution

move the state-related elements from bevy_ecs to a new crate

## Testing

- Did you test these changes? If so, how? all the automated tests
migrated and passed, ran the pre-existing examples without changes to
validate.

---

## Migration Guide

Since bevy_state is now gated behind the `bevy_state` feature, projects
that use state but don't use the `default-features` will need to add
that feature flag.

Since it is no longer part of bevy_ecs, projects that use bevy_ecs
directly will need to manually pull in `bevy_state`, trigger the
StateTransition schedule, and handle any of the elements that bevy_app
currently sets up.

---------

Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
2024-05-09 18:06:05 +00:00
moonlightaria
3f2cc244d7
Add color conversions #13224 (#13276)
# Objective
fixes #13224
adds conversions for Vec3 and Vec4 since these appear so often

## Solution
added Covert trait (couldn't think of good name) for [f32; 4], [f32, 3],
Vec4, and Vec3 along with the symmetric implementation

## Changelog
added conversions between arrays and vector to colors and vice versa

#migration
LinearRgba appears to have already had implicit conversions for [f32;4]
and Vec4
2024-05-09 18:01:52 +00:00
Brezak
9c4ac7c297
Finish the work on try_apply (#12646)
# Objective

Finish the `try_apply` implementation started in #6770 by @feyokorenhof.
Supersedes and closes #6770. Closes #6182

## Solution

Add `try_apply` to `Reflect` and implement it in all the places that
implement `Reflect`.

---

## Changelog

Added `try_apply` to `Reflect`.

---------

Co-authored-by: Feyo Korenhof <feyokorenhof@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-05-08 14:26:01 +00:00
IceSentry
64e1a7835a
Clean up 2d render phases (#12982)
# Objective

Currently, the 2d pipeline only has a transparent pass that is used for
everything. I want to have separate passes for opaque/alpha
mask/transparent meshes just like in 3d.

This PR does the basic work to start adding new phases to the 2d
pipeline and get the current setup a bit closer to 3d.

## Solution

- Use `ViewNode` for `MainTransparentPass2dNode`
- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`
- Rename everything to clarify that the main pass is currently the
transparent pass

---

## Changelog

- Added `Node2d::StartMainPass`, `Node2d::EndMainPass`

## Migration Guide

If you were using `Node2d::MainPass` to order your own custom render
node. You now need to order it relative to `Node2d::StartMainPass` or
`Node2d::EndMainPass`.
2024-05-08 08:13:39 +00:00
Patrick Walton
0dddfa07ab
Fix the WebGL 2 backend by giving the visibility_ranges array a fixed length. (#13210)
WebGL 2 doesn't support variable-length uniform buffer arrays. So we
arbitrarily set the length of the visibility ranges field to 64 on that
platform.

---------

Co-authored-by: IceSentry <c.giguere42@gmail.com>
2024-05-08 07:34:59 +00:00
Brezak
4350ad0bd1
Make AssetMetaCheck a field on the asset plugin (#13177)
# Objective

There's a TODO comment above the `AssetMetaCheck` enum mentioning this
should have been done in 0.13

## Solution

Do it in 0.14

## Testing

I've checked that all the asset tests compile. I've also run the
asset_processing and asset_settings tests and they both work.

---

## Changelog

### Changed
-
[`AssetMetaCheck`](https://docs.rs/bevy/latest/bevy/asset/enum.AssetMetaCheck.html)
is no longer a resource and is now a field on the
[`AssetPlugin`](https://docs.rs/bevy/latest/bevy/asset/struct.AssetPlugin.html).

## Migration Guide

Changes to how bevy handles asset meta files now need to be specified
when inserting the `AssetPlugin`.
2024-05-07 23:52:30 +00:00
Lynn
03f4cc5dde
Extrusion (#13270)
# Objective

- Adds a basic `Extrusion<T: Primitive2d>` shape, suggestion of #10572 

## Solution

- Adds `Measured2d` and `Measured3d` traits for getting the
perimeter/area or area/volume of shapes. This allows implementing
`.volume()` and `.area()` for all extrusions `Extrusion<T: Primitive2d +
Measured2d>` within `bevy_math`
- All existing perimeter, area and volume implementations for primitves
have been moved into implementations of `Measured2d` and `Measured3d`
- Shapes should be extruded along the Z-axis since an extrusion of depth
`0.` should be equivalent in everything but name to the base shape

## Caviats

- I am not sure about the naming. `Extrusion<T>` could also be
`Prism<T>` and the `MeasuredNd` could also be something like
`MeasuredPrimitiveNd`. If you have any other suggestions, please fell
free to share them :)

## Future work

This PR adds a basic `Extrusion` shape and does not implement a lot of
things you might want it to. Some of the future possibilities include:
- [ ] bounding for extrusions
- [ ] making extrusions work with gizmos
- [ ] meshing

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-07 14:41:55 +00:00
BD103
22305acf66
Rename bevy_reflect_derive folder to derive (#13269)
# Objective

- Some of the "large" crates have sub-crates, usually for things such as
macros.
- For an example, see [`bevy_ecs_macros` at
`bevy_ecs/macros`](4f9f987099/crates/bevy_ecs/macros).
- The one crate that does not follow this convention is
[`bevy_reflect_derive`](4f9f987099/crates/bevy_reflect/bevy_reflect_derive),
which is in the `bevy_reflect/bevy_reflect_derive` folder and not
`bevy_reflect/derive` or `bevy_reflect/macros`.

## Solution

- Rename folder `bevy_reflect_derive` to `derive`.
- I chose to use `derive` instead of `macros` because the crate name
itself ends in `_derive`. (One of only two crates to actually use this
convention, funnily enough.)

## Testing

- Build and test `bevy_reflect` and `bevy_reflect_derive`.
- Apply the following patch to `publish.sh` to run it in `--dry-run`
mode, to test that the path has been successfully updated:
- If you have any security concerns about applying random diffs, feel
free to skip this step. Worst case scenario it fails and Cart has to
manually publish a few crates.

```bash
# Apply patch to make `publish.sh` *not* actually publish anything.
git apply path/to/foo.patch
# Make `publish.sh` executable.
chmod +x tools/publish.sh
# Execute `publish.sh`.
./tools/publish.sh
```

```patch
diff --git a/tools/publish.sh b/tools/publish.sh
index b020bad28..fbcc09281 100644
--- a/tools/publish.sh
+++ b/tools/publish.sh
@@ -49,7 +49,7 @@ crates=(
 
 if [ -n "$(git status --porcelain)" ]; then
     echo "You have local changes!"
-    exit 1
+    # exit 1
 fi
 
 pushd crates
@@ -61,15 +61,15 @@ do
   cp ../LICENSE-APACHE "$crate"
   pushd "$crate"
   git add LICENSE-MIT LICENSE-APACHE
-  cargo publish --no-verify --allow-dirty
+  cargo publish --no-verify --allow-dirty --dry-run
   popd
-  sleep 20
+  # sleep 20
 done
 
 popd
 
 echo "Publishing root crate"
-cargo publish --allow-dirty
+cargo publish --allow-dirty --dry-run
 
 echo "Cleaning local state"
 git reset HEAD --hard
```

---

## Changelog

- Moved `bevy_reflect_derive` from
`crates/bevy_reflect/bevy_reflect_derive` to
`crates/bevy_reflect/derive`.
2024-05-07 07:55:32 +00:00
IceSentry
4737106bdd
Extract mesh view layouts logic (#13266)
Copied almost verbatim from the volumetric fog PR

# Objective

- Managing mesh view layouts is complicated

## Solution

- Extract it to it's own struct
- This was done as part of #13057 and is copied almost verbatim. I
wanted to keep this part of the PR it's own atomic commit in case we
ever have to revert fog or run a bisect. This change is good whether or
not we have volumetric fog.

Co-Authored-By: @pcwalton
2024-05-07 06:46:41 +00:00
moonlightaria
1126b5a3d6
replace std::f32::EPSILON with f32::EPSILON (#13267)
# Objective
fixes clippy warning related to using a std::f32::EPSILON which is
planned to be depreciated for f32::EPSILON
2024-05-07 05:23:53 +00:00
Lynn
4f9f987099
Ellipse functions (#13025)
# Objective

- Add some useful methods to `Ellipse`

## Solution

- Added `Ellipse::perimeter()` and `::focal_length()`

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-05-06 21:31:51 +00:00
Mike
fa0745fdd0
Remove bevy log's usage of non send resource (#13252)
# Objective

I'm adopting #9122 and pulling some of the non controversial changes out
to make the final pr easier to review.

This pr removes the NonSend resource usage from `bevy_log`. 

## Solution

`tracing-chrome` uses a guard that is stored in the world, so that when
it is dropped the json log file is written out. The guard is Send +
!Sync, so we can store it in a SyncCell to hold it in a regular resource
instead of using a non send resource.

## Testing

Tested by running an example with `-F tracing chrome` and making sure
there weren't any errors and the json file was created.

---

## Changelog

- replaced `bevy_log`'s usage of a non send resource.
2024-05-06 21:15:10 +00:00
Fpgu
60a73fa60b
Use Dir3 for local axis methods in GlobalTransform (#13264)
Switched the return type from `Vec3` to `Dir3` for directional axis
methods within the `GlobalTransform` component.

## Migration Guide
The `GlobalTransform` component's directional axis methods (e.g.,
`right()`, `left()`, `up()`, `down()`, `back()`, `forward()`) have been
updated from returning `Vec3` to `Dir3`.
2024-05-06 20:52:05 +00:00
andristarr
bb76a2c69c
multi_threaded feature rename (#12997)
# Objective

Fixes #12966

## Solution

Renaming multi_threaded feature to match snake case

## Migration Guide

Bevy feature multi-threaded should be refered to multi_threaded from now
on.
2024-05-06 20:49:32 +00:00
Patrick Walton
59b52fc94e
Modulate the emissive texture by the emissive color again. (#13251)
Fixes a regression introduced by #13031.
2024-05-06 20:06:10 +00:00
Patrick Walton
77ed72bc16
Implement clearcoat per the Filament and the KHR_materials_clearcoat specifications. (#13031)
Clearcoat is a separate material layer that represents a thin
translucent layer of a material. Examples include (from the [Filament
spec]) car paint, soda cans, and lacquered wood. This commit implements
support for clearcoat following the Filament and Khronos specifications,
marking the beginnings of support for multiple PBR layers in Bevy.

The [`KHR_materials_clearcoat`] specification describes the clearcoat
support in glTF. In Blender, applying a clearcoat to the Principled BSDF
node causes the clearcoat settings to be exported via this extension. As
of this commit, Bevy parses and reads the extension data when present in
glTF. Note that the `gltf` crate has no support for
`KHR_materials_clearcoat`; this patch therefore implements the JSON
semantics manually.

Clearcoat is integrated with `StandardMaterial`, but the code is behind
a series of `#ifdef`s that only activate when clearcoat is present.
Additionally, the `pbr_feature_layer_material_textures` Cargo feature
must be active in order to enable support for clearcoat factor maps,
clearcoat roughness maps, and clearcoat normal maps. This approach
mirrors the same pattern used by the existing transmission feature and
exists to avoid running out of texture bindings on platforms like WebGL
and WebGPU. Note that constant clearcoat factors and roughness values
*are* supported in the browser; only the relatively-less-common maps are
disabled on those platforms.

This patch refactors the lighting code in `StandardMaterial`
significantly in order to better support multiple layers in a natural
way. That code was due for a refactor in any case, so this is a nice
improvement.

A new demo, `clearcoat`, has been added. It's based on [the
corresponding three.js demo], but all the assets (aside from the skybox
and environment map) are my original work.

[Filament spec]:
https://google.github.io/filament/Filament.html#materialsystem/clearcoatmodel

[`KHR_materials_clearcoat`]:
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md

[the corresponding three.js demo]:
https://threejs.org/examples/webgl_materials_physical_clearcoat.html

![Screenshot 2024-04-19
101143](https://github.com/bevyengine/bevy/assets/157897/3444bcb5-5c20-490c-b0ad-53759bd47ae2)

![Screenshot 2024-04-19
102054](https://github.com/bevyengine/bevy/assets/157897/6e953944-75b8-49ef-bc71-97b0a53b3a27)

## Changelog

### Added

* `StandardMaterial` now supports a clearcoat layer, which represents a
thin translucent layer over an underlying material.
* The glTF loader now supports the `KHR_materials_clearcoat` extension,
representing materials with clearcoat layers.

## Migration Guide

* The lighting functions in the `pbr_lighting` WGSL module now have
clearcoat parameters, if `STANDARD_MATERIAL_CLEARCOAT` is defined.

* The `R` reflection vector parameter has been removed from some
lighting functions, as it was unused.
2024-05-05 22:57:05 +00:00
Lynn
89cd5f54f8
Add Annulus-gizmos (#13233)
# Objective

- Add support for drawing `Annulus`-gizmos using
`gizmos.primitive_2d(...)`

## Changelog

- Updated the example `math/render_primitives`
2024-05-05 22:23:32 +00:00
Brezak
423a4732c3
Update compile test to use ui_test 0.23 (#13245)
# Objective

Closes #13241

## Solution

Update test utils to use `ui_test` 0.23.0.

## Testing

- Run compile tests for bevy_ecs.

cc @BD103
2024-05-05 22:17:56 +00:00
IceSentry
a22ecede49
Only create changed buffer if it already exists (#13242)
# Objective

- `DynamicUniformBuffer` tries to create a buffer as soon as the changed
flag is set to true. This doesn't work correctly when the buffer wasn't
already created. This currently creates a crash because it's trying to
create a buffer of size 0 if the flag is set but there's no buffer yet.

## Solution

- Don't create a changed buffer until there's data that needs to be
written to a buffer.

## Testing

- run `cargo run --example scene_viewer` and see that it doesn't crash
anymore

Fixes #13235
2024-05-05 22:16:11 +00:00
Kim Simmons
d1099ac7db
Doc custom CameraProjection requires use of plugin (#13140)
# Objective

Documentation should mention the two plugins required for your custom
`CameraProjection` to work.

## Solution

Documented!

---

I tried linking to `bevy_pbr::PbrProjectionPlugin` from
`bevy_render:📷:CameraProjection` but it wasn't in scope. Is there
a trick to it?
2024-05-05 15:14:00 +00:00
JMS55
77ebabc4fe
Meshlet remove per-cluster data upload (#13125)
# Objective

- Per-cluster (instance of a meshlet) data upload is ridiculously
expensive in both CPU and GPU time (8 bytes per cluster, millions of
clusters, you very quickly run into PCIE bandwidth maximums, and lots of
CPU-side copies and malloc).
- We need to be uploading only per-instance/entity data. Anything else
needs to be done on the GPU.

## Solution

- Per instance, upload:
- `meshlet_instance_meshlet_counts_prefix_sum` - An exclusive prefix sum
over the count of how many clusters each instance has.
- `meshlet_instance_meshlet_slice_starts` - The starting index of the
meshlets for each instance within the `meshlets` buffer.
- A new `fill_cluster_buffers` pass once at the start of the frame has a
thread per cluster, and finds its instance ID and meshlet ID via a
binary search of `meshlet_instance_meshlet_counts_prefix_sum` to find
what instance it belongs to, and then uses that plus
`meshlet_instance_meshlet_slice_starts` to find what number meshlet
within the instance it is. The shader then writes out the per-cluster
instance/meshlet ID buffers for later passes to quickly read from.
- I've gone from 45 -> 180 FPS in my stress test scene, and saved
~30ms/frame of overall CPU/GPU time.
2024-05-04 19:56:19 +00:00
stinkytoe
ec418aa429
Re-export IntoDynamicImageError as public (#13223)
# Objective

in response to [13222](https://github.com/bevyengine/bevy/issues/13222)

## Solution

The Image trait was already re-exported in bevy_render/src/lib.rs, So I
added it inline there.

## Testing

Confirmed that it does compile. Simple change, shouldn't cause any
bugs/regressions.
2024-05-04 13:13:49 +00:00
arcashka
6027890a11
move wgsl color operations from bevy_pbr to bevy_render (#13209)
# Objective

`bevy_pbr/utils.wgsl` shader file contains mathematical constants and
color conversion functions. Both of those should be accessible without
enabling `bevy_pbr` feature. For example, tonemapping can be done in non
pbr scenario, and it uses color conversion functions.

Fixes #13207

## Solution

* Move mathematical constants (such as PI, E) from
`bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl`
* Move color conversion functions from `bevy_pbr/src/render/utils.wgsl`
into new file `bevy_render/src/color_operations.wgsl`

## Testing
Ran multiple examples, checked they are working:
* tonemapping
* color_grading
* 3d_scene
* animated_material
* deferred_rendering
* 3d_shapes
* fog
* irradiance_volumes
* meshlet
* parallax_mapping
* pbr
* reflection_probes
* shadow_biases
* 2d_gizmos
* light_gizmos
---

## Changelog
* Moved mathematical constants (such as PI, E) from
`bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl`
* Moved color conversion functions from `bevy_pbr/src/render/utils.wgsl`
into new file `bevy_render/src/color_operations.wgsl`

## Migration Guide
In user's shader code replace usage of mathematical constants from
`bevy_pbr::utils` to the usage of the same constants from
`bevy_render::maths`.
2024-05-04 10:30:23 +00:00
Bram Buurlage
d390420093
Implement Auto Exposure plugin (#12792)
# Objective

- Add auto exposure/eye adaptation to the bevy render pipeline.
- Support features that users might expect from other engines:
  - Metering masks
  - Compensation curves
  - Smooth exposure transitions 

This PR is based on an implementation I already built for a personal
project before https://github.com/bevyengine/bevy/pull/8809 was
submitted, so I wasn't able to adopt that PR in the proper way. I've
still drawn inspiration from it, so @fintelia should be credited as
well.

## Solution

An auto exposure compute shader builds a 64 bin histogram of the scene's
luminance, and then adjusts the exposure based on that histogram. Using
a histogram allows the system to ignore outliers like shadows and
specular highlights, and it allows to give more weight to certain areas
based on a mask.

---

## Changelog

- Added: AutoExposure plugin that allows to adjust a camera's exposure
based on it's scene's luminance.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-03 17:45:17 +00:00
BD103
bdb4899978
Move compile fail tests (#13196)
# Objective

- Follow-up of #13184 :)
- We use `ui_test` to test compiler errors for our custom macros.
- There are four crates related to compile fail tests
- `bevy_ecs_compile_fail_tests`, `bevy_macros_compile_fail_tests`, and
`bevy_reflect_compile_fail_tests`, which actually test the macros.
-
[`bevy_compile_test_utils`](64c1c65783/crates/bevy_compile_test_utils),
which provides helpers and common patterns for these tests.
- All of these crates reside within the `crates` directory.
- This can be confusing, especially for newcomers. All of the other
folders in `crates` are actual published libraries, except for these 4.

## Solution

- Move all compile fail tests to a `compile_fail` folder under their
corresponding crate.
- E.g. `crates/bevy_ecs_compile_fail_tests` would be moved to
`crates/bevy_ecs/compile_fail`.
- Move `bevy_compile_test_utils` to `tools/compile_fail_utils`.

There are a few benefits to this approach:

1. An internal testing detail is less intrusive (and confusing) for
those who just want to browse the public Bevy interface.
2. Follows a pre-existing approach of organizing related crates inside a
larger crate's folder.
   - See `bevy_gizmos/macros` for an example.
4. Makes consistent the terms `compile_test`, `compile_fail`, and
`compile_fail_test` in code. It's all just `compile_fail` now, because
we are specifically testing the error messages on compiler failures.
- To be clear it can still be referred to by these terms in comments and
speech, just the names of the crates and the CI command are now
consistent.

## Testing

Run the compile fail CI command:

```shell
cargo run -p ci -- compile-fail
```

If it still passes, then my refactor was successful.
2024-05-03 13:35:21 +00:00
Ycy
9d8f94d461
fix bevy_gltf crate build (#13202)
# Objective

Fixing `bevy_gltf` crate build fail when `bevy_animation` feature is
disabled

## Solution

Add missing `bevy_animation` feature
2024-05-03 13:00:18 +00:00
Lee-Orr
b9455afd0c
Schedule resource mutation (#13193)
# Objective

Resolves #13185 

## Solution

Move the following methods from `sub_app` to the `Schedules` resource,
and use them in the sub app:

- `add_systems`
- `configure_sets`
- `ignore_ambiguity`

Add an `entry(&mut self, label: impl ScheduleLabel) -> &mut Schedule`
method to the `Schedules` resource, which returns a mutable reference to
the schedule associated with the label, and creates one if it doesn't
already exist. (build on top of the `entry(..).or_insert_with(...)`
pattern in `HashMap`.

## Testing

- Did you test these changes? If so, how? Added 4 unit tests to the
`schedule.rs` - one that validates adding a system to an existing
schedule, one that validates adding a system to a new one, one that
validates configuring sets on an existing schedule, and one that
validates configuring sets on a new schedule.
- I didn't add tests for `entry` since the previous 4 tests use
functions that rely on it.
- I didn't test `ignore_ambiguity` since I didn't see examples of it's
use, and am not familiar enough with it to know how to set up a good
test for it. However, it relies on the `entry` method as well, so it
should work just like the other 2 methods.
2024-05-03 12:40:32 +00:00
Kristoffer Søholm
2089a28717
Add BufferVec, an higher-performance alternative to StorageBuffer, and make GpuArrayBuffer use it. (#13199)
This is an adoption of #12670 plus some documentation fixes. See that PR
for more details.

---

## Changelog

* Renamed `BufferVec` to `RawBufferVec` and added a new `BufferVec`
type.

## Migration Guide
`BufferVec` has been renamed to `RawBufferVec` and a new similar type
has taken the `BufferVec` name.

---------

Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2024-05-03 11:39:21 +00:00
Brezak
15687b5062
Simplify winit runner exit code reporting (#13151)
# Objective

~Returning a app exit code from the winit runner is complicated and
deadlock prone.~
The code to return a app exit code is rather shoddy. It's use of mutex
is redundant, It uses unwrap when not required and can be broken by a
maintainer simply forgetting to set a value.

## Solution

Switch to using a channel.
- Deals with situations in which a event loop exits unexpectedly.
- Never panics. Even in extreme cases.
2024-05-03 00:17:39 +00:00
Patrick Walton
31835ff76d
Implement visibility ranges, also known as hierarchical levels of detail (HLODs). (#12916)
Implement visibility ranges, also known as hierarchical levels of detail
(HLODs).

This commit introduces a new component, `VisibilityRange`, which allows
developers to specify camera distances in which meshes are to be shown
and hidden. Hiding meshes happens early in the rendering pipeline, so
this feature can be used for level of detail optimization. Additionally,
this feature is properly evaluated per-view, so different views can show
different levels of detail.

This feature differs from proper mesh LODs, which can be implemented
later. Engines generally implement true mesh LODs later in the pipeline;
they're typically more efficient than HLODs with GPU-driven rendering.
However, mesh LODs are more limited than HLODs, because they require the
lower levels of detail to be meshes with the same vertex layout and
shader (and perhaps the same material) as the original mesh. Games often
want to use objects other than meshes to replace distant models, such as
*octahedral imposters* or *billboard imposters*.

The reason why the feature is called *hierarchical level of detail* is
that HLODs can replace multiple meshes with a single mesh when the
camera is far away. This can be useful for reducing drawcall count. Note
that `VisibilityRange` doesn't automatically propagate down to children;
it must be placed on every mesh.

Crossfading between different levels of detail is supported, using the
standard 4x4 ordered dithering pattern from [1]. The shader code to
compute the dithering patterns should be well-optimized. The dithering
code is only active when visibility ranges are in use for the mesh in
question, so that we don't lose early Z.

Cascaded shadow maps show the HLOD level of the view they're associated
with. Point light and spot light shadow maps, which have no CSMs,
display all HLOD levels that are visible in any view. To support this
efficiently and avoid doing visibility checks multiple times, we
precalculate all visible HLOD levels for each entity with a
`VisibilityRange` during the `check_visibility_range` system.

A new example, `visibility_range`, has been added to the tree, as well
as a new low-poly version of the flight helmet model to go with it. It
demonstrates use of the visibility range feature to provide levels of
detail.

[1]: https://en.wikipedia.org/wiki/Ordered_dithering#Threshold_map

[^1]: Unreal doesn't have a feature that exactly corresponds to
visibility ranges, but Unreal's HLOD system serves roughly the same
purpose.

## Changelog

### Added

* A new `VisibilityRange` component is available to conditionally enable
entity visibility at camera distances, with optional crossfade support.
This can be used to implement different levels of detail (LODs).

## Screenshots

High-poly model:
![Screenshot 2024-04-09
185541](https://github.com/bevyengine/bevy/assets/157897/7e8be017-7187-4471-8866-974e2d8f2623)

Low-poly model up close:
![Screenshot 2024-04-09
185546](https://github.com/bevyengine/bevy/assets/157897/429603fe-6bb7-4246-8b4e-b4888fd1d3a0)

Crossfading between the two:
![Screenshot 2024-04-09
185604](https://github.com/bevyengine/bevy/assets/157897/86d0d543-f8f3-49ec-8fe5-caa4d0784fd4)

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-05-03 00:11:35 +00:00
François Mockers
fd4589d8df
new format for ci config file (#13154)
# Objective

- Current config file is hard to extend

## Solution

- Instead of an hard coded list of field, the file now has a list of
`(frame, event)`, and will deal with know events (exiting or taking a
screenshot), or send an event for others that can be dealt by third
party plugins
2024-05-02 22:51:47 +00:00
mgi388
78bf48b874
Use BindGroupLayoutEntryBuilder in texture_binding_array example (#13169)
# Objective

- I've been using the `texture_binding_array` example as a base to use
multiple textures in meshes in my program
- I only realised once I was deep in render code that these helpers
existed to create layouts
- I wish I knew the existed earlier because the alternative (filling in
every struct field) is so much more verbose

## Solution

- Use `BindGroupLayoutEntries::with_indices` to teach users that the
helper exists
- Also fix typo which should be `texture_2d`.

## Alternatives considered

- Just leave it as is to teach users about every single struct field
- However, leaving as is leaves users writing roughly 29 lines versus
roughly 2 lines for 2 entries and I'd prefer the 2 line approach

## Testing

Ran the example locally and compared before and after.

Before: 

<img width="1280" alt="image"
src="https://github.com/bevyengine/bevy/assets/135186256/f5897210-2560-4110-b92b-85497be9023c">

After:

<img width="1279" alt="image"
src="https://github.com/bevyengine/bevy/assets/135186256/8d13a939-b1ce-4a49-a9da-0b1779c8cb6a">

Co-authored-by: mgi388 <>
2024-05-02 20:10:32 +00:00
Pietro
5ee1b40298
fix: rewrite winit loop (#12669)
# Objective

- Simplifies/clarifies the winit loop.
- Fixes #12612.

## Solution

The Winit loop runs following this flow:
* NewEvents
* Any number of other events, that can be 0, including RequestRedraw
* AboutToWait

Bevy also uses the UpdateMode, to define how the next loop has to run.
It can be essentially:
* Continuous, using ControlFlow::Wait for windowed apps, and
ControlFlow::Poll for windowless apps
* Reactive/ReactiveLowPower, using ControlFlow::WaitUntil with a
specific wait delay

The changes are made to follow this pattern, so that 
* NewEvents define if the WaitUntil has been canceled because we
received a Winit event.
* AboutToWait:
  * checks if the window has to be redrawn
  * otherwise calls app.update() if the WaitUntil timeout has elapsed
  * updates the ControlFlow accordingly

To make the code more logical:
* AboutToWait checks if any Bevy's RequestRedraw event has been emitted
* create_windows is run every cycle, at the beginning of the loop
* the ActiveState (that could be renamed ActivityState) is updated in
AboutToWait, symmetrically for WillSuspend/WillResume
* the AppExit events are checked every loop cycle, to exit the app early

## Platform-specific testing

- [x] Windows
- [x] MacOs
- [x] Linux (x11)
- [x] Linux (Wayland)
- [x] Android
- [x] iOS
- [x] WASM/WebGL2 (Chrome)
- [x] WASM/WebGL2 (Firefox)
- [x] WASM/WebGL2 (Safari)
- [x] WASM/WebGpu (Chrome)

---------

Co-authored-by: François <francois.mockers@vleue.com>
2024-05-02 19:57:19 +00:00
Lee-Orr
b8832dc862
Computed State & Sub States (#11426)
## Summary/Description
This PR extends states to allow support for a wider variety of state
types and patterns, by providing 3 distinct types of state:
- Standard [`States`] can only be changed by manually setting the
[`NextState<S>`] resource. These states are the baseline on which the
other state types are built, and can be used on their own for many
simple patterns. See the [state
example](https://github.com/bevyengine/bevy/blob/latest/examples/ecs/state.rs)
for a simple use case - these are the states that existed so far in
Bevy.
- [`SubStates`] are children of other states - they can be changed
manually using [`NextState<S>`], but are removed from the [`World`] if
the source states aren't in the right state. See the [sub_states
example](https://github.com/lee-orr/bevy/blob/derived_state/examples/ecs/sub_states.rs)
for a simple use case based on the derive macro, or read the trait docs
for more complex scenarios.
- [`ComputedStates`] are fully derived from other states - they provide
a [`compute`](ComputedStates::compute) method that takes in the source
states and returns their derived value. They are particularly useful for
situations where a simplified view of the source states is necessary -
such as having an `InAMenu` computed state derived from a source state
that defines multiple distinct menus. See the [computed state
example](https://github.com/lee-orr/bevy/blob/derived_state/examples/ecs/computed_states.rscomputed_states.rs)
to see a sampling of uses for these states.

# Objective

This PR is another attempt at allowing Bevy to better handle complex
state objects in a manner that doesn't rely on strict equality. While my
previous attempts (https://github.com/bevyengine/bevy/pull/10088 and
https://github.com/bevyengine/bevy/pull/9957) relied on complex matching
capacities at the point of adding a system to application, this one
instead relies on deterministically deriving simple states from more
complex ones.

As a result, it does not require any special macros, nor does it change
any other interactions with the state system once you define and add
your derived state. It also maintains a degree of distinction between
`State` and just normal application state - your derivations have to end
up being discreet pre-determined values, meaning there is less of a
risk/temptation to place a significant amount of logic and data within a
given state.

### Addition - Sub States
closes #9942 
After some conversation with Maintainers & SMEs, a significant concern
was that people might attempt to use this feature as if it were
sub-states, and find themselves unable to use it appropriately. Since
`ComputedState` is mainly a state matching feature, while `SubStates`
are more of a state mutation related feature - but one that is easy to
add with the help of the machinery introduced by `ComputedState`, it was
added here as well. The relevant discussion is here:
https://discord.com/channels/691052431525675048/1200556329803186316

## Solution
closes #11358 

The solution is to create a new type of state - one implementing
`ComputedStates` - which is deterministically tied to one or more other
states. Implementors write a function to transform the source states
into the computed state, and it gets triggered whenever one of the
source states changes.

In addition, we added the `FreelyMutableState` trait , which is
implemented as part of the derive macro for `States`. This allows us to
limit use of `NextState<S>` to states that are actually mutable,
preventing mis-use of `ComputedStates`.

---

## Changelog

- Added `ComputedStates` trait
- Added `FreelyMutableState` trait
- Converted `NextState` resource to an Enum, with `Unchanged` and
`Pending`
- Added `App::add_computed_state::<S: ComputedStates>()`, to allow for
easily adding derived states to an App.
- Moved the `StateTransition` schedule label from `bevy_app` to
`bevy_ecs` - but maintained the export in `bevy_app` for continuity.
- Modified the process for updating states. Instead of just having an
`apply_state_transition` system that can be added anywhere, we now have
a multi-stage process that has to run within the `StateTransition`
label. First, all the state changes are calculated - manual transitions
rely on `apply_state_transition`, while computed transitions run their
computation process before both call `internal_apply_state_transition`
to apply the transition, send out the transition event, trigger
dependent states, and record which exit/transition/enter schedules need
to occur. Once all the states have been updated, the transition
schedules are called - first the exit schedules, then transition
schedules and finally enter schedules.
- Added `SubStates` trait
- Adjusted `apply_state_transition` to be a no-op if the `State<S>`
resource doesn't exist

## Migration Guide

If the user accessed the NextState resource's value directly or created
them from scratch they will need to adjust to use the new enum variants:
- if they created a `NextState(Some(S))` - they should now use
`NextState::Pending(S)`
- if they created a `NextState(None)` -they should now use
`NextState::Unchanged`
- if they matched on the `NextState` value, they would need to make the
adjustments above

If the user manually utilized `apply_state_transition`, they should
instead use systems that trigger the `StateTransition` schedule.

---
## Future Work
There is still some future potential work in the area, but I wanted to
keep these potential features and changes separate to keep the scope
here contained, and keep the core of it easy to understand and use.
However, I do want to note some of these things, both as inspiration to
others and an illustration of what this PR could unlock.

- `NextState::Remove` - Now that the `State` related mechanisms all
utilize options (#11417), it's fairly easy to add support for explicit
state removal. And while `ComputedStates` can add and remove themselves,
right now `FreelyMutableState`s can't be removed from within the state
system. While it existed originally in this PR, it is a different
question with a separate scope and usability concerns - so having it as
it's own future PR seems like the best approach. This feature currently
lives in a separate branch in my fork, and the differences between it
and this PR can be seen here: https://github.com/lee-orr/bevy/pull/5

- `NextState::ReEnter` - this would allow you to trigger exit & entry
systems for the current state type. We can potentially also add a
`NextState::ReEnterRecirsive` to also re-trigger any states that depend
on the current one.

- More mechanisms for `State` updates - This PR would finally make
states that aren't a set of exclusive Enums useful, and with that comes
the question of setting state more effectively. Right now, to update a
state you either need to fully create the new state, or include the
`Res<Option<State<S>>>` resource in your system, clone the state, mutate
it, and then use `NextState.set(my_mutated_state)` to make it the
pending next state. There are a few other potential methods that could
be implemented in future PRs:
- Inverse Compute States - these would essentially be compute states
that have an additional (manually defined) function that can be used to
nudge the source states so that they result in the computed states
having a given value. For example, you could use set the `IsPaused`
state, and it would attempt to pause or unpause the game by modifying
the `AppState` as needed.
- Closure-based state modification - this would involve adding a
`NextState.modify(f: impl Fn(Option<S> -> Option<S>)` method, and then
you can pass in closures or function pointers to adjust the state as
needed.
- Message-based state modification - this would involve either creating
states that can respond to specific messages, similar to Elm or Redux.
These could either use the `NextState` mechanism or the Event mechanism.

- ~`SubStates` - which are essentially a hybrid of computed and manual
states. In the simplest (and most likely) version, they would work by
having a computed element that determines whether the state should
exist, and if it should has the capacity to add a new version in, but
then any changes to it's content would be freely mutated.~ this feature
is now part of this PR. See above.

- Lastly, since states are getting more complex there might be value in
moving them out of `bevy_ecs` and into their own crate, or at least out
of the `schedule` module into a `states` module. #11087

As mentioned, all these future work elements are TBD and are explicitly
not part of this PR - I just wanted to provide them as potential
explorations for the future.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Marcel Champagne <voiceofmarcel@gmail.com>
Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
2024-05-02 19:36:23 +00:00
BD103
e357b63448
Add README.md to all crates (#13184)
# Objective

- `README.md` is a common file that usually gives an overview of the
folder it is in.
- When on <https://crates.io>, `README.md` is rendered as the main
description.
- Many crates in this repository are lacking `README.md` files, which
makes it more difficult to understand their purpose.

<img width="1552" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/78ebf91d-b0c4-4b18-9874-365d6310640f">

- There are also a few inconsistencies with `README.md` files that this
PR and its follow-ups intend to fix.

## Solution

- Create a `README.md` file for all crates that do not have one.
- This file only contains the title of the crate (underscores removed,
proper capitalization, acronyms expanded) and the <https://shields.io>
badges.
- Remove the `readme` field in `Cargo.toml` for `bevy` and
`bevy_reflect`.
- This field is redundant because [Cargo automatically detects
`README.md`
files](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field).
The field is only there if you name it something else, like `INFO.md`.
- Fix capitalization of `bevy_utils`'s `README.md`.
- It was originally `Readme.md`, which is inconsistent with the rest of
the project.
- I created two commits renaming it to `README.md`, because Git appears
to be case-insensitive.
- Expand acronyms in title of `bevy_ptr` and `bevy_utils`.
- In the commit where I created all the new `README.md` files, I
preferred using expanded acronyms in the titles. (E.g. "Bevy Developer
Tools" instead of "Bevy Dev Tools".)
- This commit changes the title of existing `README.md` files to follow
the same scheme.
- I do not feel strongly about this change, please comment if you
disagree and I can revert it.
- Add <https://shields.io> badges to `bevy_time` and `bevy_transform`,
which are the only crates currently lacking them.

---

## Changelog

- Added `README.md` files to all crates missing it.
2024-05-02 18:56:00 +00:00
Martín Maita
32cd0c5dc1
Update glam version requirement from 0.25 to 0.27 (#12757)
# Objective

- Update glam version requirement to latest version.

## Solution

- Updated `glam` version requirement from 0.25 to 0.27.
- Updated `encase` and `encase_derive_impl` version requirement from 0.7
to 0.8.
- Updated `hexasphere` version requirement from 10.0 to 12.0.
- Breaking changes from glam changelog:
- [0.26.0] Minimum Supported Rust Version bumped to 1.68.2 for impl
From<bool> for {f32,f64} support.
- [0.27.0] Changed implementation of vector fract method to match the
Rust implementation instead of the GLSL implementation, that is self -
self.trunc() instead of self - self.floor().

---

## Migration Guide

- When using `glam` exports, keep in mind that `vector` `fract()` method
now matches Rust implementation (that is `self - self.trunc()` instead
of `self - self.floor()`). If you want to use the GLSL implementation
you should now use `fract_gl()`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-02 18:42:34 +00:00
Charles Bournhonesque
fab83471b5
add schedule docs (#13174)
# Objective

I'm reading through the schedule code, which is somewhat lacking
documentation.
I've been adding some docstrings to help me understand the code; I feel
like some of them could be useful to also help others read this code.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-02 18:31:32 +00:00
Marcel Müller
6d25545c51
Implement Reflect for Result<T, E> as enum (#13182)
# Objective

- Make `Result<T, E>` implement Reflect such that it is an Enum rather
than a Value
- Fixes #13178

## Solution

- Use the correct macro

## Testing

- Did you test these changes? 

I tried it out locally, and it does what it says on the tin. Not sure
how to test it in context of the crate?


---

## Changelog

### Changed

- Result now uses `ReflectKind::Enum` rather than `ReflectKind::Value`,
allowing for inspection of its constituents

## Migration Guide

`Result<T, E>` has had its `Reflect` implementation changed to align it
with `Option<T>` and its intended semantics: A carrier of either an `Ok`
or `Err` value, and the ability to access it. To achieve this it is no
longer a `ReflectKind::Value` but rather a `ReflectKind::Enum` and as
such carries these changes with it:

For `Result<T, E>`
- Both `T` and `E` no longer require to be `Clone` and now require to be
`FromReflect`
- `<Result<T, E> as Reflect>::reflect_*` now returns a
`ReflectKind::Enum`, so any code that previously relied on it being a
`Value` kind will have to be adapted.
- `Result<T, E>` now implements `Enum`

Since the migration is highly dependent on the previous usage, no
automatic upgrade path can be given.

Signed-off-by: Marcel Müller <neikos@neikos.email>
2024-05-02 18:28:24 +00:00
Patrick Walton
961b24deaf
Implement filmic color grading. (#13121)
This commit expands Bevy's existing tonemapping feature to a complete
set of filmic color grading tools, matching those of engines like Unity,
Unreal, and Godot. The following features are supported:

* White point adjustment. This is inspired by Unity's implementation of
the feature, but simplified and optimized. *Temperature* and *tint*
control the adjustments to the *x* and *y* chromaticity values of [CIE
1931]. Following Unity, the adjustments are made relative to the [D65
standard illuminant] in the [LMS color space].

* Hue rotation. This simply converts the RGB value to [HSV], alters the
hue, and converts back.

* Color correction. This allows the *gamma*, *gain*, and *lift* values
to be adjusted according to the standard [ASC CDL combined function].

* Separate color correction for shadows, midtones, and highlights.
Blender's source code was used as a reference for the implementation of
this. The midtone ranges can be adjusted by the user. To avoid abrupt
color changes, a small crossfade is used between the different sections
of the image, again following Blender's formulas.

A new example, `color_grading`, has been added, offering a GUI to change
all the color grading settings. It uses the same test scene as the
existing `tonemapping` example, which has been factored out into a
shared glTF scene.

[CIE 1931]: https://en.wikipedia.org/wiki/CIE_1931_color_space

[D65 standard illuminant]:
https://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D

[LMS color space]: https://en.wikipedia.org/wiki/LMS_color_space

[HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV

[ASC CDL combined function]:
https://en.wikipedia.org/wiki/ASC_CDL#Combined_Function

## Changelog

### Added

* Many new filmic color grading options have been added to the
`ColorGrading` component.

## Migration Guide

* `ColorGrading::gamma` and `ColorGrading::pre_saturation` are now set
separately for the `shadows`, `midtones`, and `highlights` sections. You
can migrate code with the `ColorGrading::all_sections` and
`ColorGrading::all_sections_mut` functions, which access and/or update
all sections at once.
* `ColorGrading::post_saturation` and `ColorGrading::exposure` are now
fields of `ColorGrading::global`.

## Screenshots

![Screenshot 2024-04-27
143144](https://github.com/bevyengine/bevy/assets/157897/c1de5894-917d-4101-b5c9-e644d141a941)

![Screenshot 2024-04-27
143216](https://github.com/bevyengine/bevy/assets/157897/da393c8a-d747-42f5-b47c-6465044c788d)
2024-05-02 12:18:59 +00:00
Alice Cecile
b3ed0dd002
Add Reflect derive to Events and contained types (#13149)
# Objective

The `Events` containerr should be reflectable, in order to make dev
tools that examine its state more useful.

Fixes #13148.

## Solution

- Add a `Reflect` derive to `Events`, gated behind the `bevy_reflect`
feature
- Add `Reflect` to the contained types to make everything compile.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-01 18:47:11 +00:00
Nico Burns
96b9d0a7e2
Upgrade to Taffy 0.4 (#10690)
# Objective

- Enables support for `Display::Block`
- Enables support for `Overflow::Hidden`
- Allows for cleaner integration with text, image and other content
layout.
- Unblocks https://github.com/bevyengine/bevy/pull/8104
- Unlocks the possibility of Bevy creating a custom layout tree over
which Taffy operates.
- Enables #8808 / #10193 to remove a Mutex around the font system.

## Todo

- [x] ~Fix rendering of text/images to account for padding/border on
nodes (should size/position to content box rather than border box)~ In
order get this into a mergeable state this PR instead zeroes out
padding/border when syncing leaf node styles into Taffy to preserve the
existing behaviour. https://github.com/bevyengine/bevy/issues/6879 can
be fixed in a followup PR.

## Solution

- Update the version of Taffy
- Update code to work with the new version

Note: Taffy 0.4 has not yet been released. This PR is being created in
advance of the release to ensure that there are no blockers to upgrading
once the release occurs.

---

## Changelog

- Bevy now supports the `Display::Block` and `Overflow::Hidden` styles.
2024-04-30 14:13:17 +00:00
Friz64
9973f0c8a3
Introduce a WindowWrapper to extend the lifetime of the window when using pipelined rendering (#12978)
# Objective

A `RawWindowHandle` is only valid as long as the window it was retrieved
from is alive. Extend the lifetime of the window, so that the
`RawWindowHandle` doesn't outlive it, and bevy doesn't crash when
closing a window a pipelined renderer is drawing to.

- Fix #11236
- Fix #11150
- Fix #11734
- Alternative to / Closes #12524

## Solution

Introduce a `WindowWrapper` that takes ownership of the window. Require
it to be used when constructing a `RawHandleWrapper`. This forces
windowing backends to store their window in this wrapper.

The `WindowWrapper` is implemented by storing the window in an `Arc<dyn
Any + Send + Sync>`.

We use dynamic dispatch here because we later want the
`RawHandleWrapper` to be able dynamically hold a reference to any
windowing backend's window.

But alas, the `WindowWrapper` itself is still practically invisible to
windowing backends, because it implements `Deref` to the underlying
window, by storing its type in a `PhantomData`.

---

## Changelog

### Added

- Added `WindowWrapper`, which windowing backends are now required to
use to store their underlying window.

### Fixed

- Fixed a safety problem which caused crashes when closing bevy windows
when using pipelined rendering.

## Migration Guide

- Windowing backends now need to store their window in the new
`WindowWrapper`.
2024-04-30 14:13:07 +00:00
Patrick Walton
f1db525f14
Don't ignore unbatchable sorted items. (#13144)
In #12889, I mistakenly started dropping unbatchable sorted items on the
floor instead of giving them solitary batches. This caused the objects
in the `shader_instancing` demo to stop showing up. This patch fixes the
issue by giving those items their own batches as expected.

Fixes #13130.
2024-04-30 07:02:59 +00:00
Antony
7b4b5966d9
Deprecate ReceivedCharacter (#12868)
# Objective

- Partially resolves #12639.

## Solution

- Deprecate `ReceivedCharacter`.
- Replace `ReceivedCharacter` with `KeyboardInput` in the relevant
examples.

## Migration Guide

- `ReceivedCharacter` is now deprecated, use `KeyboardInput` instead.

- Before:
  ```rust
  fn listen_characters(events: EventReader<ReceivedCharacter>) {
    for event in events.read() {
      info!("{}", event.char);
    }
  }
  ```
  
  After:
  ```rust
  fn listen_characters(events: EventReader<KeyboardInput>) {
    for event in events.read() {
      // Only check for characters when the key is pressed.
      if event.state == ButtonState::Released {
        continue;
      }
// Note that some keys such as `Space` and `Tab` won't be detected as
before.
      // Instead, check for them with `Key::Space` and `Key::Tab`.
      if let Key::Character(character) = &event.logical_key {
        info!("{}", character);
      }
    }
  }
  ```

---------

Co-authored-by: Mike <mike.hsu@gmail.com>
2024-04-30 00:49:41 +00:00
Giacomo Stevanato
d9b69731de
Make from_reflect_or_world also try ReflectDefault and improve some comments and panic messages (#12499)
# Objective

- `from_reflect_or_world` is an internal utilty used in the
implementations of `ReflectComponent` and `ReflectBundle` to create a
`T` given a `&dyn Reflect` by trying to use `FromReflect`, and if that
fails it falls back to `ReflectFromWorld`
- reflecting `FromWorld` is not intuitive though: often it is implicitly
implemented by deriving `Default` so people might not even be aware of
it.
- the panic messages mentioning `ReflectFromWorld` are not directly
correlated to what the user would have to do (reflect `FromWorld`)

## Solution

- Also check for `ReflectDefault` in addition to `ReflectFromWorld`.
- Change the panic messages to mention the reflected trait rather than
the `Reflect*` types.

---

## Changelog

- `ReflectComponent` and `ReflectBundle` no longer require `T:
FromReflect` but instead only `T: Reflect`.
- `ReflectComponent` and `ReflectBundle` will also work with types that
only reflected `Default` and not `FromWorld`.

## Migration Guide

- `ReflectBundle::insert` now requires an additional `&TypeRegistry`
parameter.
2024-04-30 00:48:46 +00:00
miro
6c57a16b5e
Fix typo in bevy_render/src/batching/gpu_preprocessing.rs (#13141)
# Objective
   Fix typo in `bevy_render/src/batching/gpu_preprocessing.rs`
   https://github.com/bevyengine/bevy/issues/13135
2024-04-29 20:30:15 +00:00
Charles Bournhonesque
f73950767b
Update App:is_plugin_added to work inside Plugin::finish and Plugin::clean (#12761)
# Objective

I have been trying to check for the existing of some plugins via
`App::is_plugin_added` to conditionally run some behaviour in the
`Plugin::finish` part of my plugin, before realizing that the plugin
registry is actually not available during this step.
This is because the `App::is_plugin_added` using the plugin registry to
check for previous registration.

## Solution

- Switch the `App::is_plugin_added` to use the list of plugin names to
check for previous registrations
- Add a unit test showcasing that `App::is_plugin_added` works during
`Plugin::finish`
2024-04-28 21:32:16 +00:00
Patrick Walton
16531fb3e3
Implement GPU frustum culling. (#12889)
This commit implements opt-in GPU frustum culling, built on top of the
infrastructure in https://github.com/bevyengine/bevy/pull/12773. To
enable it on a camera, add the `GpuCulling` component to it. To
additionally disable CPU frustum culling, add the `NoCpuCulling`
component. Note that adding `GpuCulling` without `NoCpuCulling`
*currently* does nothing useful. The reason why `GpuCulling` doesn't
automatically imply `NoCpuCulling` is that I intend to follow this patch
up with GPU two-phase occlusion culling, and CPU frustum culling plus
GPU occlusion culling seems like a very commonly-desired mode.

Adding the `GpuCulling` component to a view puts that view into
*indirect mode*. This mode makes all drawcalls indirect, relying on the
mesh preprocessing shader to allocate instances dynamically. In indirect
mode, the `PreprocessWorkItem` `output_index` points not to a
`MeshUniform` instance slot but instead to a set of `wgpu`
`IndirectParameters`, from which it allocates an instance slot
dynamically if frustum culling succeeds. Batch building has been updated
to allocate and track indirect parameter slots, and the AABBs are now
supplied to the GPU as `MeshCullingData`.

A small amount of code relating to the frustum culling has been borrowed
from meshlets and moved into `maths.wgsl`. Note that standard Bevy
frustum culling uses AABBs, while meshlets use bounding spheres; this
means that not as much code can be shared as one might think.

This patch doesn't provide any way to perform GPU culling on shadow
maps, to avoid making this patch bigger than it already is. That can be
a followup.

## Changelog

### Added

* Frustum culling can now optionally be done on the GPU. To enable it,
add the `GpuCulling` component to a camera.
* To disable CPU frustum culling, add `NoCpuCulling` to a camera. Note
that `GpuCulling` doesn't automatically imply `NoCpuCulling`.
2024-04-28 12:50:00 +00:00
BD103
45bb6253e2
Restore dragons to their seat of power (#13124)
# Objective

- There is an unfortunate lack of dragons in the meshlet docs.
- Dragons are symbolic of majesty, power, storms, and meshlets.
- A dragon habitat such as our docs requires cultivation to ensure each
winged lizard reaches their fullest, fiery selves.

## Solution

- Fix the link to the dragon image.
- The link originally targeted the `meshlet` branch, but that was later
deleted after it was merged into `main`.

---

## Changelog

- Added a dragon back into the `MeshletPlugin` documentation.
2024-04-28 07:20:16 +00:00
JMS55
e1a0da0fa6
Meshlet LOD-compatible two-pass occlusion culling (#12898)
Keeping track of explicit visibility per cluster between frames does not
work with LODs, and leads to worse culling (using the final depth buffer
from the previous frame is more accurate).

Instead, we need to generate a second depth pyramid after the second
raster pass, and then use that in the first culling pass in the next
frame to test if a cluster would have been visible last frame or not.

As part of these changes, the write_index_buffer pass has been folded
into the culling pass for a large performance gain, and to avoid
tracking a lot of extra state that would be needed between passes.

Prepass previous model/view stuff was adapted to work with meshlets as
well.

Also fixed a bug with materials, and other misc improvements.

---------

Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
2024-04-28 05:30:20 +00:00
Aevyrie
4b446c020e
Add error when extract resource build fails (#4964)
# Objective

- Provide feedback when an extraction plugin fails to add its system.

I had some troubleshooting pain when this happened to me, as the panic
only tells you a resource is missing. This PR adds an error when the
ExtractResource plugin is added before the render world exists, instead
of silently failing.


![image](https://user-images.githubusercontent.com/2632925/172491993-673d9351-215a-4f30-96f7-af239c44686a.png)
2024-04-28 05:20:59 +00:00
François Mockers
22d605c8df
asset throttling: don't be exhausted if there is no limit (#13112)
# Objective

- Since #12622 example `compute_shader_game_of_life` crashes
```
thread 'Compute Task Pool (2)' panicked at examples/shader/compute_shader_game_of_life.rs:137:65:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `compute_shader_game_of_life::prepare_bind_group`!
thread '<unnamed>' panicked at examples/shader/compute_shader_game_of_life.rs:254:34:
Requested resource compute_shader_game_of_life::GameOfLifeImageBindGroups does not exist in the `World`.
                Did you forget to add it using `app.insert_resource` / `app.init_resource`?
                Resources are also implicitly added via `app.add_event`,
                and can be added by plugins.
Encountered a panic in system `bevy_render::renderer::render_system`!
```

## Solution

- `exhausted()` now checks that there is a limit
2024-04-27 09:00:10 +00:00
Brezak
9d59e52bb0
Switch to ui_test in compile fail tests. (#12810)
# Objective

Make compile fail tests less likely to break with new Rust versions.
Closes #12627

## Solution

Switch from [`trybuild`](https://github.com/dtolnay/trybuild) to
[`ui_test`](https://github.com/oli-obk/ui_test).

## TODO

- [x] Update `bevy_ecs_compile_fail_tests`
- [x] Update `bevy_macros_compile_fail_tests`
- [x] Update `bevy_reflect_compile_fail_tests`

---------

Co-authored-by: Oli Scherer <github35764891676564198441@oli-obk.de>
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-04-27 00:00:57 +00:00
Doonv
de9dc9c204
Fix CameraProjection panic and improve CameraProjectionPlugin (#11808)
# Objective

Fix https://github.com/bevyengine/bevy/issues/11799 and improve
`CameraProjectionPlugin`

## Solution

`CameraProjectionPlugin` is now an all-in-one plugin for adding a custom
`CameraProjection`. I also added `PbrProjectionPlugin` which is like
`CameraProjectionPlugin` but for PBR.

P.S. I'd like to get this merged after
https://github.com/bevyengine/bevy/pull/11766.

---

## Changelog

- Changed `CameraProjectionPlugin` to be an all-in-one plugin for adding
a `CameraProjection`
- Removed `VisibilitySystems::{UpdateOrthographicFrusta,
UpdatePerspectiveFrusta, UpdateProjectionFrusta}`, now replaced with
`VisibilitySystems::UpdateFrusta`
- Added `PbrProjectionPlugin` for projection-specific PBR functionality.

## Migration Guide

`VisibilitySystems`'s `UpdateOrthographicFrusta`,
`UpdatePerspectiveFrusta`, and `UpdateProjectionFrusta` variants were
removed, they were replaced with `VisibilitySystems::UpdateFrusta`
2024-04-26 23:52:09 +00:00
François Mockers
75f1c5df7d
UI: pass the untransformed node size to the shader (#12839)
# Objective

- #12500 broke rotating ui nodes, see examples `pbr` (missing "metallic"
label) or `overflow_debug` (bottom right box is empty)

## Solution

- Pass the untransformed node size to the shader
2024-04-26 23:50:04 +00:00
re0312
92928f13ed
Cleanup extract_meshes (#13026)
# Objective

- clean up extract_mesh_(gpu/cpu)_building

## Solution

- gpu_building no need to hold  `prev_render_mesh_instances`
- using `insert_unique_unchecked` instead of simple insert as we know
all entities are unique
- direcly get `previous_input_index ` in par_loop 


## Performance
this should also bring a slight performance win.

cargo run --release --example many_cubes --features bevy/trace_tracy --
--no-frustum-culling
`extract_meshes_for_gpu_building`


![image](https://github.com/bevyengine/bevy/assets/45868716/a5425e8a-258b-482d-afda-170363ee6479)

---------

Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-26 23:49:32 +00:00
robtfm
91a393a9e2
Throttle render assets (#12622)
# Objective

allow throttling of gpu uploads to prevent choppy framerate when many
textures/meshes are loaded in.

## Solution

- `RenderAsset`s can implement `byte_len()` which reports their size.
implemented this for `Mesh` and `Image`
- users can add a `RenderAssetBytesPerFrame` which specifies max bytes
to attempt to upload in a frame
- `render_assets::<A>` checks how many bytes have been written before
attempting to upload assets. the limit is a soft cap: assets will be
written until the total has exceeded the cap, to ensure some forward
progress every frame

notes:
- this is a stopgap until we have multiple wgpu queues for proper
streaming of data
- requires #12606

issues
- ~~fonts sometimes only partially upload. i have no clue why, needs to
be fixed~~ fixed now.
- choosing the #bytes is tricky as it should be hardware / framerate
dependent
- many features are not tested (env maps, light probes, etc) - they
won't break unless `RenderAssetBytesPerFrame` is explicitly used though

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-26 23:43:33 +00:00
Franklin Blanco
9c38844fc8
Added vmin and vmax to the gridtrack impls, repeatedgridtrack impls (#13096)
# Objective

- Fixes #13094 

## Solution

- Added vmin() and vmax() to the `GridTrack` & `RepeatedGridTrack`
impls, repeatedgridtrack impls, and both to the variants of Min & Max
TrackSizingFunction

## Sidenote
This would be my first PR to bevy. Feel free to say anything.

Thanks to the Bevy Team for everything you've done!

---------

Co-authored-by: Franklin <franklinblanco@tutanota.com>
2024-04-26 18:30:15 +00:00
BD103
9ee02e87d3
Remove version field for non-publish crates and update descriptions (#13100)
# Objective

- The [`version`] field in `Cargo.toml` is optional for crates not
published on <https://crates.io>.
- We have several `publish = false` tools in this repository that still
have a version field, even when it's not useful.

[`version`]:
https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field

## Solution

- Remove the [`version`] field for all crates where `publish = false`.
- Update the description on a few crates and remove extra newlines as
well.
2024-04-26 11:55:03 +00:00
Mateusz Wachowiak
64b987921c
iter_with_data (#13102)
# Objective

- Provide a way to iterate over the registered TypeData.

## Solution

- a new method on the `TypeRegistry` that iterates over
`TypeRegistrations` with theirs `TypeData`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-04-26 02:09:34 +00:00
findmyhappy
36a3e53e10
chore: fix some comments (#13083)
# Objective

remove repetitive words

Signed-off-by: findmyhappy <findhappy@sohu.com>
2024-04-25 19:09:16 +00:00
NiseVoid
414abb4959
Use Vec3A for 3D bounding volumes and raycasts (#13087)
# Objective

- People have reported bounding volumes being slower than their existing
solution because it doesn't use SIMD aligned types.

## Solution

- Use `Vec3A` internally for bounding volumes, accepting `Into<Vec3A>`
wherever possible
- Change some code to make it more likely SIMD operations are used.

---

## Changelog

- Use `Vec3A` for 3D bounding volumes and raycasts

## Migration Guide

- 3D bounding volumes now use `Vec3A` types internally, return values
from methods on them now return `Vec3A` instead of `Vec3`
2024-04-25 18:56:58 +00:00
iiYese
5b899b48f5
Better SystemId to Entity conversions (#13090)
# Objective

- Better `SystemId` <-> `Entity` conversion.

## Solution

- Provide a method `SystemId::from_entity` to create a `SystemId<I, O>`
form an `Entity`. When users want to deal with the entities manually
they need a way to convert the `Entity` back to a `SystemId` to actually
run the system with `Commands` or `World`.
- Provide a method `SystemId::entity` that returns an `Entity` from
`SystemId`. The current `From` impl is not very discoverable as it does
not appear on the `SystemId` doc page.
- Remove old `From` impl.

## Migration Guide

```rust
let system_id = world.register_system(my_sys);

// old
let entity = Entity::from(system_id);

// new
let entity = system_id.entity();
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-04-25 18:47:49 +00:00
Aevyrie
ade70b3925
Per-Object Motion Blur (#9924)
https://github.com/bevyengine/bevy/assets/2632925/e046205e-3317-47c3-9959-fc94c529f7e0

# Objective

- Adds per-object motion blur to the core 3d pipeline. This is a common
effect used in games and other simulations.
- Partially resolves #4710

## Solution

- This is a post-process effect that uses the depth and motion vector
buffers to estimate per-object motion blur. The implementation is
combined from knowledge from multiple papers and articles. The approach
itself, and the shader are quite simple. Most of the effort was in
wiring up the bevy rendering plumbing, and properly specializing for HDR
and MSAA.
- To work with MSAA, the MULTISAMPLED_SHADING wgpu capability is
required. I've extracted this code from #9000. This is because the
prepass buffers are multisampled, and require accessing with
`textureLoad` as opposed to the widely compatible `textureSample`.
- Added an example to demonstrate the effect of motion blur parameters.

## Future Improvements

- While this approach does have limitations, it's one of the most
commonly used, and is much better than camera motion blur, which does
not consider object velocity. For example, this implementation allows a
dolly to track an object, and that object will remain unblurred while
the background is blurred. The biggest issue with this implementation is
that blur is constrained to the boundaries of objects which results in
hard edges. There are solutions to this by either dilating the object or
the motion vector buffer, or by taking a different approach such as
https://casual-effects.com/research/McGuire2012Blur/index.html
- I'm using a noise PRNG function to jitter samples. This could be
replaced with a blue noise texture lookup or similar, however after
playing with the parameters, it gives quite nice results with 4 samples,
and is significantly better than the artifacts generated when not
jittering.

---

## Changelog

- Added: per-object motion blur. This can be enabled and configured by
adding the `MotionBlurBundle` to a camera entity.

---------

Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
2024-04-25 01:16:02 +00:00
BD103
c8d214d505
Add #[track_caller] to Query methods (#12984)
# Objective

- Closes #12958

## Solution

- Find all methods under `Query` that mention panicking, and add
`#[track_caller]` to them.

---

## Changelog

- Added `#[track_caller]` to `Query::many`, `Query::many_mut`,
`Query::transmute_lens`, and `Query::transmute_lens_filtered`.

## For reviewers

I'm unfamiliar with the depths of the `Query` struct. Please check
whether it makes since for the updated methods to have
`#[track_caller]`, and if I missed any!
2024-04-24 04:51:18 +00:00
BD103
f1d1491126
Use ptr::from_ref and ptr::addr_eq in macro (#13081)
# Objective

- Clippy raises a few warnings on the latest nightly release. 📎

## Solution

- Use `ptr::from_ref` when possible, because it prevents you from
accidentally changing the mutability as well as its type.
- Use `ptr::addr_eq` when comparing two pointers, ignoring pointer
metadata.
2024-04-24 01:54:24 +00:00
Andrew
d59c859a35
new example: sprite animation in response to an event (#12996)
# Objective

- animating a sprite in response to an event is a [common beginner
problem](https://www.reddit.com/r/bevy/comments/13xx4v7/sprite_animation_in_bevy/)

## Solution

- provide a simple example to show how to animate a sprite in response
to an event

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-23 21:44:03 +00:00
JMS55
6d6810c90d
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.

Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.

Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".

References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html


![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)

![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)

---------

Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
JMS55
17633c1f75
Remove unused push constants (#13076)
The shader code was removed in #11280, but we never cleaned up the rust
code.
2024-04-23 21:43:46 +00:00
Brezak
30b0931c8a
Simplify runner app exit code. (#13074)
# Objective

Both the shedule and winit runners use/reimplement `app_exit_manual`
even tough they can use `app_exit`

## Solution

Nuke `app_exit_manual` from orbit.
2024-04-23 20:42:00 +00:00
Nicolas Zhao
83f1184ea3
Expose mutable Animation Clips (#13067)
# Objective

- Be able to edit animation inside the editor and save them once
modified. This will allow bevy to modify animation assets with code.
- Fixes #13052

## Solution

- Expose the previously const getters of the Animation curves

---
2024-04-23 14:58:08 +00:00
James Liu
ddc9599d5e
Remove async-task as a dependency (#13071)
# Objective
Follow up to #13062. As of async-executor 1.11, the crate reexports
FallibleTask, which is the only reason bevy_tasks has a direct
dependency on async-task. This should avoid the two dependencies getting
out of sync in the future and causing spurious compilation failures.

## Solution
Bump async-executor to 1.11, use the reexport, remove the dependency on
async-task.
2024-04-23 14:57:55 +00:00
re0312
0f27500e46
Improve par_iter and Parallel (#12904)
# Objective

- bevy usually use `Parallel::scope` to collect items from `par_iter`,
but `scope` will be called with every satifified items. it will cause a
lot of unnecessary lookup.

## Solution

- similar to Rayon ,we introduce `for_each_init` for `par_iter` which
only be invoked when spawn a task for a group of items.

---

## Changelog

- added  `for_each_init`

## Performance
`check_visibility `  in  `many_foxes ` 

![image](https://github.com/bevyengine/bevy/assets/45868716/030c41cf-0d2f-4a36-a071-35097d93e494)
 
~40% performance gain in `check_visibility`.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-04-23 12:05:34 +00:00
Aceeri
b1ab036329
Contextually clearing gizmos (#10973)
# Objective
Allow `Gizmos` to work in `FixedUpdate` without any changes needed. This
changes `Gizmos` from being a purely immediate mode api, but allows the
user to use it as if it were an immediate mode API regardless of
schedule context.

Also allows for extending by other custom schedules by adding their own
`GizmoStorage<Clear>` and the requisite systems:
- `propagate_gizmos::<Clear>` before `update_gizmo_meshes`
- `stash_default_gizmos` when starting a clear context
- `pop_default_gizmos` when ending a clear context
- `collect_default_gizmos` when grabbing the requested gizmos 
- `clear_gizmos` for clearing the context's gizmos

## Solution
Adds a generic to `Gizmos` that defaults to `Update` (the current way
gizmos works). When entering a new clear context the default `Gizmos`
gets swapped out for that context's duration so the context can collect
the gizmos requested.

Prior work: https://github.com/bevyengine/bevy/pull/9153

## To do
- [x] `FixedUpdate` should probably get its own First, Pre, Update,
Post, Last system sets for this. Otherwise users will need to make sure
to order their systems before `clear_gizmos`. This could alternatively
be fixed by moving the setup of this to `bevy_time::fixed`?
   PR to fix this issue: https://github.com/bevyengine/bevy/pull/10977
- [x] use mem::take internally for the swaps?
- [x] Better name for the `Context` generic on gizmos? `Clear`?

---

## Changelog
- Gizmos drawn in `FixedMain` now last until the next `FixedMain`
iteration runs.
2024-04-23 00:16:12 +00:00
Daniel Skates
279e89b858
Bump async-task (#13062)
Bumps `async-task` to 4.7.0 , note this is what Cargo.lock has as well.
Building as a dependency gives the following:

```
   Compiling async-channel v1.8.0
   Compiling futures-lite v1.12.0
error[E0432]: unresolved import `async_task::Builder`
  --> /Users/daniel/.cargo/registry/src/index.crates.io-6f17d22bba15001f/async-executor-1.8.0/src/lib.rs:46:18
   |
46 | use async_task::{Builder, Runnable};
   |                  ^^^^^^^ no `Builder` in the root
   |
   = help: consider importing this struct instead:
           std:🧵:Builder

For more information about this error, try `rustc --explain E0432`.
error: could not compile `async-executor` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
```

With this change, builds correctly
2024-04-22 22:40:17 +00:00
nullicorn
f496d2a3c3
Additional doc aliases for WindingOrder in bevy_math (#13065)
# Objective

Adds a few extra `#[doc(alias)]` entries to the
`bevy_math::primitives::WindingOrder` enum and its variants to improve
searchability.

## Solution

- Add "Orientation" for `WindingOrder` itself
- Add "AntiClockwise" for `CounterClockwise` variant
- Add "Collinear" for `Invalid` variant

These alternate terms seem to be quite common, especially in the
contexts of rendering and collision-detection.

Signed-off-by: Nullicorn <git@nullicorn.me>
2024-04-22 21:50:27 +00:00
Daniel Miller
5c452c6c00
Added ButtonInput docs usage example (#13046)
# Objective

Fixes #12470

This adds a examples for `ButtonInput` with `KeyCode`, `MouseButton`,
and `GamepadButton`.

It also includes an example of checking a multi-key combination, and
checking multiple keys to mean roughly the same thing.
2024-04-22 17:48:46 +00:00
Brezak
de875fdc4c
Make AppExit more specific about exit reason. (#13022)
# Objective

Closes #13017.

## Solution

- Make `AppExit` a enum with a `Success` and `Error` variant.
- Make `App::run()` return a `AppExit` if it ever returns.
- Make app runners return a `AppExit` to signal if they encountered a
error.

---

## Changelog

### Added

- [`App::should_exit`](https://example.org/)
- [`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
to the `bevy` and `bevy_app` preludes,

### Changed

- [`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
is now a enum with 2 variants (`Success` and `Error`).
- The app's [runner
function](https://docs.rs/bevy/latest/bevy/app/struct.App.html#method.set_runner)
now has to return a `AppExit`.
-
[`App::run()`](https://docs.rs/bevy/latest/bevy/app/struct.App.html#method.run)
now also returns the `AppExit` produced by the runner function.


## Migration Guide

- Replace all usages of
[`AppExit`](https://docs.rs/bevy/latest/bevy/app/struct.AppExit.html)
with `AppExit::Success` or `AppExit::Failure`.
- Any custom app runners now need to return a `AppExit`. We suggest you
return a `AppExit::Error` if any `AppExit` raised was a Error. You can
use the new [`App::should_exit`](https://example.org/) method.
- If not exiting from `main` any other way. You should return the
`AppExit` from `App::run()` so the app correctly returns a error code if
anything fails e.g.
```rust
fn main() -> AppExit {
    App::new()
        //Your setup here...
        .run()
}
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-04-22 16:48:18 +00:00
BD103
a50223622f
Remove unecessary lint #[allow(...)] (#12983)
# Objective

- https://github.com/rust-lang/rust/pull/123905 has been merged, so the
workaround introduced in #12913 is no longer necessary.
- Closes #12968

## Solution

- Remove unecessary `allow` attribute
  - This is currently blocked until Rust beta updates.
  - Last tested with `rustc 1.78.0-beta.7 (6fd191292 2024-04-12)`.
2024-04-22 16:45:29 +00:00
Salvador Carvalhinho
16ff354f1c
Correctly handle UI hierarchy without a camera (#12816)
# Objective
Add support so bevy_ui can correctly handle an UI hierarchy without a
camera present.

- Fixes #12184

## Solution

As there was no default behavior for what should happen when a camera is
not present in a UI hierarchy, the solution
was based in defining that default behavior and improving the overall
handling of this "exception".


## Changelog

- Create default values to be used in upsert_node
- Add flag to control warnings about no camera present
- Create unit test no_camera_ui (to test if ui handles no camera
present)
2024-04-22 16:42:13 +00:00
Jonathan
e9be54b0ea
Parallel event reader (#12554)
# Objective

Allow parallel iteration over events, resolve #10766

## Solution

- Add `EventParIter` which works similarly to `QueryParIter`,
implementing a `for_each{_with_id}` operator.
I chose to not mirror `EventIteratorWithId` and instead implement both
operations on a single struct.
- Reuse `BatchingStrategy` from `QueryParIter`

## Changelog

- `EventReader` now supports parallel event iteration using
`par_read().for_each(|event| ...)`.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
2024-04-22 16:37:42 +00:00
Miles Silberling-Cook
6b95b0137a
Switch monolithic lib to module re-exports (#13059)
# Objective

Makes crate module docs render correctly in the docs for the monolithic
library. Fixes https://github.com/bevyengine/bevy/issues/13055.

## Solution

Swap from
```rust
pub mod foo {
    pub use bevy_foo::*;
}
```
to
```rust
pub use bevy_foo as foo;
```
2024-04-22 01:32:51 +00:00
Daniel Miller
570c43fdd5
ButtonInput docs - performance cost adjustment (#13047)
Adjusted the documentation to better describe the performance cost of
`ButtonInput::any_just_pressed|any_just_released|any_pressed`.

Each function iterates the full input, but each check is expected
constant cost. It was described previously as a full input check, and a
full internal list iteration, which I believe is incorrect.
2024-04-22 00:42:04 +00:00
François Mockers
c40b485095
use a u64 for MeshPipelineKey (#13015)
# Objective

- `MeshPipelineKey` use some bits for two things
- First commit in this PR adds an assertion that doesn't work currently
on main
- This leads to some mesh topology not working anymore, for example
`LineStrip`
- With examples `lines`, there should be two groups of lines, the blue
one doesn't display currently

## Solution

- Change the `MeshPipelineKey` to be backed by a `u64` instead, to have
enough bits
2024-04-21 20:01:45 +00:00
Charles Bournhonesque
13cac2eeff
Fix doc when state is missing (#13049)
# Objective

The warning mentions the function `add_state` which doesn't exist;
replaced with `init_state`
2024-04-21 13:19:26 +00:00
James Liu
54456b7ea6
Make SystemParam::new_archetype and QueryState::new_archetype unsafe functions (#13044)
# Objective
Fix #2128. Both `Query::new_archetype` and `SystemParam::new_archetype`
do not check if the `Archetype` comes from the same World the state is
initialized from. This could result in unsoundness via invalid accesses
if called incorrectly.

## Solution
Make them `unsafe` functions and lift the invariant to the caller. This
also caught one instance of us not validating the World in
`SystemState::update_archetypes_unsafe_world_cell`'s implementation.

---

## Changelog
Changed: `QueryState::new_archetype` is now an unsafe function.
Changed: `SystemParam::new_archetype` is now an unsafe function.

## Migration Guide
`QueryState::new_archetype` and `SystemParam::new_archetype` are now an
unsafe functions that must be sure that the provided `Archetype` is from
the same `World` that the state was initialized from. Callers may need
to add additional assertions or propagate the safety invariant upwards
through the callstack to ensure safety.
2024-04-21 02:49:42 +00:00
IceSentry
8403c41c67
Use WireframeColor to override global color (#13034)
# Objective

- The docs says the WireframeColor is supposed to override the default
global color but it doesn't.

## Solution

- Use WireframeColor to override global color like docs said it was
supposed to do.
- Updated the example to document this feature
- I also took the opportunity to clean up the code a bit

Fixes #13032
2024-04-20 13:59:12 +00:00
BD103
b3d3daad5a
Fix Clippy lints on WASM (#13030)
# Objective

- Fixes #13024.

## Solution

- Run `cargo clippy --target wasm32-unknown-unknown` until there are no
more errors.
  - I recommend reviewing one commit at a time :)

---

## Changelog

- Fixed Clippy lints for `wasm32-unknown-unknown` target.
- Updated `bevy_transform`'s `README.md`.
2024-04-20 09:15:42 +00:00
Kanabenki
1df41b79dd
Expose desired_maximum_frame_latency through window creation (#12954)
# Objective

- Closes #12930.

## Solution

- Add a corresponding optional field on `Window` and `ExtractedWindow`

---

## Changelog

### Added

- `wgpu`'s `desired_maximum_frame_latency` is exposed through window
creation. This can be used to override the default maximum number of
queued frames on the GPU (currently 2).

## Migration Guide

- The `desired_maximum_frame_latency` field must be added to instances
of `Window` and `ExtractedWindow` where all fields are explicitly
specified.
2024-04-19 23:09:30 +00:00
targrub
8316166622
Fix uses of "it's" vs "its". (#13033)
Grammar changes only.
2024-04-19 18:17:31 +00:00
Marco Meijer
2ad27ee4ee
fix: use try_insert instead of insert in bevy_ui to prevent panics when despawning ui nodes (#13000)
# Objective

Sometimes when despawning a ui node in the PostUpdate schedule it
panics. This is because both a despawn command and insert command are
being run on the same entity.

See this example code:

```rs
use bevy::{prelude::*, ui::UiSystem};

#[derive(Resource)]
struct SliceSquare(Handle<Image>);

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, create_ui)
        .add_systems(PostUpdate, despawn_nine_slice.after(UiSystem::Layout))
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2dBundle::default());
    commands.insert_resource(SliceSquare(asset_server.load("textures/slice_square.png")));
}

fn create_ui(mut commands: Commands, slice_square: Res<SliceSquare>) {
    commands.spawn((
        NodeBundle {
            style: Style {
                width: Val::Px(200.),
                height: Val::Px(200.),
                ..default()
            },
            background_color: Color::WHITE.into(),
            ..default()
        },
        UiImage::new(slice_square.0.clone()),
        ImageScaleMode::Sliced(TextureSlicer {
            border: BorderRect::square(220.),
            center_scale_mode: SliceScaleMode::Stretch,
            sides_scale_mode: SliceScaleMode::Stretch,
            max_corner_scale: 1.,
        }),
    ));
}

fn despawn_nine_slice(mut commands: Commands, mut slices: Query<Entity, With<ImageScaleMode>>) {
    for entity in slices.iter_mut() {
        commands.entity(entity).despawn_recursive();
    }
}
```

This code spawns a UiNode with a sliced image scale mode, and despawns
it in the same frame. The
bevy_ui::texture_slice::compute_slices_on_image_change system tries to
insert the ComputedTextureSlices component on that node, but that entity
is already despawned causing this error:

```md
error[B0003]: Could not insert a bundle (of type `bevy_ui::texture_slice::ComputedTextureSlices`) for entity Entity { index: 2, generation: 3 } because it doesn't 
exist in this World. See: https://bevyengine.org/learn/errors/#b0003
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic when applying buffers for system `bevy_ui::texture_slice::compute_slices_on_image_change`!
Encountered a panic in system `bevy_ecs::schedule::executor::apply_deferred`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
```

Note that you might have to run the code a few times before this error
appears.

## Solution

Use try_insert instead of insert for non critical inserts in the bevy_ui
crate.

## Some notes

In a lot of cases it does not makes much sense to despawn ui nodes after
the layout system has finished. Except maybe if you delete the root ui
node of a tree. I personally encountered this issue in bevy `0.13.2`
with a system that was running before the layout system. And in `0.13.2`
the `compute_slices_on_image_change` system was also running before the
layout system. But now it runs after the layout system. So the only way
that this bug appears now is if you despawn ui nodes after the layout
system. So I am not 100% sure if using try_insert in this system is the
best option. But personally I still think it is better then the program
panicking.

However the `update_children_target_camera` system does still run before
the layout system. So I do think it might still be able to panic when ui
nodes are despawned before the layout system. Though I haven't been able
to verify that.
2024-04-19 18:12:08 +00:00
Lynn
cd80b10d43
Math primitives cleanup (#13020)
# Objective

- General clenup of the primitives in `bevy_math`
- Add `eccentricity()` to `Ellipse`

## Solution

- Moved `Bounded3d` implementation for `Triangle3d` to the `bounded`
module
- Added `eccentricity()` to `Ellipse`
- `Ellipse::semi_major()` and `::semi_minor()` now accept `&self`
instead of `self`
- `Triangle3d::is_degenerate()` actually uses `f32::EPSILON` as
documented
- Added tests for `Triangle3d`-maths

---------

Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
Co-authored-by: Miles Silberling-Cook <nth.tensor@gmail.com>
2024-04-18 23:45:51 +00:00
Brezak
f68bc01544
Run CheckVisibility after all the other visibility system sets have… (#12962)
# Objective

Make visibility system ordering explicit. Fixes #12953.

## Solution

Specify `CheckVisibility` happens after all other `VisibilitySystems`
sets have happened.

---------

Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
2024-04-18 20:33:29 +00:00
andristarr
2b3e3341d6
separating finite and infinite 3d planes (#12426)
# Objective

Fixes #12388

## Solution

- Removing the plane3d and adding rect3d primitive mesh
2024-04-18 14:13:22 +00:00
vero
158defd67b
Document Camera coordinate space (#13012)
# Objective

Missing docs

## Solution

Add docs paraphrased from the Cart's mouth:
https://discord.com/channels/691052431525675048/691052431974465548/1172305792154738759
> It follows the natural "results" of right handed y-up. The default
camera will face "forward" in -Z, with +X being "right". The RH y-up
setup is reasonably common. Thats why I asked for existing examples.I
think we should appeal to the masses here / see how other RH Y-up 3D
packages / engines handle this

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2024-04-18 13:02:15 +00:00
zuiyu
3fea726db3
Added deref trait for Mesh2dHandle (#13002)
# Added deref trait for Mesh2dHandle

- Fixes #13001 ".

## Solution

- Added Derive Deref for Mesh2dHandle.
2024-04-18 12:59:29 +00:00
charlotte
ef7bafa68e
Add missing Default impl to ExtendedMaterial. (#13008)
# Objective

When trying to be generic over `Material + Default`, the lack of a
`Default` impl for `ExtendedMaterial`, even when both of its components
implement `Default`, is problematic. I think was probably just
overlooked.

## Solution

Impl `Default` if the material and extension both impl `Default`.

---

## Changelog

## Migration Guide
2024-04-18 12:57:14 +00:00
Victor
11afe16079
Fix extensionless image loading panic (#13005)
Remake of #12938 targeting main
2024-04-17 15:13:33 +00:00
vero
cab1c5702a
Fix a copy-paste typo doc (#13004)
trivial, new doc copied from
https://github.com/bevyengine/bevy/blob/main/crates/bevy_asset/src/io/mod.rs#L138
2024-04-17 03:11:56 +00:00
Brezak
368c5cef1a
Implement clone for most bundles. (#12993)
# Objective

Closes #12985.

## Solution

- Derive clone for most types with bundle in their name.
- Bundle types missing clone:
-
[`TextBundle`](https://docs.rs/bevy/latest/bevy/prelude/struct.TextBundle.html)
(Contains
[`ContentSize`](https://docs.rs/bevy/latest/bevy/ui/struct.ContentSize.html)
which can't be cloned because it itself contains a `Option<MeasureFunc>`
where
[`MeasureFunc`](https://docs.rs/taffy/0.3.18/taffy/node/enum.MeasureFunc.html)
isn't clone)
-
[`ImageBundle`](https://docs.rs/bevy/latest/bevy/prelude/struct.ImageBundle.html)
(Same as `TextBundle`)
-
[`AtlasImageBundle`](https://docs.rs/bevy/latest/bevy/prelude/struct.AtlasImageBundle.html)
(Will be deprecated in 0.14 there's no point)
2024-04-16 16:37:09 +00:00
Marco Meijer
7e9f6328da
fix: incorrect sprite size for aabb when sprite has rect and no custom_size (#12738)
# Objective

Fixes #12736 

## Solution

Use sprite rect to calculate sprite size for aabb when custom_size is
None
2024-04-16 16:36:16 +00:00
Matty
221d925e90
Make Transform::rotate_axis and Transform::rotate_local_axis use Dir3 (#12986)
# Objective

Related to #12981

Presently, there is a footgun where we allow non-normalized vectors to
be passed in the `axis` parameters of `Transform::rotate_axis` and
`Transform::rotate_local_axis`. These methods invoke
`Quat::from_axis_angle` which expects the vector to be normalized. This
PR aims to address this.

## Solution

Require `Dir3`-valued `axis` parameters for these functions so that the
vector's normalization can be enforced at type-level.

---

## Migration Guide

All calls to `Transform::rotate_axis` and `Transform::rotate_local_axis`
will need to be updated to use a `Dir3` for the `axis` parameter rather
than a `Vec3`. For a general input, this means calling `Dir3::new` and
handling the `Result`, but if the previous vector is already known to be
normalized, `Dir3::new_unchecked` can be called instead. Note that
literals like `Vec3::X` also have corresponding `Dir3` literals; e.g.
`Dir3::X`, `Dir3::NEG_Y` and so on.

---

## Discussion

This axis input is unambigiously a direction instead of a vector, and
that should probably be reflected and enforced by the function
signature. In previous cases where we used, e.g., `impl TryInto<Dir3>`,
the associated methods already implemented (and required!) additional
fall-back logic, since the input is conceptually more complicated than
merely specifying an axis. In this case, I think it's fairly
cut-and-dry, and I'm pretty sure these methods just predate our
direction types.
2024-04-16 13:07:03 +00:00
Chris Russell
e3f55d6dfc
Instrument asset loading and processing. (#12988)
# Objective

As described in #12467, Bevy does not have any spans for any of the
tasks scheduled onto the IO and async compute task pools.

## Solution

Instrument all asset loads and asset processing. Since this change is
restricted to asset tasks, it does not completely solve #12467, but it
does mean we can record the asset path in the trace.


![image](https://github.com/bevyengine/bevy/assets/8494645/59faee63-1f69-40af-bf47-312c4d67d1e2)

---

## Changelog

Tracing will now include spans for asset loading and asset processing.
2024-04-16 12:02:11 +00:00
Patrick Walton
6003a317b8
Add Cascades to the type registry, fixing lights in glTF. (#12989)
glTF files that contain lights currently panic when loaded into Bevy,
because Bevy tries to reflect on `Cascades`, which accidentally wasn't
registered.
2024-04-16 05:16:45 +00:00
Robert Walter
2532447dcb
impl Reflect for EntityHashSet (#12971)
`EntityHashSet` doesn't seem to implement `Reflect` which seems weird!
Especially since `EntityHashMap` implements `Reflect`.

This PR just added an extra `impl_reflect_value!` for `EntityHashSet`
and this seems to do the trick.

I left out doing the same for `StableHashSet` since it's marked as
deprecated.

---

I'm really wondering what was the issue here. If anyone can explain why
`EntityHashSet` can't use the `Reflect` impl of `bevy_utils::HashSet`
similar to how it's the case with the `...HashMap`s I'd be interested!
2024-04-16 02:48:03 +00:00
BD103
7b8d502083
Fix beta lints (#12980)
# Objective

- Fixes #12976

## Solution

This one is a doozy.

- Run `cargo +beta clippy --workspace --all-targets --all-features` and
fix all issues
- This includes:
- Moving inner attributes to be outer attributes, when the item in
question has both inner and outer attributes
  - Use `ptr::from_ref` in more scenarios
- Extend the valid idents list used by `clippy:doc_markdown` with more
names
  - Use `Clone::clone_from` when possible
  - Remove redundant `ron` import
  - Add backticks to **so many** identifiers and items
    - I'm sorry whoever has to review this

---

## Changelog

- Added links to more identifiers in documentation.
2024-04-16 02:46:46 +00:00
James Liu
9dde99fb96
Cleanup the multithreaded executor (#12969)
# Objective
Improve the code quality of the multithreaded executor.

## Solution
 * Remove some unused variables.
 * Use `Mutex::get_mut` where applicable instead of locking.
* Use a `startup_systems` FixedBitset to pre-compute the starting
systems instead of building it bit-by-bit on startup.
* Instead of using `FixedBitset::clear` and `FixedBitset::union_with`,
use `FixedBitset::clone_from` instead, which does only a single copy and
will not allocate if the target bitset has a large enough allocation.
* Replace the `Mutex` around `Conditions` with `SyncUnsafeCell`, and add
a `Context::try_lock` that forces it to be synchronized fetched
alongside the executor lock.

This might produce minimal performance gains, but the focus here is on
the code quality improvements.
2024-04-16 02:37:19 +00:00
Vitaliy Sapronenko
a5fa32e1e7
Normalization anchor for sprite slice in dimensions of this slice (#12769)
# Objective

Fixes #12408 .
Fixes #12680.

## Solution

- Recaclulated anchor from dimensions of sprite to dimension of each
part of it (each part contains its own anchor)
2024-04-16 01:36:47 +00:00
Pablo Reinhardt
6b0e3fa572
Add double end arrow to gizmos (#11890)
# Objective

- Implement double ended arrows, suggestion of #9400

## Solution

- Creation of new field and method to the `ArrowBuilder`

---

## Changelog

### Added
- New field `ArrowBuilder::double_ended`
- New method `ArrowBuilder::with_double_end` to redefine the
double_ended field

## Additional

I added this in the 3d_gizmos example, that's the result:


![image](https://github.com/bevyengine/bevy/assets/126117294/2f8a93eb-4952-401a-b600-b1454cf898a9)

I added this arrow in the 2d_gizmos example too:


![image](https://github.com/bevyengine/bevy/assets/126117294/c46b4871-8acf-4711-9ca8-c2df36c0464b)

---------

Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
Co-authored-by: Pablo Reinhardt <pabloreinhardt@gmail.com>
2024-04-16 01:34:22 +00:00
Patrick Walton
1141e731ff
Implement alpha to coverage (A2C) support. (#12970)
[Alpha to coverage] (A2C) replaces alpha blending with a
hardware-specific multisample coverage mask when multisample
antialiasing is in use. It's a simple form of [order-independent
transparency] that relies on MSAA. ["Anti-aliased Alpha Test: The
Esoteric Alpha To Coverage"] is a good summary of the motivation for and
best practices relating to A2C.

This commit implements alpha to coverage support as a new variant for
`AlphaMode`. You can supply `AlphaMode::AlphaToCoverage` as the
`alpha_mode` field in `StandardMaterial` to use it. When in use, the
standard material shader automatically applies the texture filtering
method from ["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"].
Objects with alpha-to-coverage materials are binned in the opaque pass,
as they're fully order-independent.

The `transparency_3d` example has been updated to feature an object with
alpha to coverage. Happily, the example was already using MSAA.

This is part of #2223, as far as I can tell.

[Alpha to coverage]: https://en.wikipedia.org/wiki/Alpha_to_coverage

[order-independent transparency]:
https://en.wikipedia.org/wiki/Order-independent_transparency

["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"]:
https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f

---

## Changelog

### Added

* The `AlphaMode` enum now supports `AlphaToCoverage`, to provide
limited order-independent transparency when multisample antialiasing is
in use.
2024-04-15 20:37:52 +00:00
re0312
09a1f94d14
fix shadow pass trace (#12977)
# Objective

- shadow pass trace does not work correctly

## Solution

- enable it.
2024-04-15 15:55:39 +00:00
Robert Walter
e7ab65675d
Update docs of set_if_neq and replace_if_neq (#12919)
# Objective

- ~~This PR adds more flexible versions of `set_if_neq` and
`replace_if_neq` to only compare and update certain fields of a
components which is not just a newtype~~
- https://github.com/bevyengine/bevy/pull/12919#issuecomment-2048049786
gave a good solution to the original problem, so let's update the docs
so that this is easier to find

## Solution

- ~~Add `set_if_neq_with` and `replace_if_neq_with` which take an
accessor closure to access the relevant field~~

---

In a recent project, a scenario emerged that required careful
consideration regarding change detection without compromising
performance. The context involves a component that maintains a
collection of `Vec<Vec2>` representing a horizontal surface, alongside a
height field. When the height is updated, there are a few approaches to
consider:

1. Clone the collection of points to utilize the existing `set_if_neq`
method.
2. Inline and adjust the `set_if_neq` code specifically for this
scenario.
3. (Consider splitting the component into more granular components.)

It's worth noting that the third option might be the most suitable in
most cases.

A similar situation arises with the Bevy internal Transform component,
which includes fields for translation, rotation, and scale. These fields
are relatively small (`Vec3` or `Quat` with 3 or 4 `f32` values), but
the creation of a single pointer (`usize`) might be more efficient than
copying the data of the other fields. This is speculative, and insights
from others could be valuable.

Questions remain:

- Is it feasible to develop a more flexible API, and what might that
entail?
- Is there general interest in this change?

There's no hard feelings if this idea or the PR is ultimately rejected.
I just wanted to put this idea out there and hope that this might be
beneficial to others and that feedback could be valuable before
abandoning the idea.
2024-04-15 12:38:38 +00:00
Robert Swain
5f05e75a70
Fix 2D BatchedInstanceBuffer clear (#12922)
# Objective

- `cargo run --release --example bevymark -- --benchmark --waves 160
--per-wave 1000 --mode mesh2d` runs slower and slower over time due to
`no_gpu_preprocessing::write_batched_instance_buffer<bevy_sprite::mesh2d::mesh::Mesh2dPipeline>`
taking longer and longer because the `BatchedInstanceBuffer` is not
cleared

## Solution

- Split the `clear_batched_instance_buffers` system into CPU and GPU
versions
- Use the CPU version for 2D meshes
2024-04-15 05:00:43 +00:00
Hexorg
7a9a459a40
Fixed crash when transcoding one- or two-channel KTX2 textures (#12629)
# Objective

Fixes a crash when transcoding one- or two-channel KTX2 textures

## Solution

transcoded array has been pre-allocated up to levels.len using a macros.
Rgb8 transcoding already uses that and addresses transcoded array by an
index. R8UnormSrgb and Rg8UnormSrgb were pushing on top of the
transcoded vec, resulting in first levels.len() vectors to stay empty,
and second levels.len() levels actually being transcoded, which then
resulted in out of bounds read when copying levels to gpu
2024-04-14 14:40:10 +00:00
BD103
a362c278bb
Fix crates not building individually (#12948)
# Objective

- `cargo check --workspace` appears to merge features and dependencies
together, so it does not catch some issues where dependencies are not
properly feature-gated.
- The issues **are** caught, though, by running `cd $crate && cargo
check`.

## Solution

- Manually check each crate for issues.

```shell
# Script used
for i in crates/bevy_* do
    pushd $i
    cargo check
    popd
done
```

- `bevy_color` had an issue where it used `#[derive(Pod, Zeroable)]`
without using `bytemuck`'s `derive` feature.
- The `FpsOverlayPlugin` in `bevy_dev_tools` uses `bevy_ui`'s
`bevy_text` integration without properly enabling `bevy_text` as a
feature.
- `bevy_gizmos`'s `light` module was not properly feature-gated behind
`bevy_pbr`.
- ~~Lights appear to only be implemented in `bevy_pbr` and not
`bevy_sprite`, so I think this is the right call. Can I get a
confirmation by a gizmos person?~~ Confirmed :)
- `bevy_gltf` imported `SmallVec`, but only used it if `bevy_animation`
was enabled.
- There was another issue, but it was more challenging to solve than the
`smallvec` one. Run `cargo check -p bevy_gltf` and it will raise an
issue about `animation_roots`.

<details>
  <summary><code>bevy_gltf</code> errors</summary>

```shell
error[E0425]: cannot find value `animation_roots` in this scope
   --> crates/bevy_gltf/src/loader.rs:608:26
    |
608 |                         &animation_roots,
    |                          ^^^^^^^^^^^^^^^ not found in this scope

warning: variable does not need to be mutable
    --> crates/bevy_gltf/src/loader.rs:1015:5
     |
1015 |     mut animation_context: Option<AnimationContext>,
     |     ----^^^^^^^^^^^^^^^^^
     |     |
     |     help: remove this `mut`
     |
     = note: `#[warn(unused_mut)]` on by default

For more information about this error, try `rustc --explain E0425`.
warning: `bevy_gltf` (lib) generated 1 warning
error: could not compile `bevy_gltf` (lib) due to 1 previous error; 1 warning emitted
```

</details> 

---

## Changelog

- Fixed `bevy_color`, `bevy_dev_tools`, and `bevy_gizmos` so they can
now compile by themselves.
2024-04-14 00:06:03 +00:00
blukai
9622557093
fix find_current_keyframe panic (#12931)
# Objective

i downloaded a random model from sketchfab
(https://sketchfab.com/3d-models/dragon-glass-fe00cb0ecaca4e4595874b70de7e116b)
to fiddle with bevy and encountered a panic when attempted to play
animations:
```
thread 'Compute Task Pool (3)' panicked at /home/username/code/bevy/crates/bevy_animation/src/lib.rs:848:58:
index out of bounds: the len is 40 but the index is 40
```

"Animation / Animated Fox"
(5caf085dac/examples/animation/animated_fox.rs)
example can be used for reproduction. to reproduce download a model from
sketchfab (link above) and load it instead of loading fox.glb, keep only
`dragon_glass.glb#Animation0` and remove `1` and `2` -> run and wait 1-2
seconds for crash to happen.

## Solution

correct keyframe indexing, i guess
2024-04-13 22:32:21 +00:00
Patrick Walton
363210f8fe
Don't examine every entity when extracting SpriteSources. (#12957)
`ExtractComponentPlugin` doesn't check to make sure the component is
actually present unless it's in the `QueryFilter`. This meant we placed
it everywhere. This regressed performance on many examples, such as
`many_cubes`.

Fixes #12956.
2024-04-13 22:25:37 +00:00
James Liu
60e400b22f
Remove the system task span (#12950)
# Objective
The system task span is pretty consistent in how much time it uses, so
all it adds is overhead/additional bandwidth when profiling.

## Solution
Remove it.
2024-04-13 19:27:11 +00:00
Patrick Walton
8577a448f7
Fix rendering of sprites, text, and meshlets after #12582. (#12945)
`Sprite`, `Text`, and `Handle<MeshletMesh>` were types of renderable
entities that the new segregated visible entity system didn't handle, so
they didn't appear.

Because `bevy_text` depends on `bevy_sprite`, and the visibility
computation of text happens in the latter crate, I had to introduce a
new marker component, `SpriteSource`. `SpriteSource` marks entities that
aren't themselves sprites but become sprites during rendering. I added
this component to `Text2dBundle`. Unfortunately, this is technically a
breaking change, although I suspect it won't break anybody in practice
except perhaps editors.

Fixes #12935.

## Changelog

### Changed

* `Text2dBundle` now includes a new marker component, `SpriteSource`.
Bevy uses this internally to optimize visibility calculation.

## Migration Guide

* `Text` now requires a `SpriteSource` marker component in order to
appear. This component has been added to `Text2dBundle`.
2024-04-13 14:15:00 +00:00
James Liu
ae9775c83b
Optimize Event Updates (#12936)
# Objective
Improve performance scalability when adding new event types to a Bevy
app. Currently, just using Bevy in the default configuration, all apps
spend upwards of 100+us in the `First` schedule, every app tick,
evaluating if it should update events or not, even if events are not
being used for that particular frame, and this scales with the number of
Events registered in the app.

## Solution
As `Events::update` is guaranteed `O(1)` by just checking if a
resource's value, swapping two Vecs, and then clearing one of them, the
actual cost of running `event_update_system` is *very* cheap. The
overhead of doing system dependency injection, task scheduling ,and the
multithreaded executor outweighs the cost of running the system by a
large margin.

Create an `EventRegistry` resource that keeps a number of function
pointers that update each event. Replace the per-event type
`event_update_system` with a singular exclusive system uses the
`EventRegistry` to update all events instead. Update `SubApp::add_event`
to use `EventRegistry` instead.

## Performance
This speeds reduces the cost of the `First` schedule in both many_foxes
and many_cubes by over 80%. Note this is with system spans on. The
majority of this is now context-switching costs from launching
`time_system`, which should be mostly eliminated with #12869.

![image](https://github.com/bevyengine/bevy/assets/3137680/037624be-21a2-4dc2-a42f-9d0bfa3e9b4a)

The actual `event_update_system` is usually *very* short, using only a
few microseconds on average.

![image](https://github.com/bevyengine/bevy/assets/3137680/01ff1689-3595-49b6-8f09-5c44bcf903e8)

---

## Changelog
TODO

## Migration Guide
TODO

---------

Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-04-13 14:11:28 +00:00
NiseVoid
57719fc998
Add archetypal to Access Debug impl (#12947)
# Objective

- The `archetypal` field in `Access` doesn't get printed in debug output

## Solution

- Add the field to the impl
2024-04-13 06:06:48 +00:00
Ycy
70ce6f110b
fix bevy_hierarchy crate optional feature bevy_app (#12943)
fix bevy_hierarchy crate optional feature `bevy_app`
2024-04-13 04:46:00 +00:00
BD103
aa2ebbb43f
Fix some nightly Clippy lints (#12927)
# Objective

- I daily drive nightly Rust when developing Bevy, so I notice when new
warnings are raised by `cargo check` and Clippy.
- `cargo +nightly clippy` raises a few of these new warnings.

## Solution

- Fix most warnings from `cargo +nightly clippy`
- I skipped the docs-related warnings because some were covered by
#12692.
- Use `Clone::clone_from` in applicable scenarios, which can sometimes
avoid an extra allocation.
- Implement `Default` for structs that have a `pub const fn new() ->
Self` method.
- Fix an occurrence where generic constraints were defined in both `<C:
Trait>` and `where C: Trait`.
  - Removed generic constraints that were implied by the `Bundle` trait.

---

## Changelog

- `BatchingStrategy`, `NonGenericTypeCell`, and `GenericTypeCell` now
implement `Default`.
2024-04-13 02:05:38 +00:00
Patrick Walton
5caf085dac
Divide the single VisibleEntities list into separate lists for 2D meshes, 3D meshes, lights, and UI elements, for performance. (#12582)
This commit splits `VisibleEntities::entities` into four separate lists:
one for lights, one for 2D meshes, one for 3D meshes, and one for UI
elements. This allows `queue_material_meshes` and similar methods to
avoid examining entities that are obviously irrelevant. In particular,
this separation helps scenes with many skinned meshes, as the individual
bones are considered visible entities but have no rendered appearance.

Internally, `VisibleEntities::entities` is a `HashMap` from the `TypeId`
representing a `QueryFilter` to the appropriate `Entity` list. I had to
do this because `VisibleEntities` is located within an upstream crate
from the crates that provide lights (`bevy_pbr`) and 2D meshes
(`bevy_sprite`). As an added benefit, this setup allows apps to provide
their own types of renderable components, by simply adding a specialized
`check_visibility` to the schedule.

This provides a 16.23% end-to-end speedup on `many_foxes` with 10,000
foxes (24.06 ms/frame to 20.70 ms/frame).

## Migration guide

* `check_visibility` and `VisibleEntities` now store the four types of
renderable entities--2D meshes, 3D meshes, lights, and UI
elements--separately. If your custom rendering code examines
`VisibleEntities`, it will now need to specify which type of entity it's
interested in using the `WithMesh2d`, `WithMesh`, `WithLight`, and
`WithNode` types respectively. If your app introduces a new type of
renderable entity, you'll need to add an explicit call to
`check_visibility` to the schedule to accommodate your new component or
components.

## Analysis

`many_foxes`, 10,000 foxes: `main`:
![Screenshot 2024-03-31
114444](https://github.com/bevyengine/bevy/assets/157897/16ecb2ff-6e04-46c0-a4b0-b2fde2084bad)

`many_foxes`, 10,000 foxes, this branch:
![Screenshot 2024-03-31
114256](https://github.com/bevyengine/bevy/assets/157897/94dedae4-bd00-45b2-9aaf-dfc237004ddb)

`queue_material_meshes` (yellow = this branch, red = `main`):
![Screenshot 2024-03-31
114637](https://github.com/bevyengine/bevy/assets/157897/f90912bd-45bd-42c4-bd74-57d98a0f036e)

`queue_shadows` (yellow = this branch, red = `main`):
![Screenshot 2024-03-31
114607](https://github.com/bevyengine/bevy/assets/157897/6ce693e3-20c0-4234-8ec9-a6f191299e2d)
2024-04-11 20:33:20 +00:00
BD103
5c3ae32ab1
Enable clippy::ref_as_ptr (#12918)
# Objective

-
[`clippy::ref_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#/ref_as_ptr)
prevents you from directly casting references to pointers, requiring you
to use `std::ptr::from_ref` instead. This prevents you from accidentally
converting an immutable reference into a mutable pointer (`&x as *mut
T`).
- Follow up to #11818, now that our [`rust-version` is
1.77](11817f4ba4/Cargo.toml (L14)).

## Solution

- Enable lint and fix all warnings.
2024-04-10 20:16:48 +00:00
Patrick Walton
d59b1e71ef
Implement percentage-closer filtering (PCF) for point lights. (#12910)
I ported the two existing PCF techniques to the cubemap domain as best I
could. Generally, the technique is to create a 2D orthonormal basis
using Gram-Schmidt normalization, then apply the technique over that
basis. The results look fine, though the shadow bias often needs
adjusting.

For comparison, Unity uses a 4-tap pattern for PCF on point lights of
(1, 1, 1), (-1, -1, 1), (-1, 1, -1), (1, -1, -1). I tried this but
didn't like the look, so I went with the design above, which ports the
2D techniques to the 3D domain. There's surprisingly little material on
point light PCF.

I've gone through every example using point lights and verified that the
shadow maps look fine, adjusting biases as necessary.

Fixes #3628.

---

## Changelog

### Added
* Shadows from point lights now support percentage-closer filtering
(PCF), and as a result look less aliased.

### Changed
* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.

## Migration Guide

* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.
2024-04-10 20:16:08 +00:00
Vitaliy Sapronenko
ddcbb3cc80
flipping texture coords methods has been added to the StandardMaterial (#12917)
# Objective

Fixes #11996 
The deprecated shape Quad's flip field role migrated to
StandardMaterial's flip/flipped methods

## Solution

flip/flipping methods of StandardMaterial is applicable to any mesh

---

## Changelog

- Added flip and flipped methods to the StandardMaterial implementation
- Added FLIP_HORIZONTAL, FLIP_VERTICAL, FLIP_X, FLIP_Y, FLIP_Z constants

## Migration Guide

Instead of using `Quad::flip` field, call `flipped(true, false)` method
on the StandardMaterial instance when adding the mesh.

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-04-10 18:23:55 +00:00
Lynn
597799a979
Add tetrahedron gizmos (#12914)
# Objective

- Adds tetrahedron gizmos, suggestion of #9400

## Solution

- Implement tetrahedron gizmos as a `gizmos.primitive_3d`

## Additional info

Here is a short video of the default tetrahedron :)


https://github.com/bevyengine/bevy/assets/62256001/a6f31b6f-78bc-4dc2-8f46-2ebd04ed8a0e

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-10 17:59:58 +00:00
Patrick Walton
11817f4ba4
Generate MeshUniforms on the GPU via compute shader where available. (#12773)
Currently, `MeshUniform`s are rather large: 160 bytes. They're also
somewhat expensive to compute, because they involve taking the inverse
of a 3x4 matrix. Finally, if a mesh is present in multiple views, that
mesh will have a separate `MeshUniform` for each and every view, which
is wasteful.

This commit fixes these issues by introducing the concept of a *mesh
input uniform* and adding a *mesh uniform building* compute shader pass.
The `MeshInputUniform` is simply the minimum amount of data needed for
the GPU to compute the full `MeshUniform`. Most of this data is just the
transform and is therefore only 64 bytes. `MeshInputUniform`s are
computed during the *extraction* phase, much like skins are today, in
order to avoid needlessly copying transforms around on CPU. (In fact,
the render app has been changed to only store the translation of each
mesh; it no longer cares about any other part of the transform, which is
stored only on the GPU and the main world.) Before rendering, the
`build_mesh_uniforms` pass runs to expand the `MeshInputUniform`s to the
full `MeshUniform`.

The mesh uniform building pass does the following, all on GPU:

1. Copy the appropriate fields of the `MeshInputUniform` to the
`MeshUniform` slot. If a single mesh is present in multiple views, this
effectively duplicates it into each view.

2. Compute the inverse transpose of the model transform, used for
transforming normals.

3. If applicable, copy the mesh's transform from the previous frame for
TAA. To support this, we double-buffer the `MeshInputUniform`s over two
frames and swap the buffers each frame. The `MeshInputUniform`s for the
current frame contain the index of that mesh's `MeshInputUniform` for
the previous frame.

This commit produces wins in virtually every CPU part of the pipeline:
`extract_meshes`, `queue_material_meshes`,
`batch_and_prepare_render_phase`, and especially
`write_batched_instance_buffer` are all faster. Shrinking the amount of
CPU data that has to be shuffled around speeds up the entire rendering
process.

| Benchmark              | This branch | `main`  | Speedup |
|------------------------|-------------|---------|---------|
| `many_cubes -nfc`      |      17.259 |  24.529 |  42.12% |
| `many_cubes -nfc -vpi` |     302.116 | 312.123 |   3.31% |
| `many_foxes`           |       3.227 |   3.515 |   8.92% |

Because mesh uniform building requires compute shader, and WebGL 2 has
no compute shader, the existing CPU mesh uniform building code has been
left as-is. Many types now have both CPU mesh uniform building and GPU
mesh uniform building modes. Developers can opt into the old CPU mesh
uniform building by setting the `use_gpu_uniform_builder` option on
`PbrPlugin` to `false`.

Below are graphs of the CPU portions of `many-cubes
--no-frustum-culling`. Yellow is this branch, red is `main`.

`extract_meshes`:
![Screenshot 2024-04-02
124842](https://github.com/bevyengine/bevy/assets/157897/a6748ea4-dd05-47b6-9254-45d07d33cb10)
It's notable that we get a small win even though we're now writing to a
GPU buffer.

`queue_material_meshes`:
![Screenshot 2024-04-02
124911](https://github.com/bevyengine/bevy/assets/157897/ecb44d78-65dc-448d-ba85-2de91aa2ad94)
There's a bit of a regression here; not sure what's causing it. In any
case it's very outweighed by the other gains.

`batch_and_prepare_render_phase`:
![Screenshot 2024-04-02
125123](https://github.com/bevyengine/bevy/assets/157897/4e20fc86-f9dd-4e5c-8623-837e4258f435)
There's a huge win here, enough to make batching basically drop off the
profile.

`write_batched_instance_buffer`:
![Screenshot 2024-04-02
125237](https://github.com/bevyengine/bevy/assets/157897/401a5c32-9dc1-4991-996d-eb1cac6014b2)
There's a massive improvement here, as expected. Note that a lot of it
simply comes from the fact that `MeshInputUniform` is `Pod`. (This isn't
a maintainability problem in my view because `MeshInputUniform` is so
simple: just 16 tightly-packed words.)

## Changelog

### Added

* Per-mesh instance data is now generated on GPU with a compute shader
instead of CPU, resulting in rendering performance improvements on
platforms where compute shaders are supported.

## Migration guide

* Custom render phases now need multiple systems beyond just
`batch_and_prepare_render_phase`. Code that was previously creating
custom render phases should now add a `BinnedRenderPhasePlugin` or
`SortedRenderPhasePlugin` as appropriate instead of directly adding
`batch_and_prepare_render_phase`.
2024-04-10 05:33:32 +00:00
BD103
a9943e8d2c
Fix beta CI (#12913)
# Objective

- Fixes #12905.

## Solution

- Use proper code `` tags for `TaskPoolBuilder::thread_name`.
- Remove leftover documentation in `TaskPool` referencing the deleted
`TaskPoolInner` struct.
- It may be possible to rephrase this, but I do not know enough about
the task pool to write something. (cc @james7132 who made the change
removing `TaskPoolInner`.)
- Ignore a buggy rustdoc lint that thinks `App` is already in scope for
`UpdateMode` doc. (Extracted from #12692.)
2024-04-09 17:33:59 +00:00
Lynn
2f0b5b9c5a
Use impl Into<Color> for gizmos.primitive_3d(...) (#12915)
# Objective

- All gizmos APIs besides `gizmos.primitive_3d` use `impl Into<Color>`
as their type for `color`.

## Solution

- This PR changes `primitive_3d()` to use `impl Into<Color>` aswell.
2024-04-09 17:33:34 +00:00
Robert Swain
ab7cbfa8fc
Consolidate Render(Ui)Materials(2d) into RenderAssets (#12827)
# Objective

- Replace `RenderMaterials` / `RenderMaterials2d` / `RenderUiMaterials`
with `RenderAssets` to enable implementing changes to one thing,
`RenderAssets`, that applies to all use cases rather than duplicating
changes everywhere for multiple things that should be one thing.
- Adopts #8149 

## Solution

- Make RenderAsset generic over the destination type rather than the
source type as in #8149
- Use `RenderAssets<PreparedMaterial<M>>` etc for render materials

---

## Changelog

- Changed:
- The `RenderAsset` trait is now implemented on the destination type.
Its `SourceAsset` associated type refers to the type of the source
asset.
- `RenderMaterials`, `RenderMaterials2d`, and `RenderUiMaterials` have
been replaced by `RenderAssets<PreparedMaterial<M>>` and similar.

## Migration Guide

- `RenderAsset` is now implemented for the destination type rather that
the source asset type. The source asset type is now the `RenderAsset`
trait's `SourceAsset` associated type.
2024-04-09 13:26:34 +00:00
Matty
956604e4c7
Meshing for Triangle3d primitive (#12686)
# Objective

- Ongoing work for #10572 
- Implement the `Meshable` trait for `Triangle3d`, allowing 3d triangle
primitives to produce meshes.

## Solution

The `Meshable` trait for `Triangle3d` directly produces a `Mesh`, much
like that of `Triangle2d`. The mesh consists only of a single triangle
(the triangle itself), and its vertex data consists of:
- Vertex positions, which are the triangle's vertices themselves (i.e.
the triangle provides its own coordinates in mesh space directly)
- Normals, which are all the normal of the triangle itself
- Indices, which are directly inferred from the vertex order (note that
this is slightly different than `Triangle2d` which, because of its lower
dimension, has an orientation which can be corrected for so that it
always faces "the right way")
- UV coordinates, which are produced as follows:
1. The first coordinate is coincident with the `ab` direction of the
triangle.
2. The second coordinate maps to be perpendicular to the first in mesh
space, so that the UV-mapping is skew-free.
3. The UV-coordinates map to the smallest rectangle possible containing
the triangle, given the preceding constraints.

Here is a visual demonstration; here, the `ab` direction of the triangle
is horizontal, left to right — the point `c` moves, expanding the
bounding rectangle of the triangle when it pushes past `a` or `b`:

<img width="1440" alt="Screenshot 2024-03-23 at 5 36 01 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/bef4d786-7b82-4207-abd4-ac4557d0f8b8">

<img width="1440" alt="Screenshot 2024-03-23 at 5 38 12 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/c0f72b8f-8e70-46fa-a750-2041ba6dfb78">

<img width="1440" alt="Screenshot 2024-03-23 at 5 37 15 PM"
src="https://github.com/bevyengine/bevy/assets/2975848/db287e4f-2b0b-4fd4-8d71-88f4e7a03b7c">

The UV-mapping of `Triangle2d` has also been changed to use the same
logic.

---

## Changelog

- Implemented `Meshable` for `Triangle3d`.
- Changed UV-mapping of `Triangle2d` to match that of `Triangle3d`.

## Migration Guide

The UV-mapping of `Triangle2d` has changed with this PR; the main
difference is that the UVs are no longer dependent on the triangle's
absolute coordinates, but instead follow translations of the triangle
itself in its definition. If you depended on the old UV-coordinates for
`Triangle2d`, then you will have to update affected areas to use the new
ones which, briefly, can be described as follows:
- The first coordinate is parallel to the line between the first two
vertices of the triangle.
- The second coordinate is orthogonal to this, pointing in the direction
of the third point.

Generally speaking, this means that the first two points will have
coordinates `[_, 0.]`, while the third coordinate will be `[_, 1.]`,
with the exact values depending on the position of the third point
relative to the first two. For acute triangles, the first two vertices
always have UV-coordinates `[0., 0.]` and `[1., 0.]` respectively. For
obtuse triangles, the third point will have coordinate `[0., 1.]` or
`[1., 1.]`, with the coordinate of one of the two other points shifting
to maintain proportionality.

For example: 
- The default `Triangle2d` has UV-coordinates `[0., 0.]`, `[0., 1.]`,
[`0.5, 1.]`.
- The triangle with vertices `vec2(0., 0.)`, `vec2(1., 0.)`, `vec2(2.,
1.)` has UV-coordinates `[0., 0.]`, `[0.5, 0.]`, `[1., 1.]`.
- The triangle with vertices `vec2(0., 0.)`, `vec2(1., 0.)`, `vec2(-2.,
1.)` has UV-coordinates `[2./3., 0.]`, `[1., 0.]`, `[0., 1.]`.

## Discussion

### Design considerations

1. There are a number of ways to UV-map a triangle (at least two of
which are fairly natural); for instance, we could instead declare the
second axis to be essentially `bc` so that the vertices are always `[0.,
0.]`, `[0., 1.]`, and `[1., 0.]`. I chose this method instead because it
is skew-free, so that the sampling from textures has only bilinear
scaling. I think this is better for cases where a relatively "uniform"
texture is mapped to the triangle, but it's possible that we might want
to support the other thing in the future. Thankfully, we already have
the capability of easily expanding to do that with Builders if the need
arises. This could also allow us to provide things like barycentric
subdivision.
2. Presently, the mesh-creation code for `Triangle3d` is set up to never
fail, even in the case that the triangle is degenerate. I have mixed
feelings about this, but none of our other primitive meshes fail, so I
decided to take the same approach. Maybe this is something that could be
worth revisiting in the future across the board.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Jakub Marcowski <37378746+Chubercik@users.noreply.github.com>
2024-04-08 23:00:04 +00:00
James Liu
934f2cfadf
Clean up some low level dependencies (#12858)
# Objective
Minimize the number of dependencies low in the tree.

## Solution

* Remove the dependency on rustc-hash in bevy_ecs (not used) and
bevy_macro_utils (only used in one spot).
* Deduplicate the dependency on `sha1_smol` with the existing blake3
dependency already being used for bevy_asset.
 * Remove the unused `ron` dependency on `bevy_app`
* Make the `serde` dependency for `bevy_ecs` optional. It's only used
for serializing Entity.
* Change the `wgpu` dependency to `wgpu-types`, and make it optional for
`bevy_color`.
 * Remove the unused `thread-local` dependency on `bevy_render`.
* Make multiple dependencies for `bevy_tasks` optional and enabled only
when running with the `multi-threaded` feature. Preferably they'd be
disabled all the time on wasm, but I couldn't find a clean way to do
this.

---

## Changelog
TODO 

## Migration Guide
TODO
2024-04-08 19:45:42 +00:00
Hexorg
b9a232966b
Fixed a bug where skybox ddsfile would crash from wgpu (#12894)
Fixed a bug where skybox ddsfile would crash from wgpu while trying to
read past the file buffer.
Added a unit-test to prevent regression.
Bumped ddsfile dependency version to 0.5.2

# Objective

Prevents a crash when loading dds skybox.

## Solution

ddsfile already automatically sets array layers to be 6 for skyboxes.
Removed bevy's extra *= 6 multiplication.

---

This is a copy of
[#12598](https://github.com/bevyengine/bevy/pull/12598) ... I made that
one off of main and wasn't able to make more pull requests without
making a new branch.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-08 17:16:25 +00:00
orzogc
5570315baf
Document the lifetime requirement of byte_offset and byte_add (#12893)
# Objective

`byte_offset` and `byte_add` of `Ptr`, `PtrMut` and `OwningPtr` are
missing the lifetime requirement.

## Solution

Add documents.
2024-04-08 17:13:35 +00:00
UkoeHB
2ee69807b1
Fix potential out-of-bounds access in pbr_functions.wgsl (#12585)
# Objective

- Fix a potential out-of-bounds access in the `pbr_functions.wgsl`
shader.

## Solution

- Correctly compute the `GpuLights::directional_lights` array length.

## Comments

I think this solves this comment in the code, but need someone to test
it:
```rust
//NOTE: When running bevy on Adreno GPU chipsets in WebGL, any value above 1 will result in a crash
// when loading the wgsl "pbr_functions.wgsl" in the function apply_fog.
```
2024-04-08 17:00:09 +00:00
Martín Maita
0c78bf3bb0
Moves intern and label modules into bevy_ecs (#12772)
# Objective

- Attempts to solve two items from
https://github.com/bevyengine/bevy/issues/11478.

## Solution

- Moved `intern` module from `bevy_utils` into `bevy_ecs` crate and
updated all relevant imports.
- Moved `label` module from `bevy_utils` into `bevy_ecs` crate and
updated all relevant imports.

---

## Migration Guide

- Replace `bevy_utils::define_label` imports with
`bevy_ecs::define_label` imports.
- Replace `bevy_utils:🏷️:DynEq` imports with
`bevy_ecs:🏷️:DynEq` imports.
- Replace `bevy_utils:🏷️:DynHash` imports with
`bevy_ecs:🏷️:DynHash` imports.
- Replace `bevy_utils::intern::Interned` imports with
`bevy_ecs::intern::Interned` imports.
- Replace `bevy_utils::intern::Internable` imports with
`bevy_ecs::intern::Internable` imports.
- Replace `bevy_utils::intern::Interner` imports with
`bevy_ecs::intern::Interner` imports.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-04-08 15:34:11 +00:00
Martín Maita
3fc0c6869d
Bump crate-ci/typos from 1.19.0 to 1.20.4 (#12907)
# Objective

- Adopting https://github.com/bevyengine/bevy/pull/12903.

## Solution

- Bump crate-ci/typos from 1.19.0 to 1.20.4.
- Fixed a typo in `crates/bevy_pbr/src/render/pbr_functions.wgsl` file.
- Added "PNG", "iy" and "SME" as exceptions to prevent false positives.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 15:31:11 +00:00
Giacomo Stevanato
74f52076a3
Make some ReflectComponent/ReflectBundle methods work with EntityMut too (#12895)
# Objective

- Make `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` work with `EntityMut` too (currently they only
work with the more restricting `EntityWorldMut`);
- Note: support for the `Filtered*` variants has been left out since the
conversion in that case is more expensive. Let me know if I should add
support for them too.

## Solution

- Make `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` take an `impl Into<EntityMut<'a>>`;
- Make the corresponding `*Fns` function pointers take a `EntityMut`.

---

## Changelog

- `ReflectComponent::apply`, `ReflectComponent::reflect_mut` and
`ReflectBundle::apply` now accept `EntityMut` as well

## Migration Guide

- `ReflectComponentFns`'s `apply` and `reflect_mut` fields now take
`EntityMut` instead of `&mut EntityWorldMut`
- `ReflectBundleFns`'s `apply` field now takes `EntityMut` instead of
`&mut EntityWorldMut`
2024-04-08 01:46:07 +00:00
JMS55
31b5943ad4
Add previous_view_uniforms.inverse_view (#12902)
# Objective
- Upload previous frame's inverse_view matrix to the GPU for use with
https://github.com/bevyengine/bevy/pull/12898.

---

## Changelog
- Added `prepass_bindings::previous_view_uniforms.inverse_view`.
- Renamed `prepass_bindings::previous_view_proj` to
`prepass_bindings::previous_view_uniforms.view_proj`.
- Renamed `PreviousViewProjectionUniformOffset` to
`PreviousViewUniformOffset`.
- Renamed `PreviousViewProjection` to `PreviousViewData`.

## Migration Guide
- Renamed `prepass_bindings::previous_view_proj` to
`prepass_bindings::previous_view_uniforms.view_proj`.
- Renamed `PreviousViewProjectionUniformOffset` to
`PreviousViewUniformOffset`.
- Renamed `PreviousViewProjection` to `PreviousViewData`.
2024-04-07 18:59:16 +00:00
robtfm
452821dd52
more robust gpu image use (#12606)
# Objective

make morph targets and tonemapping more tolerant of delayed image
loading.

neither of these actually fail currently unless using a bespoke loader
(and even then it would be rare), but i am working on adding throttling
for asset gpu uploads (as a stopgap until we can do proper asset
streaming) and they break with that.

## Solution

when a mesh with morph targets is uploaded to the gpu, the prepare
function uploads the morph target texture if it's available, otherwise
it uploads without morph targets. this is generally fine as long as
morph targets are typically loaded from bytes (in gltf loader), but may
fail for a custom loader if the asset server async-loads the target
texture and the texture is not available yet. the mesh fails to render
and doesn't update when the image is loaded
-> if morph targets are specified but not ready yet, retry mesh upload
next frame

tonemapping `unwrap`s on the lookup table image. this is never a problem
since the image is added via `include_bytes!`, but could be a problem in
future with asset gpu throttling/streaming.
-> if the lookup texture is not yet available, use a fallback
-> in the node, check if the fallback was used before caching the bind
group
2024-04-07 17:18:58 +00:00
Giacomo Stevanato
4227781e8c
Implement From<&'w mut EntityMut> for EntityMut<'w> (#12896)
# Objective

- Implement `From<&'w mut EntityMut>` for `EntityMut<'w>`;
- Make it possible to pass `&mut EntityMut` where `impl Into<EntityMut>`
is required;
- Helps with #12895.

## Solution

- Implement `From<&'w mut EntityMut>` for `EntityMut<'w>`

---

## Changelog

- `EntityMut<'w>` now implements `From<&'w mut EntityMut>`
2024-04-07 13:24:10 +00:00
JMS55
9264850a1c
Fix skybox wrong alpha (#12888)
Fix https://github.com/bevyengine/bevy/issues/12740
2024-04-06 08:08:55 +00:00
Luís Figueiredo
ac91b19118
Fixes #12000: When viewport is set to camera and switched to SizedFul… (#12861)
# Objective

- When viewport is set to the same size as the window on creation, when
adjusting to SizedFullscreen, the window may be smaller than the
viewport for a moment, which caused the arguments to be invalid and
panic.
- Fixes #12000.

## Solution

- The fix consists of matching the size of the viewport to the lower
size of the window ( if the x value of the window is lower, I update
only the x value of the viewport, same for the y value). Also added a
test to show that it does not panic anymore.

---
2024-04-06 02:22:50 +00:00
Multirious
a27ce270d0
Fix broken link in mesh docs (#12872)
# Objective

Fixes #12813

## Solution

Update the link to
`https://github.com/bevyengine/bevy/tree/main/crates/bevy_render/src/mesh/primitives`
2024-04-05 18:22:52 +00:00
François Mockers
a9964f442d
fix msaa shift with irradiance volumes in mesh pipeline key (#12845)
# Objective

- #12791 broke example `irradiance_volumes`
- Fixes #12876 

```
wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `pbr_opaque_mesh_pipeline`
    Color state [0] is invalid
    Sample count 8 is not supported by format Rgba8UnormSrgb on this device. The WebGPU spec guarentees [1, 4] samples are supported by this format. With the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature your device supports [1, 2, 4].
```

## Solution

- Shift bits a bit more
2024-04-05 17:50:23 +00:00
Remi Godin
c233d6e0d0
Added method to get waiting pipelines IDs from pipeline cache. (#12874)
# Objective
- Add a way to easily get currently waiting pipelines IDs.

## Solution
- Added a method to get waiting pipelines `CachedPipelineId`.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-04-05 03:46:15 +00:00
James Liu
a4ed1b88b8
Relax BufferVec's type constraints (#12866)
# Objective
Since BufferVec was first introduced, `bytemuck` has added additional
traits with fewer restrictions than `Pod`. Within BufferVec, we only
rely on the constraints of `bytemuck::cast_slice` to a `u8` slice, which
now only requires `T: NoUninit` which is a strict superset of `Pod`
types.

## Solution
Change out the `Pod` generic type constraint with `NoUninit`. Also
taking the opportunity to substitute `cast_slice` with
`must_cast_slice`, which avoids a runtime panic in place of a compile
time failure if `T` cannot be used.

---

## Changelog
Changed: `BufferVec` now supports working with types containing
`NoUninit` but not `Pod` members.
Changed: `BufferVec` will now fail to compile if used with a type that
cannot be safely read from. Most notably, this includes ZSTs, which
would previously always panic at runtime.
2024-04-05 02:11:41 +00:00
Matty
3a7923ea92
Random sampling of directions and quaternions (#12857)
# Objective

Augment Bevy's random sampling capabilities by providing good tools for
producing random directions and rotations.

## Solution

The `rand` crate has a natural tool for providing `Distribution`s whose
output is a type that doesn't require any additional data to sample
values — namely,
[`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html).

Here, our existing `ShapeSample` implementations have been put to good
use in providing these, resulting in patterns like the following:
```rust
// Using thread-local rng
let random_direction1: Dir3 = random();

// Using an explicit rng
let random_direction2: Dir3 = rng.gen();

// Using an explicit rng coupled explicitly with Standard
let random_directions: Vec<Dir3> = rng.sample_iter(Standard).take(5).collect();
```

Furthermore, we have introduced a trait `FromRng` which provides sugar
for `rng.gen()` that is more namespace-friendly (in this author's
opinion):
```rust
let random_direction = Dir3::from_rng(rng);
```

The types this has been implemented for are `Dir2`, `Dir3`, `Dir3A`, and
`Quat`. Notably, `Quat` uses `glam`'s implementation rather than an
in-house one, and as a result, `bevy_math`'s "rand" feature now enables
that of `glam`.

---

## Changelog

- Created `standard` submodule in `sampling` to hold implementations and
other items related to the `Standard` distribution.
- "rand" feature of `bevy_math` now enables that of `glam`.

---

## Discussion

From a quick glance at `Quat`'s distribution implementation in `glam`, I
am a bit suspicious, since it is simple and doesn't match any algorithm
that I came across in my research. I will do a little more digging as a
follow-up to this and see if it's actually uniform (maybe even using
those tools I wrote — what a thrill).

As an aside, I'd also like to say that I think
[`Distribution`](https://docs.rs/rand/latest/rand/distributions/trait.Distribution.html)
is really, really good. It integrates with distributions provided
externally (e.g. in `rand` itself and its extensions) along with doing a
good job of isolating the source of randomness, so that output can be
reliably reproduced if need be. Finally, `Distribution::sample_iter` is
quite good for ergonomically acquiring lots of random values. At one
point I found myself writing traits to describe random sampling and
essentially reinvented this one. I just think it's good, and I think
it's worth centralizing around to a significant extent.
2024-04-04 23:13:00 +00:00
Carter Anderson
b27896f875
Disable RAY_QUERY and RAY_TRACING_ACCELERATION_STRUCTURE by default (#12862)
# Objective

See https://github.com/gfx-rs/wgpu/issues/5488 for context and
rationale.

## Solution

- Disables `wgpu::Features::RAY_QUERY` and
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE` by default. They
must be explicitly opted into now.

---

## Changelog

- Disables `wgpu::Features::RAY_QUERY` and
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE` by default. They
must be explicitly opted into now.

## Migration Guide

- If you need `wgpu::Features::RAY_QUERY` or
`wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE`, enable them
explicitly using `WgpuSettings::features`
2024-04-04 19:20:19 +00:00
Vitaliy Sapronenko
4da4493449
Error info has been added to LoadState::Failed (#12709)
# Objective

Fixes #12667.

## Solution

- Stored
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html)
inside of
[LoadState::Failed](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
as a Box<AssetLoadError> to avoid bloating the size of all variants of
LoadState.
- Fixed dependent code

## Migration guide

Added
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html)
to
[LoadState::Failed](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
option
Removed `Copy`, `Ord` and `PartialOrd` implementations for
[LoadState](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
enum
Added `Eq` and `PartialEq` implementations for
[MissingAssetSourceError](https://docs.rs/bevy/latest/bevy/asset/io/struct.MissingAssetSourceError.html),
[MissingProcessedAssetReaderError](https://docs.rs/bevy/latest/bevy/asset/io/struct.MissingProcessedAssetReaderError.html),
[DeserializeMetaError](https://docs.rs/bevy/latest/bevy/asset/enum.DeserializeMetaError.html),
[LoadState](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html),
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html),
[MissingAssetLoaderForTypeNameError](https://docs.rs/bevy/latest/bevy/asset/struct.MissingAssetLoaderForTypeNameError.html)
and
[MissingAssetLoaderForTypeIdError](https://docs.rs/bevy/latest/bevy/asset/struct.MissingAssetLoaderForTypeIdError.html)
2024-04-04 14:04:27 +00:00
re0312
4ca8cf5d66
Cluster small table/archetype into single Task in parallel iteration (#12846)
# Objective

- Fix #7303
- bevy would spawn a lot of tasks in parallel iteration when it matchs a
large storage and many small storage ,it significantly increase the
overhead of schedule.

## Solution

- collect small storage into one task
2024-04-04 07:09:26 +00:00
Antony
344e28d095
Change Tetrahedron default origin to (0, 0, 0) (#12867)
# Objective

- Fixes #12837.

## Solution

- Update `Tetrahedron` default vertices to `[0.5, 0.5, 0.5]`, `[-0.5,
0.5, -0.5]`, `[-0.5, -0.5, 0.5]` and `[0.5, -0.5, -0.5]` respectively.
- Update `tetrahedron_math` tests to account for change in default
vertices.
2024-04-03 23:00:54 +00:00
Jonathan
eb82ec047e
Remove stepping from default features (#12847)
# Objective

Fix #11931 

## Solution

- Make stepping a non-default feature
- Adjust documentation and examples
- In particular, make the breakout example not show the stepping prompt
if compiled without the feature (shows a log message instead)

---

## Changelog

- Removed `bevy_debug_stepping` from default features

## Migration Guide

The system-by-system stepping feature is now disabled by default; to use
it, enable the `bevy_debug_stepping` feature explicitly:

```toml
[dependencies]
bevy = { version = "0.14", features = ["bevy_debug_stepping"] }
```

Code using
[`Stepping`](https://docs.rs/bevy/latest/bevy/ecs/schedule/struct.Stepping.html)
will still compile with the feature disabled, but will print a runtime
error message to the console if the application attempts to enable
stepping.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-03 19:16:02 +00:00
Kristoffer Søholm
3928d01841
Ignore query parameters in AssetPaths when determining the extension (#12828)
# Objective

A help thread on discord asked how to use signed URLs for assets. This
currently fails because the query parameters are included in the
extension, which causes no suitable loader to be found:

```
Failed to load asset 'http://localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject' with asset loader 'bevy_render::texture::image_loader::ImageLoader': 
Could not load texture file: Error reading image file localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject: invalid image extension: jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject, this is an error in `bevy_render`.
```

## Solution

Make `get_full_extension` remove everything after the first `?`
character.

If this is accepted then it should also be documented in `AssetPath`
that extensions cannot include question marks.

An alternative is to special case this handling only for wasm, but that
would be annoying for the
[bevy_web_asset](https://github.com/johanhelsing/bevy_web_asset) plugin,
and in my opinion also just more confusing overall.
2024-04-03 18:57:03 +00:00
Mateusz Wachowiak
6ccb2a306e
remove close_on_esc (#12859)
# Objective

- Remove `close_on_esc`
- For context about why we are removing it see:
[discord](https://discordapp.com/channels/691052431525675048/692572690833473578/1225075194524073985)

## Migration Guide

- Users who added `close_on_esc` in their application will have to
replace it with their own solution.

```rust
pub fn close_on_esc(
    mut commands: Commands,
    focused_windows: Query<(Entity, &Window)>,
    input: Res<ButtonInput<KeyCode>>,
) {
    for (window, focus) in focused_windows.iter() {
        if !focus.focused {
            continue;
        }

        if input.just_pressed(KeyCode::Escape) {
            commands.entity(window).despawn();
        }
    }
}
```
2024-04-03 18:02:50 +00:00
Peter Hayman
f516de456b
Add EntityWorldMut::remove_by_id (#12842)
# Objective

- Add `remove_by_id` method to `EntityWorldMut` and `EntityCommands`
- This is a duplicate of the awesome work by @mateuseap, last updated
04/09/23 - #9663
- I'm opening a second one to ensure the feature makes it into `0.14`
- Fixes #9261

## Solution

Almost identical to #9663 with three exceptions
- Uses a closure instead of struct for commands, consistent with other
similar commands
- Does not refactor `EntityCommands::insert`, so no migration guide
- `EntityWorldMut::remove_by_id` is now safe containing unsafe blocks, I
think thats what @SkiFire13 was indicating should happen [in this
comment](https://github.com/bevyengine/bevy/pull/9663#discussion_r1314307525)

## Changelog

- Added `EntityWorldMut::remove_by_id` method and its tests.
- Added `EntityCommands::remove_by_id` method and its tests.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-04-03 09:50:32 +00:00
Brett Striker
ba8d70288d
[bevy_ui/layout] Update tests to get GlobalTransform properly (#12802)
This is 2 of 5 iterative PR's that affect bevy_ui/layout

- [x] Blocked by https://github.com/bevyengine/bevy/pull/12801

[Diff to parent
PR](https://github.com/StrikeForceZero/bevy/compare/dev/bevy_ui/breakup_layout_mod..dev/bevy_ui/update_layout_tests)

---

# Objective

- Update a test in bevy_ui/layout to use the proper way to get an up to
date `GlobalTransform`

## Solution

- Adds `sync_simple_transforms`, and `propagate_transforms` to the test
schedule in bevy_ui/layout

---
2024-04-03 02:48:06 +00:00
Mateusz Wachowiak
1d4176d4cd
Add methods iter_resources and iter_resources_mut (#12829)
# Objective

- Closes #12019
- Related to #4955
- Useful for dev_tools and networking

## Solution

- Create `World::iter_resources()` and `World::iter_resources_mut()`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
2024-04-03 02:47:08 +00:00
Stephen Turley
257df3af5f
Changed the order of arguments for the Arc gizmo docs (#12854)
Just updating docs for the arc gizmo so that the argument documentation
matches the order of the function arguments.
Also added docs for the color argument.

# Objective

- Improve docs

## Solution

- Moved the radius argument to the end of the argument list to match the
function

---

## Changelog

> N/A

## Migration Guide

> N/A

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-03 01:46:20 +00:00
BD103
97131e1909
Move close_on_esc to bevy_dev_tools (#12855)
# Objective

- As @james7132 said [on
Discord](https://discord.com/channels/691052431525675048/692572690833473578/1224626740773523536),
the `close_on_esc` system is forcing `bevy_window` to depend on
`bevy_input`.
- `close_on_esc` is not likely to be used in production, so it arguably
does not have a place in `bevy_window`.

## Solution

- As suggested by @afonsolage, move `close_on_esc` into
`bevy_dev_tools`.
  - Add an example to the documentation too.
- Remove `bevy_window`'s dependency on `bevy_input`.
- Add `bevy_reflect`'s `smol_str` feature to `bevy_window` because it
was implicitly depended upon with `bevy_input` before it was removed.
- Remove any usage of `close_on_esc` from the examples.
- `bevy_dev_tools` is not enabled by default. I personally find it
frustrating to run examples with additional features, so I opted to
remove it entirely.
  - This is up for discussion if you have an alternate solution.

---

## Changelog

- Moved `bevy_window::close_on_esc` to `bevy_dev_tools::close_on_esc`.
- Removed usage of `bevy_dev_tools::close_on_esc` from all examples.

## Migration Guide

`bevy_window::close_on_esc` has been moved to
`bevy_dev_tools::close_on_esc`. You will first need to enable
`bevy_dev_tools` as a feature in your `Cargo.toml`:

```toml
[dependencies]
bevy = { version = "0.14", features = ["bevy_dev_tools"] }
```

Finally, modify any imports to use `bevy_dev_tools` instead:

```rust
// Old:
// use bevy:🪟:close_on_esc;

// New:
use bevy::dev_tools::close_on_esc;

App::new()
    .add_systems(Update, close_on_esc)
    // ...
    .run();
```
2024-04-03 01:29:06 +00:00
re0312
06738bff63
Remove unnecessary branch in query iteration (#12844)
# Objective

- Since #10811,Bevy uses `assert `in the hot path of iteration. The
`for_each `method has an assert in the outer loop to help the compiler
remove unnecessary branching in the internal loop.
- However , ` for` style iterations do not receive the same treatment.
it still have a branch check in the internal loop, which could
potentially hurt performance.

## Solution

- use `TableRow::from_u32 ` instead of ` TableRow::from_usize` to avoid
unnecessary branch.

Before


![image](https://github.com/bevyengine/bevy/assets/45868716/f6d2a1ac-2129-48ff-97bf-d86713ddeaaf)



After
----------------------------------------------------------------------------


![image](https://github.com/bevyengine/bevy/assets/45868716/bfe5a9ee-ba6c-4a80-85b0-1c6d43adfe8c)
2024-04-02 06:02:56 +00:00
mamekoro
8092e2c86d
Implement basic traits for AspectRatio (#12840)
# Objective
`AspectRatio` is a newtype of `f32`, so it can implement basic traits;
`Copy`, `Clone`, `Debug`, `PartialEq` and `PartialOrd`.

## Solution
Derive basic traits for `AspectRatio`.
2024-04-01 23:02:07 +00:00
Brett Striker
cf092d45f9
[bevy_ui/layout] Extract UiSurface to its own file (#12801)
This is 1 of 5 iterative PR's that affect bevy_ui/layout

---

# Objective

- Extract `UiSurface` into its own file to make diffs in future PR's
easier to digest

## Solution

- Moved `UiSurface` to its own file
2024-04-01 22:47:34 +00:00
Patrick Walton
37522fd0ae
Micro-optimize queue_material_meshes, primarily to remove bit manipulation. (#12791)
This commit makes the following optimizations:

## `MeshPipelineKey`/`BaseMeshPipelineKey` split

`MeshPipelineKey` has been split into `BaseMeshPipelineKey`, which lives
in `bevy_render` and `MeshPipelineKey`, which lives in `bevy_pbr`.
Conceptually, `BaseMeshPipelineKey` is a superclass of
`MeshPipelineKey`. For `BaseMeshPipelineKey`, the bits start at the
highest (most significant) bit and grow downward toward the lowest bit;
for `MeshPipelineKey`, the bits start at the lowest bit and grow upward
toward the highest bit. This prevents them from colliding.

The goal of this is to avoid having to reassemble bits of the pipeline
key for every mesh every frame. Instead, we can just use a bitwise or
operation to combine the pieces that make up a `MeshPipelineKey`.

## `specialize_slow`

Previously, all of `specialize()` was marked as `#[inline]`. This
bloated `queue_material_meshes` unnecessarily, as a large chunk of it
ended up being a slow path that was rarely hit. This commit refactors
the function to move the slow path to `specialize_slow()`.

Together, these two changes shave about 5% off `queue_material_meshes`:

![Screenshot 2024-03-29
130002](https://github.com/bevyengine/bevy/assets/157897/a7e5a994-a807-4328-b314-9003429dcdd2)

## Migration Guide

- The `primitive_topology` field on `GpuMesh` is now an accessor method:
`GpuMesh::primitive_topology()`.
- For performance reasons, `MeshPipelineKey` has been split into
`BaseMeshPipelineKey`, which lives in `bevy_render`, and
`MeshPipelineKey`, which lives in `bevy_pbr`. These two should be
combined with bitwise-or to produce the final `MeshPipelineKey`.
2024-04-01 21:58:53 +00:00
Matty
c8aa3ac7d1
Meshing for Annulus primitive (#12734)
# Objective

Related to #10572 
Allow the `Annulus` primitive to be meshed.

## Solution

We introduce a `Meshable` structure, `AnnulusMeshBuilder`, which allows
the `Annulus` primitive to be meshed, leaving optional configuration of
the number of angular sudivisions to the user. Here is a picture of the
annulus's UV-mapping:
<img width="1440" alt="Screenshot 2024-03-26 at 10 39 48 AM"
src="https://github.com/bevyengine/bevy/assets/2975848/b170291d-cba7-441b-90ee-2ad6841eaedb">

Other features are essentially identical to the implementations for
`Circle`/`Ellipse`.

---

## Changelog

- Introduced `AnnulusMeshBuilder`
- Implemented `Meshable` for `Annulus` with `Output =
AnnulusMeshBuilder`
- Implemented `From<Annulus>` and `From<AnnulusMeshBuilder>` for `Mesh`
- Added `impl_reflect!` declaration for `Annulus` and `Triangle3d` in
`bevy_reflect`

---

## Discussion

### Design considerations

The only interesting wrinkle here is that the existing UV-mapping of
`Ellipse` (and hence of `Circle` and `RegularPolygon`) is non-radial
(it's skew-free, created by situating the mesh in a bounding rectangle),
so the UV-mapping of `Annulus` doesn't limit to that of `Circle` as its
inner radius tends to zero, for instance. I don't see this as a real
issue for `Annulus`, which should almost certainly have this kind of
UV-mapping, but I think we ought to at least consider allowing mesh
configuration for `Circle`/`Ellipse` that performs radial UV-mapping
instead. (In these cases in particular, it would be especially easy,
since we wouldn't need a different parameter set in the builder.)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-04-01 21:55:49 +00:00
Jakub Marcowski
20ee56e719
Add Tetrahedron primitive to bevy_math::primitives (#12688)
# Objective

- #10572

There is no 3D primitive available for the common shape of a tetrahedron
(3-simplex).

## Solution

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

- `Tetrahedron`: a polyhedron composed of four triangular faces, six
straight edges, and four vertices

---

## Changelog

### Added

- `Tetrahedron` primitive to the `bevy_math` crate
- `Tetrahedron` tests (`area`, `volume` methods)
- `impl_reflect!` declaration for `Tetrahedron` in the `bevy_reflect`
crate
2024-04-01 21:53:12 +00:00
César Sagaert
aa477028ef
fix previous_position / previous_force being discarded too early (#12556)
# Objective

Fixes #12442

## Solution

Change `process_touch_event` to not update previous_position /
previous_force, and change it once per frame in
`touch_screen_input_system`.
2024-04-01 21:45:47 +00:00
Hennadii Chernyshchyk
891c2f1203
Add RemovedComponentEvents::iter (#12815)
# Objective

Sometimes it's useful to iterate over removed entities. For example, in
my library
[bevy_replicon](https://github.com/projectharmonia/bevy_replicon) I need
it to iterate over all removals to replicate them over the network.

Right now we do lookups, but it would be more convenient and faster to
just iterate over all removals.

## Solution

Add `RemovedComponentEvents::iter`.

---

## Changelog

### Added

- `RemovedComponentEvents::iter` to iterate over all removed components.

---------

Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
2024-04-01 20:20:30 +00:00
BD103
84363f2fab
Remove redundant imports (#12817)
# Objective

- There are several redundant imports in the tests and examples that are
not caught by CI because additional flags need to be passed.

## Solution

- Run `cargo check --workspace --tests` and `cargo check --workspace
--examples`, then fix all warnings.
- Add `test-check` to CI, which will be run in the check-compiles job.
This should catch future warnings for tests. Examples are already
checked, but I'm not yet sure why they weren't caught.

## Discussion

- Should the `--tests` and `--examples` flags be added to CI, so this is
caught in the future?
- If so, #12818 will need to be merged first. It was also a warning
raised by checking the examples, but I chose to split off into a
separate PR.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-01 19:59:08 +00:00
Jake
abd94480ab
Normalize warning messages with Nvidia drivers (#12833)
# Objective
There are currently 2 different warning messages that are logged when
resizing on Linux with Nvidia drivers (introduced in
70c69cdd51).
Fixes #12830

## Solution
Generalize both to say:
```Couldn't get swap chain texture. This often happens with the NVIDIA drivers on Linux. It can be safely ignored.```
2024-04-01 19:56:56 +00:00
François Mockers
93fd02e8ea
remove DeterministicRenderingConfig (#12811)
# Objective

- Since #12453, `DeterministicRenderingConfig` doesn't do anything

## Solution

- Remove it

---

## Migration Guide

- Removed `DeterministicRenderingConfig`. There shouldn't be any z
fighting anymore in the rendering even without setting
`stable_sort_z_fighting`
2024-04-01 09:32:47 +00:00
unknownue
50699ecf76
Fix typos in insert_or_spawn_batch/spawn_batch methods (#12812)
# Objective

- The `bundles` parameter in `insert_or_spawn_batch` method has
inconsistent naming with docs (e.g. `bundles_iter`) since #11107.

## Solution

- Replace `bundles` with `bundles_iter`, as `bundles_iter` is more
expressive to its type.
2024-03-31 20:18:27 +00:00
Paolo Barbolini
2ae7b4c7ac
Add repository field to bevy_utils_proc_macros (#12808)
# Objective

Make it easy for crates.io / lib.rs users or automated tools to find the
repository of `bevy_utils_proc_macros`

## Solution

Add the `repository` field to the `Cargo.toml` of
`bevy_utils_proc_macros`
2024-03-31 09:58:16 +00:00
Cameron
01649f13e2
Refactor App and SubApp internals for better separation (#9202)
# Objective

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

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

## Solution

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

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

## Changelog

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

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

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

Fixes #12199

I think this would be nice to get into 0.13.1

## Solution

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

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

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

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

## Changelog

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

## Migration Guide

---------

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

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

## Solution

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

## Migration Guide

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

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

## Solution

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

## Migration Guide

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

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

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

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

---

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

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

---------

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

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

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

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

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

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

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

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

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

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

---

## Changelog

### Changed

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

## Migration Guide

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

## Tracy graphs

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

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

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

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

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

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

---------

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

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

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

Closes #5881.

## Solution

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

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

---

## Changelog

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

---------

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

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

## Solution

- Add `Clone` to `WinitSettings`.

---

## Changelog

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

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

## Solution

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

## Comments

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

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

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

## Solution

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

## Solution

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

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

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

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

## Solution

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

## Alternative implementations

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

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

## Solution

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

## Solution
Add impls for both of the types.

---

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

---------

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

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

## Solution

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

---------

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

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

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

## Solution

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

## Review notes

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


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

---------

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

- Avoid unbounded HashMap growth for opening/closing windows.

## Solution

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

## Migration Guide

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

---

## Comments

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

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

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

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

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

## Solution

Simple `#[derive(Debug)]`

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

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

## Solution

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

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

## Solution

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

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

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

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

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

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

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

---

## Changelog

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

## Migration Guide

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

---

## Discussion

### Design considerations

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

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

### Future directions

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

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

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

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

---------

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


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

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

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

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

---------

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

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

---

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

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

## Solution

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

---------

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

- Fixes #12712

## Solution

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

---

## Changelog

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

## Migration Guide

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

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

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

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

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

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

## Solution

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

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

---

## Changelog

### Fixed

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

## Migration Guide

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

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

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

## Solution

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

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

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

---

## Changelog

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

## Migration Guide

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

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

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

## Solution

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

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


## Solution

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

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

- #10572

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

## Solution

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

- `Annulus`: the region between two concentric circles

---

## Changelog

### Added

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

---------

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

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

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

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

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

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

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

## Solution

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

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

---

## Changelog

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

## Migration Guide

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

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

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

Before

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

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

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

## Solution

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

---

## Changelog

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

## Migration Guide

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

## Additional information
Some pretty pictures :)

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

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

---------

Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
2024-03-25 19:10:45 +00:00