refactor(input): flexible datamaps

This commit is contained in:
Nova
2022-10-14 08:01:07 -04:00
parent 6cba9a010f
commit e0be6ecea9
9 changed files with 86 additions and 94 deletions

View File

@@ -42,7 +42,7 @@ serde = { version = "1.0.145", features = ["derive"] }
path = "../stereokit-rs" path = "../stereokit-rs"
default-features = false default-features = false
features = ["linux-egl"] features = ["linux-egl"]
version = "0.4.1" version = "0.5.0"
[dependencies.smithay] [dependencies.smithay]
git = "https://github.com/technobaboo/smithay.git" git = "https://github.com/technobaboo/smithay.git"

View File

@@ -109,10 +109,6 @@ fn main() -> Result<()> {
wayland.frame(sk); wayland.frame(sk);
destroy_queue::clear(); destroy_queue::clear();
input::process_input();
nodes::root::Root::logic_step(sk.time_elapsed());
drawable::draw(sk, draw_ctx);
if let Some(mouse_pointer) = &mouse_pointer { if let Some(mouse_pointer) = &mouse_pointer {
mouse_pointer.update(sk); mouse_pointer.update(sk);
} }
@@ -124,6 +120,9 @@ fn main() -> Result<()> {
controllers[0].update(sk); controllers[0].update(sk);
controllers[1].update(sk); controllers[1].update(sk);
} }
input::process_input();
nodes::root::Root::logic_step(sk.time_elapsed());
drawable::draw(sk, draw_ctx);
wayland.make_context_current(); wayland.make_context_current();
}, },

View File

