Commit graph

1992 commits

Author SHA1 Message Date
Charles Bournhonesque
8c6d9b8103
Add support for updating the tracing subscriber in LogPlugin (#10822)
# Objective

This PR is heavily inspired by
https://github.com/bevyengine/bevy/pull/7682
It aims to solve the same problem: allowing the user to extend the
tracing subscriber with extra layers.

(in my case, I'd like to use `use
metrics_tracing_context::{MetricsLayer, TracingContextLayer};`)


## Solution

I'm proposing a different api where the user has the opportunity to take
the existing `subscriber` and apply any transformations on it.

---

## Changelog

- Added a `update_subscriber` option on the `LogPlugin` that lets the
user modify the `subscriber` (for example to extend it with more tracing
`Layers`


## Migration Guide

> This section is optional. If there are no breaking changes, you can
delete this section.

- Added a new field `update_subscriber` in the `LogPlugin`

---------

Co-authored-by: Charles Bournhonesque <cbournhonesque@snapchat.com>
2024-01-15 15:26:13 +00:00
MiniaczQ
ec5b9eeba7
Extract examples CameraController into a module (#11338)
# Objective

Unify flycam-style camera controller from the examples.

`parallax_mapping` controller was kept as is.

## Solution

Fixed some mouse movement & cursor grabbing related issues too.
2024-01-14 13:50:33 +00:00
Ixentus
e2fd63104d
Simplify conditions (#11316)
# Objective

- Conditions don't have to be closures unless they have state or mutate.

## Solution

- Simplify conditions when possible.

---

## Changelog

The following run conditions are now regular systems:
- resource_exists<T>
- resource_added<T>
- resource_changed<T>
- resource_exists_and_changed<T>
- state_exists<S: States>
- state_changed<S: States>
- any_with_component<T: Component>

## Migration Guide

- resource_exists<T>() -> resource_exists<T>
- resource_added<T>() -> resource_added<T>
- resource_changed<T>() -> resource_changed<T>
- resource_exists_and_changed<T>() -> resource_exists_and_changed<T>
- state_exists<S: States>() -> state_exists<S: States>
- state_changed<S: States>() -> state_changed<S: States>
- any_with_component<T: Component>() -> any_with_component<T: Component>
2024-01-13 13:22:17 +00:00
François
3d996639a0
Revert "Implement minimal reflection probes. (#10057)" (#11307)
# Objective

- Fix working on macOS, iOS, Android on main 
- Fixes #11281 
- Fixes #11282 
- Fixes #11283 
- Fixes #11299

## Solution

- Revert #10057
2024-01-12 20:41:51 +00:00
A. Gadjev
ce5bae55f6
Fixed typo in generate_custom_mesh.rs example (#11293)
# Objective

- Fix a typo in the "Generate Custom Mesh" example

## Solution

- Fixed small typo
2024-01-11 11:29:31 +00:00
Stepan Koltsov
06bf928927
Option to enable deterministic rendering (#11248)
# Objective

Issue #10243: rendering multiple triangles in the same place results in
flickering.

## Solution

Considered these alternatives:
- `depth_bias` may not work, because of high number of entities, so
creating a material per entity is practically not possible
- rendering at slightly different positions does not work, because when
camera is far, float rounding causes the same issues (edit: assuming we
have to use the same `depth_bias`)
- considered implementing deterministic operation like
`query.par_iter().flat_map(...).collect()` to be used in
`check_visibility` system (which would solve the issue since query is
deterministic), and could not figure out how to make it as cheap as
current approach with thread-local collectors (#11249)

So adding an option to sort entities after `check_visibility` system
run.

Should not be too bad, because after visibility check, only a handful
entities remain.

This is probably not the only source of non-determinism in Bevy, but
this is one I could find so far. At least it fixes the repro example.

## Changelog

- `DeterministicRenderingConfig` option to enable deterministic
rendering

## Test

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/28969/c735bce1-3a71-44cd-8677-c19f6c0ee6bd">

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-01-09 00:46:01 +00:00
Rob Parrett
9c972f037e
Fix missed explicit conversions in examples (#11261)
# Objective

A few of these were missed in #10878

## Solution

Fix em
2024-01-09 00:44:24 +00:00
irate
ec14e946b8
Update glam, encase and hexasphere (#11082)
Update to `glam` 0.25, `encase` 0.7 and `hexasphere` to 10.0

## Changelog
Added the `FloatExt` trait to the `bevy_math` prelude which adds `lerp`,
`inverse_lerp` and `remap` methods to the `f32` and `f64` types.
2024-01-08 22:58:45 +00:00
Stepan Koltsov
42e990861c
Remove apply_deferred example (#11142)
# Objective

Re this comment:
https://github.com/bevyengine/bevy/pull/11141#issuecomment-1872455313

Since https://github.com/bevyengine/bevy/pull/9822, Bevy automatically
inserts `apply_deferred` between systems with dependencies where needed,
so manually inserted `apply_deferred` doesn't to anything useful, and in
current state this example does more harm than good.

## Solution

The example can be modified with removal of automatic `apply_deferred`
insertion, but that would immediately upgrade this example from beginner
level, to upper intermediate. Most users don't need to disable automatic
sync point insertion, and remaining few who do probably already know how
it works.

CC @hymm
2024-01-08 22:34:32 +00:00
Connor King
1260b7bcf1
StateTransitionEvent (#11089)
# Objective

- Make it possible to react to arbitrary state changes
- this will be useful regardless of the other changes to states
currently being discussed

## Solution

- added `StateTransitionEvent<S>` struct
- previously, this would have been impossible:

```rs
#[derive(States, Eq, PartialEq, Hash, Copy, Clone, Default)]
enum MyState {
  #[default]
  Foo,
  Bar(MySubState),
}

enum MySubState {
  Spam,
  Eggs,
}

app.add_system(Update, on_enter_bar);

fn on_enter_bar(trans: EventReader<StateTransition<MyState>>){
  for (befoare, after) in trans.read() {
    match before, after {
      MyState::Foo, MyState::Bar(_) => info!("detected transition foo => bar");
      _, _ => ();
    }
  }
}
```

---

## Changelog

- Added
  - `StateTransitionEvent<S>` - Fired on state changes of `S`

## Migration Guide

N/A no breaking changes

---------

Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
2024-01-08 22:27:00 +00:00
Joona Aalto
a795de30b4
Use impl Into<A> for Assets::add (#10878)
# Motivation

When spawning entities into a scene, it is very common to create assets
like meshes and materials and to add them via asset handles. A common
setup might look like this:

```rust
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn(PbrBundle {
        mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
        material: materials.add(StandardMaterial::from(Color::RED)),
        ..default()
    });
}
```

Let's take a closer look at the part that adds the assets using `add`.

```rust
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(StandardMaterial::from(Color::RED)),
```

Here, "mesh" and "material" are both repeated three times. It's very
explicit, but I find it to be a bit verbose. In addition to being more
code to read and write, the extra characters can sometimes also lead to
the code being formatted to span multiple lines even though the core
task, adding e.g. a primitive mesh, is extremely simple.

A way to address this is by using `.into()`:

```rust
mesh: meshes.add(shape::Cube { size: 1.0 }.into()),
material: materials.add(Color::RED.into()),
```

This is fine, but from the names and the type of `meshes`, we already
know what the type should be. It's very clear that `Cube` should be
turned into a `Mesh` because of the context it's used in. `.into()` is
just seven characters, but it's so common that it quickly adds up and
gets annoying.

It would be nice if you could skip all of the conversion and let Bevy
handle it for you:

```rust
mesh: meshes.add(shape::Cube { size: 1.0 }),
material: materials.add(Color::RED),
```

# Objective

Make adding assets more ergonomic by making `Assets::add` take an `impl
Into<A>` instead of `A`.

## Solution

`Assets::add` now takes an `impl Into<A>` instead of `A`, so e.g. this
works:

```rust
    commands.spawn(PbrBundle {
        mesh: meshes.add(shape::Cube { size: 1.0 }),
        material: materials.add(Color::RED),
        ..default()
    });
```

I also changed all examples to use this API, which increases consistency
as well because `Mesh::from` and `into` were being used arbitrarily even
in the same file. This also gets rid of some lines of code because
formatting is nicer.

---

## Changelog

- `Assets::add` now takes an `impl Into<A>` instead of `A`
- Examples don't use `T::from(K)` or `K.into()` when adding assets

## Migration Guide

Some `into` calls that worked previously might now be broken because of
the new trait bounds. You need to either remove `into` or perform the
conversion explicitly with `from`:

```rust
// Doesn't compile
let mesh_handle = meshes.add(shape::Cube { size: 1.0 }.into()),

// These compile
let mesh_handle = meshes.add(shape::Cube { size: 1.0 }),
let mesh_handle = meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
```

## Concerns

I believe the primary concerns might be:

1. Is this too implicit?
2. Does this increase codegen bloat?

Previously, the two APIs were using `into` or `from`, and now it's
"nothing" or `from`. You could argue that `into` is slightly more
explicit than "nothing" in cases like the earlier examples where a
`Color` gets converted to e.g. a `StandardMaterial`, but I personally
don't think `into` adds much value even in this case, and you could
still see the actual type from the asset type.

As for codegen bloat, I doubt it adds that much, but I'm not very
familiar with the details of codegen. I personally value the user-facing
code reduction and ergonomics improvements that these changes would
provide, but it might be worth checking the other effects in more
detail.

Another slight concern is migration pain; apps might have a ton of
`into` calls that would need to be removed, and it did take me a while
to do so for Bevy itself (maybe around 20-40 minutes). However, I think
the fact that there *are* so many `into` calls just highlights that the
API could be made nicer, and I'd gladly migrate my own projects for it.
2024-01-08 22:14:43 +00:00
Patrick Walton
54a943d232
Implement minimal reflection probes. (#10057)
# Objective

This pull request implements *reflection probes*, which generalize
environment maps to allow for multiple environment maps in the same
scene, each of which has an axis-aligned bounding box. This is a
standard feature of physically-based renderers and was inspired by [the
corresponding feature in Blender's Eevee renderer].

## Solution

This is a minimal implementation of reflection probes that allows
artists to define cuboid bounding regions associated with environment
maps. For every view, on every frame, a system builds up a list of the
nearest 4 reflection probes that are within the view's frustum and
supplies that list to the shader. The PBR fragment shader searches
through the list, finds the first containing reflection probe, and uses
it for indirect lighting, falling back to the view's environment map if
none is found. Both forward and deferred renderers are fully supported.

A reflection probe is an entity with a pair of components, *LightProbe*
and *EnvironmentMapLight* (as well as the standard *SpatialBundle*, to
position it in the world). The *LightProbe* component (along with the
*Transform*) defines the bounding region, while the
*EnvironmentMapLight* component specifies the associated diffuse and
specular cubemaps.

A frequent question is "why two components instead of just one?" The
advantages of this setup are:

1. It's readily extensible to other types of light probes, in particular
*irradiance volumes* (also known as ambient cubes or voxel global
illumination), which use the same approach of bounding cuboids. With a
single component that applies to both reflection probes and irradiance
volumes, we can share the logic that implements falloff and blending
between multiple light probes between both of those features.

2. It reduces duplication between the existing *EnvironmentMapLight* and
these new reflection probes. Systems can treat environment maps attached
to cameras the same way they treat environment maps applied to
reflection probes if they wish.

Internally, we gather up all environment maps in the scene and place
them in a cubemap array. At present, this means that all environment
maps must have the same size, mipmap count, and texture format. A
warning is emitted if this restriction is violated. We could potentially
relax this in the future as part of the automatic mipmap generation
work, which could easily do texture format conversion as part of its
preprocessing.

An easy way to generate reflection probe cubemaps is to bake them in
Blender and use the `export-blender-gi` tool that's part of the
[`bevy-baked-gi`] project. This tool takes a `.blend` file containing
baked cubemaps as input and exports cubemap images, pre-filtered with an
embedded fork of the [glTF IBL Sampler], alongside a corresponding
`.scn.ron` file that the scene spawner can use to recreate the
reflection probes.

Note that this is intentionally a minimal implementation, to aid
reviewability. Known issues are:

* Reflection probes are basically unsupported on WebGL 2, because WebGL
2 has no cubemap arrays. (Strictly speaking, you can have precisely one
reflection probe in the scene if you have no other cubemaps anywhere,
but this isn't very useful.)

* Reflection probes have no falloff, so reflections will abruptly change
when objects move from one bounding region to another.

* As mentioned before, all cubemaps in the world of a given type
(diffuse or specular) must have the same size, format, and mipmap count.

Future work includes:

* Blending between multiple reflection probes.

* A falloff/fade-out region so that reflected objects disappear
gradually instead of vanishing all at once.

* Irradiance volumes for voxel-based global illumination. This should
reuse much of the reflection probe logic, as they're both GI techniques
based on cuboid bounding regions.

* Support for WebGL 2, by breaking batches when reflection probes are
used.

These issues notwithstanding, I think it's best to land this with
roughly the current set of functionality, because this patch is useful
as is and adding everything above would make the pull request
significantly larger and harder to review.

---

## Changelog

### Added

* A new *LightProbe* component is available that specifies a bounding
region that an *EnvironmentMapLight* applies to. The combination of a
*LightProbe* and an *EnvironmentMapLight* offers *reflection probe*
functionality similar to that available in other engines.

[the corresponding feature in Blender's Eevee renderer]:
https://docs.blender.org/manual/en/latest/render/eevee/light_probes/reflection_cubemaps.html

[`bevy-baked-gi`]: https://github.com/pcwalton/bevy-baked-gi

[glTF IBL Sampler]: https://github.com/KhronosGroup/glTF-IBL-Sampler
2024-01-08 22:09:17 +00:00
Torstein Grindvik
99c43fabdf
Usability methods for RenderTargets and image handles (#10736)
# Objective

In my code I use a lot of images as render targets.
I'd like some convenience methods for working with this type.

## Solution

- Allow `.into()` to construct a `RenderTarget`
- Add `.as_image()` 

---

## Changelog

### Added

- `RenderTarget` can be constructed via `.into()` on a `Handle<Image>`
- `RenderTarget` new method: `as_image`

---------

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-01-04 17:01:04 +00:00
JMS55
44424391fe
Unload render assets from RAM (#10520)
# Objective
- No point in keeping Meshes/Images in RAM once they're going to be sent
to the GPU, and kept in VRAM. This saves a _significant_ amount of
memory (several GBs) on scenes like bistro.
- References
  - https://github.com/bevyengine/bevy/pull/1782
  - https://github.com/bevyengine/bevy/pull/8624 

## Solution
- Augment RenderAsset with the capability to unload the underlying asset
after extracting to the render world.
- Mesh/Image now have a cpu_persistent_access field. If this field is
RenderAssetPersistencePolicy::Unload, the asset will be unloaded from
Assets<T>.
- A new AssetEvent is sent upon dropping the last strong handle for the
asset, which signals to the RenderAsset to remove the GPU version of the
asset.

---

## Changelog
- Added `AssetEvent::NoLongerUsed` and
`AssetEvent::is_no_longer_used()`. This event is sent when the last
strong handle of an asset is dropped.
- Rewrote the API for `RenderAsset` to allow for unloading the asset
data from the CPU.
- Added `RenderAssetPersistencePolicy`.
- Added `Mesh::cpu_persistent_access` for memory savings when the asset
is not needed except for on the GPU.
- Added `Image::cpu_persistent_access` for memory savings when the asset
is not needed except for on the GPU.
- Added `ImageLoaderSettings::cpu_persistent_access`.
- Added `ExrTextureLoaderSettings`.
- Added `HdrTextureLoaderSettings`.

## Migration Guide
- Asset loaders (GLTF, etc) now load meshes and textures without
`cpu_persistent_access`. These assets will be removed from
`Assets<Mesh>` and `Assets<Image>` once `RenderAssets<Mesh>` and
`RenderAssets<Image>` contain the GPU versions of these assets, in order
to reduce memory usage. If you require access to the asset data from the
CPU in future frames after the GLTF asset has been loaded, modify all
dependent `Mesh` and `Image` assets and set `cpu_persistent_access` to
`RenderAssetPersistencePolicy::Keep`.
- `Mesh` now requires a new `cpu_persistent_access` field. Set it to
`RenderAssetPersistencePolicy::Keep` to mimic the previous behavior.
- `Image` now requires a new `cpu_persistent_access` field. Set it to
`RenderAssetPersistencePolicy::Keep` to mimic the previous behavior.
- `MorphTargetImage::new()` now requires a new `cpu_persistent_access`
parameter. Set it to `RenderAssetPersistencePolicy::Keep` to mimic the
previous behavior.
- `DynamicTextureAtlasBuilder::add_texture()` now requires that the
`TextureAtlas` you pass has an `Image` with `cpu_persistent_access:
RenderAssetPersistencePolicy::Keep`. Ensure you construct the image
properly for the texture atlas.
- The `RenderAsset` trait has significantly changed, and requires
adapting your existing implementations.
  - The trait now requires `Clone`.
- The `ExtractedAsset` associated type has been removed (the type itself
is now extracted).
  - The signature of `prepare_asset()` is slightly different
- A new `persistence_policy()` method is now required (return
RenderAssetPersistencePolicy::Unload to match the previous behavior).
- Match on the new `NoLongerUsed` variant for exhaustive matches of
`AssetEvent`.
2024-01-03 03:31:04 +00:00
Patrick Walton
dd14f3a477
Implement lightmaps. (#10231)
![Screenshot](https://i.imgur.com/A4KzWFq.png)

# Objective

Lightmaps, textures that store baked global illumination, have been a
mainstay of real-time graphics for decades. Bevy currently has no
support for them, so this pull request implements them.

## Solution

The new `Lightmap` component can be attached to any entity that contains
a `Handle<Mesh>` and a `StandardMaterial`. When present, it will be
applied in the PBR shader. Because multiple lightmaps are frequently
packed into atlases, each lightmap may have its own UV boundaries within
its texture. An `exposure` field is also provided, to control the
brightness of the lightmap.

Note that this PR doesn't provide any way to bake the lightmaps. That
can be done with [The Lightmapper] or another solution, such as Unity's
Bakery.

---

## Changelog

### Added
* A new component, `Lightmap`, is available, for baked global
illumination. If your mesh has a second UV channel (UV1), and you attach
this component to the entity with that mesh, Bevy will apply the texture
referenced in the lightmap.

[The Lightmapper]: https://github.com/Naxela/The_Lightmapper

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-01-02 20:38:47 +00:00
Stepan Koltsov
0f71dcbf1a
Simplify examples/3d/orthographic (#11045)
Current example may mislead into thinking both parameters are mandatory
to make orthographic projection work.
2024-01-02 19:27:22 +00:00
Stepan Koltsov
d8d8bcfb21
Add ability to panic to logs example (#11171)
# Objective

To debug issues like https://github.com/bevyengine/bevy/pull/11169.

## Solution

When P is pressed in logs example, call `panic!()`.

<img width="1392" alt="Screenshot 2024-01-02 at 01 10 16"
src="https://github.com/bevyengine/bevy/assets/28969/a788737e-d23c-43a3-bc68-d6c5b0ab88ad">
2024-01-02 03:02:56 +00:00
Doonv
189ceaf0d3
Replace or document ignored doctests (#11040)
# Objective

There are a lot of doctests that are `ignore`d for no documented reason.
And that should be fixed.

## Solution

I searched the bevy repo with the regex ` ```[a-z,]*ignore ` in order to
find all `ignore`d doctests. For each one of the `ignore`d doctests, I
did the following steps:
1. Attempt to remove the `ignored` attribute while still passing the
test. I did this by adding hidden dummy structs and imports.
2. If step 1 doesn't work, attempt to replace the `ignored` attribute
with the `no_run` attribute while still passing the test.
3. If step 2 doesn't work, keep the `ignored` attribute but add
documentation for why the `ignored` attribute was added.

---------

Co-authored-by: François <mockersf@gmail.com>
2024-01-01 16:50:56 +00:00
François
71adb77a2e
support all types of animation interpolation from gltf (#10755)
# Objective

- Support step and cubic spline interpolation from gltf

## Solution

- Support step and cubic spline interpolation from gltf

Tested with
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/InterpolationTest
expected: 

![](https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/InterpolationTest/screenshot/screenshot.gif)
result: 

![output](https://github.com/bevyengine/bevy/assets/8672791/e7f1afd5-20c9-4921-97d4-8d0c82203068)

---

## Migration Guide

When manually specifying an animation `VariableCurve`, the interpolation
type must be specified:

- Bevy 0.12
```rust
        VariableCurve {
            keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
            keyframes: Keyframes::Rotation(vec![
                Quat::IDENTITY,
                Quat::from_axis_angle(Vec3::Y, PI / 2.),
                Quat::from_axis_angle(Vec3::Y, PI / 2. * 2.),
                Quat::from_axis_angle(Vec3::Y, PI / 2. * 3.),
                Quat::IDENTITY,
            ]),
        },
```

- Bevy 0.13
```rust
        VariableCurve {
            keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
            keyframes: Keyframes::Rotation(vec![
                Quat::IDENTITY,
                Quat::from_axis_angle(Vec3::Y, PI / 2.),
                Quat::from_axis_angle(Vec3::Y, PI / 2. * 2.),
                Quat::from_axis_angle(Vec3::Y, PI / 2. * 3.),
                Quat::IDENTITY,
            ]),
            interpolation: Interpolation::Linear,
        },
```
2023-12-31 18:01:50 +00:00
JMS55
70b0eacc3b
Keep track of when a texture is first cleared (#10325)
# Objective
- Custom render passes, or future passes in the engine (such as
https://github.com/bevyengine/bevy/pull/10164) need a better way to know
and indicate to the core passes whether the view color/depth/prepass
attachments have been cleared or not yet this frame, to know if they
should clear it themselves or load it.

## Solution

- For all render targets (depth textures, shadow textures, prepass
textures, main textures) use an atomic bool to track whether or not each
texture has been cleared this frame. Abstracted away in the new
ColorAttachment and DepthAttachment wrappers.

---

## Changelog
- Changed `ViewTarget::get_color_attachment()`, removed arguments.
- Changed `ViewTarget::get_unsampled_color_attachment()`, removed
arguments.
- Removed `Camera3d::clear_color`.
- Removed `Camera2d::clear_color`.
- Added `Camera::clear_color`.
- Added `ExtractedCamera::clear_color`.
- Added `ColorAttachment` and `DepthAttachment` wrappers.
- Moved `ClearColor` and `ClearColorConfig` from
`bevy::core_pipeline::clear_color` to `bevy::render::camera`.
- Core render passes now track when a texture is first bound as an
attachment in order to decide whether to clear or load it.

## Migration Guide
- Remove arguments to `ViewTarget::get_color_attachment()` and
`ViewTarget::get_unsampled_color_attachment()`.
- Configure clear color on `Camera` instead of on `Camera3d` and
`Camera2d`.
- Moved `ClearColor` and `ClearColorConfig` from
`bevy::core_pipeline::clear_color` to `bevy::render::camera`.
- `ViewDepthTexture` must now be created via the `new()` method

---------

Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-12-31 00:37:37 +00:00
Mike
786abbf3f5
Fix ci xvfb (#11143)
# Objective

Fix ci hang, so we can merge pr's again.

## Solution

- switch ppa action to use mesa stable versions
https://launchpad.net/~kisak/+archive/ubuntu/turtle
- use commit from #11123

---------

Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
2023-12-30 09:07:31 +00:00
Nurzhan Sakén
8067e46049
Add example for pixel-perfect grid snapping in 2D (#8112)
# Objective

Provide an example of how to achieve pixel-perfect "grid snapping" in 2D
via rendering to a texture. This is a common use case in retro pixel art
game development.

## Solution

Render sprites to a canvas via a Camera, then use another (scaled up)
Camera to render the resulting canvas to the screen. This example is
based on the `3d/render_to_texture.rs` example. Furthermore, this
example demonstrates mixing retro-style graphics with high-resolution
graphics, as well as pixel-snapped rendering of a
`MaterialMesh2dBundle`.
2023-12-26 17:15:50 +00:00
Tygyh
1568d4a415
Reorder impl to be the same as the trait (#11076)
# Objective

- Make the implementation order consistent between all sources to fit
the order in the trait.

## Solution

- Change the implementation order.
2023-12-24 17:43:55 +00:00
Tygyh
7b8305e5b4
Remove unnecessary parens (#11075)
# Objective

- Increase readability.

## Solution

- Remove unnecessary parens.
2023-12-24 17:43:01 +00:00
Thierry Berger
80f15e0dbb
Remove CanvasParentResizePlugin (#11057)
Improves #11052

# Changelog
- Remove `Window::fit_canvas_to_parent`, as its resizing on wasm now
respects its CSS configuration.

## Migration Guide
- Remove uses of `Window::fit_canvas_to_parent` in favor of CSS
properties, for example:
  ```css
  canvas {
    width: 100%;
    height: 100%;
  }
  ```
2023-12-21 20:01:22 +00:00
Doonv
ba0f8f996f
Add insert_state to App. (#11043)
# Objective

Fix #10731.

## Solution

Rename `App::add_state<T>(&mut self)` to `init_state`, and add
`App::insert_state<T>(&mut self, state: T)`. I decided on these names
because they are more similar to `init_resource` and `insert_resource`.

I also removed the `States` trait's requirement for `Default`. Instead,
`init_state` requires `FromWorld`.

---

## Changelog

- Renamed `App::add_state` to `init_state`.
- Added `App::insert_state`.
- Removed the `States` trait's requirement for `Default`.

## Migration Guide

- Renamed `App::add_state` to `init_state`.
2023-12-21 14:09:24 +00:00
Thierry Berger
ced216f59a
Update winit dependency to 0.29 (#10702)
# Objective

- Update winit dependency to 0.29

## Changelog

### KeyCode changes

- Removed `ScanCode`, as it was [replaced by
KeyCode](https://github.com/rust-windowing/winit/blob/master/CHANGELOG.md#0292).
- `ReceivedCharacter.char` is now a `SmolStr`, [relevant
doc](https://docs.rs/winit/latest/winit/event/struct.KeyEvent.html#structfield.text).
- Changed most `KeyCode` values, and added more.

KeyCode has changed meaning. With this PR, it refers to physical
position on keyboard rather than the printed letter on keyboard keys.

In practice this means:
- On QWERTY keyboard layouts, nothing changes
- On any other keyboard layout, `KeyCode` no longer reflects the label
on key.
- This is "good". In bevy 0.12, when you used WASD for movement, users
with non-QWERTY keyboards couldn't play your game! This was especially
bad for non-latin keyboards. Now, WASD represents the physical keys. A
French player will press the ZQSD keys, which are near each other,
Kyrgyz players will use "Цфыв".
- This is "bad" as well. You can't know in advance what the label of the
key for input is. Your UI says "press WASD to move", even if in reality,
they should be pressing "ZQSD" or "Цфыв". You also no longer can use
`KeyCode` for text inputs. In any case, it was a pretty bad API for text
input. You should use `ReceivedCharacter` now instead.

### Other changes
- Use `web-time` rather than `instant` crate.
(https://github.com/rust-windowing/winit/pull/2836)
- winit did split `run_return` in `run_onDemand` and `pump_events`, I
did the same change in bevy_winit and used `pump_events`.
- Removed `return_from_run` from `WinitSettings` as `winit::run` now
returns on supported platforms.
- I left the example "return_after_run" as I think it's still useful.
- This winit change is done partly to allow to create a new window after
quitting all windows: https://github.com/emilk/egui/issues/1918 ; this
PR doesn't address.
- added `width` and `height` properties in the `canvas` from wasm
example
(https://github.com/bevyengine/bevy/pull/10702#discussion_r1420567168)

## Known regressions (important follow ups?)
- Provide an API for reacting when a specific key from current layout
was released.
- possible solutions: use winit::Key from winit::KeyEvent ; mapping
between KeyCode and Key ; or .
- We don't receive characters through alt+numpad (e.g. alt + 151 = "ù")
anymore ; reproduced on winit example "ime". maybe related to
https://github.com/rust-windowing/winit/issues/2945
- (windows) Window content doesn't refresh at all when resizing. By
reading https://github.com/rust-windowing/winit/issues/2900 ; I suspect
we should just fire a `window.request_redraw();` from `AboutToWait`, and
handle actual redrawing within `RedrawRequested`. I'm not sure how to
move all that code so I'd appreciate it to be a follow up.
- (windows) unreleased winit fix for using set_control_flow in
AboutToWait https://github.com/rust-windowing/winit/issues/3215 ; ⚠️ I'm
not sure what the implications are, but that feels bad 🤔

## Follow up 

I'd like to avoid bloating this PR, here are a few follow up tasks
worthy of a separate PR, or new issue to track them once this PR is
closed, as they would either complicate reviews, or at risk of being
controversial:
- remove CanvasParentResizePlugin
(https://github.com/bevyengine/bevy/pull/10702#discussion_r1417068856)
- avoid mentionning explicitly winit in docs from bevy_window ?
- NamedKey integration on bevy_input:
https://github.com/rust-windowing/winit/pull/3143 introduced a new
NamedKey variant. I implemented it only on the converters but we'd
benefit making the same changes to bevy_input.
- Add more info in KeyboardInput
https://github.com/bevyengine/bevy/pull/10702#pullrequestreview-1748336313
- https://github.com/bevyengine/bevy/pull/9905 added a workaround on a
bug allegedly fixed by winit 0.29. We should check if it's still
necessary.
- update to raw_window_handle 0.6
  - blocked by wgpu
- Rename `KeyCode` to `PhysicalKeyCode`
https://github.com/bevyengine/bevy/pull/10702#discussion_r1404595015
- remove `instant` dependency, [replaced
by](https://github.com/rust-windowing/winit/pull/2836) `web_time`), we'd
need to update to :
  - fastrand >= 2.0
- [`async-executor`](https://github.com/smol-rs/async-executor) >= 1.7
    - [`futures-lite`](https://github.com/smol-rs/futures-lite) >= 2.0
- Verify license, see
[discussion](https://github.com/bevyengine/bevy/pull/8745#discussion_r1402439800)
  - we might be missing a short notice or description of changes made
- Consider using https://github.com/rust-windowing/cursor-icon directly
rather than vendoring it in bevy.
- investigate [this
unwrap](https://github.com/bevyengine/bevy/pull/8745#discussion_r1387044986)
(`winit_window.canvas().unwrap();`)
- Use more good things about winit's update
- https://github.com/bevyengine/bevy/pull/10689#issuecomment-1823560428
## Migration Guide

This PR should have one.
2023-12-21 07:40:47 +00:00
Tygyh
746361bdfd
Add html tags required for accessibility (#10989)
# Objective

- Make example comply with accessibility standards.

## Solution

- Add missing tags.
2023-12-16 03:09:36 +00:00
Anton Iacobaeus
ca1874e6c6
Update texture_atlas example with different padding and sampling (#10073)
# Objective

- Expand the texture_atlas example with padding and show how it can
resolve sprite bleeding for different types of sampling.
- Fixes #9522
## Solution
Updated the texture_atlas example by adding 4 different texture atlases:
1. linear, no padding
2. linear, padding
3. nearest neighbor, no padding
4. nearest neighbor, padding

Now renders one padded and one unpadded texture atlas, and the same
upscaled sprite from each of the new texture atlases. See the screenshot
below (taken on 1080p monitor).


![Screenshot from 2023-10-10
08-37-43](https://github.com/bevyengine/bevy/assets/46004494/4cef707c-e117-4835-b2c8-66503d8c275f)

**From left->right:** linear no padding, nearest no padding, linear
padding, nearest padding.

---

---------

Co-authored-by: davidasberg <david.aasberg@gmail.com>
2023-12-14 18:48:38 +00:00
Tygyh
720d6dab82
Change Window scale factor to f32 (adopted) (#10897)
# Objective

- Finish the work done in #8942 .

## Solution

- Rebase the changes made in #8942 and fix the issues stopping it from
being merged earlier

---------

Co-authored-by: Thomas <1234328+thmsgntz@users.noreply.github.com>
2023-12-14 14:56:40 +00:00
Elabajaba
70a592f31a
Update to wgpu 0.18 (#10266)
# Objective

Keep up to date with wgpu.

## Solution

Update the wgpu version.

Currently blocked on naga_oil updating to naga 0.14 and releasing a new
version.

3d scenes (or maybe any scene with lighting?) currently don't render
anything due to
```
error: naga_oil bug, please file a report: composer failed to build a valid header: Type [2] '' is invalid
 = Capability Capabilities(CUBE_ARRAY_TEXTURES) is required
 ```

I'm not sure what should be passed in for `wgpu::InstanceFlags`, or if we want to make the gles3minorversion configurable (might be useful for debugging?)

Currently blocked on https://github.com/bevyengine/naga_oil/pull/63, and https://github.com/gfx-rs/wgpu/issues/4569 to be fixed upstream in wgpu first.

## Known issues

Amd+windows+vulkan has issues with texture_binding_arrays (see the image [here](https://github.com/bevyengine/bevy/pull/10266#issuecomment-1819946278)), but that'll be fixed in the next wgpu/naga version, and you can just use dx12 as a workaround for now (Amd+linux mesa+vulkan texture_binding_arrays are fixed though).

---

## Changelog

Updated wgpu to 0.18, naga to 0.14.2, and naga_oil to 0.11.
- Windows desktop GL should now be less painful as it no longer requires Angle.
- You can now toggle shader validation and debug information for debug and release builds using `WgpuSettings.instance_flags` and [InstanceFlags](https://docs.rs/wgpu/0.18.0/wgpu/struct.InstanceFlags.html)

## Migration Guide

- `RenderPassDescriptor` `color_attachments`  (as well as `RenderPassColorAttachment`, and `RenderPassDepthStencilAttachment`) now use `StoreOp::Store` or `StoreOp::Discard` instead of a `boolean` to declare whether or not they should be stored.
- `RenderPassDescriptor` now have `timestamp_writes` and `occlusion_query_set` fields. These can safely be set to `None`.
- `ComputePassDescriptor` now have a `timestamp_writes` field. This can be set to `None` for now.
- See the [wgpu changelog](https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#v0180-2023-10-25) for additional details
2023-12-14 02:45:47 +00:00
Mantas
5af2f022d8
Rename WorldQueryData & WorldQueryFilter to QueryData & QueryFilter (#10779)
# Rename `WorldQueryData` & `WorldQueryFilter` to `QueryData` &
`QueryFilter`

Fixes #10776 

## Solution

Traits `WorldQueryData` & `WorldQueryFilter` were renamed to `QueryData`
and `QueryFilter`, respectively. Related Trait types were also renamed.

---

## Changelog

- Trait `WorldQueryData` has been renamed to `QueryData`. Derive macro's
`QueryData` attribute `world_query_data` has been renamed to
`query_data`.
- Trait `WorldQueryFilter` has been renamed to `QueryFilter`. Derive
macro's `QueryFilter` attribute `world_query_filter` has been renamed to
`query_filter`.
- Trait's `ExtractComponent` type `Query` has been renamed to `Data`.
- Trait's `GetBatchData` types `Query` & `QueryFilter` has been renamed
to `Data` & `Filter`, respectively.
- Trait's `ExtractInstance` type `Query` has been renamed to `Data`.
- Trait's `ViewNode` type `ViewQuery` has been renamed to `ViewData`.
- Trait's `RenderCommand` types `ViewWorldQuery` & `ItemWorldQuery` has
been renamed to `ViewData` & `ItemData`, respectively.

## Migration Guide

Note: if merged before 0.13 is released, this should instead modify the
migration guide of #10776 with the updated names.

- Rename `WorldQueryData` & `WorldQueryFilter` trait usages to
`QueryData` & `QueryFilter` and their respective derive macro attributes
`world_query_data` & `world_query_filter` to `query_data` &
`query_filter`.
- Rename the following trait type usages:
  - Trait's `ExtractComponent` type `Query` to `Data`.
  - Trait's `GetBatchData` type `Query` to `Data`.
  - Trait's `ExtractInstance` type `Query` to `Data`.
  - Trait's `ViewNode` type `ViewQuery` to `ViewData`'
- Trait's `RenderCommand` types `ViewWolrdQuery` & `ItemWorldQuery` to
`ViewData` & `ItemData`, respectively.

```rust
// Before
#[derive(WorldQueryData)]
#[world_query_data(derive(Debug))]
struct EmptyQuery {
    empty: (),
}

// After
#[derive(QueryData)]
#[query_data(derive(Debug))]
struct EmptyQuery {
    empty: (),
}

// Before
#[derive(WorldQueryFilter)]
struct CustomQueryFilter<T: Component, P: Component> {
    _c: With<ComponentC>,
    _d: With<ComponentD>,
    _or: Or<(Added<ComponentC>, Changed<ComponentD>, Without<ComponentZ>)>,
    _generic_tuple: (With<T>, With<P>),
}

// After
#[derive(QueryFilter)]
struct CustomQueryFilter<T: Component, P: Component> {
    _c: With<ComponentC>,
    _d: With<ComponentD>,
    _or: Or<(Added<ComponentC>, Changed<ComponentD>, Without<ComponentZ>)>,
    _generic_tuple: (With<T>, With<P>),
}

// Before
impl ExtractComponent for ContrastAdaptiveSharpeningSettings {
    type Query = &'static Self;
    type Filter = With<Camera>;
    type Out = (DenoiseCAS, CASUniform);

    fn extract_component(item: QueryItem<Self::Query>) -> Option<Self::Out> {
        //...
    }
}

// After
impl ExtractComponent for ContrastAdaptiveSharpeningSettings {
    type Data = &'static Self;
    type Filter = With<Camera>;
    type Out = (DenoiseCAS, CASUniform);

    fn extract_component(item: QueryItem<Self::Data>) -> Option<Self::Out> {
        //...
    }
}

// Before
impl GetBatchData for MeshPipeline {
    type Param = SRes<RenderMeshInstances>;
    type Query = Entity;
    type QueryFilter = With<Mesh3d>;
    type CompareData = (MaterialBindGroupId, AssetId<Mesh>);
    type BufferData = MeshUniform;

    fn get_batch_data(
        mesh_instances: &SystemParamItem<Self::Param>,
        entity: &QueryItem<Self::Query>,
    ) -> (Self::BufferData, Option<Self::CompareData>) {
        // ....
    }
}

// After
impl GetBatchData for MeshPipeline {
    type Param = SRes<RenderMeshInstances>;
    type Data = Entity;
    type Filter = With<Mesh3d>;
    type CompareData = (MaterialBindGroupId, AssetId<Mesh>);
    type BufferData = MeshUniform;

    fn get_batch_data(
        mesh_instances: &SystemParamItem<Self::Param>,
        entity: &QueryItem<Self::Data>,
    ) -> (Self::BufferData, Option<Self::CompareData>) {
        // ....
    }
}

// Before
impl<A> ExtractInstance for AssetId<A>
where
    A: Asset,
{
    type Query = Read<Handle<A>>;
    type Filter = ();

    fn extract(item: QueryItem<'_, Self::Query>) -> Option<Self> {
        Some(item.id())
    }
}

// After
impl<A> ExtractInstance for AssetId<A>
where
    A: Asset,
{
    type Data = Read<Handle<A>>;
    type Filter = ();

    fn extract(item: QueryItem<'_, Self::Data>) -> Option<Self> {
        Some(item.id())
    }
}

// Before
impl ViewNode for PostProcessNode {
    type ViewQuery = (
        &'static ViewTarget,
        &'static PostProcessSettings,
    );

    fn run(
        &self,
        _graph: &mut RenderGraphContext,
        render_context: &mut RenderContext,
        (view_target, _post_process_settings): QueryItem<Self::ViewQuery>,
        world: &World,
    ) -> Result<(), NodeRunError> {
        // ...
    }
}

// After
impl ViewNode for PostProcessNode {
    type ViewData = (
        &'static ViewTarget,
        &'static PostProcessSettings,
    );

    fn run(
        &self,
        _graph: &mut RenderGraphContext,
        render_context: &mut RenderContext,
        (view_target, _post_process_settings): QueryItem<Self::ViewData>,
        world: &World,
    ) -> Result<(), NodeRunError> {
        // ...
    }
}

// Before
impl<P: CachedRenderPipelinePhaseItem> RenderCommand<P> for SetItemPipeline {
    type Param = SRes<PipelineCache>;
    type ViewWorldQuery = ();
    type ItemWorldQuery = ();
    #[inline]
    fn render<'w>(
        item: &P,
        _view: (),
        _entity: (),
        pipeline_cache: SystemParamItem<'w, '_, Self::Param>,
        pass: &mut TrackedRenderPass<'w>,
    ) -> RenderCommandResult {
        // ...
    }
}

// After
impl<P: CachedRenderPipelinePhaseItem> RenderCommand<P> for SetItemPipeline {
    type Param = SRes<PipelineCache>;
    type ViewData = ();
    type ItemData = ();
    #[inline]
    fn render<'w>(
        item: &P,
        _view: (),
        _entity: (),
        pipeline_cache: SystemParamItem<'w, '_, Self::Param>,
        pass: &mut TrackedRenderPass<'w>,
    ) -> RenderCommandResult {
        // ...
    }
}
```
2023-12-12 19:45:50 +00:00
robtfm
67d92e9b85
light renderlayers (#10742)
# Objective

add `RenderLayers` awareness to lights. lights default to
`RenderLayers::layer(0)`, and must intersect the camera entity's
`RenderLayers` in order to affect the camera's output.

note that lights already use renderlayers to filter meshes for shadow
casting. this adds filtering lights per view based on intersection of
camera layers and light layers.

fixes #3462 

## Solution

PointLights and SpotLights are assigned to individual views in
`assign_lights_to_clusters`, so we simply cull the lights which don't
match the view layers in that function.

DirectionalLights are global, so we 
- add the light layers to the `DirectionalLight` struct
- add the view layers to the `ViewUniform` struct
- check for intersection before processing the light in
`apply_pbr_lighting`

potential issue: when mesh/light layers are smaller than the view layers
weird results can occur. e.g:
camera = layers 1+2
light = layers 1
mesh = layers 2

the mesh does not cast shadows wrt the light as (1 & 2) == 0.
the light affects the view as (1+2 & 1) != 0. 
the view renders the mesh as (1+2 & 2) != 0.

so the mesh is rendered and lit, but does not cast a shadow. 

this could be fixed (so that the light would not affect the mesh in that
view) by adding the light layers to the point and spot light structs,
but i think the setup is pretty unusual, and space is at a premium in
those structs (adding 4 bytes more would reduce the webgl point+spot
light max count to 240 from 256).

I think typical usage is for cameras to have a single layer, and
meshes/lights to maybe have multiple layers to render to e.g. minimaps
as well as primary views.

if there is a good use case for the above setup and we should support
it, please let me know.

---

## Migration Guide

Lights no longer affect all `RenderLayers` by default, now like cameras
and meshes they default to `RenderLayers::layer(0)`. To recover the
previous behaviour and have all lights affect all views, add a
`RenderLayers::all()` component to the light entity.
2023-12-12 19:45:37 +00:00
Mateusz Wachowiak
1f97717a3d
Rename Input to ButtonInput (#10859)
# Objective

- Resolves #10853 

## Solution

- ~~Changed the name of `Input` struct to `PressableInput`.~~
- Changed the name of `Input` struct to `ButtonInput`.

## Migration Guide

- Breaking Change: Users need to rename `Input` to `ButtonInput` in
their projects.
2023-12-06 20:32:34 +00:00
Joona Aalto
d9aac887b5
Split Ray into Ray2d and Ray3d and simplify plane construction (#10856)
# Objective

A better alternative version of #10843.

Currently, Bevy has a single `Ray` struct for 3D. To allow better
interoperability with Bevy's primitive shapes (#10572) and some third
party crates (that handle e.g. spatial queries), it would be very useful
to have separate versions for 2D and 3D respectively.

## Solution

Separate `Ray` into `Ray2d` and `Ray3d`. These new structs also take
advantage of the new primitives by using `Direction2d`/`Direction3d` for
the direction:

```rust
pub struct Ray2d {
    pub origin: Vec2,
    pub direction: Direction2d,
}

pub struct Ray3d {
    pub origin: Vec3,
    pub direction: Direction3d,
}
```

and by using `Plane2d`/`Plane3d` in `intersect_plane`:

```rust
impl Ray2d {
    // ...
    pub fn intersect_plane(&self, plane_origin: Vec2, plane: Plane2d) -> Option<f32> {
        // ...
    }
}
```

---

## Changelog

### Added

- `Ray2d` and `Ray3d`
- `Ray2d::new` and `Ray3d::new` constructors
- `Plane2d::new` and `Plane3d::new` constructors

### Removed

- Removed `Ray` in favor of `Ray3d`

### Changed

- `direction` is now a `Direction2d`/`Direction3d` instead of a vector,
which provides guaranteed normalization
- `intersect_plane` now takes a `Plane2d`/`Plane3d` instead of just a
vector for the plane normal
- `Direction2d` and `Direction3d` now derive `Serialize` and
`Deserialize` to preserve ray (de)serialization

## Migration Guide

`Ray` has been renamed to `Ray3d`.

### Ray creation

Before:

```rust
Ray {
    origin: Vec3::ZERO,
    direction: Vec3::new(0.5, 0.6, 0.2).normalize(),
}
```

After:

```rust
// Option 1:
Ray3d {
    origin: Vec3::ZERO,
    direction: Direction3d::new(Vec3::new(0.5, 0.6, 0.2)).unwrap(),
}

// Option 2:
Ray3d::new(Vec3::ZERO, Vec3::new(0.5, 0.6, 0.2))
```

### Plane intersections

Before:

```rust
let result = ray.intersect_plane(Vec2::X, Vec2::Y);
```

After:

```rust
let result = ray.intersect_plane(Vec2::X, Plane2d::new(Vec2::Y));
```
2023-12-06 14:09:04 +00:00
akimakinai
f90248b052
Remove unnecessary ResMut in examples (#10879)
# Objective

- Examples containing `ResMut`s that are never mutated can be confusing
for readers.

## Solution

- Changes them to `Res`.
2023-12-05 15:42:32 +00:00
ickshonpe
166686e0f2
Rename TextAlignment to JustifyText. (#10854)
# Objective

The name `TextAlignment` is really deceptive and almost every new user
gets confused about the differences between aligning text with
`TextAlignment`, aligning text with `Style` and aligning text with
anchor (when using `Text2d`).

## Solution

* Rename `TextAlignment` to `JustifyText`. The associated helper methods
are also renamed.
* Improve the doc comments for text explaining explicitly how the
`JustifyText` component affects the arrangement of text.
* Add some extra cases to the `text_debug` example that demonstate the
differences between alignment using `JustifyText` and alignment using
`Style`.
<img width="757" alt="text_debug_2"
src="https://github.com/bevyengine/bevy/assets/27962798/9d53e647-93f9-4bc7-8a20-0d9f783304d2">

---

## Changelog
* `TextAlignment` has been renamed to `JustifyText`
* `TextBundle::with_text_alignment` has been renamed to
`TextBundle::with_text_justify`
* `Text::with_alignment` has been renamed to `Text::with_justify`
* The `text_alignment` field of `TextMeasureInfo` has been renamed to
`justification`

## Migration Guide
* `TextAlignment` has been renamed to `JustifyText`
* `TextBundle::with_text_alignment` has been renamed to
`TextBundle::with_text_justify`
* `Text::with_alignment` has been renamed to `Text::with_justify`
* The `text_alignment` field of `TextMeasureInfo` has been renamed to
`justification`
2023-12-05 03:00:41 +00:00
Jos Feenstra
18ac125997
Add helper macro's for logging only once (#10808)
# Objective

Fixes #10291

This adds a way to easily log messages once within system which are
called every frame.

## Solution

Opted for a macro-based approach. The fact that the 'once' call is
tracked per call site makes the `log_once!()` macro very versatile and
easy-to-use. I suspect it will be very handy for all of us, but
especially beginners, to get some initial feedback from systems without
spamming up the place!

I've made the macro's return its internal `has_fired` state, for
situations in which that might be useful to know (trigger something else
alongside the log, for example).

Please let me know if I placed the macro's in the right location, and if
you would like me to do something more clever with the macro's
themselves, since its looking quite copy-pastey at the moment. I've
tried ways to replace 5 with 1 macro's, but no success yet.

One downside of this approach is: Say you wish to warn the user if a
resource is invalid. In this situation, the
`resource.is_valid()` check would still be performed every frame:
```rust
fn my_system(my_res: Res<MyResource>) {
   if !my_res.is_valid() {
      warn_once!("resource is invalid!");
   }
}
```
If you want to prevent that, you would still need to introduce a local
boolean. I don't think this is a very big deal, as expensive checks
shouldn't be called every frame in any case.


## Changelog
Added: `trace_once!()`, `debug_once!()`, `info_once!()`, `warn_once!()`,
and `error_once!()` log macros which fire only once per call site.
2023-12-05 01:56:40 +00:00
Federico Rinaldi
0400ef059b
Substitute get(0) with first() (#10847)
Substitute calls to `get(0)` with `first()`, improving readability.
2023-12-02 22:13:42 +00:00
James Liu
2148518758
Override QueryIter::fold to port Query::for_each perf gains to select Iterator combinators (#6773)
# Objective
After #6547, `Query::for_each` has been capable of automatic
vectorization on certain queries, which is seeing a notable (>50% CPU
time improvements) for iteration. However, `Query::for_each` isn't
idiomatic Rust, and lacks the flexibility of iterator combinators.

Ideally, `Query::iter` and friends should be able to achieve the same
results. However, this does seem to blocked upstream
(rust-lang/rust#104914) by Rust's loop optimizations.

## Solution
This is an intermediate solution and refactor. This moves the
`Query::for_each` implementation onto the `Iterator::fold`
implementation for `QueryIter` instead. This should result in the same
automatic vectorization optimization on all `Iterator` functions that
internally use fold, including `Iterator::for_each`, `Iterator::count`,
etc.

With this, it should close the gap between the two completely.
Internally, this PR changes `Query::for_each` to use
`query.iter().for_each(..)` instead of the duplicated implementation.

Separately, the duplicate implementations of internal iteration (i.e.
`Query::par_for_each`) now use portions of the current `Query::for_each`
implementation factored out into their own functions.

This also massively cleans up our internal fragmentation of internal
iteration options, deduplicating the iteration code used in `for_each`
and `par_iter().for_each()`.

---

## Changelog
Changed: `Query::for_each`, `Query::for_each_mut`, `Query::for_each`,
and `Query::for_each_mut` have been moved to `QueryIter`'s
`Iterator::for_each` implementation, and still retains their performance
improvements over normal iteration. These APIs are deprecated in 0.13
and will be removed in 0.14.

---------

Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-12-01 09:09:55 +00:00
thepackett
e581d74f7d
Mention DynamicSceneBuilder in scene example (#10441)
# Objective

Make ```DynamicSceneBuilder``` more visible to new bevy learners!
```DynamicSceneBuilder``` is likely to be the most appropriate tool to use when creating dynamic scenes in all but the simplest scenarios. However, it's not mentioned in the scene example. This PR aims to fix this.

## Solution

I've modified the comment above where the ```DynamicScene``` is created to note that ```DynamicSceneBuilder``` can also be used to create the scene. I believe this is the best approach to introduce ```DynamicSceneBuilder``` without adding additional complexity to the example.
2023-11-30 20:05:59 +00:00
tygyh
fd308571c4
Remove unnecessary path prefixes (#10749)
# Objective

- Shorten paths by removing unnecessary prefixes

## Solution

- Remove the prefixes from many paths which do not need them. Finding
the paths was done automatically using built-in refactoring tools in
Jetbrains RustRover.
2023-11-28 23:43:40 +00:00
JMS55
4bf20e7d27
Swap material and mesh bind groups (#10485)
# Objective
- Materials should be a more frequent rebind then meshes (due to being
able to use a single vertex buffer, such as in #10164) and therefore
should be in a higher bind group.

---

## Changelog
- For 2d and 3d mesh/material setups (but not UI materials, or other
rendering setups such as gizmos, sprites, or text), mesh data is now in
bind group 1, and material data is now in bind group 2, which is swapped
from how they were before.

## Migration Guide
- Custom 2d and 3d mesh/material shaders should now use bind group 2
`@group(2) @binding(x)` for their bound resources, instead of bind group
1.
- Many internal pieces of rendering code have changed so that mesh data
is now in bind group 1, and material data is now in bind group 2.
Semi-custom rendering setups (that don't use the Material or Material2d
APIs) should adapt to these changes.
2023-11-28 22:26:22 +00:00
Kanabenki
0e9f6e92ea
Add clippy::manual_let_else at warn level to lints (#10684)
# Objective

Related to #10612.

Enable the
[`clippy::manual_let_else`](https://rust-lang.github.io/rust-clippy/master/#manual_let_else)
lint as a warning. The `let else` form seems more idiomatic to me than a
`match`/`if else` that either match a pattern or diverge, and from the
clippy doc, the lint doesn't seem to have any possible false positive.

## Solution

Add the lint as warning in `Cargo.toml`, refactor places where the lint
triggers.
2023-11-28 04:15:27 +00:00
IceSentry
6d0c11a28f
Bind group layout entries (#10224)
# Objective

- Follow up to #9694

## Solution

- Same api as #9694 but adapted for `BindGroupLayoutEntry`
- Use the same `ShaderStages` visibilty for all entries by default
- Add `BindingType` helper function that mirror the wgsl equivalent and
that make writing layouts much simpler.

Before:
```rust
let layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
    label: Some("post_process_bind_group_layout"),
    entries: &[
        BindGroupLayoutEntry {
            binding: 0,
            visibility: ShaderStages::FRAGMENT,
            ty: BindingType::Texture {
                sample_type: TextureSampleType::Float { filterable: true },
                view_dimension: TextureViewDimension::D2,
                multisampled: false,
            },
            count: None,
        },
        BindGroupLayoutEntry {
            binding: 1,
            visibility: ShaderStages::FRAGMENT,
            ty: BindingType::Sampler(SamplerBindingType::Filtering),
            count: None,
        },
        BindGroupLayoutEntry {
            binding: 2,
            visibility: ShaderStages::FRAGMENT,
            ty: BindingType::Buffer {
                ty: bevy::render::render_resource::BufferBindingType::Uniform,
                has_dynamic_offset: false,
                min_binding_size: Some(PostProcessSettings::min_size()),
            },
            count: None,
        },
    ],
});
```
After:
```rust
let layout = render_device.create_bind_group_layout(
    "post_process_bind_group_layout"),
    &BindGroupLayoutEntries::sequential(
        ShaderStages::FRAGMENT,
        (
            texture_2d_f32(),
            sampler(SamplerBindingType::Filtering),
            uniform_buffer(false, Some(PostProcessSettings::min_size())),
        ),
    ),
);
```

Here's a more extreme example in bevy_solari:
86dab7f5da

---

## Changelog

- Added `BindGroupLayoutEntries` and all `BindingType` helper functions.

## Migration Guide

`RenderDevice::create_bind_group_layout()` doesn't take a
`BindGroupLayoutDescriptor` anymore. You need to provide the parameters
separately

```rust
// 0.12
let layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
    label: Some("post_process_bind_group_layout"),
    entries: &[
        BindGroupLayoutEntry {
			// ...
        },
    ],
});

// 0.13
let layout = render_device.create_bind_group_layout(
	"post_process_bind_group_layout",
    &[
        BindGroupLayoutEntry {
			// ...
        },
    ],
);
```

## TODO

- [x] implement a `Dynamic` variant
- [x] update the `RenderDevice::create_bind_group_layout()` api to match
the one from `RenderDevice::creat_bind_group()`
- [x] docs
2023-11-28 04:00:49 +00:00
Mark Wainwright
f0a8994f55
Split WorldQuery into WorldQueryData and WorldQueryFilter (#9918)
# Objective

- Fixes #7680
- This is an updated for https://github.com/bevyengine/bevy/pull/8899
which had the same objective but fell a long way behind the latest
changes


## Solution

The traits `WorldQueryData : WorldQuery` and `WorldQueryFilter :
WorldQuery` have been added and some of the types and functions from
`WorldQuery` has been moved into them.

`ReadOnlyWorldQuery` has been replaced with `ReadOnlyWorldQueryData`. 

`WorldQueryFilter` is safe (as long as `WorldQuery` is implemented
safely).

`WorldQueryData` is unsafe - safely implementing it requires that
`Self::ReadOnly` is a readonly version of `Self` (this used to be a
safety requirement of `WorldQuery`)

The type parameters `Q` and `F` of `Query` must now implement
`WorldQueryData` and `WorldQueryFilter` respectively.

This makes it impossible to accidentally use a filter in the data
position or vice versa which was something that could lead to bugs.
~~Compile failure tests have been added to check this.~~

It was previously sometimes useful to use `Option<With<T>>` in the data
position. Use `Has<T>` instead in these cases.

The `WorldQuery` derive macro has been split into separate derive macros
for `WorldQueryData` and `WorldQueryFilter`.

Previously it was possible to derive both `WorldQuery` for a struct that
had a mixture of data and filter items. This would not work correctly in
some cases but could be a useful pattern in others. *This is no longer
possible.*

---

## Notes

- The changes outside of `bevy_ecs` are all changing type parameters to
the new types, updating the macro use, or replacing `Option<With<T>>`
with `Has<T>`.

- All `WorldQueryData` types always returned `true` for `IS_ARCHETYPAL`
so I moved it to `WorldQueryFilter` and
replaced all calls to it with `true`. That should be the only logic
change outside of the macro generation code.

- `Changed<T>` and `Added<T>` were being generated by a macro that I
have expanded. Happy to revert that if desired.

- The two derive macros share some functions for implementing
`WorldQuery` but the tidiest way I could find to implement them was to
give them a ton of arguments and ask clippy to ignore that.

## Changelog

### Changed
- Split `WorldQuery` into `WorldQueryData` and `WorldQueryFilter` which
now have separate derive macros. It is not possible to derive both for
the same type.
- `Query` now requires that the first type argument implements
`WorldQueryData` and the second implements `WorldQueryFilter`

## Migration Guide

- Update derives

```rust
// old
#[derive(WorldQuery)]
#[world_query(mutable, derive(Debug))]
struct CustomQuery {
    entity: Entity,
    a: &'static mut ComponentA
}

#[derive(WorldQuery)]
struct QueryFilter {
    _c: With<ComponentC>
}

// new 
#[derive(WorldQueryData)]
#[world_query_data(mutable, derive(Debug))]
struct CustomQuery {
    entity: Entity,
    a: &'static mut ComponentA,
}

#[derive(WorldQueryFilter)]
struct QueryFilter {
    _c: With<ComponentC>
}
```
- Replace `Option<With<T>>` with `Has<T>`

```rust
/// old
fn my_system(query: Query<(Entity, Option<With<ComponentA>>)>)
{
  for (entity, has_a_option) in query.iter(){
    let has_a:bool = has_a_option.is_some();
    //todo!()
  }
}

/// new
fn my_system(query: Query<(Entity, Has<ComponentA>)>)
{
  for (entity, has_a) in query.iter(){
    //todo!()
  }
}
```

- Fix queries which had filters in the data position or vice versa.

```rust
// old
fn my_system(query: Query<(Entity, With<ComponentA>)>)
{
  for (entity, _) in query.iter(){
  //todo!()
  }
}

// new
fn my_system(query: Query<Entity, With<ComponentA>>)
{
  for entity in query.iter(){
  //todo!()
  }
}

// old
fn my_system(query: Query<AnyOf<(&ComponentA, With<ComponentB>)>>)
{
  for (entity, _) in query.iter(){
  //todo!()
  }
}

// new
fn my_system(query: Query<Option<&ComponentA>, Or<(With<ComponentA>, With<ComponentB>)>>)
{
  for entity in query.iter(){
  //todo!()
  }
}

```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-11-28 03:56:07 +00:00
Torstein Grindvik
73bb310304
impl From<Color> for ClearColorConfig (#10734)
# Objective

I tried setting `ClearColorConfig` in my app via `Color::FOO.into()`
expecting it to work, but the impl was missing.

## Solution

- Add `impl From<Color> for ClearColorConfig`
- Change examples to use this impl

## Changelog

### Added

- `ClearColorConfig` can be constructed via `.into()` on a `Color`

---------

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2023-11-26 20:48:03 +00:00
Nick Fagerlund
91b64df96b
Fix non-functional nondeterministic_system_order example (#10719)
# Objective

The `nondeterministic_system_order` example doesn't actually detect and
log its deliberate order ambiguities! It should, tho.

## Solution

Update the schedule label, and explain in a comment that you can't turn
it on for the whole `Main` schedule in one go (alas, that would be nice,
but it makes sense that it doesn't work that way).
2023-11-25 21:13:35 +00:00
ickshonpe
bca057d7ec
Make clipped areas of UI nodes non-interactive (#10454)
# Objective

Problems:

* The clipped, non-visible regions of UI nodes are interactive.
* `RelativeCursorPostion` is set relative to the visible part of the
node. It should be relative to the whole node.
* The `RelativeCursorPostion::mouse_over` method returns `true` when the
mouse is over a clipped part of a node.

fixes #10470

## Solution

Intersect a node's bounding rect with its clipping rect before checking
if it contains the cursor.

Added the field `normalized_visible_node_rect` to
`RelativeCursorPosition`. This is set to the bounds of the unclipped
area of the node rect by `ui_focus_system` expressed in normalized
coordinates relative to the entire node.

Instead of checking if the normalized cursor position lies within a unit
square, it instead checks if it is contained by
`normalized_visible_node_rect`.

Added outlines to the `overflow` example that appear when the cursor is
over the visible part of the images, but not the clipped area.

---

## Changelog

* `ui_focus_system` intersects a node's bounding rect with its clipping
rect before checking if mouse over.
* Added the field `normalized_visible_node_rect` to
`RelativeCursorPosition`. This is set to the bounds of the unclipped
area of the node rect by `ui_focus_system` expressed in normalized
coordinates relative to the entire node.
* `RelativeCursorPostion` is calculated relative to the whole node's
position and size, not only the visible part.
* `RelativeCursorPosition::mouse_over` only returns true when the mouse
is over an unclipped region of the UI node.
* Removed the `Deref` and `DerefMut` derives from
`RelativeCursorPosition` as it is no longer a single field struct.
* Added some outlines to the `overflow` example that respond to
`Interaction` changes.

## Migration Guide

The clipped areas of UI nodes are no longer interactive.

`RelativeCursorPostion` is now calculated relative to the whole node's
position and size, not only the visible part. Its `mouse_over` method
only returns true when the cursor is over an unclipped part of the node.

`RelativeCursorPosition` no longer implements `Deref` and `DerefMut`.
2023-11-22 14:30:38 +00:00
Mike
208ecb53dc
Append commands (#10400)
# Objective

- I've been experimenting with different patterns to try and make async
tasks more convenient. One of the better ones I've found is to return a
command queue to allow for deferred &mut World access. It can be
convenient to check for task completion in a normal system, but it is
hard to do something with the command queue after getting it back. This
pr adds a `append` to Commands. This allows appending the returned
command queue onto the system's commands.

## Solution

- I edited the async compute example to use the new `append`, but not
sure if I should keep the example changed as this might be too
opinionated.

## Future Work

- It would be very easy to pull the pattern used in the example out into
a plugin or a external crate, so users wouldn't have to add the checking
system.

---

## Changelog

- add `append` to `Commands` and `CommandQueue`
2023-11-22 00:04:37 +00:00
BD103
3578eec351
Re-export futures_lite in bevy_tasks (#10670)
# Objective

- Fixes #10664

## Solution

- `pub use futures_lite as future` :)

---

## Changelog

- Made `futures_lite` available as `future` in the `bevy_tasks` module.

## Migration Guide

- Remove `futures_lite` from `Cargo.toml`.

```diff
[dependencies]
bevy = "0.12.0"
- futures-lite = "1.4.0"
```

- Replace `futures_lite` imports with `bevy::tasks::future`.

```diff
- use futures_lite::poll_once;
+ use bevy::tasks::future::poll_once;
```
2023-11-21 16:51:13 +00:00
IceSentry
83a358bf33
Improve shader_material example (#10547)
# Objective

- The current shader code is misleading since it makes it look like a
struct is passed to the bind group 0 but in reality only the color is
passed. They just happen to have the exact same memory layout so wgsl
doesn't complain and it works.
- The struct is defined after the `impl Material` block which is
backwards from pretty much every other usage of the `impl` block in
bevy.

## Solution

- Remove the unnecessary struct in the shader
- move the impl block
2023-11-20 10:24:02 +00:00
Ame
951c9bb1a2
Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011)
# Objective

- Fix adding `#![allow(clippy::type_complexity)]` everywhere. like #9796

## Solution

- Use the new [lints] table that will land in 1.74
(https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#lints)
- inherit lint to the workspace, crates and examples.
```
[lints]
workspace = true
```

## Changelog

- Bump rust version to 1.74
- Enable lints table for the workspace
```toml
[workspace.lints.clippy]
type_complexity = "allow"
```
- Allow type complexity for all crates and examples
```toml
[lints]
workspace = true
```

---------

Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2023-11-18 20:58:48 +00:00
Zachary Harrold
46b8e904f4
Added Method to Allow Pipelined Asset Loading (#10565)
# Objective

- Fixes #10518

## Solution

I've added a method to `LoadContext`, `load_direct_with_reader`, which
mirrors the behaviour of `load_direct` with a single key difference: it
is provided with the `Reader` by the caller, rather than getting it from
the contained `AssetServer`. This allows for an `AssetLoader` to process
its `Reader` stream, and then directly hand the results off to the
`LoadContext` to handle further loading. The outer `AssetLoader` can
control how the `Reader` is interpreted by providing a relevant
`AssetPath`.

For example, a Gzip decompression loader could process the asset
`images/my_image.png.gz` by decompressing the bytes, then handing the
decompressed result to the `LoadContext` with the new path
`images/my_image.png.gz/my_image.png`. This intuitively reflects the
nature of contained assets, whilst avoiding unintended behaviour, since
the generated path cannot be a real file path (a file and folder of the
same name cannot coexist in most file-systems).

```rust
#[derive(Asset, TypePath)]
pub struct GzAsset {
    pub uncompressed: ErasedLoadedAsset,
}

#[derive(Default)]
pub struct GzAssetLoader;

impl AssetLoader for GzAssetLoader {
    type Asset = GzAsset;
    type Settings = ();
    type Error = GzAssetLoaderError;
    fn load<'a>(
        &'a self,
        reader: &'a mut Reader,
        _settings: &'a (),
        load_context: &'a mut LoadContext,
    ) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
        Box::pin(async move {
            let compressed_path = load_context.path();
            let file_name = compressed_path
                .file_name()
                .ok_or(GzAssetLoaderError::IndeterminateFilePath)?
                .to_string_lossy();
            let uncompressed_file_name = file_name
                .strip_suffix(".gz")
                .ok_or(GzAssetLoaderError::IndeterminateFilePath)?;
            let contained_path = compressed_path.join(uncompressed_file_name);

            let mut bytes_compressed = Vec::new();

            reader.read_to_end(&mut bytes_compressed).await?;

            let mut decoder = GzDecoder::new(bytes_compressed.as_slice());

            let mut bytes_uncompressed = Vec::new();

            decoder.read_to_end(&mut bytes_uncompressed)?;

            // Now that we have decompressed the asset, let's pass it back to the
            // context to continue loading

            let mut reader = VecReader::new(bytes_uncompressed);

            let uncompressed = load_context
                .load_direct_with_reader(&mut reader, contained_path)
                .await?;

            Ok(GzAsset { uncompressed })
        })
    }

    fn extensions(&self) -> &[&str] {
        &["gz"]
    }
}
```

Because this example is so prudent, I've included an
`asset_decompression` example which implements this exact behaviour:

```rust
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_asset::<GzAsset>()
        .init_asset_loader::<GzAssetLoader>()
        .add_systems(Startup, setup)
        .add_systems(Update, decompress::<Image>)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2dBundle::default());

    commands.spawn((
        Compressed::<Image> {
            compressed: asset_server.load("data/compressed_image.png.gz"),
            ..default()
        },
        Sprite::default(),
        TransformBundle::default(),
        VisibilityBundle::default(),
    ));
}

fn decompress<A: Asset>(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut compressed_assets: ResMut<Assets<GzAsset>>,
    query: Query<(Entity, &Compressed<A>)>,
) {
    for (entity, Compressed { compressed, .. }) in query.iter() {
        let Some(GzAsset { uncompressed }) = compressed_assets.remove(compressed) else {
            continue;
        };

        let uncompressed = uncompressed.take::<A>().unwrap();

        commands
            .entity(entity)
            .remove::<Compressed<A>>()
            .insert(asset_server.add(uncompressed));
    }
}
```

A key limitation to this design is how to type the internally loaded
asset, since the example `GzAssetLoader` is unaware of the internal
asset type `A`. As such, in this example I store the contained asset as
an `ErasedLoadedAsset`, and leave it up to the consumer of the `GzAsset`
to handle typing the final result, which is the purpose of the
`decompress` system. This limitation can be worked around by providing
type information to the `GzAssetLoader`, such as `GzAssetLoader<Image,
ImageAssetLoader>`, but this would require registering the asset loader
for every possible decompression target.

Aside from this limitation, nested asset containerisation works as an
end user would expect; if the user registers a `TarAssetLoader`, and a
`GzAssetLoader`, then they can load assets with compound
containerisation, such as `images.tar.gz`.

---

## Changelog

- Added `LoadContext::load_direct_with_reader`
- Added `asset_decompression` example

## Notes

- While I believe my implementation of a Gzip asset loader is
reasonable, I haven't included it as a public feature of `bevy_asset` to
keep the scope of this PR as focussed as possible.
- I have included `flate2` as a `dev-dependency` for the example; it is
not included in the main dependency graph.
2023-11-16 17:47:31 +00:00
Zachary Harrold
3c689b9ca8
Update Event send methods to return EventId (#10551)
# Objective

- Fixes #10532

## Solution

I've updated the various `Event` send methods to return the sent
`EventId`(s). Since these methods previously returned nothing, and this
information is cheap to copy, there should be minimal negative
consequences to providing this additional information. In the case of
`send_batch`, an iterator is returned built from `Range` and `Map`,
which only consumes 16 bytes on the stack with no heap allocations for
all batch sizes. As such, the cost of this information is negligible.

These changes are reflected for `EventWriter` and `World`. For `World`,
the return types are optional to account for the possible lack of an
`Events` resource. Again, these methods previously returned no
information, so its inclusion should only be a benefit.

## Usage

Now when sending events, the IDs of those events is available for
immediate use:

```rust
// Example of a request-response system where the requester can track handled requests.

/// A system which can make and track requests
fn requester(
    mut requests: EventWriter<Request>,
    mut handled: EventReader<Handled>,
    mut pending: Local<HashSet<EventId<Request>>>,
) {
    // Check status of previous requests
    for Handled(id) in handled.read() {
        pending.remove(&id);
    }

    if !pending.is_empty() {
        error!("Not all my requests were handled on the previous frame!");
        pending.clear();
    }

    // Send a new request and remember its ID for later
    let request_id = requests.send(Request::MyRequest { /* ... */ });

    pending.insert(request_id);
}

/// A system which handles requests
fn responder(
    mut requests: EventReader<Request>,
    mut handled: EventWriter<Handled>,
) {
    for (request, id) in requests.read_with_id() {
        if handle(request).is_ok() {
            handled.send(Handled(id));
        }
    }
}
```

In the above example, a `requester` system can send request events, and
keep track of which ones are currently pending by `EventId`. Then, a
`responder` system can act on that event, providing the ID as a
reference that the `requester` can use. Before this PR, it was not
trivial for a system sending events to keep track of events by ID. This
is unfortunate, since for a system reading events, it is trivial to
access the ID of a event.

---

## Changelog

- Updated `Events`:
  - Added `send_batch`
  - Modified `send` to return the sent `EventId`
  - Modified `send_default` to return the sent `EventId`
- Updated `EventWriter`
  - Modified `send_batch` to return all sent `EventId`s
  - Modified `send` to return the sent `EventId`
  - Modified `send_default` to return the sent `EventId`
- Updated `World`
- Modified `send_event` to return the sent `EventId` if sent, otherwise
`None`.
- Modified `send_event_default` to return the sent `EventId` if sent,
otherwise `None`.
- Modified `send_event_batch` to return all sent `EventId`s if sent,
otherwise `None`.
- Added unit test `test_send_events_ids` to ensure returned `EventId`s
match the sent `Event`s
- Updated uses of modified methods.

## Migration Guide

### `send` / `send_default` / `send_batch`

For the following methods:

- `Events::send`
- `Events::send_default`
- `Events::send_batch`
- `EventWriter::send`
- `EventWriter::send_default`
- `EventWriter::send_batch`
- `World::send_event`
- `World::send_event_default`
- `World::send_event_batch`

Ensure calls to these methods either handle the returned value, or
suppress the result with `;`.

```rust
// Now fails to compile due to mismatched return type
fn send_my_event(mut events: EventWriter<MyEvent>) {
    events.send_default()
}

// Fix
fn send_my_event(mut events: EventWriter<MyEvent>) {
    events.send_default();
}
```

This will most likely be noticed within `match` statements:

```rust
// Before
match is_pressed {
    true => events.send(PlayerAction::Fire),
//                 ^--^ No longer returns ()
    false => {}
}

// After
match is_pressed {
    true => {
        events.send(PlayerAction::Fire);
    },
    false => {}
}
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-11-16 17:20:43 +00:00
François
ce60027db7
fix example custom_asset_reader on wasm (#10574)
# Objective

- Example `custom_asset_reader` fails to build in wasm
```
$ cargo build --profile release --target wasm32-unknown-unknown --example custom_asset_reader
   Compiling bevy v0.12.0 (/Users/runner/work/bevy-website/bevy-website)
error[E0432]: unresolved import `bevy::asset::io::file`
 --> examples/asset/custom_asset_reader.rs:7:9
  |
7 |         file::FileAssetReader, AssetReader, AssetReaderError, AssetSource, AssetSourceId,
  |  
```

## Solution

- Wrap the platform default asset reader instead of the
`FileAssetReader`
2023-11-16 01:50:13 +00:00
st0rmbtw
cbcd826612
Explicit color conversion methods (#10321)
# Objective

Closes #10319 

## Changelog
* Added a new `Color::rgba_from_array([f32; 4]) -> Color` method.
* Added a new `Color::rgb_from_array([f32; 3]) -> Color` method.
* Added a new `Color::rgba_linear_from_array([f32; 4]) -> Color` method.
* Added a new `Color::rgb_linear_from_array([f32; 3]) -> Color` method.
* Added a new `Color::hsla_from_array([f32; 4]) -> Color` method.
* Added a new `Color::hsl_from_array([f32; 3]) -> Color` method.
* Added a new `Color::lcha_from_array([f32; 4]) -> Color` method.
* Added a new `Color::lch_from_array([f32; 3]) -> Color` method.
* Added a new `Color::rgba_to_vec4(&self) -> Vec4` method.
* Added a new `Color::rgba_to_array(&self) -> [f32; 4]` method.
* Added a new `Color::rgb_to_vec3(&self) -> Vec3` method.
* Added a new `Color::rgb_to_array(&self) -> [f32; 3]` method.
* Added a new `Color::rgba_linear_to_vec4(&self) -> Vec4` method.
* Added a new `Color::rgba_linear_to_array(&self) -> [f32; 4]` method.
* Added a new `Color::rgb_linear_to_vec3(&self) -> Vec3` method.
* Added a new `Color::rgb_linear_to_array(&self) -> [f32; 3]` method.
* Added a new `Color::hsla_to_vec4(&self) -> Vec4` method.
* Added a new `Color::hsla_to_array(&self) -> [f32; 4]` method.
* Added a new `Color::hsl_to_vec3(&self) -> Vec3` method.
* Added a new `Color::hsl_to_array(&self) -> [f32; 3]` method.
* Added a new `Color::lcha_to_vec4(&self) -> Vec4` method.
* Added a new `Color::lcha_to_array(&self) -> [f32; 4]` method.
* Added a new `Color::lch_to_vec3(&self) -> Vec3` method.
* Added a new `Color::lch_to_array(&self) -> [f32; 3]` method.

## Migration Guide
`Color::from(Vec4)` is now `Color::rgba_from_array(impl Into<[f32; 4]>)`
`Vec4::from(Color)` is now `Color::rgba_to_vec4(&self)`

Before:
```rust
let color_vec4 = Vec4::new(0.5, 0.5, 0.5);
let color_from_vec4 = Color::from(color_vec4);

let color_array = [0.5, 0.5, 0.5];
let color_from_array = Color::from(color_array);
```
After:
```rust
let color_vec4 = Vec4::new(0.5, 0.5, 0.5);
let color_from_vec4 = Color::rgba_from_array(color_vec4);

let color_array = [0.5, 0.5, 0.5];
let color_from_array = Color::rgba_from_array(color_array);
```
2023-11-15 16:47:32 +00:00
Joseph
dcfae72386
Re-export ron in bevy_scene (#10529)
# Objective

Close #10504. Improve the development experience for working with scenes
by not requiring the user to specify a matching version of `ron` in
their `Cargo.toml`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-11-15 14:45:54 +00:00
Connor King
ab300d0ed9
Gizmo Arrows (#10550)
## Objective

- Add an arrow gizmo as suggested by #9400 

## Solution

(excuse my Protomen music)


https://github.com/bevyengine/bevy/assets/14184826/192adf24-079f-4a4b-a17b-091e892974ec

Wasn't horribly hard when i remembered i can change coordinate systems
whenever I want. Gave them four tips (as suggested by @alice-i-cecile in
discord) instead of trying to decide what direction the tips should
point.

Made the tip length default to 1/10 of the arrow's length, which looked
good enough to me. Hard-coded the angle from the body to the tips to 45
degrees.

## Still TODO

- [x] actual doc comments
- [x] doctests
- [x] `ArrowBuilder.with_tip_length()`

---

## Changelog

- Added `gizmos.arrow()` and `gizmos.arrow_2d()`
- Added arrows to `2d_gizmos` and `3d_gizmos` examples

## Migration Guide

N/A

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-11-15 14:19:15 +00:00
BrayMatter
bad55c1ad8
Ensure ExtendedMaterial works with reflection (to enable bevy_egui_inspector integration) (#10548)
# Objective

- Ensure ExtendedMaterial can be referenced in bevy_egui_inspector
correctly

## Solution

Add a more manual `TypePath` implementation to work around bugs in the
derive macro.
2023-11-15 12:48:36 +00:00
IceSentry
b1fd9eddbb
Fix post processing example to only run effect on camera with settings component (#10560)
# Objective

- The example says it will only run on a camera with the
`PostProcessingSettings` component but the node never filters it.

## Solution

- Add the component to the `ViewQuery`

closes: https://github.com/bevyengine/bevy/issues/10541
2023-11-14 22:35:40 +00:00
IceSentry
b1aa74d511
Add shader_material_2d example (#10542)
# Objective

- 2d materials have subtle differences with 3d materials that aren't
obvious to beginners

## Solution

- Add an example that shows how to make a 2d material
2023-11-14 02:18:25 +00:00
Rob Parrett
fe25fc6992
Fix minor issues with custom_asset example (#10337)
# Objective

- Use bevy's re-exported `AsyncReadExt` so users don't think they need
to depend on `futures-lite`.
- Fix a funky  error text
2023-11-14 01:21:02 +00:00
mamekoro
18d001d27c
Rename Timer::{percent,percent_left} to Timer::{fraction,fraction_remaining} (#10442)
# Objective
Fixes #10439

`Timer::percent()` and `Timer::percent_left()` return values in the
range of 0.0 to 1.0, even though their names contain "percent".

These functions should be renamed for clarity.

## Solution
- Rename `Timer::percent()` to `Timer::fraction()`
- Rename `Timer::percent_left()` to `Timer::fraction_remaining()`

---

## Changelog

### Changed
- Renamed `Timer::percent()` to `Timer::fraction()`
- Renamed `Timer::percent_left()` to `Timer::fraction_remaining()`

## Migration Guide
- `Timer::percent()` has been renamed to `Timer::fraction()`
- `Timer::percent_left()` has been renamed to
`Timer::fraction_remaining()`
2023-11-13 14:59:42 +00:00
Rob Parrett
cbadc31d19
Use a consistent scale factor and resolution in stress tests (#10474)
# Objective

Related to #10472.

Not having a hardcoded scale factor makes comparing results from these
stress tests difficult.

Contributors using high dpi screens may be rendering 4x as many pixels
as others (or more). Stress tests may have different behavior when moved
from one monitor in a dual setup to another. At very high resolutions,
different parts of the engine / hardware are being stressed.

1080p is also a far more common resolution for gaming.

## Solution

Use a consistent 1080p with `scale_factor_override: 1.0` everywhere.

In #9903, this sort of change was added specifically to `bevymark` and
`many_cubes` but it makes sense to do it everywhere.

## Discussion

- Maybe we should have a command line option, environment variable, or
`CI_TESTING_CONFIG` option for 1080p / 1440p / 4k.

- Will these look odd (small text?) when screenshotted and shown in the
example showcase? The aspect ratio is the same, but they will be
downscaled from 1080p instead of ~720p.

- Maybe there are other window properties that should be consistent
across stress tests. e.g. `resizable: false`.

- Should we add a `stress_test_window(title)` helper or something?

- Bevymark (pre-10472) was intentionally 800x600 to match "bunnymark", I
believe. I don't personally think this is very important.
2023-11-09 22:05:32 +00:00
Guillaume Gomez
fe7e31ea76
Fix intra-doc link warnings (#10445)
When `cargo doc -Zunstable-options -Zrustdoc-scrape-examples` (trying to
figure out why it doesn't work with bevy), I had the following warnings:

```
warning: unresolved link to `Quad`
 --> examples/2d/mesh2d.rs:1:66
  |
1 | //! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene.
  |                                                                  ^^^^ no item named `Quad` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `bevy` (example "mesh2d") generated 1 warning
warning: unresolved link to `update_weights`
 --> examples/animation/morph_targets.rs:6:17
  |
6 | //!   See the [`update_weights`] system for details.
  |                 ^^^^^^^^^^^^^^ no item named `update_weights` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: public documentation for `morph_targets` links to private item `name_morphs`
 --> examples/animation/morph_targets.rs:7:43
  |
7 | //! - How to read morph target names in [`name_morphs`].
  |                                           ^^^^^^^^^^^ this item is private
  |
  = note: this link will resolve properly if you pass `--document-private-items`
  = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default

warning: public documentation for `morph_targets` links to private item `setup_animations`
 --> examples/animation/morph_targets.rs:8:48
  |
8 | //! - How to play morph target animations in [`setup_animations`].
  |                                                ^^^^^^^^^^^^^^^^ this item is private
  |
  = note: this link will resolve properly if you pass `--document-private-items`

warning: `bevy` (example "morph_targets") generated 3 warnings
warning: unresolved link to `Quad`
 --> examples/2d/mesh2d_vertex_color_texture.rs:1:66
  |
1 | //! Shows how to render a polygonal [`Mesh`], generated from a [`Quad`] primitive, in a 2D scene.
  |                                                                  ^^^^ no item named `Quad` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `bevy` (example "mesh2d_vertex_color_texture") generated 1 warning
warning: unresolved link to `UIScale`
 --> examples/ui/ui_scaling.rs:1:36
  |
1 | //! This example illustrates the [`UIScale`] resource from `bevy_ui`.
  |                                    ^^^^^^^ no item named `UIScale` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `bevy` (example "ui_scaling") generated 1 warning
warning: unresolved link to `dependencies`
 --> examples/app/headless.rs:5:6
  |
5 | //! [dependencies]
  |      ^^^^^^^^^^^^ no item named `dependencies` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `bevy` (example "headless") generated 1 warning
warning: unresolved link to `Material2d`
 --> examples/2d/mesh2d_manual.rs:3:26
  |
3 | //! It doesn't use the [`Material2d`] abstraction, but changes the vertex buffer to include verte...
  |                          ^^^^^^^^^^ no item named `Material2d` in scope
  |
  = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
  = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: `bevy` (example "mesh2d_manual") generated 1 warning
```
2023-11-08 14:33:46 +00:00
Aevyrie
1d8d78ef0e
Update color and naming for consistency (#10367)
The `ClearColor` PR was merged before I was quite finished. This fixes a
few errors, and addresses Cart's feedback about the pixel perfect
example by updating the sprite colors to match the existing bevy bird
branding colors.


![image](https://github.com/bevyengine/bevy/assets/2632925/33722c45-ed66-4d3a-af11-f4197611a13c)
2023-11-04 02:09:23 +00:00
Markus Ort
fd232ad360
Add UI Materials (#9506)
# Objective

- Add Ui Materials so that UI can render more complex and animated
widgets.
- Fixes #5607 

## Solution
- Create a UiMaterial trait for specifying a Shader Asset and Bind Group
Layout/Data.
- Create a pipeline for rendering these Materials inside the Ui
layout/tree.
- Create a MaterialNodeBundle for simple spawning.

## Changelog

- Created a `UiMaterial` trait for specifying a Shader asset and Bind
Group.
- Created a `UiMaterialPipeline` for rendering said Materials.
- Added Example [`ui_material`
](https://github.com/MarkusTheOrt/bevy/blob/ui_material/examples/ui/ui_material.rs)
for example usage.
- Created
[`UiVertexOutput`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_vertex_output.wgsl)
export as VertexData for shaders.
- Created
[`material_ui`](https://github.com/MarkusTheOrt/bevy/blob/ui_material/crates/bevy_ui/src/render/ui_material.wgsl)
shader as default for both Vertex and Fragment shaders.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-11-03 22:33:01 +00:00
Aevyrie
1918608b02
Update default ClearColor to better match Bevy's branding (#10339)
# Objective

- Changes the default clear color to match the code block color on
Bevy's website.

## Solution

- Changed the clear color, updated text in examples to ensure adequate
contrast. Inconsistent usage of white text color set to use the default
color instead, which is already white.
- Additionally, updated the `3d_scene` example to make it look a bit
better, and use bevy's branding colors.


![image](https://github.com/bevyengine/bevy/assets/2632925/540a22c0-826c-4c33-89aa-34905e3e313a)
2023-11-03 12:57:38 +00:00
Marco Buono
44928e0df4
StandardMaterial Light Transmission (#8015)
# Objective

<img width="1920" alt="Screenshot 2023-04-26 at 01 07 34"
src="https://user-images.githubusercontent.com/418473/234467578-0f34187b-5863-4ea1-88e9-7a6bb8ce8da3.png">

This PR adds both diffuse and specular light transmission capabilities
to the `StandardMaterial`, with support for screen space refractions.
This enables realistically representing a wide range of real-world
materials, such as:

  - Glass; (Including frosted glass)
  - Transparent and translucent plastics;
  - Various liquids and gels;
  - Gemstones;
  - Marble;
  - Wax;
  - Paper;
  - Leaves;
  - Porcelain.

Unlike existing support for transparency, light transmission does not
rely on fixed function alpha blending, and therefore works with both
`AlphaMode::Opaque` and `AlphaMode::Mask` materials.

## Solution

- Introduces a number of transmission related fields in the
`StandardMaterial`;
- For specular transmission:
- Adds logic to take a view main texture snapshot after the opaque
phase; (in order to perform screen space refractions)
- Introduces a new `Transmissive3d` phase to the renderer, to which all
meshes with `transmission > 0.0` materials are sent.
- Calculates a light exit point (of the approximate mesh volume) using
`ior` and `thickness` properties
- Samples the snapshot texture with an adaptive number of taps across a
`roughness`-controlled radius enabling “blurry” refractions
- For diffuse transmission:
- Approximates transmitted diffuse light by using a second, flipped +
displaced, diffuse-only Lambertian lobe for each light source.

## To Do

- [x] Figure out where `fresnel_mix()` is taking place, if at all, and
where `dielectric_specular` is being calculated, if at all, and update
them to use the `ior` value (Not a blocker, just a nice-to-have for more
correct BSDF)
- To the _best of my knowledge, this is now taking place, after
964340cdd. The fresnel mix is actually "split" into two parts in our
implementation, one `(1 - fresnel(...))` in the transmission, and
`fresnel()` in the light implementations. A surface with more
reflectance now will produce slightly dimmer transmission towards the
grazing angle, as more of the light gets reflected.
- [x] Add `transmission_texture`
- [x] Add `diffuse_transmission_texture`
- [x] Add `thickness_texture`
- [x] Add `attenuation_distance` and `attenuation_color`
- [x] Connect values to glTF loader
  - [x] `transmission` and `transmission_texture`
  - [x] `thickness` and `thickness_texture`
  - [x] `ior`
- [ ] `diffuse_transmission` and `diffuse_transmission_texture` (needs
upstream support in `gltf` crate, not a blocker)
- [x] Add support for multiple screen space refraction “steps”
- [x] Conditionally create no transmission snapshot texture at all if
`steps == 0`
- [x] Conditionally enable/disable screen space refraction transmission
snapshots
- [x] Read from depth pre-pass to prevent refracting pixels in front of
the light exit point
- [x] Use `interleaved_gradient_noise()` function for sampling blur in a
way that benefits from TAA
- [x] Drill down a TAA `#define`, tweak some aspects of the effect
conditionally based on it
- [x] Remove const array that's crashing under HLSL (unless a new `naga`
release with https://github.com/gfx-rs/naga/pull/2496 comes out before
we merge this)
- [ ] Look into alternatives to the `switch` hack for dynamically
indexing the const array (might not be needed, compilers seem to be
decent at expanding it)
- [ ] Add pipeline keys for gating transmission (do we really want/need
this?)
- [x] Tweak some material field/function names?

## A Note on Texture Packing

_This was originally added as a comment to the
`specular_transmission_texture`, `thickness_texture` and
`diffuse_transmission_texture` documentation, I removed it since it was
more confusing than helpful, and will likely be made redundant/will need
to be updated once we have a better infrastructure for preprocessing
assets_

Due to how channels are mapped, you can more efficiently use a single
shared texture image
for configuring the following:

- R - `specular_transmission_texture`
- G - `thickness_texture`
- B - _unused_
- A - `diffuse_transmission_texture`

The `KHR_materials_diffuse_transmission` glTF extension also defines a
`diffuseTransmissionColorTexture`,
that _we don't currently support_. One might choose to pack the
intensity and color textures together,
using RGB for the color and A for the intensity, in which case this
packing advice doesn't really apply.

---

## Changelog

- Added a new `Transmissive3d` render phase for rendering specular
transmissive materials with screen space refractions
- Added rendering support for transmitted environment map light on the
`StandardMaterial` as a fallback for screen space refractions
- Added `diffuse_transmission`, `specular_transmission`, `thickness`,
`ior`, `attenuation_distance` and `attenuation_color` to the
`StandardMaterial`
- Added `diffuse_transmission_texture`, `specular_transmission_texture`,
`thickness_texture` to the `StandardMaterial`, gated behind a new
`pbr_transmission_textures` cargo feature (off by default, for maximum
hardware compatibility)
- Added `Camera3d::screen_space_specular_transmission_steps` for
controlling the number of “layers of transparency” rendered for
transmissive objects
- Added a `TransmittedShadowReceiver` component for enabling shadows in
(diffusely) transmitted light. (disabled by default, as it requires
carefully setting up the `thickness` to avoid self-shadow artifacts)
- Added support for the `KHR_materials_transmission`,
`KHR_materials_ior` and `KHR_materials_volume` glTF extensions
- Renamed items related to temporal jitter for greater consistency

## Migration Guide

- `SsaoPipelineKey::temporal_noise` has been renamed to
`SsaoPipelineKey::temporal_jitter`
- The `TAA` shader def (controlled by the presence of the
`TemporalAntiAliasSettings` component in the camera) has been replaced
with the `TEMPORAL_JITTER` shader def (controlled by the presence of the
`TemporalJitter` component in the camera)
- `MeshPipelineKey::TAA` has been replaced by
`MeshPipelineKey::TEMPORAL_JITTER`
- The `TEMPORAL_NOISE` shader def has been consolidated with
`TEMPORAL_JITTER`
2023-10-31 20:59:02 +00:00
Pascal Hertleif
0c2c52a0cd
Derive Error for more error types (#10240)
# Objective

Align all error-like types to implement `Error`.

Fixes  #10176

## Solution

- Derive `Error` on more types
- Refactor instances of manual implementations that could be derived

This adds thiserror as a dependency to bevy_transform, which might
increase compilation time -- but I don't know of any situation where you
might only use that but not any other crate that pulls in bevy_utils.

The `contributors` example has a `LoadContributorsError` type, but as
it's an example I have not updated it. Doing that would mean either
having a `use bevy_internal::utils::thiserror::Error;` in an example
file, or adding `thiserror` as a dev-dependency to the main `bevy`
crate.

---

## Changelog

- All `…Error` types now implement the `Error` trait
2023-10-28 22:20:37 +00:00
François
5d44d2a648
make deferred_rendering simpler to render for CI (#10150)
# Objective

- Example `deferred_rendering` sometimes fail to render in CI
- Make it easier to render

## Solution

- Reduce the complexity of the sphere used
2023-10-28 20:39:45 +00:00
SecretPocketCat
08248126f0
Example time api (#10204)
# Objective

- Fixes #10133 

## Solution

- Add a new example that focuses on using `Virtual` time

## Changelog

### Added

- new `virtual_time` example

### Changed

- moved `time` & `timers` examples to the new `examples/time` folder
2023-10-28 16:05:03 +00:00
Rob Parrett
7ca0a307f6
Fix outdated comment referencing CoreSet (#10294)
# Objective

Fix a comment that is referencing `CoreSet::UpdateFlush` which no longer
exists.

## Solution

Delete some words. Write some new words.
2023-10-28 03:18:27 +00:00
Carter Anderson
134750d18e
Image Sampler Improvements (#10254)
# Objective

- Build on the changes in https://github.com/bevyengine/bevy/pull/9982
- Use `ImageSamplerDescriptor` as the "public image sampler descriptor"
interface in all places (for consistency)
- Make it possible to configure textures to use the "default" sampler
(as configured in the `DefaultImageSampler` resource)
- Fix a bug introduced in #9982 that prevents configured samplers from
being used in Basis, KTX2, and DDS textures

---

## Migration Guide

- When using the `Image` API, use `ImageSamplerDescriptor` instead of
`wgpu::SamplerDescriptor`
- If writing custom wgpu renderer features that work with `Image`, call
`&image_sampler.as_wgpu()` to convert to a wgpu descriptor.
2023-10-26 23:30:09 +00:00
Niklas Eicker
317903f42a
Reduce noise in asset processing example (#10262)
# Objective

- Reduce noise to allow users to see previous asset changes and other
logs like from asset reloading
- The example file is named differently than the example

## Solution

- Only print the asset content if there are asset events
- Rename the example file to `asset_processing`
2023-10-25 19:37:03 +00:00
Griffin
6c74c8a311
fix deferred example fog values (#10249)
# Objective

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

## Solution

- Update fog color values matching the update to the values for
[atmospheric_fog.rs](https://github.com/bevyengine/bevy/pull/10226/files#diff-d43c34c9cf52e7ee72b56f8c4fc99ed86e9a1ec2f83642b839c4e75e1dd24f87)
in https://github.com/bevyengine/bevy/pull/10226

After this update:

![image](https://github.com/bevyengine/bevy/assets/33357138/5924f97d-e12b-496e-90fa-160d20b82a2e)
2023-10-24 21:44:59 +00:00
st0rmbtw
afe8b5f20d
Replace all usages of texture_descritor.size.* with the helper methods (#10227)
# Objective

A follow-up PR for https://github.com/bevyengine/bevy/pull/10221

## Changelog

Replaced usages of texture_descriptor.size with the helper methods of
`Image` through the entire engine codebase
2023-10-23 20:49:02 +00:00
François
7d504b89c3
Application lifetime events (suspend audio on Android) (#10158)
# Objective

- Handle pausing audio when Android app is suspended

## Solution

- This is the start of application lifetime events. They are mostly
useful on mobile
- Next version of winit should add a few more
- When application is suspended, send an event to notify the
application, and run the schedule one last time before actually
suspending the app
- Audio is now suspended too 🎉 



https://github.com/bevyengine/bevy/assets/8672791/d74e2e09-ee29-4f40-adf2-36a0c064f94e

---------

Co-authored-by: Marco Buono <418473+coreh@users.noreply.github.com>
2023-10-23 20:47:55 +00:00
Rafał Harabień
51c70bc98c
Fix fog color being inaccurate (#10226)
# Objective

Fog color was passed to shaders without conversion from sRGB to linear
color space. Because shaders expect colors in linear space this resulted
in wrong color being used. This is most noticeable in open scenes with
dark fog color and clear color set to the same color. In such case
background/clear color (which is properly processed) is going to be
darker than very far objects.

Example:

![image](https://github.com/bevyengine/bevy/assets/160391/89b70d97-b2d0-4bc5-80f4-c9e8b8801c4c)

[bevy-fog-color-bug.zip](https://github.com/bevyengine/bevy/files/13063718/bevy-fog-color-bug.zip)

## Solution

Add missing conversion of fog color to linear color space.

---

## Changelog

* Fixed conversion of fog color

## Migration Guide

- Colors in `FogSettings` struct (`color` and `directional_light_color`)
are now sent to the GPU in linear space. If you were using
`Color::rgb()`/`Color::rgba()` and would like to retain the previous
colors, you can quickly fix it by switching to
`Color::rgb_linear()`/`Color::rgba_linear()`.
2023-10-23 12:45:18 +00:00
st0rmbtw
8efcbf3e4f
Add convenient methods for Image (#10221)
# Objective
To get the width or height of an image you do:
```rust
self.texture_descriptor.size.{width, height}
```
that is quite verbose.
This PR adds some convenient methods for Image to reduce verbosity.

## Changelog
* Add a `width()` method for getting the width of an image.
* Add a `height()` method for getting the height of an image.
* Rename the `size()` method to `size_f32()`.
* Add a `size()` method for getting the size of an image as u32.
* Renamed the `aspect_2d()` method to `aspect_ratio()`.

## Migration Guide
Replace calls to the `Image::size()` method with `size_f32()`.
Replace calls to the `Image::aspect_2d()` method with `aspect_ratio()`.
2023-10-22 01:45:29 +00:00
François
c3627248f5
Fix alignment on ios simulator (#10178)
# Objective

- Fix #10165 
- On iOS simulator on apple silicon Macs, shader validation is going
through the host, but device limits are reported for the device. They
sometimes differ, and cause the validation to crash on something that
should work
```
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:]:5775: failed assertion `Draw Errors Validation
Fragment Function(fragment_): the offset into the buffer _naga_oil_mod_MJSXM6K7OBRHEOR2NVSXG2C7OZUWK527MJUW4ZDJNZTXG_memberfog that is bound at buffer index 6 must be a multiple of 256 but was set to 448.
```

## Solution

- Add a custom flag when building for the simulator and override the
buffer alignment
2023-10-21 22:19:46 +00:00
robtfm
6f2a5cb862
Bind group entries (#9694)
# Objective

Simplify bind group creation code. alternative to (and based on) #9476

## Solution

- Add a `BindGroupEntries` struct that can transparently be used where
`&[BindGroupEntry<'b>]` is required in BindGroupDescriptors.

Allows constructing the descriptor's entries as:
```rust
render_device.create_bind_group(
    "my_bind_group",
    &my_layout,
    &BindGroupEntries::with_indexes((
        (2, &my_sampler),
        (3, my_uniform),
    )),
);
```

instead of

```rust
render_device.create_bind_group(
    "my_bind_group",
    &my_layout,
    &[
        BindGroupEntry {
            binding: 2,
            resource: BindingResource::Sampler(&my_sampler),
        },
        BindGroupEntry {
            binding: 3,
            resource: my_uniform,
        },
    ],
);
```

or

```rust
render_device.create_bind_group(
    "my_bind_group",
    &my_layout,
    &BindGroupEntries::sequential((&my_sampler, my_uniform)),
);
```

instead of

```rust
render_device.create_bind_group(
    "my_bind_group",
    &my_layout,
    &[
        BindGroupEntry {
            binding: 0,
            resource: BindingResource::Sampler(&my_sampler),
        },
        BindGroupEntry {
            binding: 1,
            resource: my_uniform,
        },
    ],
);
```

the structs has no user facing macros, is tuple-type-based so stack
allocated, and has no noticeable impact on compile time.

- Also adds a `DynamicBindGroupEntries` struct with a similar api that
uses a `Vec` under the hood and allows extending the entries.
- Modifies `RenderDevice::create_bind_group` to take separate arguments
`label`, `layout` and `entries` instead of a `BindGroupDescriptor`
struct. The struct can't be stored due to the internal references, and
with only 3 members arguably does not add enough context to justify
itself.
- Modify the codebase to use the new api and the `BindGroupEntries` /
`DynamicBindGroupEntries` structs where appropriate (whenever the
entries slice contains more than 1 member).

## Migration Guide

- Calls to `RenderDevice::create_bind_group({BindGroupDescriptor {
label, layout, entries })` must be amended to
`RenderDevice::create_bind_group(label, layout, entries)`.
- If `label`s have been specified as `"bind_group_name".into()`, they
need to change to just `"bind_group_name"`. `Some("bind_group_name")`
and `None` will still work, but `Some("bind_group_name")` can optionally
be simplified to just `"bind_group_name"`.

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2023-10-21 15:39:22 +00:00
robtfm
61bad4eb57
update shader imports (#10180)
# Objective

- bump naga_oil to 0.10
- update shader imports to use rusty syntax

## Migration Guide

naga_oil 0.10 reworks the import mechanism to support more syntax to
make it more rusty, and test for item use before importing to determine
which imports are modules and which are items, which allows:

- use rust-style imports
```
#import bevy_pbr::{
    pbr_functions::{alpha_discard as discard, apply_pbr_lighting}, 
    mesh_bindings,
}
```

- import partial paths:
```
#import part::of::path
...
path::remainder::function();
```
which will call to `part::of::path::remainder::function`

- use fully qualified paths without importing:
```
// #import bevy_pbr::pbr_functions
bevy_pbr::pbr_functions::pbr()
```
- use imported items without qualifying
```
#import bevy_pbr::pbr_functions::pbr
// for backwards compatibility the old style is still supported:
// #import bevy_pbr::pbr_functions pbr
...
pbr()
```

- allows most imported items to end with `_` and numbers (naga_oil#30).
still doesn't allow struct members to end with `_` or numbers but it's
progress.

- the vast majority of existing shader code will work without changes,
but will emit "deprecated" warnings for old-style imports. these can be
suppressed with the `allow-deprecated` feature.

- partly breaks overrides (as far as i'm aware nobody uses these yet) -
now overrides will only be applied if the overriding module is added as
an additional import in the arguments to `Composer::make_naga_module` or
`Composer::add_composable_module`. this is necessary to support
determining whether imports are modules or items.
2023-10-21 11:51:58 +00:00
Carter Anderson
6f27e0e35f
Add asset_processor feature and remove AssetMode::ProcessedDev (#10194)
# Objective

Users shouldn't need to change their source code between "development
workflows" and "releasing". Currently, Bevy Asset V2 has two "processed"
asset modes `Processed` (assumes assets are already processed) and
`ProcessedDev` (starts an asset processor and processes assets). This
means that the mode must be changed _in code_ when switching from "app
dev" to "release". Very suboptimal.

We have already removed "runtime opt-in" for hot-reloading. Enabling the
`file_watcher` feature _automatically_ enables file watching in code.
This means deploying a game (without hot reloading enabled) just means
calling `cargo build --release` instead of `cargo run --features
bevy/file_watcher`.

We should adopt this pattern for asset processing.

## Solution

This adds the `asset_processor` feature, which will start the
`AssetProcessor` when an `AssetPlugin` runs in `AssetMode::Processed`.

The "asset processing workflow" is now:
1. Enable `AssetMode::Processed` on `AssetPlugin`
2. When developing, run with the `asset_processor` and `file_watcher`
features
3. When releasing, build without these features.

The `AssetMode::ProcessedDev` mode has been removed.
2023-10-20 20:50:26 +00:00
Robert Swain
15c54b5542
shadow_biases: Support moving the light position and resetting biases (#10185)
# Objective

- Make it possible to move the light position around in the
`shadow_biases` example
- Also support resetting the depth/normal biases to the engine defaults,
or zero.

## Solution

- The light position is displayed in the text overlay.
- The light position can be adjusted with
left/right/up/down/pgup/pgdown.
- The depth/normal biases can be reset to defaults by pressing R, or to
zero by pressing Z.

---------

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2023-10-19 14:41:39 +00:00
Robert Swain
219e2ac6e1
shadow_biases: Support different PCF methods (#10184)
# Objective

- Demonstrate the different shadow PCF methods in the `shadow_biases`
example

## Solution

- Cycle through the available methods when pressing the `F` key
- Display which filter method is being used
2023-10-19 13:08:18 +00:00
Martín Maita
0dc7e60d0e
Improve WebGPU unstable flags docs (#10163)
# Objective

- Fixes #9382

## Solution

- Added a few extra notes in regards to WebGPU experimental state and
the need of enabling unstable APIs through certain attribute flags in
`cargo_features.md` and the examples `README.md` files.
2023-10-18 17:30:44 +00:00
robtfm
c99351f7c2
allow extensions to StandardMaterial (#7820)
# Objective

allow extending `Material`s (including the built in `StandardMaterial`)
with custom vertex/fragment shaders and additional data, to easily get
pbr lighting with custom modifications, or otherwise extend a base
material.

# Solution

- added `ExtendedMaterial<B: Material, E: MaterialExtension>` which
contains a base material and a user-defined extension.
- added example `extended_material` showing how to use it
- modified AsBindGroup to have "unprepared" functions that return raw
resources / layout entries so that the extended material can combine
them

note: doesn't currently work with array resources, as i can't figure out
how to make the OwnedBindingResource::get_binding() work, as wgpu
requires a `&'a[&'a TextureView]` and i have a `Vec<TextureView>`.

# Migration Guide

manual implementations of `AsBindGroup` will need to be adjusted, the
changes are pretty straightforward and can be seen in the diff for e.g.
the `texture_binding_array` example.

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-10-17 21:28:08 +00:00
Ame :]
34da534917
fix typo in time.rs example (#10152)
## Solution
n -> s
2023-10-17 04:51:07 +00:00
Mike
88599d7fa0
Use chain in breakout example (#10124)
# Objective

- We should encourage of the simpler to reason about chain.

## Solution

- Use it in the breakout example

---

## Changelog

- Switch breakout to use `chain` instead of `before` and `after`
2023-10-16 22:15:32 +00:00
Nuutti Kotivuori
3d79dc4cdc
Unify FixedTime and Time while fixing several problems (#8964)
# Objective

Current `FixedTime` and `Time` have several problems. This pull aims to
fix many of them at once.

- If there is a longer pause between app updates, time will jump forward
a lot at once and fixed time will iterate on `FixedUpdate` for a large
number of steps. If the pause is merely seconds, then this will just
mean jerkiness and possible unexpected behaviour in gameplay. If the
pause is hours/days as with OS suspend, the game will appear to freeze
until it has caught up with real time.
- If calculating a fixed step takes longer than specified fixed step
period, the game will enter a death spiral where rendering each frame
takes longer and longer due to more and more fixed step updates being
run per frame and the game appears to freeze.
- There is no way to see current fixed step elapsed time inside fixed
steps. In order to track this, the game designer needs to add a custom
system inside `FixedUpdate` that calculates elapsed or step count in a
resource.
- Access to delta time inside fixed step is `FixedStep::period` rather
than `Time::delta`. This, coupled with the issue that `Time::elapsed`
isn't available at all for fixed steps, makes it that time requiring
systems are either implemented to be run in `FixedUpdate` or `Update`,
but rarely work in both.
- Fixes #8800 
- Fixes #8543 
- Fixes #7439
- Fixes #5692

## Solution

- Create a generic `Time<T>` clock that has no processing logic but
which can be instantiated for multiple usages. This is also exposed for
users to add custom clocks.
- Create three standard clocks, `Time<Real>`, `Time<Virtual>` and
`Time<Fixed>`, all of which contain their individual logic.
- Create one "default" clock, which is just `Time` (or `Time<()>`),
which will be overwritten from `Time<Virtual>` on each update, and
`Time<Fixed>` inside `FixedUpdate` schedule. This way systems that do
not care specifically which time they track can work both in `Update`
and `FixedUpdate` without changes and the behaviour is intuitive.
- Add `max_delta` to virtual time update, which limits how much can be
added to virtual time by a single update. This fixes both the behaviour
after a long freeze, and also the death spiral by limiting how many
fixed timestep iterations there can be per update. Possible future work
could be adding `max_accumulator` to add a sort of "leaky bucket" time
processing to possibly smooth out jumps in time while keeping frame rate
stable.
- Many minor tweaks and clarifications to the time functions and their
documentation.

## Changelog

- `Time::raw_delta()`, `Time::raw_elapsed()` and related methods are
moved to `Time<Real>::delta()` and `Time<Real>::elapsed()` and now match
`Time` API
- `FixedTime` is now `Time<Fixed>` and matches `Time` API. 
- `Time<Fixed>` default timestep is now 64 Hz, or 15625 microseconds.
- `Time` inside `FixedUpdate` now reflects fixed timestep time, making
systems portable between `Update ` and `FixedUpdate`.
- `Time::pause()`, `Time::set_relative_speed()` and related methods must
now be called as `Time<Virtual>::pause()` etc.
- There is a new `max_delta` setting in `Time<Virtual>` that limits how
much the clock can jump by a single update. The default value is 0.25
seconds.
- Removed `on_fixed_timer()` condition as `on_timer()` does the right
thing inside `FixedUpdate` now.

## Migration Guide

- Change all `Res<Time>` instances that access `raw_delta()`,
`raw_elapsed()` and related methods to `Res<Time<Real>>` and `delta()`,
`elapsed()`, etc.
- Change access to `period` from `Res<FixedTime>` to `Res<Time<Fixed>>`
and use `delta()`.
- The default timestep has been changed from 60 Hz to 64 Hz. If you wish
to restore the old behaviour, use
`app.insert_resource(Time::<Fixed>::from_hz(60.0))`.
- Change `app.insert_resource(FixedTime::new(duration))` to
`app.insert_resource(Time::<Fixed>::from_duration(duration))`
- Change `app.insert_resource(FixedTime::new_from_secs(secs))` to
`app.insert_resource(Time::<Fixed>::from_seconds(secs))`
- Change `system.on_fixed_timer(duration)` to
`system.on_timer(duration)`. Timers in systems placed in `FixedUpdate`
schedule automatically use the fixed time clock.
- Change `ResMut<Time>` calls to `pause()`, `is_paused()`,
`set_relative_speed()` and related methods to `ResMut<Time<Virtual>>`
calls. The API is the same, with the exception that `relative_speed()`
will return the actual last ste relative speed, while
`effective_relative_speed()` returns 0.0 if the time is paused and
corresponds to the speed that was set when the update for the current
frame started.

## Todo

- [x] Update pull name and description
- [x] Top level documentation on usage
- [x] Fix examples
- [x] Decide on default `max_delta` value
- [x] Decide naming of the three clocks: is `Real`, `Virtual`, `Fixed`
good?
- [x] Decide if the three clock inner structures should be in prelude
- [x] Decide on best way to configure values at startup: is manually
inserting a new clock instance okay, or should there be config struct
separately?
- [x] Fix links in docs
- [x] Decide what should be public and what not
- [x] Decide how `wrap_period` should be handled when it is changed
- [x] ~~Add toggles to disable setting the clock as default?~~ No,
separate pull if needed.
- [x] Add tests
- [x] Reformat, ensure adheres to conventions etc.
- [x] Build documentation and see that it looks correct

## Contributors

Huge thanks to @alice-i-cecile and @maniwani while building this pull.
It was a shared effort!

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Cameron <51241057+maniwani@users.noreply.github.com>
Co-authored-by: Jerome Humbert <djeedai@gmail.com>
2023-10-16 01:57:55 +00:00
Carter Anderson
35073cf7aa
Multiple Asset Sources (#9885)
This adds support for **Multiple Asset Sources**. You can now register a
named `AssetSource`, which you can load assets from like you normally
would:

```rust
let shader: Handle<Shader> = asset_server.load("custom_source://path/to/shader.wgsl");
```

Notice that `AssetPath` now supports `some_source://` syntax. This can
now be accessed through the `asset_path.source()` accessor.

Asset source names _are not required_. If one is not specified, the
default asset source will be used:

```rust
let shader: Handle<Shader> = asset_server.load("path/to/shader.wgsl");
```

The behavior of the default asset source has not changed. Ex: the
`assets` folder is still the default.

As referenced in #9714

## Why?

**Multiple Asset Sources** enables a number of often-asked-for
scenarios:

* **Loading some assets from other locations on disk**: you could create
a `config` asset source that reads from the OS-default config folder
(not implemented in this PR)
* **Loading some assets from a remote server**: you could register a new
`remote` asset source that reads some assets from a remote http server
(not implemented in this PR)
* **Improved "Binary Embedded" Assets**: we can use this system for
"embedded-in-binary assets", which allows us to replace the old
`load_internal_asset!` approach, which couldn't support asset
processing, didn't support hot-reloading _well_, and didn't make
embedded assets accessible to the `AssetServer` (implemented in this pr)

## Adding New Asset Sources

An `AssetSource` is "just" a collection of `AssetReader`, `AssetWriter`,
and `AssetWatcher` entries. You can configure new asset sources like
this:

```rust
app.register_asset_source(
    "other",
    AssetSource::build()
        .with_reader(|| Box::new(FileAssetReader::new("other")))
    )
)
```

Note that `AssetSource` construction _must_ be repeatable, which is why
a closure is accepted.
`AssetSourceBuilder` supports `with_reader`, `with_writer`,
`with_watcher`, `with_processed_reader`, `with_processed_writer`, and
`with_processed_watcher`.

Note that the "asset source" system replaces the old "asset providers"
system.

## Processing Multiple Sources

The `AssetProcessor` now supports multiple asset sources! Processed
assets can refer to assets in other sources and everything "just works".
Each `AssetSource` defines an unprocessed and processed `AssetReader` /
`AssetWriter`.

Currently this is all or nothing for a given `AssetSource`. A given
source is either processed or it is not. Later we might want to add
support for "lazy asset processing", where an `AssetSource` (such as a
remote server) can be configured to only process assets that are
directly referenced by local assets (in order to save local disk space
and avoid doing extra work).

## A new `AssetSource`: `embedded`

One of the big features motivating **Multiple Asset Sources** was
improving our "embedded-in-binary" asset loading. To prove out the
**Multiple Asset Sources** implementation, I chose to build a new
`embedded` `AssetSource`, which replaces the old `load_interal_asset!`
system.

The old `load_internal_asset!` approach had a number of issues:

* The `AssetServer` was not aware of (or capable of loading) internal
assets.
* Because internal assets weren't visible to the `AssetServer`, they
could not be processed (or used by assets that are processed). This
would prevent things "preprocessing shaders that depend on built in Bevy
shaders", which is something we desperately need to start doing.
* Each "internal asset" needed a UUID to be defined in-code to reference
it. This was very manual and toilsome.

The new `embedded` `AssetSource` enables the following pattern:

```rust
// Called in `crates/bevy_pbr/src/render/mesh.rs`
embedded_asset!(app, "mesh.wgsl");

// later in the app
let shader: Handle<Shader> = asset_server.load("embedded://bevy_pbr/render/mesh.wgsl");
```

Notice that this always treats the crate name as the "root path", and it
trims out the `src` path for brevity. This is generally predictable, but
if you need to debug you can use the new `embedded_path!` macro to get a
`PathBuf` that matches the one used by `embedded_asset`.

You can also reference embedded assets in arbitrary assets, such as WGSL
shaders:

```rust
#import "embedded://bevy_pbr/render/mesh.wgsl"
```

This also makes `embedded` assets go through the "normal" asset
lifecycle. They are only loaded when they are actually used!

We are also discussing implicitly converting asset paths to/from shader
modules, so in the future (not in this PR) you might be able to load it
like this:

```rust
#import bevy_pbr::render::mesh::Vertex
```

Compare that to the old system!

```rust
pub const MESH_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(3252377289100772450);

load_internal_asset!(app, MESH_SHADER_HANDLE, "mesh.wgsl", Shader::from_wgsl);

// The mesh asset is the _only_ accessible via MESH_SHADER_HANDLE and _cannot_ be loaded via the AssetServer.
```

## Hot Reloading `embedded`

You can enable `embedded` hot reloading by enabling the
`embedded_watcher` cargo feature:

```
cargo run --features=embedded_watcher
```

## Improved Hot Reloading Workflow

First: the `filesystem_watcher` cargo feature has been renamed to
`file_watcher` for brevity (and to match the `FileAssetReader` naming
convention).

More importantly, hot asset reloading is no longer configured in-code by
default. If you enable any asset watcher feature (such as `file_watcher`
or `rust_source_watcher`), asset watching will be automatically enabled.

This removes the need to _also_ enable hot reloading in your app code.
That means you can replace this:

```rust
app.add_plugins(DefaultPlugins.set(AssetPlugin::default().watch_for_changes()))
```

with this:

```rust
app.add_plugins(DefaultPlugins)
```

If you want to hot reload assets in your app during development, just
run your app like this:

```
cargo run --features=file_watcher
```

This means you can use the same code for development and deployment! To
deploy an app, just don't include the watcher feature

```
cargo build --release
```

My intent is to move to this approach for pretty much all dev workflows.
In a future PR I would like to replace `AssetMode::ProcessedDev` with a
`runtime-processor` cargo feature. We could then group all common "dev"
cargo features under a single `dev` feature:

```sh
# this would enable file_watcher, embedded_watcher, runtime-processor, and more
cargo run --features=dev
```

## AssetMode

`AssetPlugin::Unprocessed`, `AssetPlugin::Processed`, and
`AssetPlugin::ProcessedDev` have been replaced with an `AssetMode` field
on `AssetPlugin`.

```rust
// before 
app.add_plugins(DefaultPlugins.set(AssetPlugin::Processed { /* fields here */ })

// after 
app.add_plugins(DefaultPlugins.set(AssetPlugin { mode: AssetMode::Processed, ..default() })
```

This aligns `AssetPlugin` with our other struct-like plugins. The old
"source" and "destination" `AssetProvider` fields in the enum variants
have been replaced by the "asset source" system. You no longer need to
configure the AssetPlugin to "point" to custom asset providers.

## AssetServerMode

To improve the implementation of **Multiple Asset Sources**,
`AssetServer` was made aware of whether or not it is using "processed"
or "unprocessed" assets. You can check that like this:

```rust
if asset_server.mode() == AssetServerMode::Processed {
    /* do something */
}
```

Note that this refactor should also prepare the way for building "one to
many processed output files", as it makes the server aware of whether it
is loading from processed or unprocessed sources. Meaning we can store
and read processed and unprocessed assets differently!

## AssetPath can now refer to folders

The "file only" restriction has been removed from `AssetPath`. The
`AssetServer::load_folder` API now accepts an `AssetPath` instead of a
`Path`, meaning you can load folders from other asset sources!

## Improved AssetPath Parsing

AssetPath parsing was reworked to support sources, improve error
messages, and to enable parsing with a single pass over the string.
`AssetPath::new` was replaced by `AssetPath::parse` and
`AssetPath::try_parse`.

## AssetWatcher broken out from AssetReader

`AssetReader` is no longer responsible for constructing `AssetWatcher`.
This has been moved to `AssetSourceBuilder`.


## Duplicate Event Debouncing

Asset V2 already debounced duplicate filesystem events, but this was
_input_ events. Multiple input event types can produce the same _output_
`AssetSourceEvent`. Now that we have `embedded_watcher`, which does
expensive file io on events, it made sense to debounce output events
too, so I added that! This will also benefit the AssetProcessor by
preventing integrity checks for duplicate events (and helps keep the
noise down in trace logs).

## Next Steps

* **Port Built-in Shaders**: Currently the primary (and essentially
only) user of `load_interal_asset` in Bevy's source code is "built-in
shaders". I chose not to do that in this PR for a few reasons:
1. We need to add the ability to pass shader defs in to shaders via meta
files. Some shaders (such as MESH_VIEW_TYPES) need to pass shader def
values in that are defined in code.
2. We need to revisit the current shader module naming system. I think
we _probably_ want to imply modules from source structure (at least by
default). Ideally in a way that can losslessly convert asset paths
to/from shader modules (to enable the asset system to resolve modules
using the asset server).
  3. I want to keep this change set minimal / get this merged first.
* **Deprecate `load_internal_asset`**: we can't do that until we do (1)
and (2)
* **Relative Asset Paths**: This PR significantly increases the need for
relative asset paths (which was already pretty high). Currently when
loading dependencies, it is assumed to be an absolute path, which means
if in an `AssetLoader` you call `context.load("some/path/image.png")` it
will assume that is the "default" asset source, _even if the current
asset is in a different asset source_. This will cause breakage for
AssetLoaders that are not designed to add the current source to whatever
paths are being used. AssetLoaders should generally not need to be aware
of the name of their current asset source, or need to think about the
"current asset source" generally. We should build apis that support
relative asset paths and then encourage using relative paths as much as
possible (both via api design and docs). Relative paths are also
important because they will allow developers to move folders around
(even across providers) without reprocessing, provided there is no path
breakage.
2023-10-13 23:17:32 +00:00
IceSentry
068e42a01f
Configurable colors for wireframe (#5303)
# Objective

- Make the wireframe colors configurable at the global level and the
single mesh level
- Based on https://github.com/bevyengine/bevy/pull/5314

This video shows what happens when playing with various settings from
the example


https://github.com/bevyengine/bevy/assets/8348954/1ee9aee0-fab7-4da8-bc5d-8d0562bb34e6

## Solution

- Add a `color` field to the `WireframeMaterial`
- Use a `WireframeColor` component to configure the color per entity
- Add a `default_color` field to `WireframeConfig` for global wireframes
or wireframes with no specified color.

## Notes

- Most of the docs and the general idea for `WireframeColor` came from
[UberLambda](https://github.com/UberLambda) in #3677 but the code ended
up completely different so I created a separate branch. ~~I'm not sure
how to correctly credit them on this PR.~~ (I re-created the commit but
I added them as co-author in the commit message)

~~Closes https://github.com/bevyengine/bevy/pull/3677~~
~~Closes https://github.com/bevyengine/bevy/pull/5301~~

~~https://github.com/bevyengine/bevy/pull/5314 should be merged before
this PR.~~
2023-10-13 00:06:24 +00:00
Griffin
a15d152635
Deferred Renderer (#9258)
# Objective

- Add a [Deferred
Renderer](https://en.wikipedia.org/wiki/Deferred_shading) to Bevy.
- This allows subsequent passes to access per pixel material information
before/during shading.
- Accessing this per pixel material information is needed for some
features, like GI. It also makes other features (ex. Decals) simpler to
implement and/or improves their capability. There are multiple
approaches to accomplishing this. The deferred shading approach works
well given the limitations of WebGPU and WebGL2.

Motivation: [I'm working on a GI solution for
Bevy](https://youtu.be/eH1AkL-mwhI)

# Solution
- The deferred renderer is implemented with a prepass and a deferred
lighting pass.
- The prepass renders opaque objects into the Gbuffer attachment
(`Rgba32Uint`). The PBR shader generates a `PbrInput` in mostly the same
way as the forward implementation and then [packs it into the
Gbuffer](ec1465559f/crates/bevy_pbr/src/render/pbr.wgsl (L168)).
- The deferred lighting pass unpacks the `PbrInput` and [feeds it into
the pbr()
function](ec1465559f/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl (L65)),
then outputs the shaded color data.

- There is now a resource
[DefaultOpaqueRendererMethod](ec1465559f/crates/bevy_pbr/src/material.rs (L599))
that can be used to set the default render method for opaque materials.
If materials return `None` from
[opaque_render_method()](ec1465559f/crates/bevy_pbr/src/material.rs (L131))
the `DefaultOpaqueRendererMethod` will be used. Otherwise, custom
materials can also explicitly choose to only support Deferred or Forward
by returning the respective
[OpaqueRendererMethod](ec1465559f/crates/bevy_pbr/src/material.rs (L603))

- Deferred materials can be used seamlessly along with both opaque and
transparent forward rendered materials in the same scene. The [deferred
rendering
example](https://github.com/DGriffin91/bevy/blob/deferred/examples/3d/deferred_rendering.rs)
does this.

- The deferred renderer does not support MSAA. If any deferred materials
are used, MSAA must be disabled. Both TAA and FXAA are supported.

- Deferred rendering supports WebGL2/WebGPU. 

## Custom deferred materials
- Custom materials can support both deferred and forward at the same
time. The
[StandardMaterial](ec1465559f/crates/bevy_pbr/src/render/pbr.wgsl (L166))
does this. So does [this
example](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56).
- Custom deferred materials that require PBR lighting can create a
`PbrInput`, write it to the deferred GBuffer and let it be rendered by
the `PBRDeferredLightingPlugin`.
- Custom deferred materials that require custom lighting have two
options:
1. Use the base_color channel of the `PbrInput` combined with the
`STANDARD_MATERIAL_FLAGS_UNLIT_BIT` flag.
[Example.](https://github.com/DGriffin91/bevy_glowy_orb_tutorial/blob/deferred/assets/shaders/glowy.wgsl#L56)
(If the unlit bit is set, the base_color is stored as RGB9E5 for extra
precision)
2. A Custom Deferred Lighting pass can be created, either overriding the
default, or running in addition. The a depth buffer is used to limit
rendering to only the required fragments for each deferred lighting
pass. Materials can set their respective depth id via the
[deferred_lighting_pass_id](b79182d2a3/crates/bevy_pbr/src/prepass/prepass_io.wgsl (L95))
attachment. The custom deferred lighting pass plugin can then set [its
corresponding
depth](ec1465559f/crates/bevy_pbr/src/deferred/deferred_lighting.wgsl (L37)).
Then with the lighting pass using
[CompareFunction::Equal](ec1465559f/crates/bevy_pbr/src/deferred/mod.rs (L335)),
only the fragments with a depth that equal the corresponding depth
written in the material will be rendered.

Custom deferred lighting plugins can also be created to render the
StandardMaterial. The default deferred lighting plugin can be bypassed
with `DefaultPlugins.set(PBRDeferredLightingPlugin { bypass: true })`

---------

Co-authored-by: nickrart <nickolas.g.russell@gmail.com>
2023-10-12 22:10:38 +00:00
IceSentry
e05a9f9315
use Material for wireframes (#5314)
# Objective

- Use the `Material` abstraction for the Wireframes
- Right now this doesn't have many benefits other than simplifying some
of the rendering code
- We can reuse the default vertex shader and avoid rendering
inconsistencies
- The goal is to have a material with a color on each mesh so this
approach will make it easier to implement
- Originally done in https://github.com/bevyengine/bevy/pull/5303 but I
decided to split the Material part to it's own PR and then adding
per-entity colors and globally configurable colors will be a much
simpler diff.

## Solution

- Use the new `Material` abstraction for the Wireframes

## Notes

It's possible this isn't ideal since this adds a
`Handle<WireframeMaterial>` to all the meshes compared to the original
approach that didn't need anything. I didn't notice any performance
impact on my machine.

This might be a surprising usage of `Material` at first, because
intuitively you only have one material per mesh, but the way it's
implemented you can have as many different types of materials as you
want on a mesh.

## Migration Guide
`WireframePipeline` was removed. If you were using it directly, please
create an issue explaining your use case.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-10-10 18:53:22 +00:00
François
a52ca170ac
foxes shouldn't march in sync (#10070)
# Objective

- All foxes in `many_foxes` are running in sync
- It's scary
- It can also be a source of optimisation that won't be useful in a
general case

## Solution

- Advance the animation of each fox so that they are not synced anymore
by default
- Add a cli arg to enable them running in sync
2023-10-09 22:45:02 +00:00
Marco Buono
12a2f83edd
Add consuming builder methods for more ergonomic Mesh creation (#10056)
# Objective

- This PR aims to make creating meshes a little bit more ergonomic,
specifically by removing the need for intermediate mutable variables.

## Solution

- We add methods that consume the `Mesh` and return a mesh with the
specified changes, so that meshes can be entirely constructed via
builder-style calls, without intermediate variables;
- Methods are flagged with `#[must_use]` to ensure proper use;
- Examples are updated to use the new methods where applicable. Some
examples are kept with the mutating methods so that users can still
easily discover them, and also where the new methods wouldn't really be
an improvement.

## Examples

Before:

```rust
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vs);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, vns);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vts);
mesh.set_indices(Some(Indices::U32(tris)));
mesh
```

After:

```rust
Mesh::new(PrimitiveTopology::TriangleList)
    .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vs)
    .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vns)
    .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, vts)
    .with_indices(Some(Indices::U32(tris)))
```

Before:

```rust
let mut cube = Mesh::from(shape::Cube { size: 1.0 });

cube.generate_tangents().unwrap();

PbrBundle {
    mesh: meshes.add(cube),
    ..default()
}
```

After:

```rust
PbrBundle {
    mesh: meshes.add(
        Mesh::from(shape::Cube { size: 1.0 })
            .with_generated_tangents()
            .unwrap(),
    ),
    ..default()
}
```

---

## Changelog

- Added consuming builder methods for more ergonomic `Mesh` creation:
`with_inserted_attribute()`, `with_removed_attribute()`,
`with_indices()`, `with_duplicated_vertices()`,
`with_computed_flat_normals()`, `with_generated_tangents()`,
`with_morph_targets()`, `with_morph_target_names()`.
2023-10-09 19:47:41 +00:00
Rob Parrett
39c68e3f92
More ergonomic spatial audio (#9800)
# Objective

Spatial audio was heroically thrown together at the last minute for Bevy
0.10, but right now it's a bit of a pain to use -- users need to
manually update audio sinks with the position of the listener / emitter.

Hopefully the migration guide entry speaks for itself.

## Solution

Add a new `SpatialListener` component and automatically update sinks
with the position of the listener and and emitter.

## Changelog

`SpatialAudioSink`s are now automatically updated with positions of
emitters and listeners.

## Migration Guide

Spatial audio now automatically uses the transform of the `AudioBundle`
and of an entity with a `SpatialListener` component.

If you were manually scaling emitter/listener positions, you can use the
`spatial_scale` field of `AudioPlugin` instead.

```rust

// Old

commands.spawn(
    SpatialAudioBundle {
        source: asset_server.load("sounds/Windless Slopes.ogg"),
        settings: PlaybackSettings::LOOP,
        spatial: SpatialSettings::new(listener_position, gap, emitter_position),
    },
);

fn update(
    emitter_query: Query<(&Transform, &SpatialAudioSink)>,
    listener_query: Query<&Transform, With<Listener>>,
) {
    let listener = listener_query.single();

    for (transform, sink) in &emitter_query {
        sink.set_emitter_position(transform.translation);
        sink.set_listener_position(*listener, gap);
    }
}

// New

commands.spawn((
    SpatialBundle::from_transform(Transform::from_translation(emitter_position)),
    AudioBundle {
        source: asset_server.load("sounds/Windless Slopes.ogg"),
        settings: PlaybackSettings::LOOP.with_spatial(true),
    },
));

commands.spawn((
    SpatialBundle::from_transform(Transform::from_translation(listener_position)),
    SpatialListener::new(gap),
));
```

## Discussion

I removed `SpatialAudioBundle` because the `SpatialSettings` component
was made mostly redundant, and without that it was identical to
`AudioBundle`.

`SpatialListener` is a bare component and not a bundle which is feeling
like a maybe a strange choice. That happened from a natural aversion
both to nested bundles and to duplicating `Transform` etc in bundles and
from figuring that it is likely to just be tacked on to some other
bundle (player, head, camera) most of the time.

Let me know what you think about these things / everything else.

---------

Co-authored-by: Mike <mike.hsu@gmail.com>
2023-10-09 19:43:56 +00:00
radiish
262846e702
reflect: TypePath part 2 (#8768)
# Objective

- Followup to #7184.
- ~Deprecate `TypeUuid` and remove its internal references.~ No longer
part of this PR.
- Use `TypePath` for the type registry, and (de)serialisation instead of
`std::any::type_name`.
- Allow accessing type path information behind proxies.

## Solution
- Introduce methods on `TypeInfo` and friends for dynamically querying
type path. These methods supersede the old `type_name` methods.
- Remove `Reflect::type_name` in favor of `DynamicTypePath::type_path`
and `TypeInfo::type_path_table`.
- Switch all uses of `std::any::type_name` in reflection, non-debugging
contexts to use `TypePath`.

---

## Changelog

- Added `TypePathTable` for dynamically accessing methods on `TypePath`
through `TypeInfo` and the type registry.
- Removed `type_name` from all `TypeInfo`-like structs.
- Added `type_path` and `type_path_table` methods to all `TypeInfo`-like
structs.
- Removed `Reflect::type_name` in favor of
`DynamicTypePath::reflect_type_path` and `TypeInfo::type_path`.
- Changed the signature of all `DynamicTypePath` methods to return
strings with a static lifetime.

## Migration Guide

- Rely on `TypePath` instead of `std::any::type_name` for all stability
guarantees and for use in all reflection contexts, this is used through
with one of the following APIs:
  - `TypePath::type_path` if you have a concrete type and not a value.
- `DynamicTypePath::reflect_type_path` if you have an `dyn Reflect`
value without a concrete type.
- `TypeInfo::type_path` for use through the registry or if you want to
work with the represented type of a `DynamicFoo`.
  
- Remove `type_name` from manual `Reflect` implementations.
- Use `type_path` and `type_path_table` in place of `type_name` on
`TypeInfo`-like structs.
- Use `get_with_type_path(_mut)` over `get_with_type_name(_mut)`.

## Note to reviewers

I think if anything we were a little overzealous in merging #7184 and we
should take that extra care here.

In my mind, this is the "point of no return" for `TypePath` and while I
think we all agree on the design, we should carefully consider if the
finer details and current implementations are actually how we want them
moving forward.

For example [this incorrect `TypePath` implementation for
`String`](3fea3c6c0b/crates/bevy_reflect/src/impls/std.rs (L90))
(note that `String` is in the default Rust prelude) snuck in completely
under the radar.
2023-10-09 19:33:03 +00:00
Niklas Eicker
46f3b26724
Improve selection of iOS device in mobile example (#9282)
# Objective

- Make sure that users can "just run" the mobile example
- Device descriptions like `iPhone SE (3rd generation)
(F647334F-D7C1-4BD6-9B5F-0E3D9713C02B) (Shutdown)` currently fail
([issue
found](https://github.com/NiklasEi/bevy_game_template/pull/61#discussion_r1269747507)
by @CleanCut)

## Solution

- Improve the script that grabs the device UUID from the device list
2023-10-08 20:57:41 +00:00
François
154a490445
fix example mesh2d_manual (#9941)
# Objective

- After https://github.com/bevyengine/bevy/pull/9903, example
`mesh2d_manual` doesn't render anything

## Solution

- Fix the example using the new `RenderMesh2dInstances`
2023-10-06 20:13:09 +00:00
Zachary Harrold
dd46fd3aee
Removed anyhow (#10003)
# Objective

- Fixes #8140

## Solution

- Added Explicit Error Typing for `AssetLoader` and `AssetSaver`, which
were the last instances of `anyhow` in use across Bevy.

---

## Changelog

- Added an associated type `Error` to `AssetLoader` and `AssetSaver` for
use with the `load` and `save` methods respectively.
- Changed `ErasedAssetLoader` and `ErasedAssetSaver` `load` and `save`
methods to use `Box<dyn Error + Send + Sync + 'static>` to allow for
arbitrary `Error` types from the non-erased trait variants. Note the
strict requirements match the pre-existing requirements around
`anyhow::Error`.

## Migration Guide

- `anyhow` is no longer exported by `bevy_asset`; Add it to your own
project (if required).
- `AssetLoader` and `AssetSaver` have an associated type `Error`; Define
an appropriate error type (e.g., using `thiserror`), or use a pre-made
error type (e.g., `anyhow::Error`). Note that using `anyhow::Error` is a
drop-in replacement.
- `AssetLoaderError` has been removed; Define a new error type, or use
an alternative (e.g., `anyhow::Error`)
- All the first-party `AssetLoader`'s and `AssetSaver`'s now return
relevant (and narrow) error types instead of a single ambiguous type;
Match over the specific error type, or encapsulate (`Box<dyn>`,
`thiserror`, `anyhow`, etc.)

## Notes

A simpler PR to resolve this issue would simply define a Bevy `Error`
type defined as `Box<dyn std::error::Error + Send + Sync + 'static>`,
but I think this type of error handling should be discouraged when
possible. Since only 2 traits required the use of `anyhow`, it isn't a
substantive body of work to solidify these error types, and remove
`anyhow` entirely. End users are still encouraged to use `anyhow` if
that is their preferred error handling style. Arguably, adding the
`Error` associated type gives more freedom to end-users to decide
whether they want more or less explicit error handling (`anyhow` vs
`thiserror`).

As an aside, I didn't perform any testing on Android or WASM. CI passed
locally, but there may be mistakes for those platforms I missed.
2023-10-06 07:20:13 +00:00
IceSentry
a962240866
Alternate wireframe override api (#10023)
# Objective

https://github.com/bevyengine/bevy/pull/7328 introduced an API to
override the global wireframe config. I believe it is flawed for a few
reasons.

This PR uses a non-breaking API. Instead of making the `Wireframe` an
enum I introduced the `NeverRenderWireframe` component. Here's the
reason why I think this is better:
- Easier to migrate since it doesn't change the old behaviour.
Essentially nothing to migrate. Right now this PR is a breaking change
but I don't think it has to be.
- It's similar to other "per mesh" rendering features like
NotShadowCaster/NotShadowReceiver
- It doesn't force new users to also think about global vs not global if
all they want is to render a wireframe
- This would also let you filter at the query definition level instead
of filtering when running the query

## Solution

- Introduce a `NeverRenderWireframe` component that ignores the global
config

---

## Changelog

- Added a `NeverRenderWireframe` component that ignores the global
`WireframeConfig`
2023-10-05 12:12:08 +00:00
ickshonpe
2e887b856f
UI node outlines (#9931)
# Objective

Add support for drawing outlines outside the borders of UI nodes.

## Solution
Add a new `Outline` component with `width`, `offset` and `color` fields.
Added `outline_width` and `outline_offset` fields to `Node`. This is set
after layout recomputation by the `resolve_outlines_system`.

Properties of outlines:
* Unlike borders, outlines have to be the same width on each edge.
* Outlines do not occupy any space in the layout.
* The `Outline` component won't be added to any of the UI node bundles,
it needs to be inserted separately.
* Outlines are drawn outside the node's border, so they are clipped
using the clipping rect of their entity's parent UI node (if it exists).
* `Val::Percent` outline widths are resolved based on the width of the
outlined UI node.
* The offset of the `Outline` adds space between an outline and the edge
of its node.

I was leaning towards adding an `outline` field to `Style` but a
separate component seems more efficient for queries and change
detection. The `Outline` component isn't added to bundles for the same
reason.

---
## Examples

* This image is from the `borders` example from the Bevy UI examples but
modified to include outlines. The UI nodes are the dark red rectangles,
the bright red rectangles are borders and the white lines offset from
each node are the outlines. The yellow rectangles are separate nodes
contained with the dark red nodes:
 
<img width="406" alt="outlines"
src="https://github.com/bevyengine/bevy/assets/27962798/4e6f315a-019f-42a4-94ee-cca8e684d64a">

* This is from the same example but using a branch that implements
border-radius. Here the the outlines are in orange and there is no
offset applied. I broke the borders implementation somehow during the
merge, which is why some of the borders from the first screenshot are
missing 😅. The outlines work nicely though (as long as you
can forgive the lack of anti-aliasing):


![image](https://github.com/bevyengine/bevy/assets/27962798/d15560b6-6cd6-42e5-907b-56ccf2ad5e02)

---
## Notes

As I explained above, I don't think the `Outline` component should be
added to UI node bundles. We can have helper functions though, perhaps
something as simple as:

```rust
impl NodeBundle {
    pub fn with_outline(self, outline: Outline) -> (Self, Outline) {
        (self, outline)
    }
}
```

I didn't include anything like this as I wanted to keep the PR's scope
as narrow as possible. Maybe `with_outline` should be in a trait that we
implement for each UI node bundle.

---

## Changelog
Added support for outlines to Bevy UI.
* The `Outline` component adds an outline to a UI node.
* The `outline_width` field added to `Node` holds the resolved width of
the outline, which is set by the `resolve_outlines_system` after layout
recomputation.
* Outlines are drawn by the system `extract_uinode_outlines`.
2023-10-05 12:10:32 +00:00
Ame :]
7541bf862c
Fix some warnings shown in nightly (#10012)
# Objective

Fix warnings:
- #[warn(clippy::needless_pass_by_ref_mut)]
- #[warn(elided_lifetimes_in_associated_constant)]

## Solution

- Remove mut
- add &'static

## Errors

```rust
warning: this argument is a mutable reference, but not used mutably
   --> crates/bevy_hierarchy/src/child_builder.rs:672:31
    |
672 |     fn assert_children(world: &mut World, parent: Entity, children: Option<&[Entity]>) {
    |                               ^^^^^^^^^^ help: consider changing to: `&World`
    |
    = note: this is cfg-gated and may require further changes
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
    = note: `#[warn(clippy::needless_pass_by_ref_mut)]` on by default
```


```rust
warning: `&` without an explicit lifetime name cannot be used here
   --> examples/shader/post_processing.rs:120:21
    |
120 |     pub const NAME: &str = "post_process";
    |                     ^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #115010 <https://github.com/rust-lang/rust/issues/115010>
    = note: `#[warn(elided_lifetimes_in_associated_constant)]` on by default
help: use the `'static` lifetime
    |
120 |     pub const NAME: &'static str = "post_process";
    |                      +++++++


```
2023-10-05 05:41:09 +00:00
Wybe Westra
f9e50e767b
Allow overriding global wireframe setting. (#7328)
# Objective

Allow the user to choose between "Add wireframes to these specific
entities" or "Add wireframes to everything _except_ these specific
entities".
Fixes #7309

# Solution
Make the `Wireframe` component act like an override to the global
configuration.
Having `global` set to `false`, and adding a `Wireframe` with `enable:
true` acts exactly as before.
But now the opposite is also possible: Set `global` to `true` and add a
`Wireframe` with `enable: false` will draw wireframes for everything
_except_ that entity.

Updated the example to show how overriding the global config works.
2023-10-04 02:34:44 +00:00
Bruce Mitchener
9a798aa100
Allow clippy::type_complexity in more places. (#9796)
# Objective

- See fewer warnings when running `cargo clippy` locally.

## Solution

- allow `clippy::type_complexity` in more places, which also signals to
users they should do the same.
2023-10-02 21:55:16 +00:00
Jacques Schutte
857fb9c724
Remove monkey.gltf (#9974)
# Objective

- Fixes #9967

## Solution

- Remove `monkey.gltf`
- Added `torus.gltf`, which is two torus meshes joined together, to
replace `monkey.gltf` in the examples

## Examples

I made `torus.gltf` mainly so that the multiple_windows example clearly
shows the different camera angles

### asset_loading

![image](https://github.com/bevyengine/bevy/assets/425184/0ee51013-973d-4b23-9aa6-d254fecde7f1)

### hot_asset_reloading

![image](https://github.com/bevyengine/bevy/assets/425184/b2a2b1d8-167e-478b-b954-756ca0bbe469)

### multiple_windows:

![image](https://github.com/bevyengine/bevy/assets/425184/cb23de2c-9ff8-4843-a5c0-981e4d29ae49)

![image](https://github.com/bevyengine/bevy/assets/425184/b00bc2c7-66e8-4881-8fab-08269e223961)
2023-09-30 02:50:31 +00:00
SADIK KUZU
483f2464a8
Fix typos (#9965)
# Objective

- There were a few typos in the project.
- This PR fixes these typos.

## Solution

- Fixing the typos.

Signed-off-by: SADIK KUZU <sadikkuzu@hotmail.com>
2023-09-29 12:26:41 +00:00
ickshonpe
418405046a
text_wrap_debug scale factor commandline args (#9951)
# Objective

Add commandline arguments to `text_wrap_debug` to set the window and UI
scale factors.
2023-09-28 21:15:55 +00:00
Robert Swain
b6ead2be95
Use EntityHashMap<Entity, T> for render world entity storage for better performance (#9903)
# Objective

- Improve rendering performance, particularly by avoiding the large
system commands costs of using the ECS in the way that the render world
does.

## Solution

- Define `EntityHasher` that calculates a hash from the
`Entity.to_bits()` by `i | (i.wrapping_mul(0x517cc1b727220a95) << 32)`.
`0x517cc1b727220a95` is something like `u64::MAX / N` for N that gives a
value close to π and that works well for hashing. Thanks for @SkiFire13
for the suggestion and to @nicopap for alternative suggestions and
discussion. This approach comes from `rustc-hash` (a.k.a. `FxHasher`)
with some tweaks for the case of hashing an `Entity`. `FxHasher` and
`SeaHasher` were also tested but were significantly slower.
- Define `EntityHashMap` type that uses the `EntityHashser`
- Use `EntityHashMap<Entity, T>` for render world entity storage,
including:
- `RenderMaterialInstances` - contains the `AssetId<M>` of the material
associated with the entity. Also for 2D.
- `RenderMeshInstances` - contains mesh transforms, flags and properties
about mesh entities. Also for 2D.
- `SkinIndices` and `MorphIndices` - contains the skin and morph index
for an entity, respectively
  - `ExtractedSprites`
  - `ExtractedUiNodes`

## Benchmarks

All benchmarks have been conducted on an M1 Max connected to AC power.
The tests are run for 1500 frames. The 1000th frame is captured for
comparison to check for visual regressions. There were none.

### 2D Meshes

`bevymark --benchmark --waves 160 --per-wave 1000 --mode mesh2d`

#### `--ordered-z`

This test spawns the 2D meshes with z incrementing back to front, which
is the ideal arrangement allocation order as it matches the sorted
render order which means lookups have a high cache hit rate.

<img width="1112" alt="Screenshot 2023-09-27 at 07 50 45"
src="https://github.com/bevyengine/bevy/assets/302146/e140bc98-7091-4a3b-8ae1-ab75d16d2ccb">

-39.1% median frame time.

#### Random

This test spawns the 2D meshes with random z. This not only makes the
batching and transparent 2D pass lookups get a lot of cache misses, it
also currently means that the meshes are almost certain to not be
batchable.

<img width="1108" alt="Screenshot 2023-09-27 at 07 51 28"
src="https://github.com/bevyengine/bevy/assets/302146/29c2e813-645a-43ce-982a-55df4bf7d8c4">

-7.2% median frame time.

### 3D Meshes

`many_cubes --benchmark`

<img width="1112" alt="Screenshot 2023-09-27 at 07 51 57"
src="https://github.com/bevyengine/bevy/assets/302146/1a729673-3254-4e2a-9072-55e27c69f0fc">

-7.7% median frame time.

### Sprites

**NOTE: On `main` sprites are using `SparseSet<Entity, T>`!**

`bevymark --benchmark --waves 160 --per-wave 1000 --mode sprite`

#### `--ordered-z`

This test spawns the sprites with z incrementing back to front, which is
the ideal arrangement allocation order as it matches the sorted render
order which means lookups have a high cache hit rate.

<img width="1116" alt="Screenshot 2023-09-27 at 07 52 31"
src="https://github.com/bevyengine/bevy/assets/302146/bc8eab90-e375-4d31-b5cd-f55f6f59ab67">

+13.0% median frame time.

#### Random

This test spawns the sprites with random z. This makes the batching and
transparent 2D pass lookups get a lot of cache misses.

<img width="1109" alt="Screenshot 2023-09-27 at 07 53 01"
src="https://github.com/bevyengine/bevy/assets/302146/22073f5d-99a7-49b0-9584-d3ac3eac3033">

+0.6% median frame time.

### UI

**NOTE: On `main` UI is using `SparseSet<Entity, T>`!**

`many_buttons`

<img width="1111" alt="Screenshot 2023-09-27 at 07 53 26"
src="https://github.com/bevyengine/bevy/assets/302146/66afd56d-cbe4-49e7-8b64-2f28f6043d85">

+15.1% median frame time.

## Alternatives

- Cart originally suggested trying out `SparseSet<Entity, T>` and indeed
that is slightly faster under ideal conditions. However,
`PassHashMap<Entity, T>` has better worst case performance when data is
randomly distributed, rather than in sorted render order, and does not
have the worst case memory usage that `SparseSet`'s dense `Vec<usize>`
that maps from the `Entity` index to sparse index into `Vec<T>`. This
dense `Vec` has to be as large as the largest Entity index used with the
`SparseSet`.
- I also tested `PassHashMap<u32, T>`, intending to use `Entity.index()`
as the key, but this proved to sometimes be slower and mostly no
different.
- The only outstanding approach that has not been implemented and tested
is to _not_ clear the render world of its entities each frame. That has
its own problems, though they could perhaps be solved.
- Performance-wise, if the entities and their component data were not
cleared, then they would incur table moves on spawn, and should not
thereafter, rather just their component data would be overwritten.
Ideally we would have a neat way of either updating data in-place via
`&mut T` queries, or inserting components if not present. This would
likely be quite cumbersome to have to remember to do everywhere, but
perhaps it only needs to be done in the more performance-sensitive
systems.
- The main problem to solve however is that we want to both maintain a
mapping between main world entities and render world entities, be able
to run the render app and world in parallel with the main app and world
for pipelined rendering, and at the same time be able to spawn entities
in the render world in such a way that those Entity ids do not collide
with those spawned in the main world. This is potentially quite
solvable, but could well be a lot of ECS work to do it in a way that
makes sense.

---

## Changelog

- Changed: Component data for entities to be drawn are no longer stored
on entities in the render world. Instead, data is stored in a
`EntityHashMap<Entity, T>` in various resources. This brings significant
performance benefits due to the way the render app clears entities every
frame. Resources of most interest are `RenderMeshInstances` and
`RenderMaterialInstances`, and their 2D counterparts.

## Migration Guide

Previously the render app extracted mesh entities and their component
data from the main world and stored them as entities and components in
the render world. Now they are extracted into essentially
`EntityHashMap<Entity, T>` where `T` are structs containing an
appropriate group of data. This means that while extract set systems
will continue to run extract queries against the main world they will
store their data in hash maps. Also, systems in later sets will either
need to look up entities in the available resources such as
`RenderMeshInstances`, or maintain their own `EntityHashMap<Entity, T>`
for their own data.

Before:
```rust
fn queue_custom(
    material_meshes: Query<(Entity, &MeshTransforms, &Handle<Mesh>), With<InstanceMaterialData>>,
) {
    ...
    for (entity, mesh_transforms, mesh_handle) in &material_meshes {
        ...
    }
}
```

After:
```rust
fn queue_custom(
    render_mesh_instances: Res<RenderMeshInstances>,
    instance_entities: Query<Entity, With<InstanceMaterialData>>,
) {
    ...
    for entity in &instance_entities {
        let Some(mesh_instance) = render_mesh_instances.get(&entity) else { continue; };
        // The mesh handle in `AssetId<Mesh>` form, and the `MeshTransforms` can now
        // be found in `mesh_instance` which is a `RenderMeshInstance`
        ...
    }
}
```

---------

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2023-09-27 08:28:28 +00:00
Rob Parrett
7063c86ed4
Fix some typos (#9934)
# Objective

To celebrate the turning of the seasons, I took a small walk through the
codebase guided by the "[code spell
checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)"
VS Code extension and fixed a few typos.
2023-09-26 19:46:24 +00:00
piper
bc88f33e48
Allow other plugins to create renderer resources (#9925)
This is a duplicate of #9632, it was created since I forgot to make a
new branch when I first made this PR, so I was having trouble resolving
merge conflicts, meaning I had to rebuild my PR.

# Objective

- Allow other plugins to create the renderer resources. An example of
where this would be required is my [OpenXR
plugin](https://github.com/awtterpip/bevy_openxr)

## Solution

- Changed the bevy RenderPlugin to optionally take precreated render
resources instead of a configuration.

## Migration Guide

The `RenderPlugin` now takes a `RenderCreation` enum instead of
`WgpuSettings`. `RenderSettings::default()` returns
`RenderSettings::Automatic(WgpuSettings::default())`. `RenderSettings`
also implements `From<WgpuSettings>`.

```rust
// before
RenderPlugin {
    wgpu_settings: WgpuSettings {
    ...
    },
}

// now
RenderPlugin {
    render_creation: RenderCreation::Automatic(WgpuSettings {
    ...
    }),
}
// or
RenderPlugin {
    render_creation: WgpuSettings {
    ...
    }.into(),
}
```

---------

Co-authored-by: Malek <pocmalek@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-09-26 19:35:08 +00:00
Pixelstorm
503b861e3a
Allow using async_io::block_on in bevy_tasks (#9626)
# Objective

Fixes #9625

## Solution

Adds `async-io` as an optional dependency of `bevy_tasks`. When enabled,
this causes calls to `futures_lite::future::block_on` to be replaced
with calls to `async_io::block_on`.

---

## Changelog

- Added a new `async-io` feature to `bevy_tasks`. When enabled, this
causes `bevy_tasks` to use `async-io`'s implemention of `block_on`
instead of `futures-lite`'s implementation. You should enable this if
you use `async-io` in your application.
2023-09-25 19:59:50 +00:00
Robert Swain
5c884c5a15
Automatic batching/instancing of draw commands (#9685)
# Objective

- Implement the foundations of automatic batching/instancing of draw
commands as the next step from #89
- NOTE: More performance improvements will come when more data is
managed and bound in ways that do not require rebinding such as mesh,
material, and texture data.

## Solution

- The core idea for batching of draw commands is to check whether any of
the information that has to be passed when encoding a draw command
changes between two things that are being drawn according to the sorted
render phase order. These should be things like the pipeline, bind
groups and their dynamic offsets, index/vertex buffers, and so on.
  - The following assumptions have been made:
- Only entities with prepared assets (pipelines, materials, meshes) are
queued to phases
- View bindings are constant across a phase for a given draw function as
phases are per-view
- `batch_and_prepare_render_phase` is the only system that performs this
batching and has sole responsibility for preparing the per-object data.
As such the mesh binding and dynamic offsets are assumed to only vary as
a result of the `batch_and_prepare_render_phase` system, e.g. due to
having to split data across separate uniform bindings within the same
buffer due to the maximum uniform buffer binding size.
- Implement `GpuArrayBuffer` for `Mesh2dUniform` to store Mesh2dUniform
in arrays in GPU buffers rather than each one being at a dynamic offset
in a uniform buffer. This is the same optimisation that was made for 3D
not long ago.
- Change batch size for a range in `PhaseItem`, adding API for getting
or mutating the range. This is more flexible than a size as the length
of the range can be used in place of the size, but the start and end can
be otherwise whatever is needed.
- Add an optional mesh bind group dynamic offset to `PhaseItem`. This
avoids having to do a massive table move just to insert
`GpuArrayBufferIndex` components.

## Benchmarks

All tests have been run on an M1 Max on AC power. `bevymark` and
`many_cubes` were modified to use 1920x1080 with a scale factor of 1. I
run a script that runs a separate Tracy capture process, and then runs
the bevy example with `--features bevy_ci_testing,trace_tracy` and
`CI_TESTING_CONFIG=../benchmark.ron` with the contents of
`../benchmark.ron`:
```rust
(
    exit_after: Some(1500)
)
```
...in order to run each test for 1500 frames.

The recent changes to `many_cubes` and `bevymark` added reproducible
random number generation so that with the same settings, the same rng
will occur. They also added benchmark modes that use a fixed delta time
for animations. Combined this means that the same frames should be
rendered both on main and on the branch.

The graphs compare main (yellow) to this PR (red).

### 3D Mesh `many_cubes --benchmark`

<img width="1411" alt="Screenshot 2023-09-03 at 23 42 10"
src="https://github.com/bevyengine/bevy/assets/302146/2088716a-c918-486c-8129-090b26fd2bc4">
The mesh and material are the same for all instances. This is basically
the best case for the initial batching implementation as it results in 1
draw for the ~11.7k visible meshes. It gives a ~30% reduction in median
frame time.

The 1000th frame is identical using the flip tool:

![flip many_cubes-main-mesh3d many_cubes-batching-mesh3d 67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/2511f37a-6df8-481a-932f-706ca4de7643)

```
     Mean: 0.000000
     Weighted median: 0.000000
     1st weighted quartile: 0.000000
     3rd weighted quartile: 0.000000
     Min: 0.000000
     Max: 0.000000
     Evaluation time: 0.4615 seconds
```

### 3D Mesh `many_cubes --benchmark --material-texture-count 10`

<img width="1404" alt="Screenshot 2023-09-03 at 23 45 18"
src="https://github.com/bevyengine/bevy/assets/302146/5ee9c447-5bd2-45c6-9706-ac5ff8916daf">
This run uses 10 different materials by varying their textures. The
materials are randomly selected, and there is no sorting by material
bind group for opaque 3D so any batching is 'random'. The PR produces a
~5% reduction in median frame time. If we were to sort the opaque phase
by the material bind group, then this should be a lot faster. This
produces about 10.5k draws for the 11.7k visible entities. This makes
sense as randomly selecting from 10 materials gives a chance that two
adjacent entities randomly select the same material and can be batched.

The 1000th frame is identical in flip:

![flip many_cubes-main-mesh3d-mtc10 many_cubes-batching-mesh3d-mtc10
67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/2b3a8614-9466-4ed8-b50c-d4aa71615dbb)

```
     Mean: 0.000000
     Weighted median: 0.000000
     1st weighted quartile: 0.000000
     3rd weighted quartile: 0.000000
     Min: 0.000000
     Max: 0.000000
     Evaluation time: 0.4537 seconds
```

### 3D Mesh `many_cubes --benchmark --vary-per-instance`

<img width="1394" alt="Screenshot 2023-09-03 at 23 48 44"
src="https://github.com/bevyengine/bevy/assets/302146/f02a816b-a444-4c18-a96a-63b5436f3b7f">
This run varies the material data per instance by randomly-generating
its colour. This is the worst case for batching and that it performs
about the same as `main` is a good thing as it demonstrates that the
batching has minimal overhead when dealing with ~11k visible mesh
entities.

The 1000th frame is identical according to flip:

![flip many_cubes-main-mesh3d-vpi many_cubes-batching-mesh3d-vpi 67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/ac5f5c14-9bda-4d1a-8219-7577d4aac68c)

```
     Mean: 0.000000
     Weighted median: 0.000000
     1st weighted quartile: 0.000000
     3rd weighted quartile: 0.000000
     Min: 0.000000
     Max: 0.000000
     Evaluation time: 0.4568 seconds
```

### 2D Mesh `bevymark --benchmark --waves 160 --per-wave 1000 --mode
mesh2d`

<img width="1412" alt="Screenshot 2023-09-03 at 23 59 56"
src="https://github.com/bevyengine/bevy/assets/302146/cb02ae07-237b-4646-ae9f-fda4dafcbad4">
This spawns 160 waves of 1000 quad meshes that are shaded with
ColorMaterial. Each wave has a different material so 160 waves currently
should result in 160 batches. This results in a 50% reduction in median
frame time.

Capturing a screenshot of the 1000th frame main vs PR gives:

![flip bevymark-main-mesh2d bevymark-batching-mesh2d 67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/80102728-1217-4059-87af-14d05044df40)

```
     Mean: 0.001222
     Weighted median: 0.750432
     1st weighted quartile: 0.453494
     3rd weighted quartile: 0.969758
     Min: 0.000000
     Max: 0.990296
     Evaluation time: 0.4255 seconds
```

So they seem to produce the same results. I also double-checked the
number of draws. `main` does 160000 draws, and the PR does 160, as
expected.

### 2D Mesh `bevymark --benchmark --waves 160 --per-wave 1000 --mode
mesh2d --material-texture-count 10`

<img width="1392" alt="Screenshot 2023-09-04 at 00 09 22"
src="https://github.com/bevyengine/bevy/assets/302146/4358da2e-ce32-4134-82df-3ab74c40849c">
This generates 10 textures and generates materials for each of those and
then selects one material per wave. The median frame time is reduced by
50%. Similar to the plain run above, this produces 160 draws on the PR
and 160000 on `main` and the 1000th frame is identical (ignoring the fps
counter text overlay).

![flip bevymark-main-mesh2d-mtc10 bevymark-batching-mesh2d-mtc10 67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/ebed2822-dce7-426a-858b-b77dc45b986f)

```
     Mean: 0.002877
     Weighted median: 0.964980
     1st weighted quartile: 0.668871
     3rd weighted quartile: 0.982749
     Min: 0.000000
     Max: 0.992377
     Evaluation time: 0.4301 seconds
```

### 2D Mesh `bevymark --benchmark --waves 160 --per-wave 1000 --mode
mesh2d --vary-per-instance`

<img width="1396" alt="Screenshot 2023-09-04 at 00 13 53"
src="https://github.com/bevyengine/bevy/assets/302146/b2198b18-3439-47ad-919a-cdabe190facb">
This creates unique materials per instance by randomly-generating the
material's colour. This is the worst case for 2D batching. Somehow, this
PR manages a 7% reduction in median frame time. Both main and this PR
issue 160000 draws.

The 1000th frame is the same:

![flip bevymark-main-mesh2d-vpi bevymark-batching-mesh2d-vpi 67ppd
ldr](https://github.com/bevyengine/bevy/assets/302146/a2ec471c-f576-4a36-a23b-b24b22578b97)

```
     Mean: 0.001214
     Weighted median: 0.937499
     1st weighted quartile: 0.635467
     3rd weighted quartile: 0.979085
     Min: 0.000000
     Max: 0.988971
     Evaluation time: 0.4462 seconds
```

### 2D Sprite `bevymark --benchmark --waves 160 --per-wave 1000 --mode
sprite`

<img width="1396" alt="Screenshot 2023-09-04 at 12 21 12"
src="https://github.com/bevyengine/bevy/assets/302146/8b31e915-d6be-4cac-abf5-c6a4da9c3d43">
This just spawns 160 waves of 1000 sprites. There should be and is no
notable difference between main and the PR.

### 2D Sprite `bevymark --benchmark --waves 160 --per-wave 1000 --mode
sprite --material-texture-count 10`

<img width="1389" alt="Screenshot 2023-09-04 at 12 36 08"
src="https://github.com/bevyengine/bevy/assets/302146/45fe8d6d-c901-4062-a349-3693dd044413">
This spawns the sprites selecting a texture at random per instance from
the 10 generated textures. This has no significant change vs main and
shouldn't.

### 2D Sprite `bevymark --benchmark --waves 160 --per-wave 1000 --mode
sprite --vary-per-instance`

<img width="1401" alt="Screenshot 2023-09-04 at 12 29 52"
src="https://github.com/bevyengine/bevy/assets/302146/762c5c60-352e-471f-8dbe-bbf10e24ebd6">
This sets the sprite colour as being unique per instance. This can still
all be drawn using one batch. There should be no difference but the PR
produces median frame times that are 4% higher. Investigation showed no
clear sources of cost, rather a mix of give and take that should not
happen. It seems like noise in the results.

### Summary

| Benchmark  | % change in median frame time |
| ------------- | ------------- |
| many_cubes  | 🟩 -30%  |
| many_cubes 10 materials  | 🟩 -5%  |
| many_cubes unique materials  | 🟩 ~0%  |
| bevymark mesh2d  | 🟩 -50%  |
| bevymark mesh2d 10 materials  | 🟩 -50%  |
| bevymark mesh2d unique materials  | 🟩 -7%  |
| bevymark sprite  | 🟥 2%  |
| bevymark sprite 10 materials  | 🟥 0.6%  |
| bevymark sprite unique materials  | 🟥 4.1%  |

---

## Changelog

- Added: 2D and 3D mesh entities that share the same mesh and material
(same textures, same data) are now batched into the same draw command
for better performance.

---------

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
Co-authored-by: Nicola Papale <nico@nicopap.ch>
2023-09-21 22:12:34 +00:00
Rob Parrett
bdb063497d
Use radsort for Transparent2d PhaseItem sorting (#9882)
# Objective

Fix a performance regression in the "[bevy vs
pixi](https://github.com/SUPERCILEX/bevy-vs-pixi)" benchmark.

This benchmark seems to have a slightly pathological distribution of `z`
values -- Sprites are spawned with a random `z` value with a child
sprite at `f32::EPSILON` relative to the parent.

See discussion here:
https://github.com/bevyengine/bevy/issues/8100#issuecomment-1726978633

## Solution

Use `radsort` for sorting `Transparent2d` `PhaseItem`s.

Use random `z` values in bevymark to stress the phase sort. Add an
`--ordered-z` option to `bevymark` that uses the old behavior.

## Benchmarks

mac m1 max

| benchmark | fps before | fps after | diff |
| - | - | - | - |
| bevymark --waves 120 --per-wave 1000 --random-z | 42.16 | 47.06 | 🟩
+11.6% |
| bevymark --waves 120 --per-wave 1000 | 52.50 | 52.29 | 🟥 -0.4% |
| bevymark --waves 120 --per-wave 1000 --mode mesh2d --random-z | 9.64 |
10.24 | 🟩 +6.2% |
| bevymark --waves 120 --per-wave 1000 --mode mesh2d | 15.83 | 15.59 | 🟥
-1.5% |
| bevy-vs-pixi | 39.71 | 59.88 | 🟩 +50.1% |

## Discussion

It's possible that `TransparentUi` should also change. We could probably
use `slice::sort_unstable_by_key` with the current sort key though, as
its items are always sorted and unique. I'd prefer to follow up later to
look into that.

Here's a survey of sorts used by other `PhaseItem`s

#### slice::sort_by_key
`Transparent2d`, `TransparentUi`

#### radsort
`Opaque3d`, `AlphaMask3d`, `Transparent3d`, `Opaque3dPrepass`,
`AlphaMask3dPrepass`, `Shadow`

I also tried `slice::sort_unstable_by_key` with a compound sort key
including `Entity`, but it didn't seem as promising and I didn't test it
as thoroughly.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-09-21 17:53:20 +00:00
Nicola Papale
7163aabf29
Use a single line for of large binding lists (#9849)
# Objective

- When adding/removing bindings in large binding lists, git would
generate very difficult-to-read diffs

## Solution

- Move the `@group(X) @binding(Y)` into the same line as the binding
type declaration
2023-09-19 22:17:44 +00:00
Trashtalk217
e4b368721d
One Shot Systems (#8963)
I'm adopting this ~~child~~ PR.

# Objective

- Working with exclusive world access is not always easy: in many cases,
a standard system or three is more ergonomic to write, and more
modularly maintainable.
- For small, one-off tasks (commonly handled with scripting), running an
event-reader system incurs a small but flat overhead cost and muddies
the schedule.
- Certain forms of logic (e.g. turn-based games) want very fine-grained
linear and/or branching control over logic.
- SystemState is not automatically cached, and so performance can suffer
and change detection breaks.
- Fixes https://github.com/bevyengine/bevy/issues/2192.
- Partial workaround for https://github.com/bevyengine/bevy/issues/279.

## Solution

- Adds a SystemRegistry resource to the World, which stores initialized
systems keyed by their SystemSet.
- Allows users to call world.run_system(my_system) and
commands.run_system(my_system), without re-initializing or losing state
(essential for change detection).
- Add a Callback type to enable convenient use of dynamic one shot
systems and reduce the mental overhead of working with Box<dyn
SystemSet>.
- Allow users to run systems based on their SystemSet, enabling more
complex user-made abstractions.

## Future work

- Parameterized one-shot systems would improve reusability and bring
them closer to events and commands. The API could be something like
run_system_with_input(my_system, my_input) and use the In SystemParam.
- We should evaluate the unification of commands and one-shot systems
since they are two different ways to run logic on demand over a World.

### Prior attempts

- https://github.com/bevyengine/bevy/pull/2234
- https://github.com/bevyengine/bevy/pull/2417
- https://github.com/bevyengine/bevy/pull/4090
- https://github.com/bevyengine/bevy/pull/7999

This PR continues the work done in
https://github.com/bevyengine/bevy/pull/7999.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Alejandro Pascual Pozo <alejandro.pascual.pozo@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Dmytro Banin <banind@cs.washington.edu>
Co-authored-by: James Liu <contact@jamessliu.com>
2023-09-19 20:17:05 +00:00
Nico Burns
b995827013
Have a separate implicit viewport node per root node + make viewport node Display::Grid (#9637)
# Objective

Make `bevy_ui` "root" nodes more intuitive to use/style by:
- Removing the implicit flexbox styling (such as stretch alignment) that
is applied to them, and replacing it with more intuitive CSS Grid
styling (notably with stretch alignment disabled in both axes).
- Making root nodes layout independently of each other. Instead of there
being a single implicit "viewport" node that all root nodes are children
of, there is now an implicit "viewport" node *per root node*. And layout
of each tree is computed separately.

## Solution

- Remove the global implicit viewport node, and instead create an
implicit viewport node for each user-specified root node.
- Keep track of both the user-specified root nodes and the implicit
viewport nodes in a separate `Vec`.
- Use the window's size as the `available_space` parameter to
`Taffy.compute_layout` rather than setting it on the implicit viewport
node (and set the viewport to `height: 100%; width: 100%` to make this
"just work").

---

## Changelog

- Bevy UI now lays out root nodes independently of each other in
separate layout contexts.
- The implicit viewport node (which contains each user-specified root
node) is now `Display::Grid` with `align_items` and `justify_items` both
set to `Start`.

## Migration Guide

- Bevy UI now lays out root nodes independently of each other in
separate layout contexts. If you were relying on your root nodes being
able to affect each other's layouts, then you may need to wrap them in a
single root node.
- The implicit viewport node (which contains each user-specified root
node) is now `Display::Grid` with `align_items` and `justify_items` both
set to `Start`. You may need to add `height: Val::Percent(100.)` to your
root nodes if you were previously relying on being implicitly set.
2023-09-19 15:14:46 +00:00
Rob Parrett
73e06e33da
Use a seeded rng for custom_skinned_mesh example (#9846)
# Objective

Make the output of this example repeatable so it can be utilized by
automated screenshot diffing.

## Solution

- Use a seeded RNG for the random colors
- Offset the meshes slightly in z so they don't intersect each other at
the extents of their animations.
2023-09-19 05:57:25 +00:00
Rob Parrett
d3f612c376
Fix ambiguities in transform example (#9845)
# Objective

Fix these

```
 -- rotate_cube and move_cube
    conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
 -- rotate_cube and scale_down_sphere_proportional_to_cube_travel_distance
    conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
 -- move_cube and scale_down_sphere_proportional_to_cube_travel_distance
    conflict on: ["bevy_transform::components::transform::Transform", "transform::CubeState"]
```

The three systems in this example depend on the results of the others.
This leads to minor but detectable differences in output between runs by
automated screenshot diffing depending on the order of the schedule.

We don't necessarily need to be able to do this for **every** example,
but I think this is a case where fixing it is easy / maybe the right
thing to do anyway.

## Solution

Chain the three systems
2023-09-19 05:57:21 +00:00
Rob Parrett
26359f9b37
Remove some old references to CoreSet (#9833)
# Objective

Remove some references to `CoreSet` which was removed in #8079.
2023-09-18 01:07:11 +00:00
louis-le-cam
9ee9d627d7
Rename RemovedComponents::iter/iter_with_id to read/read_with_id (#9778)
# Objective

Rename RemovedComponents::iter/iter_with_id to read/read_with_id to make
it clear that it consume the data

Fixes #9755.

(It's my first pull request, if i've made any mistake, please let me
know)

## Solution

Refactor RemovedComponents::iter/iter_with_id to read/read_with_id



## Changelog

Refactor RemovedComponents::iter/iter_with_id to read/read_with_id

Deprecate RemovedComponents::iter/iter_with_id

Remove IntoIterator implementation

Update removal_detection example accordingly

---

## Migration Guide

Rename calls of RemovedComponents::iter/iter_with_id to
read/read_with_id

Replace IntoIterator iteration (&mut <RemovedComponents>) with .read()

---------

Co-authored-by: denshi_ika <mojang2824@gmail.com>
2023-09-15 12:37:20 +00:00
Rob Parrett
8681d1cb04
Fix animate_scale scaling z value in text2d example (#9769)
# Objective

I noticed this while testing #9733.

It's not causing any problems, but we shouldn't teach users to scale 2d
stuff in z.

## Solution

Only scale in x and y.
2023-09-13 19:25:44 +00:00
Bruce Mitchener
5eb6889832
examples: Remove unused doc comments. (#9795)
# Objective

- Compile all targets without warnings about unused doc comments.

## Solution

- Turn unused doc comments into regular comments. Doc comments aren't
supported on expressions, so they can just be regular comments.
2023-09-13 19:21:23 +00:00
A-Walrus
1a7fc57a8c
Fix comment in scene example FromResources (#9743)
Comment references non existent `FromResources` instead of `FromWorld`

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-09-11 19:50:38 +00:00
IceSentry
027ff9f378
Wait before making window visible (#9692)
# Objective

- The current example still has one white frame before it starts
rendering.

## Solution

- Wait 3 frames before toggling visibility
2023-09-11 19:09:55 +00:00
ickshonpe
625d386940
impl From<String> and From<&str> for TextSection (#8856)
# Objective

Implement `From<String>` and `From<&str>` for `TextSection`

Example from something I was working on earlier:
```rust
parent.spawn(TextBundle::from_sections([
    TextSection::new("press ".to_string(), TextStyle::default()),
    TextSection::new("space".to_string(), TextStyle { color: Color::YELLOW, ..default() }),
    TextSection::new(" to advance frames".to_string(), TextStyle::default()),
]));
```

After an `impl From<&str> for TextSection` :

```rust
parent.spawn(TextBundle::from_sections([
    "press ".into(),
    TextSection::new("space".to_string(), TextStyle { color: Color::YELLOW, ..default() }),
    " to advance frames".into(),
]));
```

* Potentially unhelpful without a default font, so behind the
`default_font` feature.

 Co-authored-by: [hate](https://github.com/hate)

---------

Co-authored-by: hate <15314665+hate@users.noreply.github.com>
2023-09-11 19:00:50 +00:00
ira
f3ab38a802
Add example for Camera::viewport_to_world (#7179)
Fixes #7177

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2023-09-11 18:52:11 +00:00
Carter Anderson
17edf4f7c7
Copy on Write AssetPaths (#9729)
# Objective

The `AssetServer` and `AssetProcessor` do a lot of `AssetPath` cloning
(across many threads). To store the path on the handle, to store paths
in dependency lists, to pass an owned path to the offloaded thread, to
pass a path to the LoadContext, etc , etc. Cloning multiple string
allocations multiple times like this will add up. It is worth optimizing
this.

Referenced in #9714 

## Solution

Added a new `CowArc<T>` type to `bevy_util`, which behaves a lot like
`Cow<T>`, but the Owned variant is an `Arc<T>`. Use this in place of
`Cow<str>` and `Cow<Path>` on `AssetPath`.

---

## Changelog

- `AssetPath` now internally uses `CowArc`, making clone operations much
cheaper
- `AssetPath` now serializes as `AssetPath("some_path.extension#Label")`
instead of as `AssetPath { path: "some_path.extension", label:
Some("Label) }`


## Migration Guide

```rust
// Old
AssetPath::new("logo.png", None);

// New
AssetPath::new("logo.png");

// Old
AssetPath::new("scene.gltf", Some("Mesh0");

// New
AssetPath::new("scene.gltf").with_label("Mesh0");
```

`AssetPath` now serializes as `AssetPath("some_path.extension#Label")`
instead of as `AssetPath { path: "some_path.extension", label:
Some("Label) }`

---------

Co-authored-by: Pascal Hertleif <killercup@gmail.com>
2023-09-09 23:15:10 +00:00
Joseph
8eb6ccdd87
Remove useless single tuples and trailing commas (#9720)
# Objective

Title
2023-09-08 21:46:54 +00:00
ickshonpe
73447b6d72
many_buttons enhancements (#9712)
# Objective

`many_buttons` enhancements:
* use `argh` to manage the commandline arguments like the other stress
tests
* add an option to set the number of buttons
* add a grid layout option
* centre the grid properly
* use viewport coords for the layout's style constraints
* replace use of absolute positioning

includes the changes from #9636

Displaying an image isn't actually about stress testing image rendering.
Without a second texture (the first is used by the text) the entire grid
will be drawn in a single batch. The extra texture used by the image
forces the renderer to break up the batches at every button displaying
an image, where it has to switch between the font atlas texture and the
image texture.

## Solution

<img width="401" alt="many_buttons_new"
src="https://github.com/bevyengine/bevy/assets/27962798/82140c6d-d72c-4e4f-b9b6-dd204176e51d">

---

## Changelog

 `many_buttons` stress test example enhancements:
* uses `argh` to the manage the commandline arguments.
* New commandline args:
  - `--help` display info & list all commandline options
  - `--buttons`  set the number of buttons.
  - `--image-freq` set the frequency of buttons displaying images
  - `--grid` use a grid layout
* style constraints are specified in viewport coords insead of
percentage values
* margins and nested bundles are used to construct the layout, instead
of absolute positioning
* the button grid centered in the window, the empty gap along the bottom
and right is removed
* an image is drawn as the background to every Nth button where N is set
using the `--image-freq` commandline option.

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2023-09-08 15:02:05 +00:00
Carter Anderson
5eb292dc10
Bevy Asset V2 (#8624)
# Bevy Asset V2 Proposal

## Why Does Bevy Need A New Asset System?

Asset pipelines are a central part of the gamedev process. Bevy's
current asset system is missing a number of features that make it
non-viable for many classes of gamedev. After plenty of discussions and
[a long community feedback
period](https://github.com/bevyengine/bevy/discussions/3972), we've
identified a number missing features:

* **Asset Preprocessing**: it should be possible to "preprocess" /
"compile" / "crunch" assets at "development time" rather than when the
game starts up. This enables offloading expensive work from deployed
apps, faster asset loading, less runtime memory usage, etc.
* **Per-Asset Loader Settings**: Individual assets cannot define their
own loaders that override the defaults. Additionally, they cannot
provide per-asset settings to their loaders. This is a huge limitation,
as many asset types don't provide all information necessary for Bevy
_inside_ the asset. For example, a raw PNG image says nothing about how
it should be sampled (ex: linear vs nearest).
* **Asset `.meta` files**: assets should have configuration files stored
adjacent to the asset in question, which allows the user to configure
asset-type-specific settings. These settings should be accessible during
the pre-processing phase. Modifying a `.meta` file should trigger a
re-processing / re-load of the asset. It should be possible to configure
asset loaders from the meta file.
* **Processed Asset Hot Reloading**: Changes to processed assets (or
their dependencies) should result in re-processing them and re-loading
the results in live Bevy Apps.
* **Asset Dependency Tracking**: The current bevy_asset has no good way
to wait for asset dependencies to load. It punts this as an exercise for
consumers of the loader apis, which is unreasonable and error prone.
There should be easy, ergonomic ways to wait for assets to load and
block some logic on an asset's entire dependency tree loading.
* **Runtime Asset Loading**: it should be (optionally) possible to load
arbitrary assets dynamically at runtime. This necessitates being able to
deploy and run the asset server alongside Bevy Apps on _all platforms_.
For example, we should be able to invoke the shader compiler at runtime,
stream scenes from sources like the internet, etc. To keep deployed
binaries (and startup times) small, the runtime asset server
configuration should be configurable with different settings compared to
the "pre processor asset server".
* **Multiple Backends**: It should be possible to load assets from
arbitrary sources (filesystems, the internet, remote asset serves, etc).
* **Asset Packing**: It should be possible to deploy assets in
compressed "packs", which makes it easier and more efficient to
distribute assets with Bevy Apps.
* **Asset Handoff**: It should be possible to hold a "live" asset
handle, which correlates to runtime data, without actually holding the
asset in memory. Ex: it must be possible to hold a reference to a GPU
mesh generated from a "mesh asset" without keeping the mesh data in CPU
memory
* **Per-Platform Processed Assets**: Different platforms and app
distributions have different capabilities and requirements. Some
platforms need lower asset resolutions or different asset formats to
operate within the hardware constraints of the platform. It should be
possible to define per-platform asset processing profiles. And it should
be possible to deploy only the assets required for a given platform.

These features have architectural implications that are significant
enough to require a full rewrite. The current Bevy Asset implementation
got us this far, but it can take us no farther. This PR defines a brand
new asset system that implements most of these features, while laying
the foundations for the remaining features to be built.

## Bevy Asset V2

Here is a quick overview of the features introduced in this PR.
* **Asset Preprocessing**: Preprocess assets at development time into
more efficient (and configurable) representations
* **Dependency Aware**: Dependencies required to process an asset are
tracked. If an asset's processed dependency changes, it will be
reprocessed
* **Hot Reprocessing/Reloading**: detect changes to asset source files,
reprocess them if they have changed, and then hot-reload them in Bevy
Apps.
* **Only Process Changes**: Assets are only re-processed when their
source file (or meta file) has changed. This uses hashing and timestamps
to avoid processing assets that haven't changed.
* **Transactional and Reliable**: Uses write-ahead logging (a technique
commonly used by databases) to recover from crashes / forced-exits.
Whenever possible it avoids full-reprocessing / only uncompleted
transactions will be reprocessed. When the processor is running in
parallel with a Bevy App, processor asset writes block Bevy App asset
reads. Reading metadata + asset bytes is guaranteed to be transactional
/ correctly paired.
* **Portable / Run anywhere / Database-free**: The processor does not
rely on an in-memory database (although it uses some database techniques
for reliability). This is important because pretty much all in-memory
databases have unsupported platforms or build complications.
* **Configure Processor Defaults Per File Type**: You can say "use this
processor for all files of this type".
* **Custom Processors**: The `Processor` trait is flexible and
unopinionated. It can be implemented by downstream plugins.
* **LoadAndSave Processors**: Most asset processing scenarios can be
expressed as "run AssetLoader A, save the results using AssetSaver X,
and then load the result using AssetLoader B". For example, load this
png image using `PngImageLoader`, which produces an `Image` asset and
then save it using `CompressedImageSaver` (which also produces an
`Image` asset, but in a compressed format), which takes an `Image` asset
as input. This means if you have an `AssetLoader` for an asset, you are
already half way there! It also means that you can share AssetSavers
across multiple loaders. Because `CompressedImageSaver` accepts Bevy's
generic Image asset as input, it means you can also use it with some
future `JpegImageLoader`.
* **Loader and Saver Settings**: Asset Loaders and Savers can now define
their own settings types, which are passed in as input when an asset is
loaded / saved. Each asset can define its own settings.
* **Asset `.meta` files**: configure asset loaders, their settings,
enable/disable processing, and configure processor settings
* **Runtime Asset Dependency Tracking** Runtime asset dependencies (ex:
if an asset contains a `Handle<Image>`) are tracked by the asset server.
An event is emitted when an asset and all of its dependencies have been
loaded
* **Unprocessed Asset Loading**: Assets do not require preprocessing.
They can be loaded directly. A processed asset is just a "normal" asset
with some extra metadata. Asset Loaders don't need to know or care about
whether or not an asset was processed.
* **Async Asset IO**: Asset readers/writers use async non-blocking
interfaces. Note that because Rust doesn't yet support async traits,
there is a bit of manual Boxing / Future boilerplate. This will
hopefully be removed in the near future when Rust gets async traits.
* **Pluggable Asset Readers and Writers**: Arbitrary asset source
readers/writers are supported, both by the processor and the asset
server.
* **Better Asset Handles**
* **Single Arc Tree**: Asset Handles now use a single arc tree that
represents the lifetime of the asset. This makes their implementation
simpler, more efficient, and allows us to cheaply attach metadata to
handles. Ex: the AssetPath of a handle is now directly accessible on the
handle itself!
* **Const Typed Handles**: typed handles can be constructed in a const
context. No more weird "const untyped converted to typed at runtime"
patterns!
* **Handles and Ids are Smaller / Faster To Hash / Compare**: Typed
`Handle<T>` is now much smaller in memory and `AssetId<T>` is even
smaller.
* **Weak Handle Usage Reduction**: In general Handles are now considered
to be "strong". Bevy features that previously used "weak `Handle<T>`"
have been ported to `AssetId<T>`, which makes it statically clear that
the features do not hold strong handles (while retaining strong type
information). Currently Handle::Weak still exists, but it is very
possible that we can remove that entirely.
* **Efficient / Dense Asset Ids**: Assets now have efficient dense
runtime asset ids, which means we can avoid expensive hash lookups.
Assets are stored in Vecs instead of HashMaps. There are now typed and
untyped ids, which means we no longer need to store dynamic type
information in the ID for typed handles. "AssetPathId" (which was a
nightmare from a performance and correctness standpoint) has been
entirely removed in favor of dense ids (which are retrieved for a path
on load)
* **Direct Asset Loading, with Dependency Tracking**: Assets that are
defined at runtime can still have their dependencies tracked by the
Asset Server (ex: if you create a material at runtime, you can still
wait for its textures to load). This is accomplished via the (currently
optional) "asset dependency visitor" trait. This system can also be used
to define a set of assets to load, then wait for those assets to load.
* **Async folder loading**: Folder loading also uses this system and
immediately returns a handle to the LoadedFolder asset, which means
folder loading no longer blocks on directory traversals.
* **Improved Loader Interface**: Loaders now have a specific "top level
asset type", which makes returning the top-level asset simpler and
statically typed.
* **Basic Image Settings and Processing**: Image assets can now be
processed into the gpu-friendly Basic Universal format. The ImageLoader
now has a setting to define what format the image should be loaded as.
Note that this is just a minimal MVP ... plenty of additional work to do
here. To demo this, enable the `basis-universal` feature and turn on
asset processing.
* **Simpler Audio Play / AudioSink API**: Asset handle providers are
cloneable, which means the Audio resource can mint its own handles. This
means you can now do `let sink_handle = audio.play(music)` instead of
`let sink_handle = audio_sinks.get_handle(audio.play(music))`. Note that
this might still be replaced by
https://github.com/bevyengine/bevy/pull/8424.
**Removed Handle Casting From Engine Features**: Ex: FontAtlases no
longer use casting between handle types

## Using The New Asset System

### Normal Unprocessed Asset Loading

By default the `AssetPlugin` does not use processing. It behaves pretty
much the same way as the old system.

If you are defining a custom asset, first derive `Asset`:

```rust
#[derive(Asset)]
struct Thing {
    value: String,
}
```

Initialize the asset:
```rust
app.init_asset:<Thing>()
```

Implement a new `AssetLoader` for it:

```rust
#[derive(Default)]
struct ThingLoader;

#[derive(Serialize, Deserialize, Default)]
pub struct ThingSettings {
    some_setting: bool,
}

impl AssetLoader for ThingLoader {
    type Asset = Thing;
    type Settings = ThingSettings;

    fn load<'a>(
        &'a self,
        reader: &'a mut Reader,
        settings: &'a ThingSettings,
        load_context: &'a mut LoadContext,
    ) -> BoxedFuture<'a, Result<Thing, anyhow::Error>> {
        Box::pin(async move {
            let mut bytes = Vec::new();
            reader.read_to_end(&mut bytes).await?;
            // convert bytes to value somehow
            Ok(Thing {
                value 
            })
        })
    }

    fn extensions(&self) -> &[&str] {
        &["thing"]
    }
}
```

Note that this interface will get much cleaner once Rust gets support
for async traits. `Reader` is an async futures_io::AsyncRead. You can
stream bytes as they come in or read them all into a `Vec<u8>`,
depending on the context. You can use `let handle =
load_context.load(path)` to kick off a dependency load, retrieve a
handle, and register the dependency for the asset.

Then just register the loader in your Bevy app:

```rust
app.init_asset_loader::<ThingLoader>()
```

Now just add your `Thing` asset files into the `assets` folder and load
them like this:

```rust
fn system(asset_server: Res<AssetServer>) {
    let handle = Handle<Thing> = asset_server.load("cool.thing");
}
```

You can check load states directly via the asset server:

```rust
if asset_server.load_state(&handle) == LoadState::Loaded { }
```

You can also listen for events:

```rust
fn system(mut events: EventReader<AssetEvent<Thing>>, handle: Res<SomeThingHandle>) {
    for event in events.iter() {
        if event.is_loaded_with_dependencies(&handle) {
        }
    }
}
```

Note the new `AssetEvent::LoadedWithDependencies`, which only fires when
the asset is loaded _and_ all dependencies (and their dependencies) have
loaded.

Unlike the old asset system, for a given asset path all `Handle<T>`
values point to the same underlying Arc. This means Handles can cheaply
hold more asset information, such as the AssetPath:

```rust
// prints the AssetPath of the handle
info!("{:?}", handle.path())
```

### Processed Assets

Asset processing can be enabled via the `AssetPlugin`. When developing
Bevy Apps with processed assets, do this:

```rust
app.add_plugins(DefaultPlugins.set(AssetPlugin::processed_dev()))
```

This runs the `AssetProcessor` in the background with hot-reloading. It
reads assets from the `assets` folder, processes them, and writes them
to the `.imported_assets` folder. Asset loads in the Bevy App will wait
for a processed version of the asset to become available. If an asset in
the `assets` folder changes, it will be reprocessed and hot-reloaded in
the Bevy App.

When deploying processed Bevy apps, do this:

```rust
app.add_plugins(DefaultPlugins.set(AssetPlugin::processed()))
```

This does not run the `AssetProcessor` in the background. It behaves
like `AssetPlugin::unprocessed()`, but reads assets from
`.imported_assets`.

When the `AssetProcessor` is running, it will populate sibling `.meta`
files for assets in the `assets` folder. Meta files for assets that do
not have a processor configured look like this:

```rust
(
    meta_format_version: "1.0",
    asset: Load(
        loader: "bevy_render::texture::image_loader::ImageLoader",
        settings: (
            format: FromExtension,
        ),
    ),
)
```

This is metadata for an image asset. For example, if you have
`assets/my_sprite.png`, this could be the metadata stored at
`assets/my_sprite.png.meta`. Meta files are totally optional. If no
metadata exists, the default settings will be used.

In short, this file says "load this asset with the ImageLoader and use
the file extension to determine the image type". This type of meta file
is supported in all AssetPlugin modes. If in `Unprocessed` mode, the
asset (with the meta settings) will be loaded directly. If in
`ProcessedDev` mode, the asset file will be copied directly to the
`.imported_assets` folder. The meta will also be copied directly to the
`.imported_assets` folder, but with one addition:

```rust
(
    meta_format_version: "1.0",
    processed_info: Some((
        hash: 12415480888597742505,
        full_hash: 14344495437905856884,
        process_dependencies: [],
    )),
    asset: Load(
        loader: "bevy_render::texture::image_loader::ImageLoader",
        settings: (
            format: FromExtension,
        ),
    ),
)
```

`processed_info` contains `hash` (a direct hash of the asset and meta
bytes), `full_hash` (a hash of `hash` and the hashes of all
`process_dependencies`), and `process_dependencies` (the `path` and
`full_hash` of every process_dependency). A "process dependency" is an
asset dependency that is _directly_ used when processing the asset.
Images do not have process dependencies, so this is empty.

When the processor is enabled, you can use the `Process` metadata
config:

```rust
(
    meta_format_version: "1.0",
    asset: Process(
        processor: "bevy_asset::processor::process::LoadAndSave<bevy_render::texture::image_loader::ImageLoader, bevy_render::texture::compressed_image_saver::CompressedImageSaver>",
        settings: (
            loader_settings: (
                format: FromExtension,
            ),
            saver_settings: (
                generate_mipmaps: true,
            ),
        ),
    ),
)
```

This configures the asset to use the `LoadAndSave` processor, which runs
an AssetLoader and feeds the result into an AssetSaver (which saves the
given Asset and defines a loader to load it with). (for terseness
LoadAndSave will likely get a shorter/friendlier type name when [Stable
Type Paths](#7184) lands). `LoadAndSave` is likely to be the most common
processor type, but arbitrary processors are supported.

`CompressedImageSaver` saves an `Image` in the Basis Universal format
and configures the ImageLoader to load it as basis universal. The
`AssetProcessor` will read this meta, run it through the LoadAndSave
processor, and write the basis-universal version of the image to
`.imported_assets`. The final metadata will look like this:

```rust
(
    meta_format_version: "1.0",
    processed_info: Some((
        hash: 905599590923828066,
        full_hash: 9948823010183819117,
        process_dependencies: [],
    )),
    asset: Load(
        loader: "bevy_render::texture::image_loader::ImageLoader",
        settings: (
            format: Format(Basis),
        ),
    ),
)
```

To try basis-universal processing out in Bevy examples, (for example
`sprite.rs`), change `add_plugins(DefaultPlugins)` to
`add_plugins(DefaultPlugins.set(AssetPlugin::processed_dev()))` and run
with the `basis-universal` feature enabled: `cargo run
--features=basis-universal --example sprite`.

To create a custom processor, there are two main paths:
1. Use the `LoadAndSave` processor with an existing `AssetLoader`.
Implement the `AssetSaver` trait, register the processor using
`asset_processor.register_processor::<LoadAndSave<ImageLoader,
CompressedImageSaver>>(image_saver.into())`.
2. Implement the `Process` trait directly and register it using:
`asset_processor.register_processor(thing_processor)`.

You can configure default processors for file extensions like this:

```rust
asset_processor.set_default_processor::<ThingProcessor>("thing")
```

There is one more metadata type to be aware of:

```rust
(
    meta_format_version: "1.0",
    asset: Ignore,
)
```

This will ignore the asset during processing / prevent it from being
written to `.imported_assets`.

The AssetProcessor stores a transaction log at `.imported_assets/log`
and uses it to gracefully recover from unexpected stops. This means you
can force-quit the processor (and Bevy Apps running the processor in
parallel) at arbitrary times!

`.imported_assets` is "local state". It should _not_ be checked into
source control. It should also be considered "read only". In practice,
you _can_ modify processed assets and processed metadata if you really
need to test something. But those modifications will not be represented
in the hashes of the assets, so the processed state will be "out of
sync" with the source assets. The processor _will not_ fix this for you.
Either revert the change after you have tested it, or delete the
processed files so they can be re-populated.

## Open Questions

There are a number of open questions to be discussed. We should decide
if they need to be addressed in this PR and if so, how we will address
them:

### Implied Dependencies vs Dependency Enumeration

There are currently two ways to populate asset dependencies:
* **Implied via AssetLoaders**: if an AssetLoader loads an asset (and
retrieves a handle), a dependency is added to the list.
* **Explicit via the optional Asset::visit_dependencies**: if
`server.load_asset(my_asset)` is called, it will call
`my_asset.visit_dependencies`, which will grab dependencies that have
been manually defined for the asset via the Asset trait impl (which can
be derived).

This means that defining explicit dependencies is optional for "loaded
assets". And the list of dependencies is always accurate because loaders
can only produce Handles if they register dependencies. If an asset was
loaded with an AssetLoader, it only uses the implied dependencies. If an
asset was created at runtime and added with
`asset_server.load_asset(MyAsset)`, it will use
`Asset::visit_dependencies`.

However this can create a behavior mismatch between loaded assets and
equivalent "created at runtime" assets if `Assets::visit_dependencies`
doesn't exactly match the dependencies produced by the AssetLoader. This
behavior mismatch can be resolved by completely removing "implied loader
dependencies" and requiring `Asset::visit_dependencies` to supply
dependency data. But this creates two problems:
* It makes defining loaded assets harder and more error prone: Devs must
remember to manually annotate asset dependencies with `#[dependency]`
when deriving `Asset`. For more complicated assets (such as scenes), the
derive likely wouldn't be sufficient and a manual `visit_dependencies`
impl would be required.
* Removes the ability to immediately kick off dependency loads: When
AssetLoaders retrieve a Handle, they also immediately kick off an asset
load for the handle, which means it can start loading in parallel
_before_ the asset finishes loading. For large assets, this could be
significant. (although this could be mitigated for processed assets if
we store dependencies in the processed meta file and load them ahead of
time)

### Eager ProcessorDev Asset Loading

I made a controversial call in the interest of fast startup times ("time
to first pixel") for the "processor dev mode configuration". When
initializing the AssetProcessor, current processed versions of unchanged
assets are yielded immediately, even if their dependencies haven't been
checked yet for reprocessing. This means that
non-current-state-of-filesystem-but-previously-valid assets might be
returned to the App first, then hot-reloaded if/when their dependencies
change and the asset is reprocessed.

Is this behavior desirable? There is largely one alternative: do not
yield an asset from the processor to the app until all of its
dependencies have been checked for changes. In some common cases (load
dependency has not changed since last run) this will increase startup
time. The main question is "by how much" and is that slower startup time
worth it in the interest of only yielding assets that are true to the
current state of the filesystem. Should this be configurable? I'm
starting to think we should only yield an asset after its (historical)
dependencies have been checked for changes + processed as necessary, but
I'm curious what you all think.

### Paths Are Currently The Only Canonical ID / Do We Want Asset UUIDs?

In this implementation AssetPaths are the only canonical asset
identifier (just like the previous Bevy Asset system and Godot). Moving
assets will result in re-scans (and currently reprocessing, although
reprocessing can easily be avoided with some changes). Asset
renames/moves will break code and assets that rely on specific paths,
unless those paths are fixed up.

Do we want / need "stable asset uuids"? Introducing them is very
possible:
1. Generate a UUID and include it in .meta files
2. Support UUID in AssetPath
3. Generate "asset indices" which are loaded on startup and map UUIDs to
paths.
4 (maybe). Consider only supporting UUIDs for processed assets so we can
generate quick-to-load indices instead of scanning meta files.

The main "pro" is that assets referencing UUIDs don't need to be
migrated when a path changes. The main "con" is that UUIDs cannot be
"lazily resolved" like paths. They need a full view of all assets to
answer the question "does this UUID exist". Which means UUIDs require
the AssetProcessor to fully finish startup scans before saying an asset
doesnt exist. And they essentially require asset pre-processing to use
in apps, because scanning all asset metadata files at runtime to resolve
a UUID is not viable for medium-to-large apps. It really requires a
pre-generated UUID index, which must be loaded before querying for
assets.

I personally think this should be investigated in a separate PR. Paths
aren't going anywhere ... _everyone_ uses filesystems (and
filesystem-like apis) to manage their asset source files. I consider
them permanent canonical asset information. Additionally, they behave
well for both processed and unprocessed asset modes. Given that Bevy is
supporting both, this feels like the right canonical ID to start with.
UUIDS (and maybe even other indexed-identifier types) can be added later
as necessary.

### Folder / File Naming Conventions

All asset processing config currently lives in the `.imported_assets`
folder. The processor transaction log is in `.imported_assets/log`.
Processed assets are added to `.imported_assets/Default`, which will
make migrating to processed asset profiles (ex: a
`.imported_assets/Mobile` profile) a non-breaking change. It also allows
us to create top-level files like `.imported_assets/log` without it
being interpreted as an asset. Meta files currently have a `.meta`
suffix. Do we like these names and conventions?

### Should the `AssetPlugin::processed_dev` configuration enable
`watch_for_changes` automatically?

Currently it does (which I think makes sense), but it does make it the
only configuration that enables watch_for_changes by default.

### Discuss on_loaded High Level Interface:

This PR includes a very rough "proof of concept" `on_loaded` system
adapter that uses the `LoadedWithDependencies` event in combination with
`asset_server.load_asset` dependency tracking to support this pattern

```rust
fn main() {
    App::new()
        .init_asset::<MyAssets>()
        .add_systems(Update, on_loaded(create_array_texture))
        .run();
}

#[derive(Asset, Clone)]
struct MyAssets {
    #[dependency]
    picture_of_my_cat: Handle<Image>,
    #[dependency]
    picture_of_my_other_cat: Handle<Image>,
}

impl FromWorld for ArrayTexture {
    fn from_world(world: &mut World) -> Self {
        picture_of_my_cat: server.load("meow.png"),
        picture_of_my_other_cat: server.load("meeeeeeeow.png"),
    }
}

fn spawn_cat(In(my_assets): In<MyAssets>, mut commands: Commands) {
    commands.spawn(SpriteBundle {
        texture: my_assets.picture_of_my_cat.clone(),  
        ..default()
    });
    
    commands.spawn(SpriteBundle {
        texture: my_assets.picture_of_my_other_cat.clone(),  
        ..default()
    });
}

```

The implementation is _very_ rough. And it is currently unsafe because
`bevy_ecs` doesn't expose some internals to do this safely from inside
`bevy_asset`. There are plenty of unanswered questions like:
* "do we add a Loadable" derive? (effectively automate the FromWorld
implementation above)
* Should `MyAssets` even be an Asset? (largely implemented this way
because it elegantly builds on `server.load_asset(MyAsset { .. })`
dependency tracking).

We should think hard about what our ideal API looks like (and if this is
a pattern we want to support). Not necessarily something we need to
solve in this PR. The current `on_loaded` impl should probably be
removed from this PR before merging.

## Clarifying Questions

### What about Assets as Entities?

This Bevy Asset V2 proposal implementation initially stored Assets as
ECS Entities. Instead of `AssetId<T>` + the `Assets<T>` resource it used
`Entity` as the asset id and Asset values were just ECS components.
There are plenty of compelling reasons to do this:
1. Easier to inline assets in Bevy Scenes (as they are "just" normal
entities + components)
2. More flexible queries: use the power of the ECS to filter assets (ex:
`Query<Mesh, With<Tree>>`).
3. Extensible. Users can add arbitrary component data to assets.
4. Things like "component visualization tools" work out of the box to
visualize asset data.

However Assets as Entities has a ton of caveats right now:
* We need to be able to allocate entity ids without a direct World
reference (aka rework id allocator in Entities ... i worked around this
in my prototypes by just pre allocating big chunks of entities)
* We want asset change events in addition to ECS change tracking ... how
do we populate them when mutations can come from anywhere? Do we use
Changed queries? This would require iterating over the change data for
all assets every frame. Is this acceptable or should we implement a new
"event based" component change detection option?
* Reconciling manually created assets with asset-system managed assets
has some nuance (ex: are they "loaded" / do they also have that
component metadata?)
* "how do we handle "static" / default entity handles" (ties in to the
Entity Indices discussion:
https://github.com/bevyengine/bevy/discussions/8319). This is necessary
for things like "built in" assets and default handles in things like
SpriteBundle.
* Storing asset information as a component makes it easy to "invalidate"
asset state by removing the component (or forcing modifications).
Ideally we have ways to lock this down (some combination of Rust type
privacy and ECS validation)

In practice, how we store and identify assets is a reasonably
superficial change (porting off of Assets as Entities and implementing
dedicated storage + ids took less than a day). So once we sort out the
remaining challenges the flip should be straightforward. Additionally, I
do still have "Assets as Entities" in my commit history, so we can reuse
that work. I personally think "assets as entities" is a good endgame,
but it also doesn't provide _significant_ value at the moment and it
certainly isn't ready yet with the current state of things.

### Why not Distill?

[Distill](https://github.com/amethyst/distill) is a high quality fully
featured asset system built in Rust. It is very natural to ask "why not
just use Distill?".

It is also worth calling out that for awhile, [we planned on adopting
Distill / I signed off on
it](https://github.com/bevyengine/bevy/issues/708).

However I think Bevy has a number of constraints that make Distill
adoption suboptimal:
* **Architectural Simplicity:**
* Distill's processor requires an in-memory database (lmdb) and RPC
networked API (using Cap'n Proto). Each of these introduces API
complexity that increases maintenance burden and "code grokability".
Ignoring tests, documentation, and examples, Distill has 24,237 lines of
Rust code (including generated code for RPC + database interactions). If
you ignore generated code, it has 11,499 lines.
* Bevy builds the AssetProcessor and AssetServer using pluggable
AssetReader/AssetWriter Rust traits with simple io interfaces. They do
not necessitate databases or RPC interfaces (although Readers/Writers
could use them if that is desired). Bevy Asset V2 (at the time of
writing this PR) is 5,384 lines of Rust code (ignoring tests,
documentation, and examples). Grain of salt: Distill does have more
features currently (ex: Asset Packing, GUIDS, remote-out-of-process
asset processor). I do plan to implement these features in Bevy Asset V2
and I personally highly doubt they will meaningfully close the 6115
lines-of-code gap.
* This complexity gap (which while illustrated by lines of code, is much
bigger than just that) is noteworthy to me. Bevy should be hackable and
there are pillars of Distill that are very hard to understand and
extend. This is a matter of opinion (and Bevy Asset V2 also has
complicated areas), but I think Bevy Asset V2 is much more approachable
for the average developer.
* Necessary disclaimer: counting lines of code is an extremely rough
complexity metric. Read the code and form your own opinions.
* **Optional Asset Processing:** Not all Bevy Apps (or Bevy App
developers) need / want asset preprocessing. Processing increases the
complexity of the development environment by introducing things like
meta files, imported asset storage, running processors in the
background, waiting for processing to finish, etc. Distill _requires_
preprocessing to work. With Bevy Asset V2 processing is fully opt-in.
The AssetServer isn't directly aware of asset processors at all.
AssetLoaders only care about converting bytes to runtime Assets ... they
don't know or care if the bytes were pre-processed or not. Processing is
"elegantly" (forgive my self-congratulatory phrasing) layered on top and
builds on the existing Asset system primitives.
* **Direct Filesystem Access to Processed Asset State:** Distill stores
processed assets in a database. This makes debugging / inspecting the
processed outputs harder (either requires special tooling to query the
database or they need to be "deployed" to be inspected). Bevy Asset V2,
on the other hand, stores processed assets in the filesystem (by default
... this is configurable). This makes interacting with the processed
state more natural. Note that both Godot and Unity's new asset system
store processed assets in the filesystem.
* **Portability**: Because Distill's processor uses lmdb and RPC
networking, it cannot be run on certain platforms (ex: lmdb is a
non-rust dependency that cannot run on the web, some platforms don't
support running network servers). Bevy should be able to process assets
everywhere (ex: run the Bevy Editor on the web, compile + process
shaders on mobile, etc). Distill does partially mitigate this problem by
supporting "streaming" assets via the RPC protocol, but this is not a
full solve from my perspective. And Bevy Asset V2 can (in theory) also
stream assets (without requiring RPC, although this isn't implemented
yet)

Note that I _do_ still think Distill would be a solid asset system for
Bevy. But I think the approach in this PR is a better solve for Bevy's
specific "asset system requirements".

### Doesn't async-fs just shim requests to "sync" `std::fs`? What is the
point?

"True async file io" has limited / spotty platform support. async-fs
(and the rust async ecosystem generally ... ex Tokio) currently use
async wrappers over std::fs that offload blocking requests to separate
threads. This may feel unsatisfying, but it _does_ still provide value
because it prevents our task pools from blocking on file system
operations (which would prevent progress when there are many tasks to
do, but all threads in a pool are currently blocking on file system
ops).

Additionally, using async APIs for our AssetReaders and AssetWriters
also provides value because we can later add support for "true async
file io" for platforms that support it. _And_ we can implement other
"true async io" asset backends (such as networked asset io).

## Draft TODO

- [x] Fill in missing filesystem event APIs: file removed event (which
is expressed as dangling RenameFrom events in some cases), file/folder
renamed event
- [x] Assets without loaders are not moved to the processed folder. This
breaks things like referenced `.bin` files for GLTFs. This should be
configurable per-non-asset-type.
- [x] Initial implementation of Reflect and FromReflect for Handle. The
"deserialization" parity bar is low here as this only worked with static
UUIDs in the old impl ... this is a non-trivial problem. Either we add a
Handle::AssetPath variant that gets "upgraded" to a strong handle on
scene load or we use a separate AssetRef type for Bevy scenes (which is
converted to a runtime Handle on load). This deserves its own discussion
in a different pr.
- [x] Populate read_asset_bytes hash when run by the processor (a bit of
a special case .. when run by the processor the processed meta will
contain the hash so we don't need to compute it on the spot, but we
don't want/need to read the meta when run by the main AssetServer)
- [x] Delay hot reloading: currently filesystem events are handled
immediately, which creates timing issues in some cases. For example hot
reloading images can sometimes break because the image isn't finished
writing. We should add a delay, likely similar to the [implementation in
this PR](https://github.com/bevyengine/bevy/pull/8503).
- [x] Port old platform-specific AssetIo implementations to the new
AssetReader interface (currently missing Android and web)
- [x] Resolve on_loaded unsafety (either by removing the API entirely or
removing the unsafe)
- [x]  Runtime loader setting overrides
- [x] Remove remaining unwraps that should be error-handled. There are
number of TODOs here
- [x] Pretty AssetPath Display impl
- [x] Document more APIs
- [x] Resolve spurious "reloading because it has changed" events (to
repro run load_gltf with `processed_dev()`)
- [x] load_dependency hot reloading currently only works for processed
assets. If processing is disabled, load_dependency changes are not hot
reloaded.
- [x] Replace AssetInfo dependency load/fail counters with
`loading_dependencies: HashSet<UntypedAssetId>` to prevent reloads from
(potentially) breaking counters. Storing this will also enable
"dependency reloaded" events (see [Next Steps](#next-steps))
- [x] Re-add filesystem watcher cargo feature gate (currently it is not
optional)
- [ ] Migration Guide
- [ ] Changelog

## Followup TODO

- [ ] Replace "eager unchanged processed asset loading" behavior with
"don't returned unchanged processed asset until dependencies have been
checked".
- [ ] Add true `Ignore` AssetAction that does not copy the asset to the
imported_assets folder.
- [ ] Finish "live asset unloading" (ex: free up CPU asset memory after
uploading an image to the GPU), rethink RenderAssets, and port renderer
features. The `Assets` collection uses `Option<T>` for asset storage to
support its removal. (1) the Option might not actually be necessary ...
might be able to just remove from the collection entirely (2) need to
finalize removal apis
- [ ] Try replacing the "channel based" asset id recycling with
something a bit more efficient (ex: we might be able to use raw atomic
ints with some cleverness)
- [ ] Consider adding UUIDs to processed assets (scoped just to helping
identify moved assets ... not exposed to load queries ... see [Next
Steps](#next-steps))
- [ ] Store "last modified" source asset and meta timestamps in
processed meta files to enable skipping expensive hashing when the file
wasn't changed
- [ ] Fix "slow loop" handle drop fix 
- [ ] Migrate to TypeName
- [x] Handle "loader preregistration". See #9429

## Next Steps

* **Configurable per-type defaults for AssetMeta**: It should be
possible to add configuration like "all png image meta should default to
using nearest sampling" (currently this hard-coded per-loader/processor
Settings::default() impls). Also see the "Folder Meta" bullet point.
* **Avoid Reprocessing on Asset Renames / Moves**: See the "canonical
asset ids" discussion in [Open Questions](#open-questions) and the
relevant bullet point in [Draft TODO](#draft-todo). Even without
canonical ids, folder renames could avoid reprocessing in some cases.
* **Multiple Asset Sources**: Expand AssetPath to support "asset source
names" and support multiple AssetReaders in the asset server (ex:
`webserver://some_path/image.png` backed by an Http webserver
AssetReader). The "default" asset reader would use normal
`some_path/image.png` paths. Ideally this works in combination with
multiple AssetWatchers for hot-reloading
* **Stable Type Names**: this pr removes the TypeUuid requirement from
assets in favor of `std::any::type_name`. This makes defining assets
easier (no need to generate a new uuid / use weird proc macro syntax).
It also makes reading meta files easier (because things have "friendly
names"). We also use type names for components in scene files. If they
are good enough for components, they are good enough for assets. And
consistency across Bevy pillars is desirable. However,
`std::any::type_name` is not guaranteed to be stable (although in
practice it is). We've developed a [stable type
path](https://github.com/bevyengine/bevy/pull/7184) to resolve this,
which should be adopted when it is ready.
* **Command Line Interface**: It should be possible to run the asset
processor in a separate process from the command line. This will also
require building a network-server-backed AssetReader to communicate
between the app and the processor. We've been planning to build a "bevy
cli" for awhile. This seems like a good excuse to build it.
* **Asset Packing**: This is largely an additive feature, so it made
sense to me to punt this until we've laid the foundations in this PR.
* **Per-Platform Processed Assets**: It should be possible to generate
assets for multiple platforms by supporting multiple "processor
profiles" per asset (ex: compress with format X on PC and Y on iOS). I
think there should probably be arbitrary "profiles" (which can be
separate from actual platforms), which are then assigned to a given
platform when generating the final asset distribution for that platform.
Ex: maybe devs want a "Mobile" profile that is shared between iOS and
Android. Or a "LowEnd" profile shared between web and mobile.
* **Versioning and Migrations**: Assets, Loaders, Savers, and Processors
need to have versions to determine if their schema is valid. If an asset
/ loader version is incompatible with the current version expected at
runtime, the processor should be able to migrate them. I think we should
try using Bevy Reflect for this, as it would allow us to load the old
version as a dynamic Reflect type without actually having the old Rust
type. It would also allow us to define "patches" to migrate between
versions (Bevy Reflect devs are currently working on patching). The
`.meta` file already has its own format version. Migrating that to new
versions should also be possible.
* **Real Copy-on-write AssetPaths**: Rust's actual Cow (clone-on-write
type) currently used by AssetPath can still result in String clones that
aren't actually necessary (cloning an Owned Cow clones the contents).
Bevy's asset system requires cloning AssetPaths in a number of places,
which result in actual clones of the internal Strings. This is not
efficient. AssetPath internals should be reworked to exhibit truer
cow-like-behavior that reduces String clones to the absolute minimum.
* **Consider processor-less processing**: In theory the AssetServer
could run processors "inline" even if the background AssetProcessor is
disabled. If we decide this is actually desirable, we could add this.
But I don't think its a priority in the short or medium term.
* **Pre-emptive dependency loading**: We could encode dependencies in
processed meta files, which could then be used by the Asset Server to
kick of dependency loads as early as possible (prior to starting the
actual asset load). Is this desirable? How much time would this save in
practice?
* **Optimize Processor With UntypedAssetIds**: The processor exclusively
uses AssetPath to identify assets currently. It might be possible to
swap these out for UntypedAssetIds in some places, which are smaller /
cheaper to hash and compare.
* **One to Many Asset Processing**: An asset source file that produces
many assets currently must be processed into a single "processed" asset
source. If labeled assets can be written separately they can each have
their own configured savers _and_ they could be loaded more granularly.
Definitely worth exploring!
* **Automatically Track "Runtime-only" Asset Dependencies**: Right now,
tracking "created at runtime" asset dependencies requires adding them
via `asset_server.load_asset(StandardMaterial::default())`. I think with
some cleverness we could also do this for
`materials.add(StandardMaterial::default())`, making tracking work
"everywhere". There are challenges here relating to change detection /
ensuring the server is made aware of dependency changes. This could be
expensive in some cases.
* **"Dependency Changed" events**: Some assets have runtime artifacts
that need to be re-generated when one of their dependencies change (ex:
regenerate a material's bind group when a Texture needs to change). We
are generating the dependency graph so we can definitely produce these
events. Buuuuut generating these events will have a cost / they could be
high frequency for some assets, so we might want this to be opt-in for
specific cases.
* **Investigate Storing More Information In Handles**: Handles can now
store arbitrary information, which makes it cheaper and easier to
access. How much should we move into them? Canonical asset load states
(via atomics)? (`handle.is_loaded()` would be very cool). Should we
store the entire asset and remove the `Assets<T>` collection?
(`Arc<RwLock<Option<Image>>>`?)
* **Support processing and loading files without extensions**: This is a
pretty arbitrary restriction and could be supported with very minimal
changes.
* **Folder Meta**: It would be nice if we could define per folder
processor configuration defaults (likely in a `.meta` or `.folder_meta`
file). Things like "default to linear filtering for all Images in this
folder".
* **Replace async_broadcast with event-listener?** This might be
approximately drop-in for some uses and it feels more light weight
* **Support Running the AssetProcessor on the Web**: Most of the hard
work is done here, but there are some easy straggling TODOs (make the
transaction log an interface instead of a direct file writer so we can
write a web storage backend, implement an AssetReader/AssetWriter that
reads/writes to something like LocalStorage).
* **Consider identifying and preventing circular dependencies**: This is
especially important for "processor dependencies", as processing will
silently never finish in these cases.
* **Built-in/Inlined Asset Hot Reloading**: This PR regresses
"built-in/inlined" asset hot reloading (previously provided by the
DebugAssetServer). I'm intentionally punting this because I think it can
be cleanly implemented with "multiple asset sources" by registering a
"debug asset source" (ex: `debug://bevy_pbr/src/render/pbr.wgsl` asset
paths) in combination with an AssetWatcher for that asset source and
support for "manually loading pats with asset bytes instead of
AssetReaders". The old DebugAssetServer was quite nasty and I'd love to
avoid that hackery going forward.
* **Investigate ways to remove double-parsing meta files**: Parsing meta
files currently involves parsing once with "minimal" versions of the
meta file to extract the type name of the loader/processor config, then
parsing again to parse the "full" meta. This is suboptimal. We should be
able to define custom deserializers that (1) assume the loader/processor
type name comes first (2) dynamically looks up the loader/processor
registrations to deserialize settings in-line (similar to components in
the bevy scene format). Another alternative: deserialize as dynamic
Reflect objects and then convert.
* **More runtime loading configuration**: Support using the Handle type
as a hint to select an asset loader (instead of relying on AssetPath
extensions)
* **More high level Processor trait implementations**: For example, it
might be worth adding support for arbitrary chains of "asset transforms"
that modify an in-memory asset representation between loading and
saving. (ex: load a Mesh, run a `subdivide_mesh` transform, followed by
a `flip_normals` transform, then save the mesh to an efficient
compressed format).
* **Bevy Scene Handle Deserialization**: (see the relevant [Draft TODO
item](#draft-todo) for context)
* **Explore High Level Load Interfaces**: See [this
discussion](#discuss-on_loaded-high-level-interface) for one prototype.
* **Asset Streaming**: It would be great if we could stream Assets (ex:
stream a long video file piece by piece)
* **ID Exchanging**: In this PR Asset Handles/AssetIds are bigger than
they need to be because they have a Uuid enum variant. If we implement
an "id exchanging" system that trades Uuids for "efficient runtime ids",
we can cut down on the size of AssetIds, making them more efficient.
This has some open design questions, such as how to spawn entities with
"default" handle values (as these wouldn't have access to the exchange
api in the current system).
* **Asset Path Fixup Tooling**: Assets that inline asset paths inside
them will break when an asset moves. The asset system provides the
functionality to detect when paths break. We should build a framework
that enables formats to define "path migrations". This is especially
important for scene files. For editor-generated files, we should also
consider using UUIDs (see other bullet point) to avoid the need to
migrate in these cases.

---------

Co-authored-by: BeastLe9enD <beastle9end@outlook.de>
Co-authored-by: Mike <mike.hsu@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-09-07 02:07:27 +00:00
Rob Parrett
04885eb49c
Fix doc link in transparent_window example (#9697)
# Objective

This link became invalid after #5589.

## Solution

The docs that were being linked to still exist, but they're on `Window`
now.

This PR just updates that link.
2023-09-05 05:43:26 +00:00
Robert Swain
e9b3aeb38f
Enhance bevymark (#9674)
# Objective

- In preparation for an initial 2D/3D mesh batching/instancing PR,
enhance `bevymark` to support some different test modes that enable
comparison and optimisation of performance
 
## Solution

- Use `argh` for command line interface options
- Use seeded `StdRng` for reproducible random number generation
- Add a mode for testing 2D meshes that includes an option to uniquely
vary the data of each material by setting a random flat colour on the
`ColorMaterial`.
- Add a way of specifying the number of different textures to use for
sprites or meshes. These are generated at the same resolution as the
Bevy bird icon, but are just random flat colours for testing.
- Add a benchmark mode that spawns all entities during setup, and
animates the entities using a fixed delta time for reproducible
animation. The initially-spawned entities are still spawned in waves and
animated as they would have been had they spawned at intervals.

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2023-09-02 19:16:44 +00:00
Rob Parrett
870d46ec2e
Use default resolution for viewport_debug example (#9666)
# Objective

The `viewport_debug` example opens a window that is physically very
large. Probably larger than the screen for the majority of machines.

## Solution

Remove the custom resolution and adjust the pixel coordinates so that
everything lines up.

At the default resolution, everything is still whole numbers even
without adjusting the viewport coordinates.
2023-09-02 18:43:56 +00:00
Robert Swain
40c6b3b91e
Enhance many_cubes stress test use cases (#9596)
# Objective

- Make `many_cubes` suitable for testing various parts of the upcoming
batching work.

## Solution

- Use `argh` for CLI.
- Default to the sphere layout as it is more useful for benchmarking.
- Add a benchmark mode that advances the camera by a fixed step to
render the same frames across runs.
- Add an option to vary the material data per-instance. The color is
randomized.
- Add an option to generate a number of textures and randomly choose one
per instance.
- Use seeded `StdRng` for deterministic random numbers.
2023-09-02 14:49:32 +00:00
Joseph
02b520b4e8
Split ComputedVisibility into two components to allow for accurate change detection and speed up visibility propagation (#9497)
# Objective

Fix #8267.
Fixes half of #7840.

The `ComputedVisibility` component contains two flags: hierarchy
visibility, and view visibility (whether its visible to any cameras).
Due to the modular and open-ended way that view visibility is computed,
it triggers change detection every single frame, even when the value
does not change. Since hierarchy visibility is stored in the same
component as view visibility, this means that change detection for
inherited visibility is completely broken.

At the company I work for, this has become a real issue. We are using
change detection to only re-render scenes when necessary. The broken
state of change detection for computed visibility means that we have to
to rely on the non-inherited `Visibility` component for now. This is
workable in the early stages of our project, but since we will
inevitably want to use the hierarchy, we will have to either:

1. Roll our own solution for computed visibility.
2. Fix the issue for everyone.

## Solution

Split the `ComputedVisibility` component into two: `InheritedVisibilty`
and `ViewVisibility`.
This allows change detection to behave properly for
`InheritedVisibility`.
View visiblity is still erratic, although it is less useful to be able
to detect changes
for this flavor of visibility.

Overall, this actually simplifies the API. Since the visibility system
consists of
self-explaining components, it is much easier to document the behavior
and usage.
This approach is more modular and "ECS-like" -- one could
strip out the `ViewVisibility` component entirely if it's not needed,
and rely only on inherited visibility.

---

## Changelog

- `ComputedVisibility` has been removed in favor of:
`InheritedVisibility` and `ViewVisiblity`.

## Migration Guide

The `ComputedVisibilty` component has been split into
`InheritedVisiblity` and
`ViewVisibility`. Replace any usages of
`ComputedVisibility::is_visible_in_hierarchy`
with `InheritedVisibility::get`, and replace
`ComputedVisibility::is_visible_in_view`
 with `ViewVisibility::get`.
 
 ```rust
 // Before:
 commands.spawn(VisibilityBundle {
     visibility: Visibility::Inherited,
     computed_visibility: ComputedVisibility::default(),
 });
 
 // After:
 commands.spawn(VisibilityBundle {
     visibility: Visibility::Inherited,
     inherited_visibility: InheritedVisibility::default(),
     view_visibility: ViewVisibility::default(),
 });
 ```
 
 ```rust
 // Before:
 fn my_system(q: Query<&ComputedVisibilty>) {
     for vis in &q {
         if vis.is_visible_in_hierarchy() {
     
 // After:
 fn my_system(q: Query<&InheritedVisibility>) {
     for inherited_visibility in &q {
         if inherited_visibility.get() {
 ```
 
 ```rust
 // Before:
 fn my_system(q: Query<&ComputedVisibilty>) {
     for vis in &q {
         if vis.is_visible_in_view() {
     
 // After:
 fn my_system(q: Query<&ViewVisibility>) {
     for view_visibility in &q {
         if view_visibility.get() {
 ```
 
 ```rust
 // Before:
 fn my_system(mut q: Query<&mut ComputedVisibilty>) {
     for vis in &mut q {
         vis.set_visible_in_view();
     
 // After:
 fn my_system(mut q: Query<&mut ViewVisibility>) {
     for view_visibility in &mut q {
         view_visibility.set();
 ```

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-09-01 13:00:18 +00:00
lelo
42e6dc8987
Refactor EventReader::iter to read (#9631)
# Objective

- The current `EventReader::iter` has been determined to cause confusion
among new Bevy users. It was suggested by @JoJoJet to rename the method
to better clarify its usage.
- Solves #9624 

## Solution

- Rename `EventReader::iter` to `EventReader::read`.
- Rename `EventReader::iter_with_id` to `EventReader::read_with_id`.
- Rename `ManualEventReader::iter` to `ManualEventReader::read`.
- Rename `ManualEventReader::iter_with_id` to
`ManualEventReader::read_with_id`.

---

## Changelog

- `EventReader::iter` has been renamed to `EventReader::read`.
- `EventReader::iter_with_id` has been renamed to
`EventReader::read_with_id`.
- `ManualEventReader::iter` has been renamed to
`ManualEventReader::read`.
- `ManualEventReader::iter_with_id` has been renamed to
`ManualEventReader::read_with_id`.
- Deprecated `EventReader::iter`
- Deprecated `EventReader::iter_with_id`
- Deprecated `ManualEventReader::iter`
- Deprecated `ManualEventReader::iter_with_id`

## Migration Guide

- Existing usages of `EventReader::iter` and `EventReader::iter_with_id`
will have to be changed to `EventReader::read` and
`EventReader::read_with_id` respectively.
- Existing usages of `ManualEventReader::iter` and
`ManualEventReader::iter_with_id` will have to be changed to
`ManualEventReader::read` and `ManualEventReader::read_with_id`
respectively.
2023-08-30 14:20:03 +00:00
Ame :]
f2f39c835a
Check for bevy_internal imports in CI (#9612)
# Objective

- Avoid using bevy_internal imports in examples. 

## Solution

- Add CI to check for bevy_internal imports like suggested in
https://github.com/bevyengine/bevy/pull/9547#issuecomment-1689377999
- Fix another import

I don't know much about CI so I don't know if this is the better
approach, but I think is better than doing a pull request every time I
found this lol, any suggestion is welcome.

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2023-08-29 19:11:06 +00:00
Ame :]
1399078f12
remove VecSwizzles imports (#9629)
# Objective

- Since #9387, there is no need to import VecSwizzles separately, it is
already included in the prelude.

## Solution

- Remove the imports.
2023-08-29 18:59:10 +00:00
ickshonpe
2b2abcef97
Replace uses of entity.insert with tuple bundles in game_menu example (#9619)
# Objective

Change two places where `entity.insert` is used to add components
individually to spawn a tuple bundle instead.
2023-08-29 12:30:02 +00:00
jnhyatt
087a345579
Rename Bezier to CubicBezier for clarity (#9554)
# Objective

A Bezier curve is a curve defined by two or more control points. In the
simplest form, it's just a line. The (arguably) most common type of
Bezier curve is a cubic Bezier, defined by four control points. These
are often used in animation, etc. Bevy has a Bezier curve struct called
`Bezier`. However, this is technically a misnomer as it only represents
cubic Bezier curves.

## Solution

This PR changes the struct name to `CubicBezier` to more accurately
reflect the struct's usage. Since it's exposed in Bevy's prelude, it can
potentially collide with other `Bezier` implementations. While that
might instead be an argument for removing it from the prelude, there's
also something to be said for adding a more general `Bezier` into Bevy,
in which case we'd likely want to use the name `Bezier`. As a final
motivator, not only is the struct located in `cubic_spines.rs`, there
are also several other spline-related structs which follow the
`CubicXxx` naming convention where applicable. For example,
`CubicSegment` represents a cubic Bezier curve (with coefficients
pre-baked).

---

## Migration Guide

- Change all `Bezier` references to `CubicBezier`
2023-08-28 17:37:42 +00:00
DevinLeamy
db5f80b2be
API updates to the AnimationPlayer (#9002)
# Objective

Added `AnimationPlayer` API UX improvements. 

- Succestor to https://github.com/bevyengine/bevy/pull/5912
- Fixes https://github.com/bevyengine/bevy/issues/5848

_(Credits to @asafigan for filing #5848, creating the initial pull
request, and the discussion in #5912)_
## Solution

- Created `RepeatAnimation` enum to describe an animation repetition
behavior.
- Added `is_finished()`, `set_repeat()`, and `is_playback_reversed()`
methods to the animation player.
- ~~Made the animation clip optional as per the comment from #5912~~
> ~~My problem is that the default handle [used the initialize a
`PlayingAnimation`] could actually refer to an actual animation if an
AnimationClip is set for the default handle, which leads me to ask,
"Should animation_clip should be an Option?"~~
- Added an accessor for the animation clip `animation_clip()` to the
animation player.

To determine if an animation is finished, we use the number of times the
animation has completed and the repetition behavior. If the animation is
playing in reverse then `elapsed < 0.0` counts as a completion.
Otherwise, `elapsed > animation.duration` counts as a completion. This
is what I would expect, personally. If there's any ambiguity, perhaps we
could add some `AnimationCompletionBehavior`, to specify that kind of
completion behavior to use.

Update: Previously `PlayingAnimation::elapsed` was being used as the
seek time into the animation clip. This was misleading because if you
increased the speed of the animation it would also increase (or
decrease) the elapsed time. In other words, the elapsed time was not
actually the elapsed time. To solve this, we introduce
`PlayingAnimation::seek_time` to serve as the value we manipulate the
move between keyframes. Consequently, `elapsed()` now returns the actual
elapsed time, and is not effected by the animation speed. Because
`set_elapsed` was being used to manipulate the displayed keyframe, we
introduce `AnimationPlayer::seek_to` and `AnimationPlayer::replay` to
provide this functionality.

## Migration Guide

- Removed `set_elapsed`.
- Removed `stop_repeating` in favour of
`AnimationPlayer::set_repeat(RepeatAnimation::Never)`.
- Introduced `seek_to` to seek to a given timestamp inside of the
animation.
- Introduced `seek_time` accessor for the `PlayingAnimation::seek_to`.
- Introduced `AnimationPlayer::replay` to reset the `PlayingAnimation`
to a state where no time has elapsed.

---------

Co-authored-by: Hennadii Chernyshchyk <genaloner@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-08-28 16:43:04 +00:00
Joseph
474b55a29c
Add system.map(...) for transforming the output of a system (#8526)
# Objective

Any time we wish to transform the output of a system, we currently use
system piping to do so:

```rust
my_system.pipe(|In(x)| do_something(x))
```

Unfortunately, system piping is not a zero cost abstraction. Each call
to `.pipe` requires allocating two extra access sets: one for the second
system and one for the combined accesses of both systems. This also adds
extra work to each call to `update_archetype_component_access`, which
stacks as one adds multiple layers of system piping.

## Solution

Add the `AdapterSystem` abstraction: similar to `CombinatorSystem`, this
allows you to implement a trait to generically control how a system is
run and how its inputs and outputs are processed. Unlike
`CombinatorSystem`, this does not have any overhead when computing world
accesses which makes it ideal for simple operations such as inverting or
ignoring the output of a system.

Add the extension method `.map(...)`: this is similar to `.pipe(...)`,
only it accepts a closure as an argument instead of an `In<T>` system.

```rust
my_system.map(do_something)
```

This has the added benefit of making system names less messy: a system
that ignores its output will just be called `my_system`, instead of
`Pipe(my_system, ignore)`

---

## Changelog

TODO

## Migration Guide

The `system_adapter` functions have been deprecated: use `.map` instead,
which is a lightweight alternative to `.pipe`.

```rust
// Before:
my_system.pipe(system_adapter::ignore)
my_system.pipe(system_adapter::unwrap)
my_system.pipe(system_adapter::new(T::from))

// After:
my_system.map(std::mem::drop)
my_system.map(Result::unwrap)
my_system.map(T::from)

// Before:
my_system.pipe(system_adapter::info)
my_system.pipe(system_adapter::dbg)
my_system.pipe(system_adapter::warn)
my_system.pipe(system_adapter::error)

// After:
my_system.map(bevy_utils::info)
my_system.map(bevy_utils::dbg)
my_system.map(bevy_utils::warn)
my_system.map(bevy_utils::error)
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-08-28 16:36:46 +00:00
James O'Brien
4f1d9a6315
Reorder render sets, refactor bevy_sprite to take advantage (#9236)
This is a continuation of this PR: #8062 

# Objective

- Reorder render schedule sets to allow data preparation when phase item
order is known to support improved batching
- Part of the batching/instancing etc plan from here:
https://github.com/bevyengine/bevy/issues/89#issuecomment-1379249074
- The original idea came from @inodentry and proved to be a good one.
Thanks!
- Refactor `bevy_sprite` and `bevy_ui` to take advantage of the new
ordering

## Solution
- Move `Prepare` and `PrepareFlush` after `PhaseSortFlush` 
- Add a `PrepareAssets` set that runs in parallel with other systems and
sets in the render schedule.
  - Put prepare_assets systems in the `PrepareAssets` set
- If explicit dependencies are needed on Mesh or Material RenderAssets
then depend on the appropriate system.
- Add `ManageViews` and `ManageViewsFlush` sets between
`ExtractCommands` and Queue
- Move `queue_mesh*_bind_group` to the Prepare stage
  - Rename them to `prepare_`
- Put systems that prepare resources (buffers, textures, etc.) into a
`PrepareResources` set inside `Prepare`
- Put the `prepare_..._bind_group` systems into a `PrepareBindGroup` set
after `PrepareResources`
- Move `prepare_lights` to the `ManageViews` set
  - `prepare_lights` creates views and this must happen before `Queue`
  - This system needs refactoring to stop handling all responsibilities
- Gather lights, sort, and create shadow map views. Store sorted light
entities in a resource

- Remove `BatchedPhaseItem`
- Replace `batch_range` with `batch_size` representing how many items to
skip after rendering the item or to skip the item entirely if
`batch_size` is 0.
- `queue_sprites` has been split into `queue_sprites` for queueing phase
items and `prepare_sprites` for batching after the `PhaseSort`
  - `PhaseItem`s are still inserted in `queue_sprites`
- After sorting adjacent compatible sprite phase items are accumulated
into `SpriteBatch` components on the first entity of each batch,
containing a range of vertex indices. The associated `PhaseItem`'s
`batch_size` is updated appropriately.
- `SpriteBatch` items are then drawn skipping over the other items in
the batch based on the value in `batch_size`
- A very similar refactor was performed on `bevy_ui`
---

## Changelog

Changed:
- Reordered and reworked render app schedule sets. The main change is
that data is extracted, queued, sorted, and then prepared when the order
of data is known.
- Refactor `bevy_sprite` and `bevy_ui` to take advantage of the
reordering.

## Migration Guide
- Assets such as materials and meshes should now be created in
`PrepareAssets` e.g. `prepare_assets<Mesh>`
- Queueing entities to `RenderPhase`s continues to be done in `Queue`
e.g. `queue_sprites`
- Preparing resources (textures, buffers, etc.) should now be done in
`PrepareResources`, e.g. `prepare_prepass_textures`,
`prepare_mesh_uniforms`
- Prepare bind groups should now be done in `PrepareBindGroups` e.g.
`prepare_mesh_bind_group`
- Any batching or instancing can now be done in `Prepare` where the
order of the phase items is known e.g. `prepare_sprites`

 
## Next Steps
- Introduce some generic mechanism to ensure items that can be batched
are grouped in the phase item order, currently you could easily have
`[sprite at z 0, mesh at z 0, sprite at z 0]` preventing batching.
 - Investigate improved orderings for building the MeshUniform buffer
 - Implementing batching across the rest of bevy

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2023-08-27 14:33:49 +00:00
Zachary Harrold
90b3ac7f3a
Added Val::ZERO Constant (#9566)
# Objective

- Fixes #9533

## Solution

* Added `Val::ZERO` as a constant which is defined as `Val::Px(0.)`.
* Added manual `PartialEq` implementation for `Val` which allows any
zero value to equal any other zero value. E.g., `Val::Px(0.) ==
Val::Percent(0.)` etc. This is technically a breaking change, as
`Val::Px(0.) == Val::Percent(0.)` now equals `true` instead of `false`
(as an example)
* Replaced instances of `Val::Px(0.)`, `Val::Percent(0.)`, etc. with
`Val::ZERO`
* Fixed `bevy_ui::layout::convert::tests::test_convert_from` test to
account for Taffy not equating `Points(0.)` and `Percent(0.)`. These
tests now use `assert_eq!(...)` instead of `assert!(matches!(...))`
which gives easier to diagnose error messages.
2023-08-26 14:00:53 +00:00
Rob Parrett
a788e31ad5
Fix CI for Rust 1.72 (#9562)
# Objective

[Rust 1.72.0](https://blog.rust-lang.org/2023/08/24/Rust-1.72.0.html) is
now stable.

# Notes

- `let-else` formatting has arrived!
- I chose to allow `explicit_iter_loop` due to
https://github.com/rust-lang/rust-clippy/issues/11074.
  
We didn't hit any of the false positives that prevent compilation, but
fixing this did produce a lot of the "symbol soup" mentioned, e.g. `for
image in &mut *image_events {`.
  
  Happy to undo this if there's consensus the other way.

---------

Co-authored-by: François <mockersf@gmail.com>
2023-08-25 12:34:24 +00:00
ickshonpe
373f1eeb1e
UI examples clean up (#9479)
# Objective

Fix a few issues with some of the examples:

* Root UI nodes have an implicit parent with `FlexDirection::Row` and
`AlignItems::Stretch` set. Only a width constraint is needed to fill the
viewport. Specifying ```height: Val::Percent(100.)``` is unnecessary and
can cause confusing overflow behaviour.

* The default for position and size constraint properties is
`Val::Auto`. Setting `left: Val::Auto`, `max_height: Val::Auto`, etc
does nothing.


## Solution

Delete those lines. There should be no observable differences in the
behaviours of any of the examples.

Also changed a padding setting in the `flex_layout` example to use the
`axes` helper function.
2023-08-23 12:49:10 +00:00
Ame :]
427ba3074a
fix bevy imports. windows_settings.rs example (#9547)
# Objective

In #9355 was added an import using bevy_internal.
This change the import to use `bevy::window` instead of a
`bevy_internal` to run the example outside of the bevy repo.
2023-08-23 12:35:42 +00:00
IceSentry
49bbbe01d5
User controlled window visibility (#9355)
# Objective

- When spawning a window, it will be white until the GPU is ready to
draw the app. To avoid this, we can make the window invisible and then
make it visible once the gpu is ready. Unfortunately, the visible flag
is not available to users.

## Solution

- Let users change the visible flag

## Notes

This is only user controlled. It would be nice if it was done
automatically by bevy instead but I want to keep this PR simple.
2023-08-20 22:42:07 +00:00
Joshua Walton
140d9612e6
Add GamepadButtonInput event (#9008)
# Objective

Add `GamepadButtonInput` event
Resolves #8988

## Solution

- Add `GamepadButtonInput` type
- Emit `GamepadButtonInput` events whenever `Input<GamepadButton>` is
written to
- Update example

---------

Co-authored-by: François <mockersf@gmail.com>
2023-08-20 20:31:27 +00:00
st0rmbtw
b6a9d8eba7
Change UiScale to a tuple struct (#9444)
# Objective

Inconvenient initialization of `UiScale`

## Solution

Change `UiScale` to a tuple struct

## Migration Guide

Replace initialization of `UiScale` like ```UiScale { scale: 1.0 }```
with ```UiScale(1.0)```
2023-08-16 18:18:50 +00:00
Robert Swain
0a11af9375
Reduce the size of MeshUniform to improve performance (#9416)
# Objective

- Significantly reduce the size of MeshUniform by only including
necessary data.

## Solution

Local to world, model transforms are affine. This means they only need a
4x3 matrix to represent them.

`MeshUniform` stores the current, and previous model transforms, and the
inverse transpose of the current model transform, all as 4x4 matrices.
Instead we can store the current, and previous model transforms as 4x3
matrices, and we only need the upper-left 3x3 part of the inverse
transpose of the current model transform. This change allows us to
reduce the serialized MeshUniform size from 208 bytes to 144 bytes,
which is over a 30% saving in data to serialize, and VRAM bandwidth and
space.

## Benchmarks

On an M1 Max, running `many_cubes -- sphere`, main is in yellow, this PR
is in red:
<img width="1484" alt="Screenshot 2023-08-11 at 02 36 43"
src="https://github.com/bevyengine/bevy/assets/302146/7d99c7b3-f2bb-4004-a8d0-4c00f755cb0d">
A reduction in frame time of ~14%.

---

## Changelog

- Changed: Redefined `MeshUniform` to improve performance by using 4x3
affine transforms and reconstructing 4x4 matrices in the shader. Helper
functions were added to `bevy_pbr::mesh_functions` to unpack the data.
`affine_to_square` converts the packed 4x3 in 3x4 matrix data to a 4x4
matrix. `mat2x4_f32_to_mat3x3` converts the 3x3 in mat2x4 + f32 matrix
data back into a 3x3.

## Migration Guide

Shader code before:
```
var model = mesh[instance_index].model;
```

Shader code after:
```
#import bevy_pbr::mesh_functions affine_to_square

var model = affine_to_square(mesh[instance_index].model);
```
2023-08-15 06:00:23 +00:00
Oli Wilkins
43fe83b7c6
Example Comment Typo Fix (#9427)
# Objective

Fixes a typo in one of the comments in an example.

## Solution

Fix the typo in the comment.
2023-08-12 21:06:15 +00:00
Seb Ospina
e489dcc9e8
webgl feature renamed to webgl2 (#9370)
Addresses:
```sh
$ cargo build --release --example lighting --target wasm32-unknown-unknown --features webgl
error: none of the selected packages contains these features: webgl, did you mean: webgl2, webp?
```

# Objective

- When following the instructions for the web examples.
- Document clearly the generated file `./target/wasm_example.js`, since
it didn't appear on `git grep` (missing extension)

## Solution

- Follow the feature rename on the docs.

---------

Signed-off-by: Seb Ospina <kraige@gmail.com>
2023-08-12 21:05:36 +00:00
ickshonpe
6a8fd54006
Unnecessary line in game_menu example (#9406)
# Objective

In the `game_menu` example:

```rust
let button_icon_style = Style {
            width: Val::Px(30.0),
            // This takes the icons out of the flexbox flow, to be positioned exactly
            position_type: PositionType::Absolute,
            // The icon will be close to the left border of the button
            left: Val::Px(10.0),
            right: Val::Auto,
            ..default()
        };
```

The default value for `right` is `Val::Auto` so that line is unnecessary
and can be removed.
2023-08-11 21:12:57 +00:00
Hans Meine
1abb6b0758
elaborate on TaskPool and bevy tasks (#8750)
# Objective

I found it very difficult to understand how bevy tasks work, and I
concluded that the documentation should be improved for beginners like
me.

## Solution

These changes to the documentation were written from my beginner's
perspective after
some extremely helpful explanations by nil on Discord.

I am not familiar enough with rustdoc yet; when looking at the source, I
found the documentation at the very top of `usages.rs` helpful, but I
don't know where they are rendered. They should probably be linked to
from the main `bevy_tasks` README.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Mike <mike.hsu@gmail.com>
2023-08-11 21:07:28 +00:00
Ame :]
06f7f9640a
Use bevy crates imports instead of bevy internal. post_processing example (#9396)
# Objective

- I want to run the post_processing example in a new project, but I
can't because it uses bevy internal imports.

## Solution

- Change the bevy_internal imports to their respective bevy crates
imports
2023-08-10 02:02:30 +00:00
Dimitri Belopopsky
b8695d06b1
Fix non-visible motion vector text in shader prepass example (#9155)
# Objective

In the shader prepass example, changing to the motion vector output
hides the text, because both it and the background are rendererd black.
Seems to have been caused by this commit?
71cf35ce42

## Solution

Make the text white on all outputs.
2023-08-10 00:01:23 +00:00
IceSentry
171ff1b1e1
use ViewNodeRunner in the post_processing example (#9127)
# Objective

- I forgot to update the example after the `ViewNodeRunner` was merged.
It was even partially mentioned in one of the comments.

## Solution

- Use the `ViewNodeRunner` in the post_processing example
- I also broke up a few lines that were a bit long

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-08-07 23:02:32 +00:00
Rob Parrett
e1e2407091
Fix post_processing example on webgl2 (#9361)
# Objective

The `post_processing` example is currently broken when run with webgl2.

```
cargo run --example post_processing --target=wasm32-unknown-unknown
```

```
wasm.js:387 panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `post_process_pipeline`
    In the provided shader, the type given for group 0 binding 2 has a size of 4. As the device does not support `DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED`, the type must have a size that is a multiple of 16 bytes.
```

I bisected the breakage to c7eaedd6a1.

## Solution

Add padding when using webgl2
2023-08-04 17:44:29 +00:00
François
b6a2fc5d80
Improve execution of examples in CI (#9331)
# Objective

- Some examples crash in CI because of needing too many resources for
the windows runner
- Some examples have random results making it hard to compare
screenshots

## Solution

- `bloom_3d`: reduce the number of spheres
- `pbr`:  use simpler spheres and reuse the mesh
- `tonemapping`: use simpler spheres and reuse the mesh
- `shadow_biases`: reduce the number of spheres
- `spotlight`: use a seeded rng, move more cubes in view while reducing
the total number of cubes, and reuse meshes and materials
- `external_source_external_thread`, `iter_combinations`,
`parallel_query`: use a seeded rng

Examples of errors encountered:
```
Caused by:
    In Device::create_bind_group
      note: label = `bloom_upsampling_bind_group`
    Not enough memory left
```

```
Caused by:
    In Queue::write_buffer
    Parent device is lost
```
```
ERROR wgpu_core::device::life: Mapping failed Device(Lost)
```
2023-08-03 12:45:28 +00:00
Cameron
c0510c87ff
Improve bevy_winit documentation (#7609)
Redo of #7590 since I messed up my branch.

# Objective

- Revise docs.
- Refactor event loop code a little bit to make it easier to follow.

## Solution

- Do the above.

---

### Migration Guide

- `UpdateMode::Reactive { max_wait: .. }` -> `UpdateMode::Reactive {
wait: .. }`
- `UpdateMode::ReactiveLowPower { max_wait: .. }` ->
`UpdateMode::ReactiveLowPower { wait: .. }`

---------

Co-authored-by: Sélène Amanita <134181069+Selene-Amanita@users.noreply.github.com>
2023-07-31 21:41:59 +00:00
Ars Militaris Dev
370eed05e5
Fix timers.rs documentation (#9290)
# Objective

The documentation for the `print_when_completed` system stated that this
system would tick the `Timer` component on every entity in the scene.

This was incorrect as this system only ticks the `Timer` on entities
with the `PrintOnCompletionTimer` component.

## Solution

We suggest a modification to the documentation of this system to make it
more clear.
2023-07-30 15:30:05 +00:00
Василий Чай
fb9c5a6cbb
Added Pitch as an alternative sound source (#9225)
# Objective
My attempt at implementing #7515

## Solution

Added struct `Pitch` and implemented on it `Source` trait.

## Changelog

 ### Added
- File pitch.rs to bevy_audio crate
- Struct `Pitch` and type aliases for `AudioSourceBundle<Pitch>` and
`SpatialAudioSourceBundle<Pitch>`
- New example showing how to use `PitchBundle`

### Changed
- `AudioPlugin` now adds system for `Pitch` audio

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-07-29 22:29:41 +00:00
Paul Buehne
0566e73af4
Fixed typo in line 322 (#9276)
`trait` was spelled `trai` and used singular instead of plural in
documenting comment.
2023-07-26 06:04:01 +00:00
张林伟
dfe462b019
Update text example using default font (#9259)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/9233
2023-07-24 18:35:14 +00:00
Joseph
ddbfa48711
Simplify parallel iteration methods (#8854)
# Objective

The `QueryParIter::for_each_mut` function is required when doing
parallel iteration with mutable queries.
This results in an unfortunate stutter:
`query.par_iter_mut().par_for_each_mut()` ('mut' is repeated).

## Solution

- Make `for_each` compatible with mutable queries, and deprecate
`for_each_mut`. In order to prevent `for_each` from being called
multiple times in parallel, we take ownership of the QueryParIter.

---

## Changelog

- `QueryParIter::for_each` is now compatible with mutable queries.
`for_each_mut` has been deprecated as it is now redundant.

## Migration Guide

The method `QueryParIter::for_each_mut` has been deprecated and is no
longer functional. Use `for_each` instead, which now supports mutable
queries.

```rust
// Before:
query.par_iter_mut().for_each_mut(|x| ...);

// After:
query.par_iter_mut().for_each(|x| ...);
```

The method `QueryParIter::for_each` now takes ownership of the
`QueryParIter`, rather than taking a shared reference.

```rust
// Before:
let par_iter = my_query.par_iter().batching_strategy(my_batching_strategy);
par_iter.for_each(|x| {
    // ...Do stuff with x...
    par_iter.for_each(|y| {
        // ...Do nested stuff with y...
    });
});

// After:
my_query.par_iter().batching_strategy(my_batching_strategy).for_each(|x| {
    // ...Do stuff with x...
    my_query.par_iter().batching_strategy(my_batching_strategy).for_each(|y| {
        // ...Do nested stuff with y...
    });
});
```
2023-07-23 11:09:24 +00:00
Aleksa Pavlović
5e8ee108cb
Add option to toggle window control buttons (#9083)
# Objective

Implements #9082 but with an option to toggle minimize and close buttons
too.

## Solution

- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.

---

## Changelog

- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.
- Added a new system to the `window_settings` example which demonstrates
the toggling functionality.

---

## Migration guide

- Added an `enabled_buttons` member to the `Window` struct through which
users can enable or disable specific window control buttons.
2023-07-23 01:02:40 +00:00
François
eb485b1acc
use AutoNoVsync in stress tests (#9229)
# Objective

- Some stress tests use `Immediate` which is not supported everywhere

## Solution

- Use `AutoNoVsync` instead
2023-07-21 20:15:13 +00:00
Manuel Fuchs
b7cda3293f
Fix path reference to contributors example (#9219)
# Objective

Fix in incorrect reference to another example.

## Solution

Fix the reference. :-)
2023-07-20 17:20:34 +00:00
ClayenKitten
ffc572728f
Fix typos throughout the project (#9090)
# Objective

Fix typos throughout the project.

## Solution

[`typos`](https://github.com/crate-ci/typos) project was used for
scanning, but no automatic corrections were applied. I checked
everything by hand before fixing.

Most of the changes are documentation/comments corrections. Also, there
are few trivial changes to code (variable name, pub(crate) function name
and a few error/panic messages).

## Unsolved

`bevy_reflect_derive` has
[typo](1b51053f19/crates/bevy_reflect/bevy_reflect_derive/src/type_path.rs (L76))
in enum variant name that I didn't fix. Enum is `pub(crate)`, so there
shouldn't be any trouble if fixed. However, code is tightly coupled with
macro usage, so I decided to leave it for more experienced contributor
just in case.
2023-07-10 00:11:51 +00:00
Ida "Iyes
fb4c21e3e6
bevy_audio: ECS-based API redesign (#8424)
# Objective

Improve the `bevy_audio` API to make it more user-friendly and
ECS-idiomatic. This PR is a first-pass at addressing some of the most
obvious (to me) problems. In the interest of keeping the scope small,
further improvements can be done in future PRs.

The current `bevy_audio` API is very clunky to work with, due to how it
(ab)uses bevy assets to represent audio sinks.

The user needs to write a lot of boilerplate (accessing
`Res<Assets<AudioSink>>`) and deal with a lot of cognitive overhead
(worry about strong vs. weak handles, etc.) in order to control audio
playback.

Audio playback is initiated via a centralized `Audio` resource, which
makes it difficult to keep track of many different sounds playing in a
typical game.

Further, everything carries a generic type parameter for the sound
source type, making it difficult to mix custom sound sources (such as
procedurally generated audio or unofficial formats) with regular audio
assets.

Let's fix these issues.

## Solution

Refactor `bevy_audio` to a more idiomatic ECS API. Remove the `Audio`
resource. Do everything via entities and components instead.

Audio playback data is now stored in components:
- `PlaybackSettings`, `SpatialSettings`, `Handle<AudioSource>` are now
components. The user inserts them to tell Bevy to play a sound and
configure the initial playback parameters.
- `AudioSink`, `SpatialAudioSink` are now components instead of special
magical "asset" types. They are inserted by Bevy when it actually begins
playing the sound, and can be queried for by the user in order to
control the sound during playback.

Bundles: `AudioBundle` and `SpatialAudioBundle` are available to make it
easy for users to play sounds. Spawn an entity with one of these bundles
(or insert them to a complex entity alongside other stuff) to play a
sound.

Each entity represents a sound to be played.

There is also a new "auto-despawn" feature (activated using
`PlaybackSettings`), which, if enabled, tells Bevy to despawn entities
when the sink playback finishes. This allows for "fire-and-forget" sound
playback. Users can simply
spawn entities whenever they want to play sounds and not have to worry
about leaking memory.

## Unsolved Questions

I think the current design is *fine*. I'd be happy for it to be merged.
It has some possibly-surprising usability pitfalls, but I think it is
still much better than the old `bevy_audio`. Here are some discussion
questions for things that we could further improve. I'm undecided on
these questions, which is why I didn't implement them. We should decide
which of these should be addressed in this PR, and what should be left
for future PRs. Or if they should be addressed at all.

### What happens when sounds start playing?

Currently, the audio sink components are inserted and the bundle
components are kept. Should Bevy remove the bundle components? Something
else?

The current design allows an entity to be reused for playing the same
sound with the same parameters repeatedly. This is a niche use case I'd
like to be supported, but if we have to give it up for a simpler design,
I'd be fine with that.

### What happens if users remove any of the components themselves?

As described above, currently, entities can be reused. Removing the
audio sink causes it to be "detached" (I kept the old `Drop` impl), so
the sound keeps playing. However, if the audio bundle components are not
removed, Bevy will detect this entity as a "queued" sound entity again
(has the bundle compoenents, without a sink component), just like before
playing the sound the first time, and start playing the sound again.

This behavior might be surprising? Should we do something different?

### Should mutations to `PlaybackSettings` be applied to the audio sink?

We currently do not do that. `PlaybackSettings` is just for the initial
settings when the sound starts playing. This is clearly documented.

Do we want to keep this behavior, or do we want to allow users to use
`PlaybackSettings` instead of `AudioSink`/`SpatialAudioSink` to control
sounds during playback too?

I think I prefer for them to be kept separate. It is not a bad mental
model once you understand it, and it is documented.

### Should `AudioSink` and `SpatialAudioSink` be unified into a single
component type?

They provide a similar API (via the `AudioSinkPlayback` trait) and it
might be annoying for users to have to deal with both of them. The
unification could be done using an enum that is matched on internally by
the methods. Spatial audio has extra features, so this might make it
harder to access. I think we shouldn't.

### Automatic synchronization of spatial sound properties from
Transforms?

Should Bevy automatically apply changes to Transforms to spatial audio
entities? How do we distinguish between listener and emitter? Which one
does the transform represent? Where should the other one come from?

Alternatively, leave this problem for now, and address it in a future
PR. Or do nothing, and let users deal with it, as shown in the
`spatial_audio_2d` and `spatial_audio_3d` examples.

---

## Changelog

Added:
- `AudioBundle`/`SpatialAudioBundle`, add them to entities to play
sounds.

Removed:
 - The `Audio` resource.
 - `AudioOutput` is no longer `pub`.

Changed:
 - `AudioSink`, `SpatialAudioSink` are now components instead of assets.

## Migration Guide

// TODO: write a more detailed migration guide, after the "unsolved
questions" are answered and this PR is finalized.

Before:

```rust

/// Need to store handles somewhere
#[derive(Resource)]
struct MyMusic {
    sink: Handle<AudioSink>,
}

fn play_music(
    asset_server: Res<AssetServer>,
    audio: Res<Audio>,
    audio_sinks: Res<Assets<AudioSink>>,
    mut commands: Commands,
) {
    let weak_handle = audio.play_with_settings(
        asset_server.load("music.ogg"),
        PlaybackSettings::LOOP.with_volume(0.5),
    );
    // upgrade to strong handle and store it
    commands.insert_resource(MyMusic {
        sink: audio_sinks.get_handle(weak_handle),
    });
}

fn toggle_pause_music(
    audio_sinks: Res<Assets<AudioSink>>,
    mymusic: Option<Res<MyMusic>>,
) {
    if let Some(mymusic) = &mymusic {
        if let Some(sink) = audio_sinks.get(&mymusic.sink) {
            sink.toggle();
        }
    }
}
```

Now:

```rust
/// Marker component for our music entity
#[derive(Component)]
struct MyMusic;

fn play_music(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
) {
    commands.spawn((
        AudioBundle::from_audio_source(asset_server.load("music.ogg"))
            .with_settings(PlaybackSettings::LOOP.with_volume(0.5)),
        MyMusic,
    ));
}

fn toggle_pause_music(
    // `AudioSink` will be inserted by Bevy when the audio starts playing
    query_music: Query<&AudioSink, With<MyMusic>>,
) {
    if let Ok(sink) = query.get_single() {
        sink.toggle();
    }
}
```
2023-07-07 23:01:17 +00:00
Gino Valente
d96933ad9c
bevy_scene: Add SceneFilter (#6793)
# Objective

Currently, `DynamicScene`s extract all components listed in the given
(or the world's) type registry. This acts as a quasi-filter of sorts.
However, it can be troublesome to use effectively and lacks decent
control.

For example, say you need to serialize only the following component over
the network:

```rust
#[derive(Reflect, Component, Default)]
#[reflect(Component)]
struct NPC {
  name: Option<String>
}
```

To do this, you'd need to:
1. Create a new `AppTypeRegistry`
2. Register `NPC`
3. Register `Option<String>`

If we skip Step 3, then the entire scene might fail to serialize as
`Option<String>` requires registration.

Not only is this annoying and easy to forget, but it can leave users
with an impossible task: serializing a third-party type that contains
private types.

Generally, the third-party crate will register their private types
within a plugin so the user doesn't need to do it themselves. However,
this means we are now unable to serialize _just_ that type— we're forced
to allow everything!

## Solution

Add the `SceneFilter` enum for filtering components to extract.

This filter can be used to optionally allow or deny entire sets of
components/resources. With the `DynamicSceneBuilder`, users have more
control over how their `DynamicScene`s are built.

To only serialize a subset of components, use the `allow` method:
```rust
let scene = builder
  .allow::<ComponentA>()
  .allow::<ComponentB>()
  .extract_entity(entity)
  .build();
```

To serialize everything _but_ a subset of components, use the `deny`
method:
```rust
let scene = builder
  .deny::<ComponentA>()
  .deny::<ComponentB>()
  .extract_entity(entity)
  .build();
```

Or create a custom filter:
```rust
let components = HashSet::from([type_id]);

let filter = SceneFilter::Allowlist(components);
// let filter = SceneFilter::Denylist(components);

let scene = builder
  .with_filter(Some(filter))
  .extract_entity(entity)
  .build();
```

Similar operations exist for resources:

<details>
<summary>View Resource Methods</summary>

To only serialize a subset of resources, use the `allow_resource`
method:
```rust
let scene = builder
  .allow_resource::<ResourceA>()
  .extract_resources()
  .build();
```

To serialize everything _but_ a subset of resources, use the
`deny_resource` method:
```rust
let scene = builder
  .deny_resource::<ResourceA>()
  .extract_resources()
  .build();
```

Or create a custom filter:
```rust
let resources = HashSet::from([type_id]);

let filter = SceneFilter::Allowlist(resources);
// let filter = SceneFilter::Denylist(resources);

let scene = builder
  .with_resource_filter(Some(filter))
  .extract_resources()
  .build();
```

</details>

### Open Questions

- [x] ~~`allow` and `deny` are mutually exclusive. Currently, they
overwrite each other. Should this instead be a panic?~~ Took @soqb's
suggestion and made it so that the opposing method simply removes that
type from the list.
- [x] ~~`DynamicSceneBuilder` extracts entity data as soon as
`extract_entity`/`extract_entities` is called. Should this behavior
instead be moved to the `build` method to prevent ordering mixups (e.g.
`.allow::<Foo>().extract_entity(entity)` vs
`.extract_entity(entity).allow::<Foo>()`)? The tradeoff would be
iterating over the given entities twice: once at extraction and again at
build.~~ Based on the feedback from @Testare it sounds like it might be
better to just keep the current functionality (if anything we can open a
separate PR that adds deferred methods for extraction, so the
choice/performance hit is up to the user).
- [ ] An alternative might be to remove the filter from
`DynamicSceneBuilder` and have it as a separate parameter to the
extraction methods (either in the existing ones or as added
`extract_entity_with_filter`-type methods). Is this preferable?
- [x] ~~Should we include constructors that include common types to
allow/deny? For example, a `SceneFilter::standard_allowlist` that
includes things like `Parent` and `Children`?~~ Consensus suggests we
should. I may split this out into a followup PR, though.
- [x] ~~Should we add the ability to remove types from the filter
regardless of whether an allowlist or denylist (e.g.
`filter.remove::<Foo>()`)?~~ See the first list item
- [x] ~~Should `SceneFilter` be an enum? Would it make more sense as a
struct that contains an `is_denylist` boolean?~~ With the added
`SceneFilter::None` state (replacing the need to wrap in an `Option` or
rely on an empty `Denylist`), it seems an enum is better suited now
- [x] ~~Bikeshed: Do we like the naming convention? Should we instead
use `include`/`exclude` terminology?~~ Sounds like we're sticking with
`allow`/`deny`!
- [x] ~~Does this feature need a new example? Do we simply include it in
the existing one (maybe even as a comment?)? Should this be done in a
followup PR instead?~~ Example will be added in a followup PR

### Followup Tasks

- [ ] Add a dedicated `SceneFilter` example
- [ ] Possibly add default types to the filter (e.g. deny things like
`ComputedVisibility`, allow `Parent`, etc)

---

## Changelog

- Added the `SceneFilter` enum for filtering components and resources
when building a `DynamicScene`
- Added methods:
  - `DynamicSceneBuilder::with_filter`
  - `DynamicSceneBuilder::allow`
  - `DynamicSceneBuilder::deny`
  - `DynamicSceneBuilder::allow_all`
  - `DynamicSceneBuilder::deny_all`
  - `DynamicSceneBuilder::with_resource_filter`
  - `DynamicSceneBuilder::allow_resource`
  - `DynamicSceneBuilder::deny_resource`
  - `DynamicSceneBuilder::allow_all_resources`
  - `DynamicSceneBuilder::deny_all_resources`
- Removed methods:
  - `DynamicSceneBuilder::from_world_with_type_registry`
- `DynamicScene::from_scene` and `DynamicScene::from_world` no longer
require an `AppTypeRegistry` reference

## Migration Guide

- `DynamicScene::from_scene` and `DynamicScene::from_world` no longer
require an `AppTypeRegistry` reference:
  ```rust
  // OLD
  let registry = world.resource::<AppTypeRegistry>();
  let dynamic_scene = DynamicScene::from_world(&world, registry);
  // let dynamic_scene = DynamicScene::from_scene(&scene, registry);
  
  // NEW
  let dynamic_scene = DynamicScene::from_world(&world);
  // let dynamic_scene = DynamicScene::from_scene(&scene);
  ```

- Removed `DynamicSceneBuilder::from_world_with_type_registry`. Now the
registry is automatically taken from the given world:
  ```rust
  // OLD
  let registry = world.resource::<AppTypeRegistry>();
let builder = DynamicSceneBuilder::from_world_with_type_registry(&world,
registry);
  
  // NEW
  let builder = DynamicSceneBuilder::from_world(&world);
  ```
2023-07-06 21:04:26 +00:00
ickshonpe
9655acebb6
Divide by UiScale when converting UI coordinates from physical to logical (#8720)
# Objective

After the UI layout is computed when the coordinates are converted back
from physical coordinates to logical coordinates the `UiScale` is
ignored. This results in a confusing situation where we have two
different systems of logical coordinates.

Example:

```rust
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, update)
        .run();
}

fn setup(mut commands: Commands, mut ui_scale: ResMut<UiScale>) {
    ui_scale.scale = 4.;

    commands.spawn(Camera2dBundle::default());
    commands.spawn(NodeBundle {
        style: Style {
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            width: Val::Percent(100.),
            ..Default::default()
        },
        ..Default::default()
    })
    .with_children(|builder| {
        builder.spawn(NodeBundle {
            style: Style {
                width: Val::Px(100.),
                height: Val::Px(100.),
                ..Default::default()
            },
            background_color: Color::MAROON.into(),
            ..Default::default()
        }).with_children(|builder| {
            builder.spawn(TextBundle::from_section("", TextStyle::default());
        });
    });
}

fn update(
    mut text_query: Query<(&mut Text, &Parent)>,
    node_query: Query<Ref<Node>>,
) {
    for (mut text, parent) in text_query.iter_mut() {
        let node = node_query.get(parent.get()).unwrap();
        if node.is_changed() {
            text.sections[0].value = format!("size: {}", node.size());
        }
    }
}
```
result:

![Bevy App 30_05_2023
16_54_32](https://github.com/bevyengine/bevy/assets/27962798/a5ecbf31-0a12-4669-87df-b0c32f058732)

We asked for a 100x100 UI node but the Node's size is multiplied by the
value of `UiScale` to give a logical size of 400x400.

## Solution

Divide the output physical coordinates by `UiScale` in
`ui_layout_system` and multiply the logical viewport size by `UiScale`
when creating the projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.

---

## Changelog
* The UI layout's physical coordinates are divided by both the window
scale factor and `UiScale` when converting them back to logical
coordinates. The logical size of Ui nodes now matches the values given
to their size constraints.
* Multiply the logical viewport size by `UiScale` before creating the
projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.
* In `ui_focus_system` the cursor position returned from `Window` is
divided by `UiScale`.
* Added a scale factor parameter to `Node::physical_size` and
`Node::physical_rect`.
* The example `viewport_debug` now uses a `UiScale` of 2. to ensure that
viewport coordinates are working correctly with a non-unit `UiScale`.

## Migration Guide

Physical UI coordinates are now divided by both the `UiScale` and the
window's scale factor to compute the logical sizes and positions of UI
nodes.

This ensures that UI Node size and position values, held by the `Node`
and `GlobalTransform` components, conform to the same logical coordinate
system as the style constraints from which they are derived,
irrespective of the current `scale_factor` and `UiScale`.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-07-06 20:27:54 +00:00
Niklas Eicker
b61397e32b
Reduce android example APK size (#8932)
# Objective

The current mobile example produces an APK of 1.5 Gb.
- Running the example on a real device takes significant time (around
one minute just to copy the file over USB to my phone).
- Default virtual devices in Android studio run out of space after the
first install. This can of course be solved/configured, but it causes
unnecessary friction.
- One impression could be, that Bevy produces bloated APKs. 1.5Gb is
even double the size of debug builds for desktop examples.

## Solution

- Strip the debug symbols of the shared libraries before they are copied
to the APK

APK size after this change: 200Mb
Copy time on my machine: ~8s

## Considered alternative

APKs built in release mode are only 50Mb in size, but require setting up
signing for the profile and compile longer.
2023-07-05 23:21:33 +00:00
Anby
7f1d084b71
Rename Interaction::Clicked -> Interaction::Pressed (#8989) (#9027)
# Objective

- Fixes #8989

## Solution

- Renamed Interaction::Clicked -> Interaction::Pressed
- Minor changes to comments to keep clarity of terms

## Migration Guide

- Rename all instances of Interaction::Clicked -> Interaction::Pressed
2023-07-05 09:25:31 +00:00
ickshonpe
a3ab507cd4
many_buttons with bordered buttons (#9004)
# Objective

 Adds a border to each button.
The borders can be disabled with the "no-borders" command line argument.
2023-07-05 01:55:13 +00:00
Nicola Papale
fd32c6f0ec
Simplify setup_scene_once_loaded in animated_fox (#8999)
# Objective

The setup code in `animated_fox` uses a `done` boolean to avoid running
the `play` logic repetitively.

It is a common pattern, but it just work with exactly one fox, and
misses an even more common pattern.

When a user modifies the code to try it with several foxes, they are
confused as to why it doesn't work (#8996).

## Solution

The more common pattern is to use `Added<AnimationPlayer>` as a query
filter.

This both reduces complexity and naturally extend the setup code to
handle several foxes, added at any time.
2023-06-29 20:21:07 +00:00
Gino Valente
aeeb20ec4c
bevy_reflect: FromReflect Ergonomics Implementation (#6056)
# Objective

**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**

---

Resolves #4597

Full details and motivation can be found in the RFC, but here's a brief
summary.

`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).

This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.

It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.

So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.

The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.

## Solution

Automatically derive `FromReflect` when deriving `Reflect`.

Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.

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

#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;

fn test<T: FromReflect>(value: T) {}

test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```

#### `ReflectFromReflect`

This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.

<details>
<summary><h4>Improved Deserialization</h4></summary>

> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.

And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.

`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.

`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.

```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(&registry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;

let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;

// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(&registry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;

let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```

</details>

---

## Changelog

* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**

## Migration Guide

* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.

  ```rust
  // OLD
  #[derive(Reflect, FromReflect)]
  struct Foo;
  
  // NEW
  #[derive(Reflect)]
  struct Foo;
  ```

If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.

  ```rust
  // OLD
  #[derive(Reflect)]
  struct Foo;
  
  impl FromReflect for Foo {/* ... */}
  
  // NEW
  #[derive(Reflect)]
  #[reflect(from_reflect = false)]
  struct Foo;
  
  impl FromReflect for Foo {/* ... */}
  ```

<details>
<summary><h4>Removed Migrations</h4></summary>

> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.

* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).

  ```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(&registry);
  let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
  
  // OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
  
  // NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
  ```

Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:

  ```rust
  // OLD
  let reflect_deserializer = UntypedReflectDeserializer::new(&registry);
  
  // NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(&registry);
  ```

</details>

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-29 01:31:34 +00:00
robtfm
10f5c92068
improve shader import model (#5703)
# Objective

operate on naga IR directly to improve handling of shader modules.
- give codespan reporting into imported modules
- allow glsl to be used from wgsl and vice-versa

the ultimate objective is to make it possible to 
- provide user hooks for core shader functions (to modify light
behaviour within the standard pbr pipeline, for example)
- make automatic binding slot allocation possible

but ... since this is already big, adds some value and (i think) is at
feature parity with the existing code, i wanted to push this now.

## Solution

i made a crate called naga_oil (https://github.com/robtfm/naga_oil -
unpublished for now, could be part of bevy) which manages modules by
- building each module independantly to naga IR
- creating "header" files for each supported language, which are used to
build dependent modules/shaders
- make final shaders by combining the shader IR with the IR for imported
modules

then integrated this into bevy, replacing some of the existing shader
processing stuff. also reworked examples to reflect this.

## Migration Guide

shaders that don't use `#import` directives should work without changes.

the most notable user-facing difference is that imported
functions/variables/etc need to be qualified at point of use, and
there's no "leakage" of visible stuff into your shader scope from the
imports of your imports, so if you used things imported by your imports,
you now need to import them directly and qualify them.

the current strategy of including/'spreading' `mesh_vertex_output`
directly into a struct doesn't work any more, so these need to be
modified as per the examples (e.g. color_material.wgsl, or many others).
mesh data is assumed to be in bindgroup 2 by default, if mesh data is
bound into bindgroup 1 instead then the shader def `MESH_BINDGROUP_1`
needs to be added to the pipeline shader_defs.
2023-06-27 00:29:22 +00:00
François
8fa94a0a0d
blend_modes example: fix label position (#8454)
# Objective

- Labels are not correctly placed
<img width="1392" alt="Screenshot 2023-04-22 at 00 12 54"
src="https://user-images.githubusercontent.com/8672791/233742996-0189b3c2-ea6b-4f3f-b2e8-68fdbf74f52f.png">

## Solution

- Set a width in the UI so that text doesn't try to wrap
<img width="1392" alt="Screenshot 2023-04-22 at 00 13 04"
src="https://user-images.githubusercontent.com/8672791/233743064-8d6045e5-3936-4c22-be07-ac618399c093.png">
2023-06-26 18:46:11 +00:00
ickshonpe
aeea4b0344
NoWrap Text feature (#8947)
# Objective

In Bevy 10.1 and before, the only way to enable text wrapping was to set
a local `Val::Px` width constraint on the text node itself.
`Val::Percent` constraints and constraints on the text node's ancestors
did nothing.

#7779 fixed those problems. But perversely displaying unwrapped text is
really difficult now, and requires users to nest each `TextBundle` in a
`NodeBundle` and apply `min_width` and `max_width` constraints. Some
constructions may even need more than one layer of nesting. I've seen
several people already who have really struggled with this when porting
their projects to main in advance of 0.11.

## Solution

Add a `NoWrap` variant to the `BreakLineOn` enum.
If `NoWrap` is set, ignore any constraints on the width for the text and
call `TextPipeline::queue_text` with a width bound of `f32::INFINITY`.



---

## Changelog
* Added a `NoWrap` variant to the `BreakLineOn` enum.
* If `NoWrap` is set, any constraints on the width for the text are
ignored and `TextPipeline::queue_text` is called with a width bound of
`f32::INFINITY`.
* Changed the `size` field of `FixedMeasure` to `pub`. This shouldn't
have been private, it was always intended to have `pub` visibility.
* Added a `with_no_wrap` method to `TextBundle`.

## Migration Guide

`bevy_text::text::BreakLineOn` has a new variant `NoWrap` that disables
text wrapping for the `Text`.
Text wrapping can also be disabled using the `with_no_wrap` method of
`TextBundle`.
2023-06-26 16:23:00 +00:00
Thierry Berger
469a19c290
fix example grid (#8940)
`Style` flattened `size`, `min_size` and `max_size` to its root struct,
causing compilation errors.

I uncommented the code to avoid further silent error not caught by CI,
but hid the view to keep the same behaviour.
2023-06-23 21:28:11 +00:00
Adam Kobzan
75c6641b41
Add example to demonstrate manual generation and UV mapping of 3D mesh (generate_custom_mesh) solve #4922 (#8909)
# Objective

- Fixes #4922

## Solution

- Add an example that maps a custom texture on a 3D mesh.

---

## Changelog

> Added the texture itself (confirmed with mod on discord before it
should be ok) to the assets folder, added to the README and Cargo.toml.

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Sélène Amanita <134181069+Selene-Amanita@users.noreply.github.com>
2023-06-23 19:26:37 +00:00
Nicola Papale
c6170d48f9
Add morph targets (#8158)
# Objective

- Add morph targets to `bevy_pbr` (closes #5756) & load them from glTF
- Supersedes #3722
- Fixes #6814

[Morph targets][1] (also known as shape interpolation, shape keys, or
blend shapes) allow animating individual vertices with fine grained
controls. This is typically used for facial expressions. By specifying
multiple poses as vertex offset, and providing a set of weight of each
pose, it is possible to define surprisingly realistic transitions
between poses. Blending between multiple poses also allow composition.
Morph targets are part of the [gltf standard][2] and are a feature of
Unity and Unreal, and babylone.js, it is only natural to implement them
in bevy.

## Solution

This implementation of morph targets uses a 3d texture where each pixel
is a component of an animated attribute. Each layer is a different
target. We use a 2d texture for each target, because the number of
attribute×components×animated vertices is expected to always exceed the
maximum pixel row size limit of webGL2. It copies fairly closely the way
skinning is implemented on the CPU side, while on the GPU side, the
shader morph target implementation is a relatively trivial detail.

We add an optional `morph_texture` to the `Mesh` struct. The
`morph_texture` is built through a method that accepts an iterator over
attribute buffers.

The `MorphWeights` component, user-accessible, controls the blend of
poses used by mesh instances (so that multiple copy of the same mesh may
have different weights), all the weights are uploaded to a uniform
buffer of 256 `f32`. We limit to 16 poses per mesh, and a total of 256
poses.

More literature:
* Old babylone.js implementation (vertex attribute-based):
https://www.eternalcoding.com/dev-log-1-morph-targets/
* Babylone.js implementation (similar to ours):
https://www.youtube.com/watch?v=LBPRmGgU0PE
* GPU gems 3:
https://developer.nvidia.com/gpugems/gpugems3/part-i-geometry/chapter-3-directx-10-blend-shapes-breaking-limits
* Development discord thread
https://discord.com/channels/691052431525675048/1083325980615114772


https://user-images.githubusercontent.com/26321040/231181046-3bca2ab2-d4d9-472e-8098-639f1871ce2e.mp4


https://github.com/bevyengine/bevy/assets/26321040/d2a0c544-0ef8-45cf-9f99-8c3792f5a258

## Acknowledgements

* Thanks to `storytold` for sponsoring the feature
* Thanks to `superdump` and `james7132` for guidance and help figuring
out stuff

## Future work

- Handling of less and more attributes (eg: animated uv, animated
arbitrary attributes)
- Dynamic pose allocation (so that zero-weighted poses aren't uploaded
to GPU for example, enables much more total poses)
- Better animation API, see #8357

----

## Changelog

- Add morph targets to bevy meshes
- Support up to 64 poses per mesh of individually up to 116508 vertices,
animation currently strictly limited to the position, normal and tangent
attributes.
	- Load a morph target using `Mesh::set_morph_targets` 
- Add `VisitMorphTargets` and `VisitMorphAttributes` traits to
`bevy_render`, this allows defining morph targets (a fairly complex and
nested data structure) through iterators (ie: single copy instead of
passing around buffers), see documentation of those traits for details
- Add `MorphWeights` component exported by `bevy_render`
- `MorphWeights` control mesh's morph target weights, blending between
various poses defined as morph targets.
- `MorphWeights` are directly inherited by direct children (single level
of hierarchy) of an entity. This allows controlling several mesh
primitives through a unique entity _as per GLTF spec_.
- Add `MorphTargetNames` component, naming each indices of loaded morph
targets.
- Load morph targets weights and buffers in `bevy_gltf` 
- handle morph targets animations in `bevy_animation` (previously, it
was a `warn!` log)
- Add the `MorphStressTest.gltf` asset for morph targets testing, taken
from the glTF samples repo, CC0.
- Add morph target manipulation to `scene_viewer`
- Separate the animation code in `scene_viewer` from the rest of the
code, reducing `#[cfg(feature)]` noise
- Add the `morph_targets.rs` example to show off how to manipulate morph
targets, loading `MorpStressTest.gltf`

## Migration Guide

- (very specialized, unlikely to be touched by 3rd parties)
- `MeshPipeline` now has a single `mesh_layouts` field rather than
separate `mesh_layout` and `skinned_mesh_layout` fields. You should
handle all possible mesh bind group layouts in your implementation
- You should also handle properly the new `MORPH_TARGETS` shader def and
mesh pipeline key. A new function is exposed to make this easier:
`setup_moprh_and_skinning_defs`
- The `MeshBindGroup` is now `MeshBindGroups`, cached bind groups are
now accessed through the `get` method.

[1]: https://en.wikipedia.org/wiki/Morph_target_animation
[2]:
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#morph-targets

---------

Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-22 20:00:01 +00:00
Edgar Geier
f18f28874a
Allow tuples and single plugins in add_plugins, deprecate add_plugin (#8097)
# Objective

- Better consistency with `add_systems`.
- Deprecating `add_plugin` in favor of a more powerful `add_plugins`.
- Allow passing `Plugin` to `add_plugins`.
- Allow passing tuples to `add_plugins`.

## Solution

- `App::add_plugins` now takes an `impl Plugins` parameter.
- `App::add_plugin` is deprecated.
- `Plugins` is a new sealed trait that is only implemented for `Plugin`,
`PluginGroup` and tuples over `Plugins`.
- All examples, benchmarks and tests are changed to use `add_plugins`,
using tuples where appropriate.

---

## Changelog

### Changed

- `App::add_plugins` now accepts all types that implement `Plugins`,
which is implemented for:
  - Types that implement `Plugin`.
  - Types that implement `PluginGroup`.
  - Tuples (up to 16 elements) over types that implement `Plugins`.
- Deprecated `App::add_plugin` in favor of `App::add_plugins`.

## Migration Guide

- Replace `app.add_plugin(plugin)` calls with `app.add_plugins(plugin)`.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-21 20:51:03 +00:00
ickshonpe
50c50cdcb6
UI Display and Visibility Example (#7629)
# Objective

An example demonstrating how Display and Visibility work in Bevy UI.

fixes #5380
related #5368

![Bevy App 15_02_2023
20_40_46](https://user-images.githubusercontent.com/27962798/219150865-419ade53-250b-4030-8197-907cac7aa5da.png)

## Changelog

* Added the example `flex_display.rs`.
2023-06-19 23:19:34 +00:00
Duncan
64405469a5
Expand FallbackImage to include a GpuImage for each possible TextureViewDimension (#6974)
# Objective

Fixes #6920 

## Solution

From the issue discussion:

> From looking at the `AsBindGroup` derive macro implementation, the
fallback image's `TextureView` is used when the binding's
`Option<Handle<Image>>` is `None`. Because this relies on already having
a view that matches the desired binding dimensions, I think the solution
will require creating a separate `GpuImage` for each possible
`TextureViewDimension`.

---

## Changelog

Users can now rely on `FallbackImage` to work with a texture binding of
any dimension.
2023-06-19 22:56:25 +00:00
mwbryant
8b5bf42c28
UI texture atlas support (#8822)
# Objective

This adds support for using texture atlas sprites in UI. From
discussions today in the ui-dev discord it seems this is a much wanted
feature.

This was previously attempted in #5070 by @ManevilleF however that was
blocked #5103. This work can be easily modified to support #5103 changes
after that merges.

## Solution

I created a new UI bundle that reuses the existing texture atlas
infrastructure. I create a new atlas image component to prevent it from
being drawn by the existing non-UI systems and to remove unused
parameters.

In extract I added new system to calculate the required values for the
texture atlas image, this extracts into the same resource as the
existing UI Image and Text components.

This should have minimal performance impact because if texture atlas is
not present then the exact same code path is followed. Also there should
be no unintended behavior changes because without the new components the
existing systems write the extract same resulting data.

I also added an example showing the sprite working and a system to
advance the animation on space bar presses.

Naming is hard and I would accept any feedback on the bundle name! 

---

## Changelog

>  Added TextureAtlasImageBundle

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
2023-06-19 21:52:02 +00:00
JMS55
3959908b6b
Small doc fix (#8889) 2023-06-19 03:58:21 +00:00
JMS55
af9c945f40
Screen Space Ambient Occlusion (SSAO) MVP (#7402)
![image](https://github.com/bevyengine/bevy/assets/47158642/dbb62645-f639-4f2b-b84b-26fd915c186d)

# Objective

- Add Screen space ambient occlusion (SSAO). SSAO approximates
small-scale, local occlusion of _indirect_ diffuse light between
objects. SSAO does not apply to direct lighting, such as point or
directional lights.
- This darkens creases, e.g. on staircases, and gives nice contact
shadows where objects meet, giving entities a more "grounded" feel.
- Closes https://github.com/bevyengine/bevy/issues/3632.

## Solution

- Implement the GTAO algorithm.
-
https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf
-
https://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
- Source code heavily based on [Intel's
XeGTAO](0d177ce06b/Source/Rendering/Shaders/XeGTAO.hlsli).
- Add an SSAO bevy example.

## Algorithm Overview
* Run a depth and normal prepass
* Create downscaled mips of the depth texture (preprocess_depths pass)
* GTAO pass - for each pixel, take several random samples from the
depth+normal buffers, reconstruct world position, raytrace in screen
space to estimate occlusion. Rather then doing completely random samples
on a hemisphere, you choose random _slices_ of the hemisphere, and then
can analytically compute the full occlusion of that slice. Also compute
edges based on depth differences here.
* Spatial denoise pass - bilateral blur, using edge detection to not
blur over edges. This is the final SSAO result.
* Main pass - if SSAO exists, sample the SSAO texture, and set occlusion
to be the minimum of ssao/material occlusion. This then feeds into the
rest of the PBR shader as normal.

---

## Future Improvements
- Maybe remove the low quality preset for now (too noisy)
- WebGPU fallback (see below)
- Faster depth->world position (see reverted code)
- Bent normals 
- Try interleaved gradient noise or spatiotemporal blue noise
- Replace the spatial denoiser with a combined spatial+temporal denoiser
- Render at half resolution and use a bilateral upsample
- Better multibounce approximation
(https://drive.google.com/file/d/1SyagcEVplIm2KkRD3WQYSO9O0Iyi1hfy/view)

## Far-Future Performance Improvements
- F16 math (missing naga-wgsl support
https://github.com/gfx-rs/naga/issues/1884)
- Faster coordinate space conversion for normals
- Faster depth mipchain creation
(https://github.com/GPUOpen-Effects/FidelityFX-SPD) (wgpu/naga does not
currently support subgroup ops)
- Deinterleaved SSAO for better cache efficiency
(https://developer.nvidia.com/sites/default/files/akamai/gameworks/samples/DeinterleavedTexturing.pdf)

## Other Interesting Papers
- Visibility bitmask
(https://link.springer.com/article/10.1007/s00371-022-02703-y,
https://cdrinmatane.github.io/posts/cgspotlight-slides/)
- Screen space diffuse lighting
(https://github.com/Patapom/GodComplex/blob/master/Tests/TestHBIL/2018%20Mayaux%20-%20Horizon-Based%20Indirect%20Lighting%20(HBIL).pdf)

## Platform Support
* SSAO currently does not work on DirectX12 due to issues with wgpu and
naga:
  * https://github.com/gfx-rs/wgpu/pull/3798
  * https://github.com/gfx-rs/naga/pull/2353
* SSAO currently does not work on WebGPU because r16float is not a valid
storage texture format
https://gpuweb.github.io/gpuweb/wgsl/#storage-texel-formats. We can fix
this with a fallback to r32float.

---

## Changelog

- Added ScreenSpaceAmbientOcclusionSettings,
ScreenSpaceAmbientOcclusionQualityLevel, and
ScreenSpaceAmbientOcclusionBundle

---------

Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: Daniel Chia <danstryder@gmail.com>
Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
Co-authored-by: Brandon Dyer <brandondyer64@gmail.com>
Co-authored-by: Edgar Geier <geieredgar@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-18 21:05:55 +00:00
Jim Eckerlein
13f50c7a53
Rename keys like LAlt to AltLeft (#8792)
# Objective

The
[`KeyCode`](https://github.com/bevyengine/bevy/blob/main/crates/bevy_input/src/keyboard.rs#L86)
enum cases `LWin` and `RWin` are too opinionated because they are also
assigned meaning by non-Windows operating systems. macOS calls the keys
completely different.

## Solution

Match [winits
approach](https://github.com/rust-windowing/winit/blob/master/src/keyboard.rs#L1635)
naming convention.

---

## Migration Guide

Migrate by replacing:
- `LAlt` → `AltLeft`
- `RAlt` → `AltRight`
- `LBracket` → `BracketLeft`
- `RBracket` → `BracketRight`
- `LControl` → `ControlLeft`
- `RControl` → `ControlRight`
- `LShift` → `ShiftLeft`
- `RShift` → `ShiftRight`
- `LWin` → `SuperLeft`
- `RWin` → `SuperRight`
2023-06-15 01:37:04 +00:00
ickshonpe
f7aa83a247
Ui Node Borders (#7795)
# Objective

Implement borders for UI nodes.

Relevant discussion: #7785
Related: #5924, #3991

<img width="283" alt="borders"
src="https://user-images.githubusercontent.com/27962798/220968899-7661d5ec-6f5b-4b0f-af29-bf9af02259b5.PNG">

## Solution

Add an extraction function to draw the borders.

---

Can only do one colour rectangular borders due to the limitations of the
Bevy UI renderer.

Maybe it can be combined with #3991 eventually to add curved border
support.

## Changelog
* Added a component `BorderColor`.
* Added the `extract_uinode_borders` system to the UI Render App.
* Added the UI example `borders`

---------

Co-authored-by: Nico Burns <nico@nicoburns.com>
2023-06-14 22:43:38 +00:00
ira
001b3eb97c
Instanced line rendering for gizmos based on bevy_polyline (#8427)
# Objective

Adopt code from
[bevy_polyline](https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline)
for gizmo line-rendering.
This adds configurable width and perspective rendering for the lines.

Many thanks to @mtsr for the initial work on bevy_polyline. Thanks to
@aevyrie for maintaining it, @nicopap for adding the depth_bias feature
and the other
[contributors](https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline/graphs/contributors)
for squashing bugs and keeping bevy_polyline up-to-date.

#### Before

![Before](https://user-images.githubusercontent.com/29694403/232831591-a8e6ed0c-3a09-4413-80fa-74cb8e0d33dd.png)
#### After - with line perspective

![After](https://user-images.githubusercontent.com/29694403/232831692-ba7cbeb7-e63a-4f8e-9b1b-1b80c668f149.png)

Line perspective is not on by default because with perspective there is
no default line width that works for every scene.

<details><summary>After - without line perspective</summary>
<p>

![After - no
perspective](https://user-images.githubusercontent.com/29694403/232836344-0dbfb4c8-09b7-4cf5-95f9-a4c26f38dca3.png)

</p>
</details>

Somewhat unexpectedly, the performance is improved with this PR.
At 200,000 lines in many_gizmos I get ~110 FPS on main and ~200 FPS with
this PR.
I'm guessing this is a CPU side difference as I would expect the
rendering technique to be more expensive on the GPU to some extent, but
I am not entirely sure.

---------

Co-authored-by: Jonas Matser <github@jonasmatser.nl>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-06-13 06:49:47 +00:00
ickshonpe
6fc619d34a
Fix the logo image in the "ui" UI example (#7894)
# Objective

The AccessKit PR removed the loading of the image logo from the UI
example.
It also added some alt text with `TextStyle::default()` as a child of
the logo image node.

If you give an image node a child, then its size is no longer determined
by the measurefunc that preserves its aspect ratio. Instead, its width
and height are determined by the constraints set on the node and the
size of the contents of the node. In this case, the image node is set to
have a width of 500 with no constraints on its height. So it looks at
its child node to determine what height it should take. Because the
child has `TextStyle::default` it allocates no space for the text, the
height of the image node is set to zero and the logo isn't drawn.

Fixes #8805

## Solution

Load the image, and set min_size and max_size constraints of 500 by 125
pixels.
2023-06-12 19:01:12 +00:00
Jim Eckerlein
008030357b
Touchpad magnify and rotate events (#8791)
# Objective

The goal of this PR is to receive touchpad magnification and rotation
events.

## Solution

Implement pendants for winit's `TouchpadMagnify` and `TouchpadRotate`
events.

Adjust the `mouse_input_events.rs` example to debug magnify and rotate
events.

Since winit only reports these events on macOS, the Bevy events for
touchpad magnification and rotation are currently only fired on macOS.
2023-06-08 20:31:43 +00:00
CatThingy
89cbc78d3d
Require #[derive(Event)] on all Events (#7086)
# Objective

Be consistent with `Resource`s and `Components` and have `Event` types
be more self-documenting.
Although not susceptible to accidentally using a function instead of a
value due to `Event`s only being initialized by their type, much of the
same reasoning for removing the blanket impl on `Resource` also applies
here.

* Not immediately obvious if a type is intended to be an event
* Prevent invisible conflicts if the same third-party or primitive types
are used as events
* Allows for further extensions (e.g. opt-in warning for missed events)

## Solution

Remove the blanket impl for the `Event` trait. Add a derive macro for
it.

---

## Changelog

- `Event` is no longer implemented for all applicable types. Add the
`#[derive(Event)]` macro for events.

## Migration Guide

* Add the `#[derive(Event)]` macro for events. Third-party types used as
events should be wrapped in a newtype.
2023-06-06 14:44:32 +00:00
张林伟
b72b15465d
Support to set window theme and expose system window theme changed event (#8593)
# Objective

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

## Solution

- Add `preferred_theme` field to `Window` and set it when window
creation
- Add `window_theme` field to `InternalWindowState` to store current
window theme
- Expose winit `WindowThemeChanged` event

---------

Co-authored-by: hate <15314665+hate@users.noreply.github.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-06-05 21:04:22 +00:00
Michael Johnson
3507b21dce
Allow systems using Diagnostics to run in parallel (#8677)
# Objective

I was trying to add some `Diagnostics` to have a better break down of
performance but I noticed that the current implementation uses a
`ResMut` which forces the functions to all run sequentially whereas
before they could run in parallel. This created too great a performance
penalty to be usable.

## Solution

This PR reworks how the diagnostics work with a couple of breaking
changes. The idea is to change how `Diagnostics` works by changing it to
a `SystemParam`. This allows us to hold a `Deferred` buffer of
measurements that can be applied later, avoiding the need for multiple
mutable references to the hashmap. This means we can run systems that
write diagnostic measurements in parallel.

Firstly, we rename the old `Diagnostics` to `DiagnosticsStore`. This
clears up the original name for the new interface while allowing us to
preserve more closely the original API.

Then we create a new `Diagnostics` struct which implements `SystemParam`
and contains a deferred `SystemBuffer`. This can be used very similar to
the old `Diagnostics` for writing new measurements.

```rust
fn system(diagnostics: ResMut<Diagnostics>) { diagnostics.new_measurement(ID, || 10.0)}
// changes to
fn system(mut diagnostics: Diagnostics) { diagnostics.new_measurement(ID, || 10.0)}
``` 
For reading the diagnostics, the user needs to change from `Diagnostics`
to `DiagnosticsStore` but otherwise the function calls are the same.

Finally, we add a new method to the `App` for registering diagnostics.
This replaces the old method of creating a startup system and adding it
manually.

Testing it, this PR does indeed allow Diagnostic systems to be run in
parallel.

## Changelog

- Change `Diagnostics` to implement `SystemParam` which allows
diagnostic systems to run in parallel.

## Migration Guide

- Register `Diagnostic`'s using the new
`app.register_diagnostic(Diagnostic::new(DIAGNOSTIC_ID,
"diagnostic_name", 10));`
- In systems for writing new measurements, change `mut diagnostics:
ResMut<Diagnostics>` to `mut diagnostics: Diagnostics` to allow the
systems to run in parallel.
- In systems for reading measurements, change `diagnostics:
Res<Diagnostics>` to `diagnostics: Res<DiagnosticsStore>`.
2023-06-05 20:51:22 +00:00
radiish
1efc762924
reflect: stable type path v2 (#7184)
# Objective

- Introduce a stable alternative to
[`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html).
- Rewrite of #5805 with heavy inspiration in design.
- On the path to #5830.
- Part of solving #3327.


## Solution

- Add a `TypePath` trait for static stable type path/name information.
- Add a `TypePath` derive macro.
- Add a `impl_type_path` macro for implementing internal and foreign
types in `bevy_reflect`.

---

## Changelog

- Added `TypePath` trait.
- Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`.
- Added a `TypePath` derive macro.
- Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on
internal and foreign types in `bevy_reflect`.
- Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to
`(Non)GenericTypedCell<T>` which allows us to be generic over both
`TypeInfo` and `TypePath`.
- `TypePath` is now a supertrait of `Asset`, `Material` and
`Material2d`.
- `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be
specified.
- `impl_reflect_value` needs to either specify path starting with a
double colon (`::core::option::Option`) or an `in my_crate::foo`
declaration.
- Added `bevy_reflect_derive::ReflectTypePath`.
- Most uses of `Ident` in `bevy_reflect_derive` changed to use
`ReflectTypePath`.

## Migration Guide

- Implementors of `Asset`, `Material` and `Material2d` now also need to
derive `TypePath`.
- Manual implementors of `Reflect` will need to implement the new
`get_type_path` method.

## Open Questions
- [x] ~This PR currently does not migrate any usages of
`std::any::type_name` to use `bevy_reflect::TypePath` to ease the review
process. Should it?~ Migration will be left to a follow-up PR.
- [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to
satisfy new bounds, mostly when deriving `TypeUuid`. Should we make
`TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in
favour of
`TypePath`?](2afbd85532 (r961067892))
2023-06-05 20:31:20 +00:00
Alice Cecile
cbd4abf0fc
Rename apply_system_buffers to apply_deferred (#8726)
# Objective

- `apply_system_buffers` is an unhelpful name: it introduces a new
internal-only concept
- this is particularly rough for beginners as reasoning about how
commands work is a critical stumbling block

## Solution

- rename `apply_system_buffers` to the more descriptive `apply_deferred`
- rename related fields, arguments and methods in the internals fo
bevy_ecs for consistency
- update the docs


## Changelog

`apply_system_buffers` has been renamed to `apply_deferred`, to more
clearly communicate its intent and relation to `Deferred` system
parameters like `Commands`.

## Migration Guide

- `apply_system_buffers` has been renamed to `apply_deferred`
- the `apply_system_buffers` method on the `System` trait has been
renamed to `apply_deferred`
- the `is_apply_system_buffers` function has been replaced by
`is_apply_deferred`
- `Executor::set_apply_final_buffers` is now
`Executor::set_apply_final_deferred`
- `Schedule::apply_system_buffers` is now `Schedule::apply_deferred`

---------

Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
2023-06-02 14:04:13 +00:00
lelo
4ce37395da
Add or_else combinator to run_conditions.rs (#8714)
# Objective

- Showcase the use of `or_else()` as requested. Fixes
https://github.com/bevyengine/bevy/issues/8702

## Solution

- Add an uninitialized resource `Unused`
- Use `or_else()` to evaluate a second run condition
- Add documentation explaining how `or_else()` works
2023-05-31 16:52:36 +00:00
François
27e1cf92ad
shader_prepass example: disable MSAA for maximum compatibility (#8504)
# Objective


Since #8446, example `shader_prepass` logs the following error on my mac
m1:
```
ERROR bevy_render::render_resource::pipeline_cache: failed to process shader:
error: Entry point fragment at Fragment is invalid
 = Argument 1 varying error
 = Capability MULTISAMPLED_SHADING is not supported
```
The example display the 3d scene but doesn't change with the preps
selected

Maybe related to this update in naga:
cc3a8ac737

## Solution

- Disable MSAA in the example, and check if it's enabled in the shader
2023-05-29 15:25:32 +00:00
Jakob Hellermann
1ff4b98755
fix new clippy lints before they reach stable (#8700)
# Objective

- fix clippy lints early to make sure CI doesn't break when they get
promoted to stable
- have a noise-free `clippy` experience for nightly users

## Solution

- `cargo clippy --fix`
- replace `filter_map(|x| x.ok())` with `map_while(|x| x.ok())` to fix
potential infinite loop in case of IO error
2023-05-29 07:23:50 +00:00
Martin Lysell
48b3118fdd
Change present mode on many_buttons and many_glyphs from Immediate to AutoNoVsync (#8681)
# Objective

Fix the examples many_buttons and many_glyphs not working on the WebGPU
examples page. Currently they both fail with the follow error:

```
panicked at 'Only FIFO/Auto* is supported on web', ..../wgpu-0.16.0/src/backend/web.rs:1162:13
```

## Solution

Change `present_mode` from `PresentMode::Immediate` to
`PresentMode::AutoNoVsync`. AutoNoVsync seems to be common mode used by
other examples of this kind.
2023-05-25 22:45:57 +00:00
François
ebac7e8268
update ahash and hashbrown (#8623)
# Objective

- Update `ahash` and `hashbrown`
- Alternative to #5700 and #7420

## Solution

- Update the dependencies

This is a breaking change because we were creating two fixed hashers
with
[`AHasher::new_with_keys`](https://docs.rs/ahash/0.7.6/ahash/struct.AHasher.html#method.new_with_keys),
which was a method that existed only for testing purpose and has been
removed from public.

I replaced it with
[`RandomState::with_seeds`](https://docs.rs/ahash/0.8.3/ahash/random_state/struct.RandomState.html#method.with_seeds)
which is the proper way to get a fixed hasher (see [this
table](https://docs.rs/ahash/0.8.3/ahash/random_state/struct.RandomState.html)).
This means that hashes won't be the same across versions

---

## Migration Guide

- If you were using hashes to an asset or using one of the fixed hasher
exposed by Bevy with a previous version, you will have to update the
hashes
2023-05-23 02:17:07 +00:00
JMS55
c399755c74
Remove outdated example code/comment (#8635) 2023-05-19 18:21:26 +00:00
François
25f013ba1b
audio and browsers section for wasm examples (#8625)
# Objective

- Help users better understand audio issues in wasm

## Solution

- Describe some of the known issues, and some of the workarounds
2023-05-17 23:54:35 +00:00
François
e0b18091b5
fix missed examples in WebGPU update (#8553)
# Objective

- I missed a few examples in #8336 
- fixes #8556 
- fixes #8620

## Solution

- Update them
2023-05-16 20:31:30 +00:00
Nico Burns
08bf1a6c2e
Flatten UI Style properties that use Size + remove Size (#8548)
# Objective

- Simplify API and make authoring styles easier

See:
https://github.com/bevyengine/bevy/issues/8540#issuecomment-1536177102

## Solution

- The `size`, `min_size`, `max_size`, and `gap` properties have been
replaced by `width`, `height`, `min_width`, `min_height`, `max_width`,
`max_height`, `row_gap`, and `column_gap` properties

---

## Changelog

- Flattened `Style` properties that have a `Size` value directly into
`Style`

## Migration Guide

- The `size`, `min_size`, `max_size`, and `gap` properties have been
replaced by the `width`, `height`, `min_width`, `min_height`,
`max_width`, `max_height`, `row_gap`, and `column_gap` properties. Use
the new properties instead.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
2023-05-16 01:36:32 +00:00
JMS55
17f045e2a0
Delay asset hot reloading (#8503)
# Objective

- Fix #5631 

## Solution

- Wait 50ms (configurable) after the last modification event before
reloading an asset.

---

## Changelog

- `AssetPlugin::watch_for_changes` is now a `ChangeWatcher` instead of a
`bool`
- Fixed https://github.com/bevyengine/bevy/issues/5631

## Migration Guide
- Replace `AssetPlugin::watch_for_changes: true` with e.g.
`ChangeWatcher::with_delay(Duration::from_millis(200))`

---------

Co-authored-by: François <mockersf@gmail.com>
2023-05-16 01:26:11 +00:00
Nicola Papale
3d75210564
Remove mod.rs in scene_viewer (#8582)
# Objective

- Cleanup file tree

## Solution

A mysterious mod.rs lies in the scene_viewer directory. It seems
completely useless, everything ignores it and it doesn't affect
anything.

We cruelly remove it, making the world a less whimsical place. A
dystopian drive for pure and complete order compels us to eliminate all
that is useless, for clarity and to prevent the wonder and beauty of
confusion.
2023-05-13 00:30:33 +00:00
SpecificProtagonist
86aaad743b
Merge ScheduleRunnerSettings into ScheduleRunnerPlugin (#8585)
# Objective

`ScheduleRunnerPlugin` was still configured via a resource, meaning
users would be able to change the settings while the app is running, but
the changes wouldn't have an effect.

## Solution

Configure plugin directly

---

## Changelog

- Changed: merged `ScheduleRunnerSettings` into `ScheduleRunnerPlugin` 

## Migration Guide

- instead of inserting the `ScheduleRunnerSettings` resource, configure
the `ScheduleRunnerPlugin`
2023-05-10 16:46:21 +00:00
lelo
b4218a4443
Re-introduce comments about frustum culling (#8579)
# Objective

Frustum culling for 2D components has been enabled since #7885,
Fixes #8490 

## Solution

Re-introduced the comments about frustum culling in the
many_animated_sprites.rs and many_sprites.rs examples.

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
2023-05-09 16:19:42 +00:00
François
71842c5ac9
Webgpu support (#8336)
# Objective

- Support WebGPU
- alternative to #5027 that doesn't need any async / await
- fixes #8315 
- Surprise fix #7318

## Solution

### For async renderer initialisation 

- Update the plugin lifecycle:
  - app builds the plugin
    - calls `plugin.build`
    - registers the plugin
  - app starts the event loop
- event loop waits for `ready` of all registered plugins in the same
order
    - returns `true` by default
- then call all `finish` then all `cleanup` in the same order as
registered
  - then execute the schedule

In the case of the renderer, to avoid anything async:
- building the renderer plugin creates a detached task that will send
back the initialised renderer through a mutex in a resource
- `ready` will wait for the renderer to be present in the resource
- `finish` will take that renderer and place it in the expected
resources by other plugins
- other plugins (that expect the renderer to be available) `finish` are
called and they are able to set up their pipelines
- `cleanup` is called, only custom one is still for pipeline rendering

### For WebGPU support

- update the `build-wasm-example` script to support passing `--api
webgpu` that will build the example with WebGPU support
- feature for webgl2 was always enabled when building for wasm. it's now
in the default feature list and enabled on all platforms, so check for
this feature must also check that the target_arch is `wasm32`

---

## Migration Guide

- `Plugin::setup` has been renamed `Plugin::cleanup`
- `Plugin::finish` has been added, and plugins adding pipelines should
do it in this function instead of `Plugin::build`
```rust
// Before
impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        app.insert_resource::<MyResource>
            .add_systems(Update, my_system);

        let render_app = match app.get_sub_app_mut(RenderApp) {
            Ok(render_app) => render_app,
            Err(_) => return,
        };

        render_app
            .init_resource::<RenderResourceNeedingDevice>()
            .init_resource::<OtherRenderResource>();
    }
}

// After
impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        app.insert_resource::<MyResource>
            .add_systems(Update, my_system);
    
        let render_app = match app.get_sub_app_mut(RenderApp) {
            Ok(render_app) => render_app,
            Err(_) => return,
        };
    
        render_app
            .init_resource::<OtherRenderResource>();
    }

    fn finish(&self, app: &mut App) {
        let render_app = match app.get_sub_app_mut(RenderApp) {
            Ok(render_app) => render_app,
            Err(_) => return,
        };
    
        render_app
            .init_resource::<RenderResourceNeedingDevice>();
    }
}
```
2023-05-04 22:07:57 +00:00
François
cb286e5b60
Screenshots in wasm (#8455)
# Objective

- Enable taking a screenshot in wasm
- Followup on #7163 

## Solution

- Create a blob from the image data, generate a url to that blob, add an
`a` element to the document linking to that url, click on that element,
then revoke the url
- This will automatically trigger a download of the screenshot file in
the browser
2023-04-28 19:37:11 +00:00
Ame
670f3f0dce
Fix panic in example: text_wrap_debug.rs (#8497)
# Objective

- Fix panic caused by incorrectly placed background color

## Solution

- Move `BackgroundColor` inside `TextBundle`
2023-04-26 22:17:19 +00:00
ickshonpe
323705e0ca
many_glyphs recompute-text option (#8499)
# Objective

Add a commandline argument to the `many_glyphs` that forces the
recomputation of all the text every frame.
2023-04-26 21:05:01 +00:00
François
8ec4b99a69
standardize instructions in examples (#8478)
# Objective

- Standardize on screen instructions in examples:
  - top left, bottom left when better
  - white, black when better
  - same margin (12px) and font size (20)

## Solution

- Started with a few examples, let's reach consensus then document and
open issues for the rest
2023-04-26 19:52:31 +00:00
Johan Klokkhammer Helsing
a1e442cd2a
Add gamepad rumble support to bevy_input (#8398)
# 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>
2023-04-24 15:28:53 +00:00
ira
b5d24d8fb2
Add a bounding box gizmo (#8468)
# 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.
2023-04-24 15:23:06 +00:00
François
7f78e063af
stress test examples: add missing warns (#8475)
# Objective

- Some stress test examples don't have the warning about performances

## Solution

- Add it
2023-04-24 14:35:03 +00:00
ickshonpe
f3360938eb
Size Constraints Example (#7956)
# Objective

Add a simple example demonstrating how to use size constraints.

Related to #7946

# Solution

<img width="827" alt="Capture"
src="https://user-images.githubusercontent.com/27962798/223741566-4b8eca99-c450-42b5-a40e-a414858c8310.PNG">

# Changelog
* Added the example `size_constraints`
2023-04-24 14:28:00 +00:00
ickshonpe
bb37ae4ab3
UI text wrapping and LineBreakOn example (#7761)
# Objective

An example demonstrating more text layout options, text wrapping and
`LineBreakOn`.

<img width="961" alt="text_wrap"
src="https://user-images.githubusercontent.com/27962798/220125391-48163d28-51d9-4df5-b34a-f95ca3661b7d.PNG">

Won't look exactly like this on main because of the remaining bugs in
text.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-04-24 14:22:31 +00:00
Robin KAY
d74533b407
Add support for custom glTF vertex attributes. (#5370)
# 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.
2023-04-24 14:20:13 +00:00
Wybe Westra
abf12f3b3b
Fixed several missing links in docs. (#8117)
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>
2023-04-23 17:28:36 +00:00
IceSentry
3f6367d584
Handle vertex_uvs if they are present in default prepass fragment shader (#8330)
# 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
2023-04-23 08:07:15 +00:00
ira
6b774c0fda
Compute vertex_count for indexed meshes on GpuMesh (#8460)
# Objective

Compute the `vertex_count` for indexed meshes as well as non-indexed
meshes.

I will need this in a future PR based on #8427 that adds a gizmo
component that draws the normals of a mesh when attached to an entity
([branch](https://github.com/devil-ira/bevy/compare/instanced-line-rendering...devil-ira:bevy:instanced-line-rendering-normals)).

<details><summary>Example image</summary>
<p>


![image](https://user-images.githubusercontent.com/29694403/233789526-cb5feb47-0aa7-4e69-90a2-e31ec24aadff.png)

</p>
</details> 

## Solution

Move `vertex_count` field from `GpuBufferInfo::NonIndexed` to `GpuMesh`

## Migration Guide

`vertex_count` is now stored directly on `GpuMesh` instead of
`GpuBufferInfo::NonIndexed`.
2023-04-22 17:28:58 +00:00
François
e0e5f3acd4
add a default font (#8445)
# 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
2023-04-21 22:30:18 +00:00
Kjolnyr
ddefc246b2
Added arc_2d function for gizmos (#8448)
# 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>
2023-04-21 15:34:07 +00:00
François
347dc0982c
typo on schedule StateTransitions name in example (#8443)
# Objective

- Fix a typo

## Solution

- Fix the typo
2023-04-20 11:33:45 +00:00
Nile
9db70da96f
Add screenshot api (#7163)
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`
2023-04-19 21:28:42 +00:00
ickshonpe
09df19bcad
Split UI Overflow by axis (#8095)
# 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()`
2023-04-17 22:23:52 +00:00
Nico Burns
919919c998
Fix text measurement algorithm (#8425)
# 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.
2023-04-17 19:59:42 +00:00
ickshonpe
8ed7723823
many-buttons commandline options for text and layout recomputation (#8418)
# Objective

Add commandline options that force the recomputation of text and layout
to happen every frame.
2023-04-17 17:49:11 +00:00
Nico Burns
363d0f0c7c
Add CSS Grid support to bevy_ui (#8026)
# 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>
2023-04-17 16:21:38 +00:00
Kjolnyr
cfa750a741
Adding a bezier curve example (#8194)
# Objective

Examples on how to use the freshly merged `Bezier` struct ( #7653 ) are
missing.

## Solution

- Added a `bezier_curve.rs` example in the `animation/` folder.

---------

Co-authored-by: ira <JustTheCoolDude@gmail.com>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
2023-04-17 16:16:56 +00:00
Nicola Papale
e243175d27
Add examples page build instructions (#8413)
# Objective

Bevy provides an easy way to build the `examples/README.md` page, but
it's difficult to discover.
By adding instructions in `CONTRIBUTING.md`, it's easier to find that
it's possible to avoid this error-prone manual process.

Precisely: #8405 took me about 1 additional hour searching what command
to use to generate automatically the file. (I could have manually edited
the README, but that's beyond the point…)
2023-04-17 16:13:24 +00:00
Nicola Papale
396c2713a6
Minor typo fixup (#8405)
# Objective

Fix two small typos in example description
2023-04-16 16:55:47 +00:00
IceSentry
c7eaedd6a1
Remove old post_processing example (#8376)
# Objective

- The old post processing example doesn't use the actual post processing
features of bevy. It also has some issues with resizing. It's also
causing some confusion for people because accessing the prepass textures
from it is not easy.
- There's already a render to texture example
- At this point, it's mostly obsolete since the post_process_pass
example is more complete and shows the recommended way to do post
processing in bevy. It's a bit more complicated, but it's well
documented and I'm working on simplifying it even more

## Solution

- Remove the old post_processing example
- Rename post_process_pass to post_processing


## Reviewer Notes
The diff is really noisy because of the rename, but I didn't change any
code in the example.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2023-04-15 21:48:31 +00:00
Nicola Papale
8df014fbaf
Add parallax mapping to bevy PBR (#5928)
# Objective

Add a [parallax mapping] shader to bevy. Please note that
this is a 3d technique, NOT a 2d sidescroller feature.

## Solution

- Add related fields to `StandardMaterial`
- update the pbr shader
- Add an example taking advantage of parallax mapping

A pre-existing implementation exists at:
https://github.com/nicopap/bevy_mod_paramap/

The implementation is derived from:

https://web.archive.org/web/20150419215321/http://sunandblackcat.com/tipFullView.php?l=eng&topicid=28

Further discussion on literature is found in the `bevy_mod_paramap`
README.

### Limitations

- The mesh silhouette isn't affected by the depth map.
- The depth of the pixel does not reflect its visual position, resulting
  in artifacts for depth-dependent features such as fog or SSAO
- GLTF does not define a height map texture, so somehow the user will
  always need to work around this limitation, though [an extension is in
  the works][gltf]

### Future work

- It's possible to update the depth in the depth buffer to follow the
  parallaxed texture. This would enable interop with depth-based
  visual effects, it also allows `discard`ing pixels of materials when
  computed depth is higher than the one in depth buffer
- Cheap lower quality single-sample method using [offset limiting]
- Add distance fading, to disable parallaxing (relatively expensive)
  on distant objects
- GLTF extension to allow defining height maps. Or a workaround
  implemented through a blender plugin to the GLTF exporter that
  uses the `extras` field to add height map.
- [Quadratic surface vertex attributes][oliveira_3] to enable parallax
  mapping on bending surfaces and allow clean silhouetting.
- noise based sampling, to limit the pancake artifacts.
- Cone mapping ([GPU gems], [Simcity (2013)][simcity]). Requires
  preprocessing, increase depth map size, reduces sample count greatly.
- [Quadtree parallax mapping][qpm] (also requires preprocessing)
- Self-shadowing of parallax-mapped surfaces by modifying the shadow map
- Generate depth map from normal map [link to slides], [blender
question]


https://user-images.githubusercontent.com/26321040/223563792-dffcc6ab-70e8-4ff9-90d1-b36c338695ad.mp4

[blender question]:
https://blender.stackexchange.com/questions/89278/how-to-get-a-smooth-curvature-map-from-a-normal-map
[link to slides]:
https://developer.download.nvidia.com/assets/gamedev/docs/nmap2displacement.pdf
[oliveira_3]:
https://www.inf.ufrgs.br/~oliveira/pubs_files/Oliveira_Policarpo_RP-351_Jan_2005.pdf
[GPU gems]:
https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-18-relaxed-cone-stepping-relief-mapping
[simcity]:
https://community.simtropolis.com/omnibus/other-games/building-and-rendering-simcity-2013-r247/
[offset limiting]:
https://raw.githubusercontent.com/marcusstenbeck/tncg14-parallax-mapping/master/documents/Parallax%20Mapping%20with%20Offset%20Limiting%20-%20A%20Per-Pixel%20Approximation%20of%20Uneven%20Surfaces.pdf
[gltf]: https://github.com/KhronosGroup/glTF/pull/2196
[qpm]:
https://www.gamedevs.org/uploads/quadtree-displacement-mapping-with-height-blending.pdf

---

## Changelog

- Add a `depth_map` field to the `StandardMaterial`, it is a grayscale
  image where white represents bottom and black the top. If `depth_map`
  is set, bevy's pbr shader will use it to do [parallax mapping] to
  give an increased feel of depth to the material. This is similar to a
  displacement map, but with infinite precision at fairly low cost.
- The fields `parallax_mapping_method`, `parallax_depth_scale` and
  `max_parallax_layer_count` allow finer grained control over the
  behavior of the parallax shader.
- Add the `parallax_mapping` example to show off the effect.

[parallax mapping]: https://en.wikipedia.org/wiki/Parallax_mapping

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-04-15 10:25:14 +00:00
François
4805e48da9
Alien Cake Addict example: don't exit when player lose (#8388)
# Objective

- Example Alien Cake Addict exit when the player lose, it's not supposed
to

## Solution

- Don't despawn the window

---------

Co-authored-by: ira <JustTheCoolDude@gmail.com>
2023-04-14 19:38:34 +00:00
JohnTheCoolingFan
ff9a178818
Explain why default_nearest is used in pixel_perfect example (#8370)
# Objective

Fixes #8367 

## Solution

Added a comment explaining why linear filtering is required in this
example, with formatting focused specifically on `ImagePlugin` to avoid
confusion
2023-04-13 17:58:06 +00:00
Liam Gallagher
dff071c2a8
Ability to set a Global Volume (#7706)
# 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>
2023-04-10 14:08:43 +00:00
Mikkel Rasmussen
e9312254d8
Non-breaking change* from UK spellings to US (#8291)
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
2023-04-08 16:22:46 +00:00
Asier Illarramendi
b8b0942f49
Add overflow_debug example (#8198)
# Objective

- Add a new example that helps debug different UI overflow scenarios
- This example tests the clipping behavior for images and text when the
node is moved, scaled or rotated.

## Solution

- Add a new `overflow_debug` example

# Preview

**Note:** Only top-left is working properly right now.


https://user-images.githubusercontent.com/188612/227629093-26c94c67-1781-437d-8410-e854b6f1adc1.mp4

---

Related #8095, #8167

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
2023-04-05 23:07:41 +00:00
ira
585baf0a66
Consistent screen-space coordinates (#8306)
# 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.
2023-04-05 22:32:36 +00:00
Mikkel Rasmussen
1575481429
Changed spelling linebreak_behaviour to linebreak_behavior (#8285)
# Objective

In the
[`Text`](3442a13d2c/crates/bevy_text/src/text.rs (L18))
struct the field is named: `linebreak_behaviour`, the British spelling
of _behavior_.
**Update**, also found: 
- `FileDragAndDrop::HoveredFileCancelled` 
- `TouchPhase::Cancelled`
- `Touches.just_cancelled`

The majority of all spelling is in the US but when you have a lot of
contributors across the world, sometimes
spelling differences can pop up in APIs such as in this case. 

For consistency, I think it would be worth a while to ensure that the
API is persistent.

Some examples:
`from_reflect.rs` has `DefaultBehavior`
TextStyle has `color` and uses the `Color` struct.
In `bevy_input/src/Touch.rs` `TouchPhase::Cancelled` and _canceled_ are
used interchangeably in the documentation

I've found that there is also the same type of discrepancies in the
documentation, though this is a low priority but is worth checking.
**Update**: I've now checked the documentation (See #8291)

## Solution

I've only renamed the inconsistencies that have breaking changes and
documentation pertaining to them. The rest of the documentation will be
changed via #8291.

Do note that the winit API is written with UK spelling, thus this may be
a cause for confusion:
`winit::event::TouchPhase::Cancelled => TouchPhase::Canceled`
`winit::event::WindowEvent::HoveredFileCancelled` -> Related to
`FileDragAndDrop::HoveredFileCanceled`

But I'm hoping to maybe outline other spelling inconsistencies in the
API, and maybe an addition to the contribution guide.

---

## Changelog

- `Text` field `linebreak_behaviour` has been renamed to
`linebreak_behavior`.
- Event `FileDragAndDrop::HoveredFileCancelled` has been renamed to
`HoveredFileCanceled`
- Function `Touches.just_cancelled` has been renamed to
`Touches.just_canceled`
- Event `TouchPhase::Cancelled` has been renamed to
`TouchPhase::Canceled`

## Migration Guide

Update where `linebreak_behaviour` is used to `linebreak_behavior`
Updated the event `FileDragAndDrop::HoveredFileCancelled` where used to
`HoveredFileCanceled`
Update `Touches.just_cancelled` where used as `Touches.just_canceled`
The event `TouchPhase::Cancelled` is now called `TouchPhase::Canceled`
2023-04-05 21:25:53 +00:00
IceSentry
614de3019c
Add RenderGraphApp to simplify adding render nodes (#8007)
# Objective

- Adding a node to the render_graph can be quite verbose and error prone
because there's a lot of moving parts to it.

## Solution

- Encapsulate this in a simple utility method
	- Mostly intended for optional nodes that have specific ordering
- Requires that the `Node` impl `FromWorld`, but every internal node is
built using a new function taking a `&mut World` so it was essentially
already `FromWorld`
- Use it for the bloom, fxaa and taa, nodes. 
- The main nodes don't use it because they rely more on the order of
many nodes being added

---

## Changelog

- Impl `FromWorld` for `BloomNode`, `FxaaNode` and `TaaNode`
- Added `RenderGraph::add_node_edges()`
- Added `RenderGraph::sub_graph()`
- Added `RenderGraph::sub_graph_mut()`
- Added `RenderGraphApp`, `RenderGraphApp::add_render_graph_node`,
`RenderGraphApp::add_render_graph_edges`,
`RenderGraphApp::add_render_graph_edge`

## Notes

~~This was taken out of https://github.com/bevyengine/bevy/pull/7995
because it works on it's own. Once the linked PR is done, the new
`add_node()` will be simplified a bit since the input/output params
won't be necessary.~~

This feature will be useful in most of the upcoming render nodes so it's
impact will be more relevant at that point.

Partially fixes #7985 

## Future work

* Add a way to automatically label nodes or at least make it part of the
trait. This would remove one more field from the functions added in this
PR
* Use it in the main pass 2d/3d

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-04-04 00:50:22 +00:00
张林伟
5c7abb0579
Remove OnUpdate system set (#8260)
# Objective

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

## Solution

- Replace `OnUpdate` with `run_if(in_state(xxx))`.

---

## Migration Guide

- Replace `OnUpdate` with `run_if(in_state(xxx))`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-04-04 00:49:41 +00:00
Elabajaba
09f1bd0be7
Add port of AMD's Robust Contrast Adaptive Sharpening (#7422)
# Objective

TAA, FXAA, and some other post processing effects can cause the image to
become blurry. Sharpening helps to counteract that.

## Solution

~~This is a port of AMD's Contrast Adaptive Sharpening (I ported it from
the
[SweetFX](https://github.com/CeeJayDK/SweetFX/blob/master/Shaders/CAS.fx)
version, which is still MIT licensed). CAS is a good sharpening
algorithm that is better at avoiding the full screen oversharpening
artifacts that simpler algorithms tend to create.~~

This is a port of AMD's Robust Contrast Adaptive Sharpening (RCAS) which
they developed for FSR 1 ([and continue to use in FSR
2](149cf26e12/src/ffx-fsr2-api/shaders/ffx_fsr1.h (L599))).
RCAS is a good sharpening algorithm that is better at avoiding the full
screen oversharpening artifacts that simpler algorithms tend to create.

---

## Future Work

- Consider porting this to a compute shader for potentially better
performance. (In my testing it is currently ridiculously cheap (0.01ms
in Bistro at 1440p where I'm GPU bound), so this wasn't a priority,
especially since it would increase complexity due to still needing the
non-compute version for webgl2 support).

---

## Changelog

- Added Contrast Adaptive Sharpening.

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-04-02 20:14:01 +00:00
JMS55
f0f5d79917
Built-in skybox (#8275)
# Objective

- Closes https://github.com/bevyengine/bevy/issues/8008

## Solution

- Add a skybox plugin that renders a fullscreen triangle, and then
modifies the vertices in a vertex shader to enforce that it renders as a
skybox background.
- Skybox is run at the end of MainOpaquePass3dNode.
- In the future, it would be nice to get something like bevy_atmosphere
built-in, and have a default skybox+environment map light.

---

## Changelog

- Added `Skybox`.
- `EnvironmentMapLight` now renders in the correct orientation.

## Migration Guide
- Flip `EnvironmentMapLight` maps if needed to match how they previously
rendered (which was backwards).

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2023-04-02 10:57:12 +00:00
Natalia
7a9e77c79c
make the examples use the States derive macro (#8289)
# Objective
Some examples still manually implement the States trait, even though
manual implementation is no longer needed as there is now the derive
macro for that.

---------

Signed-off-by: Natalia Asteria <fortressnordlys@outlook.com>
2023-04-02 04:25:47 +00:00
François
21dc3abe1b
daily job running mobile example on real devices (#8216)
# Objective

- Test mobile example on real devices

## Solution

- Use [BrowserStack](https://www.browserstack.com) to have access to
[real
devices](https://www.browserstack.com/list-of-browsers-and-platforms/app_automate)
- [App Automate](https://www.browserstack.com/app-automate) to run the
example
- [App Percy](https://www.browserstack.com/app-percy) to compare the
screenshot
- Added a daily/manual CI job that will build for iOS and Android, send
the apps to BrowserStack, run the app on one iOS device and one Android
device, capture a screenshot, send it for visual validation, and archive
it in the GitHub action

Example run: https://github.com/mockersf/bevy/actions/runs/4521883534

They currently have a bug with the settings to view snapshots, they
should be public. I'll raise it to them, and if they don't fix it in
time it's possible to work around for everyone to view the results
through their API.

@cart to get this to work, you'll need
- to set up an account on BrowserStack
- add the secrets `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY`
to the Bevy repo
- create a project in Percy
- add the secret `PERCY_TOKEN` to the Bevy repo and modify the project
name line 122 in the `Daily.yml` file
2023-03-28 23:16:07 +00:00
JMS55
53667dea56
Temporal Antialiasing (TAA) (#7291)
![image](https://user-images.githubusercontent.com/47158642/214374911-412f0986-3927-4f7a-9a6c-413bdee6b389.png)

# Objective

- Implement an alternative antialias technique
- TAA scales based off of view resolution, not geometry complexity
- TAA filters textures, firefly pixels, and other aliasing not covered
by MSAA
- TAA additionally will reduce noise / increase quality in future
stochastic rendering techniques
- Closes https://github.com/bevyengine/bevy/issues/3663

## Solution

- Add a temporal jitter component
- Add a motion vector prepass
- Add a TemporalAntialias component and plugin
- Combine existing MSAA and FXAA examples and add TAA

## Followup Work
- Prepass motion vector support for skinned meshes
- Move uniforms needed for motion vectors into a separate bind group,
instead of using different bind group layouts
- Reuse previous frame's GPU view buffer for motion vectors, instead of
recomputing
- Mip biasing for sharper textures, and or unjitter texture UVs
https://github.com/bevyengine/bevy/issues/7323
- Compute shader for better performance
- Investigate FSR techniques
  - Historical depth based disocclusion tests, for geometry disocclusion
  - Historical luminance/hue based tests, for shading disocclusion
- Pixel "locks" to reduce blending rate / revamp history confidence
mechanism
- Orthographic camera support for TemporalJitter
- Figure out COD's 1-tap bicubic filter

---

## Changelog

- Added MotionVectorPrepass and TemporalJitter
- Added TemporalAntialiasPlugin, TemporalAntialiasBundle, and
TemporalAntialiasSettings

---------

Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Daniel Chia <danstryder@gmail.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
Co-authored-by: Brandon Dyer <brandondyer64@gmail.com>
Co-authored-by: Edgar Geier <geieredgar@gmail.com>
2023-03-27 22:22:40 +00:00
Trevor Lovell
464d35aef5
docs: update docs and comments that still refer to stages (#8156)
# Objective
Documentation should no longer be using pre-stageless terminology to
avoid confusion.

## Solution
- update all docs referring to stages to instead refer to sets/schedules
where appropriate
- also mention `apply_system_buffers` for anything system-buffer-related
that previously referred to buffers being applied "at the end of a
stage"
2023-03-27 21:50:21 +00:00
Asier Illarramendi
47be369e41
Rename text_layout example to flex_layout (#7943)
# Objective

- Rename `text_layout` example to `flex_layout` to better reflect the
example purpose
- `AlignItems`/`JustifyContent` is not related to text layout, it's
about child nodes positioning

## Solution

- Rename the example

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-03-22 08:22:56 +00:00
IceSentry
2c21d423fd
Make render graph slots optional for most cases (#8109)
# Objective

- Currently, the render graph slots are only used to pass the
view_entity around. This introduces significant boilerplate for very
little value. Instead of using slots for this, make the view_entity part
of the `RenderGraphContext`. This also means we won't need to have
`IN_VIEW` on every node and and we'll be able to use the default impl of
`Node::input()`.

## Solution

- Add `view_entity: Option<Entity>` to the `RenderGraphContext`
- Update all nodes to use this instead of entity slot input

---

## Changelog

- Add optional `view_entity` to `RenderGraphContext`

## Migration Guide

You can now get the view_entity directly from the `RenderGraphContext`. 

When implementing the Node:

```rust
// 0.10
struct FooNode;
impl FooNode {
    const IN_VIEW: &'static str = "view";
}
impl Node for FooNode {
    fn input(&self) -> Vec<SlotInfo> {
        vec![SlotInfo::new(Self::IN_VIEW, SlotType::Entity)]
    }
    fn run(
        &self,
        graph: &mut RenderGraphContext,
        // ... 
    ) -> Result<(), NodeRunError> {
        let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
        // ...
        Ok(())
    }
}

// 0.11
struct FooNode;
impl Node for FooNode {
    fn run(
        &self,
        graph: &mut RenderGraphContext,
        // ... 
    ) -> Result<(), NodeRunError> {
        let view_entity = graph.view_entity();
        // ...
        Ok(())
    }
}
```

When adding the node to the graph, you don't need to specify a slot_edge
for the view_entity.

```rust
// 0.10
let mut graph = RenderGraph::default();
graph.add_node(FooNode::NAME, node);
let input_node_id = draw_2d_graph.set_input(vec![SlotInfo::new(
    graph::input::VIEW_ENTITY,
    SlotType::Entity,
)]);
graph.add_slot_edge(
    input_node_id,
    graph::input::VIEW_ENTITY,
    FooNode::NAME,
    FooNode::IN_VIEW,
);
// add_node_edge ...

// 0.11
let mut graph = RenderGraph::default();
graph.add_node(FooNode::NAME, node);
// add_node_edge ...
```

## Notes

This PR paired with #8007 will help reduce a lot of annoying boilerplate
with the render nodes. Depending on which one gets merged first. It will
require a bit of clean up work to make both compatible.

I tagged this as a breaking change, because using the old system to get
the view_entity will break things because it's not a node input slot
anymore.

## Notes for reviewers

A lot of the diffs are just removing the slots in every nodes and graph
creation. The important part is mostly in the
graph_runner/CameraDriverNode.
2023-03-21 20:11:13 +00:00
Francesco
7b38de0a64
(De) serialize resources in scenes (#6846)
# Objective

Co-Authored-By: davier
[bricedavier@gmail.com](mailto:bricedavier@gmail.com)
Fixes #3576.
Adds a `resources` field in scene serialization data to allow
de/serializing resources that have reflection enabled.

## Solution

Most of this code is taken from a previous closed PR:
https://github.com/bevyengine/bevy/pull/3580. Most of the credit goes to
@Davier , what I did was mostly getting it to work on the latest main
branch of Bevy, along with adding a few asserts in the currently
existing tests to be sure everything is working properly.

This PR changes the scene format to include resources in this way:
```
(
  resources: {
    // List of resources here, keyed by resource type name.
  },
  entities: [
    // Previous scene format here
  ],
)
```

An example taken from the tests:
```
(
  resources: {
    "bevy_scene::serde::tests::MyResource": (
      foo: 123,
    ),
  },
  entities: {
    // Previous scene format here
  },
)
```
For this, a `resources` fields has been added on the `DynamicScene` and
the `DynamicSceneBuilder` structs. The latter now also has a method
named `extract_resources` to properly extract the existing resources
registered in the local type registry, in a similar way to
`extract_entities`.


---

## Changelog


Added: Reflect resources registered in the type registry used by dynamic
scenes will now be properly de/serialized in scene data.

## Migration Guide

Since the scene format has been changed, the user may not be able to use
scenes saved prior to this PR due to the `resources` scene field being
missing. ~~To preserve backwards compatibility, I will try to make the
`resources` fully optional so that old scenes can be loaded without
issue.~~

## TODOs

- [x] I may have to update a few doc blocks still referring to dynamic
scenes as mere container of entities, since they now include resources
as well.
- [x] ~~I want to make the `resources` key optional, as specified in the
Migration Guide, so that old scenes will be compatible with this
change.~~ Since this would only be trivial for ron format, I think it
might be better to consider it in a separate PR/discussion to figure out
if it could be done for binary serialization too.
- [x] I suppose it might be a good idea to add a resources in the scene
example so that users will quickly notice they can serialize resources
just like entities.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-03-20 21:17:02 +00:00
ira
6a85eb3d7e
Immediate Mode Line/Gizmo Drawing (#6529)
# Objective
Add a convenient immediate mode drawing API for visual debugging.

Fixes #5619
Alternative to #1625
Partial alternative to #5734

Based off https://github.com/Toqozz/bevy_debug_lines with some changes:
 * Simultaneous support for 2D and 3D.
 * Methods for basic shapes; circles, spheres, rectangles, boxes, etc.
 * 2D methods.
 * Removed durations. Seemed niche, and can be handled by users.

<details>
<summary>Performance</summary>

Stress tested using Bevy's recommended optimization settings for the dev
profile with the
following command.
```bash
cargo run --example many_debug_lines \
    --config "profile.dev.package.\"*\".opt-level=3" \
    --config "profile.dev.opt-level=1"
```
I dipped to 65-70 FPS at 300,000 lines
CPU: 3700x
RAM Speed: 3200 Mhz
GPU: 2070 super - probably not very relevant, mostly cpu/memory bound

</details>

<details>
<summary>Fancy bloom screenshot</summary>


![Screenshot_20230207_155033](https://user-images.githubusercontent.com/29694403/217291980-f1e0500e-7a14-4131-8c96-eaaaf52596ae.png)

</details>

## Changelog
 * Added `GizmoPlugin`
 * Added `Gizmos` system parameter for drawing lines and wireshapes.

### TODO
- [ ] Update changelog
- [x] Update performance numbers
- [x] Add credit to PR description

### Future work
- Cache rendering primitives instead of constructing them out of line
segments each frame.
- Support for drawing solid meshes
- Interactions. (See
[bevy_mod_gizmos](https://github.com/LiamGallagher737/bevy_mod_gizmos))
- Fancier line drawing. (See
[bevy_polyline](https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline))
- Support for `RenderLayers`
- Display gizmos for a certain duration. Currently everything displays
for one frame (ie. immediate mode)
- Changing settings per drawn item like drawing on top or drawing to
different `RenderLayers`

Co-Authored By: @lassade <felipe.jorge.pereira@gmail.com>
Co-Authored By: @The5-1 <agaku@hotmail.de> 
Co-Authored By: @Toqozz <toqoz@hotmail.com>
Co-Authored By: @nicopap <nico@nicopap.ch>

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-03-20 20:57:54 +00:00
Carl B. Smiley
e27f38a3e6
improve comments in example (#8127)
# Objective

Added additional comments to describe what is going on in an example.
2023-03-20 18:42:10 +00:00
ickshonpe
5703c75d76
Allow many_buttons to be run without text (#8116) 2023-03-18 22:58:17 +00:00
Carter Anderson
aefe1f0739
Schedule-First: the new and improved add_systems (#8079)
Co-authored-by: Mike <mike.hsu@gmail.com>
2023-03-18 01:45:34 +00:00
IceSentry
9d1193df6c
Add low level post process example using a custom render pass (#6909)
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-03-16 03:22:17 +00:00
Rob Parrett
1d4910a1e3
Fix scrolling in UI example (#8069)
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-03-15 06:50:37 +00:00
Rob Parrett
f6c72a7442
Fix blend_modes example UI positioning (#8093) 2023-03-15 01:03:53 +00:00
ickshonpe
e77eb003ec
Perform text scaling calculations per text, not per glyph (#7819) 2023-03-14 00:01:27 +00:00
Mike
8a2502ce0f
change breakout to use FixedTime::period (#8076) 2023-03-13 21:12:53 +00:00
ickshonpe
87dda354dd
Remove Val::Undefined (#7485) 2023-03-13 15:17:00 +00:00
JoJoJet
fd1af7c8b8
Replace multiple calls to add_system with add_systems (#8001) 2023-03-10 18:15:22 +00:00
ickshonpe
729458815c
Fix the Text2d text anchor's incorrect horizontal alignment (#8019) 2023-03-10 14:57:41 +00:00
ira
f3cf734659
Fix broken code behind wasm feature flag in blend_modes example (#7945) 2023-03-07 13:55:34 +00:00
Marco Buono
f87de36843 Send emissive color to uniform as linear instead of sRGB (#7897)
This produces more accurate results for the `EmissiveStrengthTest` glTF test case.

(Requires manually setting the emission, for now)

Before: <img width="1392" alt="Screenshot 2023-03-04 at 18 21 25" src="https://user-images.githubusercontent.com/418473/222929455-c7363d52-7133-4d4e-9d6a-562098f6bbe8.png">

After: <img width="1392" alt="Screenshot 2023-03-04 at 18 20 57" src="https://user-images.githubusercontent.com/418473/222929454-3ea20ecb-0773-4aad-978c-3832353b6871.png">

Tagging @JMS55 as a co-author, since this fix is based on their experiments with emission.

# Objective

- Have more accurate results for the `EmissiveStrengthTest` glTF test case.

## Solution

- Make sure we send the emissive color as linear instead of sRGB.

---

## Changelog

- Emission strength is now correctly interpreted by the `StandardMaterial` as linear instead of sRGB.

## Migration Guide

- If you have previously manually specified emissive values with `Color::rgb()` and would like to retain the old visual results, you must now use `Color::rgb_linear()` instead;
- If you have previously manually specified emissive values with `Color::rgb_linear()` and would like to retain the old visual results, you'll need to apply a one-time gamma calculation to your channels manually to get the _actual_ linear RGB value: 
  - For channel values greater than `0.0031308`, use `(1.055 * value.powf(1.0 / 2.4)) - 0.055`;
  - For channel values lower than or equal to `0.0031308`, use `value * 12.92`;
- Otherwise, the results should now be more consistent with other tools/engines.
2023-03-04 23:26:04 +00:00
Robert Swain
f9226a382e Add bevy logo to the lighting example to demo alpha mask shadows (#7895)
$subj

![Screenshot 2023-03-04 at 15 46 05](https://user-images.githubusercontent.com/302146/222910129-0a38dc9c-ff65-46d9-adcc-9e26694c9c22.png)
2023-03-04 15:10:47 +00:00
François
57bf771f9a Transparent window on macos (#7617)
# Objective

- Example `transparent_window` doesn't display a transparent window on macOS
- Fixes #6330

## Solution

- Set the `composite_alpha_mode` of the window to the correct value
- Update docs
2023-03-04 14:51:23 +00:00
ickshonpe
465fff2b01 Text pipeline benchmark (#7845)
# Objective

Simple text pipeline benchmark. It's quite expensive but current examples don't capture the performance of `queue_text` as it only runs on changes to the text.
2023-03-04 12:29:08 +00:00
JMS55
2a7000a738 Revamp Bloom (#6677)
![image](https://user-images.githubusercontent.com/47158642/220197588-25e11022-02e4-45f3-b2e5-392c4ce7a025.png)

Huge credit to @StarLederer, who did almost all of the work on this. We're just reusing this PR to keep everything in one place.

# Objective

1. Make bloom more physically based.
1. Improve artistic control.
1. Allow to use bloom as screen blur.
1. Fix #6634.
1. Address #6655 (although the author makes incorrect conclusions).

## Solution

1. Set the default threshold to 0.
2. Lerp between bloom textures when `composite_mode: BloomCompositeMode::EnergyConserving`.
1. Use [a parametric function](https://starlederer.github.io/bloom) to control blend levels for each bloom texture. In the future this can be controlled per-pixel for things like lens dirt.
3. Implement BloomCompositeMode::Additive` for situations where the old school look is desired.

## Changelog

* Bloom now looks different.
* Added `BloomSettings:lf_boost`, `BloomSettings:lf_boost_curvature`, `BloomSettings::high_pass_frequency` and `BloomSettings::composite_mode`.
* `BloomSettings::scale` removed.
* `BloomSettings::knee` renamed to `BloomPrefilterSettings::softness`.
* `BloomSettings::threshold` renamed to `BloomPrefilterSettings::threshold`.
* The bloom example has been renamed to bloom_3d and improved. A bloom_2d example was added.

## Migration Guide

* Refactor mentions of `BloomSettings::knee` and `BloomSettings::threshold` as `BloomSettings::prefilter_settings` where knee is now `softness`.
* If defined without `..default()` add `..default()` to definitions of `BloomSettings` instances or manually define missing fields.
* Adapt to Bloom looking visually different (if needed).

Co-authored-by: Herman Lederer <germans.lederers@gmail.com>
2023-03-04 12:05:26 +00:00
SpecificProtagonist
91ff782439 Fix hot reloading for read_asset_bytes (#6797)
# Objective

Fixes #6780

## Solution

- record the asset path of each watched file
- call `AssetIo::watch_for_changes` in `LoadContext::read_asset_bytes`

---

## Changelog

### Fixed
- fixed hot reloading for `LoadContext::read_asset_bytes`

### Changed
- `AssetIo::watch_path_for_changes` allows watched path and path to reload to differ

## Migration Guide
- for custom `AssetIo`s, differentiate paths to watch and asset paths to reload as a consequence

Co-authored-by: Vincent Junge <specificprotagonist@posteo.org>
2023-03-02 02:51:06 +00:00
IceSentry
71cf35ce42 Allow prepass in webgl (#7537)
# Objective

- Use the prepass textures in webgl

## Solution

- Bind the prepass textures even when using webgl, but only if msaa is disabled
- Also did some refactors to centralize how textures are bound, similar to the EnvironmentMapLight PR
- ~~Also did some refactors of the example to make it work in webgl~~
- ~~To make the example work in webgl, I needed to use a sampler for the depth texture, the resulting code looks a bit weird, but it's simple enough and I think it's worth it to show how it works when using webgl~~
2023-03-02 02:23:06 +00:00
Nolan Darilek
8d1f6ff7fa Integrate AccessKit (#6874)
# Objective

UIs created for Bevy cannot currently be made accessible. This PR aims to address that.

## Solution

Integrate AccessKit as a dependency, adding accessibility support to existing bevy_ui widgets.

## Changelog

### Added

* Integrate with and expose [AccessKit](https://accesskit.dev) for platform accessibility.
* Add `Label` for marking text specifically as a label for UI controls.
2023-03-01 22:45:04 +00:00
shuo
002c9d8b7f fix whitespaces in comment (#7853)
fix double whitespaces in comments. (I know it's dumb commit, while reading code, double spaces hurts a little... :P)
2023-03-01 10:20:56 +00:00
François
261905f11d Feature documentation (#7814)
# Objective

- Fixes #1800, fixes #6984
- Alternative to #7196
- Ensure feature list is always up to date and that all are documented
- Help discovery of features

## Solution

- Use a template to update the cargo feature list
- Use the comment just above the feature declaration as the description
- Add the checks to CI
- Add the features to the base crate doc
2023-02-28 14:24:47 +00:00
Anselmo Sampietro
998e983bac Add example to show how to use apply_system_buffers (#7793)
# Objective

This PR adds an example that shows how to use `apply_system_buffers` and how to order it with respect to the relevant systems. It also shows how not ordering the systems can lead to unexpected behaviours.

## Solution

Add the example.
2023-02-28 00:19:44 +00:00
Michał Iwańczuk
3d8fe46f94 Add unsupported platforms note to ui window fallthrough example (#7827)
# Objective
This adds small comment to window fall through example that it won't work on specific platforms. This information is documented in `Cursor` api but I think it is worth to add it in example description for clarity sake.
2023-02-27 00:44:11 +00:00
JoJoJet
b8263b55fb Support system.in_schedule() and system.on_startup() (#7790)
# Objective

Support the following syntax for adding systems:

```rust
App::new()
    .add_system(setup.on_startup())
    .add_systems((
        show_menu.in_schedule(OnEnter(GameState::Paused)),
        menu_ssytem.in_set(OnUpdate(GameState::Paused)),
        hide_menu.in_schedule(OnExit(GameState::Paused)),
    ))
```

## Solution

Add the traits `IntoSystemAppConfig{s}`, which provide the extension methods necessary for configuring which schedule a system belongs to. These extension methods return `IntoSystemAppConfig{s}`, which `App::add_system{s}` uses to choose which schedule to add systems to.

---

## Changelog

+ Added the extension methods `in_schedule(label)` and  `on_startup()` for configuring the schedule a system belongs to.

## Future Work

* Replace all uses of `add_startup_system` in the engine.
* Deprecate this method
2023-02-24 18:33:55 +00:00
Rob Parrett
03c545056c Fix some more typos (#7767)
# Objective

I managed to dig up some more typos with a combination of the "[code spell checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)" and "[open folder](https://marketplace.visualstudio.com/items?itemName=rwu823.open-folder)" vscode extensions.

## Solution

Fix em
2023-02-20 23:36:28 +00:00
JoJoJet
0c98f9a225 Add AND/OR combinators for run conditions (#7605)
# Objective

Fix #7584.

## Solution

Add an abstraction for creating custom system combinators with minimal boilerplate. Use this to implement AND/OR combinators. Use this to simplify the implementation of `PipeSystem`.

## Example

Feel free to bikeshed on the syntax.

I chose the names `and_then`/`or_else` to emphasize the fact that these short-circuit, while I chose method syntax to empasize that the arguments are *not* treated equally.

```rust
app.add_systems((
    my_system.run_if(resource_exists::<R>().and_then(resource_equals(R(0)))),
    our_system.run_if(resource_exists::<R>().or_else(resource_exists::<S>())),
));
```

---

## Todo

- [ ] Decide on a syntax
- [x] Write docs
- [x] Write tests

## Changelog

+ Added the extension methods `.and_then(...)` and `.or_else(...)` to run conditions, which allows combining run conditions with short-circuiting behavior.
+ Added the trait `Combine`, which can be used with the new `CombinatorSystem` to create system combinators with custom behavior.
2023-02-20 18:16:11 +00:00
François
ca1802b774 Basic spatial audio (#6028)
# Objective

- Add basic spatial audio support to Bevy
  - this is what rodio supports, so no HRTF, just simple stereo channel manipulation
  - no "built-in" ECS support: `Emitter` and `Listener` should be components that would automatically update the positions

This PR goal is to just expose rodio functionality, made possible with the recent update to rodio 0.16. A proper ECS integration opens a lot more questions, and would probably require an RFC

Also updates rodio and fixes #6122
2023-02-20 15:31:07 +00:00
Griffin
912fb58869 Initial tonemapping options (#7594)
# Objective

Splits tone mapping from https://github.com/bevyengine/bevy/pull/6677 into a separate PR.
Address https://github.com/bevyengine/bevy/issues/2264.
Adds tone mapping options:
- None: Bypasses tonemapping for instances where users want colors output to match those set.
- Reinhard
- Reinhard Luminance: Bevy's exiting tonemapping
- [ACES](https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl) (Fitted version, based on the same implementation that Godot 4 uses) see https://github.com/bevyengine/bevy/issues/2264
- [AgX](https://github.com/sobotka/AgX)
- SomewhatBoringDisplayTransform
- TonyMcMapface
- Blender Filmic

This PR also adds support for EXR images so they can be used to compare tonemapping options with reference images.

## Migration Guide
- Tonemapping is now an enum with NONE and the various tonemappers.
- The DebandDither is now a separate component.




Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-02-19 20:38:13 +00:00
JoJoJet
5a5125671b Deprecate ChangeTrackers<T> in favor of Ref<T> (#7306)
# Objective

`ChangeTrackers<>` is a `WorldQuery` type that lets you access the change ticks for a component. #7097 has added `Ref<>`, which gives access to a component's value in addition to its change ticks. Since bevy's access model does not separate a component's value from its change ticks, there is no benefit to using `ChangeTrackers<T>` over `Ref<T>`.

## Solution

Deprecate `ChangeTrackers<>`.

---

## Changelog

* `ChangeTrackers<T>` has been deprecated. It will be removed in Bevy 0.11.

## Migration Guide

`ChangeTrackers<T>` has been deprecated, and will be removed in the next release. Any usage should be replaced with `Ref<T>`.

```rust
// Before (0.9)
fn my_system(q: Query<(&MyComponent, ChangeTrackers<MyComponent>)>) {
    for (value, trackers) in &q {
        if trackers.is_changed() {
            // Do something with `value`.
        }
    }
}

// After (0.10)
fn my_system(q: Query<Ref<MyComponent>>) {
    for value in &q {
        if value.is_changed() {
            // Do something with `value`.
        }
    }
}
```
2023-02-19 16:19:56 +00:00
Liam Gallagher
5a66d035e2 Use Commands::spawn_batch in bevymark example (#7738)
# Objective

Fixes #7735

## Solution

Use `spawn_batch` instead of `spawn` repeatedly in a for loop

I have decided to switch from using rands `thread_rng()` to its `StdRng`,  this allows us to avoid calling `collect()` on the bundle iterator, if collecting is fine then I can revert it back to using `thread_rng()`.
2023-02-19 03:26:11 +00:00
Liam Gallagher
50bba0f595 Add example for run conditions (#7652)
Added an example for run conditions. Fixes #7646 if we wait till #7605 is merged and include some of it features.
2023-02-18 05:32:59 +00:00
James Liu
04256735f6 Cleanup ScheduleBuildSettings (#7721)
# Objective
Fix #7440. Fix #7441. 

## Solution

 * Remove builder functions on `ScheduleBuildSettings` in favor of public fields, move docs to the fields.
 * Add `use_shortnames` and use it in `get_node_name` to feed it through `bevy_utils::get_short_name`.
2023-02-17 15:17:52 +00:00
Zhixing Zhang
16feb9acb7 Add push contant config to layout (#7681)
# Objective

Allow for creating pipelines that use push constants. To be able to use push constants. Fixes #4825

As of right now, trying to call `RenderPass::set_push_constants` will trigger the following error:

```
thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 59, Vulkan)>`
    In a set_push_constant command
    provided push constant is for stage(s) VERTEX | FRAGMENT | VERTEX_FRAGMENT, however the pipeline layout has no push constant range for the stage(s) VERTEX | FRAGMENT | VERTEX_FRAGMENT
```
## Solution

Add a field push_constant_ranges to` RenderPipelineDescriptor` and `ComputePipelineDescriptor`.

This PR supersedes #4908 which now contains merge conflicts due to significant changes to `bevy_render`.

Meanwhile, this PR also made the `layout` field of `RenderPipelineDescriptor` and `ComputePipelineDescriptor` non-optional. If the user do not need to specify the bind group layouts, they can simply supply an empty vector here. No need for it to be optional.

---

## Changelog
- Add a field push_constant_ranges to RenderPipelineDescriptor and ComputePipelineDescriptor
- Made the `layout` field of RenderPipelineDescriptor and ComputePipelineDescriptor non-optional.


## Migration Guide

- Add push_constant_ranges: Vec::new() to every `RenderPipelineDescriptor` and `ComputePipelineDescriptor`
- Unwrap the optional values on the `layout` field of `RenderPipelineDescriptor` and `ComputePipelineDescriptor`. If the descriptor has no layout, supply an empty vector.


Co-authored-by: Zhixing Zhang <me@neoto.xin>
2023-02-17 06:20:16 +00:00
Aceeri
c5d2d1a5ff Include 2x/8x sample counts for Msaa (#7684)
# Objective
Fixes #7295 

Should we maybe default to 4x if 2x/8x is selected but not supported?

---

## Changelog
- Added 2x and 8x sample counts for MSAA.
2023-02-17 06:04:01 +00:00
张林伟
1f6bbc6b7a Add quad to 2d_shapes example (#7708)
# Objective

- Add quad to 2d_shapes example
2023-02-17 01:50:20 +00:00
JMS55
db2fd92385 Make ktx2 and zstd default features (#7696)
# Objective
- Environment maps use these formats, and in the future rendering LUTs will need textures loaded by default in the engine

## Solution

- Make ktx2 and zstd part of the default feature
- Let examples assume these features are enabled

---

## Changelog
- `ktx2` and `zstd` are now party of bevy's default enabled features

## Migration Guide

- If you used the `ktx2` or `zstd` features, you no longer need to explicitly enable them, as they are now part of bevy's default enabled features
2023-02-17 01:00:07 +00:00
ZoOL
2efc0293ed Remove Anyhow::Result in system_piping.rs example (#7657)
# Objective

Fixes: #7610 

## Solution

- Return a specific error type
2023-02-14 03:33:47 +00:00
tomaspecl
9dadde06cb Fixed a typo in an example state.rs (#7666)
# Objective

Found and fixed a typo in an example ecs/state.rs
2023-02-14 01:16:33 +00:00
Alice Cecile
0a9c469d19 Remove .on_update method to improve API consistency and clarity (#7667)
# Objective

Fixes #7632.

As discussed in #7634, it can be quite challenging for users to intuit the mental model of how states now work.

## Solution

Rather than change the behavior of the `OnUpdate` system set, instead work on making sure it's easy to understand what's going on.

Two things have been done:

1. Remove the `.on_update` method from our bevy of system building traits. This was special-cased and made states feel much more magical than they need to.
2. Improve the docs for the `OnUpdate` system set.
2023-02-14 00:13:10 +00:00
François
f1c69b925e don't require features on examples where it's not the main focus (#7615)
# Objective

- Required features were added to some examples in #7051 even though those features aren't the main focus of the examples
- Don't require features on examples that are useful without them

## Solution

- Remove required features on examples `load_gltf` and `scene_viewer`, but log a warning when they are not enabled
2023-02-13 18:20:25 +00:00
woodroww
1bd390806f added subdivisions to shape::Plane (#7546)
# Objective

There was issue #191 requesting subdivisions on the shape::Plane.
I also could have used this recently. I then write the solution.

Fixes  #191

## Solution

I changed the shape::Plane to include subdivisions field and the code to create the subdivisions. I don't know how people are counting subdivisions so as I put in the doc comments 0 subdivisions results in the original geometry of the Plane.
Greater then 0 results in the number of lines dividing the plane.

I didn't know if it would be better to create a new struct that implemented this feature, say SubdivisionPlane or change Plane. I decided on changing Plane as that was what the original issue was.

It would be trivial to alter this to use another struct instead of altering Plane.
The issues of migration, although small, would be eliminated if a new struct was implemented.
 
## Changelog
### Added
Added subdivisions field to shape::Plane

## Migration Guide
All the examples needed to be updated to initalize the subdivisions field.
Also there were two tests in tests/window that need to be updated.

A user would have to update all their uses of shape::Plane to initalize the subdivisions field.
2023-02-13 18:20:20 +00:00
ickshonpe
eaac730617 Fix the Size helper functions using the wrong default value and improve the UI examples (#7626)
# Objective
`Size::width` sets the `height` field to `Val::DEFAULT` which is `Val::Undefined`, but the default for `Size` `height` is `Val::Auto`. 
`Size::height` has the same problem, but with the `width` field. 

The UI examples specify numeric values in many places where they could either be elided or replaced by composition of the Flex enum properties.

related: https://github.com/bevyengine/bevy/pull/7468
fixes: https://github.com/bevyengine/bevy/issues/6498

## Solution
Change `Size::width` so it sets `height` to `Val::AUTO` and change `Size::height` so it sets `width` to `Val::AUTO`.
Added some tests so this doesn't happen again.

## Changelog
Changed `Size::width` so it sets the `height` to `Val::AUTO`.
Changed `Size::height` so it sets the `width` to `Val::AUTO`.
Added tests to `geometry.rs` for `Size` and `UiRect` to ensure correct behaviour.
Simplified the UI examples. Replaced numeric values with the Flex property enums or elided them where possible, and removed the remaining use of auto margins.

## Migration Guide
The `Size::width` constructor function now sets the `height` to `Val::Auto` instead of `Val::Undefined`.
The `Size::height` constructor function now sets the `width` to `Val::Auto` instead of `Val::Undefined`.
2023-02-11 23:07:16 +00:00
JMS55
dd4299bcf9 EnvironmentMapLight, BRDF Improvements (#7051)
(Before)
![image](https://user-images.githubusercontent.com/47158642/213946111-15ec758f-1f1d-443c-b196-1fdcd4ae49da.png)
(After)
![image](https://user-images.githubusercontent.com/47158642/217051179-67381e73-dd44-461b-a2c7-87b0440ef8de.png)
![image](https://user-images.githubusercontent.com/47158642/212492404-524e4ad3-7837-4ed4-8b20-2abc276aa8e8.png)

# Objective
- Improve lighting; especially reflections.
- Closes https://github.com/bevyengine/bevy/issues/4581.

## Solution
- Implement environment maps, providing better ambient light.
- Add microfacet multibounce approximation for specular highlights from Filament.
- Occlusion is no longer incorrectly applied to direct lighting. It now only applies to diffuse indirect light. Unsure if it's also supposed to apply to specular indirect light - the glTF specification just says "indirect light". In the case of ambient occlusion, for instance, that's usually only calculated as diffuse though. For now, I'm choosing to apply this just to indirect diffuse light, and not specular.
- Modified the PBR example to use an environment map, and have labels.
- Added `FallbackImageCubemap`.

## Implementation
- IBL technique references can be found in environment_map.wgsl.
- It's more accurate to use a LUT for the scale/bias. Filament has a good reference on generating this LUT. For now, I just used an analytic approximation.
 - For now, environment maps must first be prefiltered outside of bevy using a 3rd party tool. See the `EnvironmentMap` documentation.
- Eventually, we should have our own prefiltering code, so that we can have dynamically changing environment maps, as well as let users drop in an HDR image and use asset preprocessing to create the needed textures using only bevy. 

---

## Changelog
- Added an `EnvironmentMapLight` camera component that adds additional ambient light to a scene.
- StandardMaterials will now appear brighter and more saturated at high roughness, due to internal material changes. This is more physically correct.
- Fixed StandardMaterial occlusion being incorrectly applied to direct lighting.
- Added `FallbackImageCubemap`.

Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2023-02-09 16:46:32 +00:00
Rob Parrett
1b444975ed Fix panics in ecs_guide example (#7525)
# Objective

Fixes #7565

`ecs_guide` example is currently panicking. This seems to just be a problem with the example only caused by the base sets PR.

## Solution

First, changed a few `in_set` to `in_base_set` to fix a few of

```
thread 'main' panicked at 'Systems cannot be added to 'base' system sets using 'in_set'. Use 'in_base_set' instead.', examples/ecs/ecs_guide.rs:301:45
```

And then added an `in_base_set` to fix the resulting (confusing) cycle error

```
2023-02-06T13:54:29.213843Z ERROR bevy_ecs::schedule_v3::schedule: schedule contains at least 1 cycle(s) -- cycle(s) found within:
 ---- 0: ["ecs_guide::game_over_system", "ecs_guide::score_check_system"]
```

I also changed this `add_system` call so the comment above and below make sense:
```diff
         // add_system(system) adds systems to the Update system set by default
         // However we can manually specify the set if we want to. The following is equivalent to
         // add_system(score_system)
-        .add_system(score_system)
+        .add_system(score_system.in_base_set(CoreSet::Update))
         // There are other `CoreSets`, such as `Last` which runs at the very end of each run.
```

## Notes

- Does `MySet` even need to be a base set? Seems like yes.
- Is that cycle error when there is no explicit `in_base_set` actually expected?
2023-02-08 23:01:53 +00:00
SpecificProtagonist
6314f50e7b States derive macro (#7535)
# Objective
Implementing `States` manually is repetitive, so let's not.

One thing I'm unsure of is whether the macro import statement is in the right place.
2023-02-07 14:02:21 +00:00
张林伟
aa4170d9a4 Rename schedule v3 to schedule (#7519)
# Objective

- Follow up of https://github.com/bevyengine/bevy/pull/7267

## Solution

- Rename schedule_v3 to schedule
- Suppress "module inception" lint
2023-02-06 18:44:40 +00:00
François
7e0a9bfade IOS, Android... same thing (#7493)
# Objective

- Merge the examples on iOS and Android
- Make sure they both work from the same code

## Solution

- don't create window when not in an active state (from #6830)
- exit on suspend on Android (from #6830)
- automatically enable dependency feature of bevy_audio on android so that it works out of the box
- don't inverse y position of touch events
- reuse the same example for both Android and iOS

Fixes #4616
Fixes #4103
Fixes #3648
Fixes #3458
Fixes #3249
Fixes #86
2023-02-06 18:08:49 +00:00
Rob Parrett
5b930c8486 Fix feature gating in texture_binding_array example (#7425)
# Objective

Fixes #7374

## Solution

Move the feature gate into `main`, before `MaterialPlugin::<BindlessMaterial>` is added, as described in https://github.com/bevyengine/bevy/issues/7374#issuecomment-1405890519
2023-02-06 17:51:39 +00:00
Carter Anderson
dcc03724a5 Base Sets (#7466)
# Objective

NOTE: This depends on #7267 and should not be merged until #7267 is merged. If you are reviewing this before that is merged, I highly recommend viewing the Base Sets commit instead of trying to find my changes amongst those from #7267.

"Default sets" as described by the [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45) have some [unfortunate consequences](https://github.com/bevyengine/bevy/discussions/7365).

## Solution

This adds "base sets" as a variant of `SystemSet`:

A set is a "base set" if `SystemSet::is_base` returns `true`. Typically this will be opted-in to using the `SystemSet` derive:

```rust
#[derive(SystemSet, Clone, Hash, Debug, PartialEq, Eq)]
#[system_set(base)]
enum MyBaseSet {
  A,
  B,
}
``` 

**Base sets are exclusive**: a system can belong to at most one "base set". Adding a system to more than one will result in an error. When possible we fail immediately during system-config-time with a nice file + line number. For the more nested graph-ey cases, this will fail at the final schedule build. 

**Base sets cannot belong to other sets**: this is where the word "base" comes from

Systems and Sets can only be added to base sets using `in_base_set`. Calling `in_set` with a base set will fail. As will calling `in_base_set` with a normal set.

```rust
app.add_system(foo.in_base_set(MyBaseSet::A))
       // X must be a normal set ... base sets cannot be added to base sets
       .configure_set(X.in_base_set(MyBaseSet::A))
```

Base sets can still be configured like normal sets:

```rust
app.add_system(MyBaseSet::B.after(MyBaseSet::Ap))
``` 

The primary use case for base sets is enabling a "default base set":

```rust
schedule.set_default_base_set(CoreSet::Update)
  // this will belong to CoreSet::Update by default
  .add_system(foo)
  // this will override the default base set with PostUpdate
  .add_system(bar.in_base_set(CoreSet::PostUpdate))
```

This allows us to build apis that work by default in the standard Bevy style. This is a rough analog to the "default stage" model, but it use the new "stageless sets" model instead, with all of the ordering flexibility (including exclusive systems) that it provides.

---

## Changelog

- Added "base sets" and ported CoreSet to use them.

## Migration Guide

TODO
2023-02-06 03:10:08 +00:00
Alice Cecile
206c7ce219 Migrate engine to Schedule v3 (#7267)
Huge thanks to @maniwani, @devil-ira, @hymm, @cart, @superdump and @jakobhellermann for the help with this PR.

# Objective

- Followup #6587.
- Minimal integration for the Stageless Scheduling RFC: https://github.com/bevyengine/rfcs/pull/45

## Solution

- [x]  Remove old scheduling module
- [x] Migrate new methods to no longer use extension methods
- [x] Fix compiler errors
- [x] Fix benchmarks
- [x] Fix examples
- [x] Fix docs
- [x] Fix tests

## Changelog

### Added

- a large number of methods on `App` to work with schedules ergonomically
- the `CoreSchedule` enum
- `App::add_extract_system` via the `RenderingAppExtension` trait extension method
- the private `prepare_view_uniforms` system now has a public system set for scheduling purposes, called `ViewSet::PrepareUniforms`

### Removed

- stages, and all code that mentions stages
- states have been dramatically simplified, and no longer use a stack
- `RunCriteriaLabel`
- `AsSystemLabel` trait
- `on_hierarchy_reports_enabled` run criteria (now just uses an ad hoc resource checking run condition)
- systems in `RenderSet/Stage::Extract` no longer warn when they do not read data from the main world
- `RunCriteriaLabel`
- `transform_propagate_system_set`: this was a nonstandard pattern that didn't actually provide enough control. The systems are already `pub`: the docs have been updated to ensure that the third-party usage is clear.

### Changed

- `System::default_labels` is now `System::default_system_sets`.
- `App::add_default_labels` is now `App::add_default_sets`
- `CoreStage` and `StartupStage` enums are now `CoreSet` and `StartupSet`
- `App::add_system_set` was renamed to `App::add_systems`
- The `StartupSchedule` label is now defined as part of the `CoreSchedules` enum
-  `.label(SystemLabel)` is now referred to as `.in_set(SystemSet)`
- `SystemLabel` trait was replaced by `SystemSet`
- `SystemTypeIdLabel<T>` was replaced by `SystemSetType<T>`
- The `ReportHierarchyIssue` resource now has a public constructor (`new`), and implements `PartialEq`
- Fixed time steps now use a schedule (`CoreSchedule::FixedTimeStep`) rather than a run criteria.
- Adding rendering extraction systems now panics rather than silently failing if no subapp with the `RenderApp` label is found.
- the `calculate_bounds` system, with the `CalculateBounds` label, is now in `CoreSet::Update`, rather than in `CoreSet::PostUpdate` before commands are applied. 
- `SceneSpawnerSystem` now runs under `CoreSet::Update`, rather than `CoreStage::PreUpdate.at_end()`.
- `bevy_pbr::add_clusters` is no longer an exclusive system
- the top level `bevy_ecs::schedule` module was replaced with `bevy_ecs::scheduling`
- `tick_global_task_pools_on_main_thread` is no longer run as an exclusive system. Instead, it has been replaced by `tick_global_task_pools`, which uses a `NonSend` resource to force running on the main thread.

## Migration Guide

- Calls to `.label(MyLabel)` should be replaced with `.in_set(MySet)`
- Stages have been removed. Replace these with system sets, and then add command flushes using the `apply_system_buffers` exclusive system where needed.
- The `CoreStage`, `StartupStage, `RenderStage` and `AssetStage`  enums have been replaced with `CoreSet`, `StartupSet, `RenderSet` and `AssetSet`. The same scheduling guarantees have been preserved.
  - Systems are no longer added to `CoreSet::Update` by default. Add systems manually if this behavior is needed, although you should consider adding your game logic systems to `CoreSchedule::FixedTimestep` instead for more reliable framerate-independent behavior.
  - Similarly, startup systems are no longer part of `StartupSet::Startup` by default. In most cases, this won't matter to you.
  - For example, `add_system_to_stage(CoreStage::PostUpdate, my_system)` should be replaced with 
  - `add_system(my_system.in_set(CoreSet::PostUpdate)`
- When testing systems or otherwise running them in a headless fashion, simply construct and run a schedule using `Schedule::new()` and `World::run_schedule` rather than constructing stages
- Run criteria have been renamed to run conditions. These can now be combined with each other and with states.
- Looping run criteria and state stacks have been removed. Use an exclusive system that runs a schedule if you need this level of control over system control flow.
- For app-level control flow over which schedules get run when (such as for rollback networking), create your own schedule and insert it under the `CoreSchedule::Outer` label.
- Fixed timesteps are now evaluated in a schedule, rather than controlled via run criteria. The `run_fixed_timestep` system runs this schedule between `CoreSet::First` and `CoreSet::PreUpdate` by default.
- Command flush points introduced by `AssetStage` have been removed. If you were relying on these, add them back manually.
- Adding extract systems is now typically done directly on the main app. Make sure the `RenderingAppExtension` trait is in scope, then call `app.add_extract_system(my_system)`.
- the `calculate_bounds` system, with the `CalculateBounds` label, is now in `CoreSet::Update`, rather than in `CoreSet::PostUpdate` before commands are applied. You may need to order your movement systems to occur before this system in order to avoid system order ambiguities in culling behavior.
- the `RenderLabel` `AppLabel` was renamed to `RenderApp` for clarity
- `App::add_state` now takes 0 arguments: the starting state is set based on the `Default` impl.
- Instead of creating `SystemSet` containers for systems that run in stages, simply use `.on_enter::<State::Variant>()` or its `on_exit` or `on_update` siblings.
- `SystemLabel` derives should be replaced with `SystemSet`. You will also need to add the `Debug`, `PartialEq`, `Eq`, and `Hash` traits to satisfy the new trait bounds.
- `with_run_criteria` has been renamed to `run_if`. Run criteria have been renamed to run conditions for clarity, and should now simply return a bool.
- States have been dramatically simplified: there is no longer a "state stack". To queue a transition to the next state, call `NextState::set`

## TODO

- [x] remove dead methods on App and World
- [x] add `App::add_system_to_schedule` and `App::add_systems_to_schedule`
- [x] avoid adding the default system set at inappropriate times
- [x] remove any accidental cycles in the default plugins schedule
- [x] migrate benchmarks
- [x] expose explicit labels for the built-in command flush points
- [x] migrate engine code
- [x] remove all mentions of stages from the docs
- [x] verify docs for States
- [x] fix uses of exclusive systems that use .end / .at_start / .before_commands
- [x] migrate RenderStage and AssetStage
- [x] migrate examples
- [x] ensure that transform propagation is exported in a sufficiently public way (the systems are already pub)
- [x] ensure that on_enter schedules are run at least once before the main app
- [x] re-enable opt-in to execution order ambiguities
- [x] revert change to `update_bounds` to ensure it runs in `PostUpdate`
- [x] test all examples
  - [x] unbreak directional lights
  - [x] unbreak shadows (see 3d_scene, 3d_shape, lighting, transparaency_3d examples)
  - [x] game menu example shows loading screen and menu simultaneously
  - [x] display settings menu is a blank screen
  - [x] `without_winit` example panics
- [x] ensure all tests pass
  - [x] SubApp doc test fails
  - [x] runs_spawn_local tasks fails
  - [x] [Fix panic_when_hierachy_cycle test hanging](https://github.com/alice-i-cecile/bevy/pull/120)

## Points of Difficulty and Controversy

**Reviewers, please give feedback on these and look closely**

1.  Default sets, from the RFC, have been removed. These added a tremendous amount of implicit complexity and result in hard to debug scheduling errors. They're going to be tackled in the form of "base sets" by @cart in a followup.
2. The outer schedule controls which schedule is run when `App::update` is called.
3. I implemented `Label for `Box<dyn Label>` for our label types. This enables us to store schedule labels in concrete form, and then later run them. I ran into the same set of problems when working with one-shot systems. We've previously investigated this pattern in depth, and it does not appear to lead to extra indirection with nested boxes.
4. `SubApp::update` simply runs the default schedule once. This sucks, but this whole API is incomplete and this was the minimal changeset.
5. `time_system` and `tick_global_task_pools_on_main_thread` no longer use exclusive systems to attempt to force scheduling order
6. Implemetnation strategy for fixed timesteps
7. `AssetStage` was migrated to `AssetSet` without reintroducing command flush points. These did not appear to be used, and it's nice to remove these bottlenecks.
8. Migration of `bevy_render/lib.rs` and pipelined rendering. The logic here is unusually tricky, as we have complex scheduling requirements.

## Future Work (ideally before 0.10)

- Rename schedule_v3 module to schedule or scheduling
- Add a derive macro to states, and likely a `EnumIter` trait of some form
- Figure out what exactly to do with the "systems added should basically work by default" problem
- Improve ergonomics for working with fixed timesteps and states
- Polish FixedTime API to match Time
- Rebase and merge #7415
- Resolve all internal ambiguities (blocked on better tools, especially #7442)
- Add "base sets" to replace the removed default sets.
2023-02-06 02:04:50 +00:00
Daniel Chia
52f06175dd Better cascades config defaults + builder, tweak example configs (#7456)
# Objective

- Improve ergonomics / documentation of cascaded shadow maps
- Allow for the customization of the nearest shadowing distance.
- Fixes #7393 
- Fixes #7362 

## Solution

- Introduce `CascadeShadowConfigBuilder`
- Tweak various example cascade settings for better quality.

---

## Changelog

- Made examples look nicer under cascaded shadow maps.
- Introduce `CascadeShadowConfigBuilder` to help with creating `CascadeShadowConfig`

## Migration Guide

- Configure settings for cascaded shadow maps for directional lights using the newly introduced `CascadeShadowConfigBuilder`.

Co-authored-by: Robert Swain <robert.swain@gmail.com>
2023-02-05 08:06:32 +00:00
Aceeri
67826b21d4 Replace RemovedComponents<T> backing with Events<Entity> (#5680)
# Objective
Removal events are unwieldy and require some knowledge of when to put systems that need to catch events for them, it is very easy to end up missing one and end up with memory leak-ish issues where you don't clean up after yourself.

## Solution
Consolidate removals with the benefits of `Events<...>` (such as double buffering and per system ticks for reading the events) and reduce the special casing of it, ideally I was hoping to move the removals to a `Resource` in the world, but that seems a bit more rough to implement/maintain because of double mutable borrowing issues.

This doesn't go the full length of change detection esque removal detection a la https://github.com/bevyengine/rfcs/pull/44.
Just tries to make the current workflow a bit more user friendly so detecting removals isn't such a scheduling nightmare.

---

## Changelog
- RemovedComponents<T> is now backed by an `Events<Entity>` for the benefits of double buffering.

## Migration Guide
- Add a `mut` for `removed: RemovedComponents<T>` since we are now modifying an event reader internally.
- Iterating over removed components now requires `&mut removed_components` or `removed_components.iter()` instead of `&removed_components`.
2023-02-04 20:53:37 +00:00
François
3900b48c88 update winit to 0.28 (#7480)
# Objective

- Update winit to 0.28

## Solution

- Small API change 
- A security advisory has been added for a unmaintained crate used by a dependency of winit build script for wayland

I didn't do anything for Android support in this PR though it should be fixable, it should be done in a separate one, maybe https://github.com/bevyengine/bevy/pull/6830 

---

## Changelog

- `window.always_on_top` has been removed, you can now use `window.window_level`

## Migration Guide

before:
```rust
    app.new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                always_on_top: true,
                ..default()
            }),
            ..default()
        }));
```

after:
```rust
    app.new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                window_level: bevy:🪟:WindowLevel::AlwaysOnTop,
                ..default()
            }),
            ..default()
        }));
```
2023-02-03 16:41:39 +00:00
ickshonpe
fbd569c791 Add width, height and all constructor functions to Size (#7468)
## Objective

A common easy to miss mistake is to write something like:
``` rust
Size::new(Val::Percent(100.), Val::Px(100.));
```

`UiRect` has the `left`, `right`, `all`, `vertical`, etc constructor functions, `Size` is used a lot more frequently but lacks anything similar.

## Solution

Implement `all`, `width` and `height` functions for `Size`.

## Changelog

* Added `all`, `width` and `height` functions to `Size`.
2023-02-02 14:29:39 +00:00
Nicola Papale
6beb4634f6 Cleanup many sprites stress tests (#7436)
Since the new renderer, no frustum culling is applied to 2d components
(be it Sprite or Mesh2d), the stress_tests docs is therefore misleading
and should be updated.

Furthermore, the `many_animated_sprites` example, unlike `many_sprites`
kept vsync enabled, making the stress test less useful than it could be.
We now disable vsync for `many_animated_sprites`.

Also, `many_animated_sprites` didn't have the stress_tests warning
message, instead, it had a paragraph in the module doc. I replaced the
module doc paragraph by the warning message, to be more in line with
other examples.

## Solution

- Remove the paragraph about frustum culling in the `many_sprites`
  and `many_animated_sprites` stress tests
2023-02-01 21:07:11 +00:00
Alice Cecile
5d514fb24f Reduce internal system order ambiguities, and add an example explaining them (#7383)
# Objective

- Bevy should not have any "internal" execution order ambiguities. These clutter the output of user-facing error reporting, and can result in nasty, nondetermistic, very difficult to solve bugs.
- Verifying this currently involves repeated non-trivial manual work. 

## Solution

- [x] add an example to quickly check this
- ~~[ ] ensure that this example panics if there are any unresolved ambiguities~~
- ~~[ ] run the example in CI 😈~~

There's one tricky ambiguity left, between UI and animation. I don't have the tools to fix this without system set configuration, so the remaining work is going to be left to #7267 or another PR after that.

```
2023-01-27T18:38:42.989405Z  INFO bevy_ecs::schedule::ambiguity_detection: Execution order ambiguities detected, you might want to add an explicit dependency relation between some of these systems:
 * Parallel systems:
 -- "bevy_animation::animation_player" and "bevy_ui::flex::flex_node_system"
    conflicts: ["bevy_transform::components::transform::Transform"]
  ```

## Changelog

Resolved internal execution order ambiguities for:
1. Transform propagation (ignored, we need smarter filter checking).
2. Gamepad processing (fixed).
3. bevy_winit's window handling (fixed).
4. Cascaded shadow maps and perspectives (fixed).

Also fixed a desynchronized state bug that could occur when the `Window` component is removed and then added to the same entity in a single frame.
2023-01-31 01:47:00 +00:00
Elabajaba
bfd1d4b0a7 Wgpu 0.15 (#7356)
# Objective

Update Bevy to wgpu 0.15.

## Changelog

- Update to wgpu 0.15, wgpu-hal 0.15.1, and naga 0.11
- Users can now use the [DirectX Shader Compiler](https://github.com/microsoft/DirectXShaderCompiler) (DXC) on Windows with DX12 for faster shader compilation and ShaderModel 6.0+ support (requires `dxcompiler.dll` and `dxil.dll`, which are included in DXC downloads from [here](https://github.com/microsoft/DirectXShaderCompiler/releases/latest))

## Migration Guide

### WGSL Top-Level `let` is now `const`

All top level constants are now declared with `const`, catching up with the wgsl spec.

`let` is no longer allowed at the global scope, only within functions.

```diff
-let SOME_CONSTANT = 12.0;
+const SOME_CONSTANT = 12.0;
```

#### `TextureDescriptor` and `SurfaceConfiguration` now requires a `view_formats` field

The new `view_formats` field in the `TextureDescriptor` is used to specify a list of formats the texture can be re-interpreted to in a texture view. Currently only changing srgb-ness is allowed (ex. `Rgba8Unorm` <=> `Rgba8UnormSrgb`). You should set `view_formats` to `&[]` (empty) unless you have a specific reason not to.

#### The DirectX Shader Compiler (DXC) is now supported on DX12

DXC is now the default shader compiler when using the DX12 backend. DXC is Microsoft's replacement for their legacy FXC compiler, and is faster, less buggy, and allows for modern shader features to be used (ShaderModel 6.0+). DXC requires `dxcompiler.dll` and `dxil.dll` to be available, otherwise it will log a warning and fall back to FXC.

You can get `dxcompiler.dll` and `dxil.dll` by downloading the latest release from [Microsoft's DirectXShaderCompiler github repo](https://github.com/microsoft/DirectXShaderCompiler/releases/latest) and copying them into your project's root directory. These must be included when you distribute your Bevy game/app/etc if you plan on supporting the DX12 backend and are using DXC.

`WgpuSettings` now has a `dx12_shader_compiler` field which can be used to choose between either FXC or DXC (if you pass None for the paths for DXC, it will check for the .dlls in the working directory).
2023-01-29 20:27:30 +00:00
François
3999365bc1 add Input Method Editor support (#7325)
# Objective

- Fix #7315
- Add IME support

## Solution

- Add two new fields to `Window`, to control if IME is enabled and the candidate box position

This allows the use of dead keys which are needed in French, or the full IME experience to type using Pinyin

I also added a basic general text input example that can handle IME input.

https://user-images.githubusercontent.com/8672791/213941353-5ed73a73-5dd1-4e66-a7d6-a69b49694c52.mp4
2023-01-29 20:27:29 +00:00
Marco Buono
1a96d820fd Add Distance and Atmospheric Fog support (#6412)
<img width="1392" alt="image" src="https://user-images.githubusercontent.com/418473/203873533-44c029af-13b7-4740-8ea3-af96bd5867c9.png">
<img width="1392" alt="image" src="https://user-images.githubusercontent.com/418473/203873549-36be7a23-b341-42a2-8a9f-ceea8ac7a2b8.png">


# Objective

- Add support for the “classic” distance fog effect, as well as a more advanced atmospheric fog effect.

## Solution

This PR:

- Introduces a new `FogSettings` component that controls distance fog per-camera. 
- Adds support for three widely used “traditional” fog falloff modes: `Linear`, `Exponential` and `ExponentialSquared`, as well as a more advanced `Atmospheric` fog;
- Adds support for directional light influence over fog color;
- Extracts fog via `ExtractComponent`, then uses a prepare system that sets up a new dynamic uniform struct (`Fog`), similar to other mesh view types;
- Renders fog in PBR material shader, as a final adjustment to the `output_color`, after PBR is computed (but before tone mapping);
- Adds a new `StandardMaterial` flag to enable fog; (`fog_enabled`)
- Adds convenience methods for easier artistic control when creating non-linear fog types;
- Adds documentation around fog.

---

## Changelog

### Added

- Added support for distance-based fog effects for PBR materials, controllable per-camera via the new `FogSettings` component;
- Added `FogFalloff` enum for selecting between three widely used “traditional” fog falloff modes: `Linear`, `Exponential` and `ExponentialSquared`, as well as a more advanced `Atmospheric` fog;
2023-01-29 15:28:56 +00:00
研究社交
adae877be2 Use only one sampler in the array texture example. (#7405)
# Objective

Fixes #7373 

## Solution

Use only one sampler instead of an array of samplers.
2023-01-29 15:08:21 +00:00
ickshonpe
27c4eaae24 UI text layout example (#7359)
## Objective

An example that demonstrates how the `AlignItems` and `JustifyContent` properties can be composed to layout text.

<img width="654" alt="text_layout_example" src="https://user-images.githubusercontent.com/27962798/215116345-daa8ef60-634b-40c6-9b6d-356de3af620c.png">
2023-01-27 19:07:48 +00:00
Chris Ohk
3281aea5c2 Fix minor typos in code and docs (#7378)
# Objective

I found several words in code and docs are incorrect. This should be fixed.

## Solution

- Fix several minor typos

Co-authored-by: Chris Ohk <utilforever@gmail.com>
2023-01-27 12:12:53 +00:00
Rob Parrett
461497fa2d Fix a few uninlined_format_args lints (#7368)
# Objective

Prevent things from breaking tomorrow when rust 1.67 is released.

## Solution

Fix a few `uninlined_format_args` lints in recently introduced code.
2023-01-26 17:34:52 +00:00
研究社交
6b38863313 Request WGPU Capabilities for Non-uniform Indexing (#6995)
# Objective

Fixes #6952 

## Solution

- Request WGPU capabilities `SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING`, `SAMPLER_NON_UNIFORM_INDEXING` and `UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING` when corresponding features are enabled.
- Add an example (`shaders/texture_binding_array`) illustrating (and testing) the use of non-uniform indexed textures and samplers.

![image](https://user-images.githubusercontent.com/16053640/209448310-defa4eae-6bcb-460d-9b3d-a3d2fad4316c.png)

## Changelog

- Added new capabilities for shader validation.
- Added example `shaders/texture_binding_array`.
2023-01-26 13:18:15 +00:00
Daniel Chia
c3a46822e1 Cascaded shadow maps. (#7064)
Co-authored-by: Robert Swain <robert.swain@gmail.com>

# Objective

Implements cascaded shadow maps for directional lights, which produces better quality shadows without needing excessively large shadow maps.

Fixes #3629

Before
![image](https://user-images.githubusercontent.com/1222141/210061203-bbd965a4-8d11-4cec-9a88-67fc59d0819f.png)

After
![image](https://user-images.githubusercontent.com/1222141/210061334-2ff15334-e6d7-4a31-9314-f34a7805cac6.png)


## Solution

Rather than rendering a single shadow map for directional light, the view frustum is divided into a series of cascades, each of which gets its own shadow map. The correct cascade is then sampled for shadow determination.

---

## Changelog

Directional lights now use cascaded shadow maps for improved shadow quality.


## Migration Guide

You no longer have to manually specify a `shadow_projection` for a directional light, and these settings should be removed. If customization of how cascaded shadow maps work is desired, modify the `CascadeShadowConfig` component instead.
2023-01-25 12:35:39 +00:00
Elabajaba
a3baf2ae86 Make the many_foxes plane smaller to fix shadow issues. (#7339)
# Objective

Shadows are broken on many_foxes on AMD GPUs. This seems to be due to rounding or floating point precision issues combined with the absolute unit of a plane that it's currently using.

Related: https://github.com/bevyengine/bevy/issues/6542

I'm not sure if we want to close that issue, as there's still the underlying issue of shadows breaking on overly large planes.

## Solution

Make the plane smaller.
2023-01-23 15:42:08 +00:00
Johan Klokkhammer Helsing
7ebc68bb84 Allow not preventing default event behaviors on wasm (#7304)
# Objective

On wasm, bevy applications currently prevent any of the normal browser hotkeys from working normally (Ctrl+R, F12, F5, Ctrl+F5, tab, etc.).

Some of those events you may want to override, perhaps you can hold the tab key for showing in-game stats?

However, if you want to make a well-behaved game, you probably don't want to needlessly prevent that behavior unless you have a good reason.

Secondary motivation: Also, consider the workaround presented here to get audio working: https://developer.chrome.com/blog/web-audio-autoplay/#moving-forward ; It won't work (for keydown events) if we stop event propagation.

## Solution

- Winit has a field that allows it to not stop event propagation, expose it on the window settings to allow the user to choose the desired behavior. Default to `true` for backwards compatibility.

---

## Changelog

- Added `Window::prevent_default_event_handling` . This allows bevy apps to not override default browser behavior on hotkeys like F5, F12, Ctrl+R etc.
2023-01-22 23:35:32 +00:00
James Liu
a85b740f24 Support recording multiple CommandBuffers in RenderContext (#7248)
# Objective
`RenderContext`, the core abstraction for running the render graph, currently only supports recording one `CommandBuffer` across the entire render graph. This means the entire buffer must be recorded sequentially, usually via the render graph itself. This prevents parallelization and forces users to only encode their commands in the render graph.

## Solution
Allow `RenderContext` to store a `Vec<CommandBuffer>` that it progressively appends to. By default, the context will not have a command encoder, but will create one as soon as either `begin_tracked_render_pass` or the `command_encoder` accesor is first called. `RenderContext::add_command_buffer` allows users to interrupt the current command encoder, flush it to the vec, append a user-provided `CommandBuffer` and reset the command encoder to start a new buffer. Users or the render graph will call `RenderContext::finish` to retrieve the series of buffers for submitting to the queue.

This allows users to encode their own `CommandBuffer`s outside of the render graph, potentially in different threads, and store them in components or resources.

Ideally, in the future, the core pipeline passes can run in `RenderStage::Render` systems and end up saving the completed command buffers to either `Commands` or a field in `RenderPhase`. 

## Alternatives
The alternative is to use to use wgpu's `RenderBundle`s, which can achieve similar results; however it's not universally available (no OpenGL, WebGL, and DX11).

---

## Changelog
Added: `RenderContext::new`
Added: `RenderContext::add_command_buffer`
Added: `RenderContext::finish`
Changed: `RenderContext::render_device` is now private. Use the accessor `RenderContext::render_device()` instead.
Changed: `RenderContext::command_encoder` is now private. Use the accessor `RenderContext::command_encoder()` instead.
Changed: `RenderContext` now supports adding external `CommandBuffer`s for inclusion into the render graphs. These buffers can be encoded outside of the render graph (i.e. in a system).

## Migration Guide
`RenderContext`'s fields are now private. Use the accessors on `RenderContext` instead, and construct it with `RenderContext::new`.
2023-01-22 00:21:55 +00:00
Marco Buono
603cb439d9 Standard Material Blend Modes (#6644)
# Objective

- This PR adds support for blend modes to the PBR `StandardMaterial`.

<img width="1392" alt="Screenshot 2022-11-18 at 20 00 56" src="https://user-images.githubusercontent.com/418473/202820627-0636219a-a1e5-437a-b08b-b08c6856bf9c.png">

<img width="1392" alt="Screenshot 2022-11-18 at 20 01 01" src="https://user-images.githubusercontent.com/418473/202820615-c8d43301-9a57-49c4-bd21-4ae343c3e9ec.png">

## Solution

- The existing `AlphaMode` enum is extended, adding three more modes: `AlphaMode::Premultiplied`, `AlphaMode::Add` and `AlphaMode::Multiply`;
- All new modes are rendered in the existing `Transparent3d` phase;
- The existing mesh flags for alpha mode are reorganized for a more compact/efficient representation, and new values are added;
- `MeshPipelineKey::TRANSPARENT_MAIN_PASS` is refactored into `MeshPipelineKey::BLEND_BITS`.
  -  `AlphaMode::Opaque` and `AlphaMode::Mask(f32)` share a single opaque pipeline key: `MeshPipelineKey::BLEND_OPAQUE`;
  - `Blend`, `Premultiplied` and `Add` share a single premultiplied alpha pipeline key, `MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA`. In the shader, color values are premultiplied accordingly (or not) depending on the blend mode to produce the three different results after PBR/tone mapping/dithering;
  - `Multiply` uses its own independent pipeline key, `MeshPipelineKey::BLEND_MULTIPLY`;
- Example and documentation are provided.
---

## Changelog

### Added

- Added support for additive and multiplicative blend modes in the PBR `StandardMaterial`, via `AlphaMode::Add` and `AlphaMode::Multiply`;
- Added support for premultiplied alpha in the PBR `StandardMaterial`, via `AlphaMode::Premultiplied`;
2023-01-21 21:46:53 +00:00
targrub
ff5e4fd1ec Use Time resource instead of Extracting Time (#7316)
# Objective

- "Fixes #7308".

## Solution

- Use the `Time` `Resource` instead of `Extract<Res<Time>>`
2023-01-21 17:55:39 +00:00
Molot2032
cef56a0d47 Allow users of Text/TextBundle to choose from glyph_brush_layout's BuiltInLineBreaker options. (#7283)
# Objective
Currently, Text always uses the default linebreaking behaviour in glyph_brush_layout `BuiltInLineBreaker::Unicode` which breaks lines at word boundaries. However, glyph_brush_layout also supports breaking lines at any character by setting the linebreaker to `BuiltInLineBreaker::AnyChar`. Having text wrap character-by-character instead of at word boundaries is desirable in some cases - consider that consoles/terminals usually wrap this way.

As a side note, the default Unicode linebreaker does not seem to handle emergency cases, where there is no word boundary on a line to break at. In that case, the text runs out of bounds. Issue #1867 shows an example of this.

## Solution
Basically just copies how TextAlignment is exposed, but for a new enum TextLineBreakBehaviour.
This PR exposes glyph_brush_layout's two simple linebreaking options (Unicode, AnyChar) to users of Text via the enum TextLineBreakBehaviour (which just translates those 2 aforementioned options), plus a method 'with_linebreak_behaviour' on Text and TextBundle. 

## Changelog

Added `Text::with_linebreak_behaviour`
Added `TextBundle::with_linebreak_behaviour` 
`TextPipeline::queue_text` and `GlyphBrush::compute_glyphs` now need a TextLineBreakBehaviour argument, in order to pass through the new field.
Modified the `text2d` example to show both linebreaking behaviours. 


## Example
Here's what the modified example looks like
![image](https://user-images.githubusercontent.com/117271367/213589184-b1a54bf3-116c-4721-8cb6-1cb69edb3070.png)
2023-01-21 00:17:11 +00:00
François
a94830f0c9 break feedback loop when moving cursor (#7298)
# Objective

- Fixes #7294

## Solution

- Do not trigger change detection when setting the cursor position from winit

When moving the cursor continuously, Winit sends events:
- CursorMoved(0)
- CursorMoved(1)
- => start of Bevy schedule execution
- CursorMoved(2)
- CursorMoved(3)
- <= End of Bevy schedule execution

if Bevy schedule runs after the event 1, events 2 and 3 would happen during the execution but would be read only on the next system run. During the execution, the system would detect a change on cursor position, and send back an order to winit to move it back to 1, so event 2 and 3 would be ignored. By bypassing change detection when setting the cursor from winit event, it doesn't trigger sending back that change to winit out of order.
2023-01-21 00:01:28 +00:00
IceSentry
1be3b6d592 fix shader_instancing (#7305)
# Objective

- The changes to the MeshPipeline done for the prepass broke the shader_instancing example. The issue is that the view_layout changes based on if MSAA is enabled or not, but the example hardcoded the view_layout.

## Solution

- Don't overwrite the bind_group_layout of the descriptor since the MeshPipeline already takes care of this in the specialize function.

Closes https://github.com/bevyengine/bevy/issues/7285
2023-01-20 23:10:37 +00:00
Sjael
06ada2e93d Changed Msaa to Enum (#7292)
# Objective

Fixes #6931 

Continues #6954 by squashing `Msaa` to a flat enum

Helps out  #7215 

# Solution
```
pub enum Msaa {
    Off = 1,
    #[default]
    Sample4 = 4,
}
```

# Changelog

- Modified
    - `Msaa` is now enum
    - Defaults to 4 samples
    - Uses `.samples()` method to get the sample number as `u32`

# Migration Guide
```
let multi = Msaa { samples: 4 } 
// is now
let multi = Msaa::Sample4

multi.samples
// is now
multi.samples()
```



Co-authored-by: Sjael <jakeobrien44@gmail.com>
2023-01-20 14:25:21 +00:00
James Liu
dfea88c64d Basic adaptive batching for parallel query iteration (#4777)
# Objective
Fixes #3184. Fixes #6640. Fixes #4798. Using `Query::par_for_each(_mut)` currently requires a `batch_size` parameter, which affects how it chunks up large archetypes and tables into smaller chunks to run in parallel. Tuning this value is difficult, as the performance characteristics entirely depends on the state of the `World` it's being run on. Typically, users will just use a flat constant and just tune it by hand until it performs well in some benchmarks. However, this is both error prone and risks overfitting the tuning on that benchmark.

This PR proposes a naive automatic batch-size computation based on the current state of the `World`.

## Background
`Query::par_for_each(_mut)` schedules a new Task for every archetype or table that it matches. Archetypes/tables larger than the batch size are chunked into smaller tasks. Assuming every entity matched by the query has an identical workload, this makes the worst case scenario involve using a batch size equal to the size of the largest matched archetype or table. Conversely, a batch size of `max {archetype, table} size / thread count * COUNT_PER_THREAD` is likely the sweetspot where the overhead of scheduling tasks is minimized, at least not without grouping small archetypes/tables together.

There is also likely a strict minimum batch size below which the overhead of scheduling these tasks is heavier than running the entire thing single-threaded.

## Solution

- [x] Remove the `batch_size` from `Query(State)::par_for_each`  and friends.
- [x] Add a check to compute `batch_size = max {archeytpe/table} size / thread count  * COUNT_PER_THREAD`
- [x] ~~Panic if thread count is 0.~~ Defer to `for_each` if the thread count is 1 or less.
- [x] Early return if there is no matched table/archetype. 
- [x] Add override option for users have queries that strongly violate the initial assumption that all iterated entities have an equal workload.

---

## Changelog
Changed: `Query::par_for_each(_mut)` has been changed to `Query::par_iter(_mut)` and will now automatically try to produce a batch size for callers based on the current `World` state.

## Migration Guide
The `batch_size` parameter for `Query(State)::par_for_each(_mut)` has been removed. These calls will automatically compute a batch size for you. Remove these parameters from all calls to these functions.

Before:
```rust
fn parallel_system(query: Query<&MyComponent>) {
   query.par_for_each(32, |comp| {
        ...
   });
}
```

After:

```rust
fn parallel_system(query: Query<&MyComponent>) {
   query.par_iter().for_each(|comp| {
        ...
   });
}
```

Co-authored-by: Arnav Choubey <56453634+x-52@users.noreply.github.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: Corey Farwell <coreyf@rwell.org>
Co-authored-by: Aevyrie <aevyrie@gmail.com>
2023-01-20 08:47:20 +00:00
IceSentry
b3224e135b Add depth and normal prepass (#6284)
# Objective

- Add a configurable prepass
- A depth prepass is useful for various shader effects and to reduce overdraw. It can be expansive depending on the scene so it's important to be able to disable it if you don't need any effects that uses it or don't suffer from excessive overdraw.
- The goal is to eventually use it for things like TAA, Ambient Occlusion, SSR and various other techniques that can benefit from having a prepass.

## Solution

The prepass node is inserted before the main pass. It runs for each `Camera3d` with a prepass component (`DepthPrepass`, `NormalPrepass`). The presence of one of those components is used to determine which textures are generated in the prepass. When any prepass is enabled, the depth buffer generated will be used by the main pass to reduce overdraw.

The prepass runs for each `Material` created with the `MaterialPlugin::prepass_enabled` option set to `true`. You can overload the shader used by the prepass by using `Material::prepass_vertex_shader()` and/or `Material::prepass_fragment_shader()`. It will also use the `Material::specialize()` for more advanced use cases. It is enabled by default on all materials.

The prepass works on opaque materials and materials using an alpha mask. Transparent materials are ignored.

The `StandardMaterial` overloads the prepass fragment shader to support alpha mask and normal maps.

---

## Changelog

- Add a new `PrepassNode` that runs before the main pass
- Add a `PrepassPlugin` to extract/prepare/queue the necessary data
- Add a `DepthPrepass` and `NormalPrepass` component to control which textures will be created by the prepass and available in later passes.
- Add a new `prepass_enabled` flag to the `MaterialPlugin` that will control if a material uses the prepass or not.
- Add a new `prepass_enabled` flag to the `PbrPlugin` to control if the StandardMaterial uses the prepass. Currently defaults to false.
- Add `Material::prepass_vertex_shader()` and `Material::prepass_fragment_shader()` to control the prepass from the `Material`

## Notes

In bevy's sample 3d scene, the performance is actually worse when enabling the prepass, but on more complex scenes the performance is generally better. I would like more testing on this, but @DGriffin91 has reported a very noticeable improvements in some scenes.

The prepass is also used by @JMS55 for TAA and GTAO

discord thread: <https://discord.com/channels/691052431525675048/1011624228627419187>

This PR was built on top of the work of multiple people

Co-Authored-By: @superdump 
Co-Authored-By: @robtfm 
Co-Authored-By: @JMS55 

Co-authored-by: Charles <IceSentry@users.noreply.github.com>
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-01-19 22:11:13 +00:00
Aceeri
ddfafab971 Windows as Entities (#5589)
# Objective

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

- Make it easier to open/close/modify windows by setting them up as `Entity`s with a `Window` component.
- Make multiple windows very simple to set up. (just add a `Window` component to an entity and it should open)

## Solution

- Move all properties of window descriptor to ~components~ a component.
- Replace `WindowId` with `Entity`.
- ~Use change detection for components to update backend rather than events/commands. (The `CursorMoved`/`WindowResized`/... events are kept for user convenience.~
  Check each field individually to see what we need to update, events are still kept for user convenience.

---

## Changelog

- `WindowDescriptor` renamed to `Window`.
    - Width/height consolidated into a `WindowResolution` component.
    - Requesting maximization/minimization is done on the [`Window::state`] field.
- `WindowId` is now `Entity`.

## Migration Guide

- Replace `WindowDescriptor` with `Window`.
    - Change `width` and `height` fields in a `WindowResolution`, either by doing
      ```rust
      WindowResolution::new(width, height) // Explicitly
      // or using From<_> for tuples for convenience
      (1920., 1080.).into()
      ```
- Replace any `WindowCommand` code to just modify the `Window`'s fields directly  and creating/closing windows is now by spawning/despawning an entity with a `Window` component like so:
  ```rust
  let window = commands.spawn(Window { ... }).id(); // open window
  commands.entity(window).despawn(); // close window
  ```

## Unresolved
- ~How do we tell when a window is minimized by a user?~
  ~Currently using the `Resize(0, 0)` as an indicator of minimization.~
  No longer attempting to tell given how finnicky this was across platforms, now the user can only request that a window be maximized/minimized.
  
 ## Future work
 - Move `exit_on_close` functionality out from windowing and into app(?)
 - https://github.com/bevyengine/bevy/issues/5621
 - https://github.com/bevyengine/bevy/issues/7099
 - https://github.com/bevyengine/bevy/issues/7098


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-01-19 00:38:28 +00:00
Stephen Martindale
f0c504947c Docs: App::run() might never return; effect of WinitSettings::return_from_run. (#7228)
# Objective

See:

- https://github.com/bevyengine/bevy/issues/7067#issuecomment-1381982285
  - (This does not fully close that issue in my opinion.)
- https://discord.com/channels/691052431525675048/1063454009769340989

## Solution

This merge request adds documentation:

1. Alert users to the fact that `App::run()` might never return and code placed after it might never be executed.
2. Makes `winit::WinitSettings::return_from_run` discoverable.
3. Better explains why `winit::WinitSettings::return_from_run` is discouraged and better links to up-stream docs. on that topic.
4. Adds notes to the `app/return_after_run.rs` example which otherwise promotes a feature that carries caveats.

Furthermore, w.r.t `winit::WinitSettings::return_from_run`:

- Broken links to `winit` docs are fixed.
- Links now point to BOTH `EventLoop::run()` and `EventLoopExtRunReturn::run_return()` which are the salient up-stream pages and make more sense, taken together.
- Collateral damage: "Supported platforms" heading; disambiguation of "run" → `App::run()`; links.
   
## Future Work

I deliberately structured the "`run()` might not return" section under `App::run()` to allow for alternative patterns (e.g. `AppExit` event, `WindowClosed` event) to be listed or mentioned, beneath it, in the future.
2023-01-18 23:02:38 +00:00
ickshonpe
9eefd7c022 Remove VerticalAlign from TextAlignment (#6807)
# Objective

Remove the `VerticalAlign` enum.

Text's alignment field should only affect the text's internal text alignment, not its position. The only way to control a `TextBundle`'s position and bounds should be through the manipulation of the constraints in the `Style` components of the nodes in the Bevy UI's layout tree.

 `Text2dBundle` should have a separate `Anchor` component that sets its position relative to its transform.

Related issues: #676, #1490, #5502, #5513, #5834, #6717, #6724, #6741, #6748

## Changelog
* Changed `TextAlignment` into an enum with `Left`, `Center`, and `Right` variants.
* Removed the `HorizontalAlign` and `VerticalAlign` types.
* Added an `Anchor` component to `Text2dBundle`
* Added `Component` derive to `Anchor`
* Use `f32::INFINITY` instead of `f32::MAX` to represent unbounded text in Text2dBounds

## Migration Guide
The `alignment` field of `Text` now only affects the text's internal alignment.

### Change `TextAlignment` to TextAlignment` which is now an enum. Replace:
  * `TextAlignment::TOP_LEFT`, `TextAlignment::CENTER_LEFT`, `TextAlignment::BOTTOM_LEFT` with `TextAlignment::Left`
  * `TextAlignment::TOP_CENTER`, `TextAlignment::CENTER_LEFT`, `TextAlignment::BOTTOM_CENTER` with `TextAlignment::Center`
  * `TextAlignment::TOP_RIGHT`, `TextAlignment::CENTER_RIGHT`, `TextAlignment::BOTTOM_RIGHT` with `TextAlignment::Right`

### Changes for `Text2dBundle`
`Text2dBundle` has a new field 'text_anchor' that takes an `Anchor` component that controls its position relative to its transform.
2023-01-18 02:19:17 +00:00
dis-da-moe
0df67cdaae Add AddAudioSource trait and improve Decodable docs (#6649)
# Objective

- Fixes #6361
- Fixes #6362 
- Fixes #6364 

## Solution
- Added an example for creating a custom `Decodable` type 
- Clarified the documentation on `Decodable`
- Added an `AddAudioSource` trait and implemented it for `App`

Co-authored-by: dis-da-moe <84386186+dis-da-moe@users.noreply.github.com>
2023-01-17 22:42:00 +00:00
ira
5fd628ebd3 Fix Alien Cake Addict example despawn warnings (#7236)
# Problem
The example's `teardown` system despawns all entities besides the camera using `despawn_recursive` causing it to despawn child entities multiple times which logs a warning.
![image](https://user-images.githubusercontent.com/29694403/212756554-06b3fa42-ddcb-4a05-b841-f587488a10fc.png)

# Solution
Use `despawn` instead.

Co-authored-by: Devil Ira <justthecooldude@gmail.com>
2023-01-16 20:20:37 +00:00
Dawid Piotrowski
a792f37040 Relative cursor position (#7199)
# Objective

Add useful information about cursor position relative to a UI node. Fixes #7079.

## Solution

- Added a new `RelativeCursorPosition` component

---

## Changelog

- Added
  - `RelativeCursorPosition`
  - an example showcasing the new component

Co-authored-by: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com>
2023-01-16 17:17:45 +00:00
Daniel Chia
517deda215 Make PipelineCache internally mutable. (#7205)
# Objective

- Allow rendering queue systems to use a `Res<PipelineCache>` even for queueing up new rendering pipelines. This is part of unblocking parallel execution queue systems.

## Solution

- Make `PipelineCache` internally mutable w.r.t to queueing new pipelines. Pipelines are no longer immediately updated into the cache state, but rather queued into a Vec. The Vec of pending new pipelines is then later processed at the same time we actually create the queued pipelines on the GPU device.

---

## Changelog

`PipelineCache` no longer requires mutable access in order to queue render / compute pipelines.

## Migration Guide

* Most usages of `resource_mut::<PipelineCache>` and `ResMut<PipelineCache>` can be changed to `resource::<PipelineCache>` and `Res<PipelineCache>` as long as they don't use any methods requiring mutability - the only public method requiring it is `process_queue`.
2023-01-16 15:41:14 +00:00
张林伟
0d2cdb450d Fix beta clippy lints (#7154)
# Objective

- When I run `cargo run -p ci` for my pr locally using latest beta toolchain, the ci failed due to [uninlined_format_args](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args) and [needless_lifetimes](https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes) lints

## Solution

- Fix lints according to clippy suggestions.
2023-01-11 09:51:22 +00:00
Nicola Papale
3600c5a340 Remove the GlobalTransform::translation_mut method (#7134)
# Objective

It is possible to manually update `GlobalTransform`.
The engine actually assumes this is not possible.
For example, `propagate_transform` does not update children
of an `Entity` which **`GlobalTransform`** changed,
leading to unexpected behaviors.

A `GlobalTransform` set by the user may also be blindly
overwritten by the propagation system.

## Solution

- Remove `translation_mut`
- Explain to users that they shouldn't manually update the `GlobalTransform`
- Remove `global_vs_local.rs` example, since it misleads users
  in believing that it is a valid use-case to manually update the
  `GlobalTransform`

---

## Changelog

- Remove `GlobalTransform::translation_mut`

## Migration Guide

`GlobalTransform::translation_mut` has been removed without alternative,
if you were relying on this, update the `Transform` instead. If the given entity
had children or parent, you may need to remove its parent to make its transform
independent (in which case the new `Commands::set_parent_in_place` and
`Commands::remove_parent_in_place` may be of interest)

Bevy may add in the future a way to toggle transform propagation on
an entity basis.
2023-01-10 18:55:22 +00:00
DevinLeamy
e94215c4c6 Gamepad events refactor (#6965)
# Objective 

- Remove redundant gamepad events
- Simplify consuming gamepad events.
- Refactor: Separate handling of gamepad events into multiple systems.

## Solution

- Removed `GamepadEventRaw`, and `GamepadEventType`.
- Added bespoke `GamepadConnectionEvent`, `GamepadAxisChangedEvent`, and `GamepadButtonChangedEvent`. 
- Refactored `gamepad_event_system`.
- Added `gamepad_button_event_system`, `gamepad_axis_event_system`, and `gamepad_connection_system`, which update the `Input` and `Axis` resources using their corresponding event type.

Gamepad events are now handled in their own systems and have their own types. 

This allows for querying for gamepad events without having to match on `GamepadEventType` and makes creating handlers for specific gamepad event types, like a `GamepadConnectionEvent` or `GamepadButtonChangedEvent` possible.

We remove `GamepadEventRaw` by filtering the gamepad events, using `GamepadSettings`, _at the source_, in `bevy_gilrs`. This way we can create `GamepadEvent`s directly and avoid creating `GamepadEventRaw` which do not pass the user defined filters. 

We expose ordered `GamepadEvent`s and we can respond to individual gamepad event types.

## Migration Guide

- Replace `GamepadEvent` and `GamepadEventRaw` types with their specific gamepad event type.
2023-01-09 19:24:52 +00:00
Sebastian Meßmer
fa15b31930 Smooth Transition between Animations (#6922)
# Objective

- Fixes https://github.com/bevyengine/bevy/discussions/6338

This PR allows for smooth transitions between different animations.

## Solution

- This PR uses very simple linear blending of animations.
- When starting a new animation, you can give it a duration, and throughout that duration, the previous and the new animation are being linearly blended, until only the new animation is running.
- I'm aware of https://github.com/bevyengine/rfcs/pull/49 and https://github.com/bevyengine/rfcs/pull/51, which are more complete solutions to this problem, but they seem still far from being implemented. Until they're ready, this PR allows for the most basic use case of blending, i.e. smoothly transitioning between different animations.

## Migration Guide

- no bc breaking changes
2023-01-09 19:24:51 +00:00
Rob Parrett
3dd8b42f72 Fix various typos (#7096)
I stumbled across a typo in some docs. Fixed some more while I was in there.
2023-01-06 00:43:30 +00:00
targrub
329b71fa62 Break CorePlugin into TaskPoolPlugin, TypeRegistrationPlugin, FrameCountPlugin. (#7083)
# Objective

- Fixes #7081.

## Solution

- Moved functionality from kitchen sink plugin `CorePlugin` to separate plugins, `TaskPoolPlugin`, `TypeRegistrationPlugin`, `FrameCountPlugin`.  `TaskPoolOptions` resource should now be used with `TaskPoolPlugin`.

## Changelog

Minimal changes made (code kept in `bevy_core/lib.rs`).

## Migration Guide

- `CorePlugin` broken into separate plugins.  If not using `DefaultPlugins` or `MinimalPlugins` `PluginGroup`s, the replacement for `CorePlugin` is now to add `TaskPoolPlugin`, `TypeRegistrationPlugin`, and `FrameCountPlugin` to the app.

## Notes

- Consistent with Bevy goal "modularity over deep integration" but the functionality of `TypeRegistrationPlugin` and `FrameCountPlugin` is weak (the code has to go somewhere, though!).
- No additional tests written.
2023-01-05 11:42:35 +00:00
Matthias Schiffer
85743ce49e asset: make HandleUntyped::id private (#7076)
# Objective

It is currently possible to break reference counting for assets by creating a strong `HandleUntyped` and then modifying the `id` field before dropping the handle. This should not be allowed.

## Solution

Change the `id` field visibility to private and add a getter instead. The same change was previously done for `Handle<T>` in #6176, but `HandleUntyped` was forgotten.

---

## Migration Guide

- Instead of directly accessing the ID of a `HandleUntyped` as `handle.id`, use the new getter `handle.id()`.
2023-01-04 23:40:43 +00:00
Anton Pushkarev
4fff0ce837 Add a more familiar hex color entry (#7060)
# Objective

- When using `Color::hex` for the first time, I was confused by the fact that I can't specify colors using #, which is much more familiar.
- In the code editor (if there is support) there is a preview of the color, which is very convenient.
![Снимок экрана от 2022-12-30 02-54-00](https://user-images.githubusercontent.com/69102503/209990973-f6fc3bc6-08f6-4e51-a9a9-1de8a675c82d.png)

## Solution

- Allow you to enter colors like `#ff33f2` and use the `.strip_prefix` method to delete the `#` character.
2023-01-04 23:40:42 +00:00
James Liu
2d727afaf7 Flatten render commands (#6885)
# Objective
Speed up the render phase of rendering. Simplify the trait structure for render commands.

## Solution

 - Merge `EntityPhaseItem` into `PhaseItem` (`EntityPhaseItem::entity` -> `PhaseItem::entity`)
 - Merge `EntityRenderCommand` into `RenderCommand`.
 - Add two associated types to `RenderCommand`: `RenderCommand::ViewWorldQuery` and `RenderCommand::WorldQuery`.
 - Use the new associated types to construct two `QueryStates`s for `RenderCommandState`.
 - Hoist any `SQuery<T>` fetches in `EntityRenderCommand`s into the aformentioned two queries. Batch fetch them all at once.

## Performance
`main_opaque_pass_3d` is slightly faster on `many_foxes` (427.52us -> 401.15us)

![image](https://user-images.githubusercontent.com/3137680/206359804-9928b20a-7d92-41f8-bf7d-6e8c5cc802f0.png)

The shadow pass node is also slightly faster (344.52 -> 338.24us)

![image](https://user-images.githubusercontent.com/3137680/206359977-1212198d-f933-49a0-80f1-62ff88eb5727.png)

## Future Work

 - Can we hoist the view level queries out of the core loop?

---

## Changelog
Added: `PhaseItem::entity`
Added: `RenderCommand::ViewWorldQuery` associated type.
Added: `RenderCommand::ItemorldQuery` associated type.
Added: `Draw<T>::prepare` optional trait function.
Removed: `EntityPhaseItem` trait

## Migration Guide
TODO
2023-01-04 01:13:30 +00:00
l1npengtul
290d6363b8 add system information plugin and update relevant examples (#5911)
# Objective
Solve #5464 

## Solution
Adds a `SystemInformationDiagnosticsPlugin` to add diagnostics.

Adds `Cargo.toml` flags to fix building on different platforms. 

---

## Changelog

Adds `sysinfo` crate to `bevy-diagnostics`. 

Changes in import order are due to clippy.

Co-authored-by: l1npengtul <35755164+l1npengtul@users.noreply.github.com>
Co-authored-by: IceSentry <c.giguere42@gmail.com>
2023-01-02 20:49:43 +00:00
Predko Silvestr
2665299d1c Use ``bevy`` with default features in iOS example (#7042)
# Objective

I am new to Bevy. And during my development, I noticed that the `iOS` example doesn't work.
Example panics with next message: ```panicked at 'Resource requested by bevy_ui::widget::text::text_system does not exist: bevy_asset::assets::Assets```.

I have asked for help in a `discord` iOS chat and there I receive a recommendation that it is possible that some bevy features missing.

## Solution

So, I used ```bevy``` with default features.
2022-12-28 17:09:35 +00:00
Aceeri
5566d73d9e Nicer usage for scene viewer (#7035)
# Objective
Scene viewer mouse sensitivity/cursor usage isn't the best it could be atm, so just adding some quick, maybe opinionated, tweaks to make it feel more at home in usage.

## Solution
- Mouse delta shouldn't be affected by delta time, it should be more expected that if I move my mouse 1 inch to the right that it should move the in game camera/whatever is controlled the same regardless of FPS.
- Uses a magic number of 180.0 for a nice default sensitivity, modeled after Valorant's default sensitivity.
- Cursor now gets locked/hidden when rotating the camera to give it more of the effect that you are grabbing the camera.
2022-12-27 00:34:06 +00:00
Aceeri
8ad9a7c7c4 Rename camera "priority" to "order" (#6908)
# Objective
The documentation for camera priority is very confusing at the moment, it requires a bit of "double negative" kind of thinking.

# Solution
Flipping the wording on the documentation to reflect more common usecases like having an overlay camera and also renaming it to "order", since priority implies that it will override the other camera rather than have both run.
2022-12-25 00:39:30 +00:00
ickk
a0448eca2f enum Visibility component (#6320)
Consolidation of all the feedback about #6271 as well as the addition of an "unconditionally visible" mode.

# Objective

The current implementation of the `Visibility` struct simply wraps a boolean.. which seems like an odd pattern when rust has such nice enums that allow for more expression using pattern-matching. 

Additionally as it stands Bevy only has two settings for visibility of an entity: 
- "unconditionally hidden" `Visibility { is_visible: false }`, 
- "inherit visibility from parent" `Visibility { is_visible: true }`
   where a root level entity set to "inherit" is visible. 

Note that given the behaviour, the current naming of the inner field is a little deceptive or unclear.

Using an enum for `Visibility` opens the door for adding an extra behaviour mode. This PR adds a new "unconditionally visible" mode, which causes an entity to be visible even if its Parent entity is hidden. There should not really be any performance cost to the addition of this new mode.

--
The recently added `toggle` method is removed in this PR, as its semantics could be confusing with 3 variants.

## Solution

Change the Visibility component into
```rust
enum Visibility {
  Hidden,    // unconditionally hidden
  Visible,   // unconditionally visible
  Inherited, // inherit visibility from parent
}
```

---

## Changelog

### Changed

`Visibility` is now an enum

## Migration Guide

- evaluation of the `visibility.is_visible` field should now check for `visibility == Visibility::Inherited`.
- setting the `visibility.is_visible` field should now directly set the value: `*visibility = Visibility::Inherited`.
- usage of `Visibility::VISIBLE` or `Visibility::INVISIBLE` should now use `Visibility::Inherited` or `Visibility::Hidden` respectively.
- `ComputedVisibility::INVISIBLE` and `SpatialBundle::VISIBLE_IDENTITY` have been renamed to `ComputedVisibility::HIDDEN` and `SpatialBundle::INHERITED_IDENTITY` respectively.






Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-12-25 00:39:29 +00:00
Taras Palczynski III
c7791ad9b3 Organized scene_viewer into plugins for reuse and organization (#6936)
# Objective

This PR reorganizes majority of the scene viewer example into a module of plugins which then allows reuse of functionality among new or existing examples.  In addition, this enables the scene viewer to be more succinct and showcase the distinct cases of camera control and scene control.

This work is to support future work in organization and future examples.  A more complicated 3D scene example has been requested by the community (#6551) which requests functionality currently included in scene_viewer, but previously inaccessible.  The future example can now just utilize the two plugins created here.  The existing example [animated_fox example] can utilize the scene creation and animation control functionality of `SceneViewerPlugin`.

## Solution

- Created a `scene_viewer` module inside the `tools` example folder.
- Created two plugins:  `SceneViewerPlugin` (gltf scene loading, animation control, camera tracking control, light control) and `CameraControllerPlugin` (controllable camera).
- Original `scene_viewer.rs` moved to `scene_viewer/main.rs` and now utilizes the two plugins.
2022-12-25 00:23:13 +00:00
ira
15b19b930c Move 'startup' Resource WgpuSettings into the RenderPlugin (#6946)
# Objective
The `WgpuSettings` resource is only used during plugin build. Move it into the `RenderPlugin` struct.

Changing these settings requires re-initializing the render context, which is currently not supported.
If it is supported in the future it should probably be more explicit than changing a field on a resource, maybe something similar to the `CreateWindow` event.

## Migration Guide
```rust
// Before (0.9)
App::new()
    .insert_resource(WgpuSettings { .. })
    .add_plugins(DefaultPlugins)
// After (0.10)
App::new()
    .add_plugins(DefaultPlugins.set(RenderPlugin {
        wgpu_settings: WgpuSettings { .. },
    }))
```

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-12-20 16:17:11 +00:00
James Liu
5b8b7dc08f Add a stress test profile (#6901)
# Objective
This adds a custom profile for testing against stress tests. Bevy seemingly gets notably faster with LTO turned on. To more accurately depict production level performance, LTO and other rustc-level optimizations should be enabled when performance testing on stress tests.

Also updated the stress test docs to reflect that users should be using it.
2022-12-20 15:59:41 +00:00
Jonah Henriksson
38d567d2c5 Make AsBindGroup unsized (#6937)
# Objective

`AsBindGroup` can't be used as a trait object because of the constraint `Sized` and because of the associated function.

This is a problem for [`bevy_atmosphere`](https://github.com/JonahPlusPlus/bevy_atmosphere) because it needs to use a trait that depends on `AsBindGroup` as a trait object, for switching out different shaders at runtime. The current solution it employs is reimplementing the trait and derive macro into that trait, instead of constraining to `AsBindGroup`.

## Solution

Remove the `Sized` constraint from `AsBindGroup` and add the constraint `where Self: Sized` to the associated function `bind_group_layout`. Also change `PreparedBindGroup<T: AsBindGroup>` to `PreparedBindGroup<T>` and use it as `PreparedBindGroup<Self::Data>` instead of `PreparedBindGroup<Self>`.

This weakens the constraints, but increases the flexibility of `AsBindGroup`.
I'm not entirely sure why the `Sized` constraint was there, because it worked fine without it (maybe @cart wasn't aware of use cases for `AsBindGroup` as a trait object or this was just leftover from legacy code?).

---

## Changelog

- `AsBindGroup` can be used as a trait object.
2022-12-16 01:40:15 +00:00
Rob Parrett
ec0478d100 Fix clippy lints and failed test with Rust 1.66 (#6945)
# Objective

[Rust 1.66](https://blog.rust-lang.org/inside-rust/2022/12/12/1.66.0-prerelease.html) is coming in a few days, and bevy doesn't build with it.

Fix that.

## Solution

Replace output from a trybuild test, and fix a few new instances of `needless_borrow` and `unnecessary_cast` that are now caught.

## Note

Due to the trybuild test, this can't be merged until 1.66 is released.
2022-12-15 18:05:15 +00:00
Zoey
4820917af6 Add set_if_neq method to DetectChanges trait (Rebased) (#6853)
# Objective

Change detection can be spuriously triggered by setting a field to the same value as before. As a result, a common pattern is to write:

```rust
if *foo != value {
  *foo = value;
}
```

This is confusing to read, and heavy on boilerplate.

Adopted from #5373, but untangled and rebased to current `bevy/main`.

## Solution

    1. Add a method to the `DetectChanges` trait that implements this boilerplate when the appropriate trait bounds are met.

    2. Document this minor footgun, and point users to it.


## Changelog

    * added the `set_if_neq` method to avoid triggering change detection when the new and previous values are equal. This will work on both components and resources.


## Migration Guide

If you are manually checking if a component or resource's value is equal to its new value before setting it to avoid triggering change detection, migrate to the clearer and more convenient `set_if_neq` method.
## Context

Related to #2363 as it avoids triggering change detection, but not a complete solution (as it still requires triggering it when real changes are made).



Co-authored-by: Zoey <Dessix@Dessix.net>
2022-12-11 19:24:19 +00:00
Hennadii Chernyshchyk
544776831d Remove render feature group (#6912)
# Objective

The feature doesn't have any use case in libraries or applications and many users use this feature incorrectly. See the issue for details.
Closes #5753.

## Solution

Remove it.

---

## Changelog

### Removed

- `render` feature group. 

## Migration Guide

Instead of using `render` feature group use dependencies directly. This group consisted of `bevy_core_pipeline`, `bevy_pbr`, `bevy_gltf`, `bevy_render`, `bevy_sprite`, `bevy_text` and `bevy_ui`. You probably want to check if you need all of them.
2022-12-11 18:46:46 +00:00
François
f4818bcd69 scene viewer: can select a scene from the asset path (#6859)
# Objective

- Fixes #6630, fixes #6679
- Improve scene viewer in cases where there are more than one scene in a gltf file

## Solution

- Can select which scene to display using `#SceneN`, defaults to scene 0 if not present
- Display the number of scenes available if there are more than one
2022-12-11 18:46:41 +00:00
Alejandro Pascual
95c0d99e45 Sprite sheet example: specify animation indices (#6861)
# Objective

- Make running animation fluid skipping 'idle' frame.

## Solution

- Loop through the specified indices instead of through the whole sprite sheet.

The example is correct, is just the feeling that the animation loop is not seamless.

Based on the solution suggested by @mockersf in #5429.
2022-12-11 18:22:10 +00:00
Jay Pavlina
2e7925d8d0 Add cylinder shape (#6809)
# Objective

Adds a cylinder shape. Fixes #2282.

## Solution

- I added a custom cylinder shape, taken from [here](https://github.com/rparrett/typey_birb/blob/main/src/cylinder.rs) with permission from @rparrett.
- I also added the cylinder shape to the `3d_shapes` example scene.

---

## Changelog

- Added cylinder shape

Co-Authored-By: Rob Parrett <robparrett@gmail.com>
Co-Authored-By: davidhof <7483215+davidhof@users.noreply.github.com>
2022-12-11 18:22:05 +00:00
Edvin Kjell
aea4c5b1a4 [Fixes #6224] Add logging variants of system piping (#6751)
# Objective

Fixes #6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand #5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error.

## Solution

* Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``. 
* Modified and added tests for these under examples in ``system_piping.rs``.
2022-12-11 18:10:03 +00:00
Vladyslav Batyrenko
b337ed63ad Borrow instead of consuming in EventReader::clear (#6851)
The PR fixes the interface of `EventReader::clear`. Currently, the method consumes the reader, which makes it unusable.

## Changelog

- `EventReader::clear` now takes a mutable reference instead of consuming the event reader. 

## Migration Guide

`EventReader::clear` now takes a mutable reference instead of consuming the event reader. This means that `clear` now needs explicit mutable access to the reader variable, which previously could have been omitted in some cases:

```rust
// Old (0.9)
fn clear_events(reader: EventReader<SomeEvent>) {
  reader.clear();
}

// New (0.10)
fn clear_events(mut reader: EventReader<SomeEvent>) {
  reader.clear();
}
``` 

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-12-05 23:07:20 +00:00
罗智芃
e89b043210 Fix material alpha_mode in example global_vs_local_translation (#6658)
# Objective

The global_vs_local_translation example tries to use transparency to identify static cubes, but the materials of those cubes aren't transparent.

## Solution

Change material alpha_mode to  `AlphaMode::Blend` for those cubes.
2022-12-01 15:19:54 +00:00
IceSentry
f119d9df8e Add DrawFunctionsInternals::id() (#6745)
# Objective

- Every usage of `DrawFunctionsInternals::get_id()` was followed by a `.unwrap()`. which just adds boilerplate.

## Solution

- Introduce a fallible version of `DrawFunctionsInternals::get_id()` and use it where possible.
- I also took the opportunity to improve the error message a little in the case where it fails.

---

## Changelog

- Added `DrawFunctionsInternals::id()`
2022-11-28 13:54:13 +00:00
François
056272413f Move Android example to its own package (#6759)
# Objective

- Fix CI issue with updated `cargo-app`

## Solution

- Move the Android example to its own package. It's not necessary for the CI fix, but it's cleaner, mimic the iOS example, and easier to reuse for someone wanting to setup android support in their project
- Build the package in CI instead of the example


The Android example is still working on my android device with this change 👍
2022-11-25 23:02:56 +00:00
François
d44e86507f Shader defs can now have a value (#5900)
# Objective

- shaders defs can now have a `bool` or `int` value
- `#if SHADER_DEF <operator> 3`
  - ok if `SHADER_DEF` is defined, has the correct type and pass the comparison
  - `==`, `!=`, `>=`, `>`, `<`, `<=` supported
- `#SHADER_DEF` or `#{SHADER_DEF}`
  - will be replaced by the value in the shader code
---

## Migration Guide

- replace `shader_defs.push(String::from("NAME"));` by `shader_defs.push("NAME".into());`
- if you used shader def `NO_STORAGE_BUFFERS_SUPPORT`, check how `AVAILABLE_STORAGE_BUFFER_BINDINGS` is now used in Bevy default shaders
2022-11-21 22:38:29 +00:00
Torstein Grindvik
daa57fe489 Add try_* to add_slot_edge, add_node_edge (#6720)
# Objective

`add_node_edge` and `add_slot_edge` are fallible methods, but are always used with `.unwrap()`.
`input_node` is often unwrapped as well.
This points to having an infallible behaviour as default, with an alternative fallible variant if needed.

Improves readability and ergonomics.

## Solution

- Change `add_node_edge` and `add_slot_edge` to panic on error.
- Change `input_node` to panic on `None`.
- Add `try_add_node_edge` and `try_add_slot_edge` in case fallible methods are needed.
- Add `get_input_node` to still be able to get an `Option`.
---

## Changelog

### Added

- `try_add_node_edge`
- `try_add_slot_edge`
- `get_input_node`

### Changed

- `add_node_edge` is now infallible (panics on error)
- `add_slot_edge` is now infallible (panics on error)
- `input_node` now panics on `None`

## Migration Guide

Remove `.unwrap()` from `add_node_edge` and `add_slot_edge`.
For cases where the error was handled, use `try_add_node_edge` and `try_add_slot_edge` instead.

Remove `.unwrap()` from `input_node`.
For cases where the option was handled, use `get_input_node` instead.


Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
2022-11-21 21:58:39 +00:00
Chia-Hsiang Cheng
585dac0582 Remove auto-margin properties from the examples (#6535)
# Objective

Fixes #6498.

## Solution

Adding a parent node with properties AlignItems::Center and JustifyContent::Center to centered child nodes and removing their auto-margin properties.
2022-11-21 14:38:35 +00:00
Torstein Grindvik
174819be83 ExtractComponent output optional associated type (#6699)
# Objective

Allow more use cases where the user may benefit from both `ExtractComponentPlugin` _and_ `UniformComponentPlugin`.

## Solution

Add an associated type to `ExtractComponent` in order to allow specifying the output component (or bundle).

Make `extract_component` return an `Option<_>` such that components can be extracted only when needed.

What problem does this solve?

`ExtractComponentPlugin` allows extracting components, but currently the output type is the same as the input.
This means that use cases such as having a settings struct which turns into a uniform is awkward.

For example we might have:

```rust
struct MyStruct {
    enabled: bool,
    val: f32
}

struct MyStructUniform {
    val: f32
}
```

With the new approach, we can extract `MyStruct` only when it is enabled, and turn it into its related uniform.

This chains well with `UniformComponentPlugin`.

The user may then:

```rust
app.add_plugin(ExtractComponentPlugin::<MyStruct>::default());
app.add_plugin(UniformComponentPlugin::<MyStructUniform>::default());
```

This then saves the user a fair amount of boilerplate.


## Changelog

### Changed

- `ExtractComponent` can specify output type, and outputting is optional.



Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
2022-11-21 13:19:44 +00:00
Jer
b3e45b75d6 Expose set_cursor_hittest() from winit (#6664)
# Objective

- Bevy should be usable to create 'overlay' type apps, where the input is not captured by Bevy, but passed down/into a target app, or to allow passive displays/widgets etc.
 
## Solution

- the `winit:🪟:Window` already has a `set_cursor_hittest()` which basically does this for mouse input events, so I've exposed it (trying to copy the style laid out in the existing wrappings, and added a simple demo.

---

## Changelog

- Added `hittest` to `WindowAttributes`
- Added the `hittest`'s setters/getters
- Modified the `WindowBuilder`
- Modifed the `WindowDescriptor`'s `Default` impl.
- Added an example `cargo run --example fallthrough`
2022-11-21 12:59:10 +00:00
Doru
a02e44c0db Don't kill contributors on window squish (#6675)
# Objective

- The `contributors` example panics when attempting to generate an empty range if the window height is smaller than the sprites
- Don't do that

## Solution

- Clamp the bounce height to be 0 minimum, and generate an inclusive range when passing it to `rng.gen_range`
2022-11-18 11:24:07 +00:00
Hsiang-Cheng Yang
eaa35cf99f use Mul<f32> to double the value of Vec3 (#6607)
improve the example code
2022-11-14 23:08:30 +00:00
laundmo
635320f172 Expose winit always_on_top (#6527)
# Objective

I needed a window which is always on top, to create a overlay app.

## Solution

expose the `always_on_top` property of winit in bevy's `WindowDescriptor` as a boolean flag

---

## Changelog

### Added
- add `WindowDescriptor.always_on_top` which configures a window to stay on top.
2022-11-14 22:34:29 +00:00
2ne1ugly
db0d7698e2 Change From<Icosphere> to TryFrom<Icosphere> (#6484)
# Objective

- Fixes  #6476

## Solution

- Return error instead of panic through `TryFrom`
- ~~Add `.except()` in examples~~ 
- Add `.unwrap()` in examples
2022-11-14 22:34:27 +00:00
Jakub Arnold
4de4e54755 Update post_processing example to not render UI with first pass camera (#6469)
# Objective

Make sure the post processing example won't render UI twice.

## Solution

Disable UI on the first pass camera with `UiCameraConfig`
2022-11-14 22:34:26 +00:00
Yyee
dc09ee36e2 Add pixelated Bevy to assets and an example (#6408)
# Objective
Fixes #2279 

## Solution
Added pixelated Bevy to assets folder and used in a `pixel_perfect` example.
2022-11-14 22:15:46 +00:00
ickshonpe
5f1261110f Flip UI image (#6292)
# Objective
Fixes  #3225, Allow for flippable UI Images

## Solution
Add flip_x and flip_y fields to UiImage, and swap the UV coordinates accordingly in ui_prepare_nodes.

## Changelog
* Changes UiImage to a struct with texture, flip_x, and flip_y fields.
* Adds flip_x and flip_y fields to ExtractedUiNode.
* Changes extract_uinodes to extract the flip_x and flip_y values from UiImage.
* Changes prepare_uinodes to swap the UV coordinates as required.
* Changes UiImage derefs to texture field accesses.
2022-11-14 21:59:17 +00:00
Aevyrie
c3c4088317 Fix instancing example for hdr (#6554)
# Objective

- Using the instancing example as reference, I found it was breaking when enabling HDR on the camera. I found that this was because, unlike in internal code, this was not updating the specialization key with `view.hdr`.

## Solution

- Add the missing HDR bit.
2022-11-12 09:31:03 +00:00
Rob Parrett
3d64acd0c3 Add more info to texture loading error in texture_atlas example (#6456)
# Objective

- Fix an awkwardly phrased/typoed error message
- Actually tell users which file caused the error
- IMO we don't need to panic

## Solution

- Add a warning including the involved asset path when a non-image is found by `load_folder`
- Note: uses `let else` which is stable now

```
2022-11-03T14:17:59.006861Z  WARN texture_atlas: Some(AssetPath { path: "textures/rpg/tiles/whatisthisdoinghere.ogg", label: None }) did not resolve to an `Image` asset.
```
2022-11-05 16:30:13 +00:00
targrub
96c9c60f80 Use cbrt() instead of powf(1./3.) (#6481)
# Objective

- Use cube root library function instead of handrolling.

## Solution

- Instead of `powf(1./3.)` use `cbrt()`.
2022-11-05 14:12:04 +00:00
xtr3m3nerd
40ea5b4ef6 UI scaling fix (#6479)
# Objective

Fixes: https://github.com/bevyengine/bevy/issues/6466 
Summary: The UI Scaling example dynamically scales the UI which will dynamically allocate fonts to the font atlas surpassing the protective limit, throwing a panic. 

## Solution

- Set TextSettings.allow_dynamic_font_size = true for the UI Scaling example. This is the ideal solution since the dynamic changes to the UI are not continuous yet still discrete.
- Update the panic text to reflect ui scaling as a potential cause
2022-11-05 13:51:12 +00:00
Carter Anderson
e5905379de Use new let-else syntax where possible (#6463)
# Objective

Let-else syntax is now stable!

## Solution

Use it where possible!
2022-11-04 21:32:09 +00:00
Charles
3a14ae40ee Remove Camera2d in bloom example (#6462)
# Objective

The bloom example has a 2d camera for the UI. This is an artifact of an older version of bevy. All cameras can render the UI now.

## Solution

Remove the 2d camera
2022-11-04 11:42:23 +00:00
ira
2c5d072e76 Allow passing glam vector types as vertex attributes (#6442)
Allow passing `Vec`s of glam vector types as vertex attributes.
Alternative to #4548 and #2719

Also used some macros to cut down on all the repetition.

# Migration Guide
Implementations of `From<Vec<[u16; 4]>>` and `From<Vec<[u8; 4]>>` for `VertexAttributeValues` have been removed.
I you're passing either `Vec<[u16; 4]>` or `Vec<[u8; 4]>` into `Mesh::insert_attribute` it will now require wrapping it with right the `VertexAttributeValues` enum variant. 

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-11-04 03:45:17 +00:00
JMS55
4c4f47697c Bloom (#6397)
# Objective

- Adds a bloom pass for HDR-enabled Camera3ds.
- Supersedes (and all credit due to!) https://github.com/bevyengine/bevy/pull/3430 and https://github.com/bevyengine/bevy/pull/2876

![image](https://user-images.githubusercontent.com/47158642/198698783-228edc00-20b5-4218-a613-331ccd474f38.png)

## Solution

- A threshold is applied to isolate emissive samples, and then a series of downscale and upscaling passes are applied and composited together.
- Bloom is applied to 2d or 3d Cameras with hdr: true and a BloomSettings component.

---

## Changelog

- Added a `core_pipeline::bloom::BloomSettings` component.
- Added `BloomNode` that runs between the main pass and tonemapping.
- Added a `BloomPlugin` that is loaded as part of CorePipelinePlugin.
- Added a bloom example project.

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: DGriffin91 <github@dgdigital.net>
2022-11-04 01:34:12 +00:00
Boxy
30e35764a1 Replace WorldQueryGats trait with actual gats (#6319)
# Objective

Replace `WorldQueryGats` trait with actual gats

## Solution

Replace `WorldQueryGats` trait with actual gats

---

## Changelog

- Replaced `WorldQueryGats` trait with actual gats

## Migration Guide

- Replace usage of `WorldQueryGats` assoc types with the actual gats on `WorldQuery` trait
2022-11-03 16:33:05 +00:00
ira
262b3fc40d Fix mesh.wgsl error for meshes without normals (#6439)
# Objective
Split `model` assignment out of `#ifdef VERTEX_NORMALS`.
Remove outdated code/comments talking about required mesh attributes. 

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-11-03 12:38:47 +00:00
Gabriel Bourgeois
4b5a33d970 Add z-index support with a predictable UI stack (#5877)
# Objective

Add consistent UI rendering and interaction where deep nodes inside two different hierarchies will never render on top of one-another by default and offer an escape hatch (z-index) for nodes to change their depth.

## The problem with current implementation

The current implementation of UI rendering is broken in that regard, mainly because [it sets the Z value of the `Transform` component based on a "global Z" space](https://github.com/bevyengine/bevy/blob/main/crates/bevy_ui/src/update.rs#L43) shared by all nodes in the UI. This doesn't account for the fact that each node's final `GlobalTransform` value will be relative to its parent. This effectively makes the depth unpredictable when two deep trees are rendered on top of one-another. 

At the moment, it's also up to each part of the UI code to sort all of the UI nodes. The solution that's offered here does the full sorting of UI node entities once and offers the result through a resource so that all systems can use it.

## Solution

### New ZIndex component
This adds a new optional `ZIndex` enum component for nodes which offers two mechanism:
- `ZIndex::Local(i32)`: Overrides the depth of the node relative to its siblings.
- `ZIndex::Global(i32)`: Overrides the depth of the node relative to the UI root. This basically allows any node in the tree to "escape" the parent and be ordered relative to the entire UI.

Note that in the current implementation, omitting `ZIndex` on a node has the same result as adding `ZIndex::Local(0)`. Additionally, the "global" stacking context is essentially a way to add your node to the root stacking context, so using `ZIndex::Local(n)` on a root node (one without parent) will share that space with all nodes using `Index::Global(n)`.

### New UiStack resource
This adds a new `UiStack` resource which is calculated from both hierarchy and `ZIndex` during UI update and contains a vector of all node entities in the UI, ordered by depth (from farthest from camera to closest). This is exposed publicly by the bevy_ui crate with the hope that it can be used for consistent ordering and to reduce the amount of sorting that needs to be done by UI systems (i.e. instead of sorting everything by `global_transform.z` in every system, this array can be iterated over).

### New z_index example
This also adds a new z_index example that showcases the new `ZIndex` component. It's also a good general demo of the new UI stack system, because making this kind of UI was very broken with the old system (e.g. nodes would render on top of each other, not respecting hierarchy or insert order at all).

![image](https://user-images.githubusercontent.com/1060971/189015985-8ea8f989-0e9d-4601-a7e0-4a27a43a53f9.png)

---

## Changelog

- Added the `ZIndex` component to bevy_ui.
- Added the `UiStack` resource to bevy_ui, and added implementation in a new `stack.rs` module.
- Removed the previous Z updating system from bevy_ui, because it was replaced with the above.
- Changed bevy_ui rendering to use UiStack instead of z ordering.
- Changed bevy_ui focus/interaction system to use UiStack instead of z ordering.
- Added a new z_index example.

## ZIndex demo
Here's a demo I wrote to test these features
https://user-images.githubusercontent.com/1060971/188329295-d7beebd6-9aee-43ab-821e-d437df5dbe8a.mp4


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-11-02 22:06:04 +00:00
Edvin Kjell
a8a62fcf3d [Fixes #6059] `Entity`'s “ID” should be named “index” instead (#6107)
# Objective

Fixes #6059, changing all incorrect occurrences of ``id`` in the ``entity`` module to ``index``:

* struct level documentation,
* ``id`` struct field,
* ``id`` method and its documentation.

## Solution

Renaming and verifying using CI. 


Co-authored-by: Edvin Kjell <43633999+Edwox@users.noreply.github.com>
2022-11-02 15:19:50 +00:00
Griffin
5640ec855e Add FXAA postprocessing (#6393)
# Objective

- Add post processing passes for FXAA (Fast Approximate Anti-Aliasing)
- Add example comparing MSAA and FXAA

## Solution

When the FXAA plugin is added, passes for FXAA are inserted between the main pass and the tonemapping pass. Supports using either HDR or LDR output from the main pass.

---

## Changelog

- Add a new FXAANode that runs after the main pass when the FXAA plugin is added.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-11-02 06:51:28 +00:00
Niklas Eicker
558859691e Fix return_after_run example (#6420)
# Objective

- Fixes  #6311
- Make it clearer what should be done in the example (close the Bevy app window)

## Solution

- Remove the second windowed Bevy App [since winit does not support this](https://github.com/rust-windowing/winit/blob/v0.27.4/src/event_loop.rs#L82-L83)
- Add title to the Bevy window asking the user to close it

This is more of a quick fix to have a working example. It would be nicer if we had a small real usecase for this functionality.
Another alternativ that I tried out: If we want to showcase a second Bevy app as it was before, we could still do this as long as one of them does not have a window. But I don't see how this is helpful in the context of the example, so I stuck with only one Bevy app and a simple print afterwards.
2022-10-31 16:35:20 +00:00
François
8cdd977a12 Unique plugin (#6411)
# Objective

- Make it impossible to add a plugin twice
- This is going to be more a risk for plugins with configurations, to avoid things like `App::new().add_plugins(DefaultPlugins).add_plugin(ImagePlugin::default_nearest())`

## Solution

- Panic when a plugin is added twice
- It's still possible to mark a plugin as not unique by overriding `is_unique`
- ~~Simpler version of~~ #3988 (not simpler anymore because of how `PluginGroupBuilder` implements `PluginGroup`)
2022-10-31 16:12:19 +00:00
Lena Milizé
599ca782e3 Add a way to toggle AudioSink (#6321)
# Objective

Currently toggling an `AudioSink` (for example from a game menu) requires writing

```rs
if sink.is_paused() {
    sink.play();
} else {
    sink.pause();
}
```

It would be nicer if we could reduce this down to a single line

```rs
sink.toggle();
```

## Solution

Add an `AudioSink::toggle` method which does exactly that.

---

## Changelog

- Added `AudioSink::toggle` which can be used to toggle state of a sink.
2022-10-31 15:57:51 +00:00
ira
13da481bea Add methods to Query<&Children> and Query<&Parent> to iterate over descendants and ancestors (#6185)
# Objective
Add methods to `Query<&Children>` and `Query<&Parent>` to iterate over descendants and ancestors, respectively.

## Changelog

* Added extension trait for `Query` in `bevy_hierarchy`, `HierarchyQueryExt`
* Added method `iter_descendants` to `Query<&Children>` via `HierarchyQueryExt` for iterating over the descendants of an entity.
* Added method `iter_ancestors` to `Query<&Parent>` via `HierarchyQueryExt` for iterating over the ancestors of an entity.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-10-31 15:57:50 +00:00
JoJoJet
336049da68 Remove outdated uses of single-tuple bundles (#6406)
# Objective

Bevy still has many instances of using single-tuples `(T,)` to create a bundle. Due to #2975, this is no longer necessary.

## Solution

Search for regex `\(.+\s*,\)`. This should have found every instance.
2022-10-29 18:15:28 +00:00
Mark Nokalt
306c1ac617 Rename Handle::as_weak() to cast_weak() (#5321)
# Objective

Following discussion on #3536 and #3522, `Handle::as_weak()` takes a type `U`, reinterpreting the handle as of another asset type while keeping the same ID. This is mainly used today in font atlas code. This PR does two things:

- Rename the method to `cast_weak()` to make its intent more clear
- Actually change the type uuid in the handle if it's not an asset path variant.

## Migration Guide

- Rename `Handle::as_weak` uses to `Handle::cast_weak`

    The method now properly sets the associated type uuid if the handle is a direct reference (e.g. not a reference to an `AssetPath`), so adjust you code accordingly if you relied on the previous behavior.
2022-10-28 22:43:14 +00:00
Jakob Hellermann
e71c4d2802 fix nightly clippy warnings (#6395)
# Objective

- fix new clippy lints before they get stable and break CI

## Solution

- run `clippy --fix` to auto-fix machine-applicable lints
- silence `clippy::should_implement_trait` for `fn HandleId::default<T: Asset>`

## Changes
- always prefer `format!("{inline}")` over `format!("{}", not_inline)`
- prefer `Box::default` (or `Box::<T>::default` if necessary) over `Box::new(T::default())`
2022-10-28 21:03:01 +00:00
Jakob Hellermann
838b318863 separate tonemapping and upscaling passes (#3425)
Attempt to make features like bloom https://github.com/bevyengine/bevy/pull/2876 easier to implement.

**This PR:**
- Moves the tonemapping from `pbr.wgsl` into a separate pass
- also add a separate upscaling pass after the tonemapping which writes to the swap chain (enables resolution-independant rendering and post-processing after tonemapping)
- adds a `hdr` bool to the camera which controls whether the pbr and sprite shaders render into a `Rgba16Float` texture

**Open questions:**
- ~should the 2d graph work the same as the 3d one?~ it is the same now
- ~The current solution is a bit inflexible because while you can add a post processing pass that writes to e.g. the `hdr_texture`, you can't write to a separate `user_postprocess_texture` while reading the `hdr_texture` and tell the tone mapping pass to read from the `user_postprocess_texture` instead. If the tonemapping and upscaling render graph nodes were to take in a `TextureView` instead of the view entity this would almost work, but the bind groups for their respective input textures are already created in the `Queue` render stage in the hardcoded order.~ solved by creating bind groups in render node

**New render graph:**

![render_graph](https://user-images.githubusercontent.com/22177966/147767249-57dd4229-cfab-4ec5-9bf3-dc76dccf8e8b.png)
<details>
<summary>Before</summary>

![render_graph_old](https://user-images.githubusercontent.com/22177966/147284579-c895fdbd-4028-41cf-914c-e1ffef60e44e.png)
</details>

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-10-26 20:13:59 +00:00
targrub
c18b1a839b Prepare for upcoming rustlang by fixing upcoming clippy warnings (#6376)
# Objective

- Proactive changing of code to comply with warnings generated by beta of rustlang version of cargo clippy.

## Solution

- Code changed as recommended by `rustup update`, `rustup default beta`, `cargo run -p ci -- clippy`.
- Tested using `beta` and `stable`.  No clippy warnings in either after changes made.

---

## Changelog

- Warnings fixed were: `clippy::explicit-auto-deref` (present in 11 files), `clippy::needless-borrow` (present in 2 files), and `clippy::only-used-in-recursion` (only 1 file).
2022-10-26 19:15:15 +00:00
François
5622d56be1 Use plugin setup for resource only used at setup time (#6360)
# Objective

- Build on #6336 for more plugin configurations

## Solution

- `LogSettings`, `ImageSettings` and `DefaultTaskPoolOptions` are now plugins settings rather than resources

---

## Changelog

- `LogSettings` plugin settings have been move to `LogPlugin`, `ImageSettings` to `ImagePlugin` and `DefaultTaskPoolOptions` to `CorePlugin`

## Migration Guide

The `LogSettings` settings have been moved from a resource to `LogPlugin` configuration:

```rust
// Old (Bevy 0.8)
app
  .insert_resource(LogSettings {
    level: Level::DEBUG,
    filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
  })
  .add_plugins(DefaultPlugins)

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(LogPlugin {
    level: Level::DEBUG,
    filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
}))
```


The `ImageSettings` settings have been moved from a resource to `ImagePlugin` configuration:

```rust
// Old (Bevy 0.8)
app
  .insert_resource(ImageSettings::default_nearest())
  .add_plugins(DefaultPlugins)

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
```


The `DefaultTaskPoolOptions` settings have been moved from a resource to `CorePlugin::task_pool_options`:

```rust
// Old (Bevy 0.8)
app
  .insert_resource(DefaultTaskPoolOptions::with_num_threads(4))
  .add_plugins(DefaultPlugins)

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(CorePlugin {
  task_pool_options: TaskPoolOptions::with_num_threads(4),
}))
```
2022-10-25 22:19:34 +00:00
Carter Anderson
1bb751cb8d Plugins own their settings. Rework PluginGroup trait. (#6336)
# Objective

Fixes #5884 #2879
Alternative to #2988 #5885 #2886

"Immutable" Plugin settings are currently represented as normal ECS resources, which are read as part of plugin init. This presents a number of problems:

1. If a user inserts the plugin settings resource after the plugin is initialized, it will be silently ignored (and use the defaults instead)
2. Users can modify the plugin settings resource after the plugin has been initialized. This creates a false sense of control over settings that can no longer be changed.

(1) and (2) are especially problematic and confusing for the `WindowDescriptor` resource, but this is a general problem.

## Solution

Immutable Plugin settings now live on each Plugin struct (ex: `WindowPlugin`). PluginGroups have been reworked to support overriding plugin values. This also removes the need for the `add_plugins_with` api, as the `add_plugins` api can use the builder pattern directly. Settings that can be used at runtime continue to be represented as ECS resources.

Plugins are now configured like this:

```rust
app.add_plugin(AssetPlugin {
  watch_for_changes: true,
  ..default()
})
```

PluginGroups are now configured like this:

```rust
app.add_plugins(DefaultPlugins
  .set(AssetPlugin {
    watch_for_changes: true,
    ..default()
  })
)
```

This is an alternative to #2988, which is similar. But I personally prefer this solution for a couple of reasons:
* ~~#2988 doesn't solve (1)~~ #2988 does solve (1) and will panic in that case. I was wrong!
* This PR directly ties plugin settings to Plugin types in a 1:1 relationship, rather than a loose "setup resource" <-> plugin coupling (where the setup resource is consumed by the first plugin that uses it).
* I'm not a huge fan of overloading the ECS resource concept and implementation for something that has very different use cases and constraints.

## Changelog

- PluginGroups can now be configured directly using the builder pattern. Individual plugin values can be overridden by using `plugin_group.set(SomePlugin {})`, which enables overriding default plugin values.  
- `WindowDescriptor` plugin settings have been moved to `WindowPlugin` and `AssetServerSettings` have been moved to `AssetPlugin`
- `app.add_plugins_with` has been replaced by using `add_plugins` with the builder pattern.

## Migration Guide

The `WindowDescriptor` settings have been moved from a resource to `WindowPlugin::window`:

```rust
// Old (Bevy 0.8)
app
  .insert_resource(WindowDescriptor {
    width: 400.0,
    ..default()
  })
  .add_plugins(DefaultPlugins)

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(WindowPlugin {
  window: WindowDescriptor {
    width: 400.0,
    ..default()
  },
  ..default()
}))
```


The `AssetServerSettings` resource has been removed in favor of direct `AssetPlugin` configuration:

```rust
// Old (Bevy 0.8)
app
  .insert_resource(AssetServerSettings {
    watch_for_changes: true,
    ..default()
  })
  .add_plugins(DefaultPlugins)

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.set(AssetPlugin {
  watch_for_changes: true,
  ..default()
}))
```

`add_plugins_with` has been replaced by `add_plugins` in combination with the builder pattern:

```rust
// Old (Bevy 0.8)
app.add_plugins_with(DefaultPlugins, |group| group.disable::<AssetPlugin>());

// New (Bevy 0.9)
app.add_plugins(DefaultPlugins.build().disable::<AssetPlugin>());
```
2022-10-24 21:20:33 +00:00
dataphract
bcc33f6757 feat: add GamepadInfo, expose gamepad names (#6342)
# Objective

Fixes #6339.

## Solution

This PR adds a new type, `GamepadInfo`, which holds metadata associated with a particular `Gamepad`. The `Gamepads` resource now holds a `HashMap<Gamepad, GamepadInfo>`. The `GamepadInfo` is created when the gamepad backend (by default `bevy_gilrs`) emits a "gamepad connected" event.

The `gamepad_viewer` example has been updated to showcase the new functionality.

Before:

![bevy-gamepad-old](https://user-images.githubusercontent.com/86984145/197359427-2130a3c0-bd8a-4683-ae24-2a9eaa98b586.png)

After:

![bevy-gamepad-new](https://user-images.githubusercontent.com/86984145/197359429-f7963163-df26-4906-af7f-6186fe3bd338.png)


---

## Changelog

### Added

- Added `GamepadInfo`.
- Added `Gamepads::name()`, which returns the name of the specified gamepad if it exists.

### Changed

- `GamepadEventType::Connected` is now a tuple variant with a single field of type `GamepadInfo`.
- Since `GamepadInfo` is not `Copy`, `GamepadEventType` is no longer `Copy`. The same is true of `GamepadEvent` and `GamepadEventRaw`.

## Migration Guide

- Pattern matches on `GamepadEventType::Connected` will need to be updated, as the form of the variant has changed.
- Code that requires `GamepadEvent`, `GamepadEventRaw` or `GamepadEventType` to be `Copy` will need to be updated.
2022-10-24 14:33:50 +00:00
Christopher Durham
c19aa5939d Add Exponential Moving Average into diagnostics (#4992)
# Objective

- Add Time-Adjusted Rolling EMA-based smoothing to diagnostics.
- Closes #4983; see that issue for more more information.

## Terms

- EMA - [Exponential Moving Average](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average)
- SMA - [Simple Moving Average](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average)

## Solution

- We use a fairly standard approximation of a true EMA where $EMA_{\text{frame}} = EMA_{\text{previous}} + \alpha \left( x_{\text{frame}} - EMA_{\text{previous}} \right)$ where $\alpha = \Delta t / \tau$ and $\tau$ is an arbitrary smoothness factor. (See #4983 for more discussion of the math.)
- The smoothness factor is here defaulted to $2 / 21$; this was chosen fairly arbitrarily as supposedly related to the existing 20-bucket SMA.
- The smoothness factor can be set on a per-diagnostic basis via `Diagnostic::with_smoothing_factor`.

---

## Changelog

### Added

- `Diagnostic::smoothed` - provides an exponentially smoothed view of a recorded diagnostic, to e.g. reduce jitter in frametime readings.

### Changed
- `LogDiagnosticsPlugin` now records the smoothed value rather than the raw value.
  - For diagnostics recorded less often than every 0.1 seconds, this change to defaults will have no visible effect.
  - For discrete diagnostics where this smoothing is not desirable, set a smoothing factor of 0 to disable smoothing.
  - The average of the recent history is still shown when available.
2022-10-24 13:46:37 +00:00
Cameron
7989cb2650 Add global time scaling (#5752)
# Objective

- Make `Time` API more consistent.
- Support time accel/decel/pause.

## Solution

This is just the `Time` half of #3002. I was told that part isn't controversial.

- Give the "delta time" and "total elapsed time" methods `f32`, `f64`, and `Duration` variants with consistent naming.
- Implement accelerating / decelerating the passage of time.
- Implement stopping time.

---

## Changelog

- Changed `time_since_startup` to `elapsed` because `time.time_*` is just silly.
- Added `relative_speed` and `set_relative_speed` methods.
- Added `is_paused`, `pause`, `unpause` , and methods. (I'd prefer `resume`, but `unpause` matches `Timer` API.)
- Added `raw_*` variants of the "delta time" and "total elapsed time" methods.
- Added `first_update` method because there's a non-zero duration between startup and the first update.

## Migration Guide

- `time.time_since_startup()` -> `time.elapsed()`
- `time.seconds_since_startup()` -> `time.elapsed_seconds_f64()`
- `time.seconds_since_startup_wrapped_f32()` -> `time.elapsed_seconds_wrapped()`

If you aren't sure which to use, most systems should continue to use "scaled" time (e.g. `time.delta_seconds()`). The realtime "unscaled" time measurements (e.g. `time.raw_delta_seconds()`) are mostly for debugging and profiling.
2022-10-22 18:52:29 +00:00
VitalyR
c313e21d65 Update wgpu to 0.14.0, naga to 0.10.0, winit to 0.27.4, raw-window-handle to 0.5.0, ndk to 0.7 (#6218)
# Objective

- Update `wgpu` to 0.14.0, `naga` to `0.10.0`, `winit` to 0.27.4, `raw-window-handle` to 0.5.0, `ndk` to 0.7.

## Solution

---

## Changelog

### Changed

- Changed `RawWindowHandleWrapper` to `RawHandleWrapper` which wraps both `RawWindowHandle` and `RawDisplayHandle`, which satisfies the `impl HasRawWindowHandle and HasRawDisplayHandle` that `wgpu` 0.14.0 requires.

- Changed `bevy_window::WindowDescriptor`'s `cursor_locked` to `cursor_grab_mode`, change its type from `bool` to `bevy_window::CursorGrabMode`.

## Migration Guide

- Adjust usage of `bevy_window::WindowDescriptor`'s `cursor_locked` to `cursor_grab_mode`, and adjust its type from `bool` to `bevy_window::CursorGrabMode`.
2022-10-19 17:40:23 +00:00
Rob Parrett
b2ca3fb8b5 Fix camera ambiguity warning in IOS example (#6300)
# Objective

Fix a camera ambiguity warning in the IOS example

## Solution

I'm assuming that this was accidentally added when UI cameras stopped being a thing. So just delete the extra camera.
2022-10-19 15:05:12 +00:00
张林伟
c7fe4027a1 Rename example file scaling.rs to ui_scaling.rs (#6296)
# Objective

To be consistent like other examples, it's better to keep file name and example name same, so we don't need to find correct example name in Cargo.toml.

## Solution

Rename example file scaling.rs to ui_scaling.rs.
2022-10-19 11:36:26 +00:00
Michel van der Hulst
4407cdb423 Fixes scroll example after inverting UI Y axis (#6290) 2022-10-18 13:28:35 +00:00
Michel van der Hulst
0981789ec7 Fixes incorrect glyph positioning for text2d (#6273)
# Objective
Fixes #6272

## Solution
Revert to old way of positioning text for Text2D rendered text.


Co-authored-by: Michel van der Hulst <hulstmichel@gmail.com>
2022-10-18 13:28:34 +00:00
targrub
c11fbfb3e1 Add getters and setters for InputAxis and ButtonSettings (#6088)
# Objective
Fixes https://github.com/bevyengine/bevy/issues/3418

## Solution

Originally a rebase of https://github.com/bevyengine/bevy/pull/3446.  Work was originally done by mfdorst, who should receive considerable credit.  Then the error types were extensively reworked by targrub.

## Migration Guide

`AxisSettings` now has a `new()`, which may return an `AxisSettingsError`.
`AxisSettings` fields made private; now must be accessed through getters and setters.  There's a dead zone, from `.deadzone_upperbound()` to `.deadzone_lowerbound()`, and a live zone, from `.deadzone_upperbound()` to `.livezone_upperbound()` and from `.deadzone_lowerbound()` to `.livezone_lowerbound()`.
`AxisSettings` setters no longer panic.
`ButtonSettings` fields made private; now must be accessed through getters and setters.
`ButtonSettings` now has a `new()`, which may return a `ButtonSettingsError`.

Co-authored-by: targrub <62773321+targrub@users.noreply.github.com>
2022-10-17 14:38:55 +00:00
Lena Milizé
73605f43b6 Replace the bool argument of Timer with TimerMode (#6247)
As mentioned in #2926, it's better to have an explicit type that clearly communicates the intent of the timer mode rather than an opaque boolean, which can be only understood when knowing the signature or having to look up the documentation.

This also opens up a way to merge different timers, such as `Stopwatch`, and possibly future ones, such as `DiscreteStopwatch` and `DiscreteTimer` from #2683, into one struct.

Signed-off-by: Lena Milizé <me@lvmn.org>

# Objective

Fixes #2926.

## Solution

Introduce `TimerMode` which replaces the `bool` argument of `Timer` constructors. A `Default` value for `TimerMode` is `Once`.

---

## Changelog

### Added

- `TimerMode` enum, along with variants `TimerMode::Once` and `TimerMode::Repeating`

### Changed

- Replace `bool` argument of `Timer::new` and `Timer::from_seconds` with `TimerMode`
- Change `repeating: bool` field of `Timer` with `mode: TimerMode`

## Migration Guide

- Replace `Timer::new(duration, false)` with `Timer::new(duration, TimerMode::Once)`.
- Replace `Timer::new(duration, true)` with `Timer::new(duration, TimerMode::Repeating)`.
- Replace `Timer::from_seconds(seconds, false)` with `Timer::from_seconds(seconds, TimerMode::Once)`.
- Replace `Timer::from_seconds(seconds, true)` with `Timer::from_seconds(seconds, TimerMode::Repeating)`.
- Change `timer.repeating()` to `timer.mode() == TimerMode::Repeating`.
2022-10-17 13:47:01 +00:00
Sergi-Ferrez
05c7babba2 Clarify bevy::ui::Node field and documentation (#5995)
# Objective
Fixes #5820

## Solution

Change field name and documentation from `bevy::ui::Node` struct

---

## Changelog

`bevy::ui::Node` `size` field has renamed to `calculated_size`

## Migration Guide

All references to the old `size` name has been changed, to access `bevy::ui::Node` `size` field use `calculated_size`
2022-10-17 13:27:24 +00:00
ira
92ba6224b9 Use SpatialBundle/TransformBundle in examples (#6002)
Does what it do

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-10-13 12:53:18 +00:00
Alice Cecile
c0a93aa7a4 Rename system chaining to system piping (#6230)
# Objective

> System chaining is a confusing name: it implies the ability to construct non-linear graphs, and suggests a sense of system ordering that is only incidentally true. Instead, it actually works by passing data from one system to the next, much like the pipe operator.

> In the accepted [stageless RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/45-stageless.md), this concept is renamed to piping, and "system chaining" is used to construct groups of systems with ordering dependencies between them.

Fixes #6225.

## Changelog

System chaining has been renamed to system piping to improve clarity (and free up the name for new ordering APIs). 

## Migration Guide

The `.chain(handler_system)` method on systems is now `.pipe(handler_system)`.
The `IntoChainSystem` trait is now `IntoPipeSystem`, and the `ChainSystem` struct is now `PipeSystem`.
2022-10-11 15:21:12 +00:00
Michel van der Hulst
6ce7ce208e Change UI coordinate system to have origin at top left corner (#6000)
# Objective
Fixes #5572

## Solution

Approach is to invert the Y-axis of the UI Camera by changing the UI projection matrix to render the UI upside down.

After that I'm trying to fix all issues, that pop up:
- interaction expected the "old" position
- images and text were displayed upside-down
- baseline of text was based on the top of the glyph instead of bottom

... probably a lot more.

---

Result when running examples:
<details>
    <summary>Button example</summary>

main branch:
![button main](https://user-images.githubusercontent.com/4232644/190856087-61dd1d98-42b5-4238-bd97-149744ddfeba.png)
this pr:
![button pr](https://user-images.githubusercontent.com/4232644/190856097-3f4bc97a-ed15-4e97-b7f1-2b2dd6bb8b14.png)

</details>

<details>
    <summary>Text example</summary>

m
![text main](https://user-images.githubusercontent.com/4232644/192142831-4cf19aa1-f49a-485e-af7b-374d6f5c396c.png)
ain branch: 


this pr:
![text pr fixed](https://user-images.githubusercontent.com/4232644/192142829-c433db3b-32e1-4ee8-b493-0b4a4d9c8e70.png)


</details>

<details>
    <summary>Text debug example</summary>

main branch:
![text_debug main](https://user-images.githubusercontent.com/4232644/192142822-940aefa6-e502-410b-8da4-5570f77b5df2.png)

this pr:
![text_debug pr fixed](https://user-images.githubusercontent.com/4232644/194547010-8c968f5c-5a71-4ffc-871d-790c06d48016.png)

</details>

<details>
    <summary>Transparency UI example</summary>

main branch:
![transparency_ui main](https://user-images.githubusercontent.com/4232644/190856172-328c60fe-3622-4598-97d5-2f1595db13b3.png)


this pr:
![transperency_ui pr](https://user-images.githubusercontent.com/4232644/190856179-a2dafb99-41ea-45a9-9dd6-400fa3ef24b9.png)

</details>

<details>
    <summary>UI example</summary>

**ui example**
main branch:
![ui main](https://user-images.githubusercontent.com/4232644/192142812-e20ba31a-6841-46d9-a785-4198cf22dc99.png)

this pr:
![ui pr fixed](https://user-images.githubusercontent.com/4232644/192142788-cc0b74e0-7710-4faa-b5a2-60270a5da77c.png)

</details>

## Changelog
UI coordinate system and cursor position was changed from bottom left origin, y+ up to top left origin, y+ down.

## Migration Guide
All flex layout should be inverted (ColumnReverse => Column, FlexStart => FlexEnd, WrapReverse => Wrap)
System where dealing with cursor position should be changed to account for cursor position being based on the top left instead of bottom left
2022-10-11 12:51:44 +00:00
ira
9423cb6a8d Rename Transform::mul_vec3 to transform_point and improve docs (#6132)
The docs ended up quite verbose :v

Also added a missing `#[inline]` to `GlobalTransform::mul_transform`.

I'd say this resolves #5500

# Migration Guide
`Transform::mul_vec3` has been renamed to `transform_point`.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-10-10 16:50:17 +00:00
TimJentzsch
1738527902 Make the default background color of NodeBundle transparent (#6211)
# Objective

Closes #6202.

The default background color for `NodeBundle` is currently white.
However, it's very rare that you actually want a white background color.
Instead, you often want a background color specific to the style of your game or a transparent background (e.g. for UI layout nodes).

## Solution

`Default` is not derived for `NodeBundle` anymore, but explicitly specified.
The default background color is now transparent (`Color::NONE.into()`) as this is the most common use-case, is familiar from the web and makes specifying a layout for your UI less tedious.

---

## Changelog

- Changed the default `NodeBundle.background_color` to be transparent (`Color::NONE.into()`).

## Migration Guide

If you want a `NodeBundle` with a white background color, you must explicitly specify it:

Before:

```rust
let node = NodeBundle {
    ..default()
}
```

After:

```rust
let node = NodeBundle {
    background_color: Color::WHITE.into(),
    ..default()
}
```
2022-10-09 21:03:05 +00:00
Alvin Philips
f2106bb3ce Reduced code duplication in gamepad_viewer example (#6175)
# Objective

- Reduce code duplication in the `gamepad_viewer` example.
- Fixes #6164 

## Solution

- Added a custom Bundle called `GamepadButtonBundle` to avoid repeating similar code throughout the example.
- Created a `new()` method on `GamepadButtonBundle`.



Co-authored-by: Alvin Philips <alvinphilips257@gmail.com>
2022-10-06 13:33:29 +00:00
Fanda Vacek
2362cebcae More explicit help how to cycle the cameras (#6162)
# Objective

Scene viewer example has switch camera keys defined, but only one camera was instantiated on the scene.

## Solution

More explicit help how to cycle the cameras, explaining that more cameras must be present in loaded scene.





Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-10-05 21:22:11 +00:00
ira
3aaf746675 Example cleanup (#6131)
Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-09-30 13:25:27 +00:00
Cameron
6929d95f7f Replace fixed timestep in alien_cake_addict example with timer (#5760)
# Objective

Examples should use the correct tools for the job.

## Solution

A fixed timestep, by design, can step multiple times consecutively in a single update.

That property used to crash the `alien_cake_addict` example (#2525), which was "fixed" in #3411 (by just not panicking). The proper fix is to use a timer instead, since the system is supposed to spawn a cake every 5 seconds. 

---

A timer guarantees a minimum duration. A fixed timestep guarantees a fixed number of steps per second.
Each one works by essentially sacrificing the other's guarantee.

You can use them together, but no other systems are timestep-based in this example, so the timer is enough.
2022-09-30 11:37:33 +00:00
rustui
59f872647d StreamReceiver does not need to be mutable (#6119)
ResMut -> Res
2022-09-28 17:39:36 +00:00
Charles
197392a2cd use alpha mask even when unlit (#6047)
# Objective

- Alpha mask was previously ignored when using an unlit material. 
- Fixes https://github.com/bevyengine/bevy/issues/4479

## Solution

- Extract the alpha discard to a separate function and use it when unlit is true

## Notes
I tried calling `alpha_discard()` before the `if` in pbr.wgsl, but I had errors related to having a `discard` at the beginning before doing the texture sampling. I'm not sure if there's a way to fix that instead of having the function being called in 2 places.
2022-09-28 05:54:11 +00:00
Charles
8073362039 add globals to mesh view bind group (#5409)
# Objective

- It's often really useful to have access to the time when writing shaders.

## Solution

- Add a UnifformBuffer in the mesh view bind group
- This buffer contains the time, delta time and a wrapping frame count

https://user-images.githubusercontent.com/8348954/180130314-97948c2a-2d11-423d-a9c4-fb5c9d1892c7.mp4

---

## Changelog

- Added a `GlobalsUniform` at position 9 of the mesh view bind group

## Notes

The implementation is currently split between bevy_render and bevy_pbr because I was basing my implementation on the `ViewPlugin`. I'm not sure if that's the right way to structure it.

I named this `globals` instead of just time because we could potentially add more things to it.

## References in other engines

- Godot: <https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/canvas_item_shader.html#global-built-ins>
    - Global time since startup, in seconds, by default resets to 0 after 3600 seconds
    - Doesn't seem to have anything else
- Unreal: <https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/Materials/ExpressionReference/Constant/>
    - Generic time value that updates every frame. Can be paused or scaled.
    - Frame count node, doesn't seem to be an equivalent for shaders: <https://docs.unrealengine.com/4.26/en-US/BlueprintAPI/Utilities/GetFrameCount/>
- Unity: <https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html>
    - time since startup in seconds. No mention of time wrapping. Stored as a `vec4(t/20, t, t*2, t*3)` where `t` is the value in seconds
    - Also has delta time, sin time and cos time
- ShaderToy: <https://www.shadertoy.com/howto>
    - iTime is the time since startup in seconds.
    - iFrameRate
    - iTimeDelta
    - iFrame frame counter

Co-authored-by: Charles <IceSentry@users.noreply.github.com>
2022-09-28 04:20:27 +00:00
Carter Anderson
dc3f801239 Exclusive Systems Now Implement System. Flexible Exclusive System Params (#6083)
# Objective

The [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45) involves allowing exclusive systems to be referenced and ordered relative to parallel systems. We've agreed that unifying systems under `System` is the right move.

This is an alternative to #4166 (see rationale in the comments I left there). Note that this builds on the learnings established there (and borrows some patterns).

## Solution

This unifies parallel and exclusive systems under the shared `System` trait, removing the old `ExclusiveSystem` trait / impls. This is accomplished by adding a new `ExclusiveFunctionSystem` impl similar to `FunctionSystem`. It is backed by `ExclusiveSystemParam`, which is similar to `SystemParam`. There is a new flattened out SystemContainer api (which cuts out a lot of trait and type complexity). 

This means you can remove all cases of `exclusive_system()`:

```rust
// before
commands.add_system(some_system.exclusive_system());
// after
commands.add_system(some_system);
```

I've also implemented `ExclusiveSystemParam` for `&mut QueryState` and `&mut SystemState`, which makes this possible in exclusive systems:

```rust
fn some_exclusive_system(
    world: &mut World,
    transforms: &mut QueryState<&Transform>,
    state: &mut SystemState<(Res<Time>, Query<&Player>)>,
) {
    for transform in transforms.iter(world) {
        println!("{transform:?}");
    }
    let (time, players) = state.get(world);
    for player in players.iter() {
        println!("{player:?}");
    }
}
```

Note that "exclusive function systems" assume `&mut World` is present (and the first param). I think this is a fair assumption, given that the presence of `&mut World` is what defines the need for an exclusive system.

I added some targeted SystemParam `static` constraints, which removed the need for this:
``` rust
fn some_exclusive_system(state: &mut SystemState<(Res<'static, Time>, Query<&'static Player>)>) {}
```

## Related

- #2923
- #3001
- #3946

## Changelog

- `ExclusiveSystem` trait (and implementations) has been removed in favor of sharing the `System` trait.
- `ExclusiveFunctionSystem` and `ExclusiveSystemParam` were added, enabling flexible exclusive function systems
- `&mut SystemState` and `&mut QueryState` now implement `ExclusiveSystemParam`
- Exclusive and parallel System configuration is now done via a unified `SystemDescriptor`, `IntoSystemDescriptor`, and `SystemContainer` api.

## Migration Guide

Calling `.exclusive_system()` is no longer required (or supported) for converting exclusive system functions to exclusive systems:

```rust
// Old (0.8)
app.add_system(some_exclusive_system.exclusive_system());
// New (0.9)
app.add_system(some_exclusive_system);
```

Converting "normal" parallel systems to exclusive systems is done by calling the exclusive ordering apis:

```rust
// Old (0.8)
app.add_system(some_system.exclusive_system().at_end());
// New (0.9)
app.add_system(some_system.at_end());
```

Query state in exclusive systems can now be cached via ExclusiveSystemParams, which should be preferred for clarity and performance reasons:
```rust
// Old (0.8)
fn some_system(world: &mut World) {
  let mut transforms = world.query::<&Transform>();
  for transform in transforms.iter(world) {
  }
}
// New (0.9)
fn some_system(world: &mut World, transforms: &mut QueryState<&Transform>) {
  for transform in transforms.iter(world) {
  }
}
```
2022-09-26 23:57:07 +00:00
Carlrs
750ec41c86 Don't bundle extra transform with camera in many sprites examples (#6079)
Fixes #6077 
# Objective

- Make many_sprites and many_animated_sprites work again

## Solution

- Removed the extra transform from the camera bundle - not sure why it was necessary, since `Camera2dBundle::default()` already contains a transform with the same parameters.

---
2022-09-25 18:03:53 +00:00
Rob Parrett
847c26b8dc Rename shapes examples for consistency (#6082)
# Objective

I was about to submit a PR to add these two examples to `bevy-website` and re-discovered the inconsistency.

Although it's not a major issue on the website where only the filenames are shown, this would help to visually distinguish the two examples in the list  because the names are very prominent.

This also helps out when fuzzy-searching the codebase for these files.

## Solution

Rename `shapes` to `2d_shapes`. Now the filename matches the example name, and the naming structure matches the 3d example.

## Notes

@Nilirad proposed this in https://github.com/bevyengine/bevy/pull/4613#discussion_r862455631 but it had slipped away from my brain at that time.
2022-09-25 00:57:07 +00:00
Alice Cecile
481eec2c92 Rename UiColor to BackgroundColor (#6087)
# Objective

Fixes #6078. The `UiColor` component is unhelpfully named: it is unclear, ambiguous with border color and 

## Solution

Rename the `UiColor` component (and associated fields) to `BackgroundColor` / `background_colorl`.

## Migration Guide

`UiColor` has been renamed to `BackgroundColor`. This change affects `NodeBundle`, `ButtonBundle` and `ImageBundle`. In addition, the corresponding field on `ExtractedUiNode` has been renamed to `background_color` for consistency.
2022-09-25 00:39:17 +00:00
Rob Parrett
e7cd9c1b86 Add a Gamepad Viewer tool to examples (#6074)
# Objective

Give folks an easy way to test their gamepad with bevy.

~~This is a lot of very boring code for an example. Maybe it belongs in the "tools" directory?~~

## Solution

https://user-images.githubusercontent.com/200550/191884342-ace213c0-b423-449a-9295-530cbceaa19e.mp4

## Notes

This has brought to light (to me, anyway) some fairly major issues with gamepads on the web. See:

[WASM mappings (gilrs issue 107)](https://gitlab.com/gilrs-project/gilrs/-/issues/107)
[Inaccurate value for trigger button of Xbox gamepad with WASM (gilrs issue 121)](https://gitlab.com/gilrs-project/gilrs/-/issues/121)
2022-09-24 13:21:01 +00:00
Boutillier
b91945b54d Merge TextureAtlas::from_grid_with_padding into TextureAtlas::from_grid through option arguments (#6057)
This is an adoption of #3775
This merges `TextureAtlas` `from_grid_with_padding` into `from_grid` , adding optional padding and optional offset.
Since the orignal PR, the offset had already been added to from_grid_with_padding through #4836 

## Changelog

- Added `padding` and `offset` arguments to  `TextureAtlas::from_grid`
- Removed `TextureAtlas::from_grid_with_padding`

## Migration Guide

`TextureAtlas::from_grid_with_padding` was merged into `from_grid` which takes two additional parameters for padding and an offset.
```
// 0.8
TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1);
// 0.9
TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1, None, None)

// 0.8
TextureAtlas::from_grid_with_padding(texture_handle, Vec2::new(24.0, 24.0), 7, 1, Vec2::new(4.0, 4.0));
// 0.9
TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1, Some(Vec2::new(4.0, 4.0)), None)
```

Co-authored-by: olefish <88390729+oledfish@users.noreply.github.com>
2022-09-24 12:58:06 +00:00
Carter Anderson
01aedc8431 Spawn now takes a Bundle (#6054)
# Objective

Now that we can consolidate Bundles and Components under a single insert (thanks to #2975 and #6039), almost 100% of world spawns now look like `world.spawn().insert((Some, Tuple, Here))`. Spawning an entity without any components is an extremely uncommon pattern, so it makes sense to give spawn the "first class" ergonomic api. This consolidated api should be made consistent across all spawn apis (such as World and Commands).

## Solution

All `spawn` apis (`World::spawn`, `Commands:;spawn`, `ChildBuilder::spawn`, and `WorldChildBuilder::spawn`) now accept a bundle as input:

```rust
// before:
commands
  .spawn()
  .insert((A, B, C));
world
  .spawn()
  .insert((A, B, C);

// after
commands.spawn((A, B, C));
world.spawn((A, B, C));
```

All existing instances of `spawn_bundle` have been deprecated in favor of the new `spawn` api. A new `spawn_empty` has been added, replacing the old `spawn` api.  

By allowing `world.spawn(some_bundle)` to replace `world.spawn().insert(some_bundle)`, this opened the door to removing the initial entity allocation in the "empty" archetype / table done in `spawn()` (and subsequent move to the actual archetype in `.insert(some_bundle)`).

This improves spawn performance by over 10%:
![image](https://user-images.githubusercontent.com/2694663/191627587-4ab2f949-4ccd-4231-80eb-80dd4d9ad6b9.png)

To take this measurement, I added a new `world_spawn` benchmark.

Unfortunately, optimizing `Commands::spawn` is slightly less trivial, as Commands expose the Entity id of spawned entities prior to actually spawning. Doing the optimization would (naively) require assurances that the `spawn(some_bundle)` command is applied before all other commands involving the entity (which would not necessarily be true, if memory serves). Optimizing `Commands::spawn` this way does feel possible, but it will require careful thought (and maybe some additional checks), which deserves its own PR. For now, it has the same performance characteristics of the current `Commands::spawn_bundle` on main.

**Note that 99% of this PR is simple renames and refactors. The only code that needs careful scrutiny is the new `World::spawn()` impl, which is relatively straightforward, but it has some new unsafe code (which re-uses battle tested BundlerSpawner code path).** 

---

## Changelog

- All `spawn` apis (`World::spawn`, `Commands:;spawn`, `ChildBuilder::spawn`, and `WorldChildBuilder::spawn`) now accept a bundle as input
- All instances of `spawn_bundle` have been deprecated in favor of the new `spawn` api
- World and Commands now have `spawn_empty()`, which is equivalent to the old `spawn()` behavior.  

## Migration Guide

```rust
// Old (0.8):
commands
  .spawn()
  .insert_bundle((A, B, C));
// New (0.9)
commands.spawn((A, B, C));

// Old (0.8):
commands.spawn_bundle((A, B, C));
// New (0.9)
commands.spawn((A, B, C));

// Old (0.8):
let entity = commands.spawn().id();
// New (0.9)
let entity = commands.spawn_empty().id();

// Old (0.8)
let entity = world.spawn().id();
// New (0.9)
let entity = world.spawn_empty();
```
2022-09-23 19:55:54 +00:00
Okko Hakola
69d08c5ef4 Reconfigure surface on present mode change (#6049)
# Objective

- Reconfigure surface after present mode changes. It seems that this is not done currently at runtime. It's pretty common for games to change such graphical settings at runtime.
- Fixes present mode issue in #5111 

## Solution

- Exactly like resolution change gets tracked when extracting window, do the same for present mode.

Additionally, I added present mode (vsync) toggling to window settings example.
2022-09-21 22:35:15 +00:00
Carter Anderson
cd15f0f5be Accept Bundles for insert and remove. Deprecate insert/remove_bundle (#6039)
# Objective

Take advantage of the "impl Bundle for Component" changes in #2975 / add the follow up changes discussed there.

## Solution

- Change `insert` and `remove` to accept a Bundle instead of a Component (for both Commands and World)
- Deprecate `insert_bundle`, `remove_bundle`, and `remove_bundle_intersection`
- Add `remove_intersection`

---

## Changelog

- Change `insert` and `remove` now accept a Bundle instead of a Component (for both Commands and World)
- `insert_bundle` and `remove_bundle` are deprecated
 

## Migration Guide

Replace `insert_bundle` with `insert`:
```rust
// Old (0.8)
commands.spawn().insert_bundle(SomeBundle::default());
// New (0.9)
commands.spawn().insert(SomeBundle::default());
```

Replace `remove_bundle` with `remove`:
```rust
// Old (0.8)
commands.entity(some_entity).remove_bundle::<SomeBundle>();
// New (0.9)
commands.entity(some_entity).remove::<SomeBundle>();
```

Replace `remove_bundle_intersection` with `remove_intersection`:
```rust
// Old (0.8)
world.entity_mut(some_entity).remove_bundle_intersection::<SomeBundle>();
// New (0.9)
world.entity_mut(some_entity).remove_intersection::<SomeBundle>();
```

Consider consolidating as many operations as possible to improve ergonomics and cut down on archetype moves:
```rust
// Old (0.8)
commands.spawn()
  .insert_bundle(SomeBundle::default())
  .insert(SomeComponent);

// New (0.9) - Option 1
commands.spawn().insert((
  SomeBundle::default(),
  SomeComponent,
))

// New (0.9) - Option 2
commands.spawn_bundle((
  SomeBundle::default(),
  SomeComponent,
))
```

## Next Steps

Consider changing `spawn` to accept a bundle and deprecate `spawn_bundle`.
2022-09-21 21:47:53 +00:00
Daniel McNab
1a2aedd165 Implement Bundle for Component. Use Bundle tuples for insertion (#2975)
@BoxyUwU this is your fault. 

Also cart didn't arrive in time to tell us not to do this.

# Objective

- Fix #2974

## Solution

- The first commit just does the actual change
- Follow up commits do steps to prove that this method works to unify as required, but this does not remove `insert_bundle`.

## Changelog

### Changed
Nested bundles now collapse automatically, and every `Component` now implements `Bundle`.
This means that you can combine bundles and components arbitrarily, for example:
```rust
// before:
.insert(A).insert_bundle(MyBBundle{..})
// after:
.insert_bundle((A, MyBBundle {..}))
```

Note that there will be a follow up PR that removes the current `insert` impl and renames `insert_bundle` to `insert`.

### Removed
The `bundle` attribute in `derive(Bundle)`.

## Migration guide

In `derive(Bundle)`, the `bundle` attribute has been removed. Nested bundles are not collapsed automatically. You should remove `#[bundle]` attributes.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-09-20 20:17:08 +00:00
Gino Valente
d30d3e752a bevy_reflect: Improve serialization format even more (#5723)
> Note: This is rebased off #4561 and can be viewed as a competitor to that PR. See `Comparison with #4561` section for details.

# Objective

The current serialization format used by `bevy_reflect` is both verbose and error-prone. Taking the following structs[^1] for example:

```rust
// -- src/inventory.rs

#[derive(Reflect)]
struct Inventory {
  id: String,
  max_storage: usize,
  items: Vec<Item>
}

#[derive(Reflect)]
struct Item {
  name: String
}
```

Given an inventory of a single item, this would serialize to something like:

```rust
// -- assets/inventory.ron

{
  "type": "my_game::inventory::Inventory",
  "struct": {
    "id": {
      "type": "alloc::string::String",
      "value": "inv001",
    },
    "max_storage": {
      "type": "usize",
      "value": 10
    },
    "items": {
      "type": "alloc::vec::Vec<alloc::string::String>",
      "list": [
        {
          "type": "my_game::inventory::Item",
          "struct": {
            "name": {
              "type": "alloc::string::String",
              "value": "Pickaxe"
            },
          },
        },
      ],
    },
  },
}
```

Aside from being really long and difficult to read, it also has a few "gotchas" that users need to be aware of if they want to edit the file manually. A major one is the requirement that you use the proper keys for a given type. For structs, you need `"struct"`. For lists, `"list"`. For tuple structs, `"tuple_struct"`. And so on.

It also ***requires*** that the `"type"` entry come before the actual data. Despite being a map— which in programming is almost always orderless by default— the entries need to be in a particular order. Failure to follow the ordering convention results in a failure to deserialize the data.

This makes it very prone to errors and annoyances.


## Solution

Using #4042, we can remove a lot of the boilerplate and metadata needed by this older system. Since we now have static access to type information, we can simplify our serialized data to look like:

```rust
// -- assets/inventory.ron

{
  "my_game::inventory::Inventory": (
    id: "inv001",
    max_storage: 10,
    items: [
      (
        name: "Pickaxe"
      ),
    ],
  ),
}
```

This is much more digestible and a lot less error-prone (no more key requirements and no more extra type names).

Additionally, it is a lot more familiar to users as it follows conventional serde mechanics. For example, the struct is represented with `(...)` when serialized to RON.

#### Custom Serialization

Additionally, this PR adds the opt-in ability to specify a custom serde implementation to be used rather than the one created via reflection. For example[^1]:

```rust
// -- src/inventory.rs

#[derive(Reflect, Serialize)]
#[reflect(Serialize)]
struct Item {
  #[serde(alias = "id")]
  name: String
}
```

```rust
// -- assets/inventory.ron

{
  "my_game::inventory::Inventory": (
    id: "inv001",
    max_storage: 10,
    items: [
      (
        id: "Pickaxe"
      ),
    ],
  ),
},
```

By allowing users to define their own serialization methods, we do two things:

1. We give more control over how data is serialized/deserialized to the end user
2. We avoid having to re-define serde's attributes and forcing users to apply both (e.g. we don't need a `#[reflect(alias)]` attribute).

### Improved Formats

One of the improvements this PR provides is the ability to represent data in ways that are more conventional and/or familiar to users. Many users are familiar with RON so here are some of the ways we can now represent data in RON:

###### Structs

```js
{
  "my_crate::Foo": (
    bar: 123
  )
}
// OR
{
  "my_crate::Foo": Foo(
    bar: 123
  )
}
```

<details>
<summary>Old Format</summary>

```js
{
  "type": "my_crate::Foo",
  "struct": {
    "bar": {
      "type": "usize",
      "value": 123
    }
  }
}
```

</details>

###### Tuples

```js
{
  "(f32, f32)": (1.0, 2.0)
}
```

<details>
<summary>Old Format</summary>

```js
{
  "type": "(f32, f32)",
  "tuple": [
    {
      "type": "f32",
      "value": 1.0
    },
    {
      "type": "f32",
      "value": 2.0
    }
  ]
}
```

</details>

###### Tuple Structs

```js
{
  "my_crate::Bar": ("Hello World!")
}
// OR
{
  "my_crate::Bar": Bar("Hello World!")
}
```

<details>
<summary>Old Format</summary>

```js
{
  "type": "my_crate::Bar",
  "tuple_struct": [
    {
      "type": "alloc::string::String",
      "value": "Hello World!"
    }
  ]
}
```

</details>

###### Arrays

It may be a bit surprising to some, but arrays now also use the tuple format. This is because they essentially _are_ tuples (a sequence of values with a fixed size), but only allow for homogenous types. Additionally, this is how RON handles them and is probably a result of the 32-capacity limit imposed on them (both by [serde](https://docs.rs/serde/latest/serde/trait.Serialize.html#impl-Serialize-for-%5BT%3B%2032%5D) and by [bevy_reflect](https://docs.rs/bevy/latest/bevy/reflect/trait.GetTypeRegistration.html#impl-GetTypeRegistration-for-%5BT%3B%2032%5D)).

```js
{
  "[i32; 3]": (1, 2, 3)
}
```

<details>
<summary>Old Format</summary>

```js
{
  "type": "[i32; 3]",
  "array": [
    {
      "type": "i32",
      "value": 1
    },
    {
      "type": "i32",
      "value": 2
    },
    {
      "type": "i32",
      "value": 3
    }
  ]
}
```

</details>

###### Enums

To make things simple, I'll just put a struct variant here, but the style applies to all variant types:

```js
{
  "my_crate::ItemType": Consumable(
    name: "Healing potion"
  )
}
```

<details>
<summary>Old Format</summary>

```js
{
  "type": "my_crate::ItemType",
  "enum": {
    "variant": "Consumable",
    "struct": {
      "name": {
        "type": "alloc::string::String",
        "value": "Healing potion"
      }
    }
  }
}
```

</details>

### Comparison with #4561

This PR is a rebased version of #4561. The reason for the split between the two is because this PR creates a _very_ different scene format. You may notice that the PR descriptions for either PR are pretty similar. This was done to better convey the changes depending on which (if any) gets merged first. If #4561 makes it in first, I will update this PR description accordingly.

---

## Changelog

* Re-worked serialization/deserialization for reflected types
* Added `TypedReflectDeserializer` for deserializing data with known `TypeInfo`
* Renamed `ReflectDeserializer` to `UntypedReflectDeserializer` 
* ~~Replaced usages of `deserialize_any` with `deserialize_map` for non-self-describing formats~~ Reverted this change since there are still some issues that need to be sorted out (in a separate PR). By reverting this, crates like `bincode` can throw an error when attempting to deserialize non-self-describing formats (`bincode` results in `DeserializeAnyNotSupported`)
* Structs, tuples, tuple structs, arrays, and enums are now all de/serialized using conventional serde methods

## Migration Guide

* This PR reduces the verbosity of the scene format. Scenes will need to be updated accordingly:

```js
// Old format
{
  "type": "my_game::item::Item",
  "struct": {
    "id": {
      "type": "alloc::string::String",
      "value": "bevycraft:stone",
    },
    "tags": {
      "type": "alloc::vec::Vec<alloc::string::String>",
      "list": [
        {
          "type": "alloc::string::String",
          "value": "material"
        },
      ],
    },
}

// New format
{
  "my_game::item::Item": (
    id: "bevycraft:stone",
    tags: ["material"]
  )
}
```

[^1]: Some derives omitted for brevity.
2022-09-20 19:38:18 +00:00
ira
2b80a3f279 Implement IntoIterator for &Extract<P> (#6025)
# Objective

Implement `IntoIterator` for `&Extract<P>` if the system parameter it wraps implements `IntoIterator`.

Enables the use of `IntoIterator` with an extracted query.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-09-20 00:29:10 +00:00
ira
28205fd3f4 Remove AssetServer::watch_for_changes() (#5968)
# Objective
`AssetServer::watch_for_changes()` is racy and redundant with `AssetServerSettings`.
Closes #5964.

## Changelog

* Remove `AssetServer::watch_for_changes()`
* Add `AssetServerSettings` to the prelude.
* Minor cleanup.

## Migration Guide
`AssetServer::watch_for_changes()` was removed.
Instead, use the `AssetServerSettings` resource.
```rust
app // AssetServerSettings must be inserted before adding the AssetPlugin or DefaultPlugins.
	.insert_resource(AssetServerSettings {
		watch_for_changes: true,
		..default()
	})
```


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-09-19 16:36:38 +00:00
Maksymilian Mozolewski
ac1aebed5e Add reflect(skip_serializing) which retains reflection but disables automatic serialization (#5250)
# Objective

- To address problems outlined in https://github.com/bevyengine/bevy/issues/5245

## Solution

- Introduce `reflect(skip_serializing)` on top of `reflect(ignore)` which disables automatic serialisation to scenes, but does not disable reflection of the field.

---

## Changelog
- Adds: 
  - `bevy_reflect::serde::type_data` module
  - `SerializationData` structure for describing which fields are to be/not to be ignored, automatically registers as type_data for struct-based types
  - the `skip_serialization` flag for `#[reflect(...)]`
 - Removes:
   - ability to ignore Enum variants in serialization, since that didn't work anyway   
 

## Migration Guide
- Change `#[reflect(ignore)]` to `#[reflect(skip_serializing)]` where disabling reflection is not the intended effect.
- Remove ignore/skip attributes from enum variants as these won't do anything anymore
2022-09-19 16:12:10 +00:00
François
1b9720526e Scene example: write file in a task (#5952)
# Objective

- Fix #5951 
- Improve on #5949 by not risking blocking a system

## Solution

- Wrap file writing in a task
2022-09-12 12:19:40 +00:00
Wanderrful
f83a9c23f2 Add writing of scene data to Scene example (#5949)
# 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.
2022-09-11 20:18:57 +00:00
ira
76ae6f4c6e Miscellaneous code-quality improvements. (#5860)
Does what it do.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-09-05 00:30:21 +00:00
Alice Cecile
7a29c707bf Gamepad type is Copy; do not require / return references to it in Gamepads API (#5296)
# 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`.
2022-09-03 20:08:54 +00:00
JoJoJet
697d297b55 Remove last uses of string-labels (#5420)
# Objective

* Related: #4341
* Remove all remaining uses of stringly-typed labels in the repo. Right now, it's just a bunch of tests and examples.
2022-09-03 18:06:41 +00:00
ira
b42f426fc3 Add associated constant IDENTITY to Transform and friends. (#5340)
# Objective
Since `identity` is a const fn that takes no arguments it seems logical to make it an associated constant.
This is also more in line with types from glam (eg. `Quat::IDENTITY`).

## Migration Guide

The method `identity()` on `Transform`, `GlobalTransform` and `TransformBundle` has been deprecated.
Use the associated constant `IDENTITY` instead.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-08-30 22:10:24 +00:00
ira
65252bb87a Consistently use PI to specify angles in examples. (#5825)
Examples inconsistently use either `TAU`, `PI`, `FRAC_PI_2` or `FRAC_PI_4`.
Often in odd ways and without `use`ing the constants, making it difficult to parse.

 * Use `PI` to specify angles.
 * General code-quality improvements.
 * Fix borked `hierarchy` example.


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-08-30 19:52:11 +00:00
Andreas Weibye
74520c0e95 Add window resizing example (#5813)
# Objective

- Adopted from #3836
- Example showcases how to request a new resolution
- Example showcases how to react to resolution changes


Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
2022-08-29 23:56:43 +00:00
Andreas Weibye
4fadd26168 Add UI scaling (#5814)
# Objective

- Allow users to change the scaling of the UI
- Adopted from #2808

## Solution

- This is an accessibility feature for fixed-size UI elements, allowing the developer to expose a range of UI scales for the player to set a scale that works for their needs.

> - The user can modify the UiScale struct to change the scaling at runtime. This multiplies the Px values by the scale given, while not touching any others.
> - The example showcases how this even allows for fluid transitions

> Here's how the example looks like:

https://user-images.githubusercontent.com/1631166/132979069-044161a9-8e85-45ab-9e93-fcf8e3852c2b.mp4

---

## Changelog

- Added a `UiScale` which can be used to scale all of UI


Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-08-29 23:35:53 +00:00
Andreas Weibye
675607a7e6 Add AUTO and UNDEFINED const constructors for Size (#5761)
# Objective

Very small convenience constructors added to `Size`. 

Does not change current examples too much but I'm working on a rather complex UI use-case where this cuts down on some extra typing :)
2022-08-22 23:08:08 +00:00
Tomasz Galkowski
f9104b73a2 Use circle for breakout example (#5657)
# Objective

- Replace the square with a circle in the breakout example.
- Fixes #4324, adopted from #4682 by @shaderduck.

## Solution
- Uses the Mesh2D APIs to draw a circle. The collision still uses the AABB algorithm, but it seems to be working fine, and I haven't seen any odd looking cases.
2022-08-16 23:18:54 +00:00
Jonas Wagner
110831150e Make vertex colors work without textures in bevy_sprite (#5685)
# Objective

This PR changes it possible to use vertex colors without a texture using the bevy_sprite ColorMaterial.

Fixes #5679 

## Solution

- Made multiplication of the output color independent of the COLOR_MATERIAL_FLAGS_TEXTURE_BIT bit
- Extended mesh2d_vertex_color_texture example to show off both vertex colors and tinting

Not sure if extending the existing example was the right call but it seems to be reasonable to me.

I couldn't find any tests for the shaders and I think adding shader testing would be beyond the scope of this PR. So no tests in this PR. 😬 

Co-authored-by: Jonas Wagner <jonas@29a.ch>
2022-08-16 20:46:45 +00:00
Péter Leéh
21dacbf137 fix typos in examples (#5711)
## Objective
Fixed some typos I came across while reading examples.
2022-08-16 20:28:31 +00:00
ira
992681b59b Make Resource trait opt-in, requiring #[derive(Resource)] V2 (#5577)
*This PR description is an edited copy of #5007, written by @alice-i-cecile.*
# Objective
Follow-up to https://github.com/bevyengine/bevy/pull/2254. The `Resource` trait currently has a blanket implementation for all types that meet its bounds.

While ergonomic, this results in several drawbacks:

* it is possible to make confusing, silent mistakes such as inserting a function pointer (Foo) rather than a value (Foo::Bar) as a resource
* it is challenging to discover if a type is intended to be used as a resource
* we cannot later add customization options (see the [RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/27-derive-component.md) for the equivalent choice for Component).
* dependencies can use the same Rust type as a resource in invisibly conflicting ways
* raw Rust types used as resources cannot preserve privacy appropriately, as anyone able to access that type can read and write to internal values
* we cannot capture a definitive list of possible resources to display to users in an editor
## Notes to reviewers
 * Review this commit-by-commit; there's effectively no back-tracking and there's a lot of churn in some of these commits.
   *ira: My commits are not as well organized :')*
 * I've relaxed the bound on Local to Send + Sync + 'static: I don't think these concerns apply there, so this can keep things simple. Storing e.g. a u32 in a Local is fine, because there's a variable name attached explaining what it does.
 * I think this is a bad place for the Resource trait to live, but I've left it in place to make reviewing easier. IMO that's best tackled with https://github.com/bevyengine/bevy/issues/4981.

## Changelog
`Resource` is no longer automatically implemented for all matching types. Instead, use the new `#[derive(Resource)]` macro.

## Migration Guide
Add `#[derive(Resource)]` to all types you are using as a resource.

If you are using a third party type as a resource, wrap it in a tuple struct to bypass orphan rules. Consider deriving `Deref` and `DerefMut` to improve ergonomics.

`ClearColor` no longer implements `Component`. Using `ClearColor` as a component in 0.8 did nothing.
Use the `ClearColorConfig` in the `Camera3d` and `Camera2d` components instead.


Co-authored-by: Alice <alice.i.cecile@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: devil-ira <justthecooldude@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-08-08 21:36:35 +00:00
Charlie Hills
cd19d2757b use bevy_default() for texture format in post_processing (#5601)
# Objective

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

## Solution

Use bevy_default() for texture format in example to get proper texture format for wasm.
2022-08-07 20:26:13 +00:00
Peter Hebden
c27cc59e0d Remove unnecessary use from examples (#5583)
# Objective

`bevy::render::texture::ImageSettings` was added to prelude in #5566, so these `use` statements are unnecessary and the examples can be made a bit more concise.

## Solution

Remove `use bevy::render::texture::ImageSettings`
2022-08-06 01:19:57 +00:00
McSpidey
0ffb5441c3 changed diagnostics from seconds to milliseconds (#5554)
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>

# Objective

Change frametimediagnostic from seconds to milliseconds because this will always be less than one seconds and is the common diagnostic display unit for game engines.

## Solution

- multiplied the existing value by 1000

---

## Changelog

Frametimes are now reported in milliseconds

Co-authored-by: Syama Mishra <38512086+SyamaMishra@users.noreply.github.com>
Co-authored-by: McSpidey <mcspidey@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-08-04 22:27:14 +00:00
Gino Valente
15826d6019 bevy_reflect: Reflect enums (#4761)
# Objective

> This is a revival of #1347. Credit for the original PR should go to @Davier.

Currently, enums are treated as `ReflectRef::Value` types by `bevy_reflect`. Obviously, there needs to be better a better representation for enums using the reflection API.

## Solution

Based on prior work from @Davier, an `Enum` trait has been added as well as the ability to automatically implement it via the `Reflect` derive macro. This allows enums to be expressed dynamically:

```rust
#[derive(Reflect)]
enum Foo {
  A,
  B(usize),
  C { value: f32 },
}

let mut foo = Foo::B(123);
assert_eq!("B", foo.variant_name());
assert_eq!(1, foo.field_len());

let new_value = DynamicEnum::from(Foo::C { value: 1.23 });
foo.apply(&new_value);
assert_eq!(Foo::C{value: 1.23}, foo);
```

### Features

#### Derive Macro

Use the `#[derive(Reflect)]` macro to automatically implement the `Enum` trait for enum definitions. Optionally, you can use `#[reflect(ignore)]` with both variants and variant fields, just like you can with structs. These ignored items will not be considered as part of the reflection and cannot be accessed via reflection.

```rust
#[derive(Reflect)]
enum TestEnum {
  A,
  // Uncomment to ignore all of `B`
  // #[reflect(ignore)]
  B(usize),
  C {
    // Uncomment to ignore only field `foo` of `C`
    // #[reflect(ignore)]
    foo: f32,
    bar: bool,
  },
}
```

#### Dynamic Enums

Enums may be created/represented dynamically via the `DynamicEnum` struct. The main purpose of this struct is to allow enums to be deserialized into a partial state and to allow dynamic patching. In order to ensure conversion from a `DynamicEnum` to a concrete enum type goes smoothly, be sure to add `FromReflect` to your derive macro.

```rust
let mut value = TestEnum::A;

// Create from a concrete instance
let dyn_enum = DynamicEnum::from(TestEnum::B(123));

value.apply(&dyn_enum);
assert_eq!(TestEnum::B(123), value);

// Create a purely dynamic instance
let dyn_enum = DynamicEnum::new("TestEnum", "A", ());

value.apply(&dyn_enum);
assert_eq!(TestEnum::A, value);
```

#### Variants

An enum value is always represented as one of its variants— never the enum in its entirety.

```rust
let value = TestEnum::A;
assert_eq!("A", value.variant_name());

// Since we are using the `A` variant, we cannot also be the `B` variant
assert_ne!("B", value.variant_name());
```

All variant types are representable within the `Enum` trait: unit, struct, and tuple.

You can get the current type like:

```rust
match value.variant_type() {
  VariantType::Unit => println!("A unit variant!"),
  VariantType::Struct => println!("A struct variant!"),
  VariantType::Tuple => println!("A tuple variant!"),
}
```

> Notice that they don't contain any values representing the fields. These are purely tags.

If a variant has them, you can access the fields as well:

```rust
let mut value = TestEnum::C {
  foo: 1.23,
  bar: false
};

// Read/write specific fields
*value.field_mut("bar").unwrap() = true;

// Iterate over the entire collection of fields
for field in value.iter_fields() {
  println!("{} = {:?}", field.name(), field.value());
}
```

#### Variant Swapping

It might seem odd to group all variant types under a single trait (why allow `iter_fields` on a unit variant?), but the reason this was done ~~is to easily allow *variant swapping*.~~ As I was recently drafting up the **Design Decisions** section, I discovered that other solutions could have been made to work with variant swapping. So while there are reasons to keep the all-in-one approach, variant swapping is _not_ one of them.

```rust
let mut value: Box<dyn Enum> = Box::new(TestEnum::A);
value.set(Box::new(TestEnum::B(123))).unwrap();
```

#### Serialization

Enums can be serialized and deserialized via reflection without needing to implement `Serialize` or `Deserialize` themselves (which can save thousands of lines of generated code). Below are the ways an enum can be serialized.

> Note, like the rest of reflection-based serialization, the order of the keys in these representations is important!

##### Unit

```json
{
  "type": "my_crate::TestEnum",
  "enum": {
    "variant": "A"
  }
}
```

##### Tuple

```json
{
  "type": "my_crate::TestEnum",
  "enum": {
    "variant": "B",
    "tuple": [
      {
        "type": "usize",
        "value": 123
      }
    ]
  }
}
```

<details>
<summary>Effects on Option</summary>

This ends up making `Option` look a little ugly:

```json
{
  "type": "core::option::Option<usize>",
  "enum": {
    "variant": "Some",
    "tuple": [
      {
        "type": "usize",
        "value": 123
      }
    ]
  }
}
```


</details>

##### Struct

```json
{
  "type": "my_crate::TestEnum",
  "enum": {
    "variant": "C",
    "struct": {
      "foo": {
        "type": "f32",
        "value": 1.23
      },
      "bar": {
        "type": "bool",
        "value": false
      }
    }
  }
}
```

## Design Decisions

<details>
<summary><strong>View Section</strong></summary>

This section is here to provide some context for why certain decisions were made for this PR, alternatives that could have been used instead, and what could be improved upon in the future.

### Variant Representation

One of the biggest decisions was to decide on how to represent variants. The current design uses a "all-in-one" design where unit, tuple, and struct variants are all simultaneously represented by the `Enum` trait. This is not the only way it could have been done, though.

#### Alternatives

##### 1. Variant Traits

One way of representing variants would be to define traits for each variant, implementing them whenever an enum featured at least one instance of them. This would allow us to define variants like:

```rust
pub trait Enum: Reflect {
  fn variant(&self) -> Variant;
}

pub enum Variant<'a> {
    Unit,
    Tuple(&'a dyn TupleVariant),
    Struct(&'a dyn StructVariant),
}

pub trait TupleVariant {
  fn field_len(&self) -> usize;
  // ...
}
```

And then do things like:

```rust
fn get_tuple_len(foo: &dyn Enum) -> usize {
  match foo.variant() {
    Variant::Tuple(tuple) => tuple.field_len(),
    _ => panic!("not a tuple variant!")
  }
}
```

The reason this PR does not go with this approach is because of the fact that variants are not separate types. In other words, we cannot implement traits on specific variants— these cover the *entire* enum. This means we offer an easy footgun:

```rust
let foo: Option<i32> = None;
let my_enum = Box::new(foo) as Box<dyn TupleVariant>;
```

Here, `my_enum` contains `foo`, which is a unit variant. However, since we need to implement `TupleVariant` for `Option` as a whole, it's possible to perform such a cast. This is obviously wrong, but could easily go unnoticed. So unfortunately, this makes it not a good candidate for representing variants.

##### 2. Variant Structs

To get around the issue of traits necessarily needing to apply to both the enum and its variants, we could instead use structs that are created on a per-variant basis. This was also considered but was ultimately [[removed](71d27ab3c6) due to concerns about allocations.

 Each variant struct would probably look something like:

```rust
pub trait Enum: Reflect {
  fn variant_mut(&self) -> VariantMut;
}

pub enum VariantMut<'a> {
    Unit,
    Tuple(TupleVariantMut),
    Struct(StructVariantMut),
}

struct StructVariantMut<'a> {
  fields: Vec<&'a mut dyn Reflect>,
  field_indices: HashMap<Cow<'static, str>, usize>
}
```

This allows us to isolate struct variants into their own defined struct and define methods specifically for their use. It also prevents users from casting to it since it's not a trait. However, this is not an optimal solution. Both `field_indices` and `fields` will require an allocation (remember, a `Box<[T]>` still requires a `Vec<T>` in order to be constructed). This *might* be a problem if called frequently enough.

##### 3. Generated Structs

The original design, implemented by @Davier, instead generates structs specific for each variant. So if we had a variant path like `Foo::Bar`, we'd generate a struct named `FooBarWrapper`. This would be newtyped around the original enum and forward tuple or struct methods to the enum with the chosen variant.

Because it involved using the `Tuple` and `Struct` traits (which are also both bound on `Reflect`), this meant a bit more code had to be generated. For a single struct variant with one field, the generated code amounted to ~110LoC. However, each new field added to that variant only added ~6 more LoC.

In order to work properly, the enum had to be transmuted to the generated struct:

```rust
fn variant(&self) -> crate::EnumVariant<'_> {
  match self {
    Foo::Bar {value: i32} => {
      let wrapper_ref = unsafe { 
        std::mem::transmute::<&Self, &FooBarWrapper>(self) 
      };
      crate::EnumVariant::Struct(wrapper_ref as &dyn crate::Struct)
    }
  }
}
```

This works because `FooBarWrapper` is defined as `repr(transparent)`.

Out of all the alternatives, this would probably be the one most likely to be used again in the future. The reasons for why this PR did not continue to use it was because:

* To reduce generated code (which would hopefully speed up compile times)
* To avoid cluttering the code with generated structs not visible to the user
* To keep bevy_reflect simple and extensible (these generated structs act as proxies and might not play well with current or future systems)
* To avoid additional unsafe blocks
* My own misunderstanding of @Davier's code

That last point is obviously on me. I misjudged the code to be too unsafe and unable to handle variant swapping (which it probably could) when I was rebasing it. Looking over it again when writing up this whole section, I see that it was actually a pretty clever way of handling variant representation.

#### Benefits of All-in-One

As stated before, the current implementation uses an all-in-one approach. All variants are capable of containing fields as far as `Enum` is concerned. This provides a few benefits that the alternatives do not (reduced indirection, safer code, etc.).

The biggest benefit, though, is direct field access. Rather than forcing users to have to go through pattern matching, we grant direct access to the fields contained by the current variant. The reason we can do this is because all of the pattern matching happens internally. Getting the field at index `2` will automatically return `Some(...)` for the current variant if it has a field at that index or `None` if it doesn't (or can't).

This could be useful for scenarios where the variant has already been verified or just set/swapped (or even where the type of variant doesn't matter):

```rust
let dyn_enum: &mut dyn Enum = &mut Foo::Bar {value: 123};
// We know it's the `Bar` variant
let field = dyn_enum.field("value").unwrap();
```

Reflection is not a type-safe abstraction— almost every return value is wrapped in `Option<...>`. There are plenty of places to check and recheck that a value is what Reflect says it is. Forcing users to have to go through `match` each time they want to access a field might just be an extra step among dozens of other verification processes.

 Some might disagree, but ultimately, my view is that the benefit here is an improvement to the ergonomics and usability of reflected enums.

</details>

---

## Changelog

### Added

* Added `Enum` trait
* Added `Enum` impl to `Reflect` derive macro
* Added `DynamicEnum` struct
  * Added `DynamicVariant`
* Added `EnumInfo`
  * Added `VariantInfo`
    * Added `StructVariantInfo`
    * Added `TupleVariantInfo`
    * Added `UnitVariantInfo`
* Added serializtion/deserialization support for enums
  * Added `EnumSerializer`

* Added `VariantType`
* Added `VariantFieldIter`
* Added `VariantField`
* Added `enum_partial_eq(...)`
* Added `enum_hash(...)`

### Changed

* `Option<T>` now implements `Enum`
* `bevy_window` now depends on `bevy_reflect`
  * Implemented `Reflect` and `FromReflect` for `WindowId`
* Derive `FromReflect` on `PerspectiveProjection`
* Derive `FromReflect` on `OrthographicProjection`
* Derive `FromReflect` on `WindowOrigin`
* Derive `FromReflect` on `ScalingMode`
* Derive `FromReflect` on `DepthCalculation`


## Migration Guide

* Enums no longer need to be treated as values and usages of `#[reflect_value(...)]` can be removed or replaced by `#[reflect(...)]`
* Enums (including `Option<T>`) now take a different format when serializing. The format is described above, but this may cause issues for existing scenes that make use of enums. 

---

Also shout out to @nicopap for helping clean up some of the code here! It's a big feature so help like this is really appreciated!

Co-authored-by: Gino Valente <gino.valente.code@gmail.com>
2022-08-02 22:14:41 +00:00
Robert Swain
05e5008624 Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective

- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .

## Solution

- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
  - This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
  - Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.

---

## Changelog

- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
Rob Parrett
5666788628 Fix blurry debug texture in 3d shapes example (#5472)
# Objective

The 3d shapes example uses a "UV debug texture" which probably works best with nearest neighbor filtering, but the default is now linear.

<img width="1392" alt="Screen Shot 2022-07-27 at 7 08 19 PM" src="https://user-images.githubusercontent.com/200550/181405101-f91d6ced-be80-4bf4-b6bb-79e0da9b9c6e.png">

## Solution

Add `ImageSettings::default_nearest()`

<img width="1392" alt="Screen Shot 2022-07-27 at 7 08 37 PM" src="https://user-images.githubusercontent.com/200550/181405149-3809f5f9-9ea7-4b4a-8387-6e5bef6d00e4.png">
2022-07-28 02:19:32 +00:00
Nicola Papale
a7f2120c9e Wasm optimization tips (#5443)
# Objective

Add a section to the example's README on how
to reduce generated wasm executable size.

Add a `wasm-release` profile to bevy's `Cargo.toml`
in order to use it when building bevy-website.

Notes:
- We do not recommend `strip = "symbols"` since it breaks bindgen
- see https://github.com/bevyengine/bevy-website/pull/402
2022-07-25 15:48:13 +00:00
Nicola Papale
a96b3b2e2f Add stress test for many ui elements (#5253)
# Objective

Bevy need a way to benchmark UI rendering code,
this PR adds a stress test that spawns a lot of buttons.

## Solution

- Add the `many_buttons` stress test.

---

## Changelog

- Add the `many_buttons` stress test.
2022-07-21 14:39:03 +00:00
sark
84bf6f611a Export anyhow::error for custom asset loaders (#5359)
If users try to implement a custom asset loader, they must manually import anyhow::error as it's used by the asset loader trait but not exported.

2b93ab5812/examples/asset/custom_asset.rs (L25)

Fixes #3138

Co-authored-by: sark <sarkahn@hotmail.com>
2022-07-20 14:14:30 +00:00
ira
9f906fdc8b Improve ergonomics and reduce boilerplate around creating text elements. (#5343)
# Objective

Creating UI elements is very boilerplate-y with lots of indentation.
This PR aims to reduce boilerplate around creating text elements.

## Changelog

* Renamed `Text::with_section` to `from_section`.
  It no longer takes a `TextAlignment` as argument, as the vast majority of cases left it `Default::default()`.
* Added `Text::from_sections` which creates a `Text` from a list of `TextSections`.
  Reduces line-count and reduces indentation by one level.
* Added `Text::with_alignment`.
  A builder style method for setting the `TextAlignment` of a `Text`.
* Added `TextSection::new`.
  Does not reduce line count, but reduces character count and made it easier to read. No more `.to_string()` calls!
* Added `TextSection::from_style` which creates an empty `TextSection` with a style.
  No more empty strings! Reduces indentation.
* Added `TextAlignment::CENTER` and friends.
* Added methods to `TextBundle`. `from_section`, `from_sections`, `with_text_alignment` and `with_style`.

## Note for reviewers.
Because of the nature of these changes I recommend setting diff view to 'split'.
~~Look for the book icon~~ cog in the top-left of the Files changed tab.

Have fun reviewing ❤️
<sup> >:D </sup>

## Migration Guide

`Text::with_section` was renamed to `from_section` and no longer takes a `TextAlignment` as argument.
Use `with_alignment` to set the alignment instead.

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-20 14:14:29 +00:00
Matthew Taylor
50a44417ba Derive AsBindGroup Improvements: Better errors, more options, update examples (#5364)
# Objective

- Provide better compile-time errors and diagnostics.
- Add more options to allow more textures types and sampler types.
- Update array_texture example to use upgraded AsBindGroup derive macro.

## Solution

Split out the parsing of the inner struct/field attributes (the inside part of a `#[foo(...)]` attribute) for better clarity

Parse the binding index for all inner attributes, as it is part of all attributes (`#[foo(0, ...)`), then allow each attribute implementer to parse the rest of the attribute metadata as needed. This should make it very trivial to extend/change if needed in the future.

Replaced invocations of `panic!` with the `syn::Error` type, providing fine-grained errors that retains span information. This provides much nicer compile-time errors, and even better IDE errors.

![image](https://user-images.githubusercontent.com/7478134/179452241-6d85d440-4b67-44da-80a7-9d47e8c88b8a.png)

Updated the array_texture example to demonstrate the new changes.

## New AsBindGroup attribute options


### `#[texture(u32, ...)]`
Where `...` is an optional list of arguments.
| Arguments    	| Values                                                         	| Default |
|--------------	|----------------------------------------------------------------	| ----------- |
| dimension = "..."    	| `"1d"`, `"2d"`, `"2d_array"`, `"3d"`, `"cube"`, `"cube_array"` 	|    `"2d"`    |
| sample_type = "..."  	| `"float"`, `"depth"`, `"s_int"` or `"u_int"`                   	|    `"float"`    |
| filterable = ...   	| `true`, `false`                                                	|    `true`     |
| multisampled = ... 	| `true`, `false`                                                	|    `false` |
| visibility(...) 	| `all`, `none`, or a list-combination of `vertex`, `fragment`, `compute` |   `vertex`, `fragment`   |

Example: `#[texture(0, dimension = "2d_array", visibility(vertex, fragment))]`


### `#[sampler(u32, ...)]`
Where `...` is an optional list of arguments.
| Arguments 	| Values                                            	| Default |
|-----------	|---------------------------------------------------	| ----------- |
| sampler_type = "..."   	| `"filtering"`, `"non_filtering"`, `"comparison"`. 	|  `"filtering"`  |
| visibility(...) 	| `all`, `none`, or a list-combination of `vertex`, `fragment`, `compute` |   `vertex`, `fragment`   |

Example: `#[sampler(0, sampler_type = "filtering", visibility(vertex, fragment)]`

## Changelog

- Added more options to `#[texture(...)]` and `#[sampler(...)]` attributes, supporting more kinds of materials. See above for details.
- Upgraded IDE and compile-time error messages.
- Updated array_texture example using the new options.
2022-07-19 22:05:43 +00:00
François
4affc8cd93 add a SpatialBundle with visibility and transform components (#5344)
# Objective

- Help user when they need to add both a `TransformBundle` and a `VisibilityBundle`

## Solution

- Add a `SpatialBundle` adding all components
2022-07-18 23:27:30 +00:00
ira
3fdf40d9c8 Make the contributor birbs bounce to the window height! (#5274)
Birbs no longer bounce too low, not coming close to their true bouncy potential.
Birbs also no longer bonk head when window is smaller. (Will still bonk head when window is made smaller too fast! pls no)

*cough cough*
Make the height of the birb-bounces dependent on the window size so they always bounce elegantly towards the top of the window.
Also no longer panics when closing the window q:

~~Might put a video here if I figure out how to.~~
<sup> rendering video is hard. birbrate go brr

Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-17 12:34:31 +00:00
Rob Parrett
a63d761aa3 Add VisibilityBundle and use it to fix gltfs, scenes, and examples (#5335)
# Objective

Gltfs, and a few examples were broken by #5310. Fix em.

Closes #5334

## Solution

Add `VisibilityBundle` as described here: https://github.com/bevyengine/bevy/issues/5334#issuecomment-1186050778 and sprinkle it around where needed.
2022-07-16 02:47:23 +00:00
Dusty DeWeese
9f8bdeeeb9 Use Affine3A for GlobalTransform to allow any affine transformation (#4379)
# Objective

- Add capability to use `Affine3A`s for some `GlobalTransform`s. This allows affine transformations that are not possible using a single `Transform` such as shear and non-uniform scaling along an arbitrary axis.
- Related to #1755 and #2026

## Solution

- `GlobalTransform` becomes an enum wrapping either a `Transform` or an `Affine3A`.
- The API of `GlobalTransform` is minimized to avoid inefficiency, and to make it clear that operations should be performed using the underlying data types.
- using `GlobalTransform::Affine3A` disables transform propagation, because the main use is for cases that `Transform`s cannot support.

---

## Changelog

- `GlobalTransform`s can optionally support any affine transformation using an `Affine3A`.


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-16 00:51:12 +00:00
Johan Klokkhammer Helsing
8810a73e87 Support AsBindGroup for 2d materials as well (#5312)
Port changes made to Material in #5053 to Material2d as well.

This is more or less an exact copy of the implementation in bevy_pbr; I
simply pretended the API existed, then copied stuff over until it
started building and the shapes example was working again.

# Objective

The changes in #5053 makes it possible to add custom materials with a lot less boiler plate. However, the implementation isn't shared with Material 2d as it's a kind of fork of the bevy_pbr version. It should be possible to use AsBindGroup on the 2d version as well.

## Solution

This makes the same kind of changes in Material2d in bevy_sprite.

This makes the following work:

```rust
//! Draws a circular purple bevy in the middle of the screen using a custom shader

use bevy::{
    prelude::*,
    reflect::TypeUuid,
    render::render_resource::{AsBindGroup, ShaderRef},
    sprite::{Material2d, Material2dPlugin, MaterialMesh2dBundle},
};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(Material2dPlugin::<CustomMaterial>::default())
        .add_startup_system(setup)
        .run();
}

/// set up a simple 2D scene
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<CustomMaterial>>,
    asset_server: Res<AssetServer>,
) {
    commands.spawn_bundle(MaterialMesh2dBundle {
        mesh: meshes.add(shape::Circle::new(50.).into()).into(),
        material: materials.add(CustomMaterial {
            color: Color::PURPLE,
            color_texture: Some(asset_server.load("branding/icon.png")),
        }),
        transform: Transform::from_translation(Vec3::new(-100., 0., 0.)),
        ..default()
    });

    commands.spawn_bundle(Camera2dBundle::default());
}

/// The Material2d trait is very configurable, but comes with sensible defaults for all methods.
/// You only need to implement functions for features that need non-default behavior. See the Material api docs for details!
impl Material2d for CustomMaterial {
    fn fragment_shader() -> ShaderRef {
        "shaders/custom_material.wgsl".into()
    }
}

// This is the struct that will be passed to your shader
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
pub struct CustomMaterial {
    #[uniform(0)]
    color: Color,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Option<Handle<Image>>,
}
```
2022-07-16 00:20:04 +00:00
Carter Anderson
40d4992401 Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310)
# Objective

Fixes #4907. Fixes #838. Fixes #5089.
Supersedes #5146. Supersedes #2087. Supersedes #865. Supersedes #5114

Visibility is currently entirely local. Set a parent entity to be invisible, and the children are still visible. This makes it hard for users to hide entire hierarchies of entities.

Additionally, the semantics of `Visibility` vs `ComputedVisibility` are inconsistent across entity types. 3D meshes use `ComputedVisibility` as the "definitive" visibility component, with `Visibility` being just one data source. Sprites just use `Visibility`, which means they can't feed off of `ComputedVisibility` data, such as culling information, RenderLayers, and (added in this pr) visibility inheritance information.

## Solution

Splits `ComputedVisibilty::is_visible` into `ComputedVisibilty::is_visible_in_view` and `ComputedVisibilty::is_visible_in_hierarchy`. For each visible entity, `is_visible_in_hierarchy` is computed by propagating visibility down the hierarchy. The `ComputedVisibility::is_visible()` function combines these two booleans for the canonical "is this entity visible" function.

Additionally, all entities that have `Visibility` now also have `ComputedVisibility`.  Sprites, Lights, and UI entities now use `ComputedVisibility` when appropriate.

This means that in addition to visibility inheritance, everything using Visibility now also supports RenderLayers. Notably, Sprites (and other 2d objects) now support `RenderLayers` and work properly across multiple views.

Also note that this does increase the amount of work done per sprite. Bevymark with 100,000 sprites on `main` runs in `0.017612` seconds and this runs in `0.01902`. That is certainly a gap, but I believe the api consistency and extra functionality this buys us is worth it. See [this thread](https://github.com/bevyengine/bevy/pull/5146#issuecomment-1182783452) for more info. Note that #5146 in combination with #5114 _are_ a viable alternative to this PR and _would_ perform better, but that comes at the cost of api inconsistencies and doing visibility calculations in the "wrong" place. The current visibility system does have potential for performance improvements. I would prefer to evolve that one system as a whole rather than doing custom hacks / different behaviors for each feature slice.

Here is a "split screen" example where the left camera uses RenderLayers to filter out the blue sprite.

![image](https://user-images.githubusercontent.com/2694663/178814868-2e9a2173-bf8c-4c79-8815-633899d492c3.png)


Note that this builds directly on #5146 and that @james7132 deserves the credit for the baseline visibility inheritance work. This pr moves the inherited visibility field into `ComputedVisibility`, then does the additional work of porting everything to `ComputedVisibility`. See my [comments here](https://github.com/bevyengine/bevy/pull/5146#issuecomment-1182783452) for rationale. 

## Follow up work

* Now that lights use ComputedVisibility, VisibleEntities now includes "visible lights" in the entity list. Functionally not a problem as we use queries to filter the list down in the desired context. But we should consider splitting this out into a separate`VisibleLights` collection for both clarity and performance reasons. And _maybe_ even consider scoping `VisibleEntities` down to `VisibleMeshes`?.
* Investigate alternative sprite rendering impls (in combination with visibility system tweaks) that avoid re-generating a per-view fixedbitset of visible entities every frame, then checking each ExtractedEntity. This is where most of the performance overhead lives. Ex: we could generate ExtractedEntities per-view using the VisibleEntities list, avoiding the need for the bitset.
* Should ComputedVisibility use bitflags under the hood? This would cut down on the size of the component, potentially speed up the `is_visible()` function, and allow us to cheaply expand ComputedVisibility with more data (ex: split out local visibility and parent visibility, add more culling classes, etc).
---

## Changelog

* ComputedVisibility now takes hierarchy visibility into account.
* 2D, UI and Light entities now use the ComputedVisibility component.

## Migration Guide

If you were previously reading `Visibility::is_visible` as the "actual visibility" for sprites or lights, use `ComputedVisibilty::is_visible()` instead:

```rust
// before (0.7)
fn system(query: Query<&Visibility>) {
  for visibility in query.iter() {
    if visibility.is_visible {
       log!("found visible entity");
    }
  }
}

// after (0.8)
fn system(query: Query<&ComputedVisibility>) {
  for visibility in query.iter() {
    if visibility.is_visible() {
       log!("found visible entity");
    }
  }
}
``` 


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-15 23:24:42 +00:00
Charles
6b34e81f00 add a 3d lines example (#5319)
# Objective

- Showcase how to use a `Material` and `Mesh` to spawn 3d lines

![image](https://user-images.githubusercontent.com/8348954/179034236-ebc07f90-3eb5-46cc-8fc1-be7e6bf983fb.png)

## Solution

- Add an example using a simple `Material` and `Mesh` definition to draw a 3d line
	- Shows how to use `LineList` and `LineStrip` in combination with a specialized `Material`

## Notes

This isn't just a primitive shape because it needs a special Material, but I think it's a good showcase of the power of the `Material` and `AsBindGroup` abstractions. All of this is easy to figure out when you know these options are a thing, but I think they are hard to discover which is why I think this should be an example and not shipped with bevy.

Co-authored-by: Charles <IceSentry@users.noreply.github.com>
2022-07-15 22:37:05 +00:00
François
814f8d1635 update wgpu to 0.13 (#5168)
# Objective

- Update wgpu to 0.13
- ~~Wait, is wgpu 0.13 released? No, but I had most of the changes already ready since playing with webgpu~~ well it has been released now
- Also update parking_lot to 0.12 and naga to 0.9

## Solution

- Update syntax for wgsl shaders https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#wgsl-syntax
- Add a few options, remove some references: https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#other-breaking-changes
- fragment inputs should now exactly match vertex outputs for locations, so I added exports for those to be able to reuse them https://github.com/gfx-rs/wgpu/pull/2704
2022-07-14 21:17:16 +00:00
ira
234e5af882 Implement From<bool> for ShouldRun. (#5306)
Make writing simple yes/no run criteria easier.


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-14 17:26:40 +00:00
Félix Lescaudey de Maneville
dc3b4b6c85 Added colors to sprite stress test (#5317)
# Objective

Allow better performance testing for https://github.com/bevyengine/bevy/pull/5247


## Solution

I added color tints to the `many_sprites` example stress test.
2022-07-14 11:03:13 +00:00
Troels Jessen
b3d15153f3 Added performance warning when running stress test examples in debug mode (#5029)
# Objective

Fixes #5028

## Solution
Used #[cfg(debug_assertions)] to display a warning when running examples under stress_tests in debug mode
2022-07-13 19:13:46 +00:00
CGMossa
93a131661d Very minor doc formatting changes (#5287)
# Objective

- Added a bunch of backticks to things that should have them, like equations, abstract variable names,
- Changed all small x, y, and z to capitals X, Y, Z.

This might be more annoying than helpful; Feel free to refuse this PR.
2022-07-12 13:06:16 +00:00
ira
4847f7e3ad Update codebase to use IntoIterator where possible. (#5269)
Remove unnecessary calls to `iter()`/`iter_mut()`.
Mainly updates the use of queries in our code, docs, and examples.

```rust
// From
for _ in list.iter() {
for _ in list.iter_mut() {

// To
for _ in &list {
for _ in &mut list {
```

We already enable the pedantic lint [clippy::explicit_iter_loop](https://rust-lang.github.io/rust-clippy/stable/) inside of Bevy. However, this only warns for a few known types from the standard library.

## Note for reviewers
As you can see the additions and deletions are exactly equal.
Maybe give it a quick skim to check I didn't sneak in a crypto miner, but you don't have to torture yourself by reading every line.
I already experienced enough pain making this PR :) 


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-11 15:28:50 +00:00
Christian Legnitto
2344ada89f Rename headless_defaults example to no_renderer for clarity (#5263)
# Objective

- Reduce confusion as the example opens a window and isn't truly "headless"
- Fixes https://github.com/bevyengine/bevy/issues/5260.


## Solution

- Rename the example and add to the docs that the window is expected.
2022-07-11 14:11:32 +00:00
James Liu
8eb0440f1e Hierarchy commandization (#4197)
## Objective
Implement absolute minimum viable product for the changes proposed in bevyengine/rfcs#53.

## Solution

 - Remove public mutative access to `Parent` (Children is already publicly read-only). This includes public construction methods like `Copy`, `Clone`, and `Default`.
 - Remove `PreviousParent`
 - Remove `parent_update_system`
 - Update all hierarchy related commands to immediately update both `Parent` and `Children` references.

## Remaining TODOs

 - [ ] Update documentation for both `Parent` and `Children`. Discourage using `EntityCommands::remove`
 - [x] Add `HierarchyEvent` to notify listeners of hierarchy updates. This is meant to replace listening on `PreviousParent`

## Followup

 - These changes should be best moved to the hooks mentioned in #3742.
 - Backing storage for both might be best moved to indexes mentioned in the same relations.
2022-07-10 20:29:06 +00:00
Daniel McNab
7b2cf98896 Make RenderStage::Extract run on the render world (#4402)
# Objective

- Currently, the `Extract` `RenderStage` is executed on the main world, with the render world available as a resource.
- However, when needing access to resources in the render world (e.g. to mutate them), the only way to do so was to get exclusive access to the whole `RenderWorld` resource.
- This meant that effectively only one extract which wrote to resources could run at a time.
- We didn't previously make `Extract`ing writing to the world a non-happy path, even though we want to discourage that.

## Solution

- Move the extract stage to run on the render world.
- Add the main world as a `MainWorld` resource.
- Add an `Extract` `SystemParam` as a convenience to access a (read only) `SystemParam` in the main world during `Extract`.

## Future work

It should be possible to avoid needing to use `get_or_spawn` for the render commands, since now the `Commands`' `Entities` matches up with the world being executed on.
We need to determine how this interacts with https://github.com/bevyengine/bevy/pull/3519
It's theoretically possible to remove the need for the `value` method on `Extract`. However, that requires slightly changing the `SystemParam` interface, which would make it more complicated. That would probably mess up the `SystemState` api too.

## Todo
I still need to add doc comments to `Extract`.

---

## Changelog

### Changed
- The `Extract` `RenderStage` now runs on the render world (instead of the main world as before).
   You must use the `Extract` `SystemParam` to access the main world during the extract phase.
   Resources on the render world can now be accessed using `ResMut` during extract.

### Removed
- `Commands::spawn_and_forget`. Use `Commands::get_or_spawn(e).insert_bundle(bundle)` instead

## Migration Guide

The `Extract` `RenderStage` now runs on the render world (instead of the main world as before).
You must use the `Extract` `SystemParam` to access the main world during the extract phase. `Extract` takes a single type parameter, which is any system parameter (such as `Res`, `Query` etc.). It will extract this from the main world, and returns the result of this extraction when `value` is called on it.

For example, if previously your extract system looked like:
```rust
fn extract_clouds(mut commands: Commands, clouds: Query<Entity, With<Cloud>>) {
    for cloud in clouds.iter() {
        commands.get_or_spawn(cloud).insert(Cloud);
    }
}
```
the new version would be:
```rust
fn extract_clouds(mut commands: Commands, mut clouds: Extract<Query<Entity, With<Cloud>>>) {
    for cloud in clouds.value().iter() {
        commands.get_or_spawn(cloud).insert(Cloud);
    }
}
```
The diff is:
```diff
--- a/src/clouds.rs
+++ b/src/clouds.rs
@@ -1,5 +1,5 @@
-fn extract_clouds(mut commands: Commands, clouds: Query<Entity, With<Cloud>>) {
-    for cloud in clouds.iter() {
+fn extract_clouds(mut commands: Commands, mut clouds: Extract<Query<Entity, With<Cloud>>>) {
+    for cloud in clouds.value().iter() {
         commands.get_or_spawn(cloud).insert(Cloud);
     }
 }
```
You can now also access resources from the render world using the normal system parameters during `Extract`:
```rust
fn extract_assets(mut render_assets: ResMut<MyAssets>, source_assets: Extract<Res<MyAssets>>) {
     *render_assets = source_assets.clone();
}
```
Please note that all existing extract systems need to be updated to match this new style; even if they currently compile they will not run as expected. A warning will be emitted on a best-effort basis if this is not met.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-08 23:56:33 +00:00
robtfm
132950cd55 Spotlights (#4715)
# Objective

add spotlight support

## Solution / Changelog

- add spotlight angles (inner, outer) to ``PointLight`` struct. emitted light is linearly attenuated from 100% to 0% as angle tends from inner to outer. Direction is taken from the existing transform rotation.
- add spotlight direction (vec3) and angles (f32,f32) to ``GpuPointLight`` struct (60 bytes -> 80 bytes) in ``pbr/render/lights.rs`` and ``mesh_view_bind_group.wgsl``
- reduce no-buffer-support max point light count to 204 due to above
- use spotlight data to attenuate light in ``pbr.wgsl``
- do additional cluster culling on spotlights to minimise cost in ``assign_lights_to_clusters``
- changed one of the lights in the lighting demo to a spotlight
- also added a ``spotlight`` demo - probably not justified but so reviewers can see it more easily

## notes

increasing the size of the GpuPointLight struct on my machine reduces the FPS of ``many_lights -- sphere`` from ~150fps to 140fps. 

i thought this was a reasonable tradeoff, and felt better than handling spotlights separately which is possible but would mean introducing a new bind group, refactoring light-assignment code and adding new spotlight-specific code in pbr.wgsl. the FPS impact for smaller numbers of lights should be very small.

the cluster culling strategy reintroduces the cluster aabb code which was recently removed... sorry. the aabb is used to get a cluster bounding sphere, which can then be tested fairly efficiently using the strategy described at the end of https://bartwronski.com/2017/04/13/cull-that-cone/. this works well with roughly cubic clusters (where the cluster z size is close to the same as x/y size), less well for other cases like single Z slice / tiled forward rendering. In the worst case we will end up just keeping the culling of the equivalent point light.

Co-authored-by: François <mockersf@gmail.com>
2022-07-08 19:57:43 +00:00
Boutillier
6b073ee412 Update shader_material_glsl example to include texture sampling (#5215)
# Objective

Add texture sampling to the GLSL shader example, as naga does not support the commonly used sampler2d type.
Fixes #5059

## Solution

- Align the shader_material_glsl example behaviour with the shader_material example,  as the later includes texture sampling.
- Update the GLSL shader to do texture sampling the way naga supports it, and document the way naga does not support it.

## Changelog

- The shader_material_glsl example has been updated to demonstrate texture sampling using the GLSL shading language.


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-08 01:14:22 +00:00
Mark Lodato
a249e95693 Fix small typo in example name (#5217)
**This Commit**
Renames "Scale Factor Iverride" to
"Scale Factor Override".

**Why?**
I imagine the current name is a typo.
2022-07-05 16:59:31 +00:00
Robin KAY
5b5013d540 Add ViewRangefinder3d to reduce boilerplate when enqueuing standard 3D PhaseItems. (#5014)
# Objective

Reduce the boilerplate code needed to make draw order sorting work correctly when queuing items through new common functionality. Also fix several instances in the bevy code-base (mostly examples) where this boilerplate appears to be incorrect.

## Solution

- Moved the logic for handling back-to-front vs front-to-back draw ordering into the PhaseItems by inverting the sort key ordering of Opaque3d and AlphaMask3d. The means that all the standard 3d rendering phases measure distance in the same way. Clients of these structs no longer need to know to negate the distance.
- Added a new utility struct, ViewRangefinder3d, which encapsulates the maths needed to calculate a "distance" from an ExtractedView and a mesh's transform matrix.
- Converted all the occurrences of the distance calculations in Bevy and its examples to use ViewRangefinder3d. Several of these occurrences appear to be buggy because they don't invert the view matrix or don't negate the distance where appropriate. This leads me to the view that Bevy should expose a facility to correctly perform this calculation.

## Migration Guide

Code which creates Opaque3d, AlphaMask3d, or Transparent3d phase items _should_ use ViewRangefinder3d to calculate the distance value.

Code which manually calculated the distance for Opaque3d or AlphaMask3d phase items and correctly negated the z value will no longer depth sort correctly. However, incorrect depth sorting for these types will not impact the rendered output as sorting is only a performance optimisation when drawing with depth-testing enabled. Code which manually calculated the distance for Transparent3d phase items will continue to work as before.
2022-07-05 06:13:39 +00:00
James O'Brien
46f5411605 Add TextureAtlas stress test based on many_sprites and sprite_sheet examples (#5087)
# Objective

Intended to close #5073

## Solution

Adds a stress test that use TextureAtlas based on the existing many_sprites test using the animated sprite implementation from the sprite_sheet example.

In order to satisfy the goals described in #5073 the animations are all slightly offset.

Of note is that the original stress test was designed to test fullstrum culling. I kept this test similar as to facilitate easy comparisons between the use of TextureAtlas and without.
2022-07-04 13:04:15 +00:00
Elabajaba
72e7358636 Disable Vsync for stress tests. (#5187)
# Objective

Currently stress tests are vsynced. This is undesirable for a stress test, as you want to run them with uncapped framerates.

## Solution

Ensure all stress tests are using PresentMode::Immediate if they render anything.
2022-07-03 20:17:27 +00:00
CGMossa
33f9b3940d Updated glam to 0.21. (#5142)
Removed `const_vec2`/`const_vec3`
and replaced with equivalent `.from_array`.

# Objective

Fixes #5112 

## Solution

- `encase` needs to update to `glam` as well. See teoxoy/encase#4 on progress on that. 
- `hexasphere` also needs to be updated, see OptimisticPeach/hexasphere#12.
2022-07-03 19:55:33 +00:00
SarthakSingh31
cdbabb7053 Removed world cell from places where split multable access is not needed (#5167)
Fixes #5109.
2022-07-01 17:03:32 +00:00
Jakob Hellermann
49ff42cc69 fix new clippy lints (#5160)
# Objective

- Nightly clippy lints should be fixed before they get stable and break CI
  
## Solution

- fix new clippy lints
- ignore `significant_drop_in_scrutinee` since it isn't relevant in our loop https://github.com/rust-lang/rust-clippy/issues/8987
```rust
for line in io::stdin().lines() {
    ...
}
```

Co-authored-by: Jakob Hellermann <hellermann@sipgate.de>
2022-07-01 13:41:23 +00:00
ira
ea13f0bddf Add helper methods for rotating Transforms (#5151)
# Objective
Users often ask for help with rotations as they struggle with `Quat`s.
`Quat` is rather complex and has a ton of verbose methods.

## Solution
Add rotation helper methods to `Transform`.


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-01 03:58:54 +00:00
Carter Anderson
747b0c69b0 Better Materials: AsBindGroup trait and derive, simpler Material trait (#5053)
# Objective

This PR reworks Bevy's Material system, making the user experience of defining Materials _much_ nicer. Bevy's previous material system leaves a lot to be desired:
* Materials require manually implementing the `RenderAsset` trait, which involves manually generating the bind group, handling gpu buffer data transfer, looking up image textures, etc. Even the simplest single-texture material involves writing ~80 unnecessary lines of code. This was never the long term plan.
* There are two material traits, which is confusing, hard to document, and often redundant: `Material` and `SpecializedMaterial`. `Material` implicitly implements `SpecializedMaterial`, and `SpecializedMaterial` is used in most high level apis to support both use cases. Most users shouldn't need to think about specialization at all (I consider it a "power-user tool"), so the fact that `SpecializedMaterial` is front-and-center in our apis is a miss.
* Implementing either material trait involves a lot of "type soup". The "prepared asset" parameter is particularly heinous: `&<Self as RenderAsset>::PreparedAsset`. Defining vertex and fragment shaders is also more verbose than it needs to be. 

## Solution

Say hello to the new `Material` system:

```rust
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
pub struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Handle<Image>,
}
impl Material for CoolMaterial {
    fn fragment_shader() -> ShaderRef {
        "cool_material.wgsl".into()
    }
}
```

Thats it! This same material would have required [~80 lines of complicated "type heavy" code](https://github.com/bevyengine/bevy/blob/v0.7.0/examples/shader/shader_material.rs) in the old Material system. Now it is just 14 lines of simple, readable code.

This is thanks to a new consolidated `Material` trait and the new `AsBindGroup` trait / derive.

### The new `Material` trait

The old "split" `Material` and `SpecializedMaterial` traits have been removed in favor of a new consolidated `Material` trait. All of the functions on the trait are optional.

The difficulty of implementing `Material` has been reduced by simplifying dataflow and removing type complexity:

```rust
// Old
impl Material for CustomMaterial {
    fn fragment_shader(asset_server: &AssetServer) -> Option<Handle<Shader>> {
        Some(asset_server.load("custom_material.wgsl"))
    }

    fn alpha_mode(render_asset: &<Self as RenderAsset>::PreparedAsset) -> AlphaMode {
        render_asset.alpha_mode
    }
}

// New
impl Material for CustomMaterial {
    fn fragment_shader() -> ShaderRef {
        "custom_material.wgsl".into()
    }

    fn alpha_mode(&self) -> AlphaMode {
        self.alpha_mode
    }
}
```

Specialization is still supported, but it is hidden by default under the `specialize()` function (more on this later).

### The `AsBindGroup` trait / derive

The `Material` trait now requires the `AsBindGroup` derive. This can be implemented manually relatively easily, but deriving it will almost always be preferable. 

Field attributes like `uniform` and `texture` are used to define which fields should be bindings,
what their binding type is, and what index they should be bound at:

```rust
#[derive(AsBindGroup)]
struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Handle<Image>,
}
```

In WGSL shaders, the binding looks like this:

```wgsl
struct CoolMaterial {
    color: vec4<f32>;
};

[[group(1), binding(0)]]
var<uniform> material: CoolMaterial;
[[group(1), binding(1)]]
var color_texture: texture_2d<f32>;
[[group(1), binding(2)]]
var color_sampler: sampler;
```

Note that the "group" index is determined by the usage context. It is not defined in `AsBindGroup`. Bevy material bind groups are bound to group 1.

The following field-level attributes are supported:
* `uniform(BINDING_INDEX)`
    * The field will be converted to a shader-compatible type using the `ShaderType` trait, written to a `Buffer`, and bound as a uniform. It can also be derived for custom structs.
* `texture(BINDING_INDEX)`
    * This field's `Handle<Image>` will be used to look up the matching `Texture` gpu resource, which will be bound as a texture in shaders. The field will be assumed to implement `Into<Option<Handle<Image>>>`. In practice, most fields should be a `Handle<Image>` or `Option<Handle<Image>>`. If the value of an `Option<Handle<Image>>` is `None`, the new `FallbackImage` resource will be used instead. This attribute can be used in conjunction with a `sampler` binding attribute (with a different binding index).
* `sampler(BINDING_INDEX)`
    * Behaves exactly like the `texture` attribute, but sets the Image's sampler binding instead of the texture. 

Note that fields without field-level binding attributes will be ignored.
```rust
#[derive(AsBindGroup)]
struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    this_field_is_ignored: String,
}
```

As mentioned above, `Option<Handle<Image>>` is also supported:
```rust
#[derive(AsBindGroup)]
struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Option<Handle<Image>>,
}
```
This is useful if you want a texture to be optional. When the value is `None`, the `FallbackImage` will be used for the binding instead, which defaults to "pure white".

Field uniforms with the same binding index will be combined into a single binding:
```rust
#[derive(AsBindGroup)]
struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    #[uniform(0)]
    roughness: f32,
}
```

In WGSL shaders, the binding would look like this:
```wgsl
struct CoolMaterial {
    color: vec4<f32>;
    roughness: f32;
};

[[group(1), binding(0)]]
var<uniform> material: CoolMaterial;
```

Some less common scenarios will require "struct-level" attributes. These are the currently supported struct-level attributes:
* `uniform(BINDING_INDEX, ConvertedShaderType)`
    * Similar to the field-level `uniform` attribute, but instead the entire `AsBindGroup` value is converted to `ConvertedShaderType`, which must implement `ShaderType`. This is useful if more complicated conversion logic is required.
* `bind_group_data(DataType)`
    * The `AsBindGroup` type will be converted to some `DataType` using `Into<DataType>` and stored as `AsBindGroup::Data` as part of the `AsBindGroup::as_bind_group` call. This is useful if data needs to be stored alongside the generated bind group, such as a unique identifier for a material's bind group. The most common use case for this attribute is "shader pipeline specialization".

The previous `CoolMaterial` example illustrating "combining multiple field-level uniform attributes with the same binding index" can
also be equivalently represented with a single struct-level uniform attribute:
```rust
#[derive(AsBindGroup)]
#[uniform(0, CoolMaterialUniform)]
struct CoolMaterial {
    color: Color,
    roughness: f32,
}

#[derive(ShaderType)]
struct CoolMaterialUniform {
    color: Color,
    roughness: f32,
}

impl From<&CoolMaterial> for CoolMaterialUniform {
    fn from(material: &CoolMaterial) -> CoolMaterialUniform {
        CoolMaterialUniform {
            color: material.color,
            roughness: material.roughness,
        }
    }
}
```

### Material Specialization

Material shader specialization is now _much_ simpler:

```rust
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
#[bind_group_data(CoolMaterialKey)]
struct CoolMaterial {
    #[uniform(0)]
    color: Color,
    is_red: bool,
}

#[derive(Copy, Clone, Hash, Eq, PartialEq)]
struct CoolMaterialKey {
    is_red: bool,
}

impl From<&CoolMaterial> for CoolMaterialKey {
    fn from(material: &CoolMaterial) -> CoolMaterialKey {
        CoolMaterialKey {
            is_red: material.is_red,
        }
    }
}

impl Material for CoolMaterial {
    fn fragment_shader() -> ShaderRef {
        "cool_material.wgsl".into()
    }

    fn specialize(
        pipeline: &MaterialPipeline<Self>,
        descriptor: &mut RenderPipelineDescriptor,
        layout: &MeshVertexBufferLayout,
        key: MaterialPipelineKey<Self>,
    ) -> Result<(), SpecializedMeshPipelineError> {
        if key.bind_group_data.is_red {
            let fragment = descriptor.fragment.as_mut().unwrap();
            fragment.shader_defs.push("IS_RED".to_string());
        }
        Ok(())
    }
}
```

Setting `bind_group_data` is not required for specialization (it defaults to `()`). Scenarios like "custom vertex attributes" also benefit from this system:
```rust
impl Material for CustomMaterial {
    fn vertex_shader() -> ShaderRef {
        "custom_material.wgsl".into()
    }

    fn fragment_shader() -> ShaderRef {
        "custom_material.wgsl".into()
    }

    fn specialize(
        pipeline: &MaterialPipeline<Self>,
        descriptor: &mut RenderPipelineDescriptor,
        layout: &MeshVertexBufferLayout,
        key: MaterialPipelineKey<Self>,
    ) -> Result<(), SpecializedMeshPipelineError> {
        let vertex_layout = layout.get_layout(&[
            Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
            ATTRIBUTE_BLEND_COLOR.at_shader_location(1),
        ])?;
        descriptor.vertex.buffers = vec![vertex_layout];
        Ok(())
    }
}
```

### Ported `StandardMaterial` to the new `Material` system

Bevy's built-in PBR material uses the new Material system (including the AsBindGroup derive):

```rust
#[derive(AsBindGroup, Debug, Clone, TypeUuid)]
#[uuid = "7494888b-c082-457b-aacf-517228cc0c22"]
#[bind_group_data(StandardMaterialKey)]
#[uniform(0, StandardMaterialUniform)]
pub struct StandardMaterial {
    pub base_color: Color,
    #[texture(1)]
    #[sampler(2)]
    pub base_color_texture: Option<Handle<Image>>,
    /* other fields omitted for brevity */
```

### Ported Bevy examples to the new `Material` system

The overall complexity of Bevy's "custom shader examples" has gone down significantly. Take a look at the diffs if you want a dopamine spike.

Please note that while this PR has a net increase in "lines of code", most of those extra lines come from added documentation. There is a significant reduction
in the overall complexity of the code (even accounting for the new derive logic).

---

## Changelog

### Added

* `AsBindGroup` trait and derive, which make it much easier to transfer data to the gpu and generate bind groups for a given type.

### Changed

* The old `Material` and `SpecializedMaterial` traits have been replaced by a consolidated (much simpler) `Material` trait. Materials no longer implement `RenderAsset`.
* `StandardMaterial` was ported to the new material system. There are no user-facing api changes to the `StandardMaterial` struct api, but it now implements `AsBindGroup` and `Material` instead of `RenderAsset` and `SpecializedMaterial`.

## Migration Guide
The Material system has been reworked to be much simpler. We've removed a lot of boilerplate with the new `AsBindGroup` derive and the `Material` trait is simpler as well!

### Bevy 0.7 (old)

```rust
#[derive(Debug, Clone, TypeUuid)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
pub struct CustomMaterial {
    color: Color,
    color_texture: Handle<Image>,
}

#[derive(Clone)]
pub struct GpuCustomMaterial {
    _buffer: Buffer,
    bind_group: BindGroup,
}

impl RenderAsset for CustomMaterial {
    type ExtractedAsset = CustomMaterial;
    type PreparedAsset = GpuCustomMaterial;
    type Param = (SRes<RenderDevice>, SRes<MaterialPipeline<Self>>);
    fn extract_asset(&self) -> Self::ExtractedAsset {
        self.clone()
    }

    fn prepare_asset(
        extracted_asset: Self::ExtractedAsset,
        (render_device, material_pipeline): &mut SystemParamItem<Self::Param>,
    ) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
        let color = Vec4::from_slice(&extracted_asset.color.as_linear_rgba_f32());

        let byte_buffer = [0u8; Vec4::SIZE.get() as usize];
        let mut buffer = encase::UniformBuffer::new(byte_buffer);
        buffer.write(&color).unwrap();

        let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
            contents: buffer.as_ref(),
            label: None,
            usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
        });

        let (texture_view, texture_sampler) = if let Some(result) = material_pipeline
            .mesh_pipeline
            .get_image_texture(gpu_images, &Some(extracted_asset.color_texture.clone()))
        {
            result
        } else {
            return Err(PrepareAssetError::RetryNextUpdate(extracted_asset));
        };
        let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
            entries: &[
                BindGroupEntry {
                    binding: 0,
                    resource: buffer.as_entire_binding(),
                },
                BindGroupEntry {
                    binding: 0,
                    resource: BindingResource::TextureView(texture_view),
                },
                BindGroupEntry {
                    binding: 1,
                    resource: BindingResource::Sampler(texture_sampler),
                },
            ],
            label: None,
            layout: &material_pipeline.material_layout,
        });

        Ok(GpuCustomMaterial {
            _buffer: buffer,
            bind_group,
        })
    }
}

impl Material for CustomMaterial {
    fn fragment_shader(asset_server: &AssetServer) -> Option<Handle<Shader>> {
        Some(asset_server.load("custom_material.wgsl"))
    }

    fn bind_group(render_asset: &<Self as RenderAsset>::PreparedAsset) -> &BindGroup {
        &render_asset.bind_group
    }

    fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout {
        render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
            entries: &[
                BindGroupLayoutEntry {
                    binding: 0,
                    visibility: ShaderStages::FRAGMENT,
                    ty: BindingType::Buffer {
                        ty: BufferBindingType::Uniform,
                        has_dynamic_offset: false,
                        min_binding_size: Some(Vec4::min_size()),
                    },
                    count: None,
                },
                BindGroupLayoutEntry {
                    binding: 1,
                    visibility: ShaderStages::FRAGMENT,
                    ty: BindingType::Texture {
                        multisampled: false,
                        sample_type: TextureSampleType::Float { filterable: true },
                        view_dimension: TextureViewDimension::D2Array,
                    },
                    count: None,
                },
                BindGroupLayoutEntry {
                    binding: 2,
                    visibility: ShaderStages::FRAGMENT,
                    ty: BindingType::Sampler(SamplerBindingType::Filtering),
                    count: None,
                },
            ],
            label: None,
        })
    }
}
```

### Bevy 0.8 (new)

```rust
impl Material for CustomMaterial {
    fn fragment_shader() -> ShaderRef {
        "custom_material.wgsl".into()
    }
}

#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "f690fdae-d598-45ab-8225-97e2a3f056e0"]
pub struct CustomMaterial {
    #[uniform(0)]
    color: Color,
    #[texture(1)]
    #[sampler(2)]
    color_texture: Handle<Image>,
}
```

## Future Work

* Add support for more binding types (cubemaps, buffers, etc). This PR intentionally includes a bare minimum number of binding types to keep "reviewability" in check.
* Consider optionally eliding binding indices using binding names. `AsBindGroup` could pass in (optional?) reflection info as a "hint".
    * This would make it possible for the derive to do this:
        ```rust
        #[derive(AsBindGroup)]
        pub struct CustomMaterial {
            #[uniform]
            color: Color,
            #[texture]
            #[sampler]
            color_texture: Option<Handle<Image>>,
            alpha_mode: AlphaMode,
        }
        ```
    * Or this
        ```rust
        #[derive(AsBindGroup)]
        pub struct CustomMaterial {
            #[binding]
            color: Color,
            #[binding]
            color_texture: Option<Handle<Image>>,
            alpha_mode: AlphaMode,
        }
        ```
    * Or even this (if we flip to "include bindings by default")
        ```rust
        #[derive(AsBindGroup)]
        pub struct CustomMaterial {
            color: Color,
            color_texture: Option<Handle<Image>>,
            #[binding(ignore)]
            alpha_mode: AlphaMode,
        }
        ```
* If we add the option to define custom draw functions for materials (which could be done in a type-erased way), I think that would be enough to support extra non-material bindings. Worth considering!
2022-06-30 23:48:46 +00:00
François
d4e4a92982 android - fix issues other than the rendering (#5130)
# Objective

- Make Bevy work on android

## Solution

- Update android metadata and add a few more
- Set the target sdk to 31 as it will soon (in august) be the minimum sdk level for play store
- Remove the custom code to create an activity and use ndk-glue macro instead
- Delay window creation event on android
- Set the example with compatibility settings for wgpu. Those are needed for Bevy to work on my 2019 android tablet
- Add a few details on how to debug in case of failures
- Fix running the example on emulator. This was failing because of the name of the example

Bevy still doesn't work on android with this, audio features need to be disabled because of an ndk-glue version mismatch: rodio depends on 0.6.2, winit on 0.5.2. You can test with:
```
cargo apk run --release --example android_example --no-default-features --features "bevy_winit,render"
```
2022-06-30 19:42:45 +00:00
Robert Swain
84991d34f3 Array texture example (#5077)
# Objective

- Make the reusable PBR shading functionality a little more reusable
  - Add constructor functions for `StandardMaterial` and `PbrInput` structs to populate them with default values
  - Document unclear `PbrInput` members
- Demonstrate how to reuse the bevy PBR shading functionality
- The final important piece from #3969 as the initial shot at making the PBR shader code reusable in custom materials

## Solution

- Add back and rework the 'old' `array_texture` example from pre-0.6.
- Create a custom shader material
  - Use a single array texture binding and sampler for the material bind group
  - Use a shader that calls `pbr()` from the `bevy_pbr::pbr_functions` import
- Spawn a row of cubes using the custom material
- In the shader, select the array texture layer to sample by using the world position x coordinate modulo the number of array texture layers

<img width="1392" alt="Screenshot 2022-06-23 at 12 28 05" src="https://user-images.githubusercontent.com/302146/175278593-2296f519-f577-4ece-81c0-d842283784a1.png">

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-06-28 00:58:50 +00:00
Dilyan
4f5f04041f Fix player number in example game in the ecs_guide (#5098)
# Objective

- Small bug in the example game given in examples/ecs/ecs_guide

Currently, if there are 2 players in this example game, the function exclusive_player_system can add a player with the name "Player 2". However, the name should be "Player 3". This PR fixes this. I also add a message to inform that a new player has arrived in the mock game.

Co-authored-by: Dilyan Kostov <dilyanks@amazon.com>
2022-06-26 13:58:56 +00:00
François
f8fa229465 Examples metadata in Cargo.toml (#4741)
# Objective

- Have information about examples only in one place that can be used for the repo and for the website (and remove the need to keep a list of example to build for wasm in the website 75acb73040/generate-wasm-examples/generate_wasm_examples.sh (L92-L99))

## Solution

- Add metadata about examples in `Cargo.toml`
- Build the `examples/README.md` from a template using those metadata. I used tera as the template engine to use the same tech as the website.
- Make CI fail if an example is missing metadata, or if the readme file needs to be updated (the command to update it is displayed in the failed step in CI)

## Remaining To Do

- After the next release with this merged in, the website will be able to be updated to use those metadata too
- I would like to build the examples in wasm and make them available at http://dev-docs.bevyengine.org/ but that will require more design
- https://github.com/bevyengine/bevy-website/issues/299 for other ToDos

Co-authored-by: Readme <github-actions@github.com>
2022-06-25 20:23:24 +00:00
MiniaczQ
33a5f2b977 transparency_3d example tweaks (#4968)
Fixed a typo, removed unused component, normalized comments added a touch more detail.
2022-06-23 18:36:07 +00:00
François
4967351842 many foxes: only change animation once (#5076)
# Objective

- When changing animation, all the foxes didn't play the same animation

## Solution

- Update the animation index only once
2022-06-23 02:00:45 +00:00
Félix Lescaudey de Maneville
c4fc5d88f0 Fixed bevy_ui touch input (#4099)
# Objective

`bevy_ui` doesn't support correctly touch inputs because of two problems in the focus system:
- It attempts to retrieve touch input with a specific `0` id
- It doesn't retrieve touch positions and bases its focus solely on mouse position, absent from mobile devices

## Solution

I added a few methods to the `Touches` resource, allowing to check if **any** touch input was pressed, released or cancelled and to retrieve the *position* of the first pressed touch input and adapted the focus system.

I added a test button to the *iOS* example and it works correclty on emulator. I did not test on a real touch device as:
- Android is not working (https://github.com/bevyengine/bevy/issues/3249)
- I don't have an iOS device
2022-06-20 20:32:19 +00:00
François
bb1d524833 Cleanups in diagnostics (#3871)
- changed `EntityCountDiagnosticsPlugin` to not use an exclusive system to get its entity count
- removed mention of `WgpuResourceDiagnosticsPlugin` in example `log_diagnostics` as it doesn't exist anymore
- added ability to enable, disable ~~or toggle~~ a diagnostic (fix #3767)
- made diagnostic values lazy, so they are only computed if the diagnostic is enabled
- do not log an average for diagnostics with only one value
- removed `sum` function from diagnostic as it isn't really useful
- ~~do not keep an average of the FPS diagnostic. it is already an average on the last 20 frames, so the average FPS was an average of the last 20 frames over the last 20 frames~~
- do not compute the FPS value as an average over the last 20 frames but give the actual "instant FPS"
- updated log format to use variable capture
- added some doc
- the frame counter diagnostic value can be reseted to 0
2022-06-20 17:02:25 +00:00
Robert Swain
b333386271 Add reusable shader functions for transforming position/normal/tangent (#4901)
# Objective

- Add reusable shader functions for transforming positions / normals / tangents between local and world / clip space for 2D and 3D so that they are done in a simple and correct way
- The next step in #3969 so check there for more details.

## Solution

- Add `bevy_pbr::mesh_functions` and `bevy_sprite::mesh2d_functions` shader imports
  - These contain `mesh_` and `mesh2d_` versions of the following functions:
    - `mesh_position_local_to_world`
    - `mesh_position_world_to_clip`
    - `mesh_position_local_to_clip`
    - `mesh_normal_local_to_world`
    - `mesh_tangent_local_to_world`
- Use them everywhere where it is appropriate
  - Notably not in the sprite and UI shaders where `mesh2d_position_world_to_clip` could have been used, but including all the functions depends on the mesh binding so I chose to not use the function there
- NOTE: The `mesh_` and `mesh2d_` functions are currently identical. However, if I had defined only `bevy_pbr::mesh_functions` and used that in bevy_sprite, then bevy_sprite would have a runtime dependency on bevy_pbr, which seems undesirable. I also expect that when we have a proper 2D rendering API, these functions will diverge between 2D and 3D.

---

## Changelog

- Added: `bevy_pbr::mesh_functions` and `bevy_sprite::mesh2d_functions` shader imports containing `mesh_` and `mesh2d_` versions of the following functions:
  - `mesh_position_local_to_world`
  - `mesh_position_world_to_clip`
  - `mesh_position_local_to_clip`
  - `mesh_normal_local_to_world`
  - `mesh_tangent_local_to_world`

## Migration Guide

- The `skin_tangents` function from the `bevy_pbr::skinning` shader import has been replaced with the `mesh_tangent_local_to_world` function from the `bevy_pbr::mesh_functions` shader import
2022-06-14 00:32:33 +00:00
Aevyrie
772d15238c Change default Image FilterMode to Linear (#4465)
# Objective

- Closes #4464 

## Solution

- Specify default mag and min filter types for `Image` instead of using `wgpu`'s defaults.

---

## Changelog

### Changed

- Default `Image` filtering changed from `Nearest` to `Linear`.


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-06-11 09:13:37 +00:00
Peter Hebden
1679a99738 Fix typo in game_menu.rs (#4977)
Should be trivial

# Objective

There is a typo in a comment that is fixed in this commit

## Solution

Fix the typo
`positionned` -> `positioned`

---
2022-06-09 20:57:43 +00:00
François
c6958b3056 add a SceneBundle to spawn a scene (#2424)
# Objective

- Spawning a scene is handled as a special case with a command `spawn_scene` that takes an handle but doesn't let you specify anything else. This is the only handle that works that way.
- Workaround for this have been to add the `spawn_scene` on `ChildBuilder` to be able to specify transform of parent, or to make the `SceneSpawner` available to be able to select entities from a scene by their instance id

## Solution

Add a bundle
```rust
pub struct SceneBundle {
    pub scene: Handle<Scene>,
    pub transform: Transform,
    pub global_transform: GlobalTransform,
    pub instance_id: Option<InstanceId>,
}
```

and instead of 
```rust
commands.spawn_scene(asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"));
```
you can do
```rust
commands.spawn_bundle(SceneBundle {
    scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
    ..Default::default()
});
```

The scene will be spawned as a child of the entity with the `SceneBundle`

~I would like to remove the command `spawn_scene` in favor of this bundle but didn't do it yet to get feedback first~

Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-06-09 20:34:09 +00:00
James Liu
012ae07dc8 Add global init and get accessors for all newtyped TaskPools (#2250)
Right now, a direct reference to the target TaskPool is required to launch tasks on the pools, despite the three newtyped pools (AsyncComputeTaskPool, ComputeTaskPool, and IoTaskPool) effectively acting as global instances. The need to pass a TaskPool reference adds notable friction to spawning subtasks within existing tasks. Possible use cases for this may include chaining tasks within the same pool like spawning separate send/receive I/O tasks after waiting on a network connection to be established, or allowing cross-pool dependent tasks like starting dependent multi-frame computations following a long I/O load. 

Other task execution runtimes provide static access to spawning tasks (i.e. `tokio::spawn`), which is notably easier to use than the reference passing required by `bevy_tasks` right now.

This PR makes does the following:

 * Adds `*TaskPool::init` which initializes a `OnceCell`'ed with a provided TaskPool. Failing if the pool has already been initialized.
 * Adds `*TaskPool::get` which fetches the initialized global pool of the respective type or panics. This generally should not be an issue in normal Bevy use, as the pools are initialized before they are accessed.
 * Updated default task pool initialization to either pull the global handles and save them as resources, or if they are already initialized, pull the a cloned global handle as the resource.

This should make it notably easier to build more complex task hierarchies for dependent tasks. It should also make writing bevy-adjacent, but not strictly bevy-only plugin crates easier, as the global pools ensure it's all running on the same threads.

One alternative considered is keeping a thread-local reference to the pool for all threads in each pool to enable the same `tokio::spawn` interface. This would spawn tasks on the same pool that a task is currently running in. However this potentially leads to potential footgun situations where long running blocking tasks run on `ComputeTaskPool`.
2022-06-09 02:43:24 +00:00
Carter Anderson
f28b921209 Add "depth_load_op" configuration to 3d Cameras (#4904)
# Objective

Users should be able to configure depth load operations on cameras. Currently every camera clears depth when it is rendered. But sometimes later passes need to rely on depth from previous passes.

## Solution

This adds the `Camera3d::depth_load_op` field with a new `Camera3dDepthLoadOp` value. This is a custom type because Camera3d uses "reverse-z depth" and this helps us record and document that in a discoverable way. It also gives us more control over reflection + other trait impls, whereas `LoadOp` is owned by the `wgpu` crate.

```rust
commands.spawn_bundle(Camera3dBundle {
    camera_3d: Camera3d {
        depth_load_op: Camera3dDepthLoadOp::Load,
        ..default()
    },
    ..default()
});
```

### two_passes example with the "second pass" camera configured to the default (clear depth to 0.0)

![image](https://user-images.githubusercontent.com/2694663/171743172-46d4fdd5-5090-46ea-abe4-1fbc519f6ee8.png)


### two_passes example with the "second pass" camera configured to "load" the depth
![image](https://user-images.githubusercontent.com/2694663/171743323-74dd9a1d-9c25-4883-98dd-38ca0bed8c17.png)

---

## Changelog

### Added

* `Camera3d` now has a `depth_load_op` field, which can configure the Camera's main 3d pass depth loading behavior.
2022-06-07 22:22:10 +00:00
François
73174730e4 use the default() method in examples instead of Default::default() (#4952)
# Objective

- Use the `..default()` method in examples instead of `..Default::default()`
2022-06-07 02:16:47 +00:00
Wybe Westra
25219a4d18 Add transparency examples (#3695)
Adds examples demonstrating transparency for 2d, 3d and UI.

Fixes #3215.
2022-06-06 17:52:09 +00:00
Yoshiera
2f5a1c6e16 remove redundant query parameters (#4945)
# Objective

In the `queue_custom` system in `shader_instancing` example, the query of `material_meshes`  has a redundant `With<Handle<Mesh>>` query filter because `Handle<Mesh>` is included in the component access.

## Solution

Remove the `With<Handle<Mesh>>` filter
2022-06-06 14:24:41 +00:00
Thierry Berger
765bd46c2e add a post-processing example (#4797)
# Objective

- Add an example showing a custom post processing effect, done after the first rendering pass.

## Solution

- A simple post processing "chromatic aberration" effect. I mixed together examples `3d/render_to_texture`, and `shader/shader_material_screenspace_texture`
- Reading a bit how https://github.com/bevyengine/bevy/pull/3430 was done gave me pointers to apply the main pass to the 2d render rather than using a 3d quad.

This work might be or not be relevant to https://github.com/bevyengine/bevy/issues/2724

<details>

<summary> ⚠️ Click for a video of the render ⚠️ I’ve been told it might hurt the eyes 👀 , maybe we should choose another effect just in case ?</summary>

https://user-images.githubusercontent.com/2290685/169138830-a6dc8a9f-8798-44b9-8d9e-449e60614916.mp4

</details>

# Request for feedbacks

- [ ] Is chromatic aberration effect ok ? (Correct term, not a danger for the eyes ?) I'm open to suggestion to make something different.
- [ ] Is the code idiomatic ? I preferred a "main camera -> **new camera with post processing applied to a quad**" approach to emulate minimum modification to existing code wanting to add global post processing.

---

## Changelog

- Add a full screen post processing shader example
2022-06-06 00:06:49 +00:00
Carter Anderson
5e2cfb2f19 Camera Driven Viewports (#4898)
# Objective

Users should be able to render cameras to specific areas of a render target, which enables scenarios like split screen, minimaps, etc.

Builds on the new Camera Driven Rendering added here: #4745 
Fixes: #202
Alternative to #1389 and #3626 (which are incompatible with the new Camera Driven Rendering)

## Solution

![image](https://user-images.githubusercontent.com/2694663/171560044-f0694f67-0cd9-4598-83e2-a9658c4fed57.png)


Cameras can now configure an optional "viewport", which defines a rectangle within their render target to draw to. If a `Viewport` is defined, the camera's `CameraProjection`, `View`, and visibility calculations will use the viewport configuration instead of the full render target. 

```rust
// This camera will render to the first half of the primary window (on the left side).
commands.spawn_bundle(Camera3dBundle {
    camera: Camera {
        viewport: Some(Viewport {
            physical_position: UVec2::new(0, 0),
            physical_size: UVec2::new(window.physical_width() / 2, window.physical_height()),
            depth: 0.0..1.0,
        }),
        ..default()
    },
    ..default()
});
```

To account for this, the `Camera` component has received a few adjustments:

* `Camera` now has some new getter functions:
  * `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, `projection_matrix`
*  All computed camera values are now private and live on the `ComputedCameraValues` field (logical/physical width/height, the projection matrix). They are now exposed on `Camera` via getters/setters  This wasn't _needed_ for viewports, but it was long overdue.

---

## Changelog

### Added

* `Camera` components now have a `viewport` field, which can be set to draw to a portion of a render target instead of the full target.
* `Camera` component has some new functions: `logical_viewport_size`, `physical_viewport_size`, `logical_target_size`, `physical_target_size`, and `projection_matrix`
* Added a new split_screen example illustrating how to render two cameras to the same scene

## Migration Guide

`Camera::projection_matrix` is no longer a public field. Use the new `Camera::projection_matrix()` method instead:

```rust

// Bevy 0.7
let projection = camera.projection_matrix;

// Bevy 0.8
let projection = camera.projection_matrix();
```
2022-06-05 00:27:49 +00:00
Henry Sloan
8e08e26c25 Update commented vsync code in example to use present_mode (#4926)
# Objective

- To fix the broken commented code in `examples/shader/compute_shader_game_of_life.rs` for disabling frame throttling

## Solution

- Change the commented code from using the old `WindowDescriptor::vsync` to the new `WindowDescriptor::present_mode`

### Note
I chose to use the fully qualified scope `bevy:🪟:PresentWindow::Immediate` rather than explicitly including `PresentWindow` to avoid an unused import when the code is commented.
2022-06-04 20:00:01 +00:00
Carter Anderson
f487407e07 Camera Driven Rendering (#4745)
This adds "high level camera driven rendering" to Bevy. The goal is to give users more control over what gets rendered (and where) without needing to deal with render logic. This will make scenarios like "render to texture", "multiple windows", "split screen", "2d on 3d", "3d on 2d", "pass layering", and more significantly easier. 

Here is an [example of a 2d render sandwiched between two 3d renders (each from a different perspective)](https://gist.github.com/cart/4fe56874b2e53bc5594a182fc76f4915):
![image](https://user-images.githubusercontent.com/2694663/168411086-af13dec8-0093-4a84-bdd4-d4362d850ffa.png)

Users can now spawn a camera, point it at a RenderTarget (a texture or a window), and it will "just work". 

Rendering to a second window is as simple as spawning a second camera and assigning it to a specific window id:
```rust
// main camera (main window)
commands.spawn_bundle(Camera2dBundle::default());

// second camera (other window)
commands.spawn_bundle(Camera2dBundle {
    camera: Camera {
        target: RenderTarget::Window(window_id),
        ..default()
    },
    ..default()
});
```

Rendering to a texture is as simple as pointing the camera at a texture:

```rust
commands.spawn_bundle(Camera2dBundle {
    camera: Camera {
        target: RenderTarget::Texture(image_handle),
        ..default()
    },
    ..default()
});
```

Cameras now have a "render priority", which controls the order they are drawn in. If you want to use a camera's output texture as a texture in the main pass, just set the priority to a number lower than the main pass camera (which defaults to `0`).

```rust
// main pass camera with a default priority of 0
commands.spawn_bundle(Camera2dBundle::default());

commands.spawn_bundle(Camera2dBundle {
    camera: Camera {
        target: RenderTarget::Texture(image_handle.clone()),
        priority: -1,
        ..default()
    },
    ..default()
});

commands.spawn_bundle(SpriteBundle {
    texture: image_handle,
    ..default()
})
```

Priority can also be used to layer to cameras on top of each other for the same RenderTarget. This is what "2d on top of 3d" looks like in the new system:

```rust
commands.spawn_bundle(Camera3dBundle::default());

commands.spawn_bundle(Camera2dBundle {
    camera: Camera {
        // this will render 2d entities "on top" of the default 3d camera's render
        priority: 1,
        ..default()
    },
    ..default()
});
```

There is no longer the concept of a global "active camera". Resources like `ActiveCamera<Camera2d>` and `ActiveCamera<Camera3d>` have been replaced with the camera-specific `Camera::is_active` field. This does put the onus on users to manage which cameras should be active.

Cameras are now assigned a single render graph as an "entry point", which is configured on each camera entity using the new `CameraRenderGraph` component. The old `PerspectiveCameraBundle` and `OrthographicCameraBundle` (generic on camera marker components like Camera2d and Camera3d) have been replaced by `Camera3dBundle` and `Camera2dBundle`, which set 3d and 2d default values for the `CameraRenderGraph` and projections.

```rust
// old 3d perspective camera
commands.spawn_bundle(PerspectiveCameraBundle::default())

// new 3d perspective camera
commands.spawn_bundle(Camera3dBundle::default())
```

```rust
// old 2d orthographic camera
commands.spawn_bundle(OrthographicCameraBundle::new_2d())

// new 2d orthographic camera
commands.spawn_bundle(Camera2dBundle::default())
```

```rust
// old 3d orthographic camera
commands.spawn_bundle(OrthographicCameraBundle::new_3d())

// new 3d orthographic camera
commands.spawn_bundle(Camera3dBundle {
    projection: OrthographicProjection {
        scale: 3.0,
        scaling_mode: ScalingMode::FixedVertical,
        ..default()
    }.into(),
    ..default()
})
```

Note that `Camera3dBundle` now uses a new `Projection` enum instead of hard coding the projection into the type. There are a number of motivators for this change: the render graph is now a part of the bundle, the way "generic bundles" work in the rust type system prevents nice `..default()` syntax, and changing projections at runtime is much easier with an enum (ex for editor scenarios). I'm open to discussing this choice, but I'm relatively certain we will all come to the same conclusion here. Camera2dBundle and Camera3dBundle are much clearer than being generic on marker components / using non-default constructors.

If you want to run a custom render graph on a camera, just set the `CameraRenderGraph` component:

```rust
commands.spawn_bundle(Camera3dBundle {
    camera_render_graph: CameraRenderGraph::new(some_render_graph_name),
    ..default()
})
```

Just note that if the graph requires data from specific components to work (such as `Camera3d` config, which is provided in the `Camera3dBundle`), make sure the relevant components have been added.

Speaking of using components to configure graphs / passes, there are a number of new configuration options:

```rust
commands.spawn_bundle(Camera3dBundle {
    camera_3d: Camera3d {
        // overrides the default global clear color 
        clear_color: ClearColorConfig::Custom(Color::RED),
        ..default()
    },
    ..default()
})

commands.spawn_bundle(Camera3dBundle {
    camera_3d: Camera3d {
        // disables clearing
        clear_color: ClearColorConfig::None,
        ..default()
    },
    ..default()
})
```

Expect to see more of the "graph configuration Components on Cameras" pattern in the future.

By popular demand, UI no longer requires a dedicated camera. `UiCameraBundle` has been removed. `Camera2dBundle` and `Camera3dBundle` now both default to rendering UI as part of their own render graphs. To disable UI rendering for a camera, disable it using the CameraUi component:

```rust
commands
    .spawn_bundle(Camera3dBundle::default())
    .insert(CameraUi {
        is_enabled: false,
        ..default()
    })
```

## Other Changes

* The separate clear pass has been removed. We should revisit this for things like sky rendering, but I think this PR should "keep it simple" until we're ready to properly support that (for code complexity and performance reasons). We can come up with the right design for a modular clear pass in a followup pr.
* I reorganized bevy_core_pipeline into Core2dPlugin and Core3dPlugin (and core_2d / core_3d modules). Everything is pretty much the same as before, just logically separate. I've moved relevant types (like Camera2d, Camera3d, Camera3dBundle, Camera2dBundle) into their relevant modules, which is what motivated this reorganization.
* I adapted the `scene_viewer` example (which relied on the ActiveCameras behavior) to the new system. I also refactored bits and pieces to be a bit simpler. 
* All of the examples have been ported to the new camera approach. `render_to_texture` and `multiple_windows` are now _much_ simpler. I removed `two_passes` because it is less relevant with the new approach. If someone wants to add a new "layered custom pass with CameraRenderGraph" example, that might fill a similar niche. But I don't feel much pressure to add that in this pr.
* Cameras now have `target_logical_size` and `target_physical_size` fields, which makes finding the size of a camera's render target _much_ simpler. As a result, the `Assets<Image>` and `Windows` parameters were removed from `Camera::world_to_screen`, making that operation much more ergonomic.
* Render order ambiguities between cameras with the same target and the same priority now produce a warning. This accomplishes two goals:
    1. Now that there is no "global" active camera, by default spawning two cameras will result in two renders (one covering the other). This would be a silent performance killer that would be hard to detect after the fact. By detecting ambiguities, we can provide a helpful warning when this occurs.
    2. Render order ambiguities could result in unexpected / unpredictable render results. Resolving them makes sense.

## Follow Up Work

* Per-Camera viewports, which will make it possible to render to a smaller area inside of a RenderTarget (great for something like splitscreen)
* Camera-specific MSAA config (should use the same "overriding" pattern used for ClearColor)
* Graph Based Camera Ordering: priorities are simple, but they make complicated ordering constraints harder to express. We should consider adopting a "graph based" camera ordering model with "before" and "after" relationships to other cameras (or build it "on top" of the priority system).
* Consider allowing graphs to run subgraphs from any nest level (aka a global namespace for graphs). Right now the 2d and 3d graphs each need their own UI subgraph, which feels "fine" in the short term. But being able to share subgraphs between other subgraphs seems valuable.
* Consider splitting `bevy_core_pipeline` into `bevy_core_2d` and `bevy_core_3d` packages. Theres a shared "clear color" dependency here, which would need a new home.
2022-06-02 00:12:17 +00:00
Robert Swain
cc4062ec43 Split mesh shader files (#4867)
# Objective

- Split PBR and 2D mesh shaders into types and bindings to prepare the shaders to be more reusable.
- See #3969 for details. I'm doing this in multiple steps to make review easier.

---

## Changelog

- Changed: 2D and PBR mesh shaders are now split into types and bindings, the following shader imports are available: `bevy_pbr::mesh_view_types`, `bevy_pbr::mesh_view_bindings`, `bevy_pbr::mesh_types`, `bevy_pbr::mesh_bindings`, `bevy_sprite::mesh2d_view_types`, `bevy_sprite::mesh2d_view_bindings`, `bevy_sprite::mesh2d_types`, `bevy_sprite::mesh2d_bindings`

## Migration Guide

- In shaders for 3D meshes:
  - `#import bevy_pbr::mesh_view_bind_group` -> `#import bevy_pbr::mesh_view_bindings`
  - `#import bevy_pbr::mesh_struct` -> `#import bevy_pbr::mesh_types`
    - NOTE: If you are using the mesh bind group at bind group index 2, you can remove those binding statements in your shader and just use `#import bevy_pbr::mesh_bindings` which itself imports the mesh types needed for the bindings.
- In shaders for 2D meshes:
  - `#import bevy_sprite::mesh2d_view_bind_group` -> `#import bevy_sprite::mesh2d_view_bindings`
  - `#import bevy_sprite::mesh2d_struct` -> `#import bevy_sprite::mesh2d_types`
    - NOTE: If you are using the mesh2d bind group at bind group index 2, you can remove those binding statements in your shader and just use `#import bevy_sprite::mesh2d_bindings` which itself imports the mesh2d types needed for the bindings.
2022-05-31 23:23:25 +00:00
Alex Saveau
caef967d14 Derive default on ReportExecutionOrderAmbiguities (#4873) 2022-05-31 15:54:38 +00:00
Félix Lescaudey de Maneville
f000c2b951 Clippy improvements (#4665)
# Objective

Follow up to my previous MR #3718 to add new clippy warnings to bevy:

- [x] [~~option_if_let_else~~](https://rust-lang.github.io/rust-clippy/master/#option_if_let_else) (reverted)
- [x] [redundant_else](https://rust-lang.github.io/rust-clippy/master/#redundant_else)
- [x] [match_same_arms](https://rust-lang.github.io/rust-clippy/master/#match_same_arms)
- [x] [semicolon_if_nothing_returned](https://rust-lang.github.io/rust-clippy/master/#semicolon_if_nothing_returned)
- [x] [explicit_iter_loop](https://rust-lang.github.io/rust-clippy/master/#explicit_iter_loop)
- [x] [map_flatten](https://rust-lang.github.io/rust-clippy/master/#map_flatten)

There is one commit per clippy warning, and the matching flags are added to the CI execution.

To test the CI execution you may run `cargo run -p ci -- clippy` at the root.

I choose the add the flags in the `ci` tool crate to avoid having them in every `lib.rs` but I guess it could become an issue with suprise warnings coming up after a commit/push


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-05-31 01:38:07 +00:00
Robert Swain
1e8ca45aeb scene_viewer: Make it possible to disable the animation feature (#4849)
# Objective

- The `scene_viewer` example assumes the `animation` feature is enabled, which it is by default. However, animations may have a performance cost that is undesirable when testing performance, for example. Then it is useful to be able to disable the `animation` feature and one would still like the `scene_viewer` example to work.

## Solution

- Gate animation code in `scene_viewer` on the `animation` feature being enabled.
2022-05-30 20:10:26 +00:00
Robert Swain
a0a3d8798b ExtractResourcePlugin (#3745)
# Objective

- Add an `ExtractResourcePlugin` for convenience and consistency

## Solution

- Add an `ExtractResourcePlugin` similar to `ExtractComponentPlugin` but for ECS `Resource`s. The system that is executed simply clones the main world resource into a render world resource, if and only if the main world resource was either added or changed since the last execution of the system.
- Add an `ExtractResource` trait with a `fn extract_resource(res: &Self) -> Self` function. This is used by the `ExtractResourcePlugin` to extract the resource
- Add a derive macro for `ExtractResource` on a `Resource` with the `Clone` trait, that simply returns `res.clone()`
- Use `ExtractResourcePlugin` wherever both possible and appropriate
2022-05-30 18:36:03 +00:00
Herbert "TheBracket
a6eb3fa6d6 Apply vertex colors to ColorMaterial and Mesh2D (#4812)
# Objective

- Add Vertex Color support to 2D meshes and ColorMaterial. This extends the work from #4528 (which in turn builds on the excellent tangent handling).

## Solution

- Added `#ifdef` wrapped support for vertex colors in the 2D mesh shader and `ColorMaterial` shader.
- Added an example, `mesh2d_vertex_color_texture` to demonstrate it in action.

![image](https://user-images.githubusercontent.com/14896751/169530930-6ae0c6be-2f69-40e3-a600-ba91d7178bc3.png)


---

## Changelog

- Added optional (ifdef wrapped) vertex color support to the 2dmesh and color material systems.
2022-05-30 16:59:45 +00:00
Daniel McNab
1bbd5c25c0 Enforce type safe usage of Handle::get (#4794)
# Objective

- Sometimes, people might load an asset as one type, then use it with an `Asset`s for a different type.
- See e.g. #4784. 
- This is especially likely with the Gltf types, since users may not have a clear conceptual model of what types the assets will be.
- We had an instance of this ourselves, in the `scene_viewer` example

## Solution

- Make `Assets::get` require a type safe handle.

---

## Changelog

### Changed

- `Assets::<T>::get` and `Assets::<T>::get_mut` now require that the passed handles are `Handle<T>`, improving the type safety of handles.

### Added
- `HandleUntyped::typed_weak`, a helper function for creating a weak typed version of an exisitng `HandleUntyped`.

## Migration Guide

`Assets::<T>::get` and `Assets::<T>::get_mut` now require that the passed handles are `Handle<T>`, improving the type safety of handles. If you were previously passing in:
   - a `HandleId`, use `&Handle::weak(id)` instead, to create a weak handle. You may have been able to store a type safe `Handle` instead.
   - a `HandleUntyped`, use `&handle_untyped.typed_weak()` to create a weak handle of the specified type. This is most likely to be the useful when using [load_folder](https://docs.rs/bevy_asset/latest/bevy_asset/struct.AssetServer.html#method.load_folder)
   - a `Handle<U>` of  of a different type, consider whether this is the correct handle type to store. If it is (i.e. the same handle id is used for multiple different Asset types) use `Handle::weak(handle.id)` to cast to a different type.
2022-05-30 16:59:44 +00:00
James Liu
c5e89894f4 Remove task_pool parameter from par_for_each(_mut) (#4705)
# Objective
Fixes #3183. Requiring a `&TaskPool` parameter is sort of meaningless if the only correct one is to use the one provided by `Res<ComputeTaskPool>` all the time.

## Solution
Have `QueryState` save a clone of the `ComputeTaskPool` which is used for all `par_for_each` functions.

~~Adds a small overhead of the internal `Arc` clone as a part of the startup, but the ergonomics win should be well worth this hardly-noticable overhead.~~

Updated the docs to note that it will panic the task pool is not present as a resource.

# Future Work
If https://github.com/bevyengine/rfcs/pull/54 is approved, we can replace these resource lookups with a static function call instead to get the `ComputeTaskPool`.

---

## Changelog
Removed: The `task_pool` parameter of `Query(State)::par_for_each(_mut)`. These calls will use the `World`'s `ComputeTaskPool` resource instead.

## Migration Guide
The `task_pool` parameter for `Query(State)::par_for_each(_mut)` has been removed. Remove these parameters from all calls to these functions.

Before:
```rust
fn parallel_system(
   task_pool: Res<ComputeTaskPool>,
   query: Query<&MyComponent>,
) {
   query.par_for_each(&task_pool, 32, |comp| {
        ...
   });
}
```

After:

```rust
fn parallel_system(query: Query<&MyComponent>) {
   query.par_for_each(32, |comp| {
        ...
   });
}
```

If using `Query(State)` outside of a system run by the scheduler, you may need to manually configure and initialize a `ComputeTaskPool` as a resource in the `World`.
2022-05-30 16:59:38 +00:00
Thierry Berger
deeaf64897 shader examples wording coherence (#4810)
# Objective

I noticed different examples descriptions were not using the same structure:
![different_wordings_examples](https://user-images.githubusercontent.com/2290685/169487055-ab76743e-3400-486f-b672-e8f60455b8e4.png)

This results in sentences that a reader has to read differently each time, which might result in information being hard to find, especially foreign language users.

Original discord discussion: https://discord.com/channels/691052431525675048/976846499889705020

## Solution

- Use less different words, similar structure and being straight to the point.

---

## Changelog

- Examples descriptions more accessible.
2022-05-30 15:57:25 +00:00
Thierry Berger
99e689cfd2 remove unneeded msaa explicit addition from examples (#4830)
# Objective

- Coming from 7a596f1910 (r876310734)
- Simplify the examples regarding addition of `Msaa` Resource with default value.

## Solution

- Remove addition of `Msaa` Resource with default value from examples,
2022-05-27 20:52:12 +00:00
Christopher Durham
644bd5dbc6 Split time functionality into bevy_time (#4187)
# Objective

Reduce the catch-all grab-bag of functionality in bevy_core by minimally splitting off time functionality into bevy_time. Functionality like that provided by #3002 would increase the complexity of bevy_time, so this is a good candidate for pulling into its own unit.

A step in addressing #2931 and splitting bevy_core into more specific locations.

## Solution

Pull the time module of bevy_core into a new crate, bevy_time.

# Migration guide

- Time related types (e.g. `Time`, `Timer`, `Stopwatch`, `FixedTimestep`, etc.) should be imported from `bevy::time::*` rather than `bevy::core::*`.
- If you were adding `CorePlugin` manually, you'll also want to add `TimePlugin` from `bevy::time`.
- The `bevy::core::CorePlugin::Time` system label is replaced with `bevy::time::TimeSystem`.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-05-26 00:27:18 +00:00
Teodor Tanasoaia
7cb4d3cb43 Migrate to encase from crevice (#4339)
# Objective

- Unify buffer APIs
- Also see #4272

## Solution

- Replace vendored `crevice` with `encase`

---

## Changelog

Changed `StorageBuffer`
Added `DynamicStorageBuffer`
Replaced `UniformVec` with `UniformBuffer`
Replaced `DynamicUniformVec` with `DynamicUniformBuffer`

## Migration Guide

### `StorageBuffer`

removed `set_body()`, `values()`, `values_mut()`, `clear()`, `push()`, `append()`
added `set()`, `get()`, `get_mut()`

### `UniformVec` -> `UniformBuffer`

renamed `uniform_buffer()` to `buffer()`
removed `len()`, `is_empty()`, `capacity()`, `push()`, `reserve()`, `clear()`, `values()`
added `set()`, `get()`

### `DynamicUniformVec` -> `DynamicUniformBuffer`

renamed `uniform_buffer()` to `buffer()`
removed `capacity()`, `reserve()`


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-05-18 21:09:21 +00:00
François
ae0cb549ff helper tool to build examples in wasm (#4776)
# Objective

- add an helper to build examples in wasm (from #4700)

## Solution

- `cargo run -p build-wasm-example -- lighting`
2022-05-17 19:04:08 +00:00
Aron Derenyi
2e8dfc02ef Fixing confusing near and far fields in Camera (#4457)
# Objective

- Fixes #4456 

## Solution

- Removed the `near` and `far` fields from the camera and the views.

---

## Changelog

- Removed the `near` and `far` fields from the camera and the views.
- Removed the `ClusterFarZMode::CameraFarPlane` far z mode.

## Migration Guide

- Cameras no longer accept near and far values during initialization
- `ClusterFarZMode::Constant` should be used with the far value instead of `ClusterFarZMode::CameraFarPlane`
2022-05-16 16:37:33 +00:00
Mark Schmale
1ba7429371 Doc/module style doc blocks for examples (#4438)
# Objective

Provide a starting point for #3951, or a partial solution. 
Providing a few comment blocks to discuss, and hopefully find better one in the process. 

## Solution

Since I am pretty new to pretty much anything in this context, I figured I'd just start with a draft for some file level doc blocks. For some of them I found more relevant details (or at least things I considered interessting), for some others there is less. 

## Changelog

- Moved some existing comments from main() functions in the 2d examples to the file header level
- Wrote some more comment blocks for most other 2d examples

TODO: 
- [x] 2d/sprite_sheet, wasnt able to come up with something good yet 
- [x] all other example groups...


Also: Please let me know if the commit style is okay, or to verbose. I could certainly squash these things, or add more details if needed. 
I also hope its okay to raise this PR this early, with just a few files changed. Took me long enough and I dont wanted to let it go to waste because I lost motivation to do the whole thing. Additionally I am somewhat uncertain over the style and contents of the commets. So let me know what you thing please.
2022-05-16 13:53:20 +00:00
MrGVSV
acbee7795d bevy_reflect: Reflect arrays (#4701)
# Objective

> ℹ️ **Note**: This is a rebased version of #2383. A large portion of it has not been touched (only a few minor changes) so that any additional discussion may happen here. All credit should go to @NathanSWard for their work on the original PR.

- Currently reflection is not supported for arrays.
- Fixes #1213

## Solution

* Implement reflection for arrays via the `Array` trait.
* Note, `Array` is different from `List` in the way that you cannot push elements onto an array as they are statically sized.
* Now `List` is defined as a sub-trait of `Array`.

---

## Changelog

* Added the `Array` reflection trait
* Allows arrays up to length 32 to be reflected via the `Array` trait

## Migration Guide

* The `List` trait now has the `Array` supertrait. This means that `clone_dynamic` will need to specify which version to use:
  ```rust
  // Before
  let cloned = my_list.clone_dynamic();
  // After
  let cloned = List::clone_dynamic(&my_list);
  ```
* All implementers of `List` will now need to implement `Array` (this mostly involves moving the existing methods to the `Array` impl)

Co-authored-by: NathanW <nathansward@comcast.net>
Co-authored-by: MrGVSV <49806985+MrGVSV@users.noreply.github.com>
2022-05-13 01:13:30 +00:00
Charles
dfee7879c3 Add a clear() method to the EventReader that consumes the iterator (#4693)
# Objective

- It's pretty common to want to check if an EventReader has received one or multiple events while also needing to consume the iterator to "clear" the EventReader.
- The current approach is to do something like `events.iter().count() > 0` or `events.iter().last().is_some()`. It's not immediately obvious that the purpose of that is to consume the events and check if there were any events. My solution doesn't really solve that part, but it encapsulates the pattern.

## Solution

- Add a `.clear()` method that consumes the iterator.
	- It takes the EventReader by value to make sure it isn't used again after it has been called.

---

## Migration Guide

Not a breaking change, but if you ever found yourself in a situation where you needed to consume the EventReader and check if there was any events you can now use

```rust
fn system(events: EventReader<MyEvent>) {
	if !events.is_empty {
		events.clear();
		// Process the fact that one or more event was received
	}
}
```


Co-authored-by: Charles <IceSentry@users.noreply.github.com>
2022-05-13 00:57:04 +00:00
Troels Jessen
ae580e58dd Added keyboard key to mouse control for scene viewer example (#4411)
# Objective

- Added keyboard control for scene_viewer example. Fixes #4407 


Co-authored-by: Troels Jessen <kairyuka@gmail.com>
2022-05-11 09:31:39 +00:00
Robert Swain
76829f938e Add a fun skinned mesh stress test based on the animated_fox example (#4674)
# Objective

- Add a stress test for skinned meshes

https://user-images.githubusercontent.com/302146/167111578-55a7d58a-0ec8-4735-a043-f084f0ff3939.mp4
2022-05-08 02:57:00 +00:00
Daniel McNab
b731ebad1b Allow closing windows at runtime (#3575)
# Objective

Fixes #3180, builds from https://github.com/bevyengine/bevy/pull/2898

## Solution

Support requesting a window to be closed and closing a window in `bevy_window`, and handle this in `bevy_winit`.

This is a stopgap until we move to windows as entites, which I'm sure I'll get around to eventually.

## Changelog

### Added

- `Window::close` to allow closing windows.
- `WindowClosed` to allow reacting to windows being closed.

### Changed

Replaced `bevy::system::exit_on_esc_system` with `bevy:🪟:close_on_esc`.

## Fixed

The app no longer exits when any window is closed. This difference is only observable when there are multiple windows. 

## Migration Guide

`bevy::input::system::exit_on_esc_system` has been removed. Use `bevy:🪟:close_on_esc` instead.
`CloseWindow` has been removed. Use `Window::close` instead.
The `Close` variant has been added to `WindowCommand`. Handle this by closing the relevant window.
2022-05-05 13:35:43 +00:00
Dusty DeWeese
82d849d3dc Add support for vertex colors (#4528)
# Objective

Add support for vertex colors

## Solution

This change is modeled after how vertex tangents are handled, so the shader is conditionally compiled with vertex color support if the mesh has the corresponding attribute set.

Vertex colors are multiplied by the base color. I'm not sure if this is the best for all cases, but may be useful for modifying vertex colors without creating a new mesh.

I chose `VertexFormat::Float32x4`, but I'd prefer 16-bit floats if/when support is added.

## Changelog

### Added
- Vertex colors can be specified using the `Mesh::ATTRIBUTE_COLOR` mesh attribute.
2022-05-05 00:46:32 +00:00
Rob Parrett
f8e0fc190a Add RegularPolygon and Circle meshes (#3730)
# Objective

Bevy users often want to create circles and other simple shapes.

All the machinery is in place to accomplish this, and there are external crates that help. But when writing code for e.g. a new bevy example, it's not really possible to draw a circle without bringing in a new asset, writing a bunch of scary looking mesh code, or adding a dependency.

In particular, this PR was inspired by this interaction in another PR: https://github.com/bevyengine/bevy/pull/3721#issuecomment-1016774535

## Solution

This PR adds `shape::RegularPolygon` and `shape::Circle` (which is just a `RegularPolygon` that defaults to a large number of sides)

## Discussion

There's a lot of ongoing discussion about shapes in <https://github.com/bevyengine/rfcs/pull/12> and at least one other lingering shape PR (although it seems incomplete).

That RFC currently includes `RegularPolygon` and `Circle` shapes, so I don't think that having working mesh generation code in the engine for those shapes would add much burden to an author of an implementation.

But if we'd prefer not to add additional shapes until after that's sorted out, I'm happy to close this for now.

## Alternatives for users

For any users stumbling on this issue, here are some plugins that will help if you need more shapes.

https://github.com/Nilirad/bevy_prototype_lyon
https://github.com/johanhelsing/bevy_smud
https://github.com/Weasy666/bevy_svg
https://github.com/redpandamonium/bevy_more_shapes
https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline
2022-05-05 00:03:47 +00:00
Johannes Hackel
e29bd50de8 Add file metadata to AssetIo (#2123)
This is a replacement for #2106

This adds a `Metadata` struct which contains metadata information about a file, at the moment only the file type.
It also adds a `get_metadata` to `AssetIo` trait and an `asset_io` accessor method to `AssetServer` and `LoadContext`

I am not sure about the changes in `AndroidAssetIo ` and `WasmAssetIo`.
2022-05-02 18:04:47 +00:00
Rob Parrett
61a3494a06 Add 3d shapes example (#4613)
# Objective

- As requested here: https://github.com/bevyengine/bevy/pull/4520#issuecomment-1109302039
- Make it easier to spot issues with built-in shapes

## Solution

https://user-images.githubusercontent.com/200550/165624709-c40dfe7e-0e1e-4bd3-ae52-8ae66888c171.mp4

- Add an example showcasing the built-in 3d shapes with lighting/shadows
- Rotate objects in such a way that all faces are seen by the camera
- Add a UV debug texture

## Discussion

I'm not sure if this is what @alice-i-cecile had in mind, but I adapted the little "torus playground" from the issue linked above to include all built-in shapes.

This exact arrangement might not be particularly scalable if many more shapes are added. Maybe a slow camera pan, or cycling with the keyboard or on a timer, or a sidebar with buttons would work better. If one of the latter options is used, options for showing wireframes or computed flat normals might add some additional utility.

Ideally, I think we'd have a better way of visualizing normals.

Happy to rework this or close it if there's not a consensus around it being useful.
2022-05-02 13:20:56 +00:00
KDecay
51509a9a3e Change gamepad.rs tuples to normal structs (#4519)
# Objective

- Part of the splitting process of #3692.

## Solution

- Remove / change the tuple structs inside of `gamepad.rs` of `bevy_input` to normal structs.

## Reasons

- It made the `gamepad_connection_system` cleaner.
- It made the `gamepad_input_events.rs` example cleaner (which is probably the most notable change for the user facing API).
- Tuple structs are not descriptive (`.0`, `.1`).
- Using tuple structs for more than 1 field is a bad idea (This means that the `Gamepad` type might be fine as a tuple struct, but I still prefer normal structs over tuple structs).

Feel free to discuss this change as this is more or less just a matter of taste.

## Changelog

### Changed

- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function.

## Migration Guide

- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function. To migrate change every instantiation to use the `new()` function instead and use the appropriate field names instead of `.0` and `.1`.
2022-05-02 13:20:55 +00:00
TheRawMeatball
73c78c3667 Use lifetimed, type erased pointers in bevy_ecs (#3001)
# Objective

`bevy_ecs` has large amounts of unsafe code which is hard to get right and makes it difficult to audit for soundness.

## Solution

Introduce lifetimed, type-erased pointers: `Ptr<'a>` `PtrMut<'a>` `OwningPtr<'a>'` and `ThinSlicePtr<'a, T>` which are newtypes around a raw pointer with a lifetime and conceptually representing strong invariants about the pointee and validity of the pointer.

The process of converting bevy_ecs to use these has already caught multiple cases of unsound behavior.

## Changelog

TL;DR for release notes: `bevy_ecs` now uses lifetimed, type-erased pointers internally, significantly improving safety and legibility without sacrificing performance. This should have approximately no end user impact, unless you were meddling with the (unfortunately public) internals of `bevy_ecs`.

- `Fetch`, `FilterFetch` and `ReadOnlyFetch` trait no longer have a `'state` lifetime
    - this was unneeded
- `ReadOnly/Fetch` associated types on `WorldQuery` are now on a new `WorldQueryGats<'world>` trait
    - was required to work around lack of Generic Associated Types (we wish to express `type Fetch<'a>: Fetch<'a>`)
- `derive(WorldQuery)` no longer requires `'w` lifetime on struct
    - this was unneeded, and improves the end user experience
- `EntityMut::get_unchecked_mut` returns `&'_ mut T` not `&'w mut T`
    - allows easier use of unsafe API with less footguns, and can be worked around via lifetime transmutery as a user
- `Bundle::from_components` now takes a `ctx` parameter to pass to the `FnMut` closure
    - required because closure return types can't borrow from captures
- `Fetch::init` takes `&'world World`, `Fetch::set_archetype` takes `&'world Archetype` and `&'world Tables`, `Fetch::set_table` takes `&'world Table`
    - allows types implementing `Fetch` to store borrows into world
- `WorldQuery` trait now has a `shrink` fn to shorten the lifetime in `Fetch::<'a>::Item`
    - this works around lack of subtyping of assoc types, rust doesnt allow you to turn `<T as Fetch<'static>>::Item'` into `<T as Fetch<'a>>::Item'`
    - `QueryCombinationsIter` requires this
- Most types implementing `Fetch` now have a lifetime `'w`
    - allows the fetches to store borrows of world data instead of using raw pointers

## Migration guide

- `EntityMut::get_unchecked_mut` returns a more restricted lifetime, there is no general way to migrate this as it depends on your code
- `Bundle::from_components` implementations must pass the `ctx` arg to `func`
- `Bundle::from_components` callers have to use a fn arg instead of closure captures for borrowing from world
- Remove lifetime args on `derive(WorldQuery)` structs as it is nonsensical
- `<Q as WorldQuery>::ReadOnly/Fetch` should be changed to either `RO/QueryFetch<'world>` or `<Q as WorldQueryGats<'world>>::ReadOnly/Fetch`
- `<F as Fetch<'w, 's>>` should be changed to `<F as Fetch<'w>>`
- Change the fn sigs of `Fetch::init/set_archetype/set_table` to match respective trait fn sigs
- Implement the required `fn shrink` on any `WorldQuery` implementations
- Move assoc types `Fetch` and `ReadOnlyFetch` on `WorldQuery` impls to `WorldQueryGats` impls
- Pass an appropriate `'world` lifetime to whatever fetch struct you are for some reason using

### Type inference regression

in some cases rustc may give spurrious errors when attempting to infer the `F` parameter on a query/querystate this can be fixed by manually specifying the type, i.e. `QueryState:🆕:<_, ()>(world)`. The error is rather confusing:

```rust=
error[E0271]: type mismatch resolving `<() as Fetch<'_>>::Item == bool`
    --> crates/bevy_pbr/src/render/light.rs:1413:30
     |
1413 |             main_view_query: QueryState::new(world),
     |                              ^^^^^^^^^^^^^^^ expected `bool`, found `()`
     |
     = note: required because of the requirements on the impl of `for<'x> FilterFetch<'x>` for `<() as WorldQueryGats<'x>>::Fetch`
note: required by a bound in `bevy_ecs::query::QueryState::<Q, F>::new`
    --> crates/bevy_ecs/src/query/state.rs:49:32
     |
49   |     for<'x> QueryFetch<'x, F>: FilterFetch<'x>,
     |                                ^^^^^^^^^^^^^^^ required by this bound in `bevy_ecs::query::QueryState::<Q, F>::new`
```

---

Made with help from @BoxyUwU and @alice-i-cecile 

Co-authored-by: Boxy <supbscripter@gmail.com>
2022-04-27 23:44:06 +00:00
Nathan Pinard
f1aae380ab Added example of creating a system from a closure (#4327)
Fixes #4262
2022-04-27 18:02:07 +00:00
Christopher Durham
3d4e0066f4 Move float_ord from bevy_core to bevy_utils (#4189)
# Objective

Reduce the catch-all grab-bag of functionality in bevy_core by moving FloatOrd to bevy_utils.

A step in addressing #2931 and splitting bevy_core into more specific locations.

## Solution

Move FloatOrd into bevy_utils. Fix the compile errors.

As a result, bevy_core_pipeline, bevy_pbr, bevy_sprite, bevy_text, and bevy_ui no longer depend on bevy_core (they were only using it for `FloatOrd` previously).
2022-04-27 18:02:05 +00:00
François
d5e770dfcb use elapsed on instant (#4599)
# Objective

- reopen #4497 on main
- Make the example a tiny bit more elegant
2022-04-26 18:42:44 +00:00
Aevyrie
4aa56050b6 Add infallible resource getters for WorldCell (#4104)
# Objective

- Eliminate all `worldcell.get_resource().unwrap()` cases.
- Provide helpful messages on panic.

## Solution

- Adds infallible resource getters to `WorldCell`, mirroring `World`.
2022-04-25 23:19:13 +00:00
KDecay
989fb8a78d Move Rect to bevy_ui and rename it to UiRect (#4276)
# Objective

- Closes #335.
- Related #4285.
- Part of the splitting process of #3503.

## Solution

- Move `Rect` to `bevy_ui` and rename it to `UiRect`.

## Reasons

- `Rect` is only used in `bevy_ui` and therefore calling it `UiRect` makes the intent clearer.
- We have two types that are called `Rect` currently and it's missleading (see `bevy_sprite::Rect` and #335).
- Discussion in #3503.

## Changelog

### Changed

- The `Rect` type got moved from `bevy_math` to `bevy_ui` and renamed to `UiRect`.

## Migration Guide

- The `Rect` type got renamed to `UiRect`. To migrate you just have to change every occurrence of `Rect` to `UiRect`.

Co-authored-by: KDecay <KDecayMusic@protonmail.com>
2022-04-25 19:20:38 +00:00
KDecay
7a7f097485 Move Size to bevy_ui (#4285)
# Objective

- Related #4276.
- Part of the splitting process of #3503.

## Solution

- Move `Size` to `bevy_ui`.

## Reasons

- `Size` is only needed in `bevy_ui` (because it needs to use `Val` instead of `f32`), but it's also used as a worse `Vec2`  replacement in other areas.
- `Vec2` is more powerful than `Size` so it should be used whenever possible.
- Discussion in #3503.

## Changelog

### Changed

- The `Size` type got moved from `bevy_math` to `bevy_ui`.

## Migration Guide

- The `Size` type got moved from `bevy::math` to `bevy::ui`. To migrate you just have to import `bevy::ui::Size` instead of `bevy::math::Math` or use the `bevy::prelude` instead.

Co-authored-by: KDecay <KDecayMusic@protonmail.com>
2022-04-25 13:54:46 +00:00
François
18c6a7b40e do not impl Component for Task (#4113)
# Objective

- `Task` are `Component`.
- They should not.

## Solution

- Remove the impl, and update the example to show a wrapper.

#4052 for reference
2022-04-22 06:29:38 +00:00
MrGVSV
80c6babd97 Remove nonexistent WgpuResourceDiagnosticsPlugin (#4541)
# Objective

Uncommenting the following results in a compile error: 7557f4db83/examples/diagnostics/log_diagnostics.rs (L14-L15)

## Solution

Remove the commented line.
2022-04-20 11:46:33 +00:00
Robert Swain
c2a9d5843d Faster assign lights to clusters (#4345)
# Objective

- Fixes #4234
- Fixes #4473 
- Built on top of #3989
- Improve performance of `assign_lights_to_clusters`

## Solution

- Remove the OBB-based cluster light assignment algorithm and calculation of view space AABBs
- Implement the 'iterative sphere refinement' algorithm used in Just Cause 3 by Emil Persson as documented in the Siggraph 2015 Practical Clustered Shading talk by Persson, on pages 42-44 http://newq.net/dl/pub/s2015_practical.pdf
- Adapt to also support orthographic projections
- Add `many_lights -- orthographic` for testing many lights using an orthographic projection

## Results

- `assign_lights_to_clusters` in `many_lights` before this PR on an M1 Max over 1500 frames had a median execution time of 1.71ms. With this PR it is 1.51ms, a reduction of 0.2ms or 11.7% for this system.

---

## Changelog

- Changed: Improved cluster light assignment performance

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-04-15 02:53:20 +00:00
Charles
6e5955f162 Add simple collision sound to breakout (#4331)
# Objective

- Add sound effect to the breakout example

## Solution

- Add a collision event and a system that listens to the event and plays a sound

I only added a single sound for all collisions for the sake of simplicity, but this could easily be extended to play a different sound depending on the type of entity hit.

The sound was generated randomly by using https://sfxr.me

https://sfxr.me/#11111GA9soYREjtsWhzjPrpMDEYSjX8Fo1E6PnKhxdw6tu869XW4EAc3nzpKVAYLMzToNcHQtQjeBqjZukqPmMDToGdYQQCWBnC3nEYfp53se5ep9btxRdLK

Closes #4326

https://user-images.githubusercontent.com/8348954/160154727-00e30743-3385-4c2f-97f0-1aaaf9a4dcc5.mp4

For some reason the video has a lot of delay in the sound, but when playing it locally there's no delay

---

## Changelog

- Added sound to breakout example
- Added bevy_audio and vorbis to the feature list ran for examples in CI

## Migration Guide

N/A
2022-04-14 20:20:38 +00:00
Rob Parrett
e1c2ace1f2 More tidying of contributors example (#4443)
# Objective

Continue the effort to clean up this example

## Solution

- Store contributor name as component to avoid awkward vec of tuples
- Name the variable storing the Random Number Generator "rng"
- Use init_resource for resource implementing default
- Fix a few spots where an Entity was unnecessarily referenced and immediately dereferenced
- Fix up an awkward comment
2022-04-14 19:30:36 +00:00
Dusty DeWeese
5a297d7903 Reuse texture when resolving multiple passes (#3552)
# Objective

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

## Solution

Uses a `HashMap` from `RenderTarget` to sampled textures when preparing `ViewTarget`s to ensure that two passes with the same render target get sampled to the same texture.

This builds on and depends on https://github.com/bevyengine/bevy/pull/3412, so this will be a draft PR until #3412 is merged. All changes for this PR are in the last commit.
2022-04-12 19:27:30 +00:00
Jakob Hellermann
193e8c4ada scene_viewer: load cameras (#4425)
# Objective

glTF files can contain cameras. Currently the scene viewer example uses _a_ camera defined in the file if possible, otherwise it spawns a new one. It would be nice if instead it could load all the cameras and cycle through them, while also having a separate user-controller camera.

## Solution

- instead of just a camera that is already defined, always spawn a new separate user-controller camera
- maintain a list of loaded cameras and cycle through them (wrapping to the user-controller camera) when pressing `C`

This matches the behavious that https://github.khronos.org/glTF-Sample-Viewer-Release/ has.

## Implementation notes

- The gltf scene asset loader just spawns the cameras into the world, but does not return a mapping of camera index to bevy entity. So instead the scene_viewer example just collects all spawned cameras with a good old `query.iter().collect()`, so the order is unspecified and may change between runs.

## Demo

https://user-images.githubusercontent.com/22177966/161826637-40161482-5b3b-4df5-aae8-1d5e9b918393.mp4


using the virtual city glTF sample file: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/VC

Co-authored-by: Jakob Hellermann <hellermann@sipgate.de>
2022-04-11 22:56:06 +00:00
Alice Cecile
c747cc526b Group stress test examples (#4289)
# Objective

- Several examples are useful for qualitative tests of Bevy's performance
- By contrast, these are less useful for learning material: they are often relatively complex and have large amounts of setup and are performance optimized.

## Solution

- Move bevymark, many_sprites and many_cubes into the new stress_tests example folder
- Move contributors into the games folder: unlike the remaining examples in the 2d folder, it is not focused on demonstrating a clear feature.
2022-04-10 02:05:21 +00:00
Alex Saveau
f23ae104bd Slight perf improvements and tidy for contributors example (#3764) 2022-04-08 04:02:14 +00:00
François
3555603df1 example on how to create an animation in code (#4399)
# Objective

- Animation can be used outside of glTF, but are not obvious on how to create them

## Solution

- Add an example creating an animation
2022-04-07 23:53:43 +00:00
Daniel McNab
21a875d67b Some small changes related to run criteria piping (#3923)
Remove the 'chaining' api, as it's peculiar

~~Implement the label traits for `Box<dyn ThatTrait>` (n.b. I'm not confident about this change, but it was the quickest path to not regressing)~~

Remove the need for '`.system`' when using run criteria piping
2022-04-07 19:08:08 +00:00
Robert Swain
c5963b4fd5 Use storage buffers for clustered forward point lights (#3989)
# Objective

- Make use of storage buffers, where they are available, for clustered forward bindings to support far more point lights in a scene
- Fixes #3605 
- Based on top of #4079 

This branch on an M1 Max can keep 60fps with about 2150 point lights of radius 1m in the Sponza scene where I've been testing. The bottleneck is mostly assigning lights to clusters which grows faster than linearly (I think 1000 lights was about 1.5ms and 5000 was 7.5ms). I have seen papers and presentations leveraging compute shaders that can get this up to over 1 million. That said, I think any further optimisations should probably be done in a separate PR.

## Solution

- Add `RenderDevice` to the `Material` and `SpecializedMaterial` trait `::key()` functions to allow setting flags on the keys depending on feature/limit availability
- Make `GpuPointLights` and `ViewClusterBuffers` into enums containing `UniformVec` and `StorageBuffer` variants. Implement the necessary API on them to make usage the same for both cases, and the only difference is at initialisation time.
- Appropriate shader defs in the shader code to handle the two cases

## Context on some decisions / open questions

- I'm using `max_storage_buffers_per_shader_stage >= 3` as a check to see if storage buffers are supported. I was thinking about diving into 'binding resource management' but it feels like we don't have enough use cases to understand the problem yet, and it is mostly a separate concern to this PR, so I think it should be handled separately.
- Should `ViewClusterBuffers` and `ViewClusterBindings` be merged, duplicating the count variables into the enum variants?


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-04-07 16:16:35 +00:00
François
e7e74457c7 scene viewer improvements: animation reset (#4420)
# Objective

- Changing animation mid animation can leave the model not in its original position
- ~~The movement speed is fixed, no matter the size of the model~~

## Solution

- when changing animation, set it to its initial state and wait for one frame before changing the animation
- ~~when settings the camera controller, use the camera transform to know how far it is from the origin and use the distance for the speed~~
2022-04-07 15:18:20 +00:00
Jakob Hellermann
7e3637c36f fix scene_viewer example on wasm (#4426)
The scene viewer example doesn't run on wasm because it sets the asset folder to `std::env::var("CARGO_MANIFEST_DIR").unwrap()`, which isn't supported on the web.

Solution: set the asset folder to `"."` instead.
2022-04-05 20:45:06 +00:00
Daniel McNab
99a2dc50a6 Cleanup some outdated parts of ecs_guide (#4342)
# Objective

- `Local`s can no longer be accessed outside of their creating system, but these docs say they can be.
- There's also little reason to have a pure wrapper type for `Local`s; they can just use the real type. The parameter name should be sufficiently documenting.
2022-04-04 21:16:36 +00:00
Charles
28d0a40028 Only enable mouse movement when pressed in scene_viewer (#4405)
# Objective

- Only move the camera when explicitly wanted, otherwise the camera goes crazy if the cursor isn't already in the middle of the window when it opens.

## Solution

- Check if the Left mouse button is pressed before updating the mouse delta
- Input is configurable
2022-04-03 21:42:23 +00:00
Jakob Hellermann
ac29cbecf7 add support for loading animations in scene_viewer example (#4403)
The `scene_viewer` example can be used to load and display glTF scenes. This PR also adds the ability to play animations in the file and cycle through them.

https://user-images.githubusercontent.com/22177966/161443011-0365c7de-c49e-44c4-b0f7-44330a015a4f.mp4
2022-04-03 19:35:05 +00:00
François
449a1d223c animation player (#4375)
# Objective

- Add a basic animation player
  - Single track
  - Not generic, can only animate `Transform`s
  - With plenty of possible optimisations available
  - Close-ish to https://github.com/bevyengine/rfcs/pull/49
- https://discord.com/channels/691052431525675048/774027865020039209/958820063148929064

## Solution

- Can play animations
  - looping or not
- Can pause animations
- Can seek in animation
- Can alter speed of animation
- I also removed the previous gltf animation example

https://user-images.githubusercontent.com/8672791/161051887-e79283f0-9803-448a-93d0-5f7a62acb02d.mp4
2022-04-02 22:36:02 +00:00
Jakob Hellermann
0ed08d6a15 fix multiple_windows example (#4389)
The example was broken in #3635 when the `ActiveCamera` logic was introduced, after which there could only be one active `Camera3d` globally.
Ideally there could be one `Camera3d` per render target, not globally, but that isn't the case yet.

To fix the example, we need to
- don't use `Camera3d` twice, add a new `SecondWindowCamera3d` marker
- add the `CameraTypePlugin::<SecondWindowCamera3d>`
- extract the correct `RenderPhase`s
- add a 3d pass driver node for the secondary camera

Fixes #4378

Co-authored-by: Jakob Hellermann <hellermann@sipgate.de>
2022-04-01 21:11:07 +00:00
Daniel McNab
c26be39719 Remove unnecessary system labels (#4340)
# Objective

- Since #4224, using labels which only refer to one system doesn't make sense.

## Solution

- Remove some of those.

## Future work

- We should remove the ability to use strings as system labels entirely. I haven't in this PR because there are tests which use this, and that's a lot of code to change.
   - The only use cases for labels are either intra-crate, which use #4224, or inter-crate, which should either use #4224 or explicit types. Neither of those should use strings.
2022-04-01 21:11:05 +00:00
bilsen
63fee2572b ParamSet for conflicting SystemParam:s (#2765)
# Objective
Add a system parameter `ParamSet` to be used as container for conflicting parameters.

## Solution
Added two methods to the SystemParamState trait, which gives the access used by the parameter. Did the implementation. Added some convenience methods to FilteredAccessSet. Changed `get_conflicts` to return every conflicting component instead of breaking on the first conflicting `FilteredAccess`.


Co-authored-by: bilsen <40690317+bilsen@users.noreply.github.com>
2022-03-29 23:39:38 +00:00
Yutao Yuan
954022c799 Add text wrapping support to Text2d (#4347)
# Objective

Fixes #4344.

## Solution

Add a new component `Text2dBounds` to `Text2dBundle` that specifies the maximum width and height of text. Text will wrap according to this size.
2022-03-29 23:03:20 +00:00
James Liu
31bd4ecbbc Mesh Skinning. Attempt #3 (#4238)
# Objective
Load skeletal weights and indices from GLTF files. Animate meshes.

## Solution
 - Load skeletal weights and indices from GLTF files.
 - Added `SkinnedMesh` component and ` SkinnedMeshInverseBindPose` asset
 - Added `extract_skinned_meshes` to extract joint matrices.
 - Added queue phase systems for enqueuing the buffer writes.

Some notes:

 -  This ports part of # #2359 to the current main.
 -  This generates new `BufferVec`s and bind groups every frame. The expectation here is that the number of `Query::get` calls during extract is probably going to be the stronger bottleneck, with up to 256 calls per skinned mesh. Until that is optimized, caching buffers and bind groups is probably a non-concern.
 - Unfortunately, due to the uniform size requirements, this means a 16KB buffer is allocated for every skinned mesh every frame. There's probably a few ways to get around this, but most of them require either compute shaders or storage buffers, which are both incompatible with WebGL2.

Co-authored-by: james7132 <contact@jamessliu.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
2022-03-29 18:31:13 +00:00
MrGVSV
f16768d868 bevy_derive: Add derives for Deref and DerefMut (#4328)
# Objective

A common pattern in Rust is the [newtype](https://doc.rust-lang.org/rust-by-example/generics/new_types.html). This is an especially useful pattern in Bevy as it allows us to give common/foreign types different semantics (such as allowing it to implement `Component` or `FromWorld`) or to simply treat them as a "new type" (clever). For example, it allows us to wrap a common `Vec<String>` and do things like:

```rust
#[derive(Component)]
struct Items(Vec<String>);

fn give_sword(query: Query<&mut Items>) { 
  query.single_mut().0.push(String::from("Flaming Poisoning Raging Sword of Doom"));
}
```

> We could then define another struct that wraps `Vec<String>` without anything clashing in the query.

However, one of the worst parts of this pattern is the ugly `.0` we have to write in order to access the type we actually care about. This is why people often implement `Deref` and `DerefMut` in order to get around this.

Since it's such a common pattern, especially for Bevy, it makes sense to add a derive macro to automatically add those implementations.


## Solution

Added a derive macro for `Deref` and another for `DerefMut` (both exported into the prelude). This works on all structs (including tuple structs) as long as they only contain a single field:

```rust
#[derive(Deref)]
struct Foo(String);

#[derive(Deref, DerefMut)]
struct Bar {
  name: String,
}
```

This allows us to then remove that pesky `.0`:

```rust
#[derive(Component, Deref, DerefMut)]
struct Items(Vec<String>);

fn give_sword(query: Query<&mut Items>) { 
  query.single_mut().push(String::from("Flaming Poisoning Raging Sword of Doom"));
}
```

### Alternatives

There are other alternatives to this such as by using the [`derive_more`](https://crates.io/crates/derive_more) crate. However, it doesn't seem like we need an entire crate just yet since we only need `Deref` and `DerefMut` (for now).

### Considerations

One thing to consider is that the Rust std library recommends _not_ using `Deref` and `DerefMut` for things like this: "`Deref` should only be implemented for smart pointers to avoid confusion" ([reference](https://doc.rust-lang.org/std/ops/trait.Deref.html)). Personally, I believe it makes sense to use it in the way described above, but others may disagree.

### Additional Context

Discord: https://discord.com/channels/691052431525675048/692572690833473578/956648422163746827 (controversiality discussed [here](https://discord.com/channels/691052431525675048/692572690833473578/956711911481835630))

---

## Changelog

- Add `Deref` derive macro (exported to prelude)
- Add `DerefMut` derive macro (exported to prelude)
- Updated most newtypes in examples to use one or both derives

Co-authored-by: MrGVSV <49806985+MrGVSV@users.noreply.github.com>
2022-03-29 02:10:06 +00:00
Alice Cecile
8570b651f9 Clean up Breakout logic (#4311)
# Objective

1. Spawning walls in the Breakout example was hard to follow and error-prone.
2. The strategy used in `paddle_movement_system` was somewhat convoluted.
3. Correctly modifying the size of the arena was hard, due to implicit coupling between the bounds and the bounds that the paddle can move in.

## Solution

1. Refactor this to use a WallBundle struct with a builder; neatly demonstrating some essential patterns along the way.
2. Use clamp and avoid using weird &mut strategies.
3. Refactor logic to allow users to tweak the brick size, and automatically adjust the number of rows and columns to match.
4. Make the brick layout more like classic breakout!

![image](https://user-images.githubusercontent.com/3579909/160019864-06747361-3b5b-4944-b3fd-4978604e2ef5.png)
2022-03-24 23:57:36 +00:00
Alice Cecile
a190cd59db Revert changes to colors in Breakout game (#4325)
# Objective

- existing Breakout colors are too dark and saturated in places

## Solution

- Revert colors in Breakout examples to original values.
2022-03-24 22:15:58 +00:00
Alice Cecile
ab83336f51 Replace _system system names in Breakout examples (#4312)
# Objective

- The Breakout example uses system names like `paddle_movement_system`
- _system syntax is redundant
- the [community has spoken](https://github.com/bevyengine/bevy/discussions/2804), and prefers to avoid `_system` system names by a more than 2:1 ratio
- existing system names were not terribly descriptive

## Solution

- rename the systems to take the form of `verb`, rather than `noun_system` to better capture the behavior they are implenting
- yeet `_system`
2022-03-24 17:54:40 +00:00
Carter Anderson
b1c3e9862d Auto-label function systems with SystemTypeIdLabel (#4224)
This adds the concept of "default labels" for systems (currently scoped to "parallel systems", but this could just as easily be implemented for "exclusive systems"). Function systems now include their function's `SystemTypeIdLabel` by default.

This enables the following patterns:

```rust
// ordering two systems without manually defining labels
app
  .add_system(update_velocity)
  .add_system(movement.after(update_velocity))

// ordering sets of systems without manually defining labels
app
  .add_system(foo)
  .add_system_set(
    SystemSet::new()
      .after(foo)
      .with_system(bar)
      .with_system(baz)
  )
```

Fixes: #4219
Related to: #4220 

Credit to @aevyrie @alice-i-cecile @DJMcNab (and probably others) for proposing (and supporting) this idea about a year ago. I was a big dummy that both shut down this (very good) idea and then forgot I did that. Sorry. You all were right!
2022-03-23 22:53:56 +00:00
Alice Cecile
d51b54a658 Break out Breakout components into a more sensible organization (#4261)
# Objective

- The components in the Breakout game are defined in a strange fashion.
   - Components should decouple behavior wherever possible.
   - Systems should be as general as possible, to make extending behavior easier.
   - Marker components are idiomatic and useful, but marker components and query filters were not used.
- The existing design makes it challenging for beginners to extend the example into a high-quality game.

## Solution

- Refactor component definitions in the Breakout example to reflect principles above.

## Context

A small portion of the changes made in #2094. Interacts with changes in #4255; merge conflicts will have to be resolved.
2022-03-23 21:17:50 +00:00
Kurt Kühnert
9e450f2827 Compute Pipeline Specialization (#3979)
# Objective

- Fixes #3970
- To support Bevy's shader abstraction(shader defs, shader imports and hot shader reloading) for compute shaders, I have followed carts advice and change the `PipelinenCache` to accommodate both compute and render pipelines.

## Solution

- renamed `RenderPipelineCache` to `PipelineCache`
- Cached Pipelines are now represented by an enum (render, compute)
- split the `SpecializedPipelines` into `SpecializedRenderPipelines` and `SpecializedComputePipelines`
- updated the game of life example

## Open Questions

- should `SpecializedRenderPipelines` and `SpecializedComputePipelines` be merged and how would we do that?
- should the `get_render_pipeline` and `get_compute_pipeline` methods be merged?
- is pipeline specialization for different entry points a good pattern




Co-authored-by: Kurt Kühnert <51823519+Ku95@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-03-23 00:27:26 +00:00
Boxy
024d98457c yeet unsound lifetime annotations on Query methods (#4243)
# Objective
Continuation of #2964 (I really should have checked other methods when I made that PR)

yeet unsound lifetime annotations on `Query` methods.
Example unsoundness:
```rust
use bevy::prelude::*;

fn main() {
    App::new().add_startup_system(bar).add_system(foo).run();
}

pub fn bar(mut cmds: Commands) {
    let e = cmds.spawn().insert(Foo { a: 10 }).id();
    cmds.insert_resource(e);
}

#[derive(Component, Debug, PartialEq, Eq)]
pub struct Foo {
    a: u32,
}
pub fn foo(mut query: Query<&mut Foo>, e: Res<Entity>) {
    dbg!("hi");
    {
        let data: &Foo = query.get(*e).unwrap();
        let data2: Mut<Foo> = query.get_mut(*e).unwrap();
        assert_eq!(data, &*data2); // oops UB
    }

    {
        let data: &Foo = query.single();
        let data2: Mut<Foo> = query.single_mut();
        assert_eq!(data, &*data2); // oops UB
    }

    {
        let data: &Foo = query.get_single().unwrap();
        let data2: Mut<Foo> = query.get_single_mut().unwrap();
        assert_eq!(data, &*data2); // oops UB
    }

    {
        let data: &Foo = query.iter().next().unwrap();
        let data2: Mut<Foo> = query.iter_mut().next().unwrap();
        assert_eq!(data, &*data2); // oops UB
    }

    {
        let mut opt_data: Option<&Foo> = None;
        let mut opt_data_2: Option<Mut<Foo>> = None;
        query.for_each(|data| opt_data = Some(data));
        query.for_each_mut(|data| opt_data_2 = Some(data));
        assert_eq!(opt_data.unwrap(), &*opt_data_2.unwrap()); // oops UB
    }
    dbg!("bye");
}

```

## Solution
yeet unsound lifetime annotations on `Query` methods

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-03-22 02:49:41 +00:00
François
fbe7a49d5b Gltf animations (#3751)
# Objective

- Load informations for animations from GLTF
- Make experimenting on animations easier

# Non Objective

- Implement a solutions for all animations in Bevy. This would need a discussion / RFC. The goal here is only to have the information available to try different APIs

## Solution

- Load animations with a representation close to the GLTF spec
- Add an example to display animations. There is an animation driver in the example, not in Bevy code, to show how it can be used. The example is cycling between examples from the official gltf sample ([AnimatedTriangle](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedTriangle), [BoxAnimated](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/BoxAnimated)), and one from me with some cases not present in the official examples.


https://user-images.githubusercontent.com/8672791/150696656-073403f0-d921-43b6-beaf-099c7aee16ed.mp4




Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-03-22 02:26:34 +00:00
Alex
54fbaf4b4c Add transform hierarchy stress test (#4170)
## Objective

There recently was a discussion on Discord about a possible test case for stress-testing transform hierarchies.

## Solution

Create a test case for stress testing transform propagation.

*Edit:* I have scrapped my previous example and built something more functional and less focused on visuals.

There are three test setups:

- `TestCase::Tree` recursively creates a tree with a specified depth and branch width
- `TestCase::NonUniformTree` is the same as `Tree` but omits nodes in a way that makes the tree "lean" towards one side, like this:
  <details>
  <summary></summary>

  ![image](https://user-images.githubusercontent.com/3957610/158069737-2ddf4e4a-7d5c-4ee5-8566-424a54a06723.png)
  </details>
- `TestCase::Humanoids` creates one or more separate hierarchies based on the structure of common humanoid rigs
  - this can both insert `active` and `inactive` instances of the human rig

It's possible to parameterize which parts of the hierarchy get updated (transform change) and which remain unchanged. This is based on @james7132 suggestion:
There's a probability to decide which entities should remain static. On top of that these changes can be limited to a certain range in the hierarchy (min_depth..max_depth).
2022-03-21 20:36:46 +00:00
Alice Cecile
af24576b96 Move magic numbers into constants in Breakout example (#4255)
# Objective

- The Breakout example has a lot of configurable constant values for setup, but these are buried in the source code.
- Magic numbers scattered in the source code are hard to follow.
- Providing constants up front makes tweaking examples very approachable.

## Solution

- Move magic numbers into constants

## Context

Part of the changes made in #2094; split out for easier review.
2022-03-19 23:05:02 +00:00
Robert Swain
738cd5e740 Add a scene viewer tool (#4183)
# Objective

- Allow quick and easy testing of scenes

## Solution

- Add a `scene-viewer` tool based on `load_gltf`.
  - Run it with e.g. `cargo run --release --example scene_viewer --features jpeg -- ../some/path/assets/models/Sponza/glTF/Sponza.gltf#Scene0`
- Configure the asset path as pointing to the repo root for convenience (paths specified relative to current working directory)
- Copy over the camera controller from the `shadow_biases` example
- Support toggling the light animation
- Support toggling shadows
- Support adjusting the directional light shadow projection (cascaded shadow maps will remove the need for this later)

I don't want to do too much on it up-front. Rather we can add features over time as we need them.
2022-03-19 19:14:13 +00:00
Chris Foster
21f6760b2a Render to texture example: No need to create an image handle manually. (#4223)
# Objective

- Make the example a little easier to follow by removing unnecessary steps.

## Solution

- `Assets<Image>` will give us a handle for our render texture if we call `add()` instead of `set()`.  No need to set it manually; one less thing to think about while reading the example.
2022-03-16 01:53:04 +00:00
Mizu
9dfd4e4b08 Add examples for Transforms (#2441)
# Add Transform Examples

- Adding examples for moving/rotating entities (with its own section) to resolve #2400 

I've stumbled upon this project and been fiddling around a little. Saw the issue and thought I might just add some examples for the proposed transformations.
Mind to check if I got the gist correctly and suggest anything I can improve?
2022-03-15 05:49:49 +00:00
Jakob Hellermann
bf6de89622 use marker components for cameras instead of name strings (#3635)
**Problem**
- whenever you want more than one of the builtin cameras (for example multiple windows, split screen, portals), you need to add a render graph node that executes the correct sub graph, extract the camera into the render world and add the correct `RenderPhase<T>` components
- querying for the 3d camera is annoying because you need to compare the camera's name to e.g. `CameraPlugin::CAMERA_3d`

**Solution**
- Introduce the marker types `Camera3d`, `Camera2d` and `CameraUi`
-> `Query<&mut Transform, With<Camera3d>>` works
- `PerspectiveCameraBundle::new_3d()` and `PerspectiveCameraBundle::<Camera3d>::default()` contain the `Camera3d` marker
- `OrthographicCameraBundle::new_3d()` has `Camera3d`, `OrthographicCameraBundle::new_2d()` has `Camera2d`
- remove `ActiveCameras`, `ExtractedCameraNames`
- run 2d, 3d and ui passes for every camera of their respective marker
-> no custom setup for multiple windows example needed

**Open questions**
- do we need a replacement for `ActiveCameras`? What about a component `ActiveCamera { is_active: bool }` similar to `Visibility`?

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-03-12 00:41:06 +00:00
Aevyrie
b493165bfe Use reactive rendering for ui examples. (#4164)
# Objective

- Use the low power, reactive rendering settings for UI examples.
- Make the feature more discoverable by using it in an applicable context.
2022-03-09 21:59:57 +00:00
Rob Parrett
1a85fb5ea3 Fix mesh2d_manual example (#4037)
# Objective

Fixes #4036 

## Solution

- Use `VertexBufferLayout::from_vertex_formats`
- Actually put a u32 into `ATTRIBUTE_COLOR` and convert it in the shader

I'm not 100% sure about the color stuff. It seems like `ATTRIBUTE_COLOR` has been `Uint32` this whole time, but this example previously worked with `[f32; 4]` somehow, perhaps because the vertex layout was manually specified.

Let me know if that can be improved, or feel free to close for an alternative fix.
2022-03-08 17:50:44 +00:00
Emerson MX
6ce8e50068 Add mouse grab example (#4114)
Fixes #4094
2022-03-08 17:14:08 +00:00
Robert Swain
a188babce2 many_cubes: Add a cube pattern suitable for benchmarking culling changes (#4126)
# Objective

- Add a cube pattern to `many_cubes` suitable for benchmarking culling changes

## Solution

- Use a 'golden spiral' mapped to a sphere with the strategy of optimising for average nearest neighbour distance, as per: http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/
2022-03-08 04:39:52 +00:00
Aevyrie
b3aff9a7b1 Add docs and common helper functions to Windows (#4107)
# Objective

- Improve documentation.
- Provide helper functions for common uses of `Windows` relating to getting the primary `Window`.
- Reduce repeated `Window` code.

# Solution

- Adds infallible `primary()` and `primary_mut()` functions with standard error text. This replaces the commonly used `get_primary().unwrap()` seen throughout bevy which has inconsistent or nonexistent error messages.
- Adds `scale_factor(WindowId)` to replace repeated code blocks throughout.

# Considerations

- The added functions can panic if the primary window does not exist.
    - It is very uncommon for the primary window to not exist, as seen by the regular use of `get_primary().unwrap()`. Most users will have a single window and will need to reference the primary window in their code multiple times.
    - The panic provides a consistent error message to make this class of error easy to spot from the panic text.
    - This follows the established standard of short names for infallible-but-unlikely-to-panic functions in bevy.
- Removes line noise for common usage of `Windows`.
2022-03-08 00:46:04 +00:00
Aevyrie
2d674e7c3e Reduce power usage with configurable event loop (#3974)
# Objective

- Reduce power usage for games when not focused.
- Reduce power usage to ~0 when a desktop application is minimized (opt-in).
- Reduce power usage when focused, only updating on a `winit` event, or the user sends a redraw request. (opt-in)

https://user-images.githubusercontent.com/2632925/156904387-ec47d7de-7f06-4c6f-8aaf-1e952c1153a2.mp4

Note resource usage in the Task Manager in the above video.

## Solution

- Added a type `UpdateMode` that allows users to specify how the winit event loop is updated, without exposing winit types.
- Added two fields to `WinitConfig`, both with the `UpdateMode` type. One configures how the application updates when focused, and the other configures how the application behaves when it is not focused. Users can modify this resource manually to set the type of event loop control flow they want.
- For convenience, two functions were added to `WinitConfig`, that provide reasonable presets: `game()` (default) and `desktop_app()`.
    - The `game()` preset, which is used by default, is unchanged from current behavior with one exception: when the app is out of focus the app updates at a minimum of 10fps, or every time a winit event is received. This has a huge positive impact on power use and responsiveness on my machine, which will otherwise continue running the app at many hundreds of fps when out of focus or minimized.
    - The `desktop_app()` preset is fully reactive, only updating when user input (winit event) is supplied or a `RedrawRequest` event is sent. When the app is out of focus, it only updates on `Window` events - i.e. any winit event that directly interacts with the window. What this means in practice is that the app uses *zero* resources when minimized or not interacted with, but still updates fluidly when the app is out of focus and the user mouses over the application.
- Added a `RedrawRequest` event so users can force an update even if there are no events. This is useful in an application when you want to, say, run an animation even when the user isn't providing input.
- Added an example `low_power` to demonstrate these changes

## Usage

Configuring the event loop:
```rs
use bevy::winit::{WinitConfig};
// ...
.insert_resource(WinitConfig::desktop_app()) // preset
// or
.insert_resource(WinitConfig::game()) // preset
// or
.insert_resource(WinitConfig{ .. }) // manual
```

Requesting a redraw:
```rs
use bevy:🪟:RequestRedraw;
// ...
fn request_redraw(mut event: EventWriter<RequestRedraw>) {
    event.send(RequestRedraw);
}
```

## Other details

- Because we have a single event loop for multiple windows, every time I've mentioned "focused" above, I more precisely mean, "if at least one bevy window is focused".
- Due to a platform bug in winit (https://github.com/rust-windowing/winit/issues/1619), we can't simply use `Window::request_redraw()`. As a workaround, this PR will temporarily set the window mode to `Poll` when a redraw is requested. This is then reset to the user's `WinitConfig` setting on the next frame.
2022-03-07 23:32:05 +00:00
François
159fe527a8 Slow down the many_cubes example (#4117)
# Objective

- After #4015, the `many_cubes` example could introduce discomfort in some cases

## Solution

- Slow down the camera, add space between the cubes

https://user-images.githubusercontent.com/8672791/156898412-0fcd29b4-63b1-4e11-bf52-7ec40cb8f932.mp4
2022-03-05 22:59:54 +00:00
François
6c95b582a5 Make many_cubes example more interesting (#4015)
# Objective

- Make the many_cubes example more interesting (and look more like many_sprites)

## Solution

- Actually display many cubes
- Move the camera around
2022-03-05 13:23:04 +00:00
Carter Anderson
b6a647cc01 default() shorthand (#4071)
Adds a `default()` shorthand for `Default::default()` ... because life is too short to constantly type `Default::default()`.

```rust
use bevy::prelude::*;

#[derive(Default)]
struct Foo {
  bar: usize,
  baz: usize,
}

// Normally you would do this:
let foo = Foo {
  bar: 10,
  ..Default::default()
};

// But now you can do this:
let foo = Foo {
  bar: 10,
  ..default()
};
```

The examples have been adapted to use `..default()`. I've left internal crates as-is for now because they don't pull in the bevy prelude, and the ergonomics of each case should be considered individually.
2022-03-01 20:52:09 +00:00
François
b21c69c60e Audio control - play, pause, volume, speed, loop (#3948)
# Objective

- Add ways to control how audio is played

## Solution

- playing a sound will return a (weak) handle to an asset that can be used to control playback
- if the asset is dropped, it will detach the sink (same behaviour as now)
2022-03-01 01:12:11 +00:00
Jakob Hellermann
3ffa655cdd examples: add screenspace texture shader example (#4063)
Adds a new shader example showing how to sample a texture with screenspace coordinates, similar to the end [portal in minecraft](https://bugs.mojang.com/secure/attachment/163759/portal_frame_112.gif).

https://user-images.githubusercontent.com/22177966/156031195-33d14ed8-733f-4d9e-b1da-0fc807c994a5.mp4

I just used the already existent `models/FlightHelmet/FlightHelmet_Materials_LensesMat_OcclusionRoughMetal.png` texture but maybe we should use a dedicated texture for the example. Suggestions welcome.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-28 22:55:14 +00:00
Alex Saveau
461cf536b1 Slight perf improvements and tidy for bevymark (#3765)
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-28 01:27:38 +00:00
Alice Cecile
557ab9897a Make get_resource (and friends) infallible (#4047)
# Objective

- In the large majority of cases, users were calling `.unwrap()` immediately after `.get_resource`.
- Attempting to add more helpful error messages here resulted in endless manual boilerplate (see #3899 and the linked PRs).

## Solution

- Add an infallible variant named `.resource` and so on.
- Use these infallible variants over `.get_resource().unwrap()` across the code base.

## Notes

I did not provide equivalent methods on `WorldCell`, in favor of removing it entirely in #3939.

## Migration Guide

Infallible variants of `.get_resource` have been added that implicitly panic, rather than needing to be unwrapped.

Replace `world.get_resource::<Foo>().unwrap()` with `world.resource::<Foo>()`.

## Impact

- `.unwrap` search results before: 1084
- `.unwrap` search results after: 942
- internal `unwrap_or_else` calls added: 4
- trivial unwrap calls removed from tests and code: 146
- uses of the new `try_get_resource` API: 11
- percentage of the time the unwrapping API was used internally: 93%
2022-02-27 22:37:18 +00:00
Dusty DeWeese
81d57e129b Add capability to render to a texture (#3412)
# Objective

Will fix #3377 and #3254

## Solution

Use an enum to represent either a `WindowId` or `Handle<Image>` in place of `Camera::window`.


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-24 00:40:24 +00:00
Vladyslav Batyrenko
ba6b74ba20 Implement WorldQuery derive macro (#2713)
# Objective

- Closes #786
- Closes #2252
- Closes #2588

This PR implements a derive macro that allows users to define their queries as structs with named fields.

## Example

```rust
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct NumQuery<'w, T: Component, P: Component> {
    entity: Entity,
    u: UNumQuery<'w>,
    generic: GenericQuery<'w, T, P>,
}

#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct UNumQuery<'w> {
    u_16: &'w u16,
    u_32_opt: Option<&'w u32>,
}

#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct GenericQuery<'w, T: Component, P: Component> {
    generic: (&'w T, &'w P),
}

#[derive(WorldQuery)]
#[world_query(filter)]
struct NumQueryFilter<T: Component, P: Component> {
    _u_16: With<u16>,
    _u_32: With<u32>,
    _or: Or<(With<i16>, Changed<u16>, Added<u32>)>,
    _generic_tuple: (With<T>, With<P>),
    _without: Without<Option<u16>>,
    _tp: PhantomData<(T, P)>,
}

fn print_nums_readonly(query: Query<NumQuery<u64, i64>, NumQueryFilter<u64, i64>>) {
    for num in query.iter() {
        println!("{:#?}", num);
    }
}

#[derive(WorldQuery)]
#[world_query(mutable, derive(Debug))]
struct MutNumQuery<'w, T: Component, P: Component> {
    i_16: &'w mut i16,
    i_32_opt: Option<&'w mut i32>,
}

fn print_nums(mut query: Query<MutNumQuery, NumQueryFilter<u64, i64>>) {
    for num in query.iter_mut() {
        println!("{:#?}", num);
    }
}
```

## TODOs:
- [x] Add support for `&T` and `&mut T`
  - [x] Test
- [x] Add support for optional types
  - [x] Test
- [x] Add support for `Entity`
  - [x] Test
- [x] Add support for nested `WorldQuery`
  - [x] Test
- [x] Add support for tuples
  - [x] Test
- [x] Add support for generics
  - [x] Test
- [x] Add support for query filters
  - [x] Test
- [x] Add support for `PhantomData`
  - [x] Test
- [x] Refactor `read_world_query_field_type_info`
- [x] Properly document `readonly` attribute for nested queries and the static assertions that guarantee safety
  - [x] Test that we never implement `ReadOnlyFetch` for types that need mutable access
  - [x] Test that we insert static assertions for nested `WorldQuery` that a user marked as readonly
2022-02-24 00:19:49 +00:00
Carter Anderson
e369a8ad51 Mesh vertex buffer layouts (#3959)
This PR makes a number of changes to how meshes and vertex attributes are handled, which the goal of enabling easy and flexible custom vertex attributes:
* Reworks the `Mesh` type to use the newly added `VertexAttribute` internally
  * `VertexAttribute` defines the name, a unique `VertexAttributeId`, and a `VertexFormat`
  *  `VertexAttributeId` is used to produce consistent sort orders for vertex buffer generation, replacing the more expensive and often surprising "name based sorting"  
  * Meshes can be used to generate a `MeshVertexBufferLayout`, which defines the layout of the gpu buffer produced by the mesh. `MeshVertexBufferLayouts` can then be used to generate actual `VertexBufferLayouts` according to the requirements of a specific pipeline. This decoupling of "mesh layout" vs "pipeline vertex buffer layout" is what enables custom attributes. We don't need to standardize _mesh layouts_ or contort meshes to meet the needs of a specific pipeline. As long as the mesh has what the pipeline needs, it will work transparently. 
* Mesh-based pipelines now specialize on `&MeshVertexBufferLayout` via the new `SpecializedMeshPipeline` trait (which behaves like `SpecializedPipeline`, but adds `&MeshVertexBufferLayout`). The integrity of the pipeline cache is maintained because the `MeshVertexBufferLayout` is treated as part of the key (which is fully abstracted from implementers of the trait ... no need to add any additional info to the specialization key).    
* Hashing `MeshVertexBufferLayout` is too expensive to do for every entity, every frame. To make this scalable, I added a generalized "pre-hashing" solution to `bevy_utils`: `Hashed<T>` keys and `PreHashMap<K, V>` (which uses `Hashed<T>` internally) . Why didn't I just do the quick and dirty in-place "pre-compute hash and use that u64 as a key in a hashmap" that we've done in the past? Because its wrong! Hashes by themselves aren't enough because two different values can produce the same hash. Re-hashing a hash is even worse! I decided to build a generalized solution because this pattern has come up in the past and we've chosen to do the wrong thing. Now we can do the right thing! This did unfortunately require pulling in `hashbrown` and using that in `bevy_utils`, because avoiding re-hashes requires the `raw_entry_mut` api, which isn't stabilized yet (and may never be ... `entry_ref` has favor now, but also isn't available yet). If std's HashMap ever provides the tools we need, we can move back to that. Note that adding `hashbrown` doesn't increase our dependency count because it was already in our tree. I will probably break these changes out into their own PR.
* Specializing on `MeshVertexBufferLayout` has one non-obvious behavior: it can produce identical pipelines for two different MeshVertexBufferLayouts. To optimize the number of active pipelines / reduce re-binds while drawing, I de-duplicate pipelines post-specialization using the final `VertexBufferLayout` as the key.  For example, consider a pipeline that needs the layout `(position, normal)` and is specialized using two meshes: `(position, normal, uv)` and `(position, normal, other_vec2)`. If both of these meshes result in `(position, normal)` specializations, we can use the same pipeline! Now we do. Cool!

To briefly illustrate, this is what the relevant section of `MeshPipeline`'s specialization code looks like now:

```rust
impl SpecializedMeshPipeline for MeshPipeline {
    type Key = MeshPipelineKey;

    fn specialize(
        &self,
        key: Self::Key,
        layout: &MeshVertexBufferLayout,
    ) -> RenderPipelineDescriptor {
        let mut vertex_attributes = vec![
            Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
            Mesh::ATTRIBUTE_NORMAL.at_shader_location(1),
            Mesh::ATTRIBUTE_UV_0.at_shader_location(2),
        ];

        let mut shader_defs = Vec::new();
        if layout.contains(Mesh::ATTRIBUTE_TANGENT) {
            shader_defs.push(String::from("VERTEX_TANGENTS"));
            vertex_attributes.push(Mesh::ATTRIBUTE_TANGENT.at_shader_location(3));
        }

        let vertex_buffer_layout = layout
            .get_layout(&vertex_attributes)
            .expect("Mesh is missing a vertex attribute");
```

Notice that this is _much_ simpler than it was before. And now any mesh with any layout can be used with this pipeline, provided it has vertex postions, normals, and uvs. We even got to remove `HAS_TANGENTS` from MeshPipelineKey and `has_tangents` from `GpuMesh`, because that information is redundant with `MeshVertexBufferLayout`.

This is still a draft because I still need to:

* Add more docs
* Experiment with adding error handling to mesh pipeline specialization (which would print errors at runtime when a mesh is missing a vertex attribute required by a pipeline). If it doesn't tank perf, we'll keep it.
* Consider breaking out the PreHash / hashbrown changes into a separate PR.
* Add an example illustrating this change
* Verify that the "mesh-specialized pipeline de-duplication code" works properly

Please dont yell at me for not doing these things yet :) Just trying to get this in peoples' hands asap.

Alternative to #3120
Fixes #3030


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-23 23:21:13 +00:00
Robert Swain
936468aa1e bevy_render: Use RenderDevice to get limits/features and expose AdapterInfo (#3931)
# Objective

- `WgpuOptions` is mutated to be updated with the actual device limits and features, but this information is readily available to both the main and render worlds through the `RenderDevice` which has .limits() and .features() methods
- Information about the adapter in terms of its name, the backend in use, etc were not being exposed but have clear use cases for being used to take decisions about what rendering code to use. For example, if something works well on AMD GPUs but poorly on Intel GPUs. Or perhaps something works well in Vulkan but poorly in DX12.

## Solution

- Stop mutating `WgpuOptions `and don't insert the updated values into the main and render worlds
- Return `AdapterInfo` from `initialize_renderer` and insert it into the main and render worlds
- Use `RenderDevice` limits in the lighting code that was using `WgpuOptions.limits`.
- Renamed `WgpuOptions` to `WgpuSettings`
2022-02-16 21:17:37 +00:00
RedlineTriad
5104397683 Alien cake addict: Allow holding movement keys (#2072)
I wanted to try one of the new examples but it felt so clunky that I wanted to improve it.

It did make me feel like maybe some input axes abstraction like Unity has might be useful.

Also, eating cake should probably be a separate system from movement.
2022-02-15 22:14:58 +00:00
danieleades
d8974e7c3d small and mostly pointless refactoring (#2934)
What is says on the tin.

This has got more to do with making `clippy` slightly more *quiet* than it does with changing anything that might greatly impact readability or performance.

that said, deriving `Default` for a couple of structs is a nice easy win
2022-02-13 22:33:55 +00:00
Jakob Hellermann
d305e4f026 only use unique type UUIDs (#3579)
Out of curiosity I ran `rg -F -I '#[uuid = "' | sort` to see if there were any duplicate UUIDs, and they were. Now there aren't any.
2022-02-12 19:58:02 +00:00
B-Janson
38f6da5a85 Add generic systems example (#2636)
# Objective
My attempt at fixing #2142. My very first attempt at contributing to Bevy so more than open to any feedback.
I borrowed heavily from the [Bevy Cheatbook page](https://bevy-cheatbook.github.io/patterns/generic-systems.html?highlight=generic#generic-systems).

## Solution
Fairly straightforward example using a clean up system to delete entities that are coupled with app state after exiting that state.


Co-authored-by: B-Janson <brandon@canva.com>
2022-02-08 16:24:46 +00:00
Daniel McNab
6615b7bf64 Deprecate .system (#3302)
# Objective

- Using `.system()` is no longer idiomatic.

## Solution

- Give a warning when using it
2022-02-08 04:00:58 +00:00
MinerSebas
59ee512292 Add TransformBundle (#3054)
# Objective

- Bevy currently has no simple way to make an "empty" Entity work correctly in a Hierachy.
  - The current Solution is to insert a Tuple instead: 

```rs
.insert_bundle((Transform::default(), GlobalTransform::default()))
```

## Solution

* Add a `TransformBundle` that combines the Components:

```rs
.insert_bundle(TransformBundle::default())
```

* The code is based on #2331, except for missing the more controversial usage of `TransformBundle` as a Sub-bundle in preexisting Bundles.

Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-06 01:07:55 +00:00
François
385a2b1895 add examples on how to have a data source running in another thread / in a task pool thread (#2915)
Add two examples on how to communicate with a task that is running either in another thread or in a thread from `AsyncComputeTaskPool`.

Loosely based on https://github.com/bevyengine/bevy/discussions/1150
2022-02-05 01:52:47 +00:00
aloucks
1477765f62 Replace VSync with PresentMode (#3812)
# Objective

Enable the user to specify any presentation modes (including `Mailbox`).

Fixes #3807

## Solution

I've added a new `PresentMode` enum in `bevy_window` that mirrors the `wgpu` enum 1:1. Alternatively, I could add a new dependency on `wgpu-types` if that would be preferred.
2022-02-04 03:37:44 +00:00
Gwen
b11ee3ffb8 Remove duplicate call to set_vertex_buffer(0, ...) in shader_instancing example (#3738)
## Objective

The [`DrawMeshInstanced`] command in the example sets vertex buffer 0 twice, with two identical calls to:

```rs
pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
```

## Solution

Remove the second call as it is unecessary.

[`DrawMeshInstanced`]: f3de12bc5e/examples/shader/shader_instancing.rs (L217-L258)
2022-02-04 03:37:40 +00:00
Robert Swain
e928acb9ff bevy_asset: Add AssetServerSettings watch_for_changes member (#3643)
# Objective

- `asset_server.watch_for_changes().unwrap()` only watches changes for assets loaded **_after_** that call.
- Technically, the `hot_asset_reloading` example is racey as the watch on the asset path is set up in an async task scheduled from the asset `load()`, but the filesystem watcher is only constructed in a call that comes **_after_** the call to `load()`.

## Solution

-  It feels safest to allow enabling watching the filesystem for changes on the asset server from the point of its construction. Therefore, adding such an option to `AssetServerSettings` seemed to be the correct solution.
- Fix `hot_asset_reloading` by inserting the `AssetServerSettings` resource with `watch_for_changes: true` instead of calling `asset_server.watch_for_changes().unwrap()`.
- Document the shortcomings of `.watch_for_changes()`
2022-02-04 03:21:29 +00:00
Charles
7d712406fe Simplify sending empty events (#2935)
# Objective

When using empty events, it can feel redundant to have to specify the type of the event when sending it.

## Solution

Add a new `fire()` function that sends the default value of the event. This requires that the event derives Default.


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-04 01:24:47 +00:00
Daniel McNab
6f111136b9 Cleanup some things which shouldn't be components (#2982)
# Objective

- Using `Stopwatch` and `Timer` as raw components is a footgun.

## Solution

- Stop them from being components
2022-02-03 23:56:57 +00:00
jak6jak
f991c73bdf Add move sprite example. (#2414)
## Objective
There is no bevy example that shows how to transform a sprite. At least as its singular purpose. This creates an example of how to use transform.translate to move a sprite up and down. The last pull request had issues that I couldn't fix so I created a new one

### Solution
I created move_sprite example.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-02 02:44:51 +00:00
Horváth Bálint
c285a69f76 Add the Inside version to the Collision enum (#2489)
# Objective
I think the 'collide' function inside the 'bevy/crates/bevy_sprite/src/collide_aabb.rs' file should return 'Some' if the two rectangles are fully overlapping or one is inside the other. This can happen on low-end machines when a lot of time passes between two frames because of a stutter, so a bullet for example gets inside its target. I can also think of situations where this is a valid use case even without stutters. 

## Solution
I added an 'Inside' version to the Collision enum declared in the file. And I use it, when the two rectangles are overlapping, but we can't say from which direction it happened. I gave a 'penetration depth' of minus Infinity to these cases, so that this variant only appears, when the two rectangles overlap from each side fully. I am not sure if this is the right thing to do.

Fixes #1980

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-02-01 22:40:25 +00:00
Charles Giguere
435fb7af4f Improve shader_material example documentation (#3601)
# Objective

While trying to learn how to use custom shaders, I had difficulty figuring out how to use a vertex shader. My confusion was mostly because all the other shader examples used a custom pipeline, but I didn't want a custom pipeline. After digging around I realised that I simply needed to add a function to the `impl Material` block. I also searched what was the default shader used, because it wasn't obvious to me where to find it.

## Solution

Added a few comments explaining what is going on in the example and a link to the default shader.
2022-01-26 18:52:54 +00:00
Cameron Hart
ac63c491fb Simple 2d rotation example (#3065)
# Objective

Some new bevy users are unfamiliar with quaternions and have trouble working with rotations in 2D.

There has been an [issue](https://github.com/bitshifter/glam-rs/issues/226) raised with glam to add helpers to better support these users, however for now I feel could be better to provide examples of how to do this in Bevy as a starting point for new users.

## Solution

I've added a 2d_rotation example which demonstrates 3 different rotation examples to try help get people started:

- Rotating and translating a player ship based on keyboard input
- An enemy ship type that rotates to face the player ship immediately
- An enemy ship type that rotates to face the player at a fixed angular velocity

I also have a standalone version of this example here https://github.com/bitshifter/bevy-2d-rotation-example but I think it would be more discoverable if it's included with Bevy.
2022-01-25 22:10:11 +00:00
luke.biel
6d76229c38 Fix a typo in shader_defs example (#3762)
# Objective

As in title, I'm already looking through these files so may as well rename `pipline` to `pipeline`
2022-01-24 23:44:08 +00:00
Robert Swain
55da315432 bevy_render: Provide a way to opt-out of the built-in frustum culling (#3711)
# Objective

- Allow opting-out of the built-in frustum culling for cases where its behaviour would be incorrect
- Make use of the this in the shader_instancing example that uses a custom instancing method. The built-in frustum culling breaks the custom instancing in the shader_instancing example if the camera is moved to:

```rust
    commands.spawn_bundle(PerspectiveCameraBundle {
        transform: Transform::from_xyz(12.0, 0.0, 15.0)
            .looking_at(Vec3::new(12.0, 0.0, 0.0), Vec3::Y),
        ..Default::default()
    });
```

...such that the Aabb of the cube Mesh that is at the origin goes completely out of view. This incorrectly (for the purpose of the custom instancing) culls the `Mesh` and so culls all instances even though some may be visible.


## Solution

- Add a `NoFrustumCulling` marker component
- Do not compute and add an `Aabb` to `Mesh` entities without an `Aabb` if they have a `NoFrustumCulling` marker component
- Do not apply frustum culling to entities with the `NoFrustumCulling` marker component
2022-01-17 22:55:44 +00:00
François
e88e394feb Remove wasm specific examples (#3705)
# Objective

- There are wasm specific examples, which is misleading as now it works by default
- I saw a few people on discord trying to work through those examples that are very limited

## Solution

- Remove them and update the instructions
2022-01-17 22:38:05 +00:00
Igor Shaposhnik
a3e43b6abe Remove cargo-lipo from iOS ci job (#3671)
# Objective

`cargo-lipo` no more required since #3109 merged. Also remove unused `x11` feature from example.
2022-01-17 21:43:44 +00:00
Aleksey Smirnov
758fc5af67 Remove a couple of unnecessary full paths (#3699) 2022-01-16 20:49:40 +00:00
François
3e8e6c5671 add an example using UI & states to create a game menu (#2960)
adds an example using UI for something more related to a game than the current UI examples.

Example with a game menu:
* new game - will display settings for 5 seconds before returning to menu
* preferences - can modify the settings, with two sub menus
* quit - will quit the game


I wanted a more complex UI example before starting the UI rewrite to have ground for comparison

Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
2022-01-14 19:09:42 +00:00
Daniel Bearden
8c81e81676 Thread local example cleanup (#3586)
# Objective

Fixes #1917

## Solution

- Change use of "thread local system" wording to "exclusive system".
- Add .exclusive_system() call to example.
2022-01-08 22:36:33 +00:00
Hennadii Chernyshchyk
458cb7a9e9 Add headless mode (#3439)
# Objective

In this PR I added the ability to opt-out graphical backends. Closes #3155.

## Solution

I turned backends into `Option` ~~and removed panicking sub app API to force users handle the error (was suggested by `@cart`)~~.
2022-01-08 10:39:43 +00:00
davier
c2da7800e3 Add 2d meshes and materials (#3460)
# Objective

The current 2d rendering is specialized to render sprites, we need a generic way to render 2d items, using meshes and materials like we have for 3d.

## Solution

I cloned a good part of `bevy_pbr` into `bevy_sprite/src/mesh2d`, removed lighting and pbr itself, adapted it to 2d rendering, added a `ColorMaterial`, and modified the sprite rendering to break batches around 2d meshes.

~~The PR is a bit crude; I tried to change as little as I could in both the parts copied from 3d and the current sprite rendering to make reviewing easier. In the future, I expect we could make the sprite rendering a normal 2d material, cleanly integrated with the rest.~~ _edit: see <https://github.com/bevyengine/bevy/pull/3460#issuecomment-1003605194>_

## Remaining work

- ~~don't require mesh normals~~ _out of scope_
- ~~add an example~~ _done_
- support 2d meshes & materials in the UI?
- bikeshed names (I didn't think hard about naming, please check if it's fine)

## Remaining questions

- ~~should we add a depth buffer to 2d now that there are 2d meshes?~~ _let's revisit that when we have an opaque render phase_
- ~~should we add MSAA support to the sprites, or remove it from the 2d meshes?~~ _I added MSAA to sprites since it's really needed for 2d meshes_
- ~~how to customize vertex attributes?~~ _#3120_



Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-01-08 01:29:08 +00:00
Niklas Eicker
fbab01a40d Add missing closing ticks for inline examples and some cleanup (#3573)
# Objective

- clean up documentation and inline examples

## Solution

- add missing closing "```"
- remove stray "```"
- remove whitespace in inline examples
- unify inline examples (remove some `rust` labels)
2022-01-07 09:25:12 +00:00
Daniel Bearden
b673c51e20 Bevy app docs (#3539)
# Objective

Achieve 100% documentation coverage for bevy_app crate.
See #3492 

## Solution

- Add #![warn(missing_docs)] to crate root
- Add doc comments to public items
- Add doc comment to bevy_utils::define_label macro trait
2022-01-06 23:16:47 +00:00
Daniel McNab
44f370a26c Make the iter_combinators examples more pretty (#3075)
# Objective

- More colours

## Solution

- Various changes
- Would have a video here, but don't have an easy way to record one before I go to sleep
- I intend to additionally change the distribution of the satellites, to be more uniform in space.
2022-01-06 19:13:52 +00:00
Jakob Hellermann
b1476015d9 add some more pipelined-rendering shader examples (#3041)
based on #3031 

Adds some examples showing of how to use the new pipelined rendering for custom shaders.

- a minimal shader example which doesn't use render assets
- the same but using glsl
- an example showing how to render instanced data
- a shader which uses the seconds since startup to animate some textures


Instancing shader:
![grafik](https://user-images.githubusercontent.com/22177966/139299294-e176b62a-53d1-4287-9a66-02fb55affc02.png)
Animated shader:
![animate_shader](https://user-images.githubusercontent.com/22177966/139299718-2940c0f3-8480-4ee0-98d7-b6ba40dc1472.gif)
(the gif makes it look a bit ugly)

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-01-05 19:43:11 +00:00
Carter Anderson
1d0d8a3397 Spherical area lights example (#3498)
I was putting together the Bevy 0.6 release blog post and wanted a simple area light radius example, so here we are :)

![image](https://user-images.githubusercontent.com/2694663/147786883-63454290-b5b1-4456-9762-0b0b47e16bb5.png)
2021-12-30 21:07:26 +00:00
Michael Dorst
e6bce74220 Fix doc_markdown lints in examples (#3486)
#3457 adds the `doc_markdown` clippy lint, which checks doc comments to make sure code identifiers are escaped with backticks. This causes a lot of lint errors, so this is one of a number of PR's that will fix those lint errors one crate at a time.

This PR fixes lints in the `examples` folder.
2021-12-29 17:25:34 +00:00
Carter Anderson
963e2f08a2 Materials and MaterialPlugin (#3428)
This adds "high level" `Material` and `SpecializedMaterial` traits, which can be used with a `MaterialPlugin<T: SpecializedMaterial>`. `MaterialPlugin` automatically registers the appropriate resources, draw functions, and queue systems. The `Material` trait is simpler, and should cover most use cases. `SpecializedMaterial` is like `Material`, but it also requires defining a "specialization key" (see #3031). `Material` has a trivial blanket impl of `SpecializedMaterial`, which allows us to use the same types + functions for both.

This makes defining custom 3d materials much simpler (see the `shader_material` example diff) and ensures consistent behavior across all 3d materials (both built in and custom). I ported the built in `StandardMaterial` to `MaterialPlugin`. There is also a new `MaterialMeshBundle<T: SpecializedMaterial>`, which `PbrBundle` aliases to.
2021-12-25 21:45:43 +00:00
Jakob Hellermann
adb3ad399c make sub_app return an &App and add sub_app_mut() -> &mut App (#3309)
It's sometimes useful to have a reference to an app a sub app at the same time, which is only possible with an immutable reference.
2021-12-24 06:57:30 +00:00
François
79d36e7c28 Prepare crevice for vendored release (#3394)
# Objective

- Our crevice is still called "crevice", which we can't use for a release
- Users would need to use our "crevice" directly to be able to use the derive macro

## Solution

- Rename crevice to bevy_crevice, and crevice-derive to bevy-crevice-derive
- Re-export it from bevy_render, and use it from bevy_render everywhere
- Fix derive macro to work either from bevy_render, from bevy_crevice, or from bevy

## Remaining

- It is currently re-exported as `bevy::render::bevy_crevice`, is it the path we want?
- After a brief suggestion to Cart, I changed the version to follow Bevy version instead of crevice, do we want that?
- Crevice README.md need to be updated
- in the `Cargo.toml`, there are a few things to change. How do we want to change them? How do we keep attributions to original Crevice?
```
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
documentation = "https://docs.rs/crevice"
homepage = "https://github.com/LPGhatguy/crevice"
repository = "https://github.com/LPGhatguy/crevice"
```


Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-12-23 22:49:12 +00:00
François
aeba9faf04 use ogg by default instead of mp3 (#3421)
# Objective

- mp3 feature of rodio has dependencies that are not maintained with security issues
- mp3 feature of rodio doesn't build in wasm
- mp3 feature of rodio uses internal memory allocation that cause rejection from Apple appstore

## Solution

- Use vorbis instead of mp3 by default


Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
2021-12-23 19:19:15 +00:00
Alice Cecile
b5d7ff2d75 Do not panic on failed setting of GameOver state in AlienCakeAddict (#3411)
# Objective

- Tentatively fixes #2525.

## Solution

- The panic seems to occur when the game-over state occurs nearly instantly.
- Discard the `Result`, rather than panicking. We could probably handle this better, but I want to see if this works first. Ping @qarmin.
2021-12-22 00:49:15 +00:00
MrGVSV
5479047aa2 Added set_cursor_icon(...) to Window (#3395)
# Objective

The window's cursor should be settable without having to implement a custom cursor icon solution. This will especially be helpful when creating user-interfaces that might like to use the cursor to denote some meaning (e.g., _clickable_, _resizable_, etc.).

## Solution

Added a `CursorIcon` enum that maps one-to-one to winit's `CursorIcon` enum, as well as a method to set/get it for the given `Window`.
2021-12-20 22:04:45 +00:00
davier
c79ec9cad6 Fix custom mesh pipelines (#3381)
# Objective

Fixes #3379 

## Solution

The custom mesh pipelines needed to be specialized on each mesh's primitive topology, as done in `queue_meshes()`

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-12-20 20:33:39 +00:00
研究社交
46c1480f42 Fix hierarchy example panic (#3378)
# Objective
Fixes #3321 

## Solution
Uses `despawn_recursive()` instead of `despawn()` when removing children.
2021-12-20 20:33:38 +00:00
davier
340957994d Implement the Overflow::Hidden style property for UI (#3296)
# Objective

This PR implements the `overflow` style property in `bevy_ui`. When set to `Overflow::Hidden`, the children of that node are clipped so that overflowing parts are not rendered. This is an important building block for UI widgets.

## Solution

Clipping is done on the CPU so that it does not break batching.

The clip regions update was implemented as a separate system for clarity, but it could be merged with the other UI systems to avoid doing an additional tree traversal. (I don't think it's important until we fix the layout performance issues though).

A scrolling list was added to the `ui_pipelined` example to showcase `Overflow::Hidden`. For the sake of simplicity, it can only be scrolled with a mouse.
2021-12-19 05:44:28 +00:00
François
6eb8e15e3d Improved bevymark: no bouncing offscreen and spawn waves from CLI (#3364)
# Objective

- In bevymark, bevies were very bouncy and could go off screen after a while, skewing the FPS

https://user-images.githubusercontent.com/8672791/146540848-282fa11b-d058-4da9-8e95-688ae67d9406.mp4

## Solution

- Make bevies bounce also on top of the screen
- I also changed how the examples read args from CLI to be able to spawn waves: `cargo run --example bevymark --release -- 5 100` (first is number of bevy per wave, second is number of wave, with one wave every 0.2 seconds). This makes it easier to reproduce some exact situations

https://user-images.githubusercontent.com/8672791/146542857-2f953fa0-7b8d-4772-93f8-b8d7a31259dc.mp4




Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
2021-12-18 20:13:59 +00:00
Daniel McNab
ed9d45fae5 Add an example 'showcasing' using multiple windows (#3367)
# Objective

- The multiple windows example which was viciously murdered in #3175.
- cart asked me to

## Solution

- Rework the example to work on pipelined-rendering, based on the work from #2898
2021-12-18 19:38:05 +00:00
r00ster
11f52b8c72 Add an example to draw a rectangle (#2957)
# Objective

Every time I come back to Bevy I face the same issue: how do I draw a rectangle again? How did that work? So I go to https://github.com/bevyengine/bevy/tree/main/examples in the hope of finding literally the simplest possible example that draws something on the screen without any dependency such as an image. I don't want to have to add some image first, I just quickly want to get something on the screen with `main.rs` alone so that I can continue building on from that point on. Such an example is particularly helpful for a quick start for smaller projects that don't even need any assets such as images (this is my case currently).

Currently every single example of https://github.com/bevyengine/bevy/tree/main/examples#2d-rendering (which is the first section after hello world that beginners will look for for very minimalistic and quick examples) depends on at least an asset or is too complex. This PR solves this.
It also serves as a great comparison for a beginner to realize what Bevy is really like and how different it is from what they may expect Bevy to be. For example for someone coming from [LÖVE](https://love2d.org/), they will have something like this in their head when they think of drawing a rectangle:
```lua
function love.draw()
    love.graphics.setColor(0.25, 0.25, 0.75);
    love.graphics.rectangle("fill", 0, 0, 50, 50);
end
```
This, of course, differs quite a lot from what you do in Bevy. I imagine there will be people that just want to see something as simple as this in comparison to have a better understanding for the amount of differences.

## Solution

Add a dead simple example drawing a blue 50x50 rectangle in the center with no more and no less than needed.
2021-12-18 00:52:37 +00:00
Tobenaii
d3749a98f8 Use updated window size in bevymark example (#3335)
# Objective

Have the bird spawning/collision systems in bevymark use the proper window size, instead of the size set in WindowDescriptor which isn't updated when the window is resized.

## Solution

Use the Windows resource to grab the width/height from the primary window. This is consistent with the other examples.
2021-12-18 00:29:36 +00:00
Hennadii Chernyshchyk
70c9165886 Fix crash with disabled winit (#3330)
# Objective

This PR fixes a crash when winit is enabled when there is a camera in the world. Part of #3155

## Solution

In this PR, I removed two unwraps and added an example for regression testing.
2021-12-15 00:15:47 +00:00
Carter Anderson
ffecb05a0a Replace old renderer with new renderer (#3312)
This makes the [New Bevy Renderer](#2535) the default (and only) renderer. The new renderer isn't _quite_ ready for the final release yet, but I want as many people as possible to start testing it so we can identify bugs and address feedback prior to release.

The examples are all ported over and operational with a few exceptions:

* I removed a good portion of the examples in the `shader` folder. We still have some work to do in order to make these examples possible / ergonomic / worthwhile: #3120 and "high level shader material plugins" are the big ones. This is a temporary measure.
* Temporarily removed the multiple_windows example: doing this properly in the new renderer will require the upcoming "render targets" changes. Same goes for the render_to_texture example.
* Removed z_sort_debug: entity visibility sort info is no longer available in app logic. we could do this on the "render app" side, but i dont consider it a priority.
2021-12-14 03:58:23 +00:00
davier
25b62f9577 Port bevy_ui to pipelined-rendering (#2653)
# Objective

Port bevy_ui to pipelined-rendering (see #2535 )

## Solution

I did some changes during the port:
- [X] separate color from the texture asset (as suggested [here](https://discord.com/channels/691052431525675048/743663924229963868/874353914525413406))
- [X] ~give the vertex shader a per-instance buffer instead of per-vertex buffer~ (incompatible with batching)

Remaining features to implement to reach parity with the old renderer:
- [x] textures
- [X] TextBundle

I'd also like to add these features, but they need some design discussion:
- [x] batching
- [ ] separate opaque and transparent phases
- [ ] multiple windows
- [ ] texture atlases
- [ ] (maybe) clipping
2021-12-10 22:21:23 +00:00
loui
3ca8844c90 Added transparency to window builder (#3105)
Applogies, had to recreate this pr because of branching issue.
Old PR: https://github.com/bevyengine/bevy/pull/3033

# Objective

Fixes #3032

Allowing a user to create a transparent window 

## Solution

I've allowed the transparent bool to be passed to the winit window builder
2021-12-08 20:53:35 +00:00
Rostyslav Toch
01e2141ce3 Add Gamepads resource (#3257)
# Objective

Fixes #3245 

## Solution

- Move GamepadLobby to lib
- Add connection_system to InputPlugin
- Updated gamepad_input example


Co-authored-by: CrazyRoka <rokarostuk@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-12-08 20:28:08 +00:00
Rostyslav Toch
ca80fe65ed Improve contributors example quality (#3258)
# Objective

Fixes #3181

## Solution

Refactored `contributors.rs` example:
- Renamed unclear variables
- Split setup system into two separate systems 


Co-authored-by: CrazyRoka <rokarostuk@gmail.com>
2021-12-08 20:09:53 +00:00
François
ccee658436 Fix iOS CI on Intel (for real this time) (#3232)
# Objective

- iOS CI has linker issues https://github.com/bevyengine/bevy/runs/4388921574?check_suite_focus=true

## Solution

- Building for iOS actually requires ~~both iOS SDK for target and~~ macOS SDK for build scripts. ~~I added them both when needed~~ I replaced the iOS SDK with the maOS. This was not an issue on m1 as they are compatible enough to make the build pass.
- This completely confused `shader-sys` which fails to build in this configuration. Luckily as the example now uses the new renderer, I was able to remove the old renderer and depend no more on this lib.

This is confirmed to work:
- on intel mac with simulator
- on m1 mac with simulator
- on m1 mac with real iphone
2021-12-02 07:44:40 +00:00
François
2def9027d7 Fix iOS CI (#3228)
# Objective

- With #3109 I broke iOS CI: https://github.com/bevyengine/bevy/runs/4374891646?check_suite_focus=true

## Solution

- Fix indentation in makefile
- Adds scheme that is now needed

With this, `make install` works on my m1 Mac but still fails on my intel Mac unless I run something like `make install; cargo build --target x86_64-apple-ios; make install; cargo build --target x86_64-apple-ios; make install`. It seems something is off when executing cargo through `xcodebuild` on my setup but not sure what. So this PR will probably not fix iOS CI 😞
2021-12-01 21:44:29 +00:00
François
d59a3ddd61 iOS: replace cargo-lipo, and update for new macOS (#3109)
# Objective

- Remove `cargo-lipo` as [it's deprecated](https://github.com/TimNN/cargo-lipo#maintenance-status) and doesn't work on new Apple processors
- Fix CI that will fail as soon as GitHub update the worker used by Bevy to macOS 11

## Solution

- Replace `cargo-lipo` with building with the correct target
- Setup the correct path to libraries by using `xcrun --show-sdk-path`
- Also try and fix path to cmake in case it's not found but available through homebrew
2021-11-29 23:25:22 +00:00
François
eb15f81e17 enable alpha mode for textures materials that are transparent (#3202)
# Objective

- Transparent materials used in 3d are not transparent by default

## Solution

- Enable transparency in example
2021-11-29 21:22:53 +00:00
François
3de391be21 fix calls to as_rgba_linear (#3200)
# Objective

- After #3192, some places where `as_rgba_linear` was called were doing too many conversions

## Solution

- Fix the conversions
2021-11-28 10:40:42 +00:00
François
e8412df021 add shadows in examples (#3201)
# Objective

- As mentioned in #3126, shadows need to be readded in examples

## Solution

- Add shadows in examples
2021-11-27 10:12:47 +00:00
François
7ced541cb2 increase light intensity in pbr_pipelined example (#3182)
# Objective

- example `pbr_pipelined` doesn't look like example `pbr`

`pbr`:
![pbr](https://user-images.githubusercontent.com/8672791/143328022-83797197-233c-4824-8daa-4d7bd092938d.png)


`pbr_pipelined`:
![pbr_pipelined](https://user-images.githubusercontent.com/8672791/143328034-8a8bdb39-0d75-472b-8880-7bb7cd48f448.png)


## Solution

- set the light intensity to a higher value

`pbr_pipelined` with this pr:
![pbr_pipelined_fixed](https://user-images.githubusercontent.com/8672791/143328040-4149e96c-dada-4940-9f6f-f8925e48b22e.png)
2021-11-27 10:12:45 +00:00
Carter Anderson
8009af3879 Merge New Renderer 2021-11-22 23:57:42 -08:00
Carter Anderson
2e79951659 Shader Imports. Decouple Mesh logic from PBR (#3137)
## Shader Imports

This adds "whole file" shader imports. These come in two flavors:

### Asset Path Imports

```rust
// /assets/shaders/custom.wgsl

#import "shaders/custom_material.wgsl"

[[stage(fragment)]]
fn fragment() -> [[location(0)]] vec4<f32> {
    return get_color();
}
```

```rust
// /assets/shaders/custom_material.wgsl

[[block]]
struct CustomMaterial {
    color: vec4<f32>;
};
[[group(1), binding(0)]]
var<uniform> material: CustomMaterial;
```

### Custom Path Imports

Enables defining custom import paths. These are intended to be used by crates to export shader functionality:

```rust
// bevy_pbr2/src/render/pbr.wgsl

#import bevy_pbr::mesh_view_bind_group
#import bevy_pbr::mesh_bind_group

[[block]]
struct StandardMaterial {
    base_color: vec4<f32>;
    emissive: vec4<f32>;
    perceptual_roughness: f32;
    metallic: f32;
    reflectance: f32;
    flags: u32;
};

/* rest of PBR fragment shader here */
```

```rust
impl Plugin for MeshRenderPlugin {
    fn build(&self, app: &mut bevy_app::App) {
        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
        shaders.set_untracked(
            MESH_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_bind_group"),
        );
        shaders.set_untracked(
            MESH_VIEW_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_view_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_view_bind_group"),
        );
```

By convention these should use rust-style module paths that start with the crate name. Ultimately we might enforce this convention.

Note that this feature implements _run time_ import resolution. Ultimately we should move the import logic into an asset preprocessor once Bevy gets support for that.

## Decouple Mesh Logic from PBR Logic via MeshRenderPlugin

This breaks out mesh rendering code from PBR material code, which improves the legibility of the code, decouples mesh logic from PBR logic, and opens the door for a future `MaterialPlugin<T: Material>` that handles all of the pipeline setup for arbitrary shader materials.

## Removed `RenderAsset<Shader>` in favor of extracting shaders into RenderPipelineCache

This simplifies the shader import implementation and removes the need to pass around `RenderAssets<Shader>`.

##  RenderCommands are now fallible

This allows us to cleanly handle pipelines+shaders not being ready yet. We can abort a render command early in these cases, preventing bevy from trying to bind group / do draw calls for pipelines that couldn't be bound. This could also be used in the future for things like "components not existing on entities yet". 

# Next Steps

* Investigate using Naga for "partial typed imports" (ex: `#import bevy_pbr::material::StandardMaterial`, which would import only the StandardMaterial struct)
* Implement `MaterialPlugin<T: Material>` for low-boilerplate custom material shaders
* Move shader import logic into the asset preprocessor once bevy gets support for that.

Fixes #3132
2021-11-18 03:45:02 +00:00
Niklas Eicker
94db0176fe Add readme to errors crate and clean up cargo files (#3125)
# Objective

- Document that the error codes will be rendered on the bevy website (see bevyengine/bevy-website#216)
- Some Cargo.toml files did not include the license or a description field

## Solution

- Readme for the errors crate
- Mark internal/development crates with `publish = false`
- Add missing license/descriptions to some crates

- [x] merge bevyengine/bevy-website#216
2021-11-13 23:06:48 +00:00
Carter Anderson
9a4cc42b38 EntityRenderCommand and PhaseItemRenderCommand (#3111)
Adds new `EntityRenderCommand`, `EntityPhaseItem`, and `CachedPipelinePhaseItem` traits to make it possible to reuse RenderCommands across phases. This should be helpful for features like #3072 . It also makes the trait impls slightly less generic-ey in the common cases.

This also fixes the custom shader examples to account for the recent Frustum Culling and MSAA changes (the UX for these things will be improved later).
2021-11-12 22:27:17 +00:00
Carter Anderson
85487707ef Sprite Batching (#3060)
This implements the following:

* **Sprite Batching**: Collects sprites in a vertex buffer to draw many sprites with a single draw call. Sprites are batched by their `Handle<Image>` within a specific z-level. When possible, sprites are opportunistically batched _across_ z-levels (when no sprites with a different texture exist between two sprites with the same texture on different z levels). With these changes, I can now get ~130,000 sprites at 60fps on the `bevymark_pipelined` example.
* **Sprite Color Tints**: The `Sprite` type now has a `color` field. Non-white color tints result in a specialized render pipeline that passes the color in as a vertex attribute. I chose to specialize this because passing vertex colors has a measurable price (without colors I get ~130,000 sprites on bevymark, with colors I get ~100,000 sprites). "Colored" sprites cannot be batched with "uncolored" sprites, but I think this is fine because the chance of a "colored" sprite needing to batch with other "colored" sprites is generally probably way higher than an "uncolored" sprite needing to batch with a "colored" sprite.
* **Sprite Flipping**: Sprites can be flipped on their x or y axis using `Sprite::flip_x` and `Sprite::flip_y`. This is also true for `TextureAtlasSprite`.
* **Simpler BufferVec/UniformVec/DynamicUniformVec Clearing**:  improved the clearing interface by removing the need to know the size of the final buffer at the initial clear.

![image](https://user-images.githubusercontent.com/2694663/140001821-99be0d96-025d-489e-9bfa-ba19c1dc9548.png)


Note that this moves sprites away from entity-driven rendering and back to extracted lists. We _could_ use entities here, but it necessitates that an intermediate list is allocated / populated to collect and sort extracted sprites. This redundant copy, combined with the normal overhead of spawning extracted sprite entities, brings bevymark down to ~80,000 sprites at 60fps. I think making sprites a bit more fixed (by default) is worth it. I view this as acceptable because batching makes normal entity-driven rendering pretty useless anyway (and we would want to batch most custom materials too). We can still support custom shaders with custom bindings, we'll just need to define a specific interface for it.
2021-11-04 20:28:53 +00:00
Robert Swain
2f22f5ca21 MSAA example (#3049)
Add an example that demonstrates the difference between no MSAA and MSAA 4x. This is also useful for testing panics when resizing the window using MSAA. This is on top of #3042 .

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-11-03 22:20:23 +00:00
Mike
95032a3f97 change texture atlas sprite indexing to usize (#2887)
Per this comment https://github.com/bevyengine/bevy/pull/2864#discussion_r717947232,
I have done a pass at changing all the public facing indexes for `TextureAtlas` to usize.
2021-11-01 21:28:50 +00:00
Carter Anderson
015617a774 Pipeline Specialization, Shader Assets, and Shader Preprocessing (#3031)
## New Features
This adds the following to the new renderer:

* **Shader Assets**
  * Shaders are assets again! Users no longer need to call `include_str!` for their shaders
  * Shader hot-reloading
* **Shader Defs / Shader Preprocessing**
  * Shaders now support `# ifdef NAME`, `# ifndef NAME`, and `# endif` preprocessor directives
* **Bevy RenderPipelineDescriptor and RenderPipelineCache**
  * Bevy now provides its own `RenderPipelineDescriptor` and the wgpu version is now exported as `RawRenderPipelineDescriptor`. This allows users to define pipelines with `Handle<Shader>` instead of needing to manually compile and reference `ShaderModules`, enables passing in shader defs to configure the shader preprocessor, makes hot reloading possible (because the descriptor can be owned and used to create new pipelines when a shader changes), and opens the doors to pipeline specialization.
  * The `RenderPipelineCache` now handles compiling and re-compiling Bevy RenderPipelineDescriptors. It has internal PipelineLayout and ShaderModule caches. Users receive a `CachedPipelineId`, which can be used to look up the actual `&RenderPipeline` during rendering. 
* **Pipeline Specialization**
  * This enables defining per-entity-configurable pipelines that specialize on arbitrary custom keys. In practice this will involve specializing based on things like MSAA values, Shader Defs, Bind Group existence, and Vertex Layouts.
  * Adds a `SpecializedPipeline` trait and `SpecializedPipelines<MyPipeline>` resource. This is a simple layer that generates Bevy RenderPipelineDescriptors based on a custom key defined for the pipeline.
  * Specialized pipelines are also hot-reloadable.
  * This was the result of experimentation with two different approaches:
    1. **"generic immediate mode multi-key hash pipeline specialization"**
      * breaks up the pipeline into multiple "identities" (the core pipeline definition, shader defs, mesh layout, bind group layout). each of these identities has its own key. looking up / compiling a specific version of a pipeline requires composing all of these keys together
      * the benefit of this approach is that it works for all pipelines / the pipeline is fully identified by the keys. the multiple keys allow pre-hashing parts of the pipeline identity where possible (ex: pre compute the mesh identity for all meshes)
      * the downside is that any per-entity data that informs the values of these keys could require expensive re-hashes. computing each key for each sprite tanked bevymark performance (sprites don't actually need this level of specialization yet ... but things like pbr and future sprite scenarios might). 
      * this is the approach rafx used last time i checked
    2. **"custom key specialization"**
      * Pipelines by default are not specialized
      * Pipelines that need specialization implement a SpecializedPipeline trait with a custom key associated type
      * This allows specialization keys to encode exactly the amount of information required (instead of needing to be a combined hash of the entire pipeline). Generally this should fit in a small number of bytes. Per-entity specialization barely registers anymore on things like bevymark. It also makes things like "shader defs" way cheaper to hash because we can use context specific bitflags instead of strings.
      * Despite the extra trait, it actually generally makes pipeline definitions + lookups simpler: managing multiple keys (and making the appropriate calls to manage these keys) was way more complicated.
  * I opted for custom key specialization. It performs better generally and in my opinion is better UX. Fortunately the way this is implemented also allows for custom caches as this all builds on a common abstraction: the RenderPipelineCache. The built in custom key trait is just a simple / pre-defined way to interact with the cache 

## Callouts

* The SpecializedPipeline trait makes it easy to inherit pipeline configuration in custom pipelines. The changes to `custom_shader_pipelined` and the new `shader_defs_pipelined` example illustrate how much simpler it is to define custom pipelines based on the PbrPipeline.
* The shader preprocessor is currently pretty naive (it just uses regexes to process each line). Ultimately we might want to build a more custom parser for more performance + better error handling, but for now I'm happy to optimize for "easy to implement and understand". 

## Next Steps

* Port compute pipelines to the new system
* Add more preprocessor directives (else, elif, import)
* More flexible vertex attribute specialization / enable cheaply specializing on specific mesh vertex layouts
2021-10-28 19:07:47 +00:00
Yoh Deadfall
ffde86efa0 Update to edition 2021 on master (#3028)
Objective
During work on #3009 I've found that not all jobs use actions-rs, and therefore, an previous version of Rust is used for them. So while compilation and other stuff can pass, checking markup and Android build may fail with compilation errors.

Solution
This PR adds `action-rs` for any job running cargo, and updates the edition to 2021.
2021-10-27 00:12:14 +00:00
François
2f4bcc5bf7 Update for edition 2021 (#2997)
# Objective

- update for Edition 2021

## Solution

- remove the `resolver = "2"`
- update for https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html by adding a few ` `
2021-10-25 18:00:13 +00:00
Carter Anderson
43e8a156fb Upgrade to wgpu 0.11 (#2933)
Upgrades both the old and new renderer to wgpu 0.11 (and naga 0.7). This builds on @zicklag's work here #2556.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-10-08 19:55:24 +00:00
Paweł Grabarz
07ed1d053e Implement and require #[derive(Component)] on all component structs (#2254)
This implements the most minimal variant of #1843 - a derive for marker trait. This is a prerequisite to more complicated features like statically defined storage type or opt-out component reflection.

In order to make component struct's purpose explicit and avoid misuse, it must be annotated with `#[derive(Component)]` (manual impl is discouraged for compatibility). Right now this is just a marker trait, but in the future it might be expanded. Making this change early allows us to make further changes later without breaking backward compatibility for derive macro users.

This already prevents a lot of issues, like using bundles in `insert` calls. Primitive types are no longer valid components as well. This can be easily worked around by adding newtype wrappers and deriving `Component` for them.

One funny example of prevented bad code (from our own tests) is when an newtype struct or enum variant is used. Previously, it was possible to write `insert(Newtype)` instead of `insert(Newtype(value))`. That code compiled, because function pointers (in this case newtype struct constructor) implement `Send + Sync + 'static`, so we allowed them to be used as components. This is no longer the case and such invalid code will trigger a compile error.


Co-authored-by: = <=>
Co-authored-by: TheRawMeatball <therawmeatball@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-10-03 19:23:44 +00:00
Carter Anderson
08969a24b8 Modular Rendering (#2831)
This changes how render logic is composed to make it much more modular. Previously, all extraction logic was centralized for a given "type" of rendered thing. For example, we extracted meshes into a vector of ExtractedMesh, which contained the mesh and material asset handles, the transform, etc. We looked up bindings for "drawn things" using their index in the `Vec<ExtractedMesh>`. This worked fine for built in rendering, but made it hard to reuse logic for "custom" rendering. It also prevented us from reusing things like "extracted transforms" across contexts.

To make rendering more modular, I made a number of changes:

* Entities now drive rendering:
  * We extract "render components" from "app components" and store them _on_ entities. No more centralized uber lists! We now have true "ECS-driven rendering"
  * To make this perform well, I implemented #2673 in upstream Bevy for fast batch insertions into specific entities. This was merged into the `pipelined-rendering` branch here: #2815
* Reworked the `Draw` abstraction:
  * Generic `PhaseItems`: each draw phase can define its own type of "rendered thing", which can define its own "sort key"
  * Ported the 2d, 3d, and shadow phases to the new PhaseItem impl (currently Transparent2d, Transparent3d, and Shadow PhaseItems)
  * `Draw` trait and and `DrawFunctions` are now generic on PhaseItem
  * Modular / Ergonomic `DrawFunctions` via `RenderCommands`
    * RenderCommand is a trait that runs an ECS query and produces one or more RenderPass calls. Types implementing this trait can be composed to create a final DrawFunction. For example the DrawPbr DrawFunction is created from the following DrawCommand tuple. Const generics are used to set specific bind group locations:
        ```rust
         pub type DrawPbr = (
            SetPbrPipeline,
            SetMeshViewBindGroup<0>,
            SetStandardMaterialBindGroup<1>,
            SetTransformBindGroup<2>,
            DrawMesh,
        );
        ```
    * The new `custom_shader_pipelined` example illustrates how the commands above can be reused to create a custom draw function:
       ```rust
       type DrawCustom = (
           SetCustomMaterialPipeline,
           SetMeshViewBindGroup<0>,
           SetTransformBindGroup<2>,
           DrawMesh,
       );
       ``` 
* ExtractComponentPlugin and UniformComponentPlugin:
  * Simple, standardized ways to easily extract individual components and write them to GPU buffers
* Ported PBR and Sprite rendering to the new primitives above.
* Removed staging buffer from UniformVec in favor of direct Queue usage
  * Makes UniformVec much easier to use and more ergonomic. Completely removes the need for custom render graph nodes in these contexts (see the PbrNode and view Node removals and the much simpler call patterns in the relevant Prepare systems).
* Added a many_cubes_pipelined example to benchmark baseline 3d rendering performance and ensure there were no major regressions during this port. Avoiding regressions was challenging given that the old approach of extracting into centralized vectors is basically the "optimal" approach. However thanks to a various ECS optimizations and render logic rephrasing, we pretty much break even on this benchmark!
* Lifetimeless SystemParams: this will be a bit divisive, but as we continue to embrace "trait driven systems" (ex: ExtractComponentPlugin, UniformComponentPlugin, DrawCommand), the ergonomics of `(Query<'static, 'static, (&'static A, &'static B, &'static)>, Res<'static, C>)` were getting very hard to bear. As a compromise, I added "static type aliases" for the relevant SystemParams. The previous example can now be expressed like this: `(SQuery<(Read<A>, Read<B>)>, SRes<C>)`. If anyone has better ideas / conflicting opinions, please let me know!
* RunSystem trait: a way to define Systems via a trait with a SystemParam associated type. This is used to implement the various plugins mentioned above. I also added SystemParamItem and QueryItem type aliases to make "trait stye" ecs interactions nicer on the eyes (and fingers).
* RenderAsset retrying: ensures that render assets are only created when they are "ready" and allows us to create bind groups directly inside render assets (which significantly simplified the StandardMaterial code). I think ultimately we should swap this out on "asset dependency" events to wait for dependencies to load, but this will require significant asset system changes.
* Updated some built in shaders to account for missing MeshUniform fields
2021-09-23 06:16:11 +00:00
Carter Anderson
11b41206eb Add upstream bevy_ecs and prepare for custom-shaders merge (#2815)
This updates the `pipelined-rendering` branch to use the latest `bevy_ecs` from `main`. This accomplishes a couple of goals:

1. prepares for upcoming `custom-shaders` branch changes, which were what drove many of the recent bevy_ecs changes on `main`
2. prepares for the soon-to-happen merge of `pipelined-rendering` into `main`. By including bevy_ecs changes now, we make that merge simpler / easier to review. 

I split this up into 3 commits:

1. **add upstream bevy_ecs**: please don't bother reviewing this content. it has already received thorough review on `main` and is a literal copy/paste of the relevant folders (the old folders were deleted so the directories are literally exactly the same as `main`).
2. **support manual buffer application in stages**: this is used to enable the Extract step. we've already reviewed this once on the `pipelined-rendering` branch, but its worth looking at one more time in the new context of (1).
3. **support manual archetype updates in QueryState**: same situation as (2).
2021-09-14 06:14:19 +00:00
MinerSebas
9effc3e9b3 Replace .insert_resource(T::default()) calls with init_resource::<T>() (#2807)
# Objective

I added the [INSERT_RESOURCE_WITH_DEFAULT](https://minersebas.github.io/bevy_lint/bevy_lint/static.INSERT_RESOURCE_WITH_DEFAULT.html) Lint to [bevy_lint](https://github.com/MinerSebas/bevy_lint) and while Testing it on bevy itself, I found several places where the Lint correctly triggered.



## Solution

Replace `.insert_resource(T::default())` calls with `init_resource::<T>()`
2021-09-13 14:02:28 +00:00
Charles Giguere
51a5070cd2 add get_single variant (#2793)
# Objective

The vast majority of `.single()` usage I've seen is immediately followed by a `.unwrap()`. Since it seems most people use it without handling the error, I think making it easier to just get what you want fast while also having a more verbose alternative when you want to handle the error could help.

## Solution

Instead of having a lot of `.unwrap()` everywhere, this PR introduces a `try_single()` variant that behaves like the current `.single()` and make the new `.single()` panic on error.
2021-09-10 20:23:50 +00:00
willolisp
5ff96b8e7e Improve many sprites example (#2785)
# Objective

My attempt at fixing #2075 .

This is my very first contribution to this repo. Also, I'm very new to both Rust and bevy, so any feedback is *deeply* appreciated.

## Solution
- Changed `move_camera_system` so it only targets the camera entity. My approach here differs from the one used in the [cheatbook](https://bevy-cheatbook.github.io/cookbook/cursor2world.html?highlight=maincamera#2d-games) (in which a marker component is used to track the camera), so please, let me know which of them is more idiomatic.
- `move_camera_system` does not require both `Position` and `Transform` anymore (I used `rotate` for rotating the `Transform` in place, but couldn't find an equivalent `translate` method).
- Changed `tick_system` so it only targets the timer entity.
- Sprites are now spawned via a single `spawn_batch` instead of multiple `spawn`s.
2021-09-10 19:13:14 +00:00
Caleb Boylan
ca54478569 Fix breakout example scoreboard (#2770)
# Objective

- The breakout scoreboard was not using the correct text section to display the score integer.

## Solution

- This updates the code to use the correct text section.
2021-09-04 18:52:10 +00:00
Daniel McNab
321d998615 Add convenience methods for checking a set of inputs (#2760)
# Objective

Make it easier to check if some set of inputs matches a key, such as if you want to allow all of space or up or w for jumping.

Currently, this requires:
```rust
if keyboard.pressed(KeyCode::Space)
            || keyboard.pressed(KeyCode::Up)
            || keyboard.pressed(KeyCode::W) {
    // ...
```

## Solution

Add an implementation of the helper methods, which very simply iterate through the items, used as:
```rust
if keyboard.any_pressed([KeyCode::Space, KeyCode::Up, KeyCode::W]) {
```
2021-09-01 21:21:41 +00:00
Robert Swain
045f324e97 Use the infinite reverse right-handed perspective projection (#2543)
# Objective

Forward perspective projections have poor floating point precision distribution over the depth range. Reverse projections fair much better, and instead of having to have a far plane, with the reverse projection, using an infinite far plane is not a problem. The infinite reverse perspective projection has become the industry standard. The renderer rework is a great time to migrate to it.

## Solution

All perspective projections, including point lights, have been moved to using `glam::Mat4::perspective_infinite_reverse_rh()` and so have no far plane. As various depth textures are shared between orthographic and perspective projections, a quirk of this PR is that the near and far planes of the orthographic projection are swapped when the Mat4 is computed. This has no impact on 2D/3D orthographic projection usage, and provides consistency in shaders, texture clear values, etc. throughout the codebase.

## Known issues

For some reason, when looking along -Z, all geometry is black. The camera can be translated up/down / strafed left/right and geometry will still be black. Moving forward/backward or rotating the camera away from looking exactly along -Z causes everything to work as expected.

I have tried to debug this issue but both in macOS and Windows I get crashes when doing pixel debugging. If anyone could reproduce this and debug it I would be very grateful. Otherwise I will have to try to debug it further without pixel debugging, though the projections and such all looked fine to me.
2021-08-27 20:15:09 +00:00
Zicklag
cea7db1050 Remove Need for Sprite Size Sync System (#2632)
# Objective

- Prevent the need to have a system that synchronizes sprite sizes with their images

## Solution

- Read the sprite size from the image asset when rendering the sprite
- Replace the `size` and `resize_mode` fields of `Sprite` with a `custom_size: Option<Vec2>` that will modify the sprite's rendered size to be different than the image size, but only if it is `Some(Vec2)`
2021-08-26 00:53:51 +00:00
Robert Swain
f4aa3284a8 bevy_pbr2: Add support for not casting/receiving shadows (#2726)
# Objective

Allow marking meshes as not casting / receiving shadows.

## Solution

- Added `NotShadowCaster` and `NotShadowReceiver` zero-sized type components.
- Extract these components into `bool`s in `ExtractedMesh`
- Only generate `DrawShadowMesh` `Drawable`s for meshes _without_ `NotShadowCaster`
- Add a `u32` bit `flags` member to `MeshUniform` with one flag indicating whether the mesh is a shadow receiver
- If a mesh does _not_ have the `NotShadowReceiver` component, then it is a shadow receiver, and so the bit in the `MeshUniform` is set, otherwise it is not set.
- Added an example illustrating the functionality.

NOTE: I wanted to have the default state of a mesh as being a shadow caster and shadow receiver, hence the `Not*` components. However, I am on the fence about this. I don't want to have a negative performance impact, nor have people wondering why their custom meshes don't have shadows because they forgot to add `ShadowCaster` and `ShadowReceiver` components, but I also really don't like the double negatives the `Not*` approach incurs. What do you think?

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-08-25 19:44:20 +00:00
Robert Swain
c3d3ae7f92 bevy_pbr2: Improve lighting units and documentation (#2704)
# Objective

A question was raised on Discord about the units of the `PointLight` `intensity` member.

After digging around in the bevy_pbr2 source code and [Google Filament documentation](https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower) I discovered that the intention by Filament was that the 'intensity' value for point lights would be in lumens. This makes a lot of sense as these are quite relatable units given basically all light bulbs I've seen sold over the past years are rated in lumens as people move away from thinking about how bright a bulb is relative to a non-halogen incandescent bulb.

However, it seems that the derivation of the conversion between luminous power (lumens, denoted `Φ` in the Filament formulae) and luminous intensity (lumens per steradian, `I` in the Filament formulae) was missed and I can see why as it is tucked right under equation 58 at the link above. As such, while the formula states that for a point light, `I = Φ / 4 π` we have been using `intensity` as if it were luminous intensity `I`.

Before this PR, the intensity field is luminous intensity in lumens per steradian. After this PR, the intensity field is luminous power in lumens, [as suggested by Filament](https://google.github.io/filament/Filament.html#table_lighttypesunits) (unfortunately the link jumps to the table's caption so scroll up to see the actual table).

I appreciate that it may be confusing to call this an intensity, but I think this is intended as more of a non-scientific, human-relatable general term with a bit of hand waving so that most light types can just have an intensity field and for most of them it works in the same way or at least with some relatable value. I'm inclined to think this is reasonable rather than throwing terms like luminous power, luminous intensity, blah at users.

## Solution

- Documented the `PointLight` `intensity` member as 'luminous power' in units of lumens.
- Added a table of examples relating from various types of household lighting to lumen values.
- Added in the mapping from luminous power to luminous intensity when premultiplying the intensity into the colour before it is made into a graphics uniform.
- Updated the documentation in `pbr.wgsl` to clarify the earlier confusion about the missing `/ 4 π`.
- Bumped the intensity of the point lights in `3d_scene_pipelined` to 1600 lumens.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-08-23 23:48:11 +00:00
Zicklag
3faca93f7b Add ClearColor Resource to Pipelined Renderer (#2631)
# Objective

- Allow the user to set the clear color when using the pipelined renderer

## Solution

- Add a `ClearColor` resource that can be added to the world to configure the clear color

## Remaining Issues

Currently the `ClearColor` resource is cloned from the app world to the render world every frame. There are two ways I can think of around this:

1. Figure out why `app_world.is_resource_changed::<ClearColor>()` always returns `true` in the `extract` step and fix it so that we are only updating the resource when it changes
2. Require the users to add the `ClearColor` resource to the render sub-app instead of the parent app. This is currently sub-optimal until we have labled sub-apps, and probably a helper funciton on `App` such as `app.with_sub_app(RenderApp, |app| { ... })`. Even if we had that, I think it would be more than we want the user to have to think about. They shouldn't have to know about the render sub-app I don't think.

I think the first option is the best, but I could really use some help figuring out the nuance of why `is_resource_changed` is always returning true in that context.
2021-08-19 20:34:31 +00:00
Carter Anderson
9d453530fa System Param Lifetime Split (#2605)
# Objective

Enable using exact World lifetimes during read-only access . This is motivated by the new renderer's need to allow read-only world-only queries to outlive the query itself (but still be constrained by the world lifetime).

For example:
115b170d1f/pipelined/bevy_pbr2/src/render/mod.rs (L774)

## Solution

Split out SystemParam state and world lifetimes and pipe those lifetimes up to read-only Query ops (and add into_inner for Res). According to every safety test I've run so far (except one), this is safe (see the temporary safety test commit). Note that changing the mutable variants to the new lifetimes would allow aliased mutable pointers (try doing that to see how it affects the temporary safety tests).

The new state lifetime on SystemParam does make `#[derive(SystemParam)]` more cumbersome (the current impl requires PhantomData if you don't use both lifetimes). We can make this better by detecting whether or not a lifetime is used in the derive and adjusting accordingly, but that should probably be done in its own pr.  

## Why is this a draft?

The new lifetimes break QuerySet safety in one very specific case (see the query_set system in system_safety_test). We need to solve this before we can use the lifetimes given.

This is due to the fact that QuerySet is just a wrapper over Query, which now relies on world lifetimes instead of `&self` lifetimes to prevent aliasing (but in systems, each Query has its own implied lifetime, not a centralized world lifetime).  I believe the fix is to rewrite QuerySet to have its own World lifetime (and own the internal reference). This will complicate the impl a bit, but I think it is doable. I'm curious if anyone else has better ideas.

Personally, I think these new lifetimes need to happen. We've gotta have a way to directly tie read-only World queries to the World lifetime. The new renderer is the first place this has come up, but I doubt it will be the last. Worst case scenario we can come up with a second `WorldLifetimeQuery<Q, F = ()>` parameter to enable these read-only scenarios, but I'd rather not add another type to the type zoo.
2021-08-15 20:51:53 +00:00
Carter Anderson
a89a954a17 Not me ... us (#2654)
I don't see much of a reason at this point to boost my name over anyone elses. We are all Bevy Contributors.
2021-08-15 20:08:52 +00:00
davier
6aedb2500a Cleanup FromResources (#2601)
## Objective

- Clean up remaining references to the trait `FromResources`, which was replaced in favor of `FromWorld` during the ECS rework.

## Solution

- Remove the derive macro for `FromResources`
- Change doc references of `FromResources` to `FromWorld`

(this is the first item in #2576)
2021-08-13 22:21:34 +00:00
Zicklag
c8330037e7 Re-implement Automatic Sprite Sizing (#2613)
# Objective

- Prevent the need to specify a sprite size when using the pipelined sprite renderer

## Solution

- Re-introduce the sprite auto resize system from the old renderer
2021-08-10 02:26:06 +00:00
Hoidigan
49038d03f5 Remove with bundle filter (#2623)
# Objective

Fixes #2620

## Solution

Remove WithBundle filter and temporarily remove example for query_bundle.
2021-08-10 01:55:52 +00:00
John
115b170d1f Add sprite atlases into the new renderer. (#2560)
# Objective
Restore the functionality of sprite atlases in the new renderer.

### **Note:** This PR relies on #2555 

## Solution
Mostly just a copy paste of the existing sprite atlas implementation, however I unified the rendering between sprites and atlases.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-08-04 01:16:25 +00:00
Robert Swain
ae4f809a52 Port bevy_gltf to pipelined-rendering (#2537)
# Objective

Port bevy_gltf to the pipelined-rendering branch.

## Solution

crates/bevy_gltf has been copied and pasted into pipelined/bevy_gltf2 and modifications were made to work with the pipelined-rendering branch. Notably vertex tangents and vertex colours are not supported.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-07-30 03:37:34 +00:00
Boxy
0b800e547b Fix some nightly clippy lints (#2522)
on nightly these two clippy lints fail:
- [needless_borrow](https://rust-lang.github.io/rust-clippy/master/#needless_borrow)
- [unused_unit](https://rust-lang.github.io/rust-clippy/master/#unused_unit)
2021-07-29 19:36:39 -07:00
Boxy
5ffff03b33 Fix some nightly clippy lints (#2522)
on nightly these two clippy lints fail:
- [needless_borrow](https://rust-lang.github.io/rust-clippy/master/#needless_borrow)
- [unused_unit](https://rust-lang.github.io/rust-clippy/master/#unused_unit)
2021-07-29 20:52:15 +00:00
François
b724a0f586 Down with the system! (#2496)
# Objective

- Remove all the `.system()` possible.
- Check for remaining missing cases.

## Solution

- Remove all `.system()`, fix compile errors
- 32 calls to `.system()` remains, mostly internals, the few others should be removed after #2446
2021-07-27 23:42:36 +00:00