initial commit
This commit is contained in:
@@ -1,152 +1,158 @@
|
||||
use std::{collections::VecDeque, time::Instant};
|
||||
use std::{
|
||||
collections::{BinaryHeap, VecDeque},
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use glam::{Affine3A, Vec2, Vec3, Vec3A};
|
||||
use ovr_overlay::TrackedDeviceIndex;
|
||||
use idmap::IdMap;
|
||||
|
||||
pub struct InputState<TState, THand> {
|
||||
pub hmd: Affine3A,
|
||||
pub pointers: [Pointer<THand>; 2],
|
||||
pub devices: Vec<TrackedDevice>,
|
||||
pub(super) data: TState,
|
||||
use crate::{
|
||||
overlays::{
|
||||
keyboard::create_keyboard,
|
||||
screen::{get_screens_wayland, get_screens_x11},
|
||||
watch::create_watch,
|
||||
},
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
use super::overlay::{OverlayData, OverlayState};
|
||||
|
||||
pub struct OverlayContainer<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
overlays: IdMap<usize, OverlayData<T>>,
|
||||
}
|
||||
|
||||
impl<TState, THand> InputState<TState, THand> {
|
||||
pub fn pre_update(&mut self) {
|
||||
self.pointers[0].before = self.pointers[0].now;
|
||||
self.pointers[1].before = self.pointers[1].now;
|
||||
impl<T> OverlayContainer<T>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
pub fn new(app: &mut AppState) -> Self {
|
||||
let mut overlays = IdMap::new();
|
||||
|
||||
let screens = if std::env::var("WAYLAND_DISPLAY").is_ok() {
|
||||
get_screens_wayland(&app.session)
|
||||
} else {
|
||||
get_screens_x11()
|
||||
};
|
||||
|
||||
let watch = create_watch::<T>(&app, &screens);
|
||||
overlays.insert(watch.state.id, watch);
|
||||
|
||||
let keyboard = create_keyboard(&app);
|
||||
overlays.insert(keyboard.state.id, keyboard);
|
||||
|
||||
let mut first = true;
|
||||
for mut screen in screens {
|
||||
if first {
|
||||
screen.state.want_visible = true;
|
||||
first = false;
|
||||
}
|
||||
overlays.insert(screen.state.id, screen);
|
||||
}
|
||||
|
||||
Self { overlays }
|
||||
}
|
||||
|
||||
pub fn post_update(&mut self) {
|
||||
for hand in &mut self.pointers {
|
||||
if hand.now.click_modifier_right {
|
||||
hand.interaction.mode = PointerMode::Right;
|
||||
continue;
|
||||
}
|
||||
|
||||
if hand.now.click_modifier_middle {
|
||||
hand.interaction.mode = PointerMode::Middle;
|
||||
continue;
|
||||
}
|
||||
|
||||
let hmd_up = self.hmd.transform_vector3a(Vec3A::Y);
|
||||
let dot =
|
||||
hmd_up.dot(hand.pose.transform_vector3a(Vec3A::X)) * (1.0 - 2.0 * hand.hand as f32);
|
||||
|
||||
hand.interaction.mode = if dot < -0.85 {
|
||||
PointerMode::Right
|
||||
} else if dot > 0.7 {
|
||||
PointerMode::Middle
|
||||
} else {
|
||||
PointerMode::Left
|
||||
};
|
||||
|
||||
let middle_click_orientation = false;
|
||||
let right_click_orientation = false;
|
||||
match hand.interaction.mode {
|
||||
PointerMode::Middle => {
|
||||
if !middle_click_orientation {
|
||||
hand.interaction.mode = PointerMode::Left;
|
||||
}
|
||||
}
|
||||
PointerMode::Right => {
|
||||
if !right_click_orientation {
|
||||
hand.interaction.mode = PointerMode::Left;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
pub fn mut_by_selector(&mut self, selector: &OverlaySelector) -> Option<&mut OverlayData<T>> {
|
||||
match selector {
|
||||
OverlaySelector::Id(id) => self.mut_by_id(*id),
|
||||
OverlaySelector::Name(name) => self.mut_by_name(name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_by_id<'a>(&'a mut self, id: usize) -> Option<&'a OverlayData<T>> {
|
||||
self.overlays.get(&id)
|
||||
}
|
||||
|
||||
pub fn mut_by_id<'a>(&'a mut self, id: usize) -> Option<&'a mut OverlayData<T>> {
|
||||
self.overlays.get_mut(&id)
|
||||
}
|
||||
|
||||
pub fn get_by_name<'a>(&'a mut self, name: &str) -> Option<&'a OverlayData<T>> {
|
||||
self.overlays.values().find(|o| *o.state.name == *name)
|
||||
}
|
||||
|
||||
pub fn mut_by_name<'a>(&'a mut self, name: &str) -> Option<&'a mut OverlayData<T>> {
|
||||
self.overlays.values_mut().find(|o| *o.state.name == *name)
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a OverlayData<T>> {
|
||||
self.overlays.values()
|
||||
}
|
||||
|
||||
pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &'a mut OverlayData<T>> {
|
||||
self.overlays.values_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pointer<THand> {
|
||||
pub hand: usize,
|
||||
pub pose: Affine3A,
|
||||
pub now: PointerState,
|
||||
pub before: PointerState,
|
||||
pub(super) interaction: InteractionState,
|
||||
pub(super) data: THand,
|
||||
pub enum OverlaySelector {
|
||||
Id(usize),
|
||||
Name(Arc<str>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct PointerState {
|
||||
pub scroll: f32,
|
||||
pub click: bool,
|
||||
pub grab: bool,
|
||||
pub alt_click: bool,
|
||||
pub show_hide: bool,
|
||||
pub space_drag: bool,
|
||||
pub click_modifier_right: bool,
|
||||
pub click_modifier_middle: bool,
|
||||
struct AppTask {
|
||||
pub not_before: Instant,
|
||||
pub task: TaskType,
|
||||
}
|
||||
|
||||
pub struct InteractionState {
|
||||
pub mode: PointerMode,
|
||||
pub grabbed: Option<GrabData>,
|
||||
pub clicked_id: Option<usize>,
|
||||
pub hovered_id: Option<usize>,
|
||||
pub release_actions: VecDeque<Box<dyn Fn()>>,
|
||||
pub next_push: Instant,
|
||||
impl PartialEq<AppTask> for AppTask {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.not_before == other.not_before
|
||||
}
|
||||
}
|
||||
impl PartialOrd<AppTask> for AppTask {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.not_before.cmp(&other.not_before).reverse())
|
||||
}
|
||||
}
|
||||
impl Eq for AppTask {}
|
||||
impl Ord for AppTask {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.not_before.cmp(&other.not_before).reverse()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InteractionState {
|
||||
fn default() -> Self {
|
||||
pub enum TaskType {
|
||||
Global(Box<dyn FnOnce(&mut AppState) + Send>),
|
||||
Overlay(
|
||||
OverlaySelector,
|
||||
Box<dyn FnOnce(&mut AppState, &mut OverlayState) + Send>,
|
||||
),
|
||||
}
|
||||
|
||||
pub struct TaskContainer {
|
||||
tasks: BinaryHeap<AppTask>,
|
||||
}
|
||||
|
||||
impl TaskContainer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
mode: PointerMode::Left,
|
||||
grabbed: None,
|
||||
clicked_id: None,
|
||||
hovered_id: None,
|
||||
release_actions: VecDeque::new(),
|
||||
next_push: Instant::now(),
|
||||
tasks: BinaryHeap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enqueue(&mut self, task: TaskType) {
|
||||
self.tasks.push(AppTask {
|
||||
not_before: Instant::now(),
|
||||
task,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn enqueue_at(&mut self, task: TaskType, not_before: Instant) {
|
||||
self.tasks.push(AppTask { not_before, task });
|
||||
}
|
||||
|
||||
pub fn retrieve_due(&mut self, dest_buf: &mut VecDeque<TaskType>) {
|
||||
let now = Instant::now();
|
||||
|
||||
while let Some(task) = self.tasks.peek() {
|
||||
if task.not_before > now {
|
||||
break;
|
||||
}
|
||||
|
||||
dest_buf.push_back(self.tasks.pop().unwrap().task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PointerHit {
|
||||
pub hand: usize,
|
||||
pub mode: PointerMode,
|
||||
pub primary: bool,
|
||||
pub uv: Vec2,
|
||||
pub dist: f32,
|
||||
}
|
||||
|
||||
struct RayHit {
|
||||
idx: usize,
|
||||
ray_pos: Vec3,
|
||||
hit_pos: Vec3,
|
||||
uv: Vec2,
|
||||
dist: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct GrabData {
|
||||
pub offset: Vec3,
|
||||
pub grabbed_id: usize,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub enum PointerMode {
|
||||
#[default]
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
}
|
||||
|
||||
pub struct TrackedDevice {
|
||||
pub index: TrackedDeviceIndex,
|
||||
pub valid: bool,
|
||||
pub soc: Option<f32>,
|
||||
pub charging: bool,
|
||||
pub role: TrackedDeviceRole,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum TrackedDeviceRole {
|
||||
None,
|
||||
Hmd,
|
||||
LeftHand,
|
||||
RightHand,
|
||||
Tracker,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user