@@ -1,7 +1,7 @@
use crate::nodes::fields::Field; use crate::nodes::fields::Field;
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3a, Mat4}; use glam::{vec3a, Mat4};
use stardust_xr::schemas::flat::{Datamap, Hand as FlatHand, InputDataType, Joint}; use stardust_xr::schemas::flat::{Hand as FlatHand, InputDataType, Joint};
use std::sync::Arc; use std::sync::Arc;
use super::{DistanceLink, InputSpecialization}; use super::{DistanceLink, InputSpecialization};
@@ -9,8 +9,6 @@ use super::{DistanceLink, InputSpecialization};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Hand { pub struct Hand {
pub base: FlatHand, pub base: FlatHand,
pub pinch_strength: f32,
pub grab_strength: f32,
} }
impl InputSpecialization for Hand { impl InputSpecialization for Hand {
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 { fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 {
@@ -72,13 +70,4 @@ impl InputSpecialization for Hand {
InputDataType::Hand(Box::new(hand)) InputDataType::Hand(Box::new(hand))
} }
fn serialize_datamap(&self) -> Datamap {
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("right", self.base.right);
map.push("pinchStrength", self.pinch_strength);
map.push("grabStrength", self.grab_strength);
map.end_map();
Datamap::new(fbb.view().to_vec()).unwrap()
}
} }

View File

@@ -34,7 +34,6 @@ pub trait InputSpecialization: Send + Sync {
distance_link: &DistanceLink, distance_link: &DistanceLink,
local_to_handler_matrix: Mat4, local_to_handler_matrix: Mat4,
) -> InputDataType; ) -> InputDataType;
fn serialize_datamap(&self) -> Datamap;
} }
pub enum InputType { pub enum InputType {
Pointer(Pointer), Pointer(Pointer),
@@ -58,6 +57,7 @@ pub struct InputMethod {
pub spatial: Arc<Spatial>, pub spatial: Arc<Spatial>,
pub specialization: Mutex<InputType>, pub specialization: Mutex<InputType>,
pub captures: Registry<InputHandler>, pub captures: Registry<InputHandler>,
pub datamap: Mutex<Option<Datamap>>,
} }
impl InputMethod { impl InputMethod {
pub fn new(spatial: Arc<Spatial>, specialization: InputType) -> Arc<InputMethod> { pub fn new(spatial: Arc<Spatial>, specialization: InputType) -> Arc<InputMethod> {
@@ -67,11 +67,16 @@ impl InputMethod {
spatial, spatial,
specialization: Mutex::new(specialization), specialization: Mutex::new(specialization),
captures: Registry::new(), captures: Registry::new(),
datamap: Mutex::new(None),
}; };
INPUT_METHOD_REGISTRY.add(method) INPUT_METHOD_REGISTRY.add(method)
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn add_to(node: &Arc<Node>, specialization: InputType) -> Result<()> { pub fn add_to(
node: &Arc<Node>,
specialization: InputType,
datamap: Option<Datamap>,
) -> Result<()> {
ensure!( ensure!(
node.spatial.get().is_some(), node.spatial.get().is_some(),
"Internal: Node does not have a spatial attached!" "Internal: Node does not have a spatial attached!"
@@ -83,6 +88,7 @@ impl InputMethod {
spatial: node.spatial.get().unwrap().clone(), spatial: node.spatial.get().unwrap().clone(),
specialization: Mutex::new(specialization), specialization: Mutex::new(specialization),
captures: Registry::new(), captures: Registry::new(),
datamap: Mutex::new(datamap),
}; };
let method = INPUT_METHOD_REGISTRY.add(method); let method = INPUT_METHOD_REGISTRY.add(method);
let _ = node.input_method.set(method); let _ = node.input_method.set(method);
@@ -91,9 +97,6 @@ impl InputMethod {
fn distance(&self, to: &Field) -> f32 { fn distance(&self, to: &Field) -> f32 {
self.specialization.lock().distance(&self.spatial, to) self.specialization.lock().distance(&self.spatial, to)
} }
fn serialize_datamap(&self) -> Datamap {
self.specialization.lock().serialize_datamap()
}
} }
impl Drop for InputMethod { impl Drop for InputMethod {
fn drop(&mut self) { fn drop(&mut self) {
@@ -231,8 +234,9 @@ pub fn create_input_handler_flex(
pub fn process_input() { pub fn process_input() {
for method in INPUT_METHOD_REGISTRY for method in INPUT_METHOD_REGISTRY
.get_valid_contents() .get_valid_contents()
.iter() .into_iter()
.filter(|method| *method.enabled.lock()) .filter(|method| *method.enabled.lock())
.filter(|method| method.datamap.lock().is_some())
{ {
let mut distance_links: Vec<DistanceLink> = INPUT_HANDLER_REGISTRY let mut distance_links: Vec<DistanceLink> = INPUT_HANDLER_REGISTRY
.get_valid_contents() .get_valid_contents()
@@ -248,12 +252,11 @@ pub fn process_input() {
.reverse() .reverse()
}); });
let datamap = method.serialize_datamap();
let mut last_distance = 0.0; let mut last_distance = 0.0;
let frame = FRAME.load(Ordering::Relaxed); let frame = FRAME.load(Ordering::Relaxed);
let captures = method.captures.get_valid_contents(); let captures = method.captures.get_valid_contents();
for distance_link in distance_links { for distance_link in distance_links {
distance_link.send_input(frame, datamap.clone()); distance_link.send_input(frame, method.datamap.lock().clone().unwrap());
if last_distance != distance_link.distance if last_distance != distance_link.distance
&& captures && captures
.iter() .iter()

View File

@@ -2,15 +2,11 @@ use super::{DistanceLink, InputSpecialization};
use crate::nodes::fields::{ray_march, Field, Ray, RayMarchResult}; use crate::nodes::fields::{ray_march, Field, Ray, RayMarchResult};
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3, Mat4}; use glam::{vec3, Mat4};
use stardust_xr::schemas::flat::{Datamap, InputDataType, Pointer as FlatPointer}; use stardust_xr::schemas::flat::{InputDataType, Pointer as FlatPointer};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
#[derive(Default)] #[derive(Default)]
pub struct Pointer { pub struct Pointer {}
grab: AtomicBool,
select: AtomicBool,
}
// impl Default for Pointer { // impl Default for Pointer {
// fn default() -> Self { // fn default() -> Self {
// Pointer { // Pointer {
@@ -55,12 +51,4 @@ impl InputSpecialization for Pointer {
deepest_point: deepest_point.into(), deepest_point: deepest_point.into(),
}) })
} }
fn serialize_datamap(&self) -> Datamap {
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("grab", self.grab.load(Ordering::Relaxed));
map.push("select", self.select.load(Ordering::Relaxed));
map.end_map();
Datamap::new(fbb.view().to_vec()).unwrap()
}
} }

View File

@@ -1,17 +1,20 @@
use super::{DistanceLink, InputSpecialization}; use super::{DistanceLink, InputSpecialization};
use crate::core::client::Client;
use crate::nodes::fields::Field; use crate::nodes::fields::Field;
use crate::nodes::spatial::Spatial; use crate::nodes::input::{InputMethod, InputType};
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use crate::nodes::Node;
use anyhow::Result;
use glam::{vec3a, Mat4}; use glam::{vec3a, Mat4};
use portable_atomic::AtomicF32; use serde::Deserialize;
use stardust_xr::schemas::flat::{Datamap, InputDataType, Tip as FlatTip}; use stardust_xr::schemas::flat::{Datamap, InputDataType, Tip as FlatTip};
use std::sync::atomic::Ordering; use stardust_xr::schemas::flex::deserialize;
use stardust_xr::values::Transform;
use std::sync::Arc; use std::sync::Arc;
#[derive(Default)] #[derive(Default)]
pub struct Tip { pub struct Tip {
pub radius: AtomicF32, pub radius: f32,
pub grab: AtomicF32,
pub select: AtomicF32,
} }
impl InputSpecialization for Tip { impl InputSpecialization for Tip {
@@ -27,15 +30,8 @@ impl InputSpecialization for Tip {
InputDataType::Tip(FlatTip { InputDataType::Tip(FlatTip {
origin: origin.into(), origin: origin.into(),
orientation: orientation.into(), orientation: orientation.into(),
radius: self.radius.load(Ordering::Relaxed), radius: self.radius,
}) })
} }
fn serialize_datamap(&self) -> Datamap {
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("grab", self.grab.load(Ordering::Relaxed));
map.push("select", self.select.load(Ordering::Relaxed));
map.end_map();
Datamap::new(fbb.view().to_vec()).unwrap()
} }
} }

View File

@@ -3,9 +3,12 @@ use crate::nodes::{
spatial::Spatial, spatial::Spatial,
}; };
use glam::{vec3, Mat4}; use glam::{vec3, Mat4};
use stardust_xr::values::Transform; use stardust_xr::{schemas::flat::Datamap, values::Transform};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use stereokit::{input::Ray, StereoKit}; use stereokit::{
input::{ButtonState, Key, Ray},
StereoKit,
};
pub struct MousePointer { pub struct MousePointer {
pointer: Arc<InputMethod>, pointer: Arc<InputMethod>,
@@ -32,5 +35,25 @@ impl MousePointer {
}, },
); );
} }
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push(
"select",
if sk.input_key(Key::MouseLeft).contains(ButtonState::Active) {
1.0f32
} else {
0.0f32
},
);
map.push(
"grab",
if sk.input_key(Key::MouseRight).contains(ButtonState::Active) {
1.0f32
} else {
0.0f32
},
);
map.end_map();
*self.pointer.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
} }
} }

