laser colors, improve scaling (wip)

This commit is contained in:
galister
2024-01-28 18:50:50 +01:00
parent e1e8165cc6
commit 328ef3cfde
11 changed files with 73 additions and 27 deletions

View File

@@ -46,7 +46,7 @@ where
}; };
let mut watch = create_watch::<T>(&app, &screens); let mut watch = create_watch::<T>(&app, &screens);
watch.state.want_visible = false; watch.state.want_visible = true;
overlays.insert(watch.state.id, watch); overlays.insert(watch.state.id, watch);
let mut keyboard = create_keyboard(&app); let mut keyboard = create_keyboard(&app);

View File

@@ -424,7 +424,7 @@ impl Pointer {
overlay.state.realign(hmd); overlay.state.realign(hmd);
overlay.state.dirty = true; overlay.state.dirty = true;
} else { } else {
overlay.state.spawn_point = overlay.state.transform.translation; overlay.state.spawn_point = overlay.state.transform.translation.into();
self.interaction.grabbed = None; self.interaction.grabbed = None;
log::info!("Hand {}: dropped {}", self.idx, overlay.state.name); log::info!("Hand {}: dropped {}", self.idx, overlay.state.name);
} }

View File

@@ -21,6 +21,7 @@ static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(1);
pub(super) struct LinePool { pub(super) struct LinePool {
lines: IdMap<usize, OverlayData<OpenVrOverlayData>>, lines: IdMap<usize, OverlayData<OpenVrOverlayData>>,
view: Arc<ImageView>, view: Arc<ImageView>,
colors: [Vec4; 4],
} }
impl LinePool { impl LinePool {
@@ -46,6 +47,12 @@ impl LinePool {
LinePool { LinePool {
lines: IdMap::new(), lines: IdMap::new(),
view, view,
colors: [
Vec4::new(1., 1., 1., 1.),
Vec4::new(0., 0.375, 0.5, 1.),
Vec4::new(0.69, 0.188, 0., 1.),
Vec4::new(0.375, 0., 0.5, 1.),
],
} }
} }
@@ -56,7 +63,7 @@ impl LinePool {
state: OverlayState { state: OverlayState {
name: Arc::from(format!("wlx-line{}", id)), name: Arc::from(format!("wlx-line{}", id)),
show_hide: true, show_hide: true,
width: 0.002, spawn_scale: 0.002,
size: (0, 0), size: (0, 0),
..Default::default() ..Default::default()
}, },
@@ -77,13 +84,15 @@ impl LinePool {
id id
} }
pub fn draw_from(&mut self, id: usize, mut from: Affine3A, len: f32, color: Vec4) { pub fn draw_from(&mut self, id: usize, mut from: Affine3A, len: f32, color: usize) {
let rotation = Affine3A::from_axis_angle(Vec3::X, -PI * 0.5); let rotation = Affine3A::from_axis_angle(Vec3::X, -PI * 0.5);
from.translation = from.translation + from.transform_vector3a(Vec3A::NEG_Z) * (len * 0.5); from.translation = from.translation + from.transform_vector3a(Vec3A::NEG_Z) * (len * 0.5);
let transform = from * rotation * Affine3A::from_scale(Vec3::new(1., len / 0.002, 1.)); let transform = from * rotation * Affine3A::from_scale(Vec3::new(1., len / 0.002, 1.));
self.draw_transform(id, transform, color); debug_assert!(color < self.colors.len());
self.draw_transform(id, transform, self.colors[color]);
} }
fn draw_transform(&mut self, id: usize, transform: Affine3A, color: Vec4) { fn draw_transform(&mut self, id: usize, transform: Affine3A, color: Vec4) {

View File

@@ -1,4 +1,3 @@
use glam::Vec4;
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
sync::{ sync::{
@@ -143,13 +142,17 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
input_source.update(&mut input_mngr, &mut system_mngr, &mut state); input_source.update(&mut input_mngr, &mut system_mngr, &mut state);
state.input_state.post_update(); state.input_state.post_update();
overlays
.iter_mut()
.for_each(|o| o.state.auto_movement(&mut 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(
pointer_lines[idx], pointer_lines[idx],
state.input_state.pointers[idx].pose, state.input_state.pointers[idx].pose,
*len, *len,
Vec4::ONE, state.input_state.pointers[idx].interaction.mode as usize + 1,
); );
} }

View File

@@ -12,6 +12,8 @@ use crate::{
state::AppState, state::AppState,
}; };
const WIDTH: f32 = 1.0;
#[derive(Default)] #[derive(Default)]
pub(super) struct OpenVrOverlayData { pub(super) struct OpenVrOverlayData {
handle: Option<OverlayHandle>, handle: Option<OverlayHandle>,
@@ -118,12 +120,12 @@ impl OverlayData<OpenVrOverlayData> {
} }
} }
pub(super) fn upload_width(&self, overlay: &mut OverlayManager) { fn upload_width(&self, overlay: &mut OverlayManager) {
let Some(handle) = self.data.handle else { let Some(handle) = self.data.handle else {
log::debug!("{}: No overlay handle", self.state.name); log::debug!("{}: No overlay handle", self.state.name);
return; return;
}; };
if let Err(e) = overlay.set_width(handle, self.state.width) { if let Err(e) = overlay.set_width(handle, WIDTH) {
panic!("Failed to set overlay width: {}", e); panic!("Failed to set overlay width: {}", e);
} }
} }

View File

@@ -186,13 +186,17 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
app_state.input_state.hmd = hmd_pose_from_views(&views); app_state.input_state.hmd = hmd_pose_from_views(&views);
overlays
.iter_mut()
.for_each(|o| o.state.auto_movement(&mut app_state));
let pointer_lengths = interact(&mut overlays, &mut app_state); let pointer_lengths = interact(&mut overlays, &mut app_state);
for (idx, len) in pointer_lengths.iter().enumerate() { for (idx, len) in pointer_lengths.iter().enumerate() {
lines.draw_from( lines.draw_from(
pointer_lines[idx], pointer_lines[idx],
app_state.input_state.pointers[idx].pose, app_state.input_state.pointers[idx].pose,
*len, *len,
0, app_state.input_state.pointers[idx].interaction.mode as usize + 1,
); );
} }
@@ -210,6 +214,7 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
o.init(&mut app_state); o.init(&mut app_state);
o.data.init = true; o.data.init = true;
} }
o.render(&mut app_state); o.render(&mut app_state);
if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer) { if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer) {

View File

@@ -6,6 +6,7 @@ use super::{swapchain::SwapchainRenderData, transform_to_posef, XrState};
use crate::{ use crate::{
backend::{openxr::swapchain::create_swapchain_render_data, overlay::OverlayData}, backend::{openxr::swapchain::create_swapchain_render_data, overlay::OverlayData},
graphics::WlxCommandBuffer, graphics::WlxCommandBuffer,
state::AppState,
}; };
use vulkano::image::view::ImageView; use vulkano::image::view::ImageView;
@@ -51,6 +52,11 @@ impl OverlayData<OpenXrOverlayData> {
let sub_image = data.acquire_present_release(command_buffer, my_view); let sub_image = data.acquire_present_release(command_buffer, my_view);
let posef = transform_to_posef(&self.state.transform); let posef = transform_to_posef(&self.state.transform);
let scale_x = self.state.transform.matrix3.col(0).length();
log::info!("{}: scale_x = {}", self.state.name, scale_x);
let aspect_ratio = self.backend.extent()[1] as f32 / self.backend.extent()[0] as f32;
let scale_y = scale_x * aspect_ratio;
let quad = xr::CompositionLayerQuad::new() let quad = xr::CompositionLayerQuad::new()
.pose(posef) .pose(posef)
.sub_image(sub_image) .sub_image(sub_image)
@@ -58,9 +64,8 @@ impl OverlayData<OpenXrOverlayData> {
.layer_flags(CompositionLayerFlags::CORRECT_CHROMATIC_ABERRATION) .layer_flags(CompositionLayerFlags::CORRECT_CHROMATIC_ABERRATION)
.space(&xr.stage) .space(&xr.stage)
.size(xr::Extent2Df { .size(xr::Extent2Df {
width: self.state.width, width: scale_x,
height: (self.backend.extent()[1] as f32 / self.backend.extent()[0] as f32) height: scale_y,
* self.state.width,
}); });
Some(quad) Some(quad)
} }

View File

@@ -20,13 +20,13 @@ pub trait OverlayBackend: OverlayRenderer + InteractionHandler {}
pub struct OverlayState { pub struct OverlayState {
pub id: usize, pub id: usize,
pub name: Arc<str>, pub name: Arc<str>,
pub width: f32,
pub size: (i32, i32), pub size: (i32, i32),
pub want_visible: bool, pub want_visible: bool,
pub show_hide: bool, pub show_hide: bool,
pub grabbable: bool, pub grabbable: bool,
pub dirty: bool, pub dirty: bool,
pub transform: Affine3A, pub transform: Affine3A,
pub spawn_scale: f32, // aka width
pub spawn_point: Vec3A, pub spawn_point: Vec3A,
pub spawn_rotation: Quat, pub spawn_rotation: Quat,
pub relative_to: RelativeTo, pub relative_to: RelativeTo,
@@ -39,13 +39,13 @@ impl Default for OverlayState {
OverlayState { OverlayState {
id: AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed), id: AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed),
name: Arc::from(""), name: Arc::from(""),
width: 1.,
size: (0, 0), size: (0, 0),
want_visible: false, want_visible: false,
show_hide: false, show_hide: false,
grabbable: false, grabbable: false,
dirty: false, dirty: false,
relative_to: RelativeTo::None, relative_to: RelativeTo::None,
spawn_scale: 1.0,
spawn_point: Vec3A::NEG_Z, spawn_point: Vec3A::NEG_Z,
spawn_rotation: Quat::IDENTITY, spawn_rotation: Quat::IDENTITY,
transform: Affine3A::IDENTITY, transform: Affine3A::IDENTITY,
@@ -80,8 +80,34 @@ where
} }
impl OverlayState { impl OverlayState {
pub fn reset(&mut self, _app: &mut AppState) { pub fn parent_transform(&self, app: &AppState) -> Option<Affine3A> {
todo!() match self.relative_to {
RelativeTo::None => None,
RelativeTo::Head => Some(app.input_state.hmd),
RelativeTo::Hand(idx) => Some(app.input_state.pointers[idx].pose),
}
}
pub fn auto_movement(&mut self, app: &mut AppState) {
if let Some(parent) = self.parent_transform(app) {
self.transform = parent
* Affine3A::from_scale_rotation_translation(
Vec3::ONE * self.spawn_scale,
self.spawn_rotation,
self.spawn_point.into(),
);
}
}
pub fn reset(&mut self, app: &mut AppState) {
if let RelativeTo::None = self.relative_to {
let translation = app.input_state.hmd.transform_point3a(self.spawn_point);
self.transform = Affine3A::from_scale_rotation_translation(
Vec3::ONE * self.spawn_scale,
Quat::IDENTITY,
translation.into(),
);
self.realign(&app.input_state.hmd);
}
} }
pub fn realign(&mut self, hmd: &Affine3A) { pub fn realign(&mut self, hmd: &Affine3A) {
let to_hmd = hmd.translation - self.transform.translation; let to_hmd = hmd.translation - self.transform.translation;
@@ -129,11 +155,7 @@ where
T: Default, T: Default,
{ {
pub fn init(&mut self, app: &mut AppState) { pub fn init(&mut self, app: &mut AppState) {
self.state.transform.translation = app self.state.reset(app);
.input_state
.hmd
.transform_point3a(self.state.spawn_point);
self.state.realign(&app.input_state.hmd);
self.backend.init(app); self.backend.init(app);
} }
pub fn render(&mut self, app: &mut AppState) { pub fn render(&mut self, app: &mut AppState) {

View File

@@ -118,9 +118,9 @@ where
state: OverlayState { state: OverlayState {
name: Arc::from("kbd"), name: Arc::from("kbd"),
show_hide: true, show_hide: true,
width,
size: (size.x as _, size.y as _), size: (size.x as _, size.y as _),
grabbable: true, grabbable: true,
spawn_scale: width,
spawn_point: vec3a(0., -0.5, -1.), spawn_point: vec3a(0., -0.5, -1.),
interaction_transform, interaction_transform,
..Default::default() ..Default::default()

View File

@@ -128,7 +128,7 @@ impl ScreenPipeline {
graphics.create_pipeline( graphics.create_pipeline(
view, view,
shaders.get("vert_common").unwrap().clone(), shaders.get("vert_common").unwrap().clone(),
shaders.get("frag_screen").unwrap().clone(), shaders.get("frag_sprite").unwrap().clone(),
Format::R8G8B8A8_UNORM, Format::R8G8B8A8_UNORM,
// ImageLayout::TransferSrcOptimal, // ImageLayout::TransferSrcOptimal,
// ImageLayout::TransferSrcOptimal, // ImageLayout::TransferSrcOptimal,
@@ -416,9 +416,9 @@ where
want_visible: session.show_screens.iter().any(|s| s == &*output.name), want_visible: session.show_screens.iter().any(|s| s == &*output.name),
show_hide: true, show_hide: true,
grabbable: true, grabbable: true,
spawn_rotation: Quat::from_axis_angle(axis, angle), spawn_scale: 1.5,
spawn_point: vec3a(0., 0.5, -1.), spawn_point: vec3a(0., 0.5, -1.),
width: 1., spawn_rotation: Quat::from_axis_angle(axis, angle),
interaction_transform, interaction_transform,
..Default::default() ..Default::default()
}, },

View File

@@ -165,8 +165,8 @@ where
state: OverlayState { state: OverlayState {
name: "Watch".into(), name: "Watch".into(),
size: (400, 200), size: (400, 200),
width: 0.065,
want_visible: true, want_visible: true,
spawn_scale: 0.065,
spawn_point: state.session.watch_pos.into(), spawn_point: state.session.watch_pos.into(),
spawn_rotation: state.session.watch_rot, spawn_rotation: state.session.watch_rot,
relative_to, relative_to,