Skip to content

Commit

Permalink
Rework the example slightly
Browse files Browse the repository at this point in the history
Co-authored-by: Rob Parrett <robparrett@gmail.com>
  • Loading branch information
tim-blackbird and rparrett committed Mar 25, 2023
1 parent c786a43 commit 993ac28
Showing 1 changed file with 20 additions and 49 deletions.
69 changes: 20 additions & 49 deletions examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,67 @@
//! This example demonstrates how to use the `Camera::viewport_to_world` method.

use bevy::{pbr::CascadeShadowConfigBuilder, prelude::*};
use bevy::prelude::*;

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

fn move_cube(
camera_query: Query<(&Camera, &GlobalTransform)>,
mut cube_query: Query<&mut Transform, With<Cube>>,
ground_query: Query<&Transform, With<Ground>>,
windows: Query<&Window>,
input: Res<Input<MouseButton>>,
mut gizmos: Gizmos,
) {
let (camera, camera_transform) = camera_query.single();
let mut transform = cube_query.single_mut();

if !input.pressed(MouseButton::Left) {
return;
}
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; };

let Some(distance) = ray.intersect_plane(Vec3::ZERO, Vec3::Y) 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);
transform.translation = point + Vec3::Y * 0.5;

// Draw a line poking out of the ground plane at that position.
gizmos.ray(point, ground.up(), Color::BLACK);
}

#[derive(Component)]
struct Cube;
struct Ground;

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane {
size: 50.0,
subdivisions: 0,
})),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});

// cube
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
mesh: meshes.add(Mesh::from(shape::Plane {
size: 20.0,
subdivisions: 0,
})),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
},
Cube,
Ground,
));

// light
commands.spawn(DirectionalLightBundle {
transform: Transform::from_translation(Vec3::ONE).looking_at(Vec3::ZERO, Vec3::Y),
directional_light: DirectionalLight {
shadows_enabled: true,
..default()
},
cascade_shadow_config: CascadeShadowConfigBuilder {
maximum_distance: 15.,
..default()
}
.into(),
..default()
});

// camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 6.0, 6.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(15.0, 5.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});

// UI
commands.spawn(TextBundle::from_section(
"Press the left mouse button to reposition the box.",
TextStyle {
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
font_size: 32.,
..default()
},
));
}

0 comments on commit 993ac28

Please sign in to comment.