refactor(input): make all inputs have nodes

This commit is contained in:
Nova
2023-02-24 11:43:06 -05:00
parent 931f857458
commit b5fc321e36
5 changed files with 84 additions and 77 deletions

View File

@@ -124,14 +124,20 @@ fn main() -> Result<()> {
} }
let mouse_pointer = cli_args.flatscreen.then(MousePointer::new).transpose()?; let mouse_pointer = cli_args.flatscreen.then(MousePointer::new).transpose()?;
let mut hands = let mut hands = (!cli_args.flatscreen)
(!cli_args.flatscreen).then(|| (SkHand::new(Handed::Left), SkHand::new(Handed::Right))); .then(|| {
let mut controllers = (!cli_args.flatscreen && !cli_args.disable_controller).then(|| { let left = SkHand::new(Handed::Left).ok();
( let right = SkHand::new(Handed::Right).ok();
SkController::new(Handed::Left), left.zip(right)
SkController::new(Handed::Right), })
) .flatten();
}); let mut controllers = (!cli_args.flatscreen && !cli_args.disable_controller)
.then(|| {
let left = SkController::new(Handed::Left).ok();
let right = SkController::new(Handed::Right).ok();
left.zip(right)
})
.flatten();
if hands.is_none() { if hands.is_none() {
unsafe { unsafe {

View File

@@ -11,12 +11,11 @@ use super::{
spatial::{find_spatial_parent, parse_transform, Spatial}, spatial::{find_spatial_parent, parse_transform, Spatial},
Node, Node,
}; };
use crate::core::eventloop::FRAME;
use crate::core::registry::Registry; use crate::core::registry::Registry;
use crate::core::{client::Client, task}; use crate::core::{client::Client, task};
use crate::core::{eventloop::FRAME, node_collections::LifeLinkedNodeMap};
use color_eyre::eyre::{ensure, Result}; use color_eyre::eyre::{ensure, Result};
use glam::Mat4; use glam::Mat4;
use nanoid::nanoid;
use parking_lot::Mutex; use parking_lot::Mutex;
use portable_atomic::AtomicBool; use portable_atomic::AtomicBool;
use serde::Deserialize; use serde::Deserialize;
@@ -60,6 +59,7 @@ impl Deref for InputType {
} }
pub struct InputMethod { pub struct InputMethod {
node: Weak<Node>,
pub uid: String, pub uid: String,
pub enabled: Mutex<bool>, pub enabled: Mutex<bool>,
pub spatial: Arc<Spatial>, pub spatial: Arc<Spatial>,
@@ -68,17 +68,6 @@ pub struct InputMethod {
pub datamap: Mutex<Option<Datamap>>, pub datamap: Mutex<Option<Datamap>>,
} }
impl InputMethod { impl InputMethod {
pub fn new(spatial: Arc<Spatial>, specialization: InputType) -> Arc<InputMethod> {
let method = InputMethod {
uid: nanoid!(),
enabled: Mutex::new(true),
spatial,
specialization: Mutex::new(specialization),
captures: Registry::new(),
datamap: Mutex::new(None),
};
INPUT_METHOD_REGISTRY.add(method)
}
#[allow(dead_code)] #[allow(dead_code)]
pub fn add_to( pub fn add_to(
node: &Arc<Node>, node: &Arc<Node>,
@@ -93,6 +82,7 @@ impl InputMethod {
node.add_local_signal("set_datamap", InputMethod::set_datamap); node.add_local_signal("set_datamap", InputMethod::set_datamap);
let method = InputMethod { let method = InputMethod {
node: Arc::downgrade(node),
uid: node.uid.clone(), uid: node.uid.clone(),
enabled: Mutex::new(true), enabled: Mutex::new(true),
spatial: node.spatial.get().unwrap().clone(), spatial: node.spatial.get().unwrap().clone(),
@@ -134,17 +124,14 @@ pub struct DistanceLink {
pub distance: f32, pub distance: f32,
pub method: Arc<InputMethod>, pub method: Arc<InputMethod>,
pub handler: Arc<InputHandler>, pub handler: Arc<InputHandler>,
pub handler_field: Arc<Field>,
} }
impl DistanceLink { impl DistanceLink {
fn from(method: Arc<InputMethod>, handler: Arc<InputHandler>) -> Option<Self> { fn from(method: Arc<InputMethod>, handler: Arc<InputHandler>) -> Self {
let handler_field = handler.field.upgrade()?; DistanceLink {
Some(DistanceLink { distance: method.compare_distance(&handler.field),
distance: method.compare_distance(&handler_field),
method, method,
handler, handler,
handler_field, }
})
} }
fn send_input(&self, frame: u64, datamap: Datamap) { fn send_input(&self, frame: u64, datamap: Datamap) {
@@ -160,9 +147,7 @@ impl DistanceLink {
let root = InputData { let root = InputData {
uid: self.method.uid.clone(), uid: self.method.uid.clone(),
input, input,
distance: self distance: self.method.true_distance(&self.handler.field),
.method
.true_distance(&self.handler.field.upgrade().unwrap()),
datamap, datamap,
}; };
root.serialize() root.serialize()
@@ -173,7 +158,8 @@ pub struct InputHandler {
enabled: Arc<AtomicBool>, enabled: Arc<AtomicBool>,
node: Weak<Node>, node: Weak<Node>,
spatial: Arc<Spatial>, spatial: Arc<Spatial>,
pub field: Weak<Field>, pub field: Arc<Field>,
method_aliases: LifeLinkedNodeMap<String>,
} }
impl InputHandler { impl InputHandler {
pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> { pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> {
@@ -186,7 +172,8 @@ impl InputHandler {
enabled: node.enabled.clone(), enabled: node.enabled.clone(),
node: Arc::downgrade(node), node: Arc::downgrade(node),
spatial: node.spatial.get().unwrap().clone(), spatial: node.spatial.get().unwrap().clone(),
field: Arc::downgrade(field), field: field.clone(),
method_aliases: LifeLinkedNodeMap::default(),
}; };
let handler = INPUT_HANDLER_REGISTRY.add(handler); let handler = INPUT_HANDLER_REGISTRY.add(handler);
let _ = node.input_handler.set(handler); let _ = node.input_handler.set(handler);
@@ -275,8 +262,7 @@ pub fn process_input() {
let handlers = INPUT_HANDLER_REGISTRY let handlers = INPUT_HANDLER_REGISTRY
.get_valid_contents() .get_valid_contents()
.into_iter() .into_iter()
.filter(|handler| handler.enabled.load(Ordering::Relaxed)) .filter(|handler| handler.enabled.load(Ordering::Relaxed));
.filter(|handler| handler.field.upgrade().is_some());
for method in methods { for method in methods {
debug_span!("Process input method").in_scope(|| { debug_span!("Process input method").in_scope(|| {
// Get all valid input handlers and convert them to DistanceLink objects // Get all valid input handlers and convert them to DistanceLink objects
@@ -284,7 +270,7 @@ pub fn process_input() {
.in_scope(|| { .in_scope(|| {
handlers handlers
.clone() .clone()
.filter_map(|handler| DistanceLink::from(method.clone(), handler)) .map(|handler| DistanceLink::from(method.clone(), handler))
.collect() .collect()
}); });

View File

@@ -41,10 +41,7 @@ impl InputSpecialization for Pointer {
) -> InputDataType { ) -> InputDataType {
let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation(); let (_, orientation, origin) = local_to_handler_matrix.to_scale_rotation_translation();
let direction = local_to_handler_matrix.transform_vector3(vec3(0_f32, 0_f32, 1_f32)); let direction = local_to_handler_matrix.transform_vector3(vec3(0_f32, 0_f32, 1_f32));
let ray_march = self.ray_march( let ray_march = self.ray_march(&distance_link.method.spatial, &distance_link.handler.field);
&distance_link.method.spatial,
&distance_link.handler.field.upgrade().unwrap(),
);
let deepest_point = (direction * ray_march.deepest_point_distance) + origin; let deepest_point = (direction * ray_march.deepest_point_distance) + origin;
InputDataType::Pointer(FlatPointer { InputDataType::Pointer(FlatPointer {

View File

@@ -1,36 +1,45 @@
use crate::nodes::{ use crate::{
input::{tip::Tip, InputMethod, InputType}, core::client::INTERNAL_CLIENT,
spatial::Spatial, nodes::{
input::{tip::Tip, InputMethod, InputType},
spatial::Spatial,
Node,
},
}; };
use color_eyre::eyre::Result;
use glam::Mat4; use glam::Mat4;
use nanoid::nanoid;
use stardust_xr::{ use stardust_xr::{
schemas::{flat::Datamap, flex::flexbuffers}, schemas::{flat::Datamap, flex::flexbuffers},
values::Transform, values::Transform,
}; };
use std::sync::{Arc, Weak}; use std::sync::Arc;
use stereokit::input::{ButtonState, Handed, StereoKitInput}; use stereokit::input::{ButtonState, Handed, StereoKitInput};
use tracing::instrument; use tracing::instrument;
pub struct SkController { pub struct SkController {
tip: Arc<InputMethod>, _node: Arc<Node>,
input: Arc<InputMethod>,
handed: Handed, handed: Handed,
} }
impl SkController { impl SkController {
pub fn new(handed: Handed) -> Self { pub fn new(handed: Handed) -> Result<Self> {
SkController { let _node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?;
tip: InputMethod::new( Spatial::add_to(&_node, None, Mat4::IDENTITY, false)?;
Spatial::new(Weak::new(), None, Mat4::IDENTITY), let tip = InputType::Tip(Tip::default());
InputType::Tip(Tip::default()), let input = InputMethod::add_to(&_node, tip, None)?;
), Ok(SkController {
_node,
input,
handed, handed,
} })
} }
#[instrument(level = "debug", name = "Update StereoKit Tip Input Method", skip_all)] #[instrument(level = "debug", name = "Update StereoKit Tip Input Method", skip_all)]
pub fn update(&mut self, sk: &impl StereoKitInput) { pub fn update(&mut self, sk: &impl StereoKitInput) {
let controller = sk.input_controller(self.handed); let controller = sk.input_controller(self.handed);
*self.tip.enabled.lock() = controller.tracked.contains(ButtonState::Active); *self.input.enabled.lock() = controller.tracked.contains(ButtonState::Active);
if *self.tip.enabled.lock() { if *self.input.enabled.lock() {
self.tip.spatial.set_local_transform_components( self.input.spatial.set_local_transform_components(
None, None,
Transform::from_position_rotation( Transform::from_position_rotation(
controller.pose.position, controller.pose.position,
@@ -43,6 +52,6 @@ impl SkController {
map.push("select", controller.trigger); map.push("select", controller.trigger);
map.push("grab", controller.grip); map.push("grab", controller.grip);
map.end_map(); map.end_map();
*self.tip.datamap.lock() = Datamap::new(fbb.take_buffer()).ok(); *self.input.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
} }
} }

View File

@@ -1,13 +1,19 @@
use crate::nodes::{ use crate::{
input::{hand::Hand, InputMethod, InputType}, core::client::INTERNAL_CLIENT,
spatial::Spatial, nodes::{
input::{hand::Hand, InputMethod, InputType},
spatial::Spatial,
Node,
},
}; };
use color_eyre::eyre::Result;
use glam::Mat4; use glam::Mat4;
use nanoid::nanoid;
use stardust_xr::schemas::{ use stardust_xr::schemas::{
flat::{Datamap, Hand as FlatHand, Joint}, flat::{Datamap, Hand as FlatHand, Joint},
flex::flexbuffers, flex::flexbuffers,
}; };
use std::sync::{Arc, Weak}; use std::sync::Arc;
use stereokit::{ use stereokit::{
input::{ButtonState, Handed, Joint as SkJoint, StereoKitInput}, input::{ButtonState, Handed, Joint as SkJoint, StereoKitInput},
lifecycle::StereoKitDraw, lifecycle::StereoKitDraw,
@@ -23,32 +29,35 @@ fn convert_joint(joint: SkJoint) -> Joint {
} }
pub struct SkHand { pub struct SkHand {
hand: Arc<InputMethod>, _node: Arc<Node>,
input: Arc<InputMethod>,
handed: Handed, handed: Handed,
} }
impl SkHand { impl SkHand {
pub fn new(handed: Handed) -> Self { pub fn new(handed: Handed) -> Result<Self> {
SkHand { let _node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?;
hand: InputMethod::new( Spatial::add_to(&_node, None, Mat4::IDENTITY, false)?;
Spatial::new(Weak::new(), None, Mat4::IDENTITY), let hand = InputType::Hand(Box::new(Hand {
InputType::Hand(Box::new(Hand { base: FlatHand {
base: FlatHand { right: handed == Handed::Right,
right: handed == Handed::Right, ..Default::default()
..Default::default() },
}, }));
})), let input = InputMethod::add_to(&_node, hand, None)?;
), Ok(SkHand {
_node,
input,
handed, handed,
} })
} }
#[instrument(level = "debug", name = "Update Hand Input Method", skip_all)] #[instrument(level = "debug", name = "Update Hand Input Method", skip_all)]
pub fn update(&mut self, sk: &StereoKitDraw) { pub fn update(&mut self, sk: &StereoKitDraw) {
let sk_hand = sk.input_hand(self.handed); let sk_hand = sk.input_hand(self.handed);
if let InputType::Hand(hand) = &mut *self.hand.specialization.lock() { if let InputType::Hand(hand) = &mut *self.input.specialization.lock() {
let controller = sk.input_controller(self.handed); let controller = sk.input_controller(self.handed);
*self.hand.enabled.lock() = controller.tracked.contains(ButtonState::Inactive) *self.input.enabled.lock() = controller.tracked.contains(ButtonState::Inactive)
&& sk_hand.tracked_state.contains(ButtonState::Active); && sk_hand.tracked_state.contains(ButtonState::Active);
if *self.hand.enabled.lock() { if *self.input.enabled.lock() {
hand.base.thumb.tip = convert_joint(sk_hand.fingers[0][4]); hand.base.thumb.tip = convert_joint(sk_hand.fingers[0][4]);
hand.base.thumb.distal = convert_joint(sk_hand.fingers[0][3]); hand.base.thumb.distal = convert_joint(sk_hand.fingers[0][3]);
hand.base.thumb.proximal = convert_joint(sk_hand.fingers[0][2]); hand.base.thumb.proximal = convert_joint(sk_hand.fingers[0][2]);
@@ -85,6 +94,6 @@ impl SkHand {
map.push("grab_strength", sk_hand.grip_activation); map.push("grab_strength", sk_hand.grip_activation);
map.push("pinch_strength", sk_hand.pinch_activation); map.push("pinch_strength", sk_hand.pinch_activation);
map.end_map(); map.end_map();
*self.hand.datamap.lock() = Datamap::new(fbb.take_buffer()).ok(); *self.input.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
} }
} }