Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toast spam fix #37

Merged
merged 2 commits into from
Apr 24, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
refactor
galister committed Apr 24, 2024
commit 05eecc35bb3c4e17c9f893c37b452f5e55ac713b
81 changes: 2 additions & 79 deletions src/backend/common.rs
Original file line number Diff line number Diff line change
@@ -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<str>),
}

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();
85 changes: 80 additions & 5 deletions src/backend/input.rs
Original file line number Diff line number Diff line change
@@ -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<f32>,
@@ -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()))
}
21 changes: 3 additions & 18 deletions src/backend/openxr/helpers.rs
Original file line number Diff line number Diff line change
@@ -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