Commit Graph

25 Commits

Author SHA1 Message Date
François Mockers 2969a1b8f0 fix building custom_primitives examples in wasm (#22511)
# Objective

- Example `custom_primitives` doesn't build in wasm

## Solution

- Add the missing gate
2026-01-14 18:22:27 +00:00
Aevyrie a88af65738 Contact Shadows (#22382)
# Objective

- Implement contact shadows to add fine shadow detail where shadow
cascades cannot.

## Solution

- Extend our existing pbr implementation using our existing raymarching
functions.

---

## Showcase

<img width="1824" height="1180" alt="image"
src="https://github.com/user-attachments/assets/e93b79c5-c596-4a9e-b94d-20bdde1d863b"
/>

<img width="1824" height="1180" alt="image"
src="https://github.com/user-attachments/assets/0fd7dffa-60b8-4b92-8fad-7f993d4d89dd"
/>


https://github.com/user-attachments/assets/e74b190d-9ae3-4aaf-97f0-b520930a0667


https://github.com/user-attachments/assets/e80ccb26-bbaa-4d25-a823-8ea12354c5b9


https://github.com/user-attachments/assets/b04f4b00-92bd-4a2f-b7dd-5157d8fbe0ab

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/b7629908-dd32-48db-8ee7-a4d2dd8f66c2"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/3de0258e-9191-4180-ac57-41b32e1205bd"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/951477f9-e9a9-426f-ae8d-18ae50cc7b85"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/2291453c-da57-4fcc-a6b0-f60f6eac6cbb"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/5820cdff-ea54-4294-b520-2a8d8dc24996"
/>

<img width="1073" height="685" alt="image"
src="https://github.com/user-attachments/assets/3ea16481-7689-4e99-87e2-1589f1532e4c"
/>

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: charlotte 🌸 <charlotte.c.mcelwain@gmail.com>
2026-01-13 21:51:39 +00:00
Patrick Walton 00f6eb7a1c Implement the infrastructure needed to support portals and mirrors. (#13797)
Implement the infrastructure needed to support portals and mirrors.

Bevy currently supports multiple cameras and rendering to off-screen
render targets, so one might naïvely think that the engine has support
for portals and mirrors already. However, Bevy is missing two key
features that enable portals and mirrors at present:

1. Bevy has support for neither custom clip planes nor oblique clip
planes. This prevents the construction of proper portals or mirrors, as
meshes that intersect the portal plane must be clipped to render
properly.

2. Bevy has no support for cameras that invert the culling mode, so
meshes that are reflected across a plane will render inside-out.

This PR addresses the two issues above:

1. This commit introduces a new field on `PerspectiveProjection`,
`near_plane`, which allows the application to specify a custom near
plane. That feature fully enables [Lengyel oblique clipping], which is
the most optimal way to achieve a custom near clipping plane. It allows
us to avoid having to support custom clip planes, which are often
implemented inefficiently in hardware.

2. This patch adds a new field on the `Camera` component,
`invert_culling`. This field causes the Bevy renderer to invert the
front face setting when rendering the objects visible from that camera.
When coupled with an appropriately-set [Householder matrix] on the
camera, this allows correct rendering of objects reflected across a
plane.

Additionally, this PR adds a new function to `bevy_math::mat3`,
`reflection_matrix`. This generates the matrix that reflects objects
across a plane, suitable for encoding into a `Transform`. It's fully
documented for ease of use.

Finally, a new example, `mirror`, has been added. This example is a
complete instance of a working mirror, combining a camera with a
Householder matrix, oblique projection, and inverted culling with a
custom material to render an animated mesh and its planar reflection.
The camera and mesh may be moved with the mouse, and the off-screen
render target that stores the rendered contents of the mirror world is
properly resized when the user resizes the window.

[Lengyel oblique clipping]:
https://terathon.com/lengyel/Lengyel-Oblique.pdf

[Householder matrix]:
https://en.wikipedia.org/wiki/Householder_transformation

<img width="2564" height="1500" alt="Screenshot 2025-12-05 212155"
src="https://github.com/user-attachments/assets/35652b58-a9a5-415a-bdff-367889a23b9f"
/>
2025-12-09 23:08:15 +00:00
tigregalis 0b3a34032a Ring shape primitive (#21446)
# Objective

This introduces a generalised 2d `Ring` shape for any underlying
primitive (i.e. what an `Annulus` is to a `Circle`). This allows us to
have "hollow" shapes or "outlines". `Ring` is also extrudable. It is
assumed that the inner and outer meshes have the same number of
vertices.

```rs
let capsule_ring = Ring::new(Capsule2d::new(50.0, 100.0), Capsule2d::new(45.0, 100.0));
let hexagon_ring = Ring::new(RegularPolygon::new(50.0, 6), RegularPolygon::new(45.0, 6)); // note vertex count must match
```

## Solution

There is a new generic primitive `Ring`, which takes as input any
`Primitive2d`, with two instances of that shape: the outer and the inner
(or hollow).

The mesh for a `RingMeshBuilder` is constructed by concatenating the
vertices of the outer and inner meshes, then walking the perimeter to
join corresponding vertices like so:

<img width="513" height="509" alt="image"
src="https://github.com/user-attachments/assets/2cecb458-3b59-44fb-858b-1beffecd1e57"
/>

```
# outer vertices, then inner vertices
positions = [
  0  1  2  3  4
  0' 1' 2' 3' 4'
]
# pairs of triangles
indices = [
  0  1  0'    0' 1  1'
  1  2  1'    1' 2  2'
  2  3  2'    2' 3  3'
  3  4  3'    3' 4  4'
  4  0  4'    4' 0  0'
]
```

Examples of generated meshes:

<img width="398" height="351" alt="image"
src="https://github.com/user-attachments/assets/348bbd91-9f4e-4040-bfa5-d508a4308c10"
/>

<img width="472" height="376" alt="image"
src="https://github.com/user-attachments/assets/dbaf894e-6f7f-4b79-af3e-69516da85898"
/>

<img width="388" height="357" alt="image"
src="https://github.com/user-attachments/assets/cb9881e5-4518-4743-b8de-5816b632f36f"
/>

<img width="449" height="402" alt="image"
src="https://github.com/user-attachments/assets/7d2022c9-b8cf-4b4b-bb09-cbe4fe49fb89"
/>

## Testing

I've tested these changes by updating the `2d_shapes`, `3d_shapes` and
`custom_primitives` examples.

It could potentially benefit from unit tests.

---

## Showcase

<img width="1282" height="752" alt="image"
src="https://github.com/user-attachments/assets/edab9dbf-1093-43c7-9804-8e5c8a830573"
/>

_Rings of 2d primitives (bottom row)_

<img width="1282" height="752" alt="image"
src="https://github.com/user-attachments/assets/fbeed7f9-42bb-432c-bce9-cfeca87d70af"
/>

_Extrusions of rings of extrudable primitives (back row)_

---

## Follow-up work

I've only realised this from looking at Extrudable, but because I used
the mesh positions but it does assume the positions are well-ordered
around the perimeter. Extrudable instead uses the notion of a perimeter
(via indices so it doesn't matter what order the mesh positions are in),
a follow-up may be to do something similar for Ring. An alternative idea
may be to compute the perimeter first as directly a list of Vec2
positions (maybe a Perimeter trait), then construct any needed meshes
from that.

This potentially makes `Annulus` redundant as it is equivalent to a
`Ring<Circle>`. One thing of note is that `Extrusion<Annulus>` is
textured differently from `Extrusion<Ring<Circle>>`.

Another idea is to have a way to construct `PrimitiveTopology::LineList`
meshes from Primitive shapes (which may have a similar effect as
creating a Ring).
2025-10-09 21:00:25 +00:00
TheBlckbird 13877fa84d Add a new trait to accept more types in the Val-helper functions (#20551)
# Objective

- Allow the `Val`-helper functions to accept more types besides just
`f32`

Fixes #20549

## Solution

- Adds a new trait that can be implemented for numbers
- That trait has a method that converts `self` to `f32`

## Testing

- I tested it using Rust's testing framework (although I didn't leave
the tests in, as I don't deem them important enough)

<details>
  <summary>Rust test</summary>

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_val_helpers_work() {
        let p = px(10_u8);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u16);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u32);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u64);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_u128);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i8);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i16);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i32);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i64);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10_i128);
        assert_eq!(p, Val::Px(10.0));

        let p = px(10.3_f32);
        assert_eq!(p, Val::Px(10.3));

        let p = px(10.6_f64);
        assert_eq!(p, Val::Px(10.6));
    }
}
```
</details>

---

## Showcase

```rust
// Same as Val::Px(10.)
px(10);
px(10_u8);
px(10.0);
```
2025-08-29 20:18:57 +00:00
atlv 68b848217f Yeet RenderAssetUsages re-export (#20498)
# Objective

- Forgor to yeet this

## Solution

- rember and yeet

## Testing

cargo check --examples --all-features
2025-08-11 01:42:08 +00:00
atlv 03dd839b82 Use bevy::camera in examples instead of bevy::render::camera re-export (#20477)
# Objective

- Prepare for removing re-exports

## Solution

- title

## Testing

- cargo check --examples
2025-08-09 21:09:48 +00:00
atlv acc8f6d455 Stop using mesh re-exports in-repo and add bevy_mesh prelude (#20473)
# Objective

- prepare to remove bevy_mesh re-export from bevy_render. This will be
done in 0.18, but we might as well prepare for it now.

## Solution

- Add a prelude and use bevy_mesh directly. After this pr and #20471, we
will be ready.

## Testing

- cargo check --examples
2025-08-09 17:46:27 +00:00
Benjamin Brienen c3ff6d4136 Fix non-crate typos (#18219)
# Objective

Correct spelling

## Solution

Fix typos, specifically ones that I found in folders other than /crates

## Testing

CI

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-03-11 06:17:48 +00:00
Carter Anderson 015f2c69ca Merge Style properties into Node. Use ComputedNode for computed properties. (#15975)
# Objective

Continue improving the user experience of our UI Node API in the
direction specified by [Bevy's Next Generation Scene / UI
System](https://github.com/bevyengine/bevy/discussions/14437)

## Solution

As specified in the document above, merge `Style` fields into `Node`,
and move "computed Node fields" into `ComputedNode` (I chose this name
over something like `ComputedNodeLayout` because it currently contains
more than just layout info. If we want to break this up / rename these
concepts, lets do that in a separate PR). `Style` has been removed.

This accomplishes a number of goals:

## Ergonomics wins

Specifying both `Node` and `Style` is now no longer required for
non-default styles

Before:
```rust
commands.spawn((
    Node::default(),
    Style {
        width:  Val::Px(100.),
        ..default()
    },
));
```

After:

```rust
commands.spawn(Node {
    width:  Val::Px(100.),
    ..default()
});
```

## Conceptual clarity

`Style` was never a comprehensive "style sheet". It only defined "core"
style properties that all `Nodes` shared. Any "styled property" that
couldn't fit that mold had to be in a separate component. A "real" style
system would style properties _across_ components (`Node`, `Button`,
etc). We have plans to build a true style system (see the doc linked
above).

By moving the `Style` fields to `Node`, we fully embrace `Node` as the
driving concept and remove the "style system" confusion.

## Next Steps

* Consider identifying and splitting out "style properties that aren't
core to Node". This should not happen for Bevy 0.15.

---

## Migration Guide

Move any fields set on `Style` into `Node` and replace all `Style`
component usage with `Node`.

Before:
```rust
commands.spawn((
    Node::default(),
    Style {
        width:  Val::Px(100.),
        ..default()
    },
));
```

After:

```rust
commands.spawn(Node {
    width:  Val::Px(100.),
    ..default()
});
```

For any usage of the "computed node properties" that used to live on
`Node`, use `ComputedNode` instead:

Before:
```rust
fn system(nodes: Query<&Node>) {
    for node in &nodes {
        let computed_size = node.size();
    }
}
```

After:
```rust
fn system(computed_nodes: Query<&ComputedNode>) {
    for computed_node in &computed_nodes {
        let computed_size = computed_node.size();
    }
}
```
2024-10-18 22:25:33 +00:00
Alice Cecile 2bd328220b Improve API for scaling orthographic cameras (#15969)
# Objective

Fixes #15791.

As raised in #11022, scaling orthographic cameras is confusing! In Bevy
0.14, there were multiple completely redundant ways to do this, and no
clear guidance on which to use.

As a result, #15075 removed the `scale` field from
`OrthographicProjection` completely, solving the redundancy issue.

However, this resulted in an unintuitive API and a painful migration, as
discussed in #15791. Users simply want to change a single parameter to
zoom, rather than deal with the irrelevant details of how the camera is
being scaled.

## Solution

This PR reverts #15075, and takes an alternate, more nuanced approach to
the redundancy problem. `ScalingMode::WindowSize` was by far the biggest
offender. This was the default variant, and stored a float that was
*fully* redundant to setting `scale`.

All of the other variants contained meaningful semantic information and
had an intuitive scale. I could have made these unitless, storing an
aspect ratio, but this would have been a worse API and resulted in a
pointlessly painful migration.

In the course of this work I've also:

- improved the documentation to explain that you should just set `scale`
to zoom cameras
- swapped to named fields for all of the variants in `ScalingMode` for
more clarity about the parameter meanings
- substantially improved the `projection_zoom` example
- removed the footgunny `Mul` and `Div` impls for `ScalingMode`,
especially since these no longer have the intended effect on
`ScalingMode::WindowSize`.
- removed a rounding step because this is now redundant 🎉 

## Testing

I've tested these changes as part of my work in the `projection_zoom`
example, and things seem to work fine.

## Migration Guide

`ScalingMode` has been refactored for clarity, especially on how to zoom
orthographic cameras and their projections:

- `ScalingMode::WindowSize` no longer stores a float, and acts as if its
value was 1. Divide your camera's scale by any previous value to achieve
identical results.
- `ScalingMode::FixedVertical` and `FixedHorizontal` now use named
fields.

---------

Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
2024-10-17 17:50:06 +00:00
andristarr 7482a0d26d aligning public apis of Time,Timer and Stopwatch (#15962)
Fixes #15834

## Migration Guide

The APIs of `Time`, `Timer` and `Stopwatch` have been cleaned up for
consistency with each other and the standard library's `Duration` type.
The following methods have been renamed:

- `Stowatch::paused` -> `Stopwatch::is_paused`
- `Time::elapsed_seconds` -> `Time::elasped_secs` (including `_f64` and
`_wrapped` variants)
2024-10-16 21:09:32 +00:00
Pablo Reinhardt d96a9d15f6 Migrate from Query::single and friends to Single (#15872)
# Objective

- closes #15866

## Solution

- Simply migrate where possible.

## Testing

- Expect that CI will do most of the work. Examples is another way of
testing this, as most of the work is in that area.
---

## Notes
For now, this PR doesn't migrate `QueryState::single` and friends as for
now, this look like another issue. So for example, QueryBuilders that
used single or `World::query` that used single wasn't migrated. If there
is a easy way to migrate those, please let me know.

Most of the uses of `Query::single` were removed, the only other uses
that I found was related to tests of said methods, so will probably be
removed when we remove `Query::single`.
2024-10-13 20:32:06 +00:00
UkoeHB c2c19e5ae4 Text rework (#15591)
**Ready for review. Examples migration progress: 100%.**

# Objective

- Implement https://github.com/bevyengine/bevy/discussions/15014

## Solution

This implements [cart's
proposal](https://github.com/bevyengine/bevy/discussions/15014#discussioncomment-10574459)
faithfully except for one change. I separated `TextSpan` from
`TextSpan2d` because `TextSpan` needs to require the `GhostNode`
component, which is a `bevy_ui` component only usable by UI.

Extra changes:
- Added `EntityCommands::commands_mut` that returns a mutable reference.
This is a blocker for extension methods that return something other than
`self`. Note that `sickle_ui`'s `UiBuilder::commands` returns a mutable
reference for this reason.

## Testing

- [x] Text examples all work.

---

## Showcase

TODO: showcase-worthy

## Migration Guide

TODO: very breaking

### Accessing text spans by index

Text sections are now text sections on different entities in a
hierarchy, Use the new `TextReader` and `TextWriter` system parameters
to access spans by index.

Before:
```rust
fn refresh_text(mut query: Query<&mut Text, With<TimeText>>, time: Res<Time>) {
    let text = query.single_mut();
    text.sections[1].value = format_time(time.elapsed());
}
```

After:
```rust
fn refresh_text(
    query: Query<Entity, With<TimeText>>,
    mut writer: UiTextWriter,
    time: Res<Time>
) {
    let entity = query.single();
    *writer.text(entity, 1) = format_time(time.elapsed());
}
```

### Iterating text spans

Text spans are now entities in a hierarchy, so the new `UiTextReader`
and `UiTextWriter` system parameters provide ways to iterate that
hierarchy. The `UiTextReader::iter` method will give you a normal
iterator over spans, and `UiTextWriter::for_each` lets you visit each of
the spans.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-09 18:35:36 +00:00
Joona Aalto 21b78b5990 Implement From translation and rotation for isometries (#15733)
# Objective

Several of our APIs (namely gizmos and bounding) use isometries on
current Bevy main. This is nicer than separate properties in a lot of
cases, but users have still expressed usability concerns.

One problem is that in a lot of cases, you only care about e.g.
translation, so you end up with this:

```rust
gizmos.cross_2d(
    Isometry2d::from_translation(Vec2::new(-160.0, 120.0)),
    12.0,
    FUCHSIA,
);
```

The isometry adds quite a lot of length and verbosity, and isn't really
that relevant since only the translation is important here.

It would be nice if you could use the translation directly, and only
supply an isometry if both translation and rotation are needed. This
would make the following possible:

```rust
gizmos.cross_2d(Vec2::new(-160.0, 120.0), 12.0, FUCHSIA);
```

removing a lot of verbosity.

## Solution

Implement `From<Vec2>` and `From<Rot2>` for `Isometry2d`, and
`From<Vec3>`, `From<Vec3A>`, and `From<Quat>` for `Isometry3d`. These
are lossless conversions that fit the semantics of `From`.

This makes the proposed API possible! The methods must now simply take
an `impl Into<IsometryNd>`, and this works:

```rust
gizmos.cross_2d(Vec2::new(-160.0, 120.0), 12.0, FUCHSIA);
```
2024-10-08 16:09:28 +00:00
Joona Aalto 25bfa80e60 Migrate cameras to required components (#15641)
# Objective

Yet another PR for migrating stuff to required components. This time,
cameras!

## Solution

As per the [selected
proposal](https://hackmd.io/tsYID4CGRiWxzsgawzxG_g#Combined-Proposal-1-Selected),
deprecate `Camera2dBundle` and `Camera3dBundle` in favor of `Camera2d`
and `Camera3d`.

Adding a `Camera` without `Camera2d` or `Camera3d` now logs a warning,
as suggested by Cart [on
Discord](https://discord.com/channels/691052431525675048/1264881140007702558/1291506402832945273).
I would personally like cameras to work a bit differently and be split
into a few more components, to avoid some footguns and confusing
semantics, but that is more controversial, and shouldn't block this core
migration.

## Testing

I ran a few 2D and 3D examples, and tried cameras with and without
render graphs.

---

## Migration Guide

`Camera2dBundle` and `Camera3dBundle` have been deprecated in favor of
`Camera2d` and `Camera3d`. Inserting them will now also insert the other
components required by them automatically.
2024-10-05 01:59:52 +00:00
Joona Aalto 54006b107b Migrate meshes and materials to required components (#15524)
# Objective

A big step in the migration to required components: meshes and
materials!

## Solution

As per the [selected
proposal](https://hackmd.io/@bevy/required_components/%2Fj9-PnF-2QKK0on1KQ29UWQ):

- Deprecate `MaterialMesh2dBundle`, `MaterialMeshBundle`, and
`PbrBundle`.
- Add `Mesh2d` and `Mesh3d` components, which wrap a `Handle<Mesh>`.
- Add `MeshMaterial2d<M: Material2d>` and `MeshMaterial3d<M: Material>`,
which wrap a `Handle<M>`.
- Meshes *without* a mesh material should be rendered with a default
material. The existence of a material is determined by
`HasMaterial2d`/`HasMaterial3d`, which is required by
`MeshMaterial2d`/`MeshMaterial3d`. This gets around problems with the
generics.

Previously:

```rust
commands.spawn(MaterialMesh2dBundle {
    mesh: meshes.add(Circle::new(100.0)).into(),
    material: materials.add(Color::srgb(7.5, 0.0, 7.5)),
    transform: Transform::from_translation(Vec3::new(-200., 0., 0.)),
    ..default()
});
```

Now:

```rust
commands.spawn((
    Mesh2d(meshes.add(Circle::new(100.0))),
    MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))),
    Transform::from_translation(Vec3::new(-200., 0., 0.)),
));
```

If the mesh material is missing, previously nothing was rendered. Now,
it renders a white default `ColorMaterial` in 2D and a
`StandardMaterial` in 3D (this can be overridden). Below, only every
other entity has a material:

![Näyttökuva 2024-09-29
181746](https://github.com/user-attachments/assets/5c8be029-d2fe-4b8c-ae89-17a72ff82c9a)

![Näyttökuva 2024-09-29
181918](https://github.com/user-attachments/assets/58adbc55-5a1e-4c7d-a2c7-ed456227b909)

Why white? This is still open for discussion, but I think white makes
sense for a *default* material, while *invalid* asset handles pointing
to nothing should have something like a pink material to indicate that
something is broken (I don't handle that in this PR yet). This is kind
of a mix of Godot and Unity: Godot just renders a white material for
non-existent materials, while Unity renders nothing when no materials
exist, but renders pink for invalid materials. I can also change the
default material to pink if that is preferable though.

## Testing

I ran some 2D and 3D examples to test if anything changed visually. I
have not tested all examples or features yet however. If anyone wants to
test more extensively, it would be appreciated!

## Implementation Notes

- The relationship between `bevy_render` and `bevy_pbr` is weird here.
`bevy_render` needs `Mesh3d` for its own systems, but `bevy_pbr` has all
of the material logic, and `bevy_render` doesn't depend on it. I feel
like the two crates should be refactored in some way, but I think that's
out of scope for this PR.
- I didn't migrate meshlets to required components yet. That can
probably be done in a follow-up, as this is already a huge PR.
- It is becoming increasingly clear to me that we really, *really* want
to disallow raw asset handles as components. They caused me a *ton* of
headache here already, and it took me a long time to find every place
that queried for them or inserted them directly on entities, since there
were no compiler errors for it. If we don't remove the `Component`
derive, I expect raw asset handles to be a *huge* footgun for users as
we transition to wrapper components, especially as handles as components
have been the norm so far. I personally consider this to be a blocker
for 0.15: we need to migrate to wrapper components for asset handles
everywhere, and remove the `Component` derive. Also see
https://github.com/bevyengine/bevy/issues/14124.

---

## Migration Guide

Asset handles for meshes and mesh materials must now be wrapped in the
`Mesh2d` and `MeshMaterial2d` or `Mesh3d` and `MeshMaterial3d`
components for 2D and 3D respectively. Raw handles as components no
longer render meshes.

Additionally, `MaterialMesh2dBundle`, `MaterialMeshBundle`, and
`PbrBundle` have been deprecated. Instead, use the mesh and material
components directly.

Previously:

```rust
commands.spawn(MaterialMesh2dBundle {
    mesh: meshes.add(Circle::new(100.0)).into(),
    material: materials.add(Color::srgb(7.5, 0.0, 7.5)),
    transform: Transform::from_translation(Vec3::new(-200., 0., 0.)),
    ..default()
});
```

Now:

```rust
commands.spawn((
    Mesh2d(meshes.add(Circle::new(100.0))),
    MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))),
    Transform::from_translation(Vec3::new(-200., 0., 0.)),
));
```

If the mesh material is missing, a white default material is now used.
Previously, nothing was rendered if the material was missing.

The `WithMesh2d` and `WithMesh3d` query filter type aliases have also
been removed. Simply use `With<Mesh2d>` or `With<Mesh3d>`.

---------

Co-authored-by: Tim Blackbird <justthecooldude@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-10-01 21:33:17 +00:00
Joona Aalto de888a373d Migrate lights to required components (#15554)
# Objective

Another step in the migration to required components: lights!

Note that this does not include `EnvironmentMapLight` or reflection
probes yet, because their API hasn't been fully chosen yet.

## Solution

As per the [selected
proposals](https://hackmd.io/@bevy/required_components/%2FLLnzwz9XTxiD7i2jiUXkJg):

- Deprecate `PointLightBundle` in favor of the `PointLight` component
- Deprecate `SpotLightBundle` in favor of the `PointLight` component
- Deprecate `DirectionalLightBundle` in favor of the `DirectionalLight`
component

## Testing

I ran some examples with lights.

---

## Migration Guide

`PointLightBundle`, `SpotLightBundle`, and `DirectionalLightBundle` have
been deprecated. Use the `PointLight`, `SpotLight`, and
`DirectionalLight` components instead. Adding them will now insert the
other components required by them automatically.
2024-10-01 03:20:43 +00:00
Clar Fon efda7f3f9c Simpler lint fixes: makes ci lints work but disables a lint for now (#15376)
Takes the first two commits from #15375 and adds suggestions from this
comment:
https://github.com/bevyengine/bevy/pull/15375#issuecomment-2366968300

See #15375 for more reasoning/motivation.

## Rebasing (rerunning)

```rust
git switch simpler-lint-fixes
git reset --hard main
cargo fmt --all -- --unstable-features --config normalize_comments=true,imports_granularity=Crate
cargo fmt --all
git add --update
git commit --message "rustfmt"
cargo clippy --workspace --all-targets --all-features --fix
cargo fmt --all -- --unstable-features --config normalize_comments=true,imports_granularity=Crate
cargo fmt --all
git add --update
git commit --message "clippy"
git cherry-pick e6c0b94f6795222310fb812fa5c4512661fc7887
```
2024-09-24 11:42:59 +00:00
Benjamin Brienen 29508f065f Fix floating point math (#15239)
# Objective

- Fixes #15236

## Solution

- Use bevy_math::ops instead of std floating point operations.

## Testing

- Did you test these changes? If so, how?
Unit tests and `cargo run -p ci -- test`

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
Execute `cargo run -p ci -- test` on Windows.

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
Windows

## Migration Guide

- Not a breaking change
- Projects should use bevy math where applicable

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-09-16 23:28:12 +00:00
Rich Churcher f326705cab Remove OrthographicProjection.scale (adopted) (#15075)
# Objective

Hello! I am adopting #11022 to resolve conflicts with `main`. tldr: this
removes `scale` in favour of `scaling_mode`. Please see the original PR
for explanation/discussion.

Also relates to #2580.

## Migration Guide

Replace all uses of `scale` with `scaling_mode`, keeping in mind that
`scale` is (was) a multiplier. For example, replace
```rust
    scale: 2.0,
    scaling_mode: ScalingMode::FixedHorizontal(4.0),

