feat: input pointer specialization

This commit is contained in:
Nova
2022-07-05 05:46:21 -04:00
parent 59663d2aa6
commit 204d730fb2
4 changed files with 143 additions and 14 deletions

View File

@@ -10,6 +10,7 @@ libstardustxr = {path = "../libstardustxr-rs"}
anyhow = "1.0.57"
ctrlc = "3.2.2"
dashmap = "5.3.4"
flatbuffers = "2.1.2"
flexbuffers = "2.0.0"
glam = {version = "0.20.5", features = ["mint"]}
lazy_static = "1.4.0"

View File

@@ -5,7 +5,9 @@ use crate::core::client::Client;
use crate::core::eventloop::FRAME;
use crate::core::registry::Registry;
use anyhow::{anyhow, ensure, Result};
use glam::Mat4;
use lazy_static::lazy_static;
use libstardustxr::schemas::input::{InputData, InputDataArgs, InputDataRaw};
use std::ops::Deref;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Weak};
@@ -16,8 +18,17 @@ lazy_static! {
}
pub trait InputSpecializationTrait {
fn distance(&self, space: &Spatial, field: &Field) -> f32;
fn serialize(&self, space: &Spatial, distance: f32) -> Vec<u8>;
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32;
fn serialize(
&self,
fbb: &mut flatbuffers::FlatBufferBuilder,
distance_link: &DistanceLink,
local_to_handler_matrix: Mat4,
) -> (
InputDataRaw,
flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>,
);
fn serialize_datamap(&self) -> Vec<u8>;
}
enum InputSpecialization {}
impl Deref for InputSpecialization {
@@ -31,7 +42,8 @@ impl Deref for InputSpecialization {
}
pub struct InputMethod {
spatial: Arc<Spatial>,
uid: String,
pub spatial: Arc<Spatial>,
specialization: InputSpecialization,
}
impl InputMethod {
@@ -42,6 +54,7 @@ impl InputMethod {
);
let method = InputMethod {
uid: node.uid.clone(),
spatial: node.spatial.get().unwrap().clone(),
specialization,
};
@@ -61,10 +74,10 @@ impl Drop for InputMethod {
}
}
struct DistanceLink {
distance: f32,
method: Weak<InputMethod>,
handler: Weak<InputHandler>,
pub struct DistanceLink {
pub distance: f32,
pub method: Weak<InputMethod>,
pub handler: Weak<InputHandler>,
}
impl DistanceLink {
fn from(method: &Arc<InputMethod>, handler: &Arc<InputHandler>) -> Option<Self> {
@@ -77,18 +90,44 @@ impl DistanceLink {
fn serialize(&self) -> Option<Vec<u8>> {
self.method.upgrade().and_then(|method| {
self.handler.upgrade().map(|handler| {
method
.specialization
.serialize(&handler.spatial.upgrade().unwrap(), self.distance)
let mut fbb = flatbuffers::FlatBufferBuilder::with_capacity(1024);
let uid = Some(fbb.create_string(&method.uid));
let datamap = Some(fbb.create_vector(&self.serialize_datamap()));
let (input_type, input_data) = method.specialization.serialize(
&mut fbb,
self,
Spatial::space_to_space_matrix(Some(&method.spatial), Some(&handler.spatial)),
);
let root = InputData::create(
&mut fbb,
&InputDataArgs {
uid,
input_type,
input: Some(input_data),
distance: self.distance,
datamap,
},
);
fbb.finish(root, None);
Vec::from(fbb.finished_data())
})
})
}
fn serialize_datamap(&self) -> Vec<u8> {
if let Some(method) = self.method.upgrade() {
method.specialization.serialize_datamap()
} else {
Default::default()
}
}
}
pub struct InputHandler {
node: Weak<Node>,
spatial: Weak<Spatial>,
field: Weak<Field>,
spatial: Arc<Spatial>,
pub field: Weak<Field>,
}
impl InputHandler {
pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> {
@@ -99,7 +138,7 @@ impl InputHandler {
let handler = InputHandler {
node: Arc::downgrade(node),
spatial: Arc::downgrade(node.spatial.get().unwrap()),
spatial: node.spatial.get().unwrap().clone(),
field: Arc::downgrade(field),
};
let handler = INPUT_HANDLER_REGISTRY.add(handler);
@@ -117,7 +156,9 @@ impl InputHandler {
return;
}
if let Some(data) = distance_link.serialize() {
let serialized_data = distance_link.serialize();
if let Some(data) = serialized_data {
let _ = self.node.upgrade().unwrap().execute_remote_method(
"input",
&data,

View File

@@ -0,0 +1,86 @@
use super::field::{ray_march, Field, Ray, RayMarchResult};
use super::input::{DistanceLink, InputSpecializationTrait};
use super::spatial::Spatial;
use glam::{vec3, vec3a, Mat4};
use libstardustxr::schemas::common;
use libstardustxr::schemas::input::InputDataRaw;
use libstardustxr::schemas::input_pointer;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
pub struct Pointer {
grab: AtomicBool,
select: AtomicBool,
}
impl Default for Pointer {
fn default() -> Self {
Pointer {
grab: Default::default(),
select: Default::default(),
}
}
}
impl Pointer {
fn ray_march(&self, space: &Arc<Spatial>, field: &Field) -> RayMarchResult {
ray_march(
Ray {
origin: vec3(0_f32, 0_f32, 0_f32),
direction: vec3(0_f32, 0_f32, 1_f32),
space: space.clone(),
},
field,
)
}
}
impl InputSpecializationTrait for Pointer {
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32 {
self.ray_march(space, field).distance
}
fn serialize(
&self,
fbb: &mut flatbuffers::FlatBufferBuilder,
distance_link: &DistanceLink,
local_to_handler_matrix: Mat4,
) -> (
InputDataRaw,
flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>,
) {
let origin = local_to_handler_matrix.transform_point3a(vec3a(0_f32, 0_f32, 0_f32));
let direction = local_to_handler_matrix.transform_vector3a(vec3a(0_f32, 0_f32, 1_f32));
let ray_march = self.ray_march(
&distance_link.method.upgrade().unwrap().spatial,
&distance_link
.handler
.upgrade()
.unwrap()
.field
.upgrade()
.unwrap(),
);
let deepest_point = (direction * ray_march.deepest_point_distance) + origin;
let pointer = input_pointer::Pointer::create(
fbb,
&input_pointer::PointerArgs {
origin: Some(&common::Vec3::new(origin.x, origin.y, origin.z)),
direction: Some(&common::Vec3::new(direction.x, direction.y, direction.z)),
tilt: 0_f32,
deepest_point: Some(&common::Vec3::new(
deepest_point.x,
deepest_point.y,
deepest_point.z,
)),
},
);
(InputDataRaw::Pointer, pointer.as_union_value())
}
fn serialize_datamap(&self) -> Vec<u8> {
let mut fbb = flexbuffers::Builder::default();
let mut map = fbb.start_map();
map.push("grab", self.grab.load(Ordering::Relaxed));
map.push("select", self.select.load(Ordering::Relaxed));
map.end_map();
fbb.view().to_vec()
}
}

View File

@@ -2,6 +2,7 @@ pub mod core;
pub mod data;
pub mod field;
pub mod input;
pub mod input_pointer;
pub mod item;
pub mod root;
pub mod spatial;