feat: openxr space rotate

This commit is contained in:
galister
2024-06-17 15:15:16 +09:00
parent c7aa88647c
commit d225250b77
3 changed files with 94 additions and 4 deletions

View File

@@ -141,6 +141,7 @@ pub(super) struct OpenXrHandSource {
action_alt_click: CustomClickAction,
action_show_hide: CustomClickAction,
action_space_drag: CustomClickAction,
action_space_rotate: CustomClickAction,
action_modifier_right: CustomClickAction,
action_modifier_middle: CustomClickAction,
action_move_mouse: CustomClickAction,
@@ -271,6 +272,11 @@ impl OpenXrHand {
.action_space_drag
.state(pointer.before.space_drag, xr, session)?;
pointer.now.space_rotate =
self.source
.action_space_rotate
.state(pointer.before.space_rotate, xr, session)?;
Ok(())
}
}
@@ -303,6 +309,7 @@ impl OpenXrHandSource {
action_alt_click: CustomClickAction::new(action_set, "alt_click", side)?,
action_show_hide: CustomClickAction::new(action_set, "show_hide", side)?,
action_space_drag: CustomClickAction::new(action_set, "space_drag", side)?,
action_space_rotate: CustomClickAction::new(action_set, "space_rotate", side)?,
action_modifier_right: CustomClickAction::new(
action_set,
"click_modifier_right",
@@ -456,6 +463,14 @@ fn suggest_bindings(instance: &xr::Instance, hands: &[&OpenXrHandSource; 2]) ->
instance
);
add_custom!(
profile.space_rotate,
&hands[0].action_space_rotate,
&hands[1].action_space_rotate,
bindings,
instance
);
add_custom!(
profile.click_modifier_right,
&hands[0].action_modifier_right,
@@ -509,6 +524,7 @@ struct OpenXrActionConfProfile {
alt_click: Option<OpenXrActionConfAction>,
show_hide: Option<OpenXrActionConfAction>,
space_drag: Option<OpenXrActionConfAction>,
space_rotate: Option<OpenXrActionConfAction>,
click_modifier_right: Option<OpenXrActionConfAction>,
click_modifier_middle: Option<OpenXrActionConfAction>,
move_mouse: Option<OpenXrActionConfAction>,

View File

@@ -37,6 +37,7 @@ enum ApiImpl {
pub(super) struct PlayspaceMover {
last_transform: Affine3A,
drag: Option<MoverData<Vec3A>>,
rotate: Option<MoverData<Quat>>,
libmonado: Library,
mnd_root: *mut c_void,
@@ -75,6 +76,7 @@ impl PlayspaceMover {
Ok(Self {
last_transform: Affine3A::IDENTITY,
drag: None,
rotate: None,
libmonado,
mnd_root: root,
@@ -84,6 +86,61 @@ impl PlayspaceMover {
}
pub fn update(&mut self, overlays: &mut OverlayContainer<OpenXrOverlayData>, state: &AppState) {
if let Some(mut data) = self.rotate.take() {
let pointer = &state.input_state.pointers[data.hand];
if !pointer.now.space_rotate {
self.last_transform = data.pose;
log::info!("End space rotate");
return;
}
let new_hand =
Quat::from_affine3(&(data.pose * 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 *= space_transform;
data.hand_pose = new_hand;
self.apply_offset(data.pose);
self.rotate = Some(data);
} else {
for (i, pointer) in state.input_state.pointers.iter().enumerate() {
if pointer.now.space_rotate {
let hand_pose = Quat::from_affine3(&self.last_transform);
self.rotate = Some(MoverData {
pose: self.last_transform,
hand: i,
hand_pose,
});
self.drag = None;
log::info!("Start space rotate");
return;
}
}
}
if let Some(mut data) = self.drag.take() {
let pointer = &state.input_state.pointers[data.hand];
if !pointer.now.space_drag {
@@ -137,8 +194,12 @@ impl PlayspaceMover {
pub fn reset_offset(&mut self) {
if self.drag.is_some() {
log::info!("Cannot reset offset while dragging.");
return;
log::info!("Space drag interrupted by manual reset");
self.drag = None;
}
if self.rotate.is_some() {
log::info!("Space rotate interrupted by manual reset");
self.rotate = None;
}
self.last_transform = Affine3A::IDENTITY;
@@ -147,8 +208,12 @@ impl PlayspaceMover {
pub fn fix_floor(&mut self, input: &InputState) {
if self.drag.is_some() {
log::info!("Cannot fix floor while dragging.");
return;
log::info!("Space drag interrupted by fix floor");
self.drag = None;
}
if self.rotate.is_some() {
log::info!("Space rotate interrupted by fix floor");
self.rotate = None;
}
let y1 = input.pointers[0].pose.translation.y;