```
with
```rust
    scaling_mode: ScalingMode::FixedHorizontal(8.0),
```

---------

Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
2024-09-09 22:34:58 +00:00
Robert Walter 8895113784 Use Isometry in bevy_gizmos wherever we can (#14676)
# Objective

- Solves the last bullet in and closes #14319
- Make better use of the `Isometry` types
- Prevent issues like #14655
- Probably simplify and clean up a lot of code through the use of Gizmos
as well (i.e. the 3D gizmos for cylinders circles & lines don't connect
well, probably due to wrong rotations)

## Solution

- go through the `bevy_gizmos` crate and give all methods a slight
workover

## Testing

- For all the changed examples I run `git switch main && cargo rr
--example <X> && git switch <BRANCH> && cargo rr --example <X>` and
compare the visual results
- Check if all doc tests are still compiling
- Check the docs in general and update them !!! 

---

## Migration Guide

The gizmos methods function signature changes as follows:

- 2D
- if it took `position` & `rotation_angle` before ->
`Isometry2d::new(position, Rot2::radians(rotation_angle))`
- if it just took `position` before ->
`Isometry2d::from_translation(position)`
- 3D
- if it took `position` & `rotation` before ->
`Isometry3d::new(position, rotation)`
- if it just took `position` before ->
`Isometry3d::from_translation(position)`
2024-08-28 01:37:19 +00:00
EdJoPaTo 938d810766 Apply unused_qualifications lint (#14828)
# Objective

Fixes #14782

## Solution

Enable the lint and fix all upcoming hints (`--fix`). Also tried to
figure out the false-positive (see review comment). Maybe split this PR
up into multiple parts where only the last one enables the lint, so some
can already be merged resulting in less many files touched / less
potential for merge conflicts?

Currently, there are some cases where it might be easier to read the
code with the qualifier, so perhaps remove the import of it and adapt
its cases? In the current stage it's just a plain adoption of the
suggestions in order to have a base to discuss.

## Testing

`cargo clippy` and `cargo run -p ci` are happy.
2024-08-21 12:29:33 +00:00
Matty 601cf6b9e5 Refactor Bounded2d/Bounded3d to use isometries (#14485)
# Objective

Previously, this area of bevy_math used raw translation and rotations to
encode isometries, which did not exist earlier. The goal of this PR is
to make the codebase of bevy_math more harmonious by using actual
isometries (`Isometry2d`/`Isometry3d`) in these places instead — this
will hopefully make the interfaces more digestible for end-users, in
addition to facilitating conversions.

For instance, together with the addition of #14478, this means that a
bounding box for a collider with an isometric `Transform` can be
computed as
```rust
collider.aabb_3d(collider_transform.to_isometry())
```
instead of using manual destructuring. 

## Solution

- The traits `Bounded2d` and `Bounded3d` now use `Isometry2d` and
`Isometry3d` (respectively) instead of `translation` and `rotation`
parameters; e.g.:
  ```rust
  /// A trait with methods that return 3D bounding volumes for a shape.
  pub trait Bounded3d {
/// Get an axis-aligned bounding box for the shape translated and
rotated by the given isometry.
      fn aabb_3d(&self, isometry: Isometry3d) -> Aabb3d;
/// Get a bounding sphere for the shape translated and rotated by the
given isometry.
      fn bounding_sphere(&self, isometry: Isometry3d) -> BoundingSphere;
  }
  ```
- Similarly, the `from_point_cloud` constructors for axis-aligned
bounding boxes and bounding circles/spheres now take isometries instead
of separate `translation` and `rotation`; e.g.:
  ```rust
