initial commit

This commit is contained in:
galister
2023-11-10 09:15:37 +09:00
parent f193f33f4e
commit e5ab46be91
25 changed files with 2721 additions and 1014 deletions

View File

@@ -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,
}