refactor(objects): overhaul input
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,4 +11,5 @@
|
|||||||
*result*
|
*result*
|
||||||
|
|
||||||
/libs/
|
/libs/
|
||||||
*.AppImage
|
*.AppImage
|
||||||
|
*.blend1
|
||||||
@@ -7,3 +7,4 @@ pub mod registry;
|
|||||||
pub mod resource;
|
pub mod resource;
|
||||||
pub mod scenegraph;
|
pub mod scenegraph;
|
||||||
pub mod task;
|
pub mod task;
|
||||||
|
pub mod typed_datamap;
|
||||||
|
|||||||
54
src/core/typed_datamap.rs
Normal file
54
src/core/typed_datamap.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
use color_eyre::eyre::Result;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
use stardust_xr::schemas::{
|
||||||
|
flat::Datamap,
|
||||||
|
flex::flexbuffers::{FlexbufferSerializer, Reader, ReaderError},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TypedDatamap<T: DeserializeOwned + Serialize>(T);
|
||||||
|
impl<T: DeserializeOwned + Serialize> TypedDatamap<T> {
|
||||||
|
pub fn new(data: T) -> Self {
|
||||||
|
TypedDatamap(data)
|
||||||
|
}
|
||||||
|
pub fn from_flex(data: &[u8]) -> Result<Self> {
|
||||||
|
let root = Reader::get_root(data)?;
|
||||||
|
T::deserialize(root).map(Self::new).map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
pub fn to_datamap(&mut self) -> Result<Datamap> {
|
||||||
|
let mut serializer = FlexbufferSerializer::default();
|
||||||
|
self.0.serialize(&mut serializer)?;
|
||||||
|
Datamap::new(serializer.take_buffer()).map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
pub fn serialize(&mut self) -> Option<Vec<u8>> {
|
||||||
|
let mut serializer = FlexbufferSerializer::default();
|
||||||
|
self.0.serialize(&mut serializer).ok()?;
|
||||||
|
// check if this is actually a map
|
||||||
|
Reader::get_root(serializer.view()).ok()?.get_map().ok()?;
|
||||||
|
Some(serializer.take_buffer())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: DeserializeOwned + Serialize> Default for TypedDatamap<T>
|
||||||
|
where
|
||||||
|
T: Default,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(T::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: DeserializeOwned + Serialize> Deref for TypedDatamap<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: DeserializeOwned + Serialize> DerefMut for TypedDatamap<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,7 +144,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mouse_pointer = cli_args
|
let mut mouse_pointer = cli_args
|
||||||
.flatscreen
|
.flatscreen
|
||||||
.then(MousePointer::new)
|
.then(MousePointer::new)
|
||||||
.transpose()
|
.transpose()
|
||||||
@@ -158,8 +158,8 @@ fn main() {
|
|||||||
.flatten();
|
.flatten();
|
||||||
let mut controllers = (!cli_args.flatscreen && !cli_args.disable_controller)
|
let mut controllers = (!cli_args.flatscreen && !cli_args.disable_controller)
|
||||||
.then(|| {
|
.then(|| {
|
||||||
let left = SkController::new(Handed::Left).ok();
|
let left = SkController::new(&sk, Handed::Left).ok();
|
||||||
let right = SkController::new(Handed::Right).ok();
|
let right = SkController::new(&sk, Handed::Right).ok();
|
||||||
left.zip(right)
|
left.zip(right)
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
@@ -244,7 +244,7 @@ fn main() {
|
|||||||
wayland.as_mut().unwrap().frame_event(sk);
|
wayland.as_mut().unwrap().frame_event(sk);
|
||||||
destroy_queue::clear();
|
destroy_queue::clear();
|
||||||
|
|
||||||
if let Some(mouse_pointer) = &mouse_pointer {
|
if let Some(mouse_pointer) = &mut mouse_pointer {
|
||||||
mouse_pointer.update(sk);
|
mouse_pointer.update(sk);
|
||||||
}
|
}
|
||||||
if let Some((left_hand, right_hand)) = &mut hands {
|
if let Some((left_hand, right_hand)) = &mut hands {
|
||||||
|
|||||||
BIN
src/objects/input/cursor.blend
Normal file
BIN
src/objects/input/cursor.blend
Normal file
Binary file not shown.
BIN
src/objects/input/cursor.glb
Normal file
BIN
src/objects/input/cursor.glb
Normal file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::client::INTERNAL_CLIENT,
|
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||||
nodes::{
|
nodes::{
|
||||||
data::{mask_matches, Mask, PulseSender, PULSE_RECEIVER_REGISTRY},
|
data::{mask_matches, Mask, PulseSender, PULSE_RECEIVER_REGISTRY},
|
||||||
fields::Ray,
|
fields::Ray,
|
||||||
@@ -9,18 +9,25 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::{vec3, Mat4, Vec3};
|
use glam::{vec2, vec3, Mat4, Vec2, Vec3};
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use stardust_xr::schemas::{flat::Datamap, flex::flexbuffers};
|
use stardust_xr::schemas::flex::flexbuffers;
|
||||||
use std::{convert::TryFrom, sync::Arc};
|
use std::{convert::TryFrom, sync::Arc};
|
||||||
use stereokit::{ray_from_mouse, ButtonState, Key, StereoKitMultiThread};
|
use stereokit::{ray_from_mouse, ButtonState, Key, StereoKitMultiThread};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
const SK_KEYMAP: &str = include_str!("sk.kmp");
|
const SK_KEYMAP: &str = include_str!("sk.kmp");
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
struct MouseDatamap {
|
||||||
|
select: f32,
|
||||||
|
grab: f32,
|
||||||
|
scroll: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct KeyboardEvent {
|
struct KeyboardEvent {
|
||||||
pub keyboard: String,
|
pub keyboard: String,
|
||||||
pub keymap: Option<String>,
|
pub keymap: Option<String>,
|
||||||
pub keys_up: Option<Vec<u32>>,
|
pub keys_up: Option<Vec<u32>>,
|
||||||
@@ -31,6 +38,7 @@ pub struct MousePointer {
|
|||||||
node: Arc<Node>,
|
node: Arc<Node>,
|
||||||
spatial: Arc<Spatial>,
|
spatial: Arc<Spatial>,
|
||||||
pointer: Arc<InputMethod>,
|
pointer: Arc<InputMethod>,
|
||||||
|
datamap: TypedDatamap<MouseDatamap>,
|
||||||
keyboard_sender: Arc<PulseSender>,
|
keyboard_sender: Arc<PulseSender>,
|
||||||
}
|
}
|
||||||
impl MousePointer {
|
impl MousePointer {
|
||||||
@@ -53,11 +61,12 @@ impl MousePointer {
|
|||||||
node,
|
node,
|
||||||
spatial,
|
spatial,
|
||||||
pointer,
|
pointer,
|
||||||
|
datamap: Default::default(),
|
||||||
keyboard_sender,
|
keyboard_sender,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)]
|
#[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)]
|
||||||
pub fn update(&self, sk: &impl StereoKitMultiThread) {
|
pub fn update(&mut self, sk: &impl StereoKitMultiThread) {
|
||||||
let mouse = sk.input_mouse();
|
let mouse = sk.input_mouse();
|
||||||
|
|
||||||
let ray = ray_from_mouse(mouse.pos).unwrap();
|
let ray = ray_from_mouse(mouse.pos).unwrap();
|
||||||
@@ -71,30 +80,18 @@ impl MousePointer {
|
|||||||
);
|
);
|
||||||
{
|
{
|
||||||
// Set pointer input datamap
|
// Set pointer input datamap
|
||||||
let mut fbb = flexbuffers::Builder::default();
|
self.datamap.select = if sk.input_key(Key::MouseLeft).contains(ButtonState::ACTIVE) {
|
||||||
let mut map = fbb.start_map();
|
1.0f32
|
||||||
map.push(
|
} else {
|
||||||
"select",
|
0.0f32
|
||||||
if sk.input_key(Key::MouseLeft).contains(ButtonState::ACTIVE) {
|
};
|
||||||
1.0f32
|
self.datamap.grab = if sk.input_key(Key::MouseRight).contains(ButtonState::ACTIVE) {
|
||||||
} else {
|
1.0f32
|
||||||
0.0f32
|
} else {
|
||||||
},
|
0.0f32
|
||||||
);
|
};
|
||||||
map.push(
|
self.datamap.scroll = vec2(0.0, mouse.scroll_change / 120.0);
|
||||||
"grab",
|
*self.pointer.datamap.lock() = self.datamap.to_datamap().ok();
|
||||||
if sk.input_key(Key::MouseRight).contains(ButtonState::ACTIVE) {
|
|
||||||
1.0f32
|
|
||||||
} else {
|
|
||||||
0.0f32
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let mut scroll_vec = map.start_vector("scroll");
|
|
||||||
scroll_vec.push(0_f32);
|
|
||||||
scroll_vec.push(mouse.scroll_change / 120.0);
|
|
||||||
scroll_vec.end_vector();
|
|
||||||
map.end_map();
|
|
||||||
*self.pointer.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
|
|
||||||
}
|
}
|
||||||
self.send_keyboard_input(sk);
|
self.send_keyboard_input(sk);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::client::INTERNAL_CLIENT,
|
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||||
nodes::{
|
nodes::{
|
||||||
input::{tip::Tip, InputMethod, InputType},
|
input::{tip::Tip, InputMethod, InputType},
|
||||||
spatial::Spatial,
|
spatial::Spatial,
|
||||||
@@ -7,51 +7,70 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::Mat4;
|
use glam::{Mat4, Vec2};
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use stardust_xr::{
|
use serde::{Deserialize, Serialize};
|
||||||
schemas::{flat::Datamap, flex::flexbuffers},
|
use stardust_xr::values::Transform;
|
||||||
values::Transform,
|
|
||||||
};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use stereokit::{ButtonState, Handed, StereoKitMultiThread};
|
use stereokit::{
|
||||||
|
ButtonState, Color128, Handed, Model, RenderLayer, StereoKitDraw, StereoKitMultiThread,
|
||||||
|
};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
struct ControllerDatamap {
|
||||||
|
select: f32,
|
||||||
|
grab: f32,
|
||||||
|
scroll: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SkController {
|
pub struct SkController {
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
input: Arc<InputMethod>,
|
input: Arc<InputMethod>,
|
||||||
|
model: Model,
|
||||||
handed: Handed,
|
handed: Handed,
|
||||||
|
datamap: TypedDatamap<ControllerDatamap>,
|
||||||
}
|
}
|
||||||
impl SkController {
|
impl SkController {
|
||||||
pub fn new(handed: Handed) -> Result<Self> {
|
pub fn new(sk: &impl StereoKitMultiThread, handed: Handed) -> Result<Self> {
|
||||||
let _node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?;
|
let _node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?;
|
||||||
Spatial::add_to(&_node, None, Mat4::IDENTITY, false)?;
|
Spatial::add_to(&_node, None, Mat4::IDENTITY, false)?;
|
||||||
|
let model = sk.model_create_mem("cursor", include_bytes!("cursor.glb"), None)?;
|
||||||
let tip = InputType::Tip(Tip::default());
|
let tip = InputType::Tip(Tip::default());
|
||||||
let input = InputMethod::add_to(&_node, tip, None)?;
|
let input = InputMethod::add_to(&_node, tip, None)?;
|
||||||
Ok(SkController {
|
Ok(SkController {
|
||||||
_node,
|
_node,
|
||||||
input,
|
input,
|
||||||
handed,
|
handed,
|
||||||
|
model,
|
||||||
|
datamap: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[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 StereoKitMultiThread) {
|
pub fn update(&mut self, sk: &impl StereoKitDraw) {
|
||||||
let controller = sk.input_controller(self.handed);
|
let controller = sk.input_controller(self.handed);
|
||||||
*self.input.enabled.lock() = controller.tracked.contains(ButtonState::ACTIVE);
|
*self.input.enabled.lock() = controller.tracked.contains(ButtonState::ACTIVE);
|
||||||
if *self.input.enabled.lock() {
|
if *self.input.enabled.lock() {
|
||||||
|
sk.model_draw(
|
||||||
|
&self.model,
|
||||||
|
Mat4::from_rotation_translation(
|
||||||
|
controller.aim.orientation,
|
||||||
|
controller.aim.position,
|
||||||
|
),
|
||||||
|
Color128::default(),
|
||||||
|
RenderLayer::all(),
|
||||||
|
);
|
||||||
self.input.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.aim.position,
|
||||||
controller.pose.orientation,
|
controller.aim.orientation,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let mut fbb = flexbuffers::Builder::default();
|
self.datamap.select = controller.trigger;
|
||||||
let mut map = fbb.start_map();
|
self.datamap.grab = controller.grip;
|
||||||
map.push("select", controller.trigger);
|
self.datamap.scroll = controller.stick;
|
||||||
map.push("grab", controller.grip);
|
*self.input.datamap.lock() = self.datamap.to_datamap().ok();
|
||||||
map.end_map();
|
|
||||||
*self.input.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::client::INTERNAL_CLIENT,
|
core::{client::INTERNAL_CLIENT, typed_datamap::TypedDatamap},
|
||||||
nodes::{
|
nodes::{
|
||||||
input::{hand::Hand, InputMethod, InputType},
|
input::{hand::Hand, InputMethod, InputType},
|
||||||
spatial::Spatial,
|
spatial::Spatial,
|
||||||
@@ -9,10 +9,8 @@ use crate::{
|
|||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use stardust_xr::schemas::{
|
use serde::{Deserialize, Serialize};
|
||||||
flat::{Datamap, Hand as FlatHand, Joint},
|
use stardust_xr::schemas::flat::{Hand as FlatHand, Joint};
|
||||||
flex::flexbuffers,
|
|
||||||
};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use stereokit::{ButtonState, HandJoint, Handed, StereoKitMultiThread};
|
use stereokit::{ButtonState, HandJoint, Handed, StereoKitMultiThread};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
@@ -25,10 +23,17 @@ fn convert_joint(joint: HandJoint) -> Joint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
struct HandDatamap {
|
||||||
|
pinch_strength: f32,
|
||||||
|
grab_strength: f32,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SkHand {
|
pub struct SkHand {
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
input: Arc<InputMethod>,
|
input: Arc<InputMethod>,
|
||||||
handed: Handed,
|
handed: Handed,
|
||||||
|
datamap: TypedDatamap<HandDatamap>,
|
||||||
}
|
}
|
||||||
impl SkHand {
|
impl SkHand {
|
||||||
pub fn new(handed: Handed) -> Result<Self> {
|
pub fn new(handed: Handed) -> Result<Self> {
|
||||||
@@ -45,6 +50,7 @@ impl SkHand {
|
|||||||
_node,
|
_node,
|
||||||
input,
|
input,
|
||||||
handed,
|
handed,
|
||||||
|
datamap: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
#[instrument(level = "debug", name = "Update Hand Input Method", skip_all)]
|
#[instrument(level = "debug", name = "Update Hand Input Method", skip_all)]
|
||||||
@@ -54,6 +60,7 @@ impl SkHand {
|
|||||||
let controller = sk.input_controller(self.handed);
|
let controller = sk.input_controller(self.handed);
|
||||||
*self.input.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);
|
||||||
|
sk.input_hand_visible(self.handed, *self.input.enabled.lock());
|
||||||
if *self.input.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]);
|
||||||
@@ -86,11 +93,8 @@ impl SkHand {
|
|||||||
hand.base.elbow = None;
|
hand.base.elbow = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut fbb = flexbuffers::Builder::default();
|
self.datamap.pinch_strength = sk_hand.pinch_activation;
|
||||||
let mut map = fbb.start_map();
|
self.datamap.grab_strength = sk_hand.grip_activation;
|
||||||
map.push("grab_strength", sk_hand.grip_activation);
|
*self.input.datamap.lock() = self.datamap.to_datamap().ok();
|
||||||
map.push("pinch_strength", sk_hand.pinch_activation);
|
|
||||||
map.end_map();
|
|
||||||
*self.input.datamap.lock() = Datamap::new(fbb.take_buffer()).ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user