playspace mover
This commit is contained in:
77
src/backend/openvr/helpers.rs
Normal file
77
src/backend/openvr/helpers.rs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
use glam::Affine3A;
|
||||||
|
use ovr_overlay::{pose::Matrix3x4, sys::HmdMatrix34_t};
|
||||||
|
|
||||||
|
pub trait Affine3AConvert {
|
||||||
|
fn from_affine(affine: Affine3A) -> Self;
|
||||||
|
fn to_affine(&self) -> Affine3A;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Affine3AConvert for Matrix3x4 {
|
||||||
|
fn from_affine(affine: Affine3A) -> Self {
|
||||||
|
Matrix3x4([
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.x,
|
||||||
|
affine.matrix3.y_axis.x,
|
||||||
|
affine.matrix3.z_axis.x,
|
||||||
|
affine.translation.x,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.y,
|
||||||
|
affine.matrix3.y_axis.y,
|
||||||
|
affine.matrix3.z_axis.y,
|
||||||
|
affine.translation.y,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.z,
|
||||||
|
affine.matrix3.y_axis.z,
|
||||||
|
affine.matrix3.z_axis.z,
|
||||||
|
affine.translation.z,
|
||||||
|
],
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_affine(&self) -> Affine3A {
|
||||||
|
Affine3A::from_cols_array_2d(&[
|
||||||
|
[self.0[0][0], self.0[1][0], self.0[2][0]],
|
||||||
|
[self.0[0][1], self.0[1][1], self.0[2][1]],
|
||||||
|
[self.0[0][2], self.0[1][2], self.0[2][2]],
|
||||||
|
[self.0[0][3], self.0[1][3], self.0[2][3]],
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Affine3AConvert for HmdMatrix34_t {
|
||||||
|
fn from_affine(affine: Affine3A) -> Self {
|
||||||
|
HmdMatrix34_t {
|
||||||
|
m: [
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.x,
|
||||||
|
affine.matrix3.y_axis.x,
|
||||||
|
affine.matrix3.z_axis.x,
|
||||||
|
affine.translation.x,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.y,
|
||||||
|
affine.matrix3.y_axis.y,
|
||||||
|
affine.matrix3.z_axis.y,
|
||||||
|
affine.translation.y,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
affine.matrix3.x_axis.z,
|
||||||
|
affine.matrix3.y_axis.z,
|
||||||
|
affine.matrix3.z_axis.z,
|
||||||
|
affine.translation.z,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_affine(&self) -> Affine3A {
|
||||||
|
Affine3A::from_cols_array_2d(&[
|
||||||
|
[self.m[0][0], self.m[1][0], self.m[2][0]],
|
||||||
|
[self.m[0][1], self.m[1][1], self.m[2][1]],
|
||||||
|
[self.m[0][2], self.m[1][2], self.m[2][2]],
|
||||||
|
[self.m[0][3], self.m[1][3], self.m[2][3]],
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{array, io::Write, path::Path};
|
use std::{array, io::Write, path::Path};
|
||||||
|
|
||||||
use glam::Affine3A;
|
|
||||||
use ovr_overlay::{
|
use ovr_overlay::{
|
||||||
input::{ActionHandle, ActionSetHandle, ActiveActionSet, InputManager, InputValueHandle},
|
input::{ActionHandle, ActionSetHandle, ActiveActionSet, InputManager, InputValueHandle},
|
||||||
sys::{
|
sys::{
|
||||||
k_unMaxTrackedDeviceCount, ETrackedControllerRole, ETrackedDeviceClass,
|
k_unMaxTrackedDeviceCount, ETrackedControllerRole, ETrackedDeviceClass,
|
||||||
ETrackedDeviceProperty, ETrackingUniverseOrigin, HmdMatrix34_t,
|
ETrackedDeviceProperty, ETrackingUniverseOrigin,
|
||||||
},
|
},
|
||||||
system::SystemManager,
|
system::SystemManager,
|
||||||
TrackedDeviceIndex,
|
TrackedDeviceIndex,
|
||||||
@@ -16,6 +15,8 @@ use crate::{
|
|||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::helpers::Affine3AConvert;
|
||||||
|
|
||||||
macro_rules! result_str {
|
macro_rules! result_str {
|
||||||
( $e:expr ) => {
|
( $e:expr ) => {
|
||||||
match $e {
|
match $e {
|
||||||
@@ -152,7 +153,7 @@ impl OpenVrInputSource {
|
|||||||
INPUT_ANY,
|
INPUT_ANY,
|
||||||
)
|
)
|
||||||
.and_then(|pose| {
|
.and_then(|pose| {
|
||||||
copy_from_hmd(&pose.0.pose.mDeviceToAbsoluteTracking, &mut app_hand.pose);
|
app_hand.pose = pose.0.pose.mDeviceToAbsoluteTracking.to_affine();
|
||||||
hand.has_pose = true;
|
hand.has_pose = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -199,10 +200,7 @@ impl OpenVrInputSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(
|
app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine();
|
||||||
&devices[0].mDeviceToAbsoluteTracking,
|
|
||||||
&mut app.input_state.hmd,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_devices(&mut self, system: &mut SystemManager, app: &mut AppState) {
|
pub fn update_devices(&mut self, system: &mut SystemManager, app: &mut AppState) {
|
||||||
@@ -272,21 +270,6 @@ fn get_tracked_device(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_from_hmd(in_mat: &HmdMatrix34_t, out_mat: &mut Affine3A) {
|
|
||||||
out_mat.x_axis[0] = in_mat.m[0][0];
|
|
||||||
out_mat.x_axis[1] = in_mat.m[1][0];
|
|
||||||
out_mat.x_axis[2] = in_mat.m[2][0];
|
|
||||||
out_mat.y_axis[0] = in_mat.m[0][1];
|
|
||||||
out_mat.y_axis[1] = in_mat.m[1][1];
|
|
||||||
out_mat.y_axis[2] = in_mat.m[2][1];
|
|
||||||
out_mat.z_axis[0] = in_mat.m[0][2];
|
|
||||||
out_mat.z_axis[1] = in_mat.m[1][2];
|
|
||||||
out_mat.z_axis[2] = in_mat.m[2][2];
|
|
||||||
out_mat.w_axis[0] = in_mat.m[0][3];
|
|
||||||
out_mat.w_axis[1] = in_mat.m[1][3];
|
|
||||||
out_mat.w_axis[2] = in_mat.m[2][3];
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn action_manifest_path() -> &'static Path {
|
pub fn action_manifest_path() -> &'static Path {
|
||||||
let action_path = "/tmp/wlxoverlay-s/actions.json";
|
let action_path = "/tmp/wlxoverlay-s/actions.json";
|
||||||
std::fs::create_dir_all("/tmp/wlxoverlay-s").unwrap();
|
std::fs::create_dir_all("/tmp/wlxoverlay-s").unwrap();
|
||||||
|
|||||||
@@ -30,9 +30,11 @@ use self::{input::action_manifest_path, overlay::OpenVrOverlayData};
|
|||||||
|
|
||||||
use super::common::{BackendError, OverlayContainer, TaskType};
|
use super::common::{BackendError, OverlayContainer, TaskType};
|
||||||
|
|
||||||
|
pub mod helpers;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod lines;
|
pub mod lines;
|
||||||
pub mod overlay;
|
pub mod overlay;
|
||||||
|
pub mod playspace;
|
||||||
|
|
||||||
pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
||||||
let app_type = EVRApplicationType::VRApplication_Overlay;
|
let app_type = EVRApplicationType::VRApplication_Overlay;
|
||||||
@@ -47,6 +49,7 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
//let mut settings_mngr = context.settings_mngr();
|
//let mut settings_mngr = context.settings_mngr();
|
||||||
let mut input_mngr = context.input_mngr();
|
let mut input_mngr = context.input_mngr();
|
||||||
let mut system_mngr = context.system_mngr();
|
let mut system_mngr = context.system_mngr();
|
||||||
|
let mut chaperone_mgr = context.chaperone_setup_mngr();
|
||||||
let mut compositor_mngr = context.compositor_mngr();
|
let mut compositor_mngr = context.compositor_mngr();
|
||||||
|
|
||||||
let device_extensions_fn = |device: &PhysicalDevice| {
|
let device_extensions_fn = |device: &PhysicalDevice| {
|
||||||
@@ -68,6 +71,8 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
|
|
||||||
let mut overlays = OverlayContainer::<OpenVrOverlayData>::new(&mut state);
|
let mut overlays = OverlayContainer::<OpenVrOverlayData>::new(&mut state);
|
||||||
|
|
||||||
|
let mut space_mover = playspace::PlayspaceMover::new();
|
||||||
|
|
||||||
state.hid_provider.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()) {
|
||||||
@@ -146,6 +151,8 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
.iter_mut()
|
.iter_mut()
|
||||||
.for_each(|o| o.state.auto_movement(&mut state));
|
.for_each(|o| o.state.auto_movement(&mut state));
|
||||||
|
|
||||||
|
space_mover.update(&mut chaperone_mgr, &mut overlays, &state);
|
||||||
|
|
||||||
let pointer_lengths = interact(&mut overlays, &mut state);
|
let pointer_lengths = interact(&mut overlays, &mut state);
|
||||||
for (idx, len) in pointer_lengths.iter().enumerate() {
|
for (idx, len) in pointer_lengths.iter().enumerate() {
|
||||||
lines.draw_from(
|
lines.draw_from(
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ use crate::{
|
|||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::helpers::Affine3AConvert;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(super) struct OpenVrOverlayData {
|
pub(super) struct OpenVrOverlayData {
|
||||||
pub(super) handle: Option<OverlayHandle>,
|
pub(super) handle: Option<OverlayHandle>,
|
||||||
@@ -159,26 +161,7 @@ impl OverlayData<OpenVrOverlayData> {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let transform = Matrix3x4([
|
let transform = Matrix3x4::from_affine(self.state.transform);
|
||||||
[
|
|
||||||
self.state.transform.matrix3.x_axis.x,
|
|
||||||
self.state.transform.matrix3.y_axis.x,
|
|
||||||
self.state.transform.matrix3.z_axis.x,
|
|
||||||
self.state.transform.translation.x,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
self.state.transform.matrix3.x_axis.y,
|
|
||||||
self.state.transform.matrix3.y_axis.y,
|
|
||||||
self.state.transform.matrix3.z_axis.y,
|
|
||||||
self.state.transform.translation.y,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
self.state.transform.matrix3.x_axis.z,
|
|
||||||
self.state.transform.matrix3.y_axis.z,
|
|
||||||
self.state.transform.matrix3.z_axis.z,
|
|
||||||
self.state.transform.translation.z,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
if let Err(e) = overlay.set_transform_absolute(
|
if let Err(e) = overlay.set_transform_absolute(
|
||||||
handle,
|
handle,
|
||||||
|
|||||||
77
src/backend/openvr/playspace.rs
Normal file
77
src/backend/openvr/playspace.rs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
use glam::Vec3A;
|
||||||
|
use ovr_overlay::{chaperone_setup::ChaperoneSetupManager, sys::EChaperoneConfigFile};
|
||||||
|
|
||||||
|
use crate::{backend::common::OverlayContainer, state::AppState};
|
||||||
|
|
||||||
|
use super::overlay::OpenVrOverlayData;
|
||||||
|
|
||||||
|
pub(super) struct PlayspaceMover {
|
||||||
|
drag_hand: Option<usize>,
|
||||||
|
offset: Vec3A,
|
||||||
|
start_position: Vec3A,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlayspaceMover {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
drag_hand: None,
|
||||||
|
offset: Vec3A::ZERO,
|
||||||
|
start_position: Vec3A::ZERO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
chaperone_mgr: &mut ChaperoneSetupManager,
|
||||||
|
overlays: &mut OverlayContainer<OpenVrOverlayData>,
|
||||||
|
state: &AppState,
|
||||||
|
) {
|
||||||
|
if let Some(hand) = self.drag_hand {
|
||||||
|
let pointer = &state.input_state.pointers[hand];
|
||||||
|
if !pointer.now.space_drag {
|
||||||
|
self.drag_hand = None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hand_pos = state.input_state.pointers[hand].pose.translation;
|
||||||
|
|
||||||
|
overlays.iter_mut().for_each(|overlay| {
|
||||||
|
if overlay.state.grabbable {
|
||||||
|
overlay.state.transform.translation += hand_pos * -1.0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.offset += hand_pos;
|
||||||
|
self.apply_offset(chaperone_mgr);
|
||||||
|
} else {
|
||||||
|
for (i, pointer) in state.input_state.pointers.iter().enumerate() {
|
||||||
|
if pointer.now.space_drag {
|
||||||
|
self.drag_hand = Some(i);
|
||||||
|
self.start_position = pointer.pose.translation;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.offset = Vec3A::ZERO;
|
||||||
|
self.start_position = Vec3A::ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_offset(&mut self, chaperone_mgr: &mut ChaperoneSetupManager) {
|
||||||
|
let Some(mut zero_pose) =
|
||||||
|
chaperone_mgr.get_working_standing_zero_pose_to_raw_tracking_pose()
|
||||||
|
else {
|
||||||
|
log::warn!("Can't space drag - failed to get zero pose");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
zero_pose.m[0][3] = self.offset.x;
|
||||||
|
zero_pose.m[1][3] = self.offset.y;
|
||||||
|
zero_pose.m[2][3] = self.offset.z;
|
||||||
|
|
||||||
|
chaperone_mgr.set_working_standing_zero_pose_to_raw_tracking_pose(&zero_pose);
|
||||||
|
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user