fix(input): send events even when not in handler queue

This commit is contained in:
Nova
2024-06-30 22:22:41 -04:00
parent 2988ae3c28
commit 1e8d3a3d4c
5 changed files with 82 additions and 103 deletions

View File

@@ -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::fields::{Field, FieldTrait};
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3a, Mat4, Quat}; use glam::{vec3a, Mat4, Quat};
@@ -67,7 +67,9 @@ impl InputDataTrait for Hand {
min_distance 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(); let mut joints: Vec<&mut Joint> = Vec::new();
joints.extend([&mut self.palm, &mut self.wrist]); 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(); let (_, rotation, position) = joint_matrix.to_scale_rotation_translation();
joint.position = position.into(); joint.position = position.into();
joint.rotation = rotation.into(); joint.rotation = rotation.into();
joint.distance = input_link joint.distance = handler.field.distance(&handler.spatial, position.into());
.handler
.field
.distance(&input_link.handler.spatial, position.into());
} }
} }
} }

View File

@@ -1,5 +1,5 @@
use super::{ 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, InputMethodRefAspect, INPUT_HANDLER_REGISTRY, INPUT_METHOD_REF_ASPECT_ALIAS_INFO,
INPUT_METHOD_REGISTRY, INPUT_METHOD_REGISTRY,
}; };
@@ -132,6 +132,27 @@ impl InputMethod {
self.handler_field_aliases self.handler_field_aliases
.remove_aspect(handler.field.as_ref()); .remove_aspect(handler.field.as_ref());
} }
pub(super) fn serialize(&self, alias_id: u64, handler: &Arc<InputHandler>) -> 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 { impl Aspect for InputMethod {
const NAME: &'static str = "InputMethod"; const NAME: &'static str = "InputMethod";

View File

@@ -6,7 +6,6 @@ mod tip;
pub use handler::*; pub use handler::*;
pub use method::*; pub use method::*;
use rustc_hash::FxHashMap;
use super::fields::Field; use super::fields::Field;
use super::spatial::Spatial; 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::client::Client, nodes::Node};
use crate::{core::registry::Registry, nodes::spatial::Transform}; use crate::{core::registry::Registry, nodes::spatial::Transform};
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use glam::Mat4;
use stardust_xr::values::Datamap; use stardust_xr::values::Datamap;
use std::sync::{Arc, Weak}; use std::sync::Arc;
use tracing::{debug_span, instrument}; use tracing::debug_span;
static INPUT_METHOD_REGISTRY: Registry<InputMethod> = Registry::new(); static INPUT_METHOD_REGISTRY: Registry<InputMethod> = Registry::new();
pub static INPUT_HANDLER_REGISTRY: Registry<InputHandler> = Registry::new(); pub static INPUT_HANDLER_REGISTRY: Registry<InputHandler> = Registry::new();
stardust_xr_server_codegen::codegen_input_protocol!(); stardust_xr_server_codegen::codegen_input_protocol!();
pub struct InputLink {
method: Arc<InputMethod>,
handler: Arc<InputHandler>,
}
impl InputLink {
fn from(method: Arc<InputMethod>, handler: Arc<InputHandler>) -> 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 { pub trait InputDataTrait {
fn transform(&mut self, method: &InputMethod, handler: &InputHandler);
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32; fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32;
fn update_to(&mut self, input_link: &InputLink, local_to_handler_matrix: Mat4);
} }
impl InputDataTrait for InputDataType { 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<Spatial>, field: &Field) -> f32 { fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 {
match self { match self {
InputDataType::Pointer(i) => i.distance(space, field), InputDataType::Pointer(i) => i.distance(space, field),
@@ -65,14 +44,6 @@ impl InputDataTrait for InputDataType {
InputDataType::Tip(i) => i.distance(space, field), 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); create_interface!(InputInterface);
@@ -135,56 +106,43 @@ pub fn process_input() {
for method_alias in handler.method_aliases.get_aliases() { for method_alias in handler.method_aliases.get_aliases() {
method_alias.set_enabled(false); method_alias.set_enabled(false);
} }
}
let mut handler_input: FxHashMap<u64, (Arc<Node>, Vec<Arc<Node>>, Vec<InputData>)> = let Some(handler_node) = handler.spatial.node() else {
Default::default(); continue;
// const LIMIT: usize = 50; };
for method in methods { if !handler_node.enabled() {
debug_span!("Process input method").in_scope(|| { continue;
// Get all valid input handlers and convert them to InputLink objects }
let input_links: Vec<InputLink> = debug_span!("Generate input links").in_scope(|| {
method let (methods, datas) = methods
.handler_order .clone()
// filter out methods without the handler in their handler order
.filter(|a| {
a.handler_order
.lock() .lock()
.iter() .iter()
.filter_map(Weak::upgrade) .any(|h| h.ptr_eq(&Arc::downgrade(&handler)))
.filter(|handler| { })
let Some(node) = handler.spatial.node() else { // filter out methods without the proper alias
return false; .filter_map(|m| {
}; Some((
node.enabled() handler
}) .method_aliases
.map(|handler| InputLink::from(method.clone(), handler)) .get_from_original_node(m.spatial.node.clone())?,
.collect() 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 let _ = input_handler_client::input(&handler_node, &methods, &datas);
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();
});
} }
for method in methods {
for (_, (handler, methods, data)) in handler_input { method.capture_requests.clear();
let _ = input_handler_client::input(&handler, &methods, &data);
} }
} }

View File

@@ -1,4 +1,4 @@
use super::{InputDataTrait, InputLink, Pointer}; use super::{InputDataTrait, InputHandler, InputMethod, Pointer};
use crate::nodes::{ use crate::nodes::{
fields::{Field, FieldTrait, Ray, RayMarchResult}, fields::{Field, FieldTrait, Ray, RayMarchResult},
spatial::Spatial, spatial::Spatial,
@@ -33,13 +33,13 @@ impl InputDataTrait for Pointer {
let ray_info = self.ray_march(space, field); let ray_info = self.ray_march(space, field);
ray_info.min_distance ray_info.min_distance
} }
fn update_to(&mut self, input_link: &InputLink, mut local_to_handler_matrix: Mat4) { fn transform(&mut self, method: &InputMethod, handler: &InputHandler) {
local_to_handler_matrix = let local_to_handler_matrix =
Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()) 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 (_, 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 let direction = local_to_handler_matrix
.transform_vector3(vec3(0.0, 0.0, -1.0)) .transform_vector3(vec3(0.0, 0.0, -1.0))
.normalize(); .normalize();

View File

@@ -1,4 +1,4 @@
use super::{InputDataTrait, InputLink, Tip}; use super::{InputDataTrait, InputHandler, InputMethod, Tip};
use crate::nodes::{ use crate::nodes::{
fields::{Field, FieldTrait}, fields::{Field, FieldTrait},
spatial::Spatial, spatial::Spatial,
@@ -18,9 +18,10 @@ impl InputDataTrait for Tip {
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 { fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 {
field.distance(space, self.origin.into()) field.distance(space, self.origin.into())
} }
fn update_to(&mut self, _input_link: &InputLink, mut local_to_handler_matrix: Mat4) { fn transform(&mut self, method: &InputMethod, handler: &InputHandler) {
local_to_handler_matrix *= let local_to_handler_matrix =
Mat4::from_rotation_translation(self.orientation.into(), self.origin.into()); 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(); let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation();
self.origin = origin.into(); self.origin = origin.into();
self.orientation = orientation.into(); self.orientation = orientation.into();