# 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>
# 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.
# 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`
# 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`
# 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.
# 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.
# 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()`
# 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`
# 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>
# 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.
# 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, ®istry)
```
After
```rust
let mut entity_map = EntityHashMap::default();
scene.write_to_world_with(world, &mut entity_map, ®istry)
```
# 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.
---
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.
# 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>
# 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.
# 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
# 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.
# 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`.
# 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.
# 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>
# 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>
# 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
# 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`.
# 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)
# 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
# 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.
# 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
# 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>
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>
# 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>
# 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>
# Objective
Fix#14146
## Solution
Expansion of #13323 , excluded Adreno 730 and earlier.
## Testing
Tested on android device(Adreno 730) that used to crash
# 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
# 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.
# 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.
# 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>
# 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>
# 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?