Compare commits

..
11 Commits
Author SHA1 Message Date
galister 0c6e319fbe Release v0.3.0 2024-03-10 21:40:14 +01:00
galister 4679961cb2 openvr: smoother rotate 2024-03-10 20:56:13 +01:00
galister cb12357d68 openvr: dont overwrite bindings 2024-03-10 16:55:40 +01:00
galister b401fb28fd openvr: space rotate, recenter height adjust 2024-03-10 16:28:37 +01:00
galister 06478bbfc9 openvr: recenter rework 2024-03-10 14:40:50 +01:00
galister b57b77b06a openvr: reset offsets reloads from disk 2024-03-10 14:08:12 +01:00
galister 5a077e394c openvr: reload playspace on scene app change 2024-03-10 13:23:00 +01:00
galister a08c260898 openvr: chaperone movement fix 2024-03-10 13:19:08 +01:00
galister 45d08cd89b x11: fix cursor size 2024-03-10 00:10:28 +01:00
galister 49b9cc361d x11: fix screen gamma 2024-03-10 00:02:10 +01:00
galister 2f8dcaf110 use linked openxr 2024-03-09 21:21:48 +01:00
11 changed files with 172 additions and 46 deletions

No files matched your search

+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
- name: Package AppImage
run: |
export VERSION=$GITHUB_REF_NAME
./linuxdeploy-x86_64.AppImage -dwlx-overlay-s.desktop -iwlx-overlay-s.png --appdir=${APPDIR} --output appimage --exclude-library '*libpipewire*' --library libopenxr_loader.so
./linuxdeploy-x86_64.AppImage -dwlx-overlay-s.desktop -iwlx-overlay-s.png --appdir=${APPDIR} --output appimage --exclude-library '*libpipewire*'
mv WlxOverlay-S-$VERSION-x86_64.AppImage WlxOverlay-S-x86_64.AppImage
- name: Create Release
Generated
+3 -3
View File
@@ -2198,7 +2198,7 @@ dependencies = [
[[package]]
name = "ovr_overlay"
version = "0.0.0"
source = "git+https://github.com/galister/ovr_overlay_oyasumi#9d8a3f4017024e79b6ec7fa518b97df401bf259c"
source = "git+https://github.com/galister/ovr_overlay_oyasumi#61e0e77770212d64a76775a8c76637d1ca935942"
dependencies = [
"byteorder",
"derive_more",
@@ -2213,7 +2213,7 @@ dependencies = [
[[package]]
name = "ovr_overlay_sys"
version = "0.0.0"
source = "git+https://github.com/galister/ovr_overlay_oyasumi#9d8a3f4017024e79b6ec7fa518b97df401bf259c"
source = "git+https://github.com/galister/ovr_overlay_oyasumi#61e0e77770212d64a76775a8c76637d1ca935942"
dependencies = [
"autocxx",
"autocxx-build",
@@ -3722,7 +3722,7 @@ dependencies = [
[[package]]
name = "wlx-overlay-s"
version = "0.2.6"
version = "0.3.0"
dependencies = [
"anyhow",
"ash",
+1 -1
View File
@@ -4,7 +4,7 @@ debug = true
[package]
name = "wlx-overlay-s"
version = "0.2.6"
version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+4
View File
@@ -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 {}",
@@ -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,
}
+10 -3
View File
@@ -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";
@@ -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,
}
@@ -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)?;
@@ -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,
@@ -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)
@@ -302,9 +311,7 @@ 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() {
+3 -2
View File
@@ -158,7 +158,8 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
}
EVREventType::VREvent_SeatedZeroPoseReset
| EVREventType::VREvent_StandingZeroPoseReset
| EVREventType::VREvent_ChaperoneUniverseHasChanged => {
| EVREventType::VREvent_ChaperoneUniverseHasChanged
| EVREventType::VREvent_SceneApplicationChanged => {
playspace.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr);
}
_ => {}
@@ -213,7 +214,7 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
playspace.fix_floor(&mut chaperone_mgr, &state.input_state);
}
SystemTask::ResetPlayspace => {
playspace.reset_offset(&mut chaperone_mgr);
playspace.reset_offset(&mut chaperone_mgr, &state.input_state);
}
},
}
+128 -28
View File
@@ -1,4 +1,4 @@
use glam::{Affine3A, Vec3A};
use glam::{Affine3A, Quat, Vec3, Vec3A};
use ovr_overlay::{
chaperone_setup::ChaperoneSetupManager,
compositor::CompositorManager,
@@ -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,
}
}
@@ -38,10 +40,73 @@ 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(&(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 = 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(&(mat * 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;
}
@@ -49,27 +114,28 @@ impl PlayspaceMover {
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");
return;
}
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos);
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
overlays.iter_mut().for_each(|overlay| {
if overlay.state.grabbable {
overlay.state.dirty = true;
overlay.state.transform.translation -= overlay_offset;
overlay.state.transform.translation += overlay_offset;
}
});
chaperone_mgr.revert_working_copy();
apply_chaperone_offset(overlay_offset, chaperone_mgr);
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);
}
set_working_copy(&universe, chaperone_mgr, &data.pose);
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
} else {
@@ -80,25 +146,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) {
set_working_copy(&self.universe, chaperone_mgr, &Affine3A::IDENTITY);
pub fn reset_offset(&mut self, chaperone_mgr: &mut ChaperoneSetupManager, input: &InputState) {
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 = 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;
self.drag = None;
}
if self.rotate.is_some() {
log::info!("Space rotate interrupted by manual reset");
self.rotate = None;
}
}
@@ -109,7 +194,9 @@ impl PlayspaceMover {
log::warn!("Can't fix floor - failed to get zero pose");
return;
};
mat.translation.y += y1.min(y2) - 0.03;
let offset = y1.min(y2) - 0.03;
mat.translation.y += offset;
set_working_copy(&self.universe, chaperone_mgr, &mat);
chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live);
}
@@ -129,9 +216,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;
}
}
@@ -177,15 +268,24 @@ fn set_working_copy(
}
fn apply_chaperone_offset(offset: Vec3A, chaperone_mgr: &mut ChaperoneSetupManager) {
let mut quads = chaperone_mgr.get_working_collision_bounds_info();
let mut quads = chaperone_mgr.get_live_collision_bounds_info();
quads.iter_mut().for_each(|quad| {
quad.vCorners.iter_mut().for_each(|corner| {
corner.v[0] += offset.x;
if corner.v[1] != 0.0 {
corner.v[1] += offset.y;
}
corner.v[2] += offset.z;
});
});
chaperone_mgr.set_working_collision_bounds_info(&mut quads);
chaperone_mgr.set_working_collision_bounds_info(quads.as_mut_slice());
}
fn apply_chaperone_transform(transform: Affine3A, chaperone_mgr: &mut ChaperoneSetupManager) {
let mut quads = chaperone_mgr.get_live_collision_bounds_info();
quads.iter_mut().for_each(|quad| {
quad.vCorners.iter_mut().for_each(|corner| {
let coord = transform.transform_point3a(Vec3A::from_slice(&corner.v));
corner.v[0] = coord.x;
corner.v[2] = coord.z;
});
});
chaperone_mgr.set_working_collision_bounds_info(quads.as_mut_slice());
}
+1 -3
View File
@@ -4,9 +4,7 @@ use openxr as xr;
use xr::OverlaySessionCreateFlagsEXTX;
pub(super) fn init_xr() -> Result<(xr::Instance, xr::SystemId), anyhow::Error> {
let Ok(entry) = (unsafe { xr::Entry::load() }) else {
bail!("OpenXR Loader not found.");
};
let entry = xr::Entry::linked();
let Ok(available_extensions) = entry.enumerate_extensions() else {
bail!("Failed to enumerate OpenXR extensions.");
+10 -5
View File
@@ -48,6 +48,8 @@ use crate::{
state::{AppSession, AppState},
};
const CURSOR_SIZE: f32 = 16. / 1440.;
static DRM_FORMATS: once_cell::sync::OnceCell<Vec<DrmFormat>> = once_cell::sync::OnceCell::new();
pub struct ScreenInteractionHandler {
@@ -207,18 +209,21 @@ impl ScreenPipeline {
cmd.run_ref(&pass)?;
if let (Some(mouse), Some(mouse_view)) = (mouse, self.mouse.clone()) {
let size = CURSOR_SIZE * self.extentf[1];
let half_size = size * 0.5;
let vertex_buffer = app.graphics.upload_verts(
self.extentf[0],
self.extentf[1],
mouse.x * self.extentf[0] - 2.,
mouse.y * self.extentf[1] - 2.,
4.0,
4.0,
mouse.x * self.extentf[0] - half_size,
mouse.y * self.extentf[1] - half_size,
size,
size,
)?;
let set0 = self
.pipeline
.uniform_sampler(0, mouse_view.clone(), Filter::Linear)?;
.uniform_sampler(0, mouse_view.clone(), Filter::Nearest)?;
let pass = self.pipeline.create_pass(
self.extentf,
+5
View File
@@ -40,6 +40,11 @@
"type": "boolean",
"requirement": "optional"
},
{
"name": "/actions/default/in/SpaceRotate",
"type": "boolean",
"requirement": "optional"
},
{
"name": "/actions/default/in/LeftHand",
"type": "pose",
+6
View File
@@ -94,6 +94,12 @@ pub mod frag_screen {
void main()
{
out_color = texture(in_texture, in_uv);
// linear to srgb
bvec4 cutoff = lessThan(out_color, vec4(0.0031308));
vec4 higher = (pow(out_color, vec4(0.41666)) * vec4(1.055)) - vec4(0.055);
vec4 lower = out_color*vec4(12.92);
out_color = mix(higher, lower, cutoff);
out_color.a = 1.0;
}
",