Skip to content

Commit

Permalink
Add example for Camera::viewport_to_world (bevyengine#7179)
Browse files Browse the repository at this point in the history
Fixes bevyengine#7177

---------

Co-authored-by: Rob Parrett <[email protected]>
  • Loading branch information
tim-blackbird and rparrett authored Sep 11, 2023
1 parent 0c44de7 commit f3ab38a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ description = "Changes the transform of a sprite"
category = "2D Rendering"
wasm = true

[[example]]
name = "2d_viewport_to_world"
path = "examples/2d/2d_viewport_to_world.rs"

[package.metadata.example.2d_viewport_to_world]
name = "2D Viewport To World"
description = "Demonstrates how to use the `Camera::viewport_to_world_2d` method"
category = "2D Rendering"
wasm = true

[[example]]
name = "rotation"
path = "examples/2d/rotation.rs"
Expand Down Expand Up @@ -467,6 +477,17 @@ description = "A scene showcasing the built-in 3D shapes"
category = "3D Rendering"
wasm = true

[[example]]
name = "3d_viewport_to_world"
path = "examples/3d/3d_viewport_to_world.rs"
doc-scrape-examples = true

[package.metadata.example.3d_viewport_to_world]
name = "3D Viewport To World"
description = "Demonstrates how to use the `Camera::viewport_to_world` method"
category = "3D Rendering"
wasm = true

[[example]]
name = "generate_custom_mesh"
path = "examples/3d/generate_custom_mesh.rs"
Expand Down
34 changes: 34 additions & 0 deletions examples/2d/2d_viewport_to_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! This example demonstrates how to use the `Camera::viewport_to_world_2d` method.
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, draw_cursor)
.run();
}

fn draw_cursor(
camera_query: Query<(&Camera, &GlobalTransform)>,
windows: Query<&Window>,
mut gizmos: Gizmos,
) {
let (camera, camera_transform) = camera_query.single();

let Some(cursor_position) = windows.single().cursor_position() else {
return;
};

// Calculate a world position based on the cursor's position.
let Some(point) = camera.viewport_to_world_2d(camera_transform, cursor_position) else {
return;
};

gizmos.circle_2d(point, 10., Color::WHITE);
}

fn setup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
}
70 changes: 70 additions & 0 deletions examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! This example demonstrates how to use the `Camera::viewport_to_world` method.
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, draw_cursor)
.run();
}

fn draw_cursor(
camera_query: Query<(&Camera, &GlobalTransform)>,
ground_query: Query<&GlobalTransform, With<Ground>>,
windows: Query<&Window>,
mut gizmos: Gizmos,
) {
let (camera, camera_transform) = camera_query.single();
let ground = ground_query.single();

let Some(cursor_position) = windows.single().cursor_position() else {
return;
};

// Calculate a ray pointing from the camera into the world based on the cursor's position.
let Some(ray) = camera.viewport_to_world(camera_transform, cursor_position) else {
return;
};

// Calculate if and where the ray is hitting the ground plane.
let Some(distance) = ray.intersect_plane(ground.translation(), ground.up()) else {
return;
};
let point = ray.get_point(distance);

// Draw a circle just above the ground plane at that position.
gizmos.circle(point + ground.up() * 0.01, ground.up(), 0.2, Color::WHITE);
}

#[derive(Component)]
struct Ground;

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// plane
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Plane::from_size(20.).into()),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
},
Ground,
));

// light
commands.spawn(DirectionalLightBundle {
transform: Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

// camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(15.0, 5.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
}
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ Example | Description
[2D Gizmos](../examples/2d/2d_gizmos.rs) | A scene showcasing 2D gizmos
[2D Rotation](../examples/2d/rotation.rs) | Demonstrates rotating entities in 2D with quaternions
[2D Shapes](../examples/2d/2d_shapes.rs) | Renders a rectangle, circle, and hexagon
[2D Viewport To World](../examples/2d/2d_viewport_to_world.rs) | Demonstrates how to use the `Camera::viewport_to_world_2d` method
[Custom glTF vertex attribute 2D](../examples/2d/custom_gltf_vertex_attribute.rs) | Renders a glTF mesh in 2D with a custom vertex attribute
[Manual Mesh 2D](../examples/2d/mesh2d_manual.rs) | Renders a custom mesh "manually" with "mid-level" renderer apis
[Mesh 2D](../examples/2d/mesh2d.rs) | Renders a 2d mesh
Expand All @@ -116,6 +117,7 @@ Example | Description
[3D Gizmos](../examples/3d/3d_gizmos.rs) | A scene showcasing 3D gizmos
[3D Scene](../examples/3d/3d_scene.rs) | Simple 3D scene with basic shapes and lighting
[3D Shapes](../examples/3d/3d_shapes.rs) | A scene showcasing the built-in 3D shapes
[3D Viewport To World](../examples/3d/3d_viewport_to_world.rs) | Demonstrates how to use the `Camera::viewport_to_world` method
[Anti-aliasing](../examples/3d/anti_aliasing.rs) | Compares different anti-aliasing methods
[Atmospheric Fog](../examples/3d/atmospheric_fog.rs) | A scene showcasing the atmospheric fog effect
[Blend Modes](../examples/3d/blend_modes.rs) | Showcases different blend modes
Expand Down

0 comments on commit f3ab38a

Please sign in to comment.