laser billboard & sorting fix
This commit is contained in:
@@ -4,7 +4,7 @@ use std::{
|
|||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::Vec2;
|
use glam::{Affine3A, Vec2, Vec3A};
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -180,3 +180,24 @@ impl TaskContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn raycast(
|
||||||
|
source: &Affine3A,
|
||||||
|
source_fwd: Vec3A,
|
||||||
|
plane: &Affine3A,
|
||||||
|
plane_norm: Vec3A,
|
||||||
|
) -> Option<(Vec3A, f32)> {
|
||||||
|
let plane_normal = plane.transform_vector3a(plane_norm);
|
||||||
|
let ray_dir = source.transform_vector3a(source_fwd);
|
||||||
|
|
||||||
|
let d = plane.translation.dot(-plane_normal);
|
||||||
|
let dist = -(d + source.translation.dot(plane_normal)) / ray_dir.dot(plane_normal);
|
||||||
|
|
||||||
|
if dist < 0.0 {
|
||||||
|
// plane is behind the caster
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hit_pos = source.translation + ray_dir * dist;
|
||||||
|
Some((hit_pos, dist))
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ use smallvec::{smallvec, SmallVec};
|
|||||||
|
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
|
|
||||||
use super::{common::OverlayContainer, overlay::OverlayData};
|
use super::{
|
||||||
|
common::{raycast, OverlayContainer},
|
||||||
|
overlay::OverlayData,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct TrackedDevice {
|
pub struct TrackedDevice {
|
||||||
#[cfg(feature = "openvr")]
|
#[cfg(feature = "openvr")]
|
||||||
@@ -437,18 +440,9 @@ impl Pointer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ray_test(&self, overlay: usize, plane: &Affine3A) -> Option<RayHit> {
|
fn ray_test(&self, overlay: usize, plane: &Affine3A) -> Option<RayHit> {
|
||||||
let plane_normal = plane.transform_vector3a(Vec3A::NEG_Z);
|
let Some((hit_pos, dist)) = raycast(&self.pose, Vec3A::NEG_Z, plane, Vec3A::NEG_Z) else {
|
||||||
let ray_dir = self.pose.transform_vector3a(Vec3A::NEG_Z);
|
|
||||||
|
|
||||||
let d = plane.translation.dot(-plane_normal);
|
|
||||||
let dist = -(d + self.pose.translation.dot(plane_normal)) / ray_dir.dot(plane_normal);
|
|
||||||
|
|
||||||
if dist < 0.0 {
|
|
||||||
// plane is behind the caster
|
|
||||||
return None;
|
return None;
|
||||||
}
|
};
|
||||||
|
|
||||||
let hit_pos = self.pose.translation + ray_dir * dist;
|
|
||||||
|
|
||||||
Some(RayHit {
|
Some(RayHit {
|
||||||
overlay,
|
overlay,
|
||||||
|
|||||||
@@ -87,11 +87,36 @@ impl LinePool {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_from(&mut self, id: usize, mut from: Affine3A, len: f32, color: usize) {
|
pub fn draw_from(
|
||||||
|
&mut self,
|
||||||
|
id: usize,
|
||||||
|
mut from: Affine3A,
|
||||||
|
len: f32,
|
||||||
|
color: usize,
|
||||||
|
hmd: &Affine3A,
|
||||||
|
) {
|
||||||
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 mut transform = from * rotation * Affine3A::from_scale(Vec3::new(1., len / 0.002, 1.));
|
||||||
|
|
||||||
|
let to_hmd = hmd.translation - from.translation;
|
||||||
|
let sides = [Vec3A::Z, Vec3A::X, Vec3A::NEG_Z, Vec3A::NEG_X];
|
||||||
|
let rotations = [
|
||||||
|
Affine3A::IDENTITY,
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * 0.5),
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * 1.0),
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * 1.5),
|
||||||
|
];
|
||||||
|
let mut closest = (0, 0.0);
|
||||||
|
for (i, &side) in sides.iter().enumerate() {
|
||||||
|
let dot = to_hmd.dot(transform.transform_vector3a(side));
|
||||||
|
if i == 0 || dot > closest.1 {
|
||||||
|
closest = (i, dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transform = transform * rotations[closest.0];
|
||||||
|
|
||||||
debug_assert!(color < self.colors.len());
|
debug_assert!(color < self.colors.len());
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
state.input_state.pointers[idx].pose,
|
state.input_state.pointers[idx].pose,
|
||||||
*len,
|
*len,
|
||||||
state.input_state.pointers[idx].interaction.mode as usize + 1,
|
state.input_state.pointers[idx].interaction.mode as usize + 1,
|
||||||
|
&state.input_state.hmd,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,14 @@ impl LinePool {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn draw_from(&mut self, id: usize, mut from: Affine3A, len: f32, color: usize) {
|
pub(super) fn draw_from(
|
||||||
|
&mut self,
|
||||||
|
id: usize,
|
||||||
|
mut from: Affine3A,
|
||||||
|
len: f32,
|
||||||
|
color: usize,
|
||||||
|
hmd: &Affine3A,
|
||||||
|
) {
|
||||||
if len < 0.01 {
|
if len < 0.01 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -83,7 +90,25 @@ impl LinePool {
|
|||||||
let rotation = Affine3A::from_axis_angle(Vec3::X, PI * 1.5);
|
let rotation = Affine3A::from_axis_angle(Vec3::X, PI * 1.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;
|
let mut transform = from * rotation;
|
||||||
|
|
||||||
|
let to_hmd = hmd.translation - from.translation;
|
||||||
|
let sides = [Vec3A::Z, Vec3A::X, Vec3A::NEG_Z, Vec3A::NEG_X];
|
||||||
|
let rotations = [
|
||||||
|
Affine3A::IDENTITY,
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * 0.5),
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * -1.0),
|
||||||
|
Affine3A::from_axis_angle(Vec3::Y, PI * 1.5),
|
||||||
|
];
|
||||||
|
let mut closest = (0, 0.0);
|
||||||
|
for (i, &side) in sides.iter().enumerate() {
|
||||||
|
let dot = to_hmd.dot(transform.transform_vector3a(side));
|
||||||
|
if i == 0 || dot > closest.1 {
|
||||||
|
closest = (i, dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transform = transform * rotations[closest.0];
|
||||||
|
|
||||||
let posef = transform_to_posef(&transform);
|
let posef = transform_to_posef(&transform);
|
||||||
|
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
app_state.input_state.pointers[idx].pose,
|
app_state.input_state.pointers[idx].pose,
|
||||||
*len,
|
*len,
|
||||||
app_state.input_state.pointers[idx].interaction.mode as usize + 1,
|
app_state.input_state.pointers[idx].interaction.mode as usize + 1,
|
||||||
|
&app_state.input_state.hmd,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +254,10 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
let dist_sq = (app_state.input_state.hmd.translation - o.state.transform.translation)
|
let dist_sq = (app_state.input_state.hmd.translation - o.state.transform.translation)
|
||||||
.length_squared();
|
.length_squared();
|
||||||
|
|
||||||
|
if !dist_sq.is_normal() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer) {
|
if let Some(quad) = o.present_xr(&xr_state, &mut command_buffer) {
|
||||||
layers.push((dist_sq, quad));
|
layers.push((dist_sq, quad));
|
||||||
};
|
};
|
||||||
@@ -264,7 +269,7 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
|||||||
|
|
||||||
command_buffer.build_and_execute_now();
|
command_buffer.build_and_execute_now();
|
||||||
|
|
||||||
layers.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
|
layers.sort_by(|a, b| b.0.total_cmp(&a.0));
|
||||||
|
|
||||||
let frame_ref = layers
|
let frame_ref = layers
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user