feat: input pointer specialization
This commit is contained in:
@@ -10,6 +10,7 @@ libstardustxr = {path = "../libstardustxr-rs"}
|
|||||||
anyhow = "1.0.57"
|
anyhow = "1.0.57"
|
||||||
ctrlc = "3.2.2"
|
ctrlc = "3.2.2"
|
||||||
dashmap = "5.3.4"
|
dashmap = "5.3.4"
|
||||||
|
flatbuffers = "2.1.2"
|
||||||
flexbuffers = "2.0.0"
|
flexbuffers = "2.0.0"
|
||||||
glam = {version = "0.20.5", features = ["mint"]}
|
glam = {version = "0.20.5", features = ["mint"]}
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ use crate::core::client::Client;
|
|||||||
use crate::core::eventloop::FRAME;
|
use crate::core::eventloop::FRAME;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
use anyhow::{anyhow, ensure, Result};
|
use anyhow::{anyhow, ensure, Result};
|
||||||
|
use glam::Mat4;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use libstardustxr::schemas::input::{InputData, InputDataArgs, InputDataRaw};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
@@ -16,8 +18,17 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait InputSpecializationTrait {
|
pub trait InputSpecializationTrait {
|
||||||
fn distance(&self, space: &Spatial, field: &Field) -> f32;
|
fn distance(&self, space: &Arc<Spatial>, field: &Field) -> f32;
|
||||||
fn serialize(&self, space: &Spatial, distance: f32) -> Vec<u8>;
|
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 {}
|
enum InputSpecialization {}
|
||||||
impl Deref for InputSpecialization {
|
impl Deref for InputSpecialization {
|
||||||
@@ -31,7 +42,8 @@ impl Deref for InputSpecialization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct InputMethod {
|
pub struct InputMethod {
|
||||||
spatial: Arc<Spatial>,
|
uid: String,
|
||||||
|
pub spatial: Arc<Spatial>,
|
||||||
specialization: InputSpecialization,
|
specialization: InputSpecialization,
|
||||||
}
|
}
|
||||||
impl InputMethod {
|
impl InputMethod {
|
||||||
@@ -42,6 +54,7 @@ impl InputMethod {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let method = InputMethod {
|
let method = InputMethod {
|
||||||
|
uid: node.uid.clone(),
|
||||||
spatial: node.spatial.get().unwrap().clone(),
|
spatial: node.spatial.get().unwrap().clone(),
|
||||||
specialization,
|
specialization,
|
||||||
};
|
};
|
||||||
@@ -61,10 +74,10 @@ impl Drop for InputMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DistanceLink {
|
pub struct DistanceLink {
|
||||||
distance: f32,
|
pub distance: f32,
|
||||||
method: Weak<InputMethod>,
|
pub method: Weak<InputMethod>,
|
||||||
handler: Weak<InputHandler>,
|
pub handler: Weak<InputHandler>,
|
||||||
}
|
}
|
||||||
impl DistanceLink {
|
impl DistanceLink {
|
||||||
fn from(method: &Arc<InputMethod>, handler: &Arc<InputHandler>) -> Option<Self> {
|
fn from(method: &Arc<InputMethod>, handler: &Arc<InputHandler>) -> Option<Self> {
|
||||||
@@ -77,18 +90,44 @@ impl DistanceLink {
|
|||||||
fn serialize(&self) -> Option<Vec<u8>> {
|
fn serialize(&self) -> Option<Vec<u8>> {
|
||||||
self.method.upgrade().and_then(|method| {
|
self.method.upgrade().and_then(|method| {
|
||||||
self.handler.upgrade().map(|handler| {
|
self.handler.upgrade().map(|handler| {
|
||||||
method
|
let mut fbb = flatbuffers::FlatBufferBuilder::with_capacity(1024);
|
||||||
.specialization
|
let uid = Some(fbb.create_string(&method.uid));
|
||||||
.serialize(&handler.spatial.upgrade().unwrap(), self.distance)
|
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 {
|
pub struct InputHandler {
|
||||||
node: Weak<Node>,
|
node: Weak<Node>,
|
||||||
spatial: Weak<Spatial>,
|
spatial: Arc<Spatial>,
|
||||||
field: Weak<Field>,
|
pub field: Weak<Field>,
|
||||||
}
|
}
|
||||||
impl InputHandler {
|
impl InputHandler {
|
||||||
pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> {
|
pub fn add_to(node: &Arc<Node>, field: &Arc<Field>) -> Result<()> {
|
||||||
@@ -99,7 +138,7 @@ impl InputHandler {
|
|||||||
|
|
||||||
let handler = InputHandler {
|
let handler = InputHandler {
|
||||||
node: Arc::downgrade(node),
|
node: Arc::downgrade(node),
|
||||||
spatial: Arc::downgrade(node.spatial.get().unwrap()),
|
spatial: node.spatial.get().unwrap().clone(),
|
||||||
field: Arc::downgrade(field),
|
field: Arc::downgrade(field),
|
||||||
};
|
};
|
||||||
let handler = INPUT_HANDLER_REGISTRY.add(handler);
|
let handler = INPUT_HANDLER_REGISTRY.add(handler);
|
||||||
@@ -117,7 +156,9 @@ impl InputHandler {
|
|||||||
return;
|
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(
|
let _ = self.node.upgrade().unwrap().execute_remote_method(
|
||||||
"input",
|
"input",
|
||||||
&data,
|
&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 data;
|
||||||
pub mod field;
|
pub mod field;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod input_pointer;
|
||||||
pub mod item;
|
pub mod item;
|
||||||
pub mod root;
|
pub mod root;
|
||||||
pub mod spatial;
|
pub mod spatial;
|
||||||
|
|||||||
Reference in New Issue
Block a user