Skip to content

Commit

Permalink
initial naive playspace mover impl
Browse files Browse the repository at this point in the history
  • Loading branch information
RinLovesYou committed Apr 29, 2024
1 parent c70833b commit 3fe5384
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ input-linux = "0.6.0"
json = { version = "0.12.4", optional = true }
json5 = "0.4.1"
libc = "0.2.153"
libloading = "0.8.3"
log = "0.4.21"
once_cell = "1.19.0"
openxr = { version = "0.17.1", features = ["linked"], optional = true }
Expand Down
17 changes: 17 additions & 0 deletions src/backend/openxr/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub(super) struct OpenXrHandSource {
action_scroll: xr::Action<f32>,
action_alt_click: xr::Action<f32>,
action_show_hide: xr::Action<bool>,
action_space_drag: xr::Action<bool>,
action_click_modifier_right: xr::Action<bool>,
action_click_modifier_middle: xr::Action<bool>,
action_move_mouse: xr::Action<bool>,
Expand Down Expand Up @@ -201,6 +202,12 @@ impl OpenXrHand {
.state(&xr.session, xr::Path::NULL)?
.current_state;

pointer.now.space_drag = self
.source
.action_space_drag
.state(&xr.session, xr::Path::NULL)?
.current_state;

Ok(())
}
}
Expand Down Expand Up @@ -259,6 +266,11 @@ impl OpenXrHandSource {
&format!("{} hand haptics", side),
&[],
)?;
let action_space_drag = action_set.create_action::<bool>(
&format!("{}_space_drag", side),
&format!("{} hand space drag", side),
&[],
)?;

Ok(Self {
action_pose,
Expand All @@ -271,6 +283,7 @@ impl OpenXrHandSource {
action_click_modifier_middle,
action_move_mouse,
action_haptics,
action_space_drag,
})
}
}
Expand Down Expand Up @@ -439,6 +452,10 @@ fn suggest_bindings(
&hands[0].action_show_hide,
instance.string_to_path("/user/hand/left/input/b/click")?,
),
xr::Binding::new(
&hands[1].action_space_drag,
instance.string_to_path("/user/hand/right/input/b/click")?,
),
xr::Binding::new(
&hands[0].action_click_modifier_right,
instance.string_to_path("/user/hand/left/input/b/touch")?,
Expand Down
3 changes: 3 additions & 0 deletions src/backend/openxr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mod input;
mod lines;
mod overlay;
mod swapchain;
mod playspace;

const VIEW_TYPE: xr::ViewConfigurationType = xr::ViewConfigurationType::PRIMARY_STEREO;
const VIEW_COUNT: u32 = 2;
Expand Down Expand Up @@ -72,6 +73,7 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
notifications.run_udp();

let mut delete_queue = vec![];
let mut space_mover = playspace::PlayspaceMover::new();

#[cfg(feature = "osc")]
let mut osc_sender =
Expand Down Expand Up @@ -204,6 +206,7 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
}

watch_fade(&mut app_state, overlays.mut_by_id(watch_id).unwrap()); // want panic
space_mover.update(&mut overlays, &app_state);

for o in overlays.iter_mut() {
o.after_input(&mut app_state)?;
Expand Down
134 changes: 134 additions & 0 deletions src/backend/openxr/playspace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::ffi::c_void;

use glam::Vec3A;
use libloading::{Library, Symbol};

use crate::{
backend::common::OverlayContainer,
state::AppState,
};

use super::overlay::OpenXrOverlayData;

pub(super) struct PlayspaceMover {
drag_hand: Option<usize>,
offset: Vec3A,
start_position: Vec3A,

has_pressed: bool,
has_unpressed: bool,
pressed_timer: std::time::Instant,

libmonado: Library,
mnd_root: *mut c_void,
playspace_move: extern "C" fn(*mut c_void, f32, f32, f32) -> i32,
}

impl PlayspaceMover {
pub fn new() -> Self {
unsafe {
//user currently has to manually specify this. ex: LIBMONADO_PATH="/home/sarah/.local/share/envision/prefixes/c6cea4c7-69d5-4a36-af9d-ddf14e1222a6/lib/libmonado.so"
let libmonado_path = std::env::var("LIBMONADO_PATH");
let libmonado_path = match libmonado_path {
Ok(path) => path,
Err(_) => {
log::error!("please specify the path to libmonado.so using the LIBMONADO_PATH environment variable.");
std::process::exit(1);
}
};

let libmonado = Library::new(libmonado_path).unwrap();
let root_create: Symbol<extern "C" fn(*mut *mut c_void) -> i32> =
libmonado.get(b"mnd_root_create").unwrap();
let playspace_move: Symbol<extern "C" fn(*mut c_void, f32, f32, f32) -> i32> =
libmonado.get(b"mnd_root_playspace_move").unwrap();
let playspace_move_raw = *playspace_move;

let mut root: *mut c_void = std::ptr::null_mut();

let ret = root_create(&mut root);

if ret != 0 {
log::error!("Failed to create root, error code: {}", ret);
}

Self {
drag_hand: None,
offset: Vec3A::ZERO,
start_position: Vec3A::ZERO,

has_pressed: false,
has_unpressed: false,
pressed_timer: std::time::Instant::now(),

libmonado,
mnd_root: root,
playspace_move: playspace_move_raw,
}
}
}

pub fn update(&mut self, overlays: &mut OverlayContainer<OpenXrOverlayData>, state: &AppState) {
if self.has_unpressed {
if self.pressed_timer.elapsed().as_secs_f32() > 0.2 {
self.has_unpressed = false;
self.has_pressed = false;
}
}

if let Some(hand) = self.drag_hand {
let pointer = &state.input_state.pointers[hand];
if !pointer.now.space_drag {
self.drag_hand = None;
log::info!("End space drag");
return;
}

let hand_pos = state.input_state.pointers[hand].pose.translation;
let relative_pos = hand_pos - self.start_position;

overlays.iter_mut().for_each(|overlay| {
if overlay.state.grabbable {
overlay.state.dirty = true;
overlay.state.transform.translation += relative_pos * -1.0;
}
});

self.offset += relative_pos;
self.apply_offset();
} else {
let mut pressed = false;
for (i, pointer) in state.input_state.pointers.iter().enumerate() {
if pointer.now.space_drag {
pressed = true;
if !self.has_pressed {
self.has_pressed = true;
break;
}

if self.has_pressed && self.has_unpressed {
self.drag_hand = Some(i);
self.start_position = pointer.pose.translation;
self.has_pressed = false;
self.has_unpressed = false;
break;
}
}
}

if !pressed && self.has_pressed && !self.has_unpressed {
self.has_unpressed = true;
self.pressed_timer = std::time::Instant::now();
}
}
}

pub fn reset(&mut self) {
self.offset = Vec3A::ZERO;
self.start_position = Vec3A::ZERO;
}

fn apply_offset(&mut self) {
(self.playspace_move)(self.mnd_root, self.offset.x, self.offset.y, self.offset.z);
}
}

0 comments on commit 3fe5384

Please sign in to comment.