laser colors, improve scaling (wip)
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user