grab with realign

This commit is contained in:
galister
2023-12-09 22:26:55 +01:00
parent 1842259e66
commit 6cfbc6ffcd
10 changed files with 289 additions and 211 deletions

View File

@@ -1,12 +1,7 @@
[profile.release-with-debug] [profile.release-with-debug]
inherits = "release" inherits = "release"
debuginfo-level = 1
jemalloc = false
debug = true debug = true
[rust]
debuginfo-level = 1
[package] [package]
name = "wlx-overlay-s" name = "wlx-overlay-s"
version = "0.1.0" version = "0.1.0"

View File

@@ -26,14 +26,21 @@ pub enum TrackedDeviceRole {
Tracker, Tracker,
} }
pub struct InputState<TState, THand> { pub struct InputState {
pub hmd: Affine3A, pub hmd: Affine3A,
pub pointers: [Pointer<THand>; 2], pub pointers: [Pointer; 2],
pub devices: Vec<TrackedDevice>, pub devices: Vec<TrackedDevice>,
pub(super) data: TState,
} }
impl<TState, THand> InputState<TState, THand> { impl InputState {
pub fn new() -> Self {
Self {
hmd: Affine3A::IDENTITY,
pointers: [Pointer::new(0), Pointer::new(1)],
devices: Vec::new(),
}
}
pub fn pre_update(&mut self) { pub fn pre_update(&mut self) {
self.pointers[0].before = self.pointers[0].now; self.pointers[0].before = self.pointers[0].now;
self.pointers[1].before = self.pointers[1].now; self.pointers[1].before = self.pointers[1].now;
@@ -86,7 +93,7 @@ impl<TState, THand> InputState<TState, THand> {
let hmd_up = self.hmd.transform_vector3a(Vec3A::Y); let hmd_up = self.hmd.transform_vector3a(Vec3A::Y);
let dot = let dot =
hmd_up.dot(hand.pose.transform_vector3a(Vec3A::X)) * (1.0 - 2.0 * hand.hand as f32); hmd_up.dot(hand.pose.transform_vector3a(Vec3A::X)) * (1.0 - 2.0 * hand.idx as f32);
hand.interaction.mode = if dot < -0.85 { hand.interaction.mode = if dot < -0.85 {
PointerMode::Right PointerMode::Right
@@ -137,17 +144,28 @@ impl Default for InteractionState {
} }
} }
pub struct Pointer<THand> { pub struct Pointer {
pub idx: usize, pub idx: usize,
pub hand: u8,
pub pose: Affine3A, pub pose: Affine3A,
pub now: PointerState, pub now: PointerState,
pub before: PointerState, pub before: PointerState,
pub(super) interaction: InteractionState, pub(super) interaction: InteractionState,
pub(super) data: THand,
} }
#[derive(Debug, Clone, Copy, Default)] impl Pointer {
pub fn new(idx: usize) -> Self {
debug_assert!(idx == 0 || idx == 1);
Self {
idx,
pose: Affine3A::IDENTITY,
now: Default::default(),
before: Default::default(),
interaction: Default::default(),
}
}
}
#[derive(Clone, Copy, Default)]
pub struct PointerState { pub struct PointerState {
pub scroll: f32, pub scroll: f32,
pub click: bool, pub click: bool,
@@ -207,34 +225,46 @@ pub enum PointerMode {
Middle, Middle,
} }
impl<THand> Pointer<THand> { pub fn interact<O>(overlays: &mut OverlayContainer<O>, app: &mut AppState) -> [f32; 2]
pub fn interact<O>(&mut self, overlays: &mut OverlayContainer<O>, app: &mut AppState) -> f32 where
where
O: Default, O: Default,
{ {
if let Some(grab_data) = self.interaction.grabbed { [
interact_hand(0, overlays, app),
interact_hand(1, overlays, app),
]
}
fn interact_hand<O>(idx: usize, overlays: &mut OverlayContainer<O>, app: &mut AppState) -> f32
where
O: Default,
{
let hmd = &app.input_state.hmd;
let mut pointer = &mut app.input_state.pointers[idx];
if let Some(grab_data) = pointer.interaction.grabbed {
if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) { if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) {
self.handle_grabbed(grabbed); pointer.handle_grabbed(grabbed, hmd);
} else { } else {
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id); log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id);
self.interaction.grabbed = None; pointer.interaction.grabbed = None;
} }
return 0.1; return 0.1;
} }
let Some(mut hit) = self.get_nearest_hit(overlays) else { let Some(mut hit) = pointer.get_nearest_hit(overlays) else {
if let Some(hovered_id) = self.interaction.hovered_id.take() { if let Some(hovered_id) = pointer.interaction.hovered_id.take() {
if let Some(hovered) = overlays.mut_by_id(hovered_id) { if let Some(hovered) = overlays.mut_by_id(hovered_id) {
hovered.backend.on_left(app, self.idx); hovered.backend.on_left(app, idx);
} }
self.interaction.hovered_id = None; pointer = &mut app.input_state.pointers[idx];
pointer.interaction.hovered_id = None;
} }
if let Some(clicked_id) = self.interaction.clicked_id.take() { if let Some(clicked_id) = pointer.interaction.clicked_id.take() {
if let Some(clicked) = overlays.mut_by_id(clicked_id) { if let Some(clicked) = overlays.mut_by_id(clicked_id) {
let hit = PointerHit { let hit = PointerHit {
pointer: self.idx, pointer: pointer.idx,
overlay: clicked_id, overlay: clicked_id,
mode: self.interaction.mode, mode: pointer.interaction.mode,
..Default::default() ..Default::default()
}; };
clicked.backend.on_pointer(app, &hit, false); clicked.backend.on_pointer(app, &hit, false);
@@ -243,13 +273,14 @@ impl<THand> Pointer<THand> {
return 0.0; // no hit return 0.0; // no hit
}; };
if let Some(hovered_id) = self.interaction.hovered_id { if let Some(hovered_id) = pointer.interaction.hovered_id {
if hovered_id != hit.overlay { if hovered_id != hit.overlay {
if let Some(old_hovered) = overlays.mut_by_id(hovered_id) { if let Some(old_hovered) = overlays.mut_by_id(hovered_id) {
if Some(self.idx) == old_hovered.primary_pointer { if Some(pointer.idx) == old_hovered.primary_pointer {
old_hovered.primary_pointer = None; old_hovered.primary_pointer = None;
} }
old_hovered.backend.on_left(app, self.idx); old_hovered.backend.on_left(app, idx);
pointer = &mut app.input_state.pointers[idx];
} }
} }
} }
@@ -258,7 +289,7 @@ impl<THand> Pointer<THand> {
return 0.0; // no hit return 0.0; // no hit
}; };
self.interaction.hovered_id = Some(hit.overlay); pointer.interaction.hovered_id = Some(hit.overlay);
if let Some(primary_pointer) = hovered.primary_pointer { if let Some(primary_pointer) = hovered.primary_pointer {
if hit.pointer <= primary_pointer { if hit.pointer <= primary_pointer {
@@ -273,22 +304,25 @@ impl<THand> Pointer<THand> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
log::trace!("Hit: {} {:?}", hovered.state.name, hit); log::trace!("Hit: {} {:?}", hovered.state.name, hit);
if self.now.grab && !self.before.grab { if pointer.now.grab && !pointer.before.grab {
self.start_grab(hovered); pointer.start_grab(hovered);
return hit.dist; return hit.dist;
} }
hovered.backend.on_hover(app, &hit); hovered.backend.on_hover(app, &hit);
pointer = &mut app.input_state.pointers[idx];
if self.now.scroll.abs() > 0.1 { if pointer.now.scroll.abs() > 0.1 {
hovered.backend.on_scroll(app, &hit, self.now.scroll); let scroll = pointer.now.scroll;
hovered.backend.on_scroll(app, &hit, scroll);
pointer = &mut app.input_state.pointers[idx];
} }
if self.now.click && !self.before.click { if pointer.now.click && !pointer.before.click {
self.interaction.clicked_id = Some(hit.overlay); pointer.interaction.clicked_id = Some(hit.overlay);
hovered.backend.on_pointer(app, &hit, true); hovered.backend.on_pointer(app, &hit, true);
} else if !self.now.click && self.before.click { } else if !pointer.now.click && pointer.before.click {
if let Some(clicked_id) = self.interaction.clicked_id.take() { if let Some(clicked_id) = pointer.interaction.clicked_id.take() {
if let Some(clicked) = overlays.mut_by_id(clicked_id) { if let Some(clicked) = overlays.mut_by_id(clicked_id) {
clicked.backend.on_pointer(app, &hit, false); clicked.backend.on_pointer(app, &hit, false);
} }
@@ -297,8 +331,9 @@ impl<THand> Pointer<THand> {
} }
} }
hit.dist hit.dist
} }
impl Pointer {
fn get_nearest_hit<O>(&mut self, overlays: &mut OverlayContainer<O>) -> Option<PointerHit> fn get_nearest_hit<O>(&mut self, overlays: &mut OverlayContainer<O>) -> Option<PointerHit>
where where
O: Default, O: Default,
@@ -362,7 +397,7 @@ impl<THand> Pointer<THand> {
log::debug!("Hand {}: grabbed {}", self.idx, overlay.state.name); log::debug!("Hand {}: grabbed {}", self.idx, overlay.state.name);
} }
fn handle_grabbed<O>(&mut self, overlay: &mut OverlayData<O>) fn handle_grabbed<O>(&mut self, overlay: &mut OverlayData<O>, hmd: &Affine3A)
where where
O: Default, O: Default,
{ {
@@ -386,6 +421,7 @@ impl<THand> Pointer<THand> {
} }
} }
overlay.state.transform.translation = self.pose.transform_point3a(grab_data.offset); overlay.state.transform.translation = self.pose.transform_point3a(grab_data.offset);
overlay.state.realign(hmd);
overlay.state.dirty = true; overlay.state.dirty = true;
} else { } else {
overlay.state.spawn_point = overlay.state.transform.translation; overlay.state.spawn_point = overlay.state.transform.translation;

View File

@@ -11,8 +11,9 @@ use ovr_overlay::{
TrackedDeviceIndex, TrackedDeviceIndex,
}; };
use crate::backend::input::{ use crate::{
InputState, InteractionState, Pointer, PointerState, TrackedDevice, TrackedDeviceRole, backend::input::{TrackedDevice, TrackedDeviceRole},
state::AppState,
}; };
macro_rules! result_str { macro_rules! result_str {
@@ -46,7 +47,8 @@ const PATH_CLICK_MODIFIER_MIDDLE: &str = "/actions/default/in/ClickModifierMiddl
const INPUT_ANY: InputValueHandle = InputValueHandle(ovr_overlay::sys::k_ulInvalidInputValueHandle); const INPUT_ANY: InputValueHandle = InputValueHandle(ovr_overlay::sys::k_ulInvalidInputValueHandle);
pub(super) struct OpenVrInputState { pub(super) struct OpenVrInputSource {
hands: [OpenVrHandSource; 2],
set_hnd: ActionSetHandle, set_hnd: ActionSetHandle,
click_hnd: ActionHandle, click_hnd: ActionHandle,
grab_hnd: ActionHandle, grab_hnd: ActionHandle,
@@ -58,15 +60,14 @@ pub(super) struct OpenVrInputState {
click_modifier_middle_hnd: ActionHandle, click_modifier_middle_hnd: ActionHandle,
} }
pub(super) struct OpenVrHandState { pub(super) struct OpenVrHandSource {
pub(super) line_id: usize,
has_pose: bool, has_pose: bool,
input_hnd: InputValueHandle, input_hnd: InputValueHandle,
pose_hnd: ActionHandle, pose_hnd: ActionHandle,
haptics_hnd: ActionHandle, haptics_hnd: ActionHandle,
} }
impl InputState<OpenVrInputState, OpenVrHandState> { impl OpenVrInputSource {
pub fn new(input: &mut InputManager) -> Result<Self, &'static str> { pub fn new(input: &mut InputManager) -> Result<Self, &'static str> {
let set_hnd = result_str!(input.get_action_set_handle(SET_DEFAULT))?; let set_hnd = result_str!(input.get_action_set_handle(SET_DEFAULT))?;
@@ -96,27 +97,14 @@ impl InputState<OpenVrInputState, OpenVrHandState> {
.map(|path| Ok(result_str!(input.get_action_handle(path))?)) .map(|path| Ok(result_str!(input.get_action_handle(path))?))
.collect::<Result<_, &'static str>>()?; .collect::<Result<_, &'static str>>()?;
let hands: [Pointer<OpenVrHandState>; 2] = array::from_fn(|i| Pointer::<OpenVrHandState> { let hands: [OpenVrHandSource; 2] = array::from_fn(|i| OpenVrHandSource {
idx: i,
hand: i as u8,
now: PointerState::default(),
before: PointerState::default(),
pose: Affine3A::IDENTITY,
interaction: InteractionState::default(),
data: OpenVrHandState {
line_id: 0,
has_pose: false, has_pose: false,
input_hnd: input_hnd[i], input_hnd: input_hnd[i],
pose_hnd: pose_hnd[i], pose_hnd: pose_hnd[i],
haptics_hnd: haptics_hnd[i], haptics_hnd: haptics_hnd[i],
},
}); });
Ok(InputState { Ok(OpenVrInputSource {
hmd: Affine3A::IDENTITY,
pointers: hands,
devices: vec![],
data: OpenVrInputState {
set_hnd, set_hnd,
click_hnd, click_hnd,
grab_hnd, grab_hnd,
@@ -126,14 +114,19 @@ impl InputState<OpenVrInputState, OpenVrHandState> {
space_drag_hnd, space_drag_hnd,
click_modifier_right_hnd, click_modifier_right_hnd,
click_modifier_middle_hnd, click_modifier_middle_hnd,
}, hands,
}) })
} }
pub fn update(&mut self, input: &mut InputManager, system: &mut SystemManager) { pub fn update(
&mut self,
input: &mut InputManager,
system: &mut SystemManager,
app: &mut AppState,
) {
let aas = ActiveActionSet { let aas = ActiveActionSet {
0: ovr_overlay::sys::VRActiveActionSet_t { 0: ovr_overlay::sys::VRActiveActionSet_t {
ulActionSet: self.data.set_hnd.0, ulActionSet: self.set_hnd.0,
ulRestrictedToDevice: 0, ulRestrictedToDevice: 0,
ulSecondaryActionSet: 0, ulSecondaryActionSet: 0,
unPadding: 0, unPadding: 0,
@@ -146,70 +139,74 @@ impl InputState<OpenVrInputState, OpenVrHandState> {
let universe = ETrackingUniverseOrigin::TrackingUniverseStanding; let universe = ETrackingUniverseOrigin::TrackingUniverseStanding;
for i in 0..2 { for i in 0..2 {
let hand = &mut self.pointers[i]; let hand = &mut self.hands[i];
let app_hand = &mut app.input_state.pointers[i];
hand.data.has_pose = false; hand.has_pose = false;
let _ = input let _ = input
.get_pose_action_data_relative_to_now( .get_pose_action_data_relative_to_now(
hand.data.pose_hnd, hand.pose_hnd,
universe.clone(), universe.clone(),
0.005, 0.005,
INPUT_ANY, INPUT_ANY,
) )
.and_then(|pose| { .and_then(|pose| {
copy_from_hmd(&pose.0.pose.mDeviceToAbsoluteTracking, &mut hand.pose); copy_from_hmd(&pose.0.pose.mDeviceToAbsoluteTracking, &mut app_hand.pose);
hand.data.has_pose = true; hand.has_pose = true;
Ok(()) Ok(())
}); });
hand.now.click = input app_hand.now.click = input
.get_digital_action_data(self.data.click_hnd, hand.data.input_hnd) .get_digital_action_data(self.click_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.grab = input app_hand.now.grab = input
.get_digital_action_data(self.data.grab_hnd, hand.data.input_hnd) .get_digital_action_data(self.grab_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.alt_click = input app_hand.now.alt_click = input
.get_digital_action_data(self.data.alt_click_hnd, hand.data.input_hnd) .get_digital_action_data(self.alt_click_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.show_hide = input app_hand.now.show_hide = input
.get_digital_action_data(self.data.show_hide_hnd, hand.data.input_hnd) .get_digital_action_data(self.show_hide_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.space_drag = input app_hand.now.space_drag = input
.get_digital_action_data(self.data.space_drag_hnd, hand.data.input_hnd) .get_digital_action_data(self.space_drag_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.click_modifier_right = input app_hand.now.click_modifier_right = input
.get_digital_action_data(self.data.click_modifier_right_hnd, hand.data.input_hnd) .get_digital_action_data(self.click_modifier_right_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.click_modifier_middle = input app_hand.now.click_modifier_middle = input
.get_digital_action_data(self.data.click_modifier_middle_hnd, hand.data.input_hnd) .get_digital_action_data(self.click_modifier_middle_hnd, hand.input_hnd)
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
hand.now.scroll = input app_hand.now.scroll = input
.get_analog_action_data(self.data.scroll_hnd, hand.data.input_hnd) .get_analog_action_data(self.scroll_hnd, hand.input_hnd)
.map(|x| x.0.y) .map(|x| x.0.y)
.unwrap_or(0.0); .unwrap_or(0.0);
} }
let devices = system.get_device_to_absolute_tracking_pose(universe, 0.005); let devices = system.get_device_to_absolute_tracking_pose(universe, 0.005);
copy_from_hmd(&devices[0].mDeviceToAbsoluteTracking, &mut self.hmd); copy_from_hmd(
&devices[0].mDeviceToAbsoluteTracking,
&mut app.input_state.hmd,
);
} }
pub fn update_devices(&mut self, system: &mut SystemManager) { pub fn update_devices(&mut self, system: &mut SystemManager, app: &mut AppState) {
self.devices.clear(); app.input_state.devices.clear();
for i in 0..k_unMaxTrackedDeviceCount { for i in 0..k_unMaxTrackedDeviceCount {
let index = TrackedDeviceIndex(i); let index = TrackedDeviceIndex(i);
let maybe_role = match system.get_tracked_device_class(index) { let maybe_role = match system.get_tracked_device_class(index) {
@@ -234,11 +231,11 @@ impl InputState<OpenVrInputState, OpenVrHandState> {
if let Some(role) = maybe_role { if let Some(role) = maybe_role {
if let Some(device) = get_tracked_device(system, index, role) { if let Some(device) = get_tracked_device(system, index, role) {
self.devices.push(device); app.input_state.devices.push(device);
} }
} }
} }
self.devices.sort_by(|a, b| { app.input_state.devices.sort_by(|a, b| {
(a.role as u8) (a.role as u8)
.cmp(&(b.role as u8)) .cmp(&(b.role as u8))
.then(a.index.0.cmp(&b.index.0)) .then(a.index.0.cmp(&b.index.0))

View File

@@ -14,14 +14,17 @@ use vulkano::{
Handle, VulkanObject, Handle, VulkanObject,
}; };
use crate::{backend::openvr::lines::LinePool, state::AppState}; use crate::{
backend::{
input::interact,
openvr::{input::OpenVrInputSource, lines::LinePool},
},
state::AppState,
};
use self::{input::action_manifest_path, overlay::OpenVrOverlayData}; use self::{input::action_manifest_path, overlay::OpenVrOverlayData};
use super::{ use super::common::{OverlayContainer, TaskType};
common::{OverlayContainer, TaskType},
input::InputState,
};
pub mod input; pub mod input;
pub mod lines; pub mod lines;
@@ -55,14 +58,14 @@ pub fn openvr_run() {
let mut state = AppState::new(instance_extensions, device_extensions_fn); let mut state = AppState::new(instance_extensions, device_extensions_fn);
let mut overlays = OverlayContainer::<OpenVrOverlayData>::new(&mut state); let mut overlays = OverlayContainer::<OpenVrOverlayData>::new(&mut state);
state.input.set_desktop_extent(overlays.extent); state.hid_provider.set_desktop_extent(overlays.extent);
if let Err(e) = input_mngr.set_action_manifest(action_manifest_path()) { if let Err(e) = input_mngr.set_action_manifest(action_manifest_path()) {
log::error!("Failed to set action manifest: {}", e.description()); log::error!("Failed to set action manifest: {}", e.description());
return; return;
}; };
let Ok(mut input) = InputState::new(&mut input_mngr) else { let Ok(mut input_source) = OpenVrInputSource::new(&mut input_mngr) else {
log::error!("Failed to initialize input"); log::error!("Failed to initialize input");
return; return;
}; };
@@ -82,8 +85,10 @@ pub fn openvr_run() {
let mut due_tasks = VecDeque::with_capacity(4); let mut due_tasks = VecDeque::with_capacity(4);
let mut lines = LinePool::new(state.graphics.clone()); let mut lines = LinePool::new(state.graphics.clone());
input.pointers[0].data.line_id = lines.allocate(&mut overlay_mngr, &mut state); let pointer_lines = [
input.pointers[1].data.line_id = lines.allocate(&mut overlay_mngr, &mut state); lines.allocate(&mut overlay_mngr, &mut state),
lines.allocate(&mut overlay_mngr, &mut state),
];
loop { loop {
while let Some(event) = system_mngr.poll_next_event() { while let Some(event) = system_mngr.poll_next_event() {
@@ -102,7 +107,7 @@ pub fn openvr_run() {
} }
if next_device_update <= Instant::now() { if next_device_update <= Instant::now() {
input.update_devices(&mut system_mngr); input_source.update_devices(&mut system_mngr, &mut state);
next_device_update = Instant::now() + Duration::from_secs(30); next_device_update = Instant::now() + Duration::from_secs(30);
} }
@@ -118,19 +123,19 @@ pub fn openvr_run() {
} }
} }
input.pre_update(); state.input_state.pre_update();
input.update(&mut input_mngr, &mut system_mngr); input_source.update(&mut input_mngr, &mut system_mngr, &mut state);
input.post_update(); state.input_state.post_update();
input.pointers.iter_mut().for_each(|p| { let pointer_lengths = interact(&mut overlays, &mut state);
let dist = p.interact(&mut overlays, &mut state); for (idx, len) in pointer_lengths.iter().enumerate() {
if dist > 0.001 { lines.draw_from(
lines.draw_from(p.data.line_id, p.pose, dist, Vec4::ONE); pointer_lines[idx],
} else { state.input_state.pointers[idx].pose,
lines.draw_from(p.data.line_id, p.pose, 20.0, Vec4::ONE); *len,
// lines.hide(p.data.line_id); Vec4::ONE,
);
} }
});
lines.update(&mut overlay_mngr, &mut state); lines.update(&mut overlay_mngr, &mut state);
@@ -157,7 +162,7 @@ pub fn openvr_run() {
// playspace moved end frame // playspace moved end frame
state.input.on_new_frame(); state.hid_provider.on_new_frame();
let mut seconds_since_vsync = 0f32; let mut seconds_since_vsync = 0f32;
std::thread::sleep(Duration::from_secs_f32( std::thread::sleep(Duration::from_secs_f32(

View File

@@ -1,9 +1,12 @@
use std::sync::{ use std::{
f32::consts::PI,
sync::{
atomic::{AtomicUsize, Ordering}, atomic::{AtomicUsize, Ordering},
Arc, Arc,
},
}; };
use glam::{Affine2, Affine3A, Quat, Vec3A}; use glam::{Affine2, Affine3A, Mat3A, Quat, Vec3, Vec3A};
use vulkano::image::ImageViewAbstract; use vulkano::image::ImageViewAbstract;
use crate::state::AppState; use crate::state::AppState;
@@ -80,6 +83,45 @@ impl OverlayState {
pub fn reset(&mut self, _app: &mut AppState) { pub fn reset(&mut self, _app: &mut AppState) {
todo!() todo!()
} }
pub fn realign(&mut self, hmd: &Affine3A) {
let to_hmd = hmd.translation - self.transform.translation;
let up_dir: Vec3A;
if hmd.x_axis.dot(Vec3A::Y).abs() > 0.2 {
// Snap upright
up_dir = hmd.y_axis;
} else {
let dot = to_hmd.normalize().dot(hmd.z_axis);
let z_dist = to_hmd.length();
let y_dist = (self.transform.translation.y - hmd.translation.y).abs();
let x_angle = (y_dist / z_dist).asin();
if dot < -f32::EPSILON {
// facing down
let up_point = hmd.translation + z_dist / x_angle.cos() * Vec3A::Y;
up_dir = (up_point - self.transform.translation).normalize();
} else if dot > f32::EPSILON {
// facing up
let dn_point = hmd.translation + z_dist / x_angle.cos() * Vec3A::NEG_Y;
up_dir = (self.transform.translation - dn_point).normalize();
} else {
// perfectly upright
up_dir = Vec3A::Y;
}
}
let scale = self.transform.x_axis.length();
let col_z = (self.transform.translation - hmd.translation).normalize();
let col_y = up_dir;
let col_x = col_y.cross(col_z);
let col_y = col_z.cross(col_x).normalize();
let col_x = col_x.normalize();
let rot = Mat3A::from_quat(self.spawn_rotation)
* Mat3A::from_quat(Quat::from_axis_angle(Vec3::Y, PI));
self.transform.matrix3 = Mat3A::from_cols(col_x, col_y, col_z).mul_scalar(scale) * rot;
}
} }
impl<T> OverlayData<T> impl<T> OverlayData<T>

View File

@@ -11,7 +11,7 @@ use std::fs::File;
use std::mem::transmute; use std::mem::transmute;
use strum::{EnumIter, EnumString, IntoEnumIterator}; use strum::{EnumIter, EnumString, IntoEnumIterator};
pub fn initialize_input() -> Box<dyn InputProvider> { pub fn initialize() -> Box<dyn HidProvider> {
if let Some(uinput) = UInputProvider::try_new() { if let Some(uinput) = UInputProvider::try_new() {
log::info!("Initialized uinput."); log::info!("Initialized uinput.");
return Box::new(uinput); return Box::new(uinput);
@@ -21,7 +21,7 @@ pub fn initialize_input() -> Box<dyn InputProvider> {
Box::new(DummyProvider {}) Box::new(DummyProvider {})
} }
pub trait InputProvider { pub trait HidProvider {
fn mouse_move(&mut self, pos: Vec2); fn mouse_move(&mut self, pos: Vec2);
fn send_button(&self, button: u16, down: bool); fn send_button(&self, button: u16, down: bool);
fn wheel(&self, delta: i32); fn wheel(&self, delta: i32);
@@ -137,7 +137,7 @@ impl UInputProvider {
} }
} }
impl InputProvider for UInputProvider { impl HidProvider for UInputProvider {
fn mouse_move(&mut self, pos: Vec2) { fn mouse_move(&mut self, pos: Vec2) {
if self.mouse_moved { if self.mouse_moved {
return; return;
@@ -209,7 +209,7 @@ impl InputProvider for UInputProvider {
} }
} }
impl InputProvider for DummyProvider { impl HidProvider for DummyProvider {
fn mouse_move(&mut self, _pos: Vec2) {} fn mouse_move(&mut self, _pos: Vec2) {}
fn send_button(&self, _button: u16, _down: bool) {} fn send_button(&self, _button: u16, _down: bool) {}
fn wheel(&self, _delta: i32) {} fn wheel(&self, _delta: i32) {}

View File

@@ -2,7 +2,7 @@
mod backend; mod backend;
mod graphics; mod graphics;
mod gui; mod gui;
mod input; mod hid;
mod overlays; mod overlays;
mod shaders; mod shaders;
mod state; mod state;

View File

@@ -12,7 +12,7 @@ use std::{
use crate::{ use crate::{
backend::overlay::{OverlayData, OverlayState}, backend::overlay::{OverlayData, OverlayState},
gui::{color_parse, CanvasBuilder, Control}, gui::{color_parse, CanvasBuilder, Control},
input::{KeyModifier, VirtualKey, KEYS_TO_MODS}, hid::{KeyModifier, VirtualKey, KEYS_TO_MODS},
state::AppState, state::AppState,
}; };
use glam::{vec2, vec3a}; use glam::{vec2, vec3a};
@@ -129,7 +129,7 @@ fn key_press(
match control.state.as_mut() { match control.state.as_mut() {
Some(KeyButtonData::Key { vk, pressed }) => { Some(KeyButtonData::Key { vk, pressed }) => {
data.key_click(); data.key_click();
app.input.send_key(*vk as _, true); app.hid_provider.send_key(*vk as _, true);
*pressed = true; *pressed = true;
} }
Some(KeyButtonData::Modifier { Some(KeyButtonData::Modifier {
@@ -140,13 +140,13 @@ fn key_press(
*sticky = data.modifiers & *modifier == 0; *sticky = data.modifiers & *modifier == 0;
data.modifiers |= *modifier; data.modifiers |= *modifier;
data.key_click(); data.key_click();
app.input.set_modifiers(data.modifiers); app.hid_provider.set_modifiers(data.modifiers);
*pressed = true; *pressed = true;
} }
Some(KeyButtonData::Macro { verbs }) => { Some(KeyButtonData::Macro { verbs }) => {
data.key_click(); data.key_click();
for (vk, press) in verbs { for (vk, press) in verbs {
app.input.send_key(*vk as _, *press); app.hid_provider.send_key(*vk as _, *press);
} }
} }
Some(KeyButtonData::Exec { program, args }) => { Some(KeyButtonData::Exec { program, args }) => {
@@ -170,7 +170,7 @@ fn key_release(
) { ) {
match control.state.as_mut() { match control.state.as_mut() {
Some(KeyButtonData::Key { vk, pressed }) => { Some(KeyButtonData::Key { vk, pressed }) => {
app.input.send_key(*vk as _, false); app.hid_provider.send_key(*vk as _, false);
*pressed = false; *pressed = false;
} }
Some(KeyButtonData::Modifier { Some(KeyButtonData::Modifier {
@@ -180,7 +180,7 @@ fn key_release(
}) => { }) => {
if !*sticky { if !*sticky {
data.modifiers &= !*modifier; data.modifiers &= !*modifier;
app.input.set_modifiers(data.modifiers); app.hid_provider.set_modifiers(data.modifiers);
*pressed = false; *pressed = false;
} }
} }

View File

@@ -31,7 +31,7 @@ use crate::{
overlay::{OverlayData, OverlayRenderer, OverlayState, SplitOverlayBackend}, overlay::{OverlayData, OverlayRenderer, OverlayState, SplitOverlayBackend},
}, },
graphics::{Vert2Uv, WlxGraphics, WlxPipeline}, graphics::{Vert2Uv, WlxGraphics, WlxPipeline},
input::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT}, hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
shaders::{frag_sprite, vert_common}, shaders::{frag_sprite, vert_common},
state::{AppSession, AppState}, state::{AppSession, AppState},
}; };
@@ -76,12 +76,12 @@ impl InteractionHandler for ScreenInteractionHandler {
log::trace!("Hover: {:?}", hit.uv); log::trace!("Hover: {:?}", hit.uv);
if self.next_move < Instant::now() { if self.next_move < Instant::now() {
let pos = self.mouse_transform.transform_point2(hit.uv); let pos = self.mouse_transform.transform_point2(hit.uv);
app.input.mouse_move(pos); app.hid_provider.mouse_move(pos);
} }
} }
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) { fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
let pos = self.mouse_transform.transform_point2(hit.uv); let pos = self.mouse_transform.transform_point2(hit.uv);
app.input.mouse_move(pos); app.hid_provider.mouse_move(pos);
let btn = match hit.mode { let btn = match hit.mode {
PointerMode::Right => MOUSE_RIGHT, PointerMode::Right => MOUSE_RIGHT,
@@ -94,14 +94,14 @@ impl InteractionHandler for ScreenInteractionHandler {
Instant::now() + Duration::from_millis(app.session.click_freeze_time_ms); Instant::now() + Duration::from_millis(app.session.click_freeze_time_ms);
} }
app.input.send_button(btn, pressed); app.hid_provider.send_button(btn, pressed);
} }
fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta: f32) { fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta: f32) {
let millis = (1. - delta.abs()) * delta; let millis = (1. - delta.abs()) * delta;
if let Some(next_scroll) = Instant::now().checked_add(Duration::from_millis(millis as _)) { if let Some(next_scroll) = Instant::now().checked_add(Duration::from_millis(millis as _)) {
self.next_scroll = next_scroll; self.next_scroll = next_scroll;
} }
app.input.wheel(if delta < 0. { -1 } else { 1 }) app.hid_provider.wheel(if delta < 0. { -1 } else { 1 })
} }
fn on_left(&mut self, _app: &mut AppState, _hand: usize) {} fn on_left(&mut self, _app: &mut AppState, _hand: usize) {}
} }

View File

@@ -8,8 +8,10 @@ use vulkano::{
}; };
use crate::{ use crate::{
backend::common::TaskContainer, graphics::WlxGraphics, gui::font::FontCache, backend::{common::TaskContainer, input::InputState},
input::InputProvider, graphics::WlxGraphics,
gui::font::FontCache,
hid::HidProvider,
}; };
pub const WATCH_DEFAULT_POS: Vec3 = Vec3::new(0., 0., 0.15); pub const WATCH_DEFAULT_POS: Vec3 = Vec3::new(0., 0., 0.15);
@@ -17,12 +19,12 @@ pub const WATCH_DEFAULT_ROT: Quat = Quat::from_xyzw(0.7071066, 0., 0.7071066, 0.
pub struct AppState { pub struct AppState {
pub fc: FontCache, pub fc: FontCache,
//pub input: InputState,
pub session: AppSession, pub session: AppSession,
pub tasks: TaskContainer, pub tasks: TaskContainer,
pub graphics: Arc<WlxGraphics>, pub graphics: Arc<WlxGraphics>,
pub format: vulkano::format::Format, pub format: vulkano::format::Format,
pub input: Box<dyn InputProvider>, pub input_state: InputState,
pub hid_provider: Box<dyn HidProvider>,
} }
impl AppState { impl AppState {
@@ -39,7 +41,8 @@ impl AppState {
tasks: TaskContainer::new(), tasks: TaskContainer::new(),
graphics: graphics.clone(), graphics: graphics.clone(),
format: Format::R8G8B8A8_UNORM, format: Format::R8G8B8A8_UNORM,
input: crate::input::initialize_input(), input_state: InputState::new(),
hid_provider: crate::hid::initialize(),
} }
} }
} }