2024-03-06 22:21:41 +00:00
|
|
|
//! Bevy logo as a desk toy using transparent windows! Now with Googly Eyes!
|
|
|
|
//!
|
|
|
|
//! This example demonstrates:
|
|
|
|
//! - Transparent windows that can be clicked through.
|
|
|
|
//! - Drag-and-drop operations in 2D.
|
|
|
|
//! - Using entity hierarchy and [`SpatialBundle`]s to create simple animations.
|
|
|
|
//! - Creating simple 2D meshes based on shape primitives.
|
|
|
|
|
|
|
|
use bevy::{
|
|
|
|
app::AppExit,
|
|
|
|
input::common_conditions::{input_just_pressed, input_just_released},
|
|
|
|
prelude::*,
|
|
|
|
window::{PrimaryWindow, WindowLevel},
|
|
|
|
};
|
|
|
|
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
use bevy::window::CompositeAlphaMode;
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
App::new()
|
|
|
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
|
|
|
primary_window: Some(Window {
|
|
|
|
title: "Bevy Desk Toy".into(),
|
|
|
|
transparent: true,
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
composite_alpha_mode: CompositeAlphaMode::PostMultiplied,
|
|
|
|
..default()
|
|
|
|
}),
|
|
|
|
..default()
|
|
|
|
}))
|
|
|
|
.insert_resource(ClearColor(WINDOW_CLEAR_COLOR))
|
|
|
|
.insert_resource(WindowTransparency(false))
|
|
|
|
.insert_resource(CursorWorldPos(None))
|
|
|
|
.add_systems(Startup, setup)
|
|
|
|
.add_systems(
|
|
|
|
Update,
|
|
|
|
(
|
|
|
|
get_cursor_world_pos,
|
|
|
|
update_cursor_hit_test,
|
|
|
|
(
|
|
|
|
start_drag.run_if(input_just_pressed(MouseButton::Left)),
|
|
|
|
end_drag.run_if(input_just_released(MouseButton::Left)),
|
|
|
|
drag.run_if(resource_exists::<DragOperation>),
|
|
|
|
quit.run_if(input_just_pressed(MouseButton::Right)),
|
|
|
|
toggle_transparency.run_if(input_just_pressed(KeyCode::Space)),
|
|
|
|
move_pupils.after(drag),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
.chain(),
|
|
|
|
)
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether the window is transparent
|
|
|
|
#[derive(Resource)]
|
|
|
|
struct WindowTransparency(bool);
|
|
|
|
|
|
|
|
/// The projected 2D world coordinates of the cursor (if it's within primary window bounds).
|
|
|
|
#[derive(Resource)]
|
|
|
|
struct CursorWorldPos(Option<Vec2>);
|
|
|
|
|
|
|
|
/// The current drag operation including the offset with which we grabbed the Bevy logo.
|
|
|
|
#[derive(Resource)]
|
|
|
|
struct DragOperation(Vec2);
|
|
|
|
|
|
|
|
/// Marker component for the instructions text entity.
|
|
|
|
#[derive(Component)]
|
|
|
|
struct InstructionsText;
|
|
|
|
|
|
|
|
/// Marker component for the Bevy logo entity.
|
|
|
|
#[derive(Component)]
|
|
|
|
struct BevyLogo;
|
|
|
|
|
|
|
|
/// Component for the moving pupil entity (the moving part of the googly eye).
|
|
|
|
#[derive(Component)]
|
|
|
|
struct Pupil {
|
|
|
|
/// Radius of the eye containing the pupil.
|
|
|
|
eye_radius: f32,
|
|
|
|
/// Radius of the pupil.
|
|
|
|
pupil_radius: f32,
|
|
|
|
/// Current velocity of the pupil.
|
|
|
|
velocity: Vec2,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dimensions are based on: assets/branding/icon.png
|
|
|
|
// Bevy logo radius
|
|
|
|
const BEVY_LOGO_RADIUS: f32 = 128.0;
|
|
|
|
// Birds' eyes x y (offset from the origin) and radius
|
|
|
|
// These values are manually determined from the logo image
|
|
|
|
const BIRDS_EYES: [(f32, f32, f32); 3] = [
|
|
|
|
(145.0 - 128.0, -(56.0 - 128.0), 12.0),
|
|
|
|
(198.0 - 128.0, -(87.0 - 128.0), 10.0),
|
|
|
|
(222.0 - 128.0, -(140.0 - 128.0), 8.0),
|
|
|
|
];
|
|
|
|
|
|
|
|
const WINDOW_CLEAR_COLOR: Color = Color::srgb(0.2, 0.2, 0.2);
|
|
|
|
|
|
|
|
/// Spawn the scene
|
|
|
|
fn setup(
|
|
|
|
mut commands: Commands,
|
|
|
|
asset_server: Res<AssetServer>,
|
|
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
|
|
) {
|
|
|
|
// Spawn a 2D camera
|
2024-10-05 01:59:52 +00:00
|
|
|
commands.spawn(Camera2d);
|
2024-03-06 22:21:41 +00:00
|
|
|
|
|
|
|
// Spawn the text instructions
|
|
|
|
let font = asset_server.load("fonts/FiraSans-Bold.ttf");
|
2024-10-13 17:06:22 +00:00
|
|
|
let text_style = TextFont {
|
2024-03-06 22:21:41 +00:00
|
|
|
font: font.clone(),
|
2024-09-16 23:14:37 +00:00
|
|
|
font_size: 25.0,
|
2024-05-31 16:41:27 +00:00
|
|
|
..default()
|
2024-03-06 22:21:41 +00:00
|
|
|
};
|
|
|
|
commands.spawn((
|
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
|
|
|
Text2d::new("Press Space to play on your desktop! Press it again to return.\nRight click Bevy logo to exit."),
|
|
|
|
text_style.clone(),
|
|
|
|
Transform::from_xyz(0.0, -300.0, 100.0),
|
2024-03-06 22:21:41 +00:00
|
|
|
InstructionsText,
|
|
|
|
));
|
|
|
|
|
|
|
|
// Create a circle mesh. We will reuse this mesh for all our circles.
|
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
|
|
|
let circle = meshes.add(Circle { radius: 1.0 });
|
2024-03-06 22:21:41 +00:00
|
|
|
// Create the different materials we will use for each part of the eyes. For this demo they are basic [`ColorMaterial`]s.
|
|
|
|
let outline_material = materials.add(Color::BLACK);
|
|
|
|
let sclera_material = materials.add(Color::WHITE);
|
|
|
|
let pupil_material = materials.add(Color::srgb(0.2, 0.2, 0.2));
|
|
|
|
let pupil_highlight_material = materials.add(Color::srgba(1.0, 1.0, 1.0, 0.2));
|
|
|
|
|
|
|
|
// Spawn the Bevy logo sprite
|
|
|
|
commands
|
|
|
|
.spawn((
|
2024-10-09 16:17:26 +00:00
|
|
|
Sprite::from_image(asset_server.load("branding/icon.png")),
|
2024-03-06 22:21:41 +00:00
|
|
|
BevyLogo,
|
|
|
|
))
|
|
|
|
.with_children(|commands| {
|
|
|
|
// For each bird eye
|
|
|
|
for (x, y, radius) in BIRDS_EYES {
|
|
|
|
// eye outline
|
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
|
|
|
commands.spawn((
|
|
|
|
Mesh2d(circle.clone()),
|
|
|
|
MeshMaterial2d(outline_material.clone()),
|
|
|
|
Transform::from_xyz(x, y - 1.0, 1.0)
|
2024-03-06 22:21:41 +00:00
|
|
|
.with_scale(Vec2::splat(radius + 2.0).extend(1.0)),
|
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
|
|
|
));
|
2024-03-06 22:21:41 +00:00
|
|
|
|
|
|
|
// sclera
|
|
|
|
commands
|
|
|
|
.spawn(SpatialBundle::from_transform(Transform::from_xyz(
|
|
|
|
x, y, 2.0,
|
|
|
|
)))
|
|
|
|
.with_children(|commands| {
|
|
|
|
// sclera
|
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
|
|
|
commands.spawn((
|
|
|
|
Mesh2d(circle.clone()),
|
|
|
|
MeshMaterial2d(sclera_material.clone()),
|
|
|
|
Transform::from_scale(Vec3::new(radius, radius, 0.0)),
|
|
|
|
));
|
2024-03-06 22:21:41 +00:00
|
|
|
|
|
|
|
let pupil_radius = radius * 0.6;
|
|
|
|
let pupil_highlight_radius = radius * 0.3;
|
|
|
|
let pupil_highlight_offset = radius * 0.3;
|
|
|
|
// pupil
|
|
|
|
commands
|
|
|
|
.spawn((
|
|
|
|
SpatialBundle::from_transform(Transform::from_xyz(0.0, 0.0, 1.0)),
|
|
|
|
Pupil {
|
|
|
|
eye_radius: radius,
|
|
|
|
pupil_radius,
|
|
|
|
velocity: Vec2::ZERO,
|
|
|
|
},
|
|
|
|
))
|
|
|
|
.with_children(|commands| {
|
|
|
|
// pupil main
|
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
|
|
|
commands.spawn((
|
|
|
|
Mesh2d(circle.clone()),
|
|
|
|
MeshMaterial2d(pupil_material.clone()),
|
|
|
|
Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::new(
|
|
|
|
pupil_radius,
|
|
|
|
pupil_radius,
|
|
|
|
1.0,
|
|
|
|
)),
|
|
|
|
));
|
2024-03-06 22:21:41 +00:00
|
|
|
|
|
|
|
// pupil highlight
|
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
|
|
|
commands.spawn((
|
|
|
|
Mesh2d(circle.clone()),
|
|
|
|
MeshMaterial2d(pupil_highlight_material.clone()),
|
|
|
|
Transform::from_xyz(
|
2024-03-06 22:21:41 +00:00
|
|
|
-pupil_highlight_offset,
|
|
|
|
pupil_highlight_offset,
|
|
|
|
1.0,
|
|
|
|
)
|
|
|
|
.with_scale(Vec3::new(
|
|
|
|
pupil_highlight_radius,
|
|
|
|
pupil_highlight_radius,
|
|
|
|
1.0,
|
|
|
|
)),
|
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
|
|
|
));
|
2024-03-06 22:21:41 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Project the cursor into the world coordinates and store it in a resource for easy use
|
|
|
|
fn get_cursor_world_pos(
|
|
|
|
mut cursor_world_pos: ResMut<CursorWorldPos>,
|
|
|
|
q_primary_window: Query<&Window, With<PrimaryWindow>>,
|
|
|
|
q_camera: Query<(&Camera, &GlobalTransform)>,
|
|
|
|
) {
|
|
|
|
let primary_window = q_primary_window.single();
|
|
|
|
let (main_camera, main_camera_transform) = q_camera.single();
|
|
|
|
// Get the cursor position in the world
|
2024-09-03 19:45:15 +00:00
|
|
|
cursor_world_pos.0 = primary_window.cursor_position().and_then(|cursor_pos| {
|
|
|
|
main_camera
|
|
|
|
.viewport_to_world_2d(main_camera_transform, cursor_pos)
|
|
|
|
.ok()
|
|
|
|
});
|
2024-03-06 22:21:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Update whether the window is clickable or not
|
|
|
|
fn update_cursor_hit_test(
|
|
|
|
cursor_world_pos: Res<CursorWorldPos>,
|
|
|
|
mut q_primary_window: Query<&mut Window, With<PrimaryWindow>>,
|
|
|
|
q_bevy_logo: Query<&Transform, With<BevyLogo>>,
|
|
|
|
) {
|
|
|
|
let mut primary_window = q_primary_window.single_mut();
|
|
|
|
|
|
|
|
// If the window has decorations (e.g. a border) then it should be clickable
|
|
|
|
if primary_window.decorations {
|
2024-08-12 15:49:03 +00:00
|
|
|
primary_window.cursor_options.hit_test = true;
|
2024-03-06 22:21:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the cursor is not within the window we don't need to update whether the window is clickable or not
|
|
|
|
let Some(cursor_world_pos) = cursor_world_pos.0 else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
// If the cursor is within the radius of the Bevy logo make the window clickable otherwise the window is not clickable
|
|
|
|
let bevy_logo_transform = q_bevy_logo.single();
|
2024-08-12 15:49:03 +00:00
|
|
|
primary_window.cursor_options.hit_test = bevy_logo_transform
|
2024-03-06 22:21:41 +00:00
|
|
|
.translation
|
|
|
|
.truncate()
|
|
|
|
.distance(cursor_world_pos)
|
|
|
|
< BEVY_LOGO_RADIUS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Start the drag operation and record the offset we started dragging from
|
|
|
|
fn start_drag(
|
|
|
|
mut commands: Commands,
|
|
|
|
cursor_world_pos: Res<CursorWorldPos>,
|
|
|
|
q_bevy_logo: Query<&Transform, With<BevyLogo>>,
|
|
|
|
) {
|
|
|
|
// If the cursor is not within the primary window skip this system
|
|
|
|
let Some(cursor_world_pos) = cursor_world_pos.0 else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get the offset from the cursor to the Bevy logo sprite
|
|
|
|
let bevy_logo_transform = q_bevy_logo.single();
|
|
|
|
let drag_offset = bevy_logo_transform.translation.truncate() - cursor_world_pos;
|
|
|
|
|
|
|
|
// If the cursor is within the Bevy logo radius start the drag operation and remember the offset of the cursor from the origin
|
|
|
|
if drag_offset.length() < BEVY_LOGO_RADIUS {
|
|
|
|
commands.insert_resource(DragOperation(drag_offset));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Stop the current drag operation
|
|
|
|
fn end_drag(mut commands: Commands) {
|
|
|
|
commands.remove_resource::<DragOperation>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Drag the Bevy logo
|
|
|
|
fn drag(
|
|
|
|
drag_offset: Res<DragOperation>,
|
|
|
|
cursor_world_pos: Res<CursorWorldPos>,
|
|
|
|
time: Res<Time>,
|
|
|
|
mut q_bevy_logo: Query<&mut Transform, With<BevyLogo>>,
|
|
|
|
mut q_pupils: Query<&mut Pupil>,
|
|
|
|
) {
|
|
|
|
// If the cursor is not within the primary window skip this system
|
|
|
|
let Some(cursor_world_pos) = cursor_world_pos.0 else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get the current Bevy logo transform
|
|
|
|
let mut bevy_transform = q_bevy_logo.single_mut();
|
|
|
|
|
|
|
|
// Calculate the new translation of the Bevy logo based on cursor and drag offset
|
|
|
|
let new_translation = cursor_world_pos + drag_offset.0;
|
|
|
|
|
|
|
|
// Calculate how fast we are dragging the Bevy logo (unit/second)
|
|
|
|
let drag_velocity =
|
|
|
|
(new_translation - bevy_transform.translation.truncate()) / time.delta_seconds();
|
|
|
|
|
|
|
|
// Update the translation of Bevy logo transform to new translation
|
|
|
|
bevy_transform.translation = new_translation.extend(bevy_transform.translation.z);
|
|
|
|
|
|
|
|
// Add the cursor drag velocity in the opposite direction to each pupil.
|
|
|
|
// Remember pupils are using local coordinates to move. So when the Bevy logo moves right they need to move left to
|
|
|
|
// simulate inertia, otherwise they will move fixed to the parent.
|
|
|
|
for mut pupil in &mut q_pupils {
|
|
|
|
pupil.velocity -= drag_velocity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Quit when the user right clicks the Bevy logo
|
|
|
|
fn quit(
|
|
|
|
cursor_world_pos: Res<CursorWorldPos>,
|
|
|
|
mut app_exit: EventWriter<AppExit>,
|
|
|
|
q_bevy_logo: Query<&Transform, With<BevyLogo>>,
|
|
|
|
) {
|
|
|
|
// If the cursor is not within the primary window skip this system
|
|
|
|
let Some(cursor_world_pos) = cursor_world_pos.0 else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
// If the cursor is within the Bevy logo radius send the [`AppExit`] event to quit the app
|
|
|
|
let bevy_logo_transform = q_bevy_logo.single();
|
|
|
|
if bevy_logo_transform
|
|
|
|
.translation
|
|
|
|
.truncate()
|
|
|
|
.distance(cursor_world_pos)
|
|
|
|
< BEVY_LOGO_RADIUS
|
|
|
|
{
|
2024-04-22 16:48:18 +00:00
|
|
|
app_exit.send(AppExit::Success);
|
2024-03-06 22:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Enable transparency for the window and make it on top
|
|
|
|
fn toggle_transparency(
|
|
|
|
mut commands: Commands,
|
|
|
|
mut window_transparency: ResMut<WindowTransparency>,
|
|
|
|
mut q_instructions_text: Query<&mut Visibility, With<InstructionsText>>,
|
|
|
|
mut q_primary_window: Query<&mut Window, With<PrimaryWindow>>,
|
|
|
|
) {
|
|
|
|
// Toggle the window transparency resource
|
|
|
|
window_transparency.0 = !window_transparency.0;
|
|
|
|
|
|
|
|
// Show or hide the instructions text
|
|
|
|
for mut visibility in &mut q_instructions_text {
|
|
|
|
*visibility = if window_transparency.0 {
|
|
|
|
Visibility::Hidden
|
|
|
|
} else {
|
|
|
|
Visibility::Visible
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the primary window's decorations (e.g. borders), make it always on top of other desktop windows, and set the clear color to transparent
|
|
|
|
// only if window transparency is enabled
|
|
|
|
let mut window = q_primary_window.single_mut();
|
|
|
|
let clear_color;
|
|
|
|
(window.decorations, window.window_level, clear_color) = if window_transparency.0 {
|
|
|
|
(false, WindowLevel::AlwaysOnTop, Color::NONE)
|
|
|
|
} else {
|
|
|
|
(true, WindowLevel::Normal, WINDOW_CLEAR_COLOR)
|
|
|
|
};
|
|
|
|
|
|
|
|
// Set the clear color
|
|
|
|
commands.insert_resource(ClearColor(clear_color));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Move the pupils and bounce them around
|
|
|
|
fn move_pupils(time: Res<Time>, mut q_pupils: Query<(&mut Pupil, &mut Transform)>) {
|
|
|
|
for (mut pupil, mut transform) in &mut q_pupils {
|
|
|
|
// The wiggle radius is how much the pupil can move within the eye
|
|
|
|
let wiggle_radius = pupil.eye_radius - pupil.pupil_radius;
|
|
|
|
// Store the Z component
|
|
|
|
let z = transform.translation.z;
|
|
|
|
// Truncate the Z component to make the calculations be on [`Vec2`]
|
|
|
|
let mut translation = transform.translation.truncate();
|
|
|
|
// Decay the pupil velocity
|
2024-09-16 23:28:12 +00:00
|
|
|
pupil.velocity *= ops::powf(0.04f32, time.delta_seconds());
|
2024-03-06 22:21:41 +00:00
|
|
|
// Move the pupil
|
|
|
|
translation += pupil.velocity * time.delta_seconds();
|
|
|
|
// If the pupil hit the outside border of the eye, limit the translation to be within the wiggle radius and invert the velocity.
|
|
|
|
// This is not physically accurate but it's good enough for the googly eyes effect.
|
|
|
|
if translation.length() > wiggle_radius {
|
|
|
|
translation = translation.normalize() * wiggle_radius;
|
|
|
|
// Invert and decrease the velocity of the pupil when it bounces
|
|
|
|
pupil.velocity *= -0.75;
|
|
|
|
}
|
|
|
|
// Update the entity transform with the new translation after reading the Z component
|
|
|
|
transform.translation = translation.extend(z);
|
|
|
|
}
|
|
|
|
}
|