From 6af7c44eeb5eb6b84deba98cd4a48d2406291576 Mon Sep 17 00:00:00 2001 From: Feisal Schlee Date: Fri, 23 Aug 2024 15:17:28 +0200 Subject: [PATCH 1/2] Create 3d variation of the existing drag_and_drop example --- examples/drag_and_drop3d.rs | 113 ++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 examples/drag_and_drop3d.rs diff --git a/examples/drag_and_drop3d.rs b/examples/drag_and_drop3d.rs new file mode 100644 index 00000000..7b84a68e --- /dev/null +++ b/examples/drag_and_drop3d.rs @@ -0,0 +1,113 @@ +use std::f32::consts::FRAC_PI_2; +use bevy::prelude::*; +use bevy_mod_picking::prelude::*; + +fn main() { + let mut app = App::new(); + app.add_plugins(( + DefaultPlugins.set(low_latency_window_plugin()), + DefaultPickingPlugins, + SpinPlugin, + )) + .insert_resource(DebugPickingMode::Normal) + .add_systems(Startup, setup); + #[cfg(feature = "backend_egui")] + app.add_plugins(bevy_egui::EguiPlugin); + app.run(); +} + +/// Set up a simple 3D scene +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + // Spawn camera + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 1200.0, -400.0).looking_at(Vec3::ZERO, Vec3::Y), + .. default()}); + // Spawn cubes + for x in -2..=2 { + let z = 0.5 + x as f32 * 0.1; + commands.spawn(( + PbrBundle { + mesh: meshes.add(Cuboid::default()).into(), + transform: Transform::from_xyz(x as f32 * 200.0, 0.0, z) + .with_scale(Vec3::splat(100.)), + material: materials.add(Color::hsl(0.0, 1.0, z)), + ..default() + }, + PickableBundle::default(), // <- Makes the mesh pickable. + On::>::target_insert(Pickable::IGNORE), // Disable picking + On::>::target_insert(Pickable::default()), // Re-enable picking + On::>::run(on_drag), + On::>::commands_mut(|event, commands| { + commands.entity(event.dropped).insert(Spin(FRAC_PI_2)); // Spin dropped entity + commands.entity(event.target).insert(Spin(-FRAC_PI_2)); // Spin dropped-on entity + }), + )); + } +} + +fn on_drag( + listener: Listener>, + mut transforms: Query<(&mut Transform, &GlobalTransform)>, + windows: Query>, + cameras: Query<(&Camera, &GlobalTransform)>, +) { + let Ok(primary_window) = windows.get_single() else { + return; + }; + let target = &listener.pointer_location.target; + let Some((cam, cam_trans)) = cameras.iter().find(|(c, _)| { + c.is_active && c.target.normalize(Some(primary_window)).as_ref() == Some(target) + }) else { + return; + }; + + let Ok((mut t, gt)) = transforms.get_mut(listener.target) else { + return; + }; + let Some(prev) = cam.world_to_viewport(cam_trans, gt.translation()) else { + return; + }; + + let new = prev + listener.event.delta; + let Some(ray) = cam.viewport_to_world(cam_trans, new) else { + return; + }; + if let Some(dist) = ray.intersect_plane(Vec3::Y, InfinitePlane3d { normal: Dir3::Y }) { + t.translation += ray.get_point(dist) - gt.translation(); + } +} + +pub struct SpinPlugin; + +impl Plugin for SpinPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, spin) + .add_systems(Update, spin_cleanup); + } +} + +#[derive(Component)] +struct Spin(f32); + +fn spin(mut square: Query<(&mut Spin, &mut Transform)>) { + for (mut spin, mut transform) in square.iter_mut() { + transform.rotation = Quat::from_rotation_z(spin.0); + let delta = -spin.0.clamp(-1.0, 1.0) * 0.05; + spin.0 += delta; + } +} + +fn spin_cleanup(mut square: Query<(Entity, &Spin, &mut Transform)>, mut commands: Commands) { + for (entity, spin, mut transform) in square.iter_mut() { + if spin.0.abs().le(&0.001) { + transform.rotation = Quat::default(); // <- reset the rotation to zero when it's visually neglible + commands.entity(entity).remove::(); // <- remove the component so it's stopped updating + } + } +} + + From 693a93d79c24f3625c9b98877e9c016d61980e49 Mon Sep 17 00:00:00 2001 From: Feisal Schlee Date: Fri, 23 Aug 2024 15:29:54 +0200 Subject: [PATCH 2/2] cargo fmt --- examples/drag_and_drop3d.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/drag_and_drop3d.rs b/examples/drag_and_drop3d.rs index 7b84a68e..993ab42c 100644 --- a/examples/drag_and_drop3d.rs +++ b/examples/drag_and_drop3d.rs @@ -1,6 +1,6 @@ -use std::f32::consts::FRAC_PI_2; use bevy::prelude::*; use bevy_mod_picking::prelude::*; +use std::f32::consts::FRAC_PI_2; fn main() { let mut app = App::new(); @@ -23,9 +23,10 @@ fn setup( mut materials: ResMut>, ) { // Spawn camera - commands.spawn(Camera3dBundle { - transform: Transform::from_xyz(0.0, 1200.0, -400.0).looking_at(Vec3::ZERO, Vec3::Y), - .. default()}); + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 1200.0, -400.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); // Spawn cubes for x in -2..=2 { let z = 0.5 + x as f32 * 0.1; @@ -109,5 +110,3 @@ fn spin_cleanup(mut square: Query<(Entity, &Spin, &mut Transform)>, mut commands } } } - -