From 1e8d3a3d4c689ea8e83fd4d1e994c3d1392919ca Mon Sep 17 00:00:00 2001 From: Nova Date: Sun, 30 Jun 2024 22:22:41 -0400 Subject: [PATCH] fix(input): send events even when not in handler queue --- src/nodes/input/hand.rs | 11 ++-- src/nodes/input/method.rs | 23 ++++++- src/nodes/input/mod.rs | 132 +++++++++++++------------------------ src/nodes/input/pointer.rs | 10 +-- src/nodes/input/tip.rs | 9 +-- 5 files changed, 82 insertions(+), 103 deletions(-) diff --git a/src/nodes/input/hand.rs b/src/nodes/input/hand.rs index 391edf1..789d2e1 100644 --- a/src/nodes/input/hand.rs +++ b/src/nodes/input/hand.rs @@ -1,4 +1,4 @@ -use super::{Finger, Hand, InputDataTrait, InputLink, Joint, Thumb}; +use super::{Finger, Hand, InputDataTrait, InputHandler, InputMethod, Joint, Thumb}; use crate::nodes::fields::{Field, FieldTrait}; use crate::nodes::spatial::Spatial; use glam::{vec3a, Mat4, Quat}; @@ -67,7 +67,9 @@ impl InputDataTrait for Hand { min_distance } - fn update_to(&mut self, input_link: &InputLink, local_to_handler_matrix: Mat4) { + fn transform(&mut self, method: &InputMethod, handler: &InputHandler) { + let local_to_handler_matrix = + Spatial::space_to_space_matrix(Some(&method.spatial), Some(&handler.spatial)); let mut joints: Vec<&mut Joint> = Vec::new(); joints.extend([&mut self.palm, &mut self.wrist]); @@ -101,10 +103,7 @@ impl InputDataTrait for Hand { let (_, rotation, position) = joint_matrix.to_scale_rotation_translation(); joint.position = position.into(); joint.rotation = rotation.into(); - joint.distance = input_link - .handler - .field - .distance(&input_link.handler.spatial, position.into()); + joint.distance = handler.field.distance(&handler.spatial, position.into()); } } } diff --git a/src/nodes/input/method.rs b/src/nodes/input/method.rs index 7df106b..3ac536d 100644 --- a/src/nodes/input/method.rs +++ b/src/nodes/input/method.rs @@ -1,5 +1,5 @@ use super::{ - input_method_client, InputDataTrait, InputDataType, InputHandler, InputMethodAspect, + input_method_client, InputData, InputDataTrait, InputDataType, InputHandler, InputMethodAspect, InputMethodRefAspect, INPUT_HANDLER_REGISTRY, INPUT_METHOD_REF_ASPECT_ALIAS_INFO, INPUT_METHOD_REGISTRY, }; @@ -132,6 +132,27 @@ impl InputMethod { self.handler_field_aliases .remove_aspect(handler.field.as_ref()); } + + pub(super) fn serialize(&self, alias_id: u64, handler: &Arc) -> InputData { + let mut input = self.data.lock().clone(); + input.transform(&self, &handler); + + InputData { + id: alias_id, + input, + distance: self.distance(&handler.field), + datamap: self.datamap.lock().clone(), + order: self + .handler_order + .lock() + .iter() + .enumerate() + .find(|(_, h)| h.ptr_eq(&Arc::downgrade(handler))) + .unwrap() + .0 as u32, + captured: self.captures.get_valid_contents().contains(handler), + } + } } impl Aspect for InputMethod { const NAME: &'static str = "InputMethod"; diff --git a/src/nodes/input/mod.rs b/src/nodes/input/mod.rs index 1423ad1..a0b6503 100644 --- a/src/nodes/input/mod.rs +++ b/src/nodes/input/mod.rs @@ -6,7 +6,6 @@ mod tip; pub use handler::*; pub use method::*; -use rustc_hash::FxHashMap; use super::fields::Field; use super::spatial::Spatial; @@ -16,48 +15,28 @@ use crate::nodes::spatial::SPATIAL_REF_ASPECT_ALIAS_INFO; use crate::{core::client::Client, nodes::Node}; use crate::{core::registry::Registry, nodes::spatial::Transform}; use color_eyre::eyre::Result; -use glam::Mat4; use stardust_xr::values::Datamap; -use std::sync::{Arc, Weak}; -use tracing::{debug_span, instrument}; +use std::sync::Arc; +use tracing::debug_span; static INPUT_METHOD_REGISTRY: Registry = Registry::new(); pub static INPUT_HANDLER_REGISTRY: Registry = Registry::new(); stardust_xr_server_codegen::codegen_input_protocol!(); -pub struct InputLink { - method: Arc, - handler: Arc, -} -impl InputLink { - fn from(method: Arc, handler: Arc) -> Self { - InputLink { method, handler } - } - - #[instrument(level = "debug", skip(self))] - fn serialize(&self, id: u64, order: u32, captured: bool, datamap: Datamap) -> InputData { - let mut input = self.method.data.lock().clone(); - input.update_to( - self, - Spatial::space_to_space_matrix(Some(&self.method.spatial), Some(&self.handler.spatial)), - ); - - InputData { - id, - input, - distance: self.method.distance(&self.handler.field), - datamap, - order, - captured, - } - } -} pub trait InputDataTrait { + fn transform(&mut self, method: &InputMethod, handler: &InputHandler); fn distance(&self, space: &Arc, field: &Field) -> f32; - fn update_to(&mut self, input_link: &InputLink, local_to_handler_matrix: Mat4); } impl InputDataTrait for InputDataType { + fn transform(&mut self, method: &InputMethod, handler: &InputHandler) { + match self { + InputDataType::Pointer(i) => i.transform(method, handler), + InputDataType::Hand(i) => i.transform(method, handler), + InputDataType::Tip(i) => i.transform(method, handler), + } + } + fn distance(&self, space: &Arc, field: &Field) -> f32 { match self { InputDataType::Pointer(i) => i.distance(space, field), @@ -65,14 +44,6 @@ impl InputDataTrait for InputDataType { InputDataType::Tip(i) => i.distance(space, field), } } - - fn update_to(&mut self, input_link: &InputLink, local_to_handler_matrix: Mat4) { - match self { - InputDataType::Pointer(i) => i.update_to(input_link, local_to_handler_matrix), - InputDataType::Hand(i) => i.update_to(input_link, local_to_handler_matrix), - InputDataType::Tip(i) => i.update_to(input_link, local_to_handler_matrix), - } - } } create_interface!(InputInterface); @@ -135,56 +106,43 @@ pub fn process_input() { for method_alias in handler.method_aliases.get_aliases() { method_alias.set_enabled(false); } - } - let mut handler_input: FxHashMap, Vec>, Vec)> = - Default::default(); - // const LIMIT: usize = 50; - for method in methods { - debug_span!("Process input method").in_scope(|| { - // Get all valid input handlers and convert them to InputLink objects - let input_links: Vec = debug_span!("Generate input links").in_scope(|| { - method - .handler_order + + let Some(handler_node) = handler.spatial.node() else { + continue; + }; + if !handler_node.enabled() { + continue; + } + + let (methods, datas) = methods + .clone() + // filter out methods without the handler in their handler order + .filter(|a| { + a.handler_order .lock() .iter() - .filter_map(Weak::upgrade) - .filter(|handler| { - let Some(node) = handler.spatial.node() else { - return false; - }; - node.enabled() - }) - .map(|handler| InputLink::from(method.clone(), handler)) - .collect() - }); + .any(|h| h.ptr_eq(&Arc::downgrade(&handler))) + }) + // filter out methods without the proper alias + .filter_map(|m| { + Some(( + handler + .method_aliases + .get_from_original_node(m.spatial.node.clone())?, + m, + )) + }) + // make sure the input method alias is enabled + .inspect(|(a, _)| { + a.set_enabled(true); + }) + // serialize the data + .map(|(a, m)| (a.clone(), m.serialize(a.get_id(), &handler))) + .unzip::<_, _, Vec<_>, Vec<_>>(); - // Iterate over the distance links and send input to them - for (i, input_link) in input_links.into_iter().enumerate() { - let handler = input_link.handler.spatial.node().unwrap(); - handler_input - .entry(handler.id) - .or_insert_with(|| (handler.clone(), Vec::new(), Vec::new())); - let (_, methods, datas) = handler_input.get_mut(&handler.id).unwrap(); - - let method_alias = input_link - .handler - .method_aliases - .get_from_aspect(input_link.method.as_ref()) - .unwrap(); - method_alias.set_enabled(true); - datas.push(input_link.serialize( - method_alias.id, - i as u32, - method.captures.contains(&input_link.handler), - method.datamap.lock().clone(), - )); - methods.push(method_alias); - } - method.capture_requests.clear(); - }); + let _ = input_handler_client::input(&handler_node, &methods, &datas); } - - for (_, (handler, methods, data)) in handler_input { - let _ = input_handler_client::input(&handler, &methods, &data); + for method in methods { + method.capture_requests.clear(); } } diff --git a/src/nodes/input/pointer.rs b/src/nodes/input/pointer.rs index e970eab..d2b669e 100644 --- a/src/nodes/input/pointer.rs +++ b/src/nodes/input/pointer.rs @@ -1,4 +1,4 @@ -use super::{InputDataTrait, InputLink, Pointer}; +use super::{InputDataTrait, InputHandler, InputMethod, Pointer}; use crate::nodes::{ fields::{Field, FieldTrait, Ray, RayMarchResult}, spatial::Spatial, @@ -33,13 +33,13 @@ impl InputDataTrait for Pointer { let ray_info = self.ray_march(space, field); ray_info.min_distance } - fn update_to(&mut self, input_link: &InputLink, mut local_to_handler_matrix: Mat4) { - local_to_handler_matrix = + fn transform(&mut self, method: &InputMethod, handler: &InputHandler) { + let local_to_handler_matrix = Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()) - * local_to_handler_matrix; + * Spatial::space_to_space_matrix(Some(&method.spatial), Some(&handler.spatial)); let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation(); - let ray_march = self.ray_march(&input_link.method.spatial, &input_link.handler.field); + let ray_march = self.ray_march(&method.spatial, &handler.field); let direction = local_to_handler_matrix .transform_vector3(vec3(0.0, 0.0, -1.0)) .normalize(); diff --git a/src/nodes/input/tip.rs b/src/nodes/input/tip.rs index 5282ce2..1543610 100644 --- a/src/nodes/input/tip.rs +++ b/src/nodes/input/tip.rs @@ -1,4 +1,4 @@ -use super::{InputDataTrait, InputLink, Tip}; +use super::{InputDataTrait, InputHandler, InputMethod, Tip}; use crate::nodes::{ fields::{Field, FieldTrait}, spatial::Spatial, @@ -18,9 +18,10 @@ impl InputDataTrait for Tip { fn distance(&self, space: &Arc, field: &Field) -> f32 { field.distance(space, self.origin.into()) } - fn update_to(&mut self, _input_link: &InputLink, mut local_to_handler_matrix: Mat4) { - local_to_handler_matrix *= - Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()); + fn transform(&mut self, method: &InputMethod, handler: &InputHandler) { + let local_to_handler_matrix = + Spatial::space_to_space_matrix(Some(&method.spatial), Some(&handler.spatial)) + * Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()); let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation(); self.origin = origin.into(); self.orientation = orientation.into();