View File

@@ -3,10 +3,12 @@ use crate::nodes::{
spatial::Spatial, spatial::Spatial,
}; };
use glam::Mat4; use glam::Mat4;
use portable_atomic::Ordering; use stardust_xr::{schemas::flat::Datamap, values::Transform};
use stardust_xr::values::Transform;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use stereokit::{input::Handed, StereoKit}; use stereokit::{
input::{ButtonState, Handed},
StereoKit,
};
pub struct SkController { pub struct SkController {
tip: Arc<InputMethod>, tip: Arc<InputMethod>,
@@ -23,22 +25,23 @@ impl SkController {
} }
} }
pub fn update(&mut self, sk: &StereoKit) { pub fn update(&mut self, sk: &StereoKit) {
if let InputType::Tip(tip) = &mut *self.tip.specialization.lock() { let controller = sk.input_controller(self.handed);
let controller = sk.input_controller(self.handed); *self.tip.enabled.lock() = controller.tracked.contains(ButtonState::Active);
*self.tip.enabled.lock() = controller.tracked.is_active(); if *self.tip.enabled.lock() {
if controller.tracked.is_active() { self.tip.spatial.set_local_transform_components(
self.tip.spatial.set_local_transform_components( None,
None, Transform {
Transform { position: Some(controller.pose.position),
position: Some(controller.pose.position), rotation: Some(controller.pose.orientation),
rotation: Some(controller.pose.orientation), scale: None,
scale: None, },
}, );
);
}
tip.select.store(controller.trigger, Ordering::Relaxed);
tip.grab.store(controller.grip, Ordering::Relaxed);
} }
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("select", controller.trigger);
map.push("grab", controller.grip);
map.end_map();
*self.tip.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
} }
} }

View File

@@ -3,10 +3,10 @@ use crate::nodes::{
spatial::Spatial, spatial::Spatial,
}; };
use glam::Mat4; use glam::Mat4;
use stardust_xr::schemas::flat::{Hand as FlatHand, Joint}; use stardust_xr::schemas::flat::{Datamap, Hand as FlatHand, Joint};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use stereokit::{ use stereokit::{
input::{Handed, Joint as SkJoint}, input::{ButtonState, Handed, Joint as SkJoint},
StereoKit, StereoKit,
}; };
@@ -32,19 +32,17 @@ impl SkHand {
right: handed == Handed::Right, right: handed == Handed::Right,
..Default::default() ..Default::default()
}, },
pinch_strength: 0.0,
grab_strength: 0.0,
})), })),
), ),
handed, handed,
} }
} }
pub fn update(&mut self, sk: &StereoKit) { pub fn update(&mut self, sk: &StereoKit) {
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.hand.specialization.lock() {
let sk_hand = *sk.input_hand(self.handed);
let controller = sk.input_controller(self.handed); let controller = sk.input_controller(self.handed);
*self.hand.enabled.lock() = *self.hand.enabled.lock() = controller.tracked.contains(ButtonState::Inactive)
controller.tracked.is_inactive() && sk_hand.tracked_state.is_active(); && sk_hand.tracked_state.contains(ButtonState::Active);
if *self.hand.enabled.lock() { if *self.hand.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]);
@@ -75,20 +73,13 @@ impl SkHand {
(sk_hand.fingers[0][0].radius + sk_hand.fingers[4][0].radius) * 0.5; (sk_hand.fingers[0][0].radius + sk_hand.fingers[4][0].radius) * 0.5;
hand.base.elbow = None; hand.base.elbow = None;
//hand.pinch_strength = sk_hand.pinch_activation;
//hand.grab_strength = sk_hand.grip_activation;
hand.pinch_strength = if sk_hand.pinch_state.is_active() {
1.0
} else {
0.0
};
hand.grab_strength = if sk_hand.grip_state.is_active() {
1.0
} else {
0.0
};
} }
} }
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("grabStrength", sk_hand.grip_activation);
map.push("pinchStrength", sk_hand.pinch_activation);
map.end_map();
*self.hand.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
} }
} }