feat: input pointer specialization
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
86
src/nodes/input_pointer.rs
Normal file
86
src/nodes/input_pointer.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user