From 05eecc35bb3c4e17c9f893c37b452f5e55ac713b Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:35:54 +0900 Subject: [PATCH] refactor --- src/backend/common.rs | 81 +-------------------------------- src/backend/input.rs | 85 ++++++++++++++++++++++++++++++++--- src/backend/openxr/helpers.rs | 21 ++------- 3 files changed, 85 insertions(+), 102 deletions(-) diff --git a/src/backend/common.rs b/src/backend/common.rs index b2d3a36..4b7c1c6 100644 --- a/src/backend/common.rs +++ b/src/backend/common.rs @@ -1,10 +1,10 @@ -use std::{f32::consts::PI, sync::Arc}; +use std::sync::Arc; use once_cell::sync::Lazy; #[cfg(feature = "openxr")] use openxr as xr; -use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; +use glam::{Affine3A, Vec3, Vec3A}; use idmap::IdMap; use serde::Deserialize; use thiserror::Error; @@ -346,83 +346,6 @@ pub enum OverlaySelector { Name(Arc), } -pub fn raycast_plane( - source: &Affine3A, - source_fwd: Vec3A, - plane: &Affine3A, - plane_norm: Vec3A, -) -> Option<(f32, Vec2)> { - 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); - - let hit_local = plane - .inverse() - .transform_point3a(source.translation + ray_dir * dist) - .xy(); - - Some((dist, hit_local)) -} - -pub fn raycast_cylinder( - source: &Affine3A, - source_fwd: Vec3A, - plane: &Affine3A, - curvature: f32, -) -> Option<(f32, Vec2)> { - // this is solved locally; (0,0) is the center of the cylinder, and the cylinder is aligned with the Y axis - let size = plane.x_axis.length(); - let to_local = Affine3A { - matrix3: plane.matrix3.mul_scalar(1.0 / size), - translation: plane.translation, - } - .inverse(); - - let r = size / (2.0 * PI * curvature); - - let ray_dir = to_local.transform_vector3a(source.transform_vector3a(source_fwd)); - let ray_origin = to_local.transform_point3a(source.translation) + Vec3A::NEG_Z * r; - - let d = ray_dir.xz(); - let s = ray_origin.xz(); - - let a = d.dot(d); - let b = d.dot(s); - let c = s.dot(s) - r * r; - - let d = (b * b) - (a * c); - if d < f32::EPSILON { - return None; - } - - let sqrt_d = d.sqrt(); - - let t1 = (-b - sqrt_d) / a; - let t2 = (-b + sqrt_d) / a; - - let t = t1.max(t2); - - if t < f32::EPSILON { - return None; - } - - let mut hit_local = ray_origin + ray_dir * t; - if hit_local.z > 0.0 { - // hitting the opposite half of the cylinder - return None; - } - - let max_angle = 2.0 * (size / (2.0 * r)); - let x_angle = (hit_local.x / r).asin(); - - hit_local.x = x_angle / max_angle; - hit_local.y /= size; - - Some((t, hit_local.xy())) -} - pub fn snap_upright(transform: Affine3A, up_dir: Vec3A) -> Affine3A { if transform.x_axis.dot(up_dir).abs() < 0.2 { let scale = transform.x_axis.length(); diff --git a/src/backend/input.rs b/src/backend/input.rs index 35dc970..0a99b09 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -1,6 +1,7 @@ +use std::f32::consts::PI; use std::{collections::VecDeque, time::Instant}; -use glam::{Affine3A, Vec2, Vec3, Vec3A}; +use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; use smallvec::{smallvec, SmallVec}; @@ -10,10 +11,7 @@ use crate::overlays::anchor::ANCHOR_NAME; use crate::state::AppState; use super::task::{TaskContainer, TaskType}; -use super::{ - common::{raycast_cylinder, raycast_plane, OverlayContainer}, - overlay::OverlayData, -}; +use super::{common::OverlayContainer, overlay::OverlayData}; pub struct TrackedDevice { pub soc: Option, @@ -590,3 +588,80 @@ impl Pointer { }) } } + +fn raycast_plane( + source: &Affine3A, + source_fwd: Vec3A, + plane: &Affine3A, + plane_norm: Vec3A, +) -> Option<(f32, Vec2)> { + 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); + + let hit_local = plane + .inverse() + .transform_point3a(source.translation + ray_dir * dist) + .xy(); + + Some((dist, hit_local)) +} + +fn raycast_cylinder( + source: &Affine3A, + source_fwd: Vec3A, + plane: &Affine3A, + curvature: f32, +) -> Option<(f32, Vec2)> { + // this is solved locally; (0,0) is the center of the cylinder, and the cylinder is aligned with the Y axis + let size = plane.x_axis.length(); + let to_local = Affine3A { + matrix3: plane.matrix3.mul_scalar(1.0 / size), + translation: plane.translation, + } + .inverse(); + + let r = size / (2.0 * PI * curvature); + + let ray_dir = to_local.transform_vector3a(source.transform_vector3a(source_fwd)); + let ray_origin = to_local.transform_point3a(source.translation) + Vec3A::NEG_Z * r; + + let d = ray_dir.xz(); + let s = ray_origin.xz(); + + let a = d.dot(d); + let b = d.dot(s); + let c = s.dot(s) - r * r; + + let d = (b * b) - (a * c); + if d < f32::EPSILON { + return None; + } + + let sqrt_d = d.sqrt(); + + let t1 = (-b - sqrt_d) / a; + let t2 = (-b + sqrt_d) / a; + + let t = t1.max(t2); + + if t < f32::EPSILON { + return None; + } + + let mut hit_local = ray_origin + ray_dir * t; + if hit_local.z > 0.0 { + // hitting the opposite half of the cylinder + return None; + } + + let max_angle = 2.0 * (size / (2.0 * r)); + let x_angle = (hit_local.x / r).asin(); + + hit_local.x = x_angle / max_angle; + hit_local.y /= size; + + Some((t, hit_local.xy())) +} diff --git a/src/backend/openxr/helpers.rs b/src/backend/openxr/helpers.rs index 8c93b58..aadce8d 100644 --- a/src/backend/openxr/helpers.rs +++ b/src/backend/openxr/helpers.rs @@ -129,29 +129,14 @@ pub(super) fn hmd_pose_from_views(views: &[xr::View]) -> (Affine3A, f32) { (pos0 + pos1) * 0.5 }; let rot = { - let rot0 = unsafe { std::mem::transmute(views[0].pose.orientation) }; - let rot1 = unsafe { std::mem::transmute(views[1].pose.orientation) }; - quat_lerp(rot0, rot1, 0.5) + let rot0: Quat = unsafe { std::mem::transmute(views[0].pose.orientation) }; + let rot1: Quat = unsafe { std::mem::transmute(views[1].pose.orientation) }; + rot0.lerp(rot1, 0.5) }; (Affine3A::from_rotation_translation(rot, pos), ipd) } -fn quat_lerp(a: Quat, mut b: Quat, t: f32) -> Quat { - let l2 = a.dot(b); - if l2 < 0.0 { - b = -b; - } - - Quat::from_xyzw( - a.x - t * (a.x - b.x), - a.y - t * (a.y - b.y), - a.z - t * (a.z - b.z), - a.w - t * (a.w - b.w), - ) - .normalize() -} - pub(super) fn transform_to_norm_quat(transform: &Affine3A) -> Quat { let norm_mat3 = transform .matrix3