refactor(input): make all inputs have nodes
This commit is contained in:
22
src/main.rs
22
src/main.rs
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user