/// Computes the smallest [`Aabb3d`] containing the given set of points,
/// transformed by the rotation and translation of the given isometry.
    ///
    /// # Panics
    ///
    /// Panics if the given set of points is empty.
    #[inline(always)]
    pub fn from_point_cloud(
        isometry: Isometry3d,
        points: impl Iterator<Item = impl Into<Vec3A>>,
    ) -> Aabb3d { //... }
  ```

This has a couple additional results:
1. The end-user no longer interacts directly with `Into<Vec3A>` or
`Into<Rot2>` parameters; these conversions all happen earlier now,
inside the isometry types.
2. Similarly, almost all intermediate `Vec3 -> Vec3A` conversions have
been eliminated from the `Bounded3d` implementations for primitives.
This probably has some performance benefit, but I have not measured it
as of now.

## Testing

Existing unit tests help ensure that nothing has been broken in the
refactor.

---

## Migration Guide

The `Bounded2d` and `Bounded3d` traits now take `Isometry2d` and
`Isometry3d` parameters (respectively) instead of separate translation
and rotation arguments. Existing calls to `aabb_2d`, `bounding_circle`,
`aabb_3d`, and `bounding_sphere` will have to be changed to use
isometries instead. A straightforward conversion is to refactor just by
calling `Isometry2d/3d::new`, as follows:
```rust
// Old:
let aabb = my_shape.aabb_2d(my_translation, my_rotation);

// New:
let aabb = my_shape.aabb_2d(Isometry2d::new(my_translation, my_rotation));
```

However, if the old translation and rotation are 3d
translation/rotations originating from a `Transform` or
`GlobalTransform`, then `to_isometry` may be used instead. For example:
```rust
// Old:
let bounding_sphere = my_shape.bounding_sphere(shape_transform.translation, shape_transform.rotation);

// New:
let bounding_sphere = my_shape.bounding_sphere(shape_transform.to_isometry());
```

This discussion also applies to the `from_point_cloud` construction
method of `Aabb2d`/`BoundingCircle`/`Aabb3d`/`BoundingSphere`, which has
similarly been altered to use isometries.
2024-07-29 23:37:02 +00:00
Lynn c172c3c4b5 Custom primitives example (#13795)
# Objective

- Add a new example showcasing how to add custom primitives and what you
can do with them.

## Solution

- Added a new example `custom_primitives` with a 2D heart shape
primitive highlighting
  - `Bounded2d` by implementing and visualising bounding shapes,
  - `Measured2d` by implementing it,
  - `Meshable` to show the shape on the screen
- The example also includes an `Extrusion<Heart>` implementing
  - `Measured3d`,
  - `Bounded3d` using the `BoundedExtrusion` trait and
  - meshing using the `Extrudable` trait.

## Additional information

Here are two images of the heart and its extrusion:

![image_2024-06-10_194631194](https://github.com/bevyengine/bevy/assets/62256001/53f1836c-df74-4ba6-85e9-fabdafa94c66)
![Screenshot 2024-06-10
194609](https://github.com/bevyengine/bevy/assets/62256001/b1630e71-6e94-4293-b7b5-da8d9cc98faf)

---------

Co-authored-by: Jakub Marcowski <37378746+Chubercik@users.noreply.github.com>
2024-06-10 21:15:21 +00:00