This is 3 of 5 iterative PR's that affect bevy_ui/layout
- [x] Blocked by https://github.com/bevyengine/bevy/pull/12801
- [x] Blocked by https://github.com/bevyengine/bevy/pull/12802
---
# Objective
- Add tests to `UiSurface`
- Add missing asserts in `_assert_send_sync_ui_surface_impl_safe`
- Add missing Debug field print for `camera_entity_to_taffy`
## Solution
- Adds tests to `UiSurface`
- Adds missing asserts in `_assert_send_sync_ui_surface_impl_safe`
- Adds missing impl Debug field print for `camera_entity_to_taffy`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Fixes#15897
## Solution
- Despawn light view entities when they go unused or when the
corresponding view is not alive.
## Testing
- `scene_viewer` example no longer prints "The preprocessing index
buffer wasn't present" warning
- modified an example to try toggling shadows for all kinds of light:
https://gist.github.com/akimakinai/ddb0357191f5052b654370699d2314cf
# Objective
Ensure that components that are conditionally extracted do not linger in
the render world when not extracted from the main world.
## Solution
If the `ExtractComponent` returns `None`, we'll remove the render world
component. I think this is the most sensible behavior here. In the
future if there really is a use case for keeping the previous render
component around, we could add a `Option<Self::Out>` parameter for the
previous render component to the method, or something similar. I think
that this follows the principle of least surprise here relative to what
`None` would suggest and the way that render nodes are typically
written. The alternative would be to add an `enabled` field to pretty
much every camera settings component, or duplicate the extraction
condition as #15856 does.
## Testing
`transmission` no longer crashes.
## Migration Guide
Components that implement `ExtractComponent` and return `None` will
cause the extracted component to be removed from the render world.
# Objective
Currently, is is very painful to wait for an asset to load from the
context of an `async` task. While bevy's `AssetServer` is asynchronous
at its core, the public API is mainly focused on being used from
synchronous contexts such as bevy systems. Currently, the best way of
waiting for an asset handle to finish loading is to have a system that
runs every frame, and either listens for `AssetEvents` or manually polls
the asset server. While this is an acceptable interface for bevy
systems, it is extremely awkward to do this in a way that integrates
well with the `async` task system. At my work we had to create our own
(inefficient) abstraction that encapsulated the boilerplate of checking
an asset's load status and waking up a task when it's done.
## Solution
Add the method `AssetServer::wait_for_asset`, which returns a future
that suspends until the asset associated with a given `Handle` either
finishes loading or fails to load.
## Testing
- CI
## Notes
This is an adoption of #14431, the above description is directly from
that original PR.
---------
Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
Co-authored-by: andriyDev <andriydzikh@gmail.com>
# Objective
Improve the average user's ability to understand what the heck is going
on with the Curve API.
## Solution
I wrote some docs. I doubt these are perfect; I'm probably far too close
to this for that to be the case. :)
# Objective
Benchmark overhead of validation for:
- `DynSystemParam`,
- `ParamSet`,
- combinator systems.
Needed for #15606
## Solution
As noted in objective, I've added 3 benchmarks, where each uses an
excessive amount of the specific functionality.
I benchmark on the level of schedules, rather than individual
`validate_param` calls, so we get a better idea how changes to the code
impact memory-lookup, etc. related side effects.
## Testing
```
param/combinator_system/8_piped_systems
time: [1.7560 µs 1.7865 µs 1.8180 µs]
change: [+4.5244% +6.7955% +9.1413%] (p = 0.00 < 0.05)
Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severe
param/combinator_system/8_dyn_params_system
time: [89.354 ns 89.790 ns 90.300 ns]
change: [+0.6751% +1.6825% +2.6842%] (p = 0.00 < 0.05)
Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
6 (6.00%) high mild
3 (3.00%) high severe
param/combinator_system/8_variant_param_set_system
time: [88.295 ns 89.202 ns 90.208 ns]
change: [+0.1320% +1.0060% +1.8482%] (p = 0.02 < 0.05)
Change within noise threshold.
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) high mild
```
2 back-to-back runs of the benchmarks, there is quire a lot of noise,
can use feedback on fixing that
# Objective
Fixes#15891
## Solution
Just remove the invalid triangle. I'm assuming that line of code was
originally copied from one that was drawing a quad.
## Testing
- `cargo run --example specialized_mesh_pipeline`
- hover over over the triangles
Tested on macos
# Objective
Cleanup naming and docs, add missing migration guide after #15591
All text root nodes now use `Text` (UI) / `Text2d`.
All text readers/writers use `Text<Type>Reader`/`Text<Type>Writer`
convention.
---
## Migration Guide
Doubles as #15591 migration guide.
Text bundles (`TextBundle` and `Text2dBundle`) were removed in favor of
`Text` and `Text2d`.
Shared configuration fields were replaced with `TextLayout`, `TextFont`
and `TextColor` components.
Just `TextBundle`'s additional field turned into `TextNodeFlags`
component,
while `Text2dBundle`'s additional fields turned into `TextBounds` and
`Anchor` components.
Text sections were removed in favor of hierarchy-based approach.
For root text entities with `Text` or `Text2d` components, child
entities with `TextSpan` will act as additional text sections.
To still access text spans by index, use the new `TextUiReader`,
`Text2dReader` and `TextUiWriter`, `Text2dWriter` system parameters.
# Objective
This is a follow-up to #15650. While the core `Image` stuff moved from
`bevy_render` to `bevy_image`, the `ImageLoader` and the
`CompressedImageSaver` remained in `bevy_render`.
## Solution
I moved `ImageLoader` and `CompressedImageSaver` to `bevy_image` and
re-exported everything out from `bevy_render`. The second step isn't
strictly necessary, but `bevy_render` is already doing this for all the
other `bevy_image` types, so I kept it the same for consistency.
Unfortunately I had to give `ImageLoader` a constructor so I can keep
the `RenderDevice` stuff in `bevy_render`.
## Testing
It compiles!
## Migration Guide
- `ImageLoader` can no longer be initialized directly through
`init_asset_loader`. Now you must use
`app.register_asset_loader(ImageLoader::new(supported_compressed_formats))`
(check out the implementation of `bevy_render::ImagePlugin`). This only
affects you if you are initializing the loader manually and does not
affect users of `bevy_render::ImagePlugin`.
## Followup work
- We should be able to move most of the `ImagePlugin` to `bevy_image`.
This would likely require an `ImagePlugin` and a `RenderImagePlugin` or
something though.
# Objective
- Closes#14774
## Solution
Added:
```rust
impl<'w, E, B: Bundle> Trigger<'w, E, B> {
pub fn components(&self) -> &[ComponentId];
}
```
I went with storing it in the trigger as a `SmallVec<[Component; 1]>`
because a singular target component will be the most common case, and it
remains the same size as `Vec<ComponentId>`.
## Testing
Added a test.
# Objective
Change UI clipping to respect borders and padding.
Fixes#15335
## Solution
Based on #15163
1. Add a `padding` field to `Node`.
2. In `ui_layout_size` copy the padding values from taffy to
`Node::padding`.
4. Determine the node's content box (The innermost part of the node
excluding the padding and border).
5. In `update_clipping` perform the clipping intersection with the
node's content box.
## Notes
* `Rect` probably needs some helper methods for working with insets but
because `Rect` and `BorderRect` are in different crates it's awkward to
add them. Left for a follow up.
* We could have another `Overflow` variant (probably called
`Overflow::Hidden`) to that clips inside of the border box instead of
the content box. Left it out here as I'm not certain about the naming or
behaviour though. If this PR is adopted, it would be trivial to add a
`Hidden` variant in a follow up.
* Depending on UI scaling there are sometimes gaps in the layout:
<img width="532" alt="rounding-bug"
src="https://github.com/user-attachments/assets/cc29aa0d-44fe-403f-8f0e-cd28a8b1d1b3">
This is caused by existing bugs in `ui_layout_system`'s coordinates
rounding and not anything to do with the changes in this PR.
## Testing
This PR also changes the `overflow` example to display borders on the
overflow nodes so you can see how this works:
#### main (The image is clipped at the edges of the node, overwriting
the border).
<img width="722" alt="main_overflow"
src="https://github.com/user-attachments/assets/eb316cd0-fff8-46ee-b481-e0cd6bab3f5c">
#### this PR (The image is clipped at the edges of the node's border).
<img width="711" alt="content-box-clip"
src="https://github.com/user-attachments/assets/fb302e56-9302-47b9-9a29-ec3e15fe9a9f">
## Migration Guide
Migration guide is on #15561
---------
Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
# Objective
- Used the wrong variable to set metadata
- new fixes after https://github.com/bevyengine/bevy/pull/15911
## Solution
- Use the right one
- Also keep a reference to the original PR when there's one
# Objective
Another clippy-lint fix: the goal is so that `ci lints` actually
displays the problems that a contributor caused, and not a bunch of
existing stuff in the repo. (when run on nightly)
## Solution
This fixes all but the `clippy::needless_lifetimes` lint, which will
result in substantially more fixes and be in other PR(s). I also
explicitly allow `non_local_definitions` since it is [not working
correctly, but will be
fixed](https://github.com/rust-lang/rust/issues/131643).
A few things were manually fixed: for example, some places had an
explicitly defined `div_ceil` function that was used, which is no longer
needed since this function is stable on unsigned integers. Also, empty
lines in doc comments were handled individually.
## Testing
I ran `cargo clippy --workspace --all-targets --all-features --fix
--allow-staged` with the `clippy::needless_lifetimes` lint marked as
`allow` in `Cargo.toml` to avoid fixing that too. It now passes with all
but the listed lint.
# Objective
- After merging #13248 the new upload job fails
## Solution
- Fix the file path
- Instead of a pull_request_target workflow, keep the examples in the
pull_request workflow and add another job that will run once its all
completed on a `workflow_run` event to upload screenshots
## Testing
- Tested in a ubuntu docker container, running the exact same script
- Manual result:
https://pixel-eagle.com/project/B04F67C0-C054-4A6F-92EC-F599FEC2FD1D/run/5/compare/2
- The CI on this job will still fail as its using the job from main
Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.25.0 to
1.26.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.26.0</h2>
<h2>[1.26.0] - 2024-10-07</h2>
<h3>Compatibility</h3>
<ul>
<li><em>(pre-commit)</em> Requires 3.2+</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><em>(pre-commit)</em> Resolve deprecations in 4.0 about deprecated
stage names</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h2>[1.26.0] - 2024-10-07</h2>
<h3>Compatibility</h3>
<ul>
<li><em>(pre-commit)</em> Requires 3.2+</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><em>(pre-commit)</em> Resolve deprecations in 4.0 about deprecated
stage names</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6802cc60d4"><code>6802cc6</code></a>
chore: Release</li>
<li><a
href="caa55026ae"><code>caa5502</code></a>
docs: Update changelog</li>
<li><a
href="2114c19241"><code>2114c19</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1114">#1114</a>
from tobiasraabe/patch-1</li>
<li><a
href="9de7b2c6be"><code>9de7b2c</code></a>
Updates stage names in <code>.pre-commit-hooks.yaml</code>.</li>
<li><a
href="14f49f455c"><code>14f49f4</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1105">#1105</a>
from crate-ci/renovate/unicode-width-0.x</li>
<li><a
href="58ffa4baef"><code>58ffa4b</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1108">#1108</a>
from crate-ci/renovate/stable-1.x</li>
<li><a
href="003cb76937"><code>003cb76</code></a>
chore(deps): Update dependency STABLE to v1.81.0</li>
<li><a
href="bc00184a23"><code>bc00184</code></a>
chore(deps): Update Rust crate unicode-width to 0.2.0</li>
<li>See full diff in <a
href="https://github.com/crate-ci/typos/compare/v1.25.0...v1.26.0">compare
view</a></li>
</ul>
</details>
<br />
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crate-ci/typos&package-manager=github_actions&previous-version=1.25.0&new-version=1.26.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Objective
- Compare screenshots for a few examples between PRs and main
## Solution
- Send screenshots taken to a screenshot comparison service
- Not completely sure every thing will work at once, but it shouldn't
break anything at least
- it needs a secret to work, I'll add it if enough people agree with
this PR
- this PR doesn't change anything on the screenshot selection (load_gltf
and breakout currently), this will need rendering folks input and can
happen later
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Android doesn't receive lifecycle event `Suspended` before suspension
## Solution
- Fix update triggering just after state change on android
## Testing
- Tested on the android emulator
# Objective
Fixes#15847
Alternative to #15862. Would appreciate a rendering person signaling
preference for one or the other.
## Solution
Partially revert the changes made to this example in #15524.
Add comment explaining that the non-usage of the built-in color vertex
attribute is intentional.
## Testing
`cargo run --example mesh2d_manual`
# Objective
The type `AssetLoadError` has `PartialEq` and `Eq` impls, which is
problematic due to the fact that the `AssetLoaderError` and
`AddAsyncError` variants lie in their impls: they will return `true` for
any `Box<dyn Error>` with the same `TypeId`, even if the actual value is
different. This can lead to subtle bugs if a user relies on the equality
comparison to ensure that two values are equal.
The same is true for `DependencyLoadState`,
`RecursiveDependencyLoadState`.
More generally, it is an anti-pattern for large error types involving
dynamic dispatch, such as `AssetLoadError`, to have equality
comparisons. Directly comparing two errors for equality is usually not
desired -- if some logic needs to branch based on the value of an error,
it is usually more correct to check for specific variants and inspect
their fields.
As far as I can tell, the only reason these errors have equality
comparisons is because the `LoadState` enum wraps `AssetLoadError` for
its `Failed` variant. This equality comparison is only used to check for
`== LoadState::Loaded`, which we can easily replace with an `is_loaded`
method.
## Solution
Remove the `{Partial}Eq` impls from `LoadState`, which also allows us to
remove it from the error types.
## Migration Guide
The types `bevy_asset::AssetLoadError` and `bevy_asset::LoadState` no
longer support equality comparisons. If you need to check for an asset's
load state, consider checking for a specific variant using
`LoadState::is_loaded` or the `matches!` macro. Similarly, consider
using the `matches!` macro to check for specific variants of the
`AssetLoadError` type if you need to inspect the value of an asset load
error in your code.
`DependencyLoadState` and `RecursiveDependencyLoadState` are not
released yet, so no migration needed,
---------
Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
# Objective
#15320 is a particularly painful breaking change, and the new
`RenderEntity` in particular is very noisy, with a lot of `let entity =
entity.id()` spam.
## Solution
Implement `WorldQuery`, `QueryData` and `ReadOnlyQueryData` for
`RenderEntity` and `WorldEntity`.
These work the same as the `Entity` impls from a user-facing
perspective: they simply return an owned (copied) `Entity` identifier.
This dramatically reduces noise and eases migration.
Under the hood, these impls defer to the implementations for `&T` for
everything other than the "call .id() for the user" bit, as they involve
read-only access to component data. Doing it this way (as opposed to
implementing a custom fetch, as tried in the first commit) dramatically
reduces the maintenance risk of complex unsafe code outside of
`bevy_ecs`.
To make this easier (and encourage users to do this themselves!), I've
made `ReadFetch` and `WriteFetch` slightly more public: they're no
longer `doc(hidden)`. This is a good change, since trying to vendor the
logic is much worse than just deferring to the existing tested impls.
## Testing
I've run a handful of rendering examples (breakout, alien_cake_addict,
auto_exposure, fog_volumes, box_shadow) and nothing broke.
## Follow-up
We should lint for the uses of `&RenderEntity` and `&MainEntity` in
queries: this is just less nice for no reason.
---------
Co-authored-by: Trashtalk217 <trashtalk217@gmail.com>
# Objective
- closes#15866
## Solution
- Simply migrate where possible.
## Testing
- Expect that CI will do most of the work. Examples is another way of
testing this, as most of the work is in that area.
---
## Notes
For now, this PR doesn't migrate `QueryState::single` and friends as for
now, this look like another issue. So for example, QueryBuilders that
used single or `World::query` that used single wasn't migrated. If there
is a easy way to migrate those, please let me know.
Most of the uses of `Query::single` were removed, the only other uses
that I found was related to tests of said methods, so will probably be
removed when we remove `Query::single`.
# Objective
`insert_or_spawn_batch` exists, but a version for just inserting doesn't
- Closes#2693
- Closes#8384
- Adopts/supersedes #8600
## Solution
Add `insert_batch`, along with the most common `insert` variations:
- `World::insert_batch`
- `World::insert_batch_if_new`
- `World::try_insert_batch`
- `World::try_insert_batch_if_new`
- `Commands::insert_batch`
- `Commands::insert_batch_if_new`
- `Commands::try_insert_batch`
- `Commands::try_insert_batch_if_new`
## Testing
Added tests, and added a benchmark for `insert_batch`.
Performance is slightly better than `insert_or_spawn_batch` when only
inserting:
![Code_HPnUN0QeWe](https://github.com/user-attachments/assets/53091e4f-6518-43f4-a63f-ae57d5470c66)
<details>
<summary>old benchmark</summary>
This was before reworking it to remove the `UnsafeWorldCell`:
![Code_QhXJb8sjlJ](https://github.com/user-attachments/assets/1061e2a7-a521-48e1-a799-1b6b8d1c0b93)
</details>
---
## Showcase
Usage is the same as `insert_or_spawn_batch`:
```
use bevy_ecs::{entity::Entity, world::World, component::Component};
#[derive(Component)]
struct A(&'static str);
#[derive(Component, PartialEq, Debug)]
struct B(f32);
let mut world = World::new();
let entity_a = world.spawn_empty().id();
let entity_b = world.spawn_empty().id();
world.insert_batch([
(entity_a, (A("a"), B(0.0))),
(entity_b, (A("b"), B(1.0))),
]);
assert_eq!(world.get::<B>(entity_a), Some(&B(0.0)));
```
# Objective
- Required components replace bundles, but `SpatialBundle` is yet to be
deprecated
## Solution
- Deprecate `SpatialBundle`
- Insert `Transform` and `Visibility` instead in examples using it
- In `spawn` or `insert` inserting a default `Transform` or `Visibility`
with component already requiring either, remove those components from
the tuple
## Testing
- Did you test these changes? If so, how?
Yes, I ran the examples I changed and tests
- Are there any parts that need more testing?
The `gamepad_viewer` and and `custom_shader_instancing` examples don't
work as intended due to entirely unrelated code, didn't check main.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
Run examples, or just check that all spawned values are identical
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
Linux, wayland trough x11 (cause that's the default feature)
---
## Migration Guide
`SpatialBundle` is now deprecated, insert `Transform` and `Visibility`
instead which will automatically insert all other components that were
in the bundle. If you do not specify these values and any other
components in your `spawn`/`insert` call already requires either of
these components you can leave that one out.
before:
```rust
commands.spawn(SpatialBundle::default());
```
after:
```rust
commands.spawn((Transform::default(), Visibility::default());
```
# Objective
Fixes#15515
## Solution
I went for the simplest solution because "format" in
`shader_format_spirv` didn't sound directly related.
## Testing
The command `cargo b -p bevy --no-default-features -F
spirv_shader_passthrough,x11` failed before, but works now.
# Objective
With the warning removed in
https://github.com/bevyengine/bevy/pull/15736, the rules for the UI tree
changes.
We no longer need to traverse non `Node`/`GhostNode` entities.
## Solution
- Added a filter `Or<(With<Node>, With<GhostNode>)>` to the child
traversal query so we don't unnecessarily traverse nodes that are not
part of the UI tree (like text nodes).
- Also moved the warning for NoUI->UI entities so it is actually
triggered (see comments)
## Testing
- Ran unit tests (still passing)
- Ran the ghost_nodes and ui examples, still works and looks fine 👍
- Tested the warning by spawning a Node under an empty entity.
---
---------
Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
# Objective
Closes#15545.
`bevy_picking` supports UI and sprite picking, but not mesh picking.
Being able to pick meshes would be extremely useful for various games,
tools, and our own examples, as well as scene editors and inspectors.
So, we need a mesh picking backend!
Luckily,
[`bevy_mod_picking`](https://github.com/aevyrie/bevy_mod_picking) (which
`bevy_picking` is based on) by @aevyrie already has a [backend for
it](74f0c3c0fb/backends/bevy_picking_raycast/src/lib.rs)
using [`bevy_mod_raycast`](https://github.com/aevyrie/bevy_mod_raycast).
As a side product of adding mesh picking, we also get support for
performing ray casts on meshes!
## Solution
Upstream a large chunk of the immediate-mode ray casting functionality
from `bevy_mod_raycast`, and add a mesh picking backend based on
`bevy_mod_picking`. Huge thanks to @aevyrie who did all the hard work on
these incredible crates!
All meshes are pickable by default. Picking can be disabled for
individual entities by adding `PickingBehavior::IGNORE`, like normal.
Or, if you want mesh picking to be entirely opt-in, you can set
`MeshPickingBackendSettings::require_markers` to `true` and add a
`RayCastPickable` component to the desired camera and target entities.
You can also use the new `MeshRayCast` system parameter to cast rays
into the world manually:
```rust
fn ray_cast_system(mut ray_cast: MeshRayCast, foo_query: Query<(), With<Foo>>) {
let ray = Ray3d::new(Vec3::ZERO, Dir3::X);
// Only ray cast against entities with the `Foo` component.
let filter = |entity| foo_query.contains(entity);
// Never early-exit. Note that you can change behavior per-entity.
let early_exit_test = |_entity| false;
// Ignore the visibility of entities. This allows ray casting hidden entities.
let visibility = RayCastVisibility::Any;
let settings = RayCastSettings::default()
.with_filter(&filter)
.with_early_exit_test(&early_exit_test)
.with_visibility(visibility);
// Cast the ray with the settings, returning a list of intersections.
let hits = ray_cast.cast_ray(ray, &settings);
}
```
This is largely a direct port, but I did make several changes to match
our APIs better, remove things we don't need or that I think are
unnecessary, and do some general improvements to code quality and
documentation.
### Changes Relative to `bevy_mod_raycast` and `bevy_mod_picking`
- Every `Raycast` and "raycast" has been renamed to `RayCast` and "ray
cast" (similar reasoning as the "Naming" section in #15724)
- `Raycast` system param has been renamed to `MeshRayCast` to avoid
naming conflicts and to be explicit that it is not for colliders
- `RaycastBackend` has been renamed to `MeshPickingBackend`
- `RayCastVisibility` variants are now `Any`, `Visible`, and
`VisibleInView` instead of `Ignore`, `MustBeVisible`, and
`MustBeVisibleAndInView`
- `NoBackfaceCulling` has been renamed to `RayCastBackfaces`, to avoid
implying that it affects the rendering of backfaces for meshes (it
doesn't)
- `SimplifiedMesh` and `RayCastBackfaces` live near other ray casting
API types, not in their own 10 LoC module
- All intersection logic and types are in the same `intersections`
module, not split across several modules
- Some intersection types have been renamed to be clearer and more
consistent
- `IntersectionData` -> `RayMeshHit`
- `RayHit` -> `RayTriangleHit`
- General documentation and code quality improvements
### Removed / Not Ported
- Removed unused ray helpers and types, like `PrimitiveIntersection`
- Removed getters on intersection types, and made their properties
public
- There is no `2d` feature, and `Raycast::mesh_query` and
`Raycast::mesh2d_query` have been merged into `MeshRayCast::mesh_query`,
which handles both 2D and 3D
- I assume this existed previously because `Mesh2dHandle` used to be in
`bevy_sprite`. Now both the 2D and 3D mesh are in `bevy_render`.
- There is no `debug` feature or ray debug rendering
- There is no deferred API (`RaycastSource`)
- There is no `CursorRayPlugin` (the picking backend handles this)
### Note for Reviewers
In case it's helpful, the [first
commit](281638ef10)
here is essentially a one-to-one port. The rest of the commits are
primarily refactoring and cleaning things up in the ways listed earlier,
as well as changes to the module structure.
It may also be useful to compare the original [picking
backend](74f0c3c0fb/backends/bevy_picking_raycast/src/lib.rs)
and [`bevy_mod_raycast`](https://github.com/aevyrie/bevy_mod_raycast) to
this PR. Feel free to mention if there are any changes that I should
revert or something I should not include in this PR.
## Testing
I tested mesh picking and relevant components in some examples, for both
2D and 3D meshes, and added a new `mesh_picking` example. I also
~~stole~~ ported over the [ray-mesh intersection
benchmark](dbc5ef32fe/benches/ray_mesh_intersection.rs)
from `bevy_mod_raycast`.
---
## Showcase
Below is a version of the `2d_shapes` example modified to demonstrate 2D
mesh picking. This is not included in this PR.
https://github.com/user-attachments/assets/7742528c-8630-4c00-bacd-81576ac432bf
And below is the new `mesh_picking` example:
https://github.com/user-attachments/assets/b65c7a5a-fa3a-4c2d-8bbd-e7a2c772986e
There is also a really cool new `mesh_ray_cast` example ported over from
`bevy_mod_raycast`:
https://github.com/user-attachments/assets/3c5eb6c0-bd94-4fb0-bec6-8a85668a06c9
---------
Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Trent <2771466+tbillington@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
Currently text is recomputed unnecessarily on any changes to its color,
which is extremely expensive.
## Solution
Split up `TextStyle` into two separate components `TextFont` and
`TextColor`.
## Testing
I added this system to `many_buttons`:
```rust
fn set_text_colors_changed(mut colors: Query<&mut TextColor>) {
for mut text_color in colors.iter_mut() {
text_color.set_changed();
}
}
```
reports ~4fps on main, ~50fps with this PR.
## Migration Guide
`TextStyle` has been renamed to `TextFont` and its `color` field has
been moved to a separate component named `TextColor` which newtypes
`Color`.
# Objective
The previous `PhantomData` instances were written somewhat lazily, so
they were just things like `PhantomData<T>` for curves with an output
type of `T`. This looks innocuous, but it unnecessarily constrains
`Send/Sync` inference based on `T`. See
[here](https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns).
## Solution
Switch to `PhantomData` of the form `PhantomData<fn() -> T>` for most of
these adaptors. Since they only have a functional relationship to `T`
(i.e. it shows up in the return type of trait methods), this is more
accurate.
## Testing
Tested by compiling Bevy.
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- Fixes#15837
## Solution
- Change `Emitter` components to use `Stopwatch` to allow the time to be
tracked independently.
## Testing
- Changes were tested.
- Run either the `spatial_audio_2d` or `spatial_audio_3d` example to
test
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- Example validation job fails in CI
- This happened after GitHub updated the latest version of ubuntu from
the 22.04 to the 24.04
- The package libegl1-mesa is not available on ubuntu 24.04
## Solution
- Keep using ubuntu 22.04
- This is a temp fix and we should fix the update
## Testing
- if it can get merged then it works 🤷
# Objective
MacOS has some nice options for controlling the window and titlebar to
make the content appear much more "immersively" in the window. This PR
exposes options for controlling this.
## Solution
Adds new fields to `Window` to control these, with doc comments to
explain what they do and that they're MacOS only.
## Testing
Tested on a MacOS machine (not my own, I don't have one). That's where
the below screenshots were taken.
---
## Showcase
On MacOS, you now have more options for configuring the window titlebar.
You can, for example, make the title bar transparent and only show the
window controls. This provides a more "immersive" experience for your
rendered content.
Before, only this was possible:
<img width="1392" alt="image"
src="https://github.com/user-attachments/assets/abf03da2-d247-4202-a7e7-731c45d80d54">
Now, you can create windows like this:
<img width="1392" alt="image2"
src="https://github.com/user-attachments/assets/3239d0e3-4708-4798-8755-188541e14f93">
This uses the following `bevy_window::Window` settings:
```rs
fullsize_content_view: true,
titlebar_transparent: true,
titlebar_show_title: false,
```
## Migration Guide
`bevy_window::Window` now has extra fields for configuring MacOS window
settings:
```rs
pub movable_by_window_background: bool,
pub fullsize_content_view: bool,
pub has_shadow: bool,
pub titlebar_shown: bool,
pub titlebar_transparent: bool,
pub titlebar_show_title: bool,
pub titlebar_show_buttons: bool,
```
Using `Window::default` keeps the same behaviour as before.
# Objective
Animation docs could use some clarification regarding:
- how exactly curves are evaluated
- how additive blend nodes actually work
## Solution
Add some documentation that explains how curve domains are used and how
additive blend nodes treat their children.
## Commentary
The way additive blend nodes work right now is a little bit weird, since
their first child's weight is ignored. Arguably this makes sense, since
additive animations are authored differently from ordinary animations,
but it also feels a bit strange. We could make the first node's weight
actually be applied, and the present behavior would be recovered when
the weight is set to 1.
The main disadvantage of how things are set up now is that combining a
bunch of additive animations without a base pose is pretty awkward (e.g.
to add them onto a base pose later in the graph). If we changed it, the
main downside would be that reusing the same animation on different
parts of the graph is harder; on the other hand, the weights can be
locally reassigned by using blend nodes with no other children, which
rectifies this shortfall.
# Objective
Fixes#15832
## Solution
It seems that this was just a transliteration mistake during #15591.
Update the correct text span index.
## Testing
I tested on macos with:
`cargo run --example gamepad_viewer`
- without gamepad connected
- with gamepad connected
- disconnecting and reconnecting gamepad while running
# Objective
The `minimising` example is a bit annoying to run locally, because it
attempts to minimize the window every frame, so un-minimizing it is
difficult.
## Solution
Only minimize once.
The contents of the example can now be inspected, and the window easily
closed after the minimization happens.
## Testing
`cargo run --example minimising`
I tested on macos only.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Fixes a mistake in the migration done in #15591.
## Solution
Restore a line of instructions that was accidentally dropped.
## Testing
`cargo run --example motion_blur`
Tested that instructions make sense and text updates correctly when keys
are pressed.
# Objective
This example uses `println` from a system, which we don't advise people
do. It also gives no context for the debug prints, which I assumed to be
stray debug code at first.
## Solution
Use `info!`, and add a small amount of context so the console output
looks deliberate.
## Testing
`cargo run --example morph_targets`
# Objective
- Fixes#15840
## Solution
Added a new subcommand to the CI tool, `compile-check-no-std`, which
will attempt to compile each `no_std` crate in Bevy with the appropriate
features (no-defaults, `libm`, etc.) for `x86_64-unknown-none`. The
exact target chosen could be changed to any reasonable platform which
does not include the `std` library.
The currently tested crates are:
- `bevy_ptr`
- `bevy_utils`
- `bevy_mikktspace`
As more crates have `no_std` support added, they _should_ be added to
this CI command. Once Bevy itself can be `no_std`, the individual checks
can be replaced with just checking Bevy, since it will transiently check
all other crates as appropriate.
## Testing
- Ran CI. From a clean target directory (`cargo clean`), these new
checks take approximately 10 seconds total.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
On mobile devices, it's best to use the OS's native logging due to the
difficulty of accessing the console. This is already done for Android.
This is an updated version of
https://github.com/bevyengine/bevy/pull/4462.
## Solution
This PR uses Absolucy's
[tracing-oslog](https://github.com/Absolucy/tracing-oslog) ([ZLib
license](https://github.com/Absolucy/tracing-oslog/blob/main/LICENSE.md))
for iOS in order to use Apple's `os_log`.
## Testing
I ran `examples/mobile` with the logging from `examples/app/logs.rs` on
an iOS device, I then checked the logs could be filtered in the MacOS
Console.app.
## Changelog
- Change bevy_log to use Apple's os_log on iOS.
## Questions for Reviewers
It's worth noting that the dependency this adds hasn't had bug fixes
released in a few years, so we may want to consider one or more of:
1. a feature flag to opt-in, and it would also allow `os_log` on MacOS
2. merge as-is and have some (minor?) upstream bugs
3. hold off on this PR until a suitable alternative dependency arises
4. maintain our own implementation
## Future work
In a follow-up PR it might be good to make the `subsystem` field have a
better default value, like [this
one](https://github.com/bevyengine/bevy/blob/main/examples/mobile/bevy_mobile_example.xcodeproj/project.pbxproj#L363).
That value can be retrieved programmatically if we bind another system
API (For posterity in Swift this is `Bundle.main.bundleIdentifier`, but
the C/ObjC equivalent is likely easier to bind). This would almost
always be the correct value, while the current default is unlikely to
ever be correct.
---------
Co-authored-by: Dusty DeWeese <dustin.deweese@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
Since #15641, `loading_screen` panics.
```
called `Result::unwrap()` on an `Err` value: MultipleEntities("bevy_ecs::query::state::QueryState<&mut bevy_render::view::visibility::Visibility, bevy_ecs::query::filter::With<loading_screen::LoadingScreen>>")
```
Before that PR, the camera did not have a `Visibility` component. But
`Visibility` is now a required component of `Camera`. So the query
matches multiple entities.
## Solution
Minimal change to make the example behave like it used to.
Plus a tiny drive-by cleanup to remove a redundant unwrap.
## Testing
`cargo run --example loading_screen`
# Objective
Oftentimes, users will store an entity on a component or resource. To
make this component/resource `Default`-able, they might initialize it
with `Entity::PLACEHOLDER`. This is sometimes done to avoid the need for
an `Option<Entity>`, especially if it complicates other logic.
For example, it's used in this `Selection` resource to denote "no
selection":
```rust
#[derive(Resource, Debug)]
struct Selection(Entity);
impl Default for Selection {
fn default() -> Self {
Self(Entity::PLACEHOLDER)
}
}
```
The problem is that if we try to `Debug` the current `Selection`, we get
back: `4294967295v1#8589934591`. It's not immediately obvious whether or
not the entity is an actual entity or the placeholder.
Now while it doesn't take long to realize that this is in fact just the
value of `Entity::PLACEHOLDER`, it would be a lot clearer if this was
made explicit, especially for these particular use cases.
## Solution
This PR makes the `Debug` and `Display` impls for `Entity` return
`PLACEHOLDER` for the `Entity::PLACEHOLDER` constant.
~~Feel free to bikeshed the actual value returned here. I think
`PLACEHOLDER` on its own could work too.~~ Swapped to `PLACEHOLDER` from
`Entity::PLACEHOLDER`.
## Testing
You can test locally by running:
```
cargo test --package bevy_ecs
```
---
## Migration Guide
The `Debug` and `Display` impls for `Entity` now return `PLACEHOLDER`
for the `Entity::PLACEHOLDER` constant. If you had any code relying on
these values, you may need to account for this change.
# Objective
- Immediate mode gizmos don't have a main world entity but the phase
items require `MainEntity` since #15756
## Solution
- Add a dummy `MainEntity` component.
## Testing
Both the `3d_gizmos` and `2d_gizmos` examples show gizmos again
# Objective
The other `Curve -> AnimationCurve` wrappers allow public access to the
inner curve, so this one should as well.
## Solution
Made the field public. Instances will still need to be constructed using
the (more ergonomic) `from_curve` method, which infers the phantom type
for the user.