# Objective
Provide the ability to trigger controller rumbling (force-feedback) with
a cross-platform API.
## Solution
This adds the `GamepadRumbleRequest` event to `bevy_input` and adds a
system in `bevy_gilrs` to read them and rumble controllers accordingly.
It's a relatively primitive API with a `duration` in seconds and
`GamepadRumbleIntensity` with values for the weak and strong gamepad
motors. It's is an almost 1-to-1 mapping to platform APIs. Some
platforms refer to these motors as left and right, and low frequency and
high frequency, but by convention, they're usually the same.
I used #3868 as a starting point, updated to main, removed the low-level
gilrs effect API, and moved the requests to `bevy_input` and exposed the
strong and weak intensities.
I intend this to hopefully be a non-controversial cross-platform
starting point we can build upon to eventually support more fine-grained
control (closer to the gilrs effect API)
---
## Changelog
### Added
- Gamepads can now be rumbled by sending the `GamepadRumbleRequest`
event.
---------
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Bruce Reif (Buswolley) <bruce.reif@dynata.com>
# Objective
`Camera::logical_viewport_rect()` returns `Option<(Vec2, Vec2)>` which
is a tuple of vectors representing the `(min, max)` bounds of the
viewport rect. Since the function says it returns a rect and there is a
`Rect { min, max }` struct in `bevy_math`, using the struct will be
clearer.
## Solution
Replaced `Option<(Vec2, Vec2)>` with `Option<Rect>` for
`Camera::logical_viewport_rect()`.
---
## Changelog
- Changed `Camera::logical_viewport_rect` return type from `(Vec2,
Vec2)` to `Rect`
## Migration Guide
Before:
```
fn view_logical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some((min, max)) = camera.logical_viewport_rect() else { return };
dbg!(min, max);
}
```
After:
```
fn view_logical_camera_rect(camera_query: Query<&Camera>) {
let camera = camera_query.single();
let Some(Rect { min, max }) = camera.logical_viewport_rect() else { return };
dbg!(min, max);
}
```
# Objective
Add a bounding box gizmo
![Screenshot from 2023-04-22
23-49-40](https://user-images.githubusercontent.com/29694403/233808825-7593dc38-0623-48a9-b0d7-a4ca24a9e071.png)
## Changes
- Added the `AabbGizmo` component that will draw the `Aabb` component on
that entity.
- Added an option to draw all bounding boxes in a scene on the
`GizmoConfig` resource.
- Added `TransformPoint` trait to generalize over the point
transformation methods on various transform types (e.g `Transform` and
`GlobalTransform`).
- Changed the `Gizmos::cuboid` method to accept an `impl TransformPoint`
instead of separate translation, rotation, and scale.
# Objective
Timer with zero `Duration` panics at `tick()` because of division by
zero. This PR Fixes#8463 .
## Solution
- Handle division by zero separately with `checked_div` and
`checked_rem`.
---
## Changelog
- Replace division with `checked_div`. Set `times_finished_this_tick` to
u32::MAX when duration is zero.
- Set `elapsed` to `Duration::ZERO` when timer duration is zero.
- Set `percent` to `1.0` when duration is zero.
- `times_finished_this_tick` is [not used
anywhere](https://github.com/bevyengine/bevy/search?q=times_finished_this_tick),
that's why this change will not affect other parts of the project.
- `times_finished_this_tick` is set to `0` after `reset()` and before
first `tick()` call.
# Objective
- Add `Aabb` calculation for `Sprite`, `TextureAtlasSprite` and
`Mesh2d`.
- Enable frustum culling for 2D entities since frustum culling requires
a `Aabb` component in the entity to function.
- Improve 2D performance massively when there are many sprites out of
view. (ex: `many_sprites`)
## Solution
- Derived from @Weasy666's #3944 pull request, which had no activity
since multiple months.
- Adapted the code to the latest version of Bevy.
- Added support for sprites with non-center `Anchor`s to avoid culling
prematurely when part of the sprite is still in view or not culling when
sprite is already out of view.
### Note
- Gives 15.8x performance boosts in some scenarios. (5 fps vs 79 fps
with 409600 sprites in `many_sprites`)
---------
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
The objective is to be able to load data from "application-specific"
(see glTF spec 3.7.2.1.) vertex attribute semantics from glTF files into
Bevy meshes.
## Solution
Rather than probe the glTF for the specific attributes supported by
Bevy, this PR changes the loader to iterate through all the attributes
and map them onto `MeshVertexAttribute`s. This mapping includes all the
previously supported attributes, plus it is now possible to add mappings
using the `add_custom_vertex_attribute()` method on `GltfPlugin`.
## Changelog
- Add support for loading custom vertex attributes from glTF files.
- Add the `custom_gltf_vertex_attribute.rs` example to illustrate
loading custom vertex attributes.
## Migration Guide
- If you were instantiating `GltfPlugin` using the unit-like struct
syntax, you must instead use `GltfPlugin::default()` as the type is no
longer unit-like.
This line does not appear to be an intended part of the `Panics`
section, but instead looks like it was missed when copy-pasting a
`Panics` section from above.
It confused me when I was reading the docs. At first I read it as if it
was an imperative statement saying not to use `match` statements which
seemed odd and out of place. Once I saw the code it was clearly in err.
# Objective
- Cleanup documentation string to reduce end-user confusion.
Links in the api docs are nice. I noticed that there were several places
where structs / functions and other things were referenced in the docs,
but weren't linked. I added the links where possible / logical.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Enabling AlphaMode::Opaque in the shader_prepass example crashes. The
issue seems to be that enabling opaque also generates vertex_uvs
Fixes https://github.com/bevyengine/bevy/issues/8273
## Solution
- Use the vertex_uvs in the shader if they are present
# Objective
The first query of `measure_text_system`'s `text_queries` `ParamSet`
queries for all changed `Text` meaning that non-UI `Text` entities could
be added to its queue.
## Solution
Add a `With<Node>` query filter.
---
## Changelog
changes:
* Added a `With<Node>` query filter to first query of
`measure_text_system`'s `text_queries` `ParamSet` to ensure that only UI
node entities are added to its local queue.
* Fixed comment (text is not computed on changes to style).
# Objective
- Fix the issue described in #8183: Box<dyn Reflect> structs with a
hashmap in them will panic when clone_value is called on it
- Fixes: #8183
## Solution
- Updates the implementation of Reflect for Hashmaps to make clone_value
call from_reflect on the key before inserting it into the new struct
# Objective
- Have a default font
## Solution
- Add a font based on FiraMono containing only ASCII characters and use
it as the default font
- It is behind a feature `default_font` enabled by default
- I also updated examples to use it, but not UI examples to still show
how to use a custom font
---
## Changelog
* If you display text without using the default handle provided by
`TextStyle`, the text will be displayed
# Objective
Added the possibility to draw arcs in 2d via gizmos
## Solution
- Added `arc_2d` function to `Gizmos`
- Added `arc_inner` function
- Added `Arc2dBuilder<'a, 's>`
- Updated `2d_gizmos.rs` example to draw an arc
---------
Co-authored-by: kjolnyr <kjolnyr@protonmail.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
If a UI node has a changed `CalculatedSize` component and either the UI
does a full update or the node also has a changed `Style` component, the
node's corresponding Taffy node will be updated twice by
`flex_node_system`.
## Solution
Add a `Without<Calculated>` query filter so that the two changed node
queries in `flex_node_system` are mutually exclusive and move the
`CalculatedSize` node updater into the else block of the full-update if
conditional.
# Objective
- Mesh entities should cast shadows when not having Aabbs and having
NoFrustumCulling
- Fixes#8442
## Solution
- Mesh entities with NoFrustumCulling get no automatic Aabbs added
- Point and spot lights do not cull mesh entities for their shadow
mapping if they do not have an Aabb, but directional lights do
- Make directional lights not cull mesh entities from cascades if the do
not have Aabbs. So no Aabb as a consequence of a NoFrustumCulling
component will mean that those mesh entities are not culled and so are
visible to the light.
---
## Changelog
- Fixed: Mesh entities with NoFrustumCulling will cast shadows for
directional light shadow maps
Fixes https://github.com/bevyengine/bevy/issues/1207
# Objective
Right now, it's impossible to capture a screenshot of the entire window
without forking bevy. This is because
- The swapchain texture never has the COPY_SRC usage
- It can't be accessed without taking ownership of it
- Taking ownership of it breaks *a lot* of stuff
## Solution
- Introduce a dedicated api for taking a screenshot of a given bevy
window, and guarantee this screenshot will always match up with what
gets put on the screen.
---
## Changelog
- Added the `ScreenshotManager` resource with two functions,
`take_screenshot` and `save_screenshot_to_disk`
# Objective
Methods for interacting with world schedules currently have two
variants: one that takes `impl ScheduleLabel` and one that takes `&dyn
ScheduleLabel`. Operations such as `run_schedule` or `schedule_scope`
only use the label by reference, so there is little reason to have an
owned variant of these functions.
## Solution
Decrease maintenance burden by merging the `ref` variants of these
functions with the owned variants.
---
## Changelog
- Deprecated `World::run_schedule_ref`. It is now redundant, since
`World::run_schedule` can take values by reference.
## Migration Guide
The method `World::run_schedule_ref` has been deprecated, and will be
removed in the next version of Bevy. Use `run_schedule` instead.
# Objective
Label traits such as `ScheduleLabel` currently have a major footgun: the
trait is implemented for `Box<dyn ScheduleLabel>`, but the
implementation does not function as one would expect since `Box<T>` is
considered to be a distinct type from `T`. This is because the behavior
of the `ScheduleLabel` trait is specified mainly through blanket
implementations, which prevents `Box<dyn ScheduleLabel>` from being
properly special-cased.
## Solution
Replace the blanket-implemented behavior with a series of methods
defined on `ScheduleLabel`. This allows us to fully special-case
`Box<dyn ScheduleLabel>` .
---
## Changelog
Fixed a bug where boxed label types (such as `Box<dyn ScheduleLabel>`)
behaved incorrectly when compared with concretely-typed labels.
## Migration Guide
The `ScheduleLabel` trait has been refactored to no longer depend on the
traits `std::any::Any`, `bevy_utils::DynEq`, and `bevy_utils::DynHash`.
Any manual implementations will need to implement new trait methods in
their stead.
```rust
impl ScheduleLabel for MyType {
// Before:
fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }
// After:
fn dyn_clone(&self) -> Box<dyn ScheduleLabel> { ... }
fn as_dyn_eq(&self) -> &dyn DynEq {
self
}
// No, `mut state: &mut` is not a typo.
fn dyn_hash(&self, mut state: &mut dyn Hasher) {
self.hash(&mut state);
// Hashing the TypeId isn't strictly necessary, but it prevents collisions.
TypeId::of::<Self>().hash(&mut state);
}
}
```
Added helper extracted from #7711. that PR contains some controversy
conditions, but this one should be good to go.
---
## Changelog
### Added
- `any_component_removed` condition.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
Split the UI overflow enum so that overflow can be set for each axis
separately.
## Solution
Change `Overflow` from an enum to a struct with `x` and `y`
`OverflowAxis` fields, where `OverflowAxis` is an enum with `Clip` and
`Visible` variants. Modify `update_clipping` to calculate clipping for
each axis separately. If only one axis is clipped, the other axis is
given infinite bounds.
<img width="642" alt="overflow"
src="https://user-images.githubusercontent.com/27962798/227592983-568cf76f-7e40-48c4-a511-43c886f5e431.PNG">
---
## Changelog
* Split the UI overflow implementation so overflow can be set for each
axis separately.
* Added the enum `OverflowAxis` with `Clip` and `Visible` variants.
* Changed `Overflow` to a struct with `x` and `y` fields of type
`OverflowAxis`.
* `Overflow` has new methods `visible()` and `hidden()` that replace its
previous `Clip` and `Visible` variants.
* Added `Overflow` helper methods `clip_x()` and `clip_y()` that return
a new `Overflow` value with the given axis clipped.
* Modified `update_clipping` so it calculates clipping for each axis
separately. If a node is only clipped on a single axis, the other axis
is given `-f32::INFINITY` to `f32::INFINITY` clipping bounds.
## Migration Guide
The `Style` property `Overflow` is now a struct with `x` and `y` fields,
that allow for per-axis overflow control.
Use these helper functions to replace the variants of `Overflow`:
* Replace `Overflow::Visible` with `Overflow::visible()`
* Replace `Overflow::Hidden` with `Overflow::clip()`
# Objective
Avoid queuing empty meshes for rendering.
Should prevent #8144 from triggering when no gizmos are in use. Not a
real fix, unfortunately.
## Solution
Add an `in_use` field to `GizmoStorage` and only set it to true when
there are gizmos to draw.
# Objective
Follow-up to #8377.
As the system module has been refactored, there are many types that no
longer make sense to live in the files that they do:
- The `IntoSystem` trait is in `function_system.rs`, even though this
trait is relevant to all kinds of systems. Same for the `In<T>` type.
- `PipeSystem` is now just an implementation of `CombinatorSystem`, so
`system_piping.rs` no longer needs its own file.
## Solution
- Move `IntoSystem`, `In<T>`, and system piping combinators & tests into
the top-level `mod.rs` file for `bevy_ecs::system`.
- Move `PipeSystem` into `combinator.rs`.
# Objective
Add Reflection to `TextureAtlasSprite` to bring it inline with `Sprite`
## Solution
Addition of appropriate macros to the type
---
## Changelog
`#[reflect(Component)]` and derive `FromReflect` for
`TextureAtlasSprite`
Added `TextureAtlasSprite` to the TypeRegistry
# Objective
Fixes#8415.
## Solution
I simply added the missing types to the type registry.
## Changelog
Added `#[reflect(Component]` to `bevi_ui::ui_node::ZIndex`, since it
impls `Component` and `Reflect.`
The following types have been added to the type registry:
1. `bevy_ui::ZIndex`
2. `bevy_math::Rect`
3. `bevy_text::BreakLineOn`
4. `bevy_text::Text2dBounds`
# Objective
Followup to #7779 which tweaks the actual text measurement algorithm to
be more robust.
Before:
<img width="822" alt="Screenshot 2023-04-17 at 18 12 05"
src="https://user-images.githubusercontent.com/1007307/232566858-3d3f0fd5-f3d4-400a-8371-3c2a3f541e56.png">
After:
<img width="810" alt="Screenshot 2023-04-17 at 18 41 40"
src="https://user-images.githubusercontent.com/1007307/232566919-4254cbfa-1cc3-4ea7-91ed-8ca1b759bacf.png">
(note extra space taken up in header in before example)
## Solution
- Text layout of horizontal text (currently the only kind of text we
support) is now based solely on the layout constraints in the horizontal
axis. It ignores constraints in the vertical axis and computes vertical
size based on wrapping subject to the horizontal axis constraints.
- I've also added a paragraph to the `grid` example for testing / demo
purposes.
# Objective
When changing an Entity's `Parent` to a new one from an old `Parent`
that doesn't exist, Bevy panics. Fixes#8337.
## Solution
Use `get_entity_mut` instead of `entity_mut` in `remove_from_children`.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
- Incorrectly resolved merge conflicts in
https://github.com/bevyengine/bevy/pull/8026 have caused UI text to not
render at all.
## Solution
Restore correct system schedule for text systems
# Objective
An easy way to create 2D grid layouts
## Solution
Enable the `grid` feature in Taffy and add new style types for defining
grids.
## Notes
- ~I'm having a bit of trouble getting `#[derive(Reflect)]` to work
properly. Help with that would be appreciated (EDIT: got it to compile
by ignoring the problematic fields, but this presumably can't be
merged).~ This is now fixed
- ~The alignment types now have a `Normal` variant because I couldn't
get reflect to work with `Option`.~ I've decided to stick with the
flattened variant, as it saves a level of wrapping when authoring
styles. But I've renamed the variants from `Normal` to `Default`.
- ~This currently exposes a simplified API on top of grid. In particular
the following is not currently supported:~
- ~Negative grid indices~ Now supported.
- ~Custom `end` values for grid placement (you can only use `start` and
`span`)~ Now supported
- ~`minmax()` track sizing functions~ minmax is now support through a
`GridTrack::minmax()` constructor
- ~`repeat()`~ repeat is now implemented as `RepeatedGridTrack`
- ~Documentation still needs to be improved.~ An initial pass over the
documentation has been completed.
## Screenshot
<img width="846" alt="Screenshot 2023-03-10 at 17 56 21"
src="https://user-images.githubusercontent.com/1007307/224435332-69aa9eac-123d-4856-b75d-5449d3f1d426.png">
---
## Changelog
- Support for CSS Grid layout added to `bevy_ui`
---------
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
# Objective
- Currently, it is not possible to call `.pipe` on a system that takes
any input other than `()`.
- The `IntoPipeSystem` trait is currently very difficult to parse due to
its use of generics.
## Solution
Remove the `IntoPipeSystem` trait, and move the `pipe` method to
`IntoSystem`.
---
## Changelog
- System piping has been made more flexible: it is now possible to call
`.pipe` on a system that takes an input.
## Migration Guide
The `IntoPipeSystem` trait has been removed, and the `pipe` method has
been moved to the `IntoSystem` trait.
```rust
// Before:
use bevy_ecs::system::IntoPipeSystem;
schedule.add_systems(first.pipe(second));
// After:
use bevy_ecs::system::IntoSystem;
schedule.add_systems(first.pipe(second));
```
# Objective
- Fixes unclear warning when `insert_non_send_resource` is called on a
Send resource
## Solution
- Add a message to the asssert statement that checks this
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
`text_system` runs before the UI layout is calculated and the size of
the text node is determined, so it cannot correctly shape the text to
fit the layout, and has no way of determining if the text needs to be
wrapped.
The function `text_constraint` attempts to determine the size of the
node from the local size constraints in the `Style` component. It can't
be made to work, you have to compute the whole layout to get the correct
size. A simple example of where this fails completely is a text node set
to stretch to fill the empty space adjacent to a node with size
constraints set to `Val::Percent(50.)`. The text node will take up half
the space, even though its size constraints are `Val::Auto`
Also because the `text_system` queries for changes to the `Style`
component, when a style value is changed that doesn't affect the node's
geometry the text is recomputed unnecessarily.
Querying on changes to `Node` is not much better. The UI layout is
changed to fit the `CalculatedSize` of the text, so the size of the node
is changed and so the text and UI layout get recalculated multiple times
from a single change to a `Text`.
Also, the `MeasureFunc` doesn't work at all, it doesn't have enough
information to fit the text correctly and makes no attempt.
Fixes#7663, #6717, #5834, #1490,
## Solution
Split the `text_system` into two functions:
* `measure_text_system` which calculates the size constraints for the
text node and runs before `UiSystem::Flex`
* `text_system` which runs after `UiSystem::Flex` and generates the
actual text.
* Fix the `MeasureFunc` calculations.
---
Text wrapping in main:
<img width="961" alt="Capturemain"
src="https://user-images.githubusercontent.com/27962798/220425740-4fe4bf46-24fb-4685-a1cf-bc01e139e72d.PNG">
With this PR:
<img width="961" alt="captured_wrap"
src="https://user-images.githubusercontent.com/27962798/220425807-949996b0-f127-4637-9f33-56a6da944fb0.PNG">
## Changelog
* Removed the previous fields from `CalculatedSize`. `CalculatedSize`
now contains a boxed `Measure`.
* Added `measurement` module to `bevy_ui`.
* Added the method `create_text_measure` to `TextPipeline`.
* Added a new system `measure_text_system` that runs before
`UiSystem::Flex` that creates a `MeasureFunc` for the text.
* Rescheduled `text_system` to run after `UiSystem::Flex`.
* Added a trait `Measure`. A `Measure` is used to compute the size of a
UI node when the size of that node is based on its content.
* Added `ImageMeasure` and `TextMeasure` which implement `Measure`.
* Added a new component `UiImageSize` which is used by
`update_image_calculated_size_system` to track image size changes.
* Added a `UiImageSize` component to `ImageBundle`.
## Migration Guide
`ImageBundle` has a new component `UiImageSize` which contains the size
of the image bundle's texture and is updated automatically by
`update_image_calculated_size_system`
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The implementation of `System::run_unsafe` for `FunctionSystem` requires
that the world is the same one used to initialize the system. However,
the `System` trait has no requirements that the world actually matches,
which makes this implementation unsound.
This was previously mentioned in
https://github.com/bevyengine/bevy/pull/7605#issuecomment-1426491871
Fixes part of #7833.
## Solution
Add the safety invariant that
`System::update_archetype_component_access` must be called prior to
`System::run_unsafe`. Since
`FunctionSystem::update_archetype_component_access` properly validates
the world, this ensures that `run_unsafe` is not called with a
mismatched world.
Most exclusive systems are not required to be run on the same world that
they are initialized with, so this is not a concern for them. Systems
formed by combining an exclusive system with a regular system *do*
require the world to match, however the validation is done inside of
`System::run` when needed.
# Objective
This PR attempts to improve query compatibility checks in scenarios
involving `Or` filters.
Currently, for the following two disjoint queries, Bevy will throw a
panic:
```
fn sys(_: Query<&mut C, Or<(With<A>, With<B>)>>, _: Query<&mut C, (Without<A>, Without<B>)>) {}
```
This PR addresses this particular scenario.
## Solution
`FilteredAccess::with` now stores a vector of `AccessFilters`
(representing a pair of `with` and `without` bitsets), where each member
represents an `Or` "variant".
Filters like `(With<A>, Or<(With<B>, Without<C>)>` are expected to be
expanded into `A * B + A * !C`.
When calculating whether queries are compatible, every `AccessFilters`
of a query is tested for incompatibility with every `AccessFilters` of
another query.
---
## Changelog
- Improved system and query data access compatibility checks in
scenarios involving `Or` filters
---------
Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
If you want to execute a schedule on the world using arbitrarily complex
behavior, you currently need to use "hokey-pokey strats": remove the
schedule from the world, do your thing, and add it back to the world.
Not only is this cumbersome, it's potentially error-prone as one might
forget to re-insert the schedule.
## Solution
Add the `World::{try}schedule_scope{ref}` family of functions, which is
a convenient abstraction over hokey pokey strats. This method
essentially works the same way as `World::resource_scope`.
### Example
```rust
// Run the schedule five times.
world.schedule_scope(MySchedule, |world, schedule| {
for _ in 0..5 {
schedule.run(world);
}
});
```
---
## Changelog
Added the `World::schedule_scope` family of methods, which provide a way
to get mutable access to a world and one of its schedules at the same
time.
---------
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
The default StandardMaterial values of `pbr_material.rs` and
`pbr_types.wgsl` are out of sync.
I think they are out of sync since
https://github.com/bevyengine/bevy/pull/7664.
## Solution
Adapt the values: `metallic = 0.0`, `perceptual_roughness = 0.5`.
# Objective
We don't have a constructor function for `UiRect` that sets uniform
horizontal and vertical values, even though it is a common pattern.
## Solution
Add a constructor function to `UiRect` called `axes`, that sets both
`left` and `right` to the same given horizontal value,
and sets both `top` and `bottom` to same given vertical value.
## Changelog
* Added a constructor function `axes` to `UiRect`.
# Objective
fixes#8348
## Solution
- Uses multi-line string with backslashes allowing rustfmt to work
properly in the surrounding area.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
The behavior of change detection within `PipeSystem` is very tricky and
subtle, and is not currently covered by any of our tests as far as I'm
aware.
# Objective
Upon closer inspection, there are a few functions in the ECS that are
not being inlined, even with the highest optimizations and LTO enabled:
- Almost all
[WorldQuery::init_fetch](9fd5f20e25/results/query_get.s (L57))
calls. Affects `Query::get` calls in hot loops. In particular, the
`WorldQuery` implementation for `()` is used *everywhere* as the default
filter and is effectively a no-op.
-
[Entities::get](9fd5f20e25/results/query_get.s (L39)).
Affects `Query::get`, `World::get`, and any component insertion or
removal.
-
[Entities::set](9fd5f20e25/results/entity_remove.s (L2487)).
Affects any component insertion or removal.
-
[Tick::new](9fd5f20e25/results/entity_insert.s (L1368)).
I've only seen this in component insertion and spawning.
- ArchetypeRow::new
- BlobVec::set_len
Almost all of these have trivial or even empty implementations or have
significant opportunity to be optimized into surrounding code when
inlined with LTO enabled.
## Solution
Inline them
# Objective
The method `World::try_run_schedule` currently panics if the `Schedules`
resource does not exist, but it should just return an `Err`. Similarly,
`World::add_schedule` panics unnecessarily if the resource does not
exist.
Also, the documentation for `World::add_schedule` is completely wrong.
## Solution
When the `Schedules` resource does not exist, we now treat it the same
as if it did exist but was empty. When calling `add_schedule`, we
initialize it if it does not exist.
# Objective
Fixes#8215 and #8152. When systems panic, it causes the main thread to
panic as well, which clutters the output.
## Solution
Resolves the panic in the multi-threaded scheduler. Also adds an extra
message that tells the user the system that panicked.
Using the example from the issue, here is what the messages now look
like:
```rust
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Update, panicking_system)
.run();
}
fn panicking_system() {
panic!("oooh scary");
}
```
### Before
```
Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
Finished dev [unoptimized + debuginfo] target(s) in 2m 58s
Running `target\debug\bevy_test.exe`
2023-03-30T22:19:09.234932Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (5)' panicked at 'A system has panicked so the executor cannot continue.: RecvError', E:\Projects\Rust\bevy\crates\bevy_ecs\src\schedule\executor\multi_threaded.rs:194:60
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', E:\Projects\Rust\bevy\crates\bevy_tasks\src\task_pool.rs:376:49
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```
### After
```
Compiling bevy_test v0.1.0 (E:\Projects\Rust\bevy_test)
Finished dev [unoptimized + debuginfo] target(s) in 2.39s
Running `target\debug\bevy_test.exe`
2023-03-30T22:11:24.748513Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19044", cpu: "AMD Ryzen 5 2600 Six-Core Processor", core_count: "6", memory: "15.9 GiB" }
thread 'Compute Task Pool (5)' panicked at 'oooh scary', src\main.rs:11:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in system `bevy_test::panicking_system`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
error: process didn't exit successfully: `target\debug\bevy_test.exe` (exit code: 101)
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Fix#8191.
Currently, a state transition will be triggered whenever the `NextState`
resource has a value, even if that "transition" is to the same state as
the previous one. This caused surprising/meaningless behavior, such as
the existence of an `OnTransition { from: A, to: A }` schedule.
## Solution
State transition schedules now only run if the new state is not equal to
the old state. Change detection works the same way, only being triggered
when the states compare not equal.
---
## Changelog
- State transition schedules are no longer run when transitioning to and
from the same state.
## Migration Guide
State transitions are now only triggered when the exited and entered
state differ. This means that if the world is currently in state `A`,
the `OnEnter(A)` schedule (or `OnExit`) will no longer be run if you
queue up a state transition to the same state `A`.
# Objective
Noticed while writing #7728 that we are using `trace!` logs in our event
functions. This has shown to have significant overhead, even trace level
logs are disabled globally, as seen in #7639.
## Solution
Use the `detailed_trace!` macro introduced in #7639. Also removed the
`event_trace` function that was only used in one location.
---
## Changelog
Changed: Event trace logs are now feature gated behind the
`detailed-trace` feature.
# Objective
Fix#8321
## Solution
The `old_viewport_size` that is used to detect whether the viewport has
changed was not being updated and thus always `None`.
# Objective
Adds a new resource to control a global volume.
Fixes#7690
---
## Solution
Added a new resource to control global volume, this is then multiplied
with an audio sources volume to get the output volume, individual audio
sources can opt out of this my enabling the `absolute_volume` field in
`PlaybackSettings`.
---
## Changelog
### Added
- `GlobalVolume` a resource to control global volume (in prelude).
- `global_volume` field to `AudioPlugin` or setting the initial value of
`GlobalVolume`.
- `Volume` enum that can be `Relative` or `Absolute`.
- `VolumeLevel` struct for defining a volume level.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
when a mesh uses zero for all bone weights, vertices end up in the
middle of the screen.
## Solution
we can address this by explicitly setting the first bone weight to 1
when the weights are given as zero. this is the approach taken by
[unity](https://forum.unity.com/threads/whats-the-problem-with-this-import-fbx-warning.133736/)
(although that also sets the bone index to zero) and
[three.js](94c1a4b86f/src/objects/SkinnedMesh.js (L98)),
and likely other engines.
## Alternatives
it does add a bit of overhead, and users can always fix this themselves,
though it's a bit awkward particularly with gltfs.
(note - this is for work so my sme status shouldn't apply)
---------
Co-authored-by: ira <JustTheCoolDude@gmail.com>
# Objective
- Fix#7263
This has nothing to do with #7024. This is for the case where the
user opted to **not** keep the same global transform on update.
## Solution
- Add a `RemovedComponent<Parent>` to `propagate_transforms`
- Add a `RemovedComponent<Parent>` and `Local<Vec<Entity>>` to
`sync_simple_transforms`
- Add test to make sure all of this works.
### Performance note
This should only incur a cost in cases where a parent is removed.
A minimal overhead (one look up in the `removed_components`
sparse set) per root entities without children which transform didn't
change. A `Vec` the size of the largest number of entities removed
with a `Parent` component in a single frame, and a binary search on
a `Vec` per root entities.
It could slow up considerably in situations where a lot of entities are
orphaned consistently during every frame, since
`sync_simple_transforms` is not parallel. But in this situation,
it is likely that the overhead of archetype updates overwhelms
everything.
---
## Changelog
- Fix the `GlobalTransform` not getting updated when `Parent` is removed
## Migration Guide
- If you called `bevy_transform::systems::sync_simple_transforms` and
`bevy_transform::systems::propagate_transforms` (which is not
re-exported by bevy) you need to account for the additional
`RemovedComponents<Parent>` parameter.
---------
Co-authored-by: vyb <vyb@users.noreply.github.com>
Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Fixes#8333
# Objective
Fixes issue which causes failure to compile if using
`#![deny(missing_docs)]`.
## Solution
Added some very basic commenting to the generated read-only fields.
honestly I feel this to be up for debate since the comments are very
basic and give very little useful information but the purpose of this PR
is to fix the issue at hand.
---
## Changelog
Added comments to the derive macro and the projects now successfully
compile.
---------
Co-authored-by: lupan <kallll5@hotmail.com>
Fixes issue mentioned in PR #8285.
_Note: By mistake, this is currently dependent on #8285_
# Objective
Ensure consistency in the spelling of the documentation.
Exceptions:
`crates/bevy_mikktspace/src/generated.rs` - Has not been changed from
licence to license as it is part of a licensing agreement.
Maybe for further consistency,
https://github.com/bevyengine/bevy-website should also be given a look.
## Solution
### Changed the spelling of the current words (UK/CN/AU -> US) :
cancelled -> canceled (Breaking API changes in #8285)
behaviour -> behavior (Breaking API changes in #8285)
neighbour -> neighbor
grey -> gray
recognise -> recognize
centre -> center
metres -> meters
colour -> color
### ~~Update [`engine_style_guide.md`]~~ Moved to #8324
---
## Changelog
Changed UK spellings in documentation to US
## Migration Guide
Non-breaking changes*
\* If merged after #8285
# Objective
The clippy lint `type_complexity` is known not to play well with bevy.
It frequently triggers when writing complex queries, and taking the
lint's advice of using a type alias almost always just obfuscates the
code with no benefit. Because of this, this lint is currently ignored in
CI, but unfortunately it still shows up when viewing bevy code in an
IDE.
As someone who's made a fair amount of pull requests to this repo, I
will say that this issue has been a consistent thorn in my side. Since
bevy code is filled with spurious, ignorable warnings, it can be very
difficult to spot the *real* warnings that must be fixed -- most of the
time I just ignore all warnings, only to later find out that one of them
was real after I'm done when CI runs.
## Solution
Suppress this lint in all bevy crates. This was previously attempted in
#7050, but the review process ended up making it more complicated than
it needs to be and landed on a subpar solution.
The discussion in https://github.com/rust-lang/rust-clippy/pull/10571
explores some better long-term solutions to this problem. Since there is
no timeline on when these solutions may land, we should resolve this
issue in the meantime by locally suppressing these lints.
### Unresolved issues
Currently, these lints are not suppressed in our examples, since that
would require suppressing the lint in every single source file. They are
still ignored in CI.
# Objective
Make the coordinate systems of screen-space items (cursor position, UI,
viewports, etc.) consistent.
## Solution
Remove the weird double inversion of the cursor position's Y origin.
Once in bevy_winit to the bottom and then again in bevy_ui back to the
top.
This leaves the origin at the top left like it is in every other popular
app framework.
Update the `world_to_viewport`, `viewport_to_world`, and
`viewport_to_world_2d` methods to flip the Y origin (as they should
since the viewport coordinates were always relative to the top left).
## Migration Guide
`Window::cursor_position` now returns the position of the cursor
relative to the top left instead of the bottom left.
This now matches other screen-space coordinates like
`RelativeCursorPosition`, UI, and viewports.
The `world_to_viewport`, `viewport_to_world`, and `viewport_to_world_2d`
methods on `Camera` now return/take the viewport position relative to
the top left instead of the bottom left.
If you were using `world_to_viewport` to position a UI node the returned
`y` value should now be passed into the `top` field on `Style` instead
of the `bottom` field.
Note that this might shift the position of the UI node as it is now
anchored at the top.
If you were passing `Window::cursor_position` to `viewport_to_world` or
`viewport_to_world_2d` no change is necessary.
# Objective
Text glyphs that were clipped were not sized correctly because the
transform extracted from the `extract_text_uinodes` had a scaling on it
that wasn't accounted for.
fixes#8167
## Solution
Remove the scaling from the transform and multiply the size of the
glyphs by the inverse of the scale factor.
# Objective
Add helper functions to `UiImage` for creating flipped images.
## Changelog
* Added `with_flip_x` and `with_flip_y` methods to `UiImage` that return
the `UiImage` flipped along the respective axis.
# Objective
Exposes `empty()` method for `AudioSink`.
Based on `0.10.0`, should be a non-breaking change.
---
## Changelog
- Expose `empty()` method for `AudioSink`
- Add `AudioSink::empty()` example
---------
Co-authored-by: hank <hank@hank.co.in>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
When a `CalculatedSize` component from a UI Node entity is removed, the
corresponding Taffy measure isn't removed which will mess up the layout
in confusing, unpredictable ways.
## Solution
Iterate through all the entities with removed `CalculatedSize`
components and remove the corresponding Taffy measures.