From 8091ad8e886bfe9b950d7d9ebba0114f76cd0f51 Mon Sep 17 00:00:00 2001 From: MalekiRe Date: Fri, 1 Sep 2023 17:34:44 -0700 Subject: [PATCH] added rotation and resizing of objects in flatscreen --- Cargo.lock | 143 +++++++++++++++++++++ Cargo.toml | 4 +- README.md | 2 +- skills/manipulation-flatscreen/Cargo.toml | 15 +++ skills/manipulation-flatscreen/src/main.rs | 123 ++++++++++++++++++ 5 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 skills/manipulation-flatscreen/Cargo.toml create mode 100644 skills/manipulation-flatscreen/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 1ef3289..b4baebd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -498,6 +498,37 @@ dependencies = [ "encase_derive_impl", ] +[[package]] +name = "bevy_eventlistener" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233f729a5a2c7182f89b17c5d603cd604d095ee68d22c81b29be3cd30324f77d" +dependencies = [ + "bevy_eventlistener_core", + "bevy_eventlistener_derive", +] + +[[package]] +name = "bevy_eventlistener_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd344e21cb61878a24169bff3f2e0bc5584df77b06732b5223a13a96a92dfe9" +dependencies = [ + "bevy", +] + +[[package]] +name = "bevy_eventlistener_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "407110082f2a861eb198c254226aa4a24c239fcff235f2aec41b0b0db5e8937f" +dependencies = [ + "bevy_eventlistener_core", + "proc-macro2", + "quote", + "syn 2.0.29", +] + [[package]] name = "bevy_gilrs" version = "0.11.2" @@ -689,6 +720,33 @@ dependencies = [ "bevy", ] +[[package]] +name = "bevy_mod_picking" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce0837727f451ec62dad98a7bd35a8ff929e5a148bb0044122aba02683c09df" +dependencies = [ + "bevy", + "bevy_eventlistener", + "bevy_picking_core", + "bevy_picking_highlight", + "bevy_picking_input", + "bevy_picking_raycast", + "bevy_picking_selection", + "bevy_picking_sprite", + "bevy_picking_ui", +] + +[[package]] +name = "bevy_mod_raycast" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cbc448fc8a8817cbf225f58a58ab45ab87e9d335b66c4c1674fba45f062c822" +dependencies = [ + "bevy", + "crossbeam-channel", +] + [[package]] name = "bevy_pbr" version = "0.11.2" @@ -712,6 +770,81 @@ dependencies = [ "radsort", ] +[[package]] +name = "bevy_picking_core" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b10f159071accb3f17f86b70a2cafed27f96a828f155721d8f82706d5a65af" +dependencies = [ + "bevy", + "bevy_eventlistener", +] + +[[package]] +name = "bevy_picking_highlight" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9127248f32843064b9d58d7126e0155378b7321b80acc53e8aafb0e3a61f2219" +dependencies = [ + "bevy", + "bevy_picking_core", + "bevy_picking_input", + "bevy_picking_selection", +] + +[[package]] +name = "bevy_picking_input" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc165dccadf85856cd713f1dabf5c845c7b6fd56e2c901a53f69f3693c5149" +dependencies = [ + "bevy", + "bevy_picking_core", + "bevy_picking_selection", +] + +[[package]] +name = "bevy_picking_raycast" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f53ba9aee1a3a48e016f4d35b066cca75d2ddd983ad2a0e14ecf92956501a3c" +dependencies = [ + "bevy", + "bevy_mod_raycast", + "bevy_picking_core", +] + +[[package]] +name = "bevy_picking_selection" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61980e57b09ff29b52c2910ba5b4e9bcfe8f9481931e62fd277a16b6ec3390f2" +dependencies = [ + "bevy", + "bevy_eventlistener", + "bevy_picking_core", +] + +[[package]] +name = "bevy_picking_sprite" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179b555e09296ac77280e0c283c4e0f380dc64ddd5a02b5bd1773c00a6a3b9c5" +dependencies = [ + "bevy", + "bevy_picking_core", +] + +[[package]] +name = "bevy_picking_ui" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1533a7723939a1dfad933da76a4cfb0d37eb15abd64519c0db2477f04de1ee8b" +dependencies = [ + "bevy", + "bevy_picking_core", +] + [[package]] name = "bevy_ptr" version = "0.11.2" @@ -2154,6 +2287,16 @@ dependencies = [ "libc", ] +[[package]] +name = "manipulation-flatscreen" +version = "0.0.0" +dependencies = [ + "bevy", + "bevy_mod_picking", + "color-eyre", + "tracing", +] + [[package]] name = "matchers" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 65131fa..d42889b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "skills/cube", "skills/ik", + "skills/manipulation-flatscreen" ] # These settings will apply to all members of the workspace that opt in to them @@ -14,7 +15,8 @@ edition = "2021" rust-version = "1.72.0" [workspace.dependencies] -bevy = "0.11" +bevy = "0.11.2" +bevy_mod_picking = "0.15.0" color-eyre = "0.6" eyre = "0.6" tracing = "0.1" diff --git a/README.md b/README.md index f55bab7..5cb728f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Feel free to add to the following lists: - 📋 Dynamic foveated rendering - 📋 Get tracked positions from SlimeVR/SolarXR - 📋 Laser pointers -- 📋 Resizing and grabbing object +- ✅ Rotating and resize flatscreen - 📋 Friends list ( Social Feature ) - 📋 Avatar list ( Social Feature ) - 📋 Active game worlds ( Social Feature ) diff --git a/skills/manipulation-flatscreen/Cargo.toml b/skills/manipulation-flatscreen/Cargo.toml new file mode 100644 index 0000000..3b3a051 --- /dev/null +++ b/skills/manipulation-flatscreen/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "manipulation-flatscreen" +version.workspace = true +license.workspace = true +repository.workspace = true +edition.workspace = true +rust-version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bevy.workspace = true +color-eyre.workspace = true +tracing.workspace = true +bevy_mod_picking.workspace = true \ No newline at end of file diff --git a/skills/manipulation-flatscreen/src/main.rs b/skills/manipulation-flatscreen/src/main.rs new file mode 100644 index 0000000..4bb3645 --- /dev/null +++ b/skills/manipulation-flatscreen/src/main.rs @@ -0,0 +1,123 @@ +use bevy::{pbr::DirectionalLightShadowMap, prelude::*}; +use bevy::ecs::system::EntityCommands; +use bevy_mod_picking::{DefaultPickingPlugins, PickableBundle}; +use bevy_mod_picking::events::Drag; +use bevy_mod_picking::pointer::PointerButton; +use bevy_mod_picking::prelude::{Click, On, Pointer, RaycastPickCamera, RaycastPickTarget}; +use color_eyre::eyre::Result; +use tracing::info; + +const ASSET_FOLDER: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/"); + +fn main() -> Result<()> { + // Set up nice error messages + color_eyre::install()?; + + info!("Running `manipulation-flatscreen` skill"); + + App::new() + .add_plugins(DefaultPlugins.set(AssetPlugin { + asset_folder: ASSET_FOLDER.to_string(), + ..Default::default() + })) + .add_plugins(DefaultPickingPlugins) + .add_systems(Startup, setup) + .add_systems(Update, animate_light) + .run(); + + Ok(()) +} + +pub fn add_events(entity_commands: &mut EntityCommands) { + entity_commands.insert(( + On::>::target_component_mut::(|drag, transform| { + let delta_y = drag.delta.y; + let mut delta_x = drag.delta.x; + match drag.button { + PointerButton::Primary => { + if drag.pointer_location.position.y < transform.translation.y { + delta_x *= -1.0; + } + + let axis_of_rotation = Vec3::new(delta_y, delta_x, 0.0).normalize_or_zero(); + + // Compute the magnitude of rotation. You can scale this to adjust rotation speed + let rotation_magnitude = (delta_x.powi(2) + delta_y.powi(2)).sqrt() * 0.01; + + // Create quaternion from axis-angle representation + let rotation_quat = Quat::from_axis_angle(axis_of_rotation, rotation_magnitude); + transform.rotation = rotation_quat * transform.rotation; + } + PointerButton::Secondary => { + transform.scale += Vec3::splat((delta_x + delta_y) * 0.01); + } + PointerButton::Middle => { + transform.rotate_local_y((delta_y + delta_x) * 0.01); + } + } + + }), + PickableBundle::default(), // Makes the entity pickable + RaycastPickTarget::default() + )); +} + +fn setup( + assets: Res, + mut meshes: ResMut>, + mut materials: ResMut>, + mut commands: Commands, +) { + info!("Running setup system"); + + // Load assets + let tree_img: Handle = assets.load("tree.png"); + + // Build cube + let mut cube = commands.spawn(PbrBundle { + mesh: meshes.add(shape::Cube::default().into()), + material: materials.add(StandardMaterial { + base_color_texture: Some(tree_img), + ..default() + }), + ..default() + }); + add_events(&mut cube); + + // Build the rest of the scene + commands.spawn(DirectionalLightBundle { + directional_light: DirectionalLight { + shadows_enabled: true, + illuminance: 10000., + ..default() + }, + transform: Transform::from_xyz(8.0, 16.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); + commands.insert_resource(DirectionalLightShadowMap { size: 4096 }); + commands.spawn((Camera3dBundle { + transform: Transform::from_xyz(0.0, 6., 12.0) + .looking_at(Vec3::new(0., 1., 0.), Vec3::Y), + ..default() + + }, RaycastPickCamera::default())); + commands.spawn(PbrBundle { + mesh: meshes.add( + shape::Plane { + size: 10., + subdivisions: 4, + } + .into(), + ), + material: materials.add(Color::MIDNIGHT_BLUE.into()), + transform: Transform::from_xyz(0., 0., 0.), + ..default() + }); +} + +fn animate_light(mut query: Query<&mut Transform, With>) { + for mut t in query.iter_mut() { + let t: &mut Transform = &mut t; + t.rotate_y(0.01); + } +}