refactor(input): flexible datamaps
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user