From 04d0a77093176a76bdc27af3a7d073a4fdd65044 Mon Sep 17 00:00:00 2001 From: Nova Date: Tue, 23 May 2023 18:56:46 -0400 Subject: [PATCH] feat: eye gaze support --- src/main.rs | 5 +++ src/objects/input/eye_pointer.rs | 56 ++++++++++++++++++++++++++++++++ src/objects/input/mod.rs | 1 + 3 files changed, 62 insertions(+) create mode 100644 src/objects/input/eye_pointer.rs diff --git a/src/main.rs b/src/main.rs index ce36cab..5857285 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod wayland; use crate::core::destroy_queue; use crate::nodes::{audio, drawable, hmd, input}; +use crate::objects::input::eye_pointer::EyePointer; use crate::objects::input::mouse_pointer::MousePointer; use crate::objects::input::sk_controller::SkController; use crate::objects::input::sk_hand::SkHand; @@ -149,6 +150,7 @@ fn main() -> Result<()> { left.zip(right) }) .flatten(); + let eye_pointer = sk.device_has_eye_gaze().then(EyePointer::new).transpose()?; if hands.is_none() { sk.input_hand_visible(Handed::Left, false); @@ -218,6 +220,9 @@ fn main() -> Result<()> { left_controller.update(sk); right_controller.update(sk); } + if let Some(eye_pointer) = &eye_pointer { + eye_pointer.update(sk); + } input::process_input(); nodes::root::Root::send_frame_events(sk.time_elapsed_unscaled()); adaptive_sleep( diff --git a/src/objects/input/eye_pointer.rs b/src/objects/input/eye_pointer.rs new file mode 100644 index 0000000..61bf7b5 --- /dev/null +++ b/src/objects/input/eye_pointer.rs @@ -0,0 +1,56 @@ +use crate::{ + core::client::INTERNAL_CLIENT, + nodes::{ + input::{pointer::Pointer, InputMethod, InputType}, + spatial::Spatial, + Node, + }, +}; +use color_eyre::eyre::Result; +use glam::Mat4; +use nanoid::nanoid; +use serde::Serialize; +use stardust_xr::schemas::{flat::Datamap, flex::flexbuffers}; +use std::sync::Arc; +use stereokit::StereoKitMultiThread; +use tracing::instrument; + +#[derive(Debug, Clone, Serialize)] +pub struct KeyboardEvent { + pub keyboard: String, + pub keymap: Option, + pub keys_up: Option>, + pub keys_down: Option>, +} + +pub struct EyePointer { + spatial: Arc, + pointer: Arc, +} +impl EyePointer { + pub fn new() -> Result { + let node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?; + let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false).unwrap(); + let pointer = + InputMethod::add_to(&node, InputType::Pointer(Pointer::default()), None).unwrap(); + + Ok(EyePointer { spatial, pointer }) + } + #[instrument(level = "debug", name = "Update Flatscreen Pointer Ray", skip_all)] + pub fn update(&self, sk: &impl StereoKitMultiThread) { + let ray = sk.input_eyes(); + self.spatial + .set_local_transform(Mat4::from_rotation_translation( + ray.orientation, + ray.position, + )); + { + // Set pointer input datamap + let mut fbb = flexbuffers::Builder::default(); + let mut map = fbb.start_map(); + map.push("eye", 2); + map.end_map(); + *self.pointer.datamap.lock() = Datamap::new(fbb.take_buffer()).ok(); + } + } +} diff --git a/src/objects/input/mod.rs b/src/objects/input/mod.rs index 6ef66b9..108ac92 100644 --- a/src/objects/input/mod.rs +++ b/src/objects/input/mod.rs @@ -1,3 +1,4 @@ +pub mod eye_pointer; pub mod mouse_pointer; pub mod sk_controller; pub mod sk_hand;