2022-05-16 13:53:20 +00:00
|
|
|
//! Shows how to render simple primitive shapes with a single color.
|
|
|
|
|
2024-02-14 23:36:18 +00:00
|
|
|
use bevy::{
|
|
|
|
prelude::*,
|
2024-05-30 20:00:59 +00:00
|
|
|
sprite::{MaterialMesh2dBundle, Mesh2dHandle, Wireframe2dConfig, Wireframe2dPlugin},
|
2024-02-14 23:36:18 +00:00
|
|
|
};
|
2022-05-05 00:03:47 +00:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
App::new()
|
2024-05-30 20:00:59 +00:00
|
|
|
.add_plugins((DefaultPlugins, Wireframe2dPlugin))
|
2023-03-18 01:45:34 +00:00
|
|
|
.add_systems(Startup, setup)
|
2024-05-30 20:00:59 +00:00
|
|
|
.add_systems(Update, toggle_wireframe)
|
2022-05-05 00:03:47 +00:00
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
2024-05-26 15:27:57 +00:00
|
|
|
const X_EXTENT: f32 = 900.;
|
2024-02-14 23:36:18 +00:00
|
|
|
|
2022-05-05 00:03:47 +00:00
|
|
|
fn setup(
|
|
|
|
mut commands: Commands,
|
|
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
|
|
) {
|
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
|
|
|
commands.spawn(Camera2dBundle::default());
|
2022-05-05 00:03:47 +00:00
|
|
|
|
2024-02-14 23:36:18 +00:00
|
|
|
let shapes = [
|
|
|
|
Mesh2dHandle(meshes.add(Circle { radius: 50.0 })),
|
2024-05-23 16:12:46 +00:00
|
|
|
Mesh2dHandle(meshes.add(CircularSector::new(50.0, 1.0))),
|
|
|
|
Mesh2dHandle(meshes.add(CircularSegment::new(50.0, 1.25))),
|
2024-02-14 23:36:18 +00:00
|
|
|
Mesh2dHandle(meshes.add(Ellipse::new(25.0, 50.0))),
|
2024-04-02 07:18:09 +00:00
|
|
|
Mesh2dHandle(meshes.add(Annulus::new(25.0, 50.0))),
|
2024-02-14 23:36:18 +00:00
|
|
|
Mesh2dHandle(meshes.add(Capsule2d::new(25.0, 50.0))),
|
2024-05-26 15:27:57 +00:00
|
|
|
Mesh2dHandle(meshes.add(Rhombus::new(75.0, 100.0))),
|
2024-02-14 23:36:18 +00:00
|
|
|
Mesh2dHandle(meshes.add(Rectangle::new(50.0, 100.0))),
|
|
|
|
Mesh2dHandle(meshes.add(RegularPolygon::new(50.0, 6))),
|
|
|
|
Mesh2dHandle(meshes.add(Triangle2d::new(
|
|
|
|
Vec2::Y * 50.0,
|
|
|
|
Vec2::new(-50.0, -50.0),
|
|
|
|
Vec2::new(50.0, -50.0),
|
|
|
|
))),
|
|
|
|
];
|
|
|
|
let num_shapes = shapes.len();
|
|
|
|
|
|
|
|
for (i, shape) in shapes.into_iter().enumerate() {
|
|
|
|
// Distribute colors evenly across the rainbow.
|
Migrate from `LegacyColor` to `bevy_color::Color` (#12163)
# Objective
- As part of the migration process we need to a) see the end effect of
the migration on user ergonomics b) check for serious perf regressions
c) actually migrate the code
- To accomplish this, I'm going to attempt to migrate all of the
remaining user-facing usages of `LegacyColor` in one PR, being careful
to keep a clean commit history.
- Fixes #12056.
## Solution
I've chosen to use the polymorphic `Color` type as our standard
user-facing API.
- [x] Migrate `bevy_gizmos`.
- [x] Take `impl Into<Color>` in all `bevy_gizmos` APIs
- [x] Migrate sprites
- [x] Migrate UI
- [x] Migrate `ColorMaterial`
- [x] Migrate `MaterialMesh2D`
- [x] Migrate fog
- [x] Migrate lights
- [x] Migrate StandardMaterial
- [x] Migrate wireframes
- [x] Migrate clear color
- [x] Migrate text
- [x] Migrate gltf loader
- [x] Register color types for reflection
- [x] Remove `LegacyColor`
- [x] Make sure CI passes
Incidental improvements to ease migration:
- added `Color::srgba_u8`, `Color::srgba_from_array` and friends
- added `set_alpha`, `is_fully_transparent` and `is_fully_opaque` to the
`Alpha` trait
- add and immediately deprecate (lol) `Color::rgb` and friends in favor
of more explicit and consistent `Color::srgb`
- standardized on white and black for most example text colors
- added vector field traits to `LinearRgba`: ~~`Add`, `Sub`,
`AddAssign`, `SubAssign`,~~ `Mul<f32>` and `Div<f32>`. Multiplications
and divisions do not scale alpha. `Add` and `Sub` have been cut from
this PR.
- added `LinearRgba` and `Srgba` `RED/GREEN/BLUE`
- added `LinearRgba_to_f32_array` and `LinearRgba::to_u32`
## Migration Guide
Bevy's color types have changed! Wherever you used a
`bevy::render::Color`, a `bevy::color::Color` is used instead.
These are quite similar! Both are enums storing a color in a specific
color space (or to be more precise, using a specific color model).
However, each of the different color models now has its own type.
TODO...
- `Color::rgba`, `Color::rgb`, `Color::rbga_u8`, `Color::rgb_u8`,
`Color::rgb_from_array` are now `Color::srgba`, `Color::srgb`,
`Color::srgba_u8`, `Color::srgb_u8` and `Color::srgb_from_array`.
- `Color::set_a` and `Color::a` is now `Color::set_alpha` and
`Color::alpha`. These are part of the `Alpha` trait in `bevy_color`.
- `Color::is_fully_transparent` is now part of the `Alpha` trait in
`bevy_color`
- `Color::r`, `Color::set_r`, `Color::with_r` and the equivalents for
`g`, `b` `h`, `s` and `l` have been removed due to causing silent
relatively expensive conversions. Convert your `Color` into the desired
color space, perform your operations there, and then convert it back
into a polymorphic `Color` enum.
- `Color::hex` is now `Srgba::hex`. Call `.into` or construct a
`Color::Srgba` variant manually to convert it.
- `WireframeMaterial`, `ExtractedUiNode`, `ExtractedDirectionalLight`,
`ExtractedPointLight`, `ExtractedSpotLight` and `ExtractedSprite` now
store a `LinearRgba`, rather than a polymorphic `Color`
- `Color::rgb_linear` and `Color::rgba_linear` are now
`Color::linear_rgb` and `Color::linear_rgba`
- The various CSS color constants are no longer stored directly on
`Color`. Instead, they're defined in the `Srgba` color space, and
accessed via `bevy::color::palettes::css`. Call `.into()` on them to
convert them into a `Color` for quick debugging use, and consider using
the much prettier `tailwind` palette for prototyping.
- The `LIME_GREEN` color has been renamed to `LIMEGREEN` to comply with
the standard naming.
- Vector field arithmetic operations on `Color` (add, subtract, multiply
and divide by a f32) have been removed. Instead, convert your colors
into `LinearRgba` space, and perform your operations explicitly there.
This is particularly relevant when working with emissive or HDR colors,
whose color channel values are routinely outside of the ordinary 0 to 1
range.
- `Color::as_linear_rgba_f32` has been removed. Call
`LinearRgba::to_f32_array` instead, converting if needed.
- `Color::as_linear_rgba_u32` has been removed. Call
`LinearRgba::to_u32` instead, converting if needed.
- Several other color conversion methods to transform LCH or HSL colors
into float arrays or `Vec` types have been removed. Please reimplement
these externally or open a PR to re-add them if you found them
particularly useful.
- Various methods on `Color` such as `rgb` or `hsl` to convert the color
into a specific color space have been removed. Convert into
`LinearRgba`, then to the color space of your choice.
- Various implicitly-converting color value methods on `Color` such as
`r`, `g`, `b` or `h` have been removed. Please convert it into the color
space of your choice, then check these properties.
- `Color` no longer implements `AsBindGroup`. Store a `LinearRgba`
internally instead to avoid conversion costs.
---------
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-02-29 19:35:12 +00:00
|
|
|
let color = Color::hsl(360. * i as f32 / num_shapes as f32, 0.95, 0.7);
|
2024-02-14 23:36:18 +00:00
|
|
|
|
|
|
|
commands.spawn(MaterialMesh2dBundle {
|
|
|
|
mesh: shape,
|
|
|
|
material: materials.add(color),
|
|
|
|
transform: Transform::from_xyz(
|
2024-04-03 21:35:15 +00:00
|
|
|
// Distribute shapes from -X_EXTENT/2 to +X_EXTENT/2.
|
2024-02-14 23:36:18 +00:00
|
|
|
-X_EXTENT / 2. + i as f32 / (num_shapes - 1) as f32 * X_EXTENT,
|
|
|
|
0.0,
|
|
|
|
0.0,
|
|
|
|
),
|
|
|
|
..default()
|
|
|
|
});
|
|
|
|
}
|
2024-05-30 20:00:59 +00:00
|
|
|
|
|
|
|
commands.spawn(
|
2024-05-31 16:41:27 +00:00
|
|
|
TextBundle::from_section("Press space to toggle wireframes", TextStyle::default())
|
|
|
|
.with_style(Style {
|
|
|
|
position_type: PositionType::Absolute,
|
|
|
|
top: Val::Px(12.0),
|
|
|
|
left: Val::Px(12.0),
|
2024-05-30 20:00:59 +00:00
|
|
|
..default()
|
2024-05-31 16:41:27 +00:00
|
|
|
}),
|
2024-05-30 20:00:59 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn toggle_wireframe(
|
|
|
|
mut wireframe_config: ResMut<Wireframe2dConfig>,
|
|
|
|
keyboard: Res<ButtonInput<KeyCode>>,
|
|
|
|
) {
|
|
|
|
if keyboard.just_pressed(KeyCode::Space) {
|
|
|
|
wireframe_config.global = !wireframe_config.global;
|
|
|
|
}
|
2022-05-05 00:03:47 +00:00
|
|
|
}
|