feat: openxr space rotate
This commit is contained in:
@@ -200,6 +200,15 @@ impl PlayspaceMover {
|
|||||||
|
|
||||||
set_working_copy(&self.universe, chaperone_mgr, &mat);
|
set_working_copy(&self.universe, chaperone_mgr, &mat);
|
||||||
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
|
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
|
||||||
|
|
||||||
|
if self.drag.is_some() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn playspace_changed(
|
pub fn playspace_changed(
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ pub(super) struct OpenXrHandSource {
|
|||||||
action_alt_click: CustomClickAction,
|
action_alt_click: CustomClickAction,
|
||||||
action_show_hide: CustomClickAction,
|
action_show_hide: CustomClickAction,
|
||||||
action_space_drag: CustomClickAction,
|
action_space_drag: CustomClickAction,
|
||||||
|
action_space_rotate: CustomClickAction,
|
||||||
action_modifier_right: CustomClickAction,
|
action_modifier_right: CustomClickAction,
|
||||||
action_modifier_middle: CustomClickAction,
|
action_modifier_middle: CustomClickAction,
|
||||||
action_move_mouse: CustomClickAction,
|
action_move_mouse: CustomClickAction,
|
||||||
@@ -271,6 +272,11 @@ impl OpenXrHand {
|
|||||||
.action_space_drag
|
.action_space_drag
|
||||||
.state(pointer.before.space_drag, xr, session)?;
|
.state(pointer.before.space_drag, xr, session)?;
|
||||||
|
|
||||||
|
pointer.now.space_rotate =
|
||||||
|
self.source
|
||||||
|
.action_space_rotate
|
||||||
|
.state(pointer.before.space_rotate, xr, session)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,6 +309,7 @@ impl OpenXrHandSource {
|
|||||||
action_alt_click: CustomClickAction::new(action_set, "alt_click", side)?,
|
action_alt_click: CustomClickAction::new(action_set, "alt_click", side)?,
|
||||||
action_show_hide: CustomClickAction::new(action_set, "show_hide", side)?,
|
action_show_hide: CustomClickAction::new(action_set, "show_hide", side)?,
|
||||||
action_space_drag: CustomClickAction::new(action_set, "space_drag", 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_modifier_right: CustomClickAction::new(
|
||||||
action_set,
|
action_set,
|
||||||
"click_modifier_right",
|
"click_modifier_right",
|
||||||
@@ -456,6 +463,14 @@ fn suggest_bindings(instance: &xr::Instance, hands: &[&OpenXrHandSource; 2]) ->
|
|||||||
instance
|
instance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
add_custom!(
|
||||||
|
profile.space_rotate,
|
||||||
|
&hands[0].action_space_rotate,
|
||||||
|
&hands[1].action_space_rotate,
|
||||||
|
bindings,
|
||||||
|
instance
|
||||||
|
);
|
||||||
|
|
||||||
add_custom!(
|
add_custom!(
|
||||||
profile.click_modifier_right,
|
profile.click_modifier_right,
|
||||||
&hands[0].action_modifier_right,
|
&hands[0].action_modifier_right,
|
||||||
@@ -509,6 +524,7 @@ struct OpenXrActionConfProfile {
|
|||||||
alt_click: Option<OpenXrActionConfAction>,
|
alt_click: Option<OpenXrActionConfAction>,
|
||||||
show_hide: Option<OpenXrActionConfAction>,
|
show_hide: Option<OpenXrActionConfAction>,
|
||||||
space_drag: Option<OpenXrActionConfAction>,
|
space_drag: Option<OpenXrActionConfAction>,
|
||||||
|
space_rotate: Option<OpenXrActionConfAction>,
|
||||||
click_modifier_right: Option<OpenXrActionConfAction>,
|
click_modifier_right: Option<OpenXrActionConfAction>,
|
||||||
click_modifier_middle: Option<OpenXrActionConfAction>,
|
click_modifier_middle: Option<OpenXrActionConfAction>,
|
||||||
move_mouse: Option<OpenXrActionConfAction>,
|
move_mouse: Option<OpenXrActionConfAction>,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ enum ApiImpl {
|
|||||||
pub(super) struct PlayspaceMover {
|
pub(super) struct PlayspaceMover {
|
||||||
last_transform: Affine3A,
|
last_transform: Affine3A,
|
||||||
drag: Option<MoverData<Vec3A>>,
|
drag: Option<MoverData<Vec3A>>,
|
||||||
|
rotate: Option<MoverData<Quat>>,
|
||||||
|
|
||||||
libmonado: Library,
|
libmonado: Library,
|
||||||
mnd_root: *mut c_void,
|
mnd_root: *mut c_void,
|
||||||
@@ -75,6 +76,7 @@ impl PlayspaceMover {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
last_transform: Affine3A::IDENTITY,
|
last_transform: Affine3A::IDENTITY,
|
||||||
drag: None,
|
drag: None,
|
||||||
|
rotate: None,
|
||||||
|
|
||||||
libmonado,
|
libmonado,
|
||||||
mnd_root: root,
|
mnd_root: root,
|
||||||
@@ -84,6 +86,61 @@ impl PlayspaceMover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, overlays: &mut OverlayContainer<OpenXrOverlayData>, state: &AppState) {
|
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() {
|
if let Some(mut data) = self.drag.take() {
|
||||||
let pointer = &state.input_state.pointers[data.hand];
|
let pointer = &state.input_state.pointers[data.hand];
|
||||||
if !pointer.now.space_drag {
|
if !pointer.now.space_drag {
|
||||||
@@ -137,8 +194,12 @@ impl PlayspaceMover {
|
|||||||
|
|
||||||
pub fn reset_offset(&mut self) {
|
pub fn reset_offset(&mut self) {
|
||||||
if self.drag.is_some() {
|
if self.drag.is_some() {
|
||||||
log::info!("Cannot reset offset while dragging.");
|
log::info!("Space drag interrupted by manual reset");
|
||||||
return;
|
self.drag = None;
|
||||||
|
}
|
||||||
|
if self.rotate.is_some() {
|
||||||
|
log::info!("Space rotate interrupted by manual reset");
|
||||||
|
self.rotate = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_transform = Affine3A::IDENTITY;
|
self.last_transform = Affine3A::IDENTITY;
|
||||||
@@ -147,8 +208,12 @@ impl PlayspaceMover {
|
|||||||
|
|
||||||
pub fn fix_floor(&mut self, input: &InputState) {
|
pub fn fix_floor(&mut self, input: &InputState) {
|
||||||
if self.drag.is_some() {
|
if self.drag.is_some() {
|
||||||
log::info!("Cannot fix floor while dragging.");
|
log::info!("Space drag interrupted by fix floor");
|
||||||
return;
|
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;
|
let y1 = input.pointers[0].pose.translation.y;
|
||||||
|
|||||||
Reference in New Issue
Block a user