From 8c23767a54dcea8c4c036fae70c16b1e38005a13 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Sun, 29 Dec 2024 21:33:27 +0100 Subject: [PATCH] refactor fixup after rebase Signed-off-by: Schmarni --- src/nodes/audio.rs | 15 ++-- src/nodes/items/panel.rs | 4 +- src/objects/input/sk_controller.rs | 105 +++++--------------------- src/objects/input/sk_hand.rs | 116 ++++++++--------------------- src/objects/mod.rs | 2 +- 5 files changed, 62 insertions(+), 180 deletions(-) diff --git a/src/nodes/audio.rs b/src/nodes/audio.rs index 369f748..f3b36fe 100644 --- a/src/nodes/audio.rs +++ b/src/nodes/audio.rs @@ -121,7 +121,9 @@ impl Sound { let sound_arc = SOUND_REGISTRY.add(sound); node.add_aspect_raw(sound_arc.clone()); if let Some(sender) = SPAWN_SOUND_SENDER.get() { - sender.send(sound_arc.clone())?; + sender + .send(sound_arc.clone()) + .map_err(|_| eyre!("Unable to Spawn Audio Node"))?; } Ok(sound_arc) } @@ -139,7 +141,9 @@ impl SoundAspect for Sound { .get() .and_then(|s| Some((s, *sound.entity.get()?))) { - sender.send((entity, SoundAction::Play))? + sender + .send((entity, SoundAction::Play)) + .map_err(|_| eyre!("Unable to Play Audio"))? } Ok(()) } @@ -149,7 +153,9 @@ impl SoundAspect for Sound { .get() .and_then(|s| Some((s, *sound.entity.get()?))) { - sender.send((entity, SoundAction::Stop))? + sender + .send((entity, SoundAction::Stop)) + .map_err(|_| eyre!("Unable to Stop Audio"))? } Ok(()) } @@ -163,8 +169,7 @@ impl Drop for Sound { } } -struct AudioInterface; -impl InterfaceAspect for AudioInterface { +impl InterfaceAspect for Interface { #[doc = "Create a sound node. WAV and MP3 are supported."] fn create_sound( _node: Arc, diff --git a/src/nodes/items/panel.rs b/src/nodes/items/panel.rs index a3cb813..c3b8b9c 100644 --- a/src/nodes/items/panel.rs +++ b/src/nodes/items/panel.rs @@ -1,4 +1,4 @@ -use super::camera::CameraItemAcceptor; +// use super::camera::CameraItemAcceptor; use super::{create_item_acceptor_flex, register_item_ui_flex}; use crate::bail; use crate::core::error::Result; @@ -469,7 +469,7 @@ impl Drop for PanelItem { impl InterfaceAspect for Interface { #[doc = "Register this client to manage the items of a certain type and create default 3D UI for them."] fn register_panel_item_ui(node: Arc, calling_client: Arc) -> Result<()> { - node.add_aspect(CameraItemAcceptor); + // node.add_aspect(CameraItemAcceptor); register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_PANEL) } diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index 3f8ef8b..5b59ec3 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -19,6 +19,7 @@ use bevy::{ pbr::MeshMaterial3d, prelude::{Children, Commands, Component, Mesh, Query, Res, ResMut, Transform}, scene::SceneRoot, + utils::default, }; use bevy_mod_openxr::{ helper_traits::{ToQuat, ToVec2, ToVec3}, @@ -96,7 +97,7 @@ fn update_controllers( if input_node.enabled() { let world_transform = location; if let Some(mat) = controller.material.get().and_then(|v| mats.get_mut(v)) { - mat.base_color = if controller.capture.is_none() { + mat.base_color = if controller.capture_manager.capture.is_none() { LinearRgba::rgb(1.0, 1.0, 1.0) } else { LinearRgba::rgb(0.0, 1.0, 0.75) @@ -132,95 +133,23 @@ fn update_controllers( *controller.input.datamap.lock() = Datamap::from_typed(&controller.datamap).unwrap(); // remove the capture when it's removed from captures list - if let Some(capture) = &controller.capture { - if !controller - .input - .capture_requests - .get_valid_contents() - .contains(capture) - { - controller.capture.take(); - } - } - // add the capture that's the closest if we don't have one - if controller.capture.is_none() { - controller.capture = controller - .input - .capture_requests - .get_valid_contents() - .into_iter() - .map(|handler| { - ( - handler.clone(), - handler - .field - .distance(&controller.input.spatial, [0.0; 3].into()) - .abs(), - ) - }) - .reduce(|(handlers_a, distance_a), (handlers_b, distance_b)| { - if distance_a < distance_b { - (handlers_a, distance_a) - } else { - (handlers_b, distance_b) - } - }) - .map(|(rx, _)| rx); - } + let distance_calculator = |space: &Arc, _data: &InputDataType, field: &Field| { + Some(field.distance(space, [0.0; 3].into()).abs()) + }; - // make sure that if something is captured only send input to it - controller.input.captures.clear(); - if let Some(capture) = &controller.capture { - controller.input.set_handler_order([capture].into_iter()); - controller.input.captures.add_raw(capture); + let input = controller.input.clone(); + controller.capture_manager.update_capture(&input); + controller + .capture_manager + .set_new_capture(&input, distance_calculator); + controller.capture_manager.apply_capture(&input); + + if controller.capture_manager.capture.is_some() { return; } - // send input to all the input handlers that are the closest to the ray as possible - controller.input.set_handler_order( - INPUT_HANDLER_REGISTRY - .get_valid_contents() - .into_iter() - // filter out all the disabled handlers - .filter(|handler| { - let Some(node) = handler.spatial.node() else { - return false; - }; - node.enabled() - }) - // filter out all the fields with disabled handlers - .filter(|handler| { - let Some(node) = handler.field.spatial.node() else { - return false; - }; - node.enabled() - }) - // get the unsigned distance to the handler's field (unsigned so giant fields won't always eat input) - .map(|handler| { - ( - vec![handler.clone()], - handler - .field - .distance(&controller.input.spatial, [0.0; 3].into()) - .abs(), - ) - }) - // now collect all handlers that are same distance if they're the closest - .reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| { - if (distance_a - distance_b).abs() < 0.001 { - // distance is basically the same (within 1mm) - handlers_a.extend(handlers_b); - (handlers_a, distance_a) - } else if distance_a < distance_b { - (handlers_a, distance_a) - } else { - (handlers_b, distance_b) - } - }) - .map(|(rx, _)| rx) - .unwrap_or_default() - .iter(), - ); + let sorted_handlers = get_sorted_handlers(&input, distance_calculator); + controller.input.set_handler_order(sorted_handlers.iter()); } } @@ -290,7 +219,6 @@ fn spawn_controllers( input, handed, material: OnceCell::new(), - capture: None, datamap: Default::default(), space: actions .pose @@ -301,6 +229,7 @@ fn spawn_controllers( ) .unwrap(), actions, + capture_manager: default(), }, )); } @@ -313,10 +242,10 @@ pub struct SkController { input: Arc, handed: HandSide, material: OnceCell>, - capture: Option>, datamap: ControllerDatamap, space: openxr::Space, actions: Actions, + capture_manager: CaptureManager, } struct Actions { set: openxr::ActionSet, diff --git a/src/objects/input/sk_hand.rs b/src/objects/input/sk_hand.rs index 7b0e2b3..efe6961 100644 --- a/src/objects/input/sk_hand.rs +++ b/src/objects/input/sk_hand.rs @@ -12,9 +12,7 @@ use crate::objects::{ObjectHandle, SpatialRef}; use crate::DefaultMaterial; use bevy::app::{Plugin, PostUpdate}; use bevy::asset::{AssetServer, Assets, Handle}; -use bevy::prelude::{ - Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut, -}; +use bevy::prelude::{Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut}; use bevy::utils::default; use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3}; use bevy_mod_openxr::resources::OxrFrameState; @@ -32,6 +30,8 @@ use std::sync::Arc; use tracing::error; use zbus::Connection; +use super::{get_sorted_handlers, CaptureManager}; + fn update_joint(joint: &mut Joint, oxr_joint: openxr::HandJointLocation) { let flags = OxrSpaceLocationFlags(oxr_joint.location_flags); if flags.pos_valid() && flags.rot_valid() { @@ -114,88 +114,35 @@ fn update_hands( hand.datamap.grab_strength = grip_activation(joints); *hand.input.datamap.lock() = Datamap::from_typed(&hand.datamap).unwrap(); } - // remove the capture when it's removed from captures list - if let Some(capture) = &hand.capture { - if !hand - .input - .capture_requests - .get_valid_contents() - .contains(capture) - { - hand.capture.take(); - } - } - // add the capture that's the closest if we don't have one - if hand.capture.is_none() { - hand.capture = hand - .input - .capture_requests - .get_valid_contents() - .into_iter() - .map(|handler| (handler.clone(), hand.compare_distance(&handler.field).abs())) - .reduce(|(handlers_a, distance_a), (handlers_b, distance_b)| { - if distance_a < distance_b { - (handlers_a, distance_a) - } else { - (handlers_b, distance_b) - } - }) - .map(|(rx, _)| rx); - } + let distance_calculator = |space: &Arc, data: &InputDataType, field: &Field| { + let InputDataType::Hand(hand) = data else { + return None; + }; + let thumb_tip_distance = field.distance(space, hand.thumb.tip.position.into()); + let index_tip_distance = field.distance(space, hand.index.tip.position.into()); + let middle_tip_distance = field.distance(space, hand.middle.tip.position.into()); + let ring_tip_distance = field.distance(space, hand.ring.tip.position.into()); - // make sure that if something is captured only send input to it - hand.input.captures.clear(); - if let Some(capture) = &hand.capture { - hand.input.set_handler_order([capture].into_iter()); - hand.input.captures.add_raw(capture); + Some( + (thumb_tip_distance * 0.3) + + (index_tip_distance * 0.4) + + (middle_tip_distance * 0.15) + + (ring_tip_distance * 0.15), + ) + }; + + let input = hand.input.clone(); + hand.capture_manager.update_capture(&input); + hand.capture_manager + .set_new_capture(&input, distance_calculator); + hand.capture_manager.apply_capture(&input); + + if hand.capture_manager.capture.is_some() { return; } - // send input to all the input handlers that are the closest to the ray as possible - hand.input.set_handler_order( - INPUT_HANDLER_REGISTRY - .get_valid_contents() - .into_iter() - // filter out all the disabled handlers - .filter(|handler| { - let Some(node) = handler.spatial.node() else { - return false; - }; - node.enabled() - }) - // filter out all the fields with disabled handlers - .filter(|handler| { - let Some(node) = handler.field.spatial.node() else { - return false; - }; - node.enabled() - }) - // get the unsigned distance to the handler's field (unsigned so giant fields won't always eat input) - .map(|handler| { - ( - vec![handler.clone()], - hand.compare_distance(&handler.field).abs(), - ) - }) - // .inspect(|(_, result)| { - // dbg!(result); - // }) - // now collect all handlers that are same distance if they're the closest - .reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| { - if (distance_a - distance_b).abs() < 0.001 { - // distance is basically the same (within 1mm) - handlers_a.extend(handlers_b); - (handlers_a, distance_a) - } else if distance_a < distance_b { - (handlers_a, distance_a) - } else { - (handlers_b, distance_b) - } - }) - .map(|(rx, _)| rx) - .unwrap_or_default() - .iter(), - ); + let sorted_handlers = get_sorted_handlers(&hand.input, distance_calculator); + hand.input.set_handler_order(sorted_handlers.iter()); } } @@ -268,7 +215,7 @@ fn create_hands(connection: Res, session: Res, mut c palm_object, handed, input, - capture: None, + capture_manager: default(), datamap: Default::default(), material: OnceCell::new(), vis_entity: OnceCell::new(), @@ -308,16 +255,16 @@ pub struct SkHand { palm_object: ObjectHandle, handed: HandSide, input: Arc, - capture: Option>, datamap: HandDatamap, material: OnceCell>, vis_entity: OnceCell, hand_tracker: openxr::HandTracker, + capture_manager: CaptureManager, } impl SkHand { fn compare_distance(&self, field: &Field) -> f32 { let InputDataType::Hand(hand) = &*self.input.data.lock() else { - return INFINITY; + return f32::INFINITY; }; let spatial = &self.input.spatial; let thumb_tip_distance = field.distance(spatial, hand.thumb.tip.position.into()); @@ -331,3 +278,4 @@ impl SkHand { + (ring_tip_distance * 0.15) } } + diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 52aecee..65fed3a 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -203,7 +203,7 @@ impl ServerObjects { eye_pointer.update(); } } - Some(Inputs::MousePointer(mouse_pointer)) => mouse_pointer.update(), + Some(Inputs::MousePointer(mouse_pointer)) => {} // Inputs::Controllers((left, right)) => { // left.update(token); // right.update(token);