fix(input): send events even when not in handler queue
This commit is contained in:
@@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user