Very small change that improves the usability of `Sprite`.
Before this PR, the only way to render a portion of an `Image` was to create a `TextureAtlas` and use `TextureAtlasSprite`/`SpriteSheetBundle`. This can be very annoying for one-off use cases, like if you just want to remove a border from an image, or something. Using `Sprite`/`SpriteBundle` always meant that the entire full image would be rendered.
This PR adds an optional `rect` field to `Sprite`, allowing a sub-rectangle of the image to be rendered. This is similar to how texture atlases work, but does not require creating a texture atlas asset, making it much more convenient and efficient for quick one-off use cases.
Given how trivial this change is, it really felt like missing functionality in Bevy's sprites API. ;)
## Changelog
Added:
- `rect` field on `Sprite`: allows rendering a portion of the sprite's image; more convenient for one-off use cases, than creating a texture atlas.
# Objective
fixes#5946
## Solution
adjust cluster index calculation for viewport origin.
from reading point 2 of the rasterization algorithm description in https://gpuweb.github.io/gpuweb/#rasterization, it looks like framebuffer space (and so @bulitin(position)) is not meant to be adjusted for viewport origin, so we need to subtract that to get the right cluster index.
- add viewport origin to rust `ExtractedView` and wgsl `View` structs
- subtract from frag coord for cluster index calculation
# Objective
Currently some TextureFormats are not supported by the Image type.
The `TextureFormat::Rg16Unorm` format is useful for storing minmax heightmaps.
Similar to #5249 I now additionally require image to support the dual channel variant.
## Solution
Added `TextureFormat::Rg16Unorm` support to Image.
Additionally this PR derives `Resource` for `SpecializedComputePipelines`, because for some reason this was missing.
All other special pipelines do derive `Resource` already.
Co-authored-by: Kurt Kühnert <51823519+Ku95@users.noreply.github.com>
# Objective
Fixes#5963
## Solution
Add remaining fn in Timer class, this function only minus total duration with elapsed time.
Co-authored-by: Sergi-Ferrez <61662926+Sergi-Ferrez@users.noreply.github.com>
# Objective
While coding in bevy I needed to get the elapsed time of a stopwatch as f64.
I found it quite odd there are functions on Timer to get time as f64 but not on the Stopwatch.
## Solution
- added a function that returns the `Stopwatch` elapsed time as `f64`
---
## Changelog
### Added
- Added a function to get `Stopwatch` elapsed time as `f64`
### Fixed
- The Stopwatch elapsed function had a wrong docs link
# Objective
While using the ParallelExecutor, systems do not actually start until `prepare_systems` completes. In stages where there are large numbers of "empty" systems with very little work to do, this delay adds significant overhead, which can add up over many stages.
## Solution
Immediately and synchronously signal the start of systems that can run without dependencies inside `prepare_systems` instead of waiting for the first executor iteration after `prepare_systems` completes. Any system that is dependent on them still cannot run until after `prepare_systems` completes, but there are a large number of unconstrained systems in the base engine where this is a general benefit in almost every case.
## Performance
This change was tested against `many_foxes` in the default configuration. As this change is sensitive to the overhead around scheduling systems, the spans for measuring system timing, system overhead, and system commands were all commented out for these measurements.
The median stage timings between `main` and this PR are as follows:
|stage|main|this PR|
|:--|:--|:--|
|First|75.54 us|61.61 us|
|LoadAssets|51.05 us|42.32 us|
|PreUpdate|54.6 us|55.56 us|
|Update|61.89 us|51.5 us|
|PostUpdate|7.27 ms|6.71 ms|
|AssetEvents|47.82 us|35.95 us|
|Last|39.19 us|37.71 us|
|reserve_and_flush|57.83 us|48.2 us|
|Extract|1.41 ms|1.28 ms|
|Prepare|554.49 us|502.53 us|
|Queue|216.29 us|207.51 us|
|Sort|67.03 us|60.99 us|
|Render|1.73 ms|1.58 ms|
|Cleanup|33.55 us|30.76 us|
|Clear Entities|18.56 us|17.05 us|
|**full frame**|**11.9 ms**|**10.91 ms**|
For the first few stages, the benefit is small but cumulative over each. For PostUpdate in particular, this allows `parent_update` to run while prepare_systems is running, which is required for the animation and transform propagation systems, which dominate the time spent in the stage, but also frontloads the contention as the other "empty" systems are also running while `parent_update` is running. For Render, where there is just a single large exclusive system, the benefit comes from not waiting on a spuriously scheduled task on the task pool to kick off the system: it's immediately scheduled to run.
# Objective
Fixes#5390. Makes https://dev-docs.bevyengine.org/ a bit more discoverable.
## Solution
Mention the option as an alternative option to building the docs yourself in CONTRIBUTING.md.
# Objective
EntityMut::world takes &mut self instead of &self I don't see any reason for this.
EntityRef is overly restrictive with fn world and could return &'w World
---
## Changelog
- EntityRef now implements Copy and Clone
- EntityRef::world is now fn(&self) -> &'w World instead of fn(&mut self) -> &World
- EntityMut::world is now fn(&self) -> &World instead of fn(&mut self) -> &World
# Objective
Currently, `Local` has a `Sync` bound. Theoretically this is unnecessary as a local can only ever be accessed from its own system, ensuring exclusive access on one thread. This PR removes this restriction.
## Solution
- By removing the `Resource` bound from `Local` and adding the new `SyncCell` threading primative, `Local` can have the `Sync` bound removed.
## Changelog
### Added
- Added `SyncCell` to `bevy_utils`
### Changed
- Removed `Resource` bound from `Local`
- `Local` is now wrapped in a `SyncCell`
## Migration Guide
- Any code relying on `Local<T>` having `T: Resource` may have to be changed, but this is unlikely.
Co-authored-by: PROMETHIA-27 <42193387+PROMETHIA-27@users.noreply.github.com>
While looking into `collide()`, I wrote some tests to confirm the behavior I read in the code. This PR adds those tests and improves the documentation.
Co-authored-by: robem <669201+robem@users.noreply.github.com>
# Objective
- Make people stop believing that commands are applied immediately (hopefully).
- Close#5913.
- Alternative to #5930.
## Solution
I added the clause “to perform impactful changes to the `World`” to the first line to subliminally help the reader accept the fact that some operations cannot be performed immediately without messing up everything.
Then I explicitely said that applying a command requires exclusive `World` access, and finally I proceeded to show when these commands are automatically applied.
I also added a brief paragraph about how commands can be applied manually, if they want.
---
### Further possibilities
If you agree, we can also change the text of the method documentation (in a separate PR) to stress about enqueueing an action instead of just performing it. For example, in `Commands::spawn`:
> Creates a new `Entity`
would be changed to something like:
> Issues a `Command` to spawn a new `Entity`
This may even have a greater effect, since when typing in an IDE, the docs of the method pop up and the programmer can read them on the fly.
# Objective
Alice says to make this PR: https://discord.com/channels/691052431525675048/745805740274614303/1018554340841107477
- The "scene" example in the examples folder has a TODO comment about writing the serialized data to a file. This PR implements that.
## Solution
The `AssetIo` trait in the `AssetServer` only supports reading data, not writing it. So, I used `std::io::File` for the implementation. This way, every time you run the example, it will mutate the file in-place.
I had thought about adding a UUID string to the example Component, so that every time you run the example, the file will be guaranteed to change (currently, it just writes the same numbers over and over). However, I didn't bother because it was beyond the scope of the TODO comment.
One thing to note is that the logic for serializing the scene into RON data has changed since the existing RON file was created, and so even though the data is the same, it's rendered in a different order for whatever reason.
I left the changed output to the example file, because it's presumably trivial. I can remove it and force-push if you don't want that included in here.
# Objective
Without this we can inappropriately merge batches together without properly accounting for non-batch items between them, and the merged batch will then be sorted incorrectly later.
This change seems to reliably fix the issue I was seeing in #5919.
## Solution
Ensure the `batch_phase_system` runs after the `sort_phase_system`, so that batching can only look at actually adjacent phase items.
# Objective
I wanted to run the code
```rust
let reflect_resource: ReflectResource = ...;
let value: Mut<dyn Reflect> = reflect_resource.reflect(world);
value.deref();
// ^ ERROR: deref method doesn't exist because `dyn Reflect` doesnt satisfy `: Sized`.
```
## Solution
Relax `Sized` bounds in all the methods and trait implementations for `Mut` and friends.
# Objective
This code is very disjoint, and the `stage.rs` file that it's in is already very long.
All I've done is move the code and clean up the compiler errors that result.
Followup to #5916, split out from #4299.
# Objective
Ambiguity sets are used to ignore system order ambiguities between groups of systems. However, they are not very useful: they are clunky, poorly integrated, and generally hampered by the difficulty using (or discovering) the ambiguity detector.
As a first step to the work in #4299, we're removing them.
## Migration Guide
Ambiguity sets have been removed.
# Objective
- Our existing change detection API is not flexible enough for advanced users: particularly those attempting to do rollback networking.
- This is an important use case, and with adequate warnings we can make mucking about with change ticks scary enough that users generally won't do it.
- Fixes#5633.
- Closes#2363.
## Changelog
- added `ChangeDetection::set_last_changed` to manually mutate the `last_change_ticks` field"
- the `ChangeDetection` trait now requires an `Inner` associated type, which contains the value being wrapped.
- added `ChangeDetection::bypass_change_detection`, which hands out a raw `&mut Inner`
## Migration Guide
Add the `Inner` associated type and new methods to any type that you've implemented `DetectChanges` for.
# Objective
- I'm currently working on being able to call methods on reflect types (https://github.com/jakobhellermann/bevy_reflect_fns)
- for that, I'd like to add methods to the `Input<KeyCode>` resource (which I'm doing by registering type data)
- implementing `Reflect` is currently a requirement for having type data in the `TypeRegistry`
## Solution
- derive `Reflect` for `KeyCode` and `Input`
- uses `#[reflect_value]` for `Input`, since it's fields aren't supposed to be observable
- using reflect_value would need `Clone` bounds on `T`, but since all the methods (`.pressed` etc) already require `T: Copy`, I unified everything to requiring `Copy`
- add `Send + Sync + 'static` bounds, also required by reflect derive
## Unrelated improvements
I can extract into a separate PR if needed.
- the `Reflect` derive would previously ignore `#[reflect_value]` and only accept `#[reflect_value()]` which was a bit confusing
- the generated code used `val.clone()` on a reference, which is fine if `val` impls `Clone`, but otherwise also compiles with a worse error message. Change to `std::clone::Clone::clone(val)` instead which gives a neat `T does not implement Clone` error
Make API users aware that the type aliases `QueryItem` and `QueryFetch` can be used instead of the more bloated alternative with `WorldQueryGats`.
Fixes#5842
# Objective
Make `TextLayoutInfo` more accessible as a component, rather than internal to `TextPipeline`. I am working on a plugin that manipulates these and there is no (mutable) access to them right now.
## Solution
This changes `TextPipeline::queue_text` to return `TextLayoutInfo`'s rather than storing them in a map internally. `text2d_system` and `text_system` now take the returned `TextLayoutInfo` and store it as a component of the entity. I considered adding an accessor to `TextPipeline` (e.g. `get_glyphs_mut`) but this seems like it might be a little faster, and also has the added benefit of cleaning itself up when entities are removed. Right now nothing is ever removed from the glyphs map.
## Changelog
Removed `DefaultTextPipeline`. `TextPipeline` no longer has a generic key type. `TextPipeline::queue_text` returns `TextLayoutInfo` directly.
## Migration Guide
This might break a third-party crate? I could restore the orginal TextPipeline API as a wrapper around what's in this PR.
# Objective
Fixes#5882
## Solution
Per https://github.com/rust-windowing/winit/issues/1705, the root cause is "UIWindow should be created inside UIApplicationMain". Currently, there are two places to create UIWindow, one is Plugin's build function, which is not inside UIApplicationMain. Just comment it out, and it works.
# Objective
Support monitor selection for all window modes.
Fixes#5875.
## Changelog
* Moved `MonitorSelection` out of `WindowPosition::Centered`, into `WindowDescriptor`.
* `WindowPosition::At` is now relative to the monitor instead of being in 'desktop space'.
* Renamed `MonitorSelection::Number` to `MonitorSelection::Index` for clarity.
* Added `WindowMode` to the prelude.
* `Window::set_position` is now relative to a monitor and takes a `MonitorSelection` as argument.
## Migration Guide
`MonitorSelection` was moved out of `WindowPosition::Centered`, into `WindowDescriptor`.
`MonitorSelection::Number` was renamed to `MonitorSelection::Index`.
```rust
// Before
.insert_resource(WindowDescriptor {
position: WindowPosition::Centered(MonitorSelection::Number(1)),
..default()
})
// After
.insert_resource(WindowDescriptor {
monitor: MonitorSelection::Index(1),
position: WindowPosition::Centered,
..default()
})
```
`Window::set_position` now takes a `MonitorSelection` as argument.
```rust
window.set_position(MonitorSelection::Current, position);
```
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
Clean up taffy nodes when the associated UI node gets removed. The current UI code will keep the taffy nodes around forever.
## Solution
Use `RemovedComponents<Node>` to iterate over nodes that are no longer valid UI nodes or that have been despawned, and remove them from taffy and the internal hash map.
## Implementation Notes
Do note that using `despawn()` instead of `despawn_recursive()` on a UI node that has children will result in a [warnings spam](https://github.com/bevyengine/bevy/blob/main/crates/bevy_ui/src/flex/mod.rs#L120) since the children will not be part of a proper UI hierarchy anymore.
---
## Changelog
- Fixed memory leak when nodes are removed in bevy_ui
# Objective
- The `Gamepad` type is a tiny value-containing type that implements `Copy`.
- By convention, references to `Copy` types should be avoided, as they can introduce overhead and muddle the semantics of what's going on.
- This allows us to reduce boilerplate reference manipulation and lifetimes in user facing code.
## Solution
- Make assorted methods on `Gamepads` take / return a raw `Gamepad`, rather than `&Gamepad`.
## Migration Guide
- `Gamepads::iter` now returns an iterator of `Gamepad`. rather than an iterator of `&Gamepad`.
- `Gamepads::contains` now accepts a `Gamepad`, rather than a `&Gamepad`.
## Solution
Exposes the image <-> "texture" as methods on `Image`.
## Extra
I'm wondering if `image_texture_conversion.rs` should be renamed to `image_conversion.rs`. That or the file be deleted altogether in favour of putting the code alongside the rest of the `Image` impl. Its kind-of weird to refer to the `Image` as a texture.
Also `Image::convert` is a public method so I didn't want to edit its signature, but it might be nice to have the function consume the image instead of just passing a reference to it because it would eliminate a clone.
## Changelog
> Rename `image_to_texture` to `Image::from_dynamic`
> Rename `texture_to_image` to `Image::try_into_dynamic`
> `Image::try_into_dynamic` now returns a `Result` (this is to make it easier for users who didn't read that only a few conversions are supported to figure it out.)
# Objective
Document most of the public items of the `bevy_render::camera` module and its
sub-modules.
## Solution
Add docs to most public items. Follow-up from #3447.
# Objective
- Increase consistency across documentation of `Query` methods.
- Fixes#5506
## Solution
- See #4989. This PR is derived from it. It just includes changes to the `Query` methods' docs.
# Objective
Document `PipelineCache` and a few other related types.
## Solution
Add documenting comments to `PipelineCache` and a few other related
types in the same file.
# Objective
https://github.com/bevyengine/bevy/pull/503 added these.
I don't know what problem it solved, the PR doesn't say and the code didn't make it obvious to me.
## Solution
AFAIK removing unsafe `Send`/`Sync` impls can't introduce unsoundness.
Yeet.
## Migration Guide
Why tho.
Co-authored-by: devil-ira <justthecooldude@gmail.com>
# Objective
The documentation on `Reflect` doesn't account for the recently added reflection traits: [`Array`](https://github.com/bevyengine/bevy/pull/4701) and [`Enum`](https://github.com/bevyengine/bevy/pull/4761).
## Solution
Updated the documentation for `Reflect` to account for the `Array` and `Enum`.
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
- Update notify dependency to 5.0.0 stable
- Fix breaking changes
- Closes#5861
## Solution
- RecommendedWatcher now takes a Config argument. Giving it the default Config should be the same behavior as before (check every 30 seconds)
# Objective
- Update ron to 0.8.0
- Fix breaking changes
- Closes#5862
## Solution
- Removed now non-existing method call (behavior is now the same without it)
# Objective
- Update `Query` docs with better terminology
- add some performance remarks (Fixes#4742)
## Solution
- See #4989. This PR is derived from it. It just includes changes to the `Query` struct docs.
# Objective
Promote the `Rect` utility of `sprite::Rect`, which defines a rectangle
by its minimum and maximum corners, to the `bevy_math` crate to make it
available as a general math type to all crates without the need to
depend on the `bevy_sprite` crate.
Fixes#5575
## Solution
Move `sprite::Rect` into `bevy_math` and fix all uses.
Implement `Reflect` for `Rect` directly into the `bevy_reflect` crate by
having `bevy_reflect` depend on `bevy_math`. This looks like a new
dependency, but the `bevy_reflect` was "cheating" for other math types
by directly depending on `glam` to reflect other math types, thereby
giving the illusion that there was no dependency on `bevy_math`. In
practice conceptually Bevy's math types are reflected into the
`bevy_reflect` crate to avoid a dependency of that crate to a "lower
level" utility crate like `bevy_math` (which in turn would make
`bevy_reflect` be a dependency of most other crates, and increase the
risk of circular dependencies). So this change simply formalizes that
dependency in `Cargo.toml`.
The `Rect` struct is also augmented in this change with a collection of
utility methods to improve its usability. A few uses cases are updated
to use those new methods, resulting is more clear and concise syntax.
---
## Changelog
### Changed
- Moved the `sprite::Rect` type into `bevy_math`.
### Added
- Added several utility methods to the `math::Rect` type.
## Migration Guide
The `bevy::sprite::Rect` type moved to the math utility crate as
`bevy::math::Rect`. You should change your imports from `use
bevy::sprite::Rect` to `use bevy::math::Rect`.