Skip to content

Commit

Permalink
openvr: space rotate, recenter height adjust
Browse files Browse the repository at this point in the history
  • Loading branch information
galister committed Mar 10, 2024
1 parent 06478bb commit b401fb2
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 38 deletions.
4 changes: 4 additions & 0 deletions src/backend/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ impl InputState {
if hand.now.space_drag != hand.before.space_drag {
log::debug!("Hand {}: space_drag {}", hand.idx, hand.now.space_drag);
}
if hand.now.space_rotate != hand.before.space_rotate {
log::debug!("Hand {}: space_rotate {}", hand.idx, hand.now.space_rotate);
}
if hand.now.click_modifier_right != hand.before.click_modifier_right {
log::debug!(
"Hand {}: click_modifier_right {}",
Expand Down Expand Up @@ -189,6 +192,7 @@ pub struct PointerState {
pub alt_click: bool,
pub show_hide: bool,
pub space_drag: bool,
pub space_rotate: bool,
pub click_modifier_right: bool,
pub click_modifier_middle: bool,
}
Expand Down
31 changes: 16 additions & 15 deletions src/backend/openvr/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const PATH_SCROLL: &str = "/actions/default/in/Scroll";
const PATH_ALT_CLICK: &str = "/actions/default/in/AltClick";
const PATH_SHOW_HIDE: &str = "/actions/default/in/ShowHide";
const PATH_SPACE_DRAG: &str = "/actions/default/in/SpaceDrag";
const PATH_SPACE_ROTATE: &str = "/actions/default/in/SpaceRotate";
const PATH_CLICK_MODIFIER_RIGHT: &str = "/actions/default/in/ClickModifierRight";
const PATH_CLICK_MODIFIER_MIDDLE: &str = "/actions/default/in/ClickModifierMiddle";

Expand All @@ -50,6 +51,7 @@ pub(super) struct OpenVrInputSource {
alt_click_hnd: ActionHandle,
show_hide_hnd: ActionHandle,
space_drag_hnd: ActionHandle,
space_rotate_hnd: ActionHandle,
click_modifier_right_hnd: ActionHandle,
click_modifier_middle_hnd: ActionHandle,
}
Expand All @@ -72,6 +74,7 @@ impl OpenVrInputSource {
let alt_click_hnd = input.get_action_handle(PATH_ALT_CLICK)?;
let show_hide_hnd = input.get_action_handle(PATH_SHOW_HIDE)?;
let space_drag_hnd = input.get_action_handle(PATH_SPACE_DRAG)?;
let space_rotate_hnd = input.get_action_handle(PATH_SPACE_ROTATE)?;
let click_modifier_right_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_RIGHT)?;
let click_modifier_middle_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_MIDDLE)?;

Expand Down Expand Up @@ -106,6 +109,7 @@ impl OpenVrInputSource {
alt_click_hnd,
show_hide_hnd,
space_drag_hnd,
space_rotate_hnd,
click_modifier_right_hnd,
click_modifier_middle_hnd,
hands,
Expand Down Expand Up @@ -193,6 +197,11 @@ impl OpenVrInputSource {
.map(|x| x.0.bState)
.unwrap_or(false);

app_hand.now.space_rotate = input
.get_digital_action_data(self.space_rotate_hnd, hand.input_hnd)
.map(|x| x.0.bState)
.unwrap_or(false);

app_hand.now.click_modifier_right = input
.get_digital_action_data(self.click_modifier_right_hnd, hand.input_hnd)
.map(|x| x.0.bState)
Expand Down Expand Up @@ -302,27 +311,19 @@ fn get_tracked_device(
pub fn set_action_manifest(input: &mut InputManager) -> anyhow::Result<()> {
let action_path = CONFIG_ROOT_PATH.join("actions.json");

if !action_path.is_file() {
File::create(&action_path)?.write_all(include_bytes!("../../res/actions.json"))?;
}
File::create(&action_path)?.write_all(include_bytes!("../../res/actions.json"))?;

let binding_path = CONFIG_ROOT_PATH.join("actions_binding_knuckles.json");
if !binding_path.is_file() {
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_knuckles.json"))?;
}
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_knuckles.json"))?;

let binding_path = CONFIG_ROOT_PATH.join("actions_binding_vive.json");
if !binding_path.is_file() {
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_vive.json"))?;
}
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_vive.json"))?;

let binding_path = CONFIG_ROOT_PATH.join("actions_binding_oculus.json");
if !binding_path.is_file() {
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_oculus.json"))?;
}
File::create(&binding_path)?
.write_all(include_bytes!("../../res/actions_binding_oculus.json"))?;

if let Err(e) = input.set_action_manifest(action_path.as_path()) {
bail!("Failed to set action manifest: {}", e);
Expand Down
123 changes: 100 additions & 23 deletions src/backend/openvr/playspace.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glam::{Affine3A, Vec3, Vec3A};
use glam::{Affine3A, Quat, Vec3, Vec3A};
use ovr_overlay::{
chaperone_setup::ChaperoneSetupManager,
compositor::CompositorManager,
Expand All @@ -12,22 +12,24 @@ use crate::{

use super::{helpers::Affine3AConvert, overlay::OpenVrOverlayData};

struct DragData {
struct MoverData<T> {
pose: Affine3A,
hand: usize,
hand_pos: Vec3A,
hand_pose: T,
}

pub(super) struct PlayspaceMover {
universe: ETrackingUniverseOrigin,
last: Option<DragData>,
drag: Option<MoverData<Vec3A>>,
rotate: Option<MoverData<Quat>>,
}

impl PlayspaceMover {
pub fn new() -> Self {
Self {
universe: ETrackingUniverseOrigin::TrackingUniverseRawAndUncalibrated,
last: None,
drag: None,
rotate: None,
}
}

Expand All @@ -38,18 +40,80 @@ impl PlayspaceMover {
state: &AppState,
) {
let universe = self.universe.clone();
if let Some(data) = self.last.as_mut() {

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

let new_hand = Quat::from_affine3(&state.input_state.pointers[data.hand].raw_pose);

let dq = new_hand * data.hand_pose.conjugate();
let rel_y = f32::atan2(
2.0 * (dq.y * dq.w + dq.x * dq.z),
(2.0 * (dq.w * dq.w + dq.x * dq.x)) - 1.0,
);

let mut space_transform = Affine3A::from_rotation_y(rel_y);
let offset = (space_transform.transform_vector3a(state.input_state.hmd.translation)
- state.input_state.hmd.translation)
* -1.0;
let mut overlay_transform = Affine3A::from_rotation_y(-rel_y);

overlay_transform.translation = offset;
space_transform.translation = offset;

overlays.iter_mut().for_each(|overlay| {
if overlay.state.grabbable {
overlay.state.dirty = true;
overlay.state.transform.translation =
overlay_transform.transform_point3a(overlay.state.transform.translation);
}
});

data.pose = data.pose * space_transform;
data.hand_pose = new_hand;

if self.universe == ETrackingUniverseOrigin::TrackingUniverseStanding {
apply_chaperone_transform(space_transform.inverse(), chaperone_mgr);
}
set_working_copy(&universe, chaperone_mgr, &data.pose);
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
} else {
for (i, pointer) in state.input_state.pointers.iter().enumerate() {
if pointer.now.space_rotate {
let Some(mat) = get_working_copy(&universe, chaperone_mgr) else {
log::warn!("Can't space rotate - failed to get zero pose");
return;
};
let hand_pose = Quat::from_affine3(&pointer.raw_pose);
self.rotate = Some(MoverData {
pose: mat,
hand: i,
hand_pose,
});
self.drag = None;
log::info!("Start space rotate");
return;
}
}
}

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

let new_hand = data
.pose
.transform_point3a(state.input_state.pointers[data.hand].raw_pose.translation);
let relative_pos = new_hand - data.hand_pos;
let relative_pos = new_hand - data.hand_pose;

if relative_pos.length_squared() > 1000.0 {
log::warn!("Space drag too fast, ignoring");
Expand All @@ -66,7 +130,7 @@ impl PlayspaceMover {
});

data.pose.translation += relative_pos;
data.hand_pos = new_hand;
data.hand_pose = new_hand;

if self.universe == ETrackingUniverseOrigin::TrackingUniverseStanding {
apply_chaperone_offset(overlay_offset, chaperone_mgr);
Expand All @@ -81,35 +145,44 @@ impl PlayspaceMover {
return;
};
let hand_pos = mat.transform_point3a(pointer.raw_pose.translation);
self.last = Some(DragData {
self.drag = Some(MoverData {
pose: mat,
hand: i,
hand_pos,
hand_pose: hand_pos,
});
self.rotate = None;
log::info!("Start space drag");
break;
return;
}
}
}
}

pub fn reset_offset(&mut self, chaperone_mgr: &mut ChaperoneSetupManager, input: &InputState) {
let mut height = 1.7;
let mut height = 1.6;
if let Some(mat) = get_working_copy(&self.universe, chaperone_mgr) {
height = input.hmd.translation.y - mat.translation.y;
if self.universe == ETrackingUniverseOrigin::TrackingUniverseStanding {
apply_chaperone_transform(mat, chaperone_mgr);
}
}
let xform = Affine3A::from_translation(Vec3::Y * height);
if self.universe == ETrackingUniverseOrigin::TrackingUniverseStanding {
chaperone_mgr.reload_from_disk(EChaperoneConfigFile::EChaperoneConfigFile_Live);
}

let xform = if self.universe == ETrackingUniverseOrigin::TrackingUniverseSeated {
Affine3A::from_translation(Vec3::NEG_Y * height)
} else {
Affine3A::IDENTITY
};

set_working_copy(&self.universe, chaperone_mgr, &xform);
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);

if self.last.is_some() {
if self.drag.is_some() {
log::info!("Space drag interrupted by manual reset");
self.last = None;
} else {
log::info!("Playspace reset");
self.drag = None;
}
if self.rotate.is_some() {
log::info!("Space rotate interrupted by manual reset");
self.rotate = None;
}
}

Expand Down Expand Up @@ -142,9 +215,13 @@ impl PlayspaceMover {
self.universe = new_universe;
}

if self.last.is_some() {
if self.drag.is_some() {
log::info!("Space drag interrupted by external change");
self.last = None;
self.drag = None;
}
if self.rotate.is_some() {
log::info!("Space rotate interrupted by external change");
self.rotate = None;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/res/actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"type": "boolean",
"requirement": "optional"
},
{
"name": "/actions/default/in/SpaceRotate",
"type": "boolean",
"requirement": "optional"
},
{
"name": "/actions/default/in/LeftHand",
"type": "pose",
Expand Down

0 comments on commit b401fb2

Please sign in to comment.