From 1c90ed98cfbaab930e8e3e89a9d570311a860cb7 Mon Sep 17 00:00:00 2001 From: Nicola Guerrera Date: Thu, 2 Mar 2023 16:03:29 +0100 Subject: [PATCH] make the hex launcher grabbable --- examples/app_grid.rs | 26 -------------------- examples/hexagon_launcher.rs | 39 ++++++++++++++++++++++-------- src/protostar.rs | 46 +++++++++++++++++++----------------- 3 files changed, 53 insertions(+), 58 deletions(-) diff --git a/examples/app_grid.rs b/examples/app_grid.rs index f892d58..36e55e6 100644 --- a/examples/app_grid.rs +++ b/examples/app_grid.rs @@ -1,5 +1,4 @@ use color_eyre::eyre::Result; -use glam::Quat; use manifest_dir_macros::directory_relative_path; use mint::Vector3; use protostar::{ @@ -8,8 +7,6 @@ use protostar::{ }; use stardust_xr_fusion::{ client::{Client, FrameInfo, RootHandler}, - core::values::Transform, - drawable::{Alignment, Bounds, Text, TextFit, TextStyle}, spatial::Spatial, }; @@ -72,7 +69,6 @@ impl RootHandler for AppGrid { } } struct App { - _text: Text, _desktop_file: DesktopFile, protostar: ProtoStar, } @@ -82,33 +78,11 @@ impl App { parent: &Spatial, position: impl Into>, desktop_file: DesktopFile, - //style: TextStyle, ) -> Option { let position = position.into(); - let style = TextStyle { - character_height: APP_SIZE * 0.1, - bounds: Some(Bounds { - bounds: [APP_SIZE; 2].into(), - fit: TextFit::Wrap, - bounds_align: Alignment::XCenter | Alignment::YCenter, - }), - text_align: Alignment::XCenter | Alignment::YCenter, - ..Default::default() - }; let protostar = ProtoStar::create_from_desktop_file(parent, position, desktop_file.clone()).ok()?; - let text = Text::create( - protostar.content_parent(), - Transform::from_position_rotation( - [0.0, 0.0, APP_SIZE / 2.0], - Quat::from_rotation_y(3.14), - ), - desktop_file.name.as_deref().unwrap_or("Unknown"), - style, - ) - .unwrap(); Some(App { - _text: text, _desktop_file: desktop_file, protostar, }) diff --git a/examples/hexagon_launcher.rs b/examples/hexagon_launcher.rs index 9fd04ae..318c68e 100644 --- a/examples/hexagon_launcher.rs +++ b/examples/hexagon_launcher.rs @@ -10,10 +10,11 @@ use stardust_xr_fusion::{ client::{Client, FrameInfo, RootHandler}, core::values::Transform, drawable::{MaterialParameter, Model, ResourceID}, + fields::BoxField, node::NodeError, spatial::Spatial, }; -use stardust_xr_molecules::touch_plane::TouchPlane; +use stardust_xr_molecules::{touch_plane::TouchPlane, GrabData, Grabbable}; use std::f32::consts::PI; use tween::TweenTime; @@ -110,7 +111,7 @@ impl AppHexGrid { }; apps.push( App::new( - client.get_root(), + button.grabbable.content_parent(), hex.get_coords(), desktop_files.pop().unwrap(), ) @@ -126,7 +127,7 @@ impl AppHexGrid { } impl RootHandler for AppHexGrid { fn frame(&mut self, info: FrameInfo) { - self.button.touch_plane.update(); + self.button.frame(info); if self.button.touch_plane.touch_started() { let color = [0.0, 1.0, 0.0, 1.0]; self.button @@ -176,30 +177,48 @@ impl RootHandler for App { struct Button { touch_plane: TouchPlane, + grabbable: Grabbable, model: Model, } impl Button { fn new(client: &Client) -> Result { - let touch_plane = TouchPlane::new( + let field = BoxField::create(client.get_root(), Transform::default(), [APP_SIZE; 3])?; + let grabbable = Grabbable::new( client.get_root(), Transform::default(), + &field, + GrabData { + max_distance: 0.01, + ..Default::default() + }, + )?; + field.set_spatial_parent(grabbable.content_parent())?; + let touch_plane = TouchPlane::new( + grabbable.content_parent(), + Transform::default(), [(APP_SIZE + PADDING) / 2.0; 2], (APP_SIZE + PADDING) / 2.0, )?; + let model = Model::create( - client.get_root(), + grabbable.content_parent(), Transform::from_rotation_scale( Quat::from_rotation_x(PI / 2.0) * Quat::from_rotation_y(PI), [0.03, 0.03, 0.03], ), &ResourceID::new_namespaced("protostar", "hexagon/hexagon"), )?; - model - .set_material_parameter(1, "color", MaterialParameter::Color([0.0, 0.0, 1.0, 1.0])) - .unwrap(); - Ok(Button { touch_plane, model }) + model.set_material_parameter(1, "color", MaterialParameter::Color([0.0, 0.0, 1.0, 1.0]))?; + Ok(Button { + touch_plane, + grabbable, + model, + }) } } impl RootHandler for Button { - fn frame(&mut self, _info: FrameInfo) {} + fn frame(&mut self, info: FrameInfo) { + self.touch_plane.update(); + self.grabbable.update(&info); + } } diff --git a/src/protostar.rs b/src/protostar.rs index 0706549..71e773a 100644 --- a/src/protostar.rs +++ b/src/protostar.rs @@ -5,18 +5,18 @@ use mint::Vector3; use nix::unistd::setsid; use regex::Regex; use stardust_xr_fusion::{ - client::{Client, FrameInfo, RootHandler}, + client::{FrameInfo, RootHandler}, core::values::Transform, - drawable::{Alignment, MaterialParameter, Model, ResourceID, Text, TextStyle, Bounds, TextFit}, + drawable::{Alignment, Bounds, MaterialParameter, Model, ResourceID, Text, TextFit, TextStyle}, fields::BoxField, node::NodeType, spatial::Spatial, startup_settings::StartupSettings, }; use stardust_xr_molecules::{GrabData, Grabbable}; +use std::f32::consts::PI; use std::os::unix::process::CommandExt; use std::process::{Command, Stdio}; -use std::{f32::consts::PI, sync::Arc}; use tween::{QuartInOut, Tweener}; const MODEL_SCALE: f32 = 0.03; @@ -57,7 +57,7 @@ fn model_from_icon(parent: &Spatial, icon: &Icon) -> Result { } pub struct ProtoStar { - client: Arc, + parent: Spatial, position: Vector3, grabbable: Grabbable, field: BoxField, @@ -112,14 +112,7 @@ impl ProtoStar { execute_command: String, ) -> Result { let position = position.into(); - let field = BoxField::create( - parent, - Transform::default(), - match icon.as_ref() { - Some(_) => [0.05, 0.0665, 0.005], - _ => [0.05; 3], - }, - )?; + let field = BoxField::create(parent, Transform::default(), [MODEL_SCALE * 2.0; 3])?; let grabbable = Grabbable::new( parent, Transform::from_position(position), @@ -129,6 +122,7 @@ impl ProtoStar { ..Default::default() }, )?; + grabbable.content_parent().set_spatial_parent(parent)?; field.set_spatial_parent(grabbable.content_parent())?; let icon = icon .map(|i| model_from_icon(grabbable.content_parent(), &i)) @@ -144,8 +138,8 @@ impl ProtoStar { })?; let label_style = TextStyle { - character_height: MODEL_SCALE*4.0 , - bounds: Some(Bounds{ + character_height: MODEL_SCALE * 4.0, + bounds: Some(Bounds { bounds: [1.0; 2].into(), fit: TextFit::Wrap, bounds_align: Alignment::XCenter | Alignment::YCenter, @@ -157,7 +151,7 @@ impl ProtoStar { Text::create( &icon, Transform::from_position_rotation( - [0.0, 0.1, -(MODEL_SCALE*8.0)], + [0.0, 0.1, -(MODEL_SCALE * 8.0)], Quat::from_rotation_x(PI * 0.5), ), name, @@ -166,7 +160,7 @@ impl ProtoStar { .ok() }); Ok(ProtoStar { - client: parent.client()?, + parent: parent.alias(), position, grabbable, field, @@ -204,7 +198,7 @@ impl RootHandler for ProtoStar { self.grabbable .content_parent() .set_position( - Some(self.client.get_root()), + Some(&self.parent), [ self.position.x * scale, self.position.y * scale, @@ -225,9 +219,13 @@ impl RootHandler for ProtoStar { let scale = grabbable_shrink.move_by(info.delta); self.grabbable .content_parent() - .set_scale(None, Vector3::from([scale; 3])) + .set_scale(Some(&self.parent), Vector3::from([scale; 3])) .unwrap(); } else { + self.grabbable + .content_parent() + .set_spatial_parent(&self.parent) + .unwrap(); if self.currently_shown { self.grabbable_grow = Some(Tweener::quart_in_out(0.0001, 1.0, 0.25)); self.grabbable.cancel_angular_velocity(); @@ -236,11 +234,11 @@ impl RootHandler for ProtoStar { self.grabbable_shrink = None; self.grabbable .content_parent() - .set_position(Some(self.client.get_root()), self.position) + .set_position(Some(&self.parent), self.position) .unwrap(); self.grabbable .content_parent() - .set_rotation(Some(self.client.get_root()), Quat::default()) + .set_rotation(Some(&self.parent), Quat::default()) .unwrap(); self.icon .set_rotation( @@ -254,9 +252,13 @@ impl RootHandler for ProtoStar { let scale = grabbable_grow.move_by(info.delta); self.grabbable .content_parent() - .set_scale(None, Vector3::from([scale; 3])) + .set_scale(Some(&self.parent), Vector3::from([scale; 3])) .unwrap(); } else { + self.grabbable + .content_parent() + .set_spatial_parent(&self.parent) + .unwrap(); self.grabbable_grow = None; } } else if self.grabbable.grab_action().actor_stopped() { @@ -268,7 +270,7 @@ impl RootHandler for ProtoStar { let distance_future = self .grabbable .content_parent() - .get_position_rotation_scale(self.client.get_root()) + .get_position_rotation_scale(&self.parent) .unwrap(); let executable = self.execute_command.clone();