feat(input): custom pointers
This commit is contained in:
@@ -5,9 +5,9 @@ use std::sync::{Arc, Weak};
|
|||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct AliasInfo {
|
pub struct AliasInfo {
|
||||||
pub(super) local_signals: Vec<&'static str>,
|
pub(super) server_signals: Vec<&'static str>,
|
||||||
pub(super) local_methods: Vec<&'static str>,
|
pub(super) server_methods: Vec<&'static str>,
|
||||||
pub(super) remote_signals: Vec<&'static str>,
|
pub(super) client_signals: Vec<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use super::{Alias, Node};
|
|||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
use crate::core::node_collections::LifeLinkedNodeMap;
|
use crate::core::node_collections::LifeLinkedNodeMap;
|
||||||
use crate::core::registry::Registry;
|
use crate::core::registry::Registry;
|
||||||
use crate::nodes::fields::find_field;
|
use crate::nodes::fields::{find_field, FIELD_ALIAS_INFO};
|
||||||
use crate::nodes::spatial::find_spatial_parent;
|
use crate::nodes::spatial::find_spatial_parent;
|
||||||
use color_eyre::eyre::{ensure, eyre, Result};
|
use color_eyre::eyre::{ensure, eyre, Result};
|
||||||
use glam::vec3a;
|
use glam::vec3a;
|
||||||
@@ -90,7 +90,7 @@ impl PulseSender {
|
|||||||
receiver.uid.as_str(),
|
receiver.uid.as_str(),
|
||||||
&rx_node,
|
&rx_node,
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_methods: vec!["sendData", "getTransform"],
|
server_methods: vec!["sendData", "getTransform"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -104,10 +104,7 @@ impl PulseSender {
|
|||||||
rx_alias.get_path(),
|
rx_alias.get_path(),
|
||||||
"field",
|
"field",
|
||||||
&rx_field_node,
|
&rx_field_node,
|
||||||
AliasInfo {
|
FIELD_ALIAS_INFO.clone(),
|
||||||
local_methods: vec!["sendData", "getTransform"],
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
if let Ok(rx_field_alias) = rx_field_alias {
|
if let Ok(rx_field_alias) = rx_field_alias {
|
||||||
self.aliases
|
self.aliases
|
||||||
@@ -143,9 +140,10 @@ impl PulseSender {
|
|||||||
let _ = tx_node.send_remote_signal("new_receiver", &data);
|
let _ = tx_node.send_remote_signal("new_receiver", &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_drop_receiver(&self, uid: String) {
|
fn handle_drop_receiver(&self, receiver: &PulseReceiver) {
|
||||||
self.aliases.remove(&uid);
|
let uid = receiver.uid.as_str();
|
||||||
self.aliases.remove(&(uid.clone() + "-field"));
|
self.aliases.remove(uid);
|
||||||
|
self.aliases.remove(&(uid.to_string() + "-field"));
|
||||||
let Some(tx_node) = self.node.upgrade() else {return};
|
let Some(tx_node) = self.node.upgrade() else {return};
|
||||||
let Ok(data) = serialize(&uid) else {return};
|
let Ok(data) = serialize(&uid) else {return};
|
||||||
let _ = tx_node.send_remote_signal("drop_receiver", &data);
|
let _ = tx_node.send_remote_signal("drop_receiver", &data);
|
||||||
@@ -217,7 +215,7 @@ impl Drop for PulseReceiver {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
PULSE_RECEIVER_REGISTRY.remove(self);
|
PULSE_RECEIVER_REGISTRY.remove(self);
|
||||||
for sender in PULSE_SENDER_REGISTRY.get_valid_contents() {
|
for sender in PULSE_SENDER_REGISTRY.get_valid_contents() {
|
||||||
sender.handle_drop_receiver(self.uid.clone());
|
sender.handle_drop_receiver(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use self::r#box::{create_box_field_flex, BoxField};
|
|||||||
use self::sphere::{create_sphere_field_flex, SphereField};
|
use self::sphere::{create_sphere_field_flex, SphereField};
|
||||||
use self::torus::{create_torus_field_flex, TorusField};
|
use self::torus::{create_torus_field_flex, TorusField};
|
||||||
|
|
||||||
|
use super::alias::AliasInfo;
|
||||||
use super::spatial::Spatial;
|
use super::spatial::Spatial;
|
||||||
use super::Node;
|
use super::Node;
|
||||||
use crate::core::client::Client;
|
use crate::core::client::Client;
|
||||||
@@ -15,12 +16,18 @@ use crate::nodes::spatial::find_reference_space;
|
|||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use glam::{vec2, vec3a, Vec3, Vec3A};
|
use glam::{vec2, vec3a, Vec3, Vec3A};
|
||||||
use mint::Vector3;
|
use mint::Vector3;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub static FIELD_ALIAS_INFO: Lazy<AliasInfo> = Lazy::new(|| AliasInfo {
|
||||||
|
server_methods: vec!["distance", "normal", "closest_point", "ray_march"],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
pub trait FieldTrait {
|
pub trait FieldTrait {
|
||||||
fn add_field_methods(&self, node: &Arc<Node>) {
|
fn add_field_methods(&self, node: &Arc<Node>) {
|
||||||
node.add_local_method("distance", field_distance_flex);
|
node.add_local_method("distance", field_distance_flex);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub fn make_alias(client: &Arc<Client>) -> Result<Arc<Node>> {
|
|||||||
"hmd",
|
"hmd",
|
||||||
&HMD,
|
&HMD,
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_signals: vec!["get_transform"],
|
server_signals: vec!["get_transform"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,19 +8,23 @@ use self::tip::Tip;
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
alias::{Alias, AliasInfo},
|
alias::{Alias, AliasInfo},
|
||||||
fields::{find_field, Field},
|
fields::{find_field, Field, FIELD_ALIAS_INFO},
|
||||||
spatial::{find_spatial_parent, parse_transform, Spatial},
|
spatial::{find_spatial_parent, parse_transform, Spatial},
|
||||||
Node,
|
Node,
|
||||||
};
|
};
|
||||||
use crate::core::client::Client;
|
use crate::core::{client::Client, node_collections::LifeLinkedNodeMap};
|
||||||
use crate::core::{node_collections::LifeLinkedNodeList, registry::Registry};
|
use crate::core::{node_collections::LifeLinkedNodeList, registry::Registry};
|
||||||
use color_eyre::eyre::{ensure, Result};
|
use color_eyre::eyre::{ensure, Result};
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use portable_atomic::AtomicBool;
|
use portable_atomic::AtomicBool;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use stardust_xr::schemas::flat::{Datamap, InputDataType};
|
|
||||||
use stardust_xr::schemas::{flat::InputData, flex::deserialize};
|
use stardust_xr::schemas::{flat::InputData, flex::deserialize};
|
||||||
|
use stardust_xr::schemas::{
|
||||||
|
flat::{Datamap, InputDataType},
|
||||||
|
flex::serialize,
|
||||||
|
};
|
||||||
use stardust_xr::values::Transform;
|
use stardust_xr::values::Transform;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
@@ -63,6 +67,8 @@ pub struct InputMethod {
|
|||||||
pub specialization: Mutex<InputType>,
|
pub specialization: Mutex<InputType>,
|
||||||
captures: Registry<InputHandler>,
|
captures: Registry<InputHandler>,
|
||||||
pub datamap: Mutex<Option<Datamap>>,
|
pub datamap: Mutex<Option<Datamap>>,
|
||||||
|
handler_aliases: LifeLinkedNodeMap<String>,
|
||||||
|
handler_order: OnceCell<Mutex<Vec<Weak<InputHandler>>>>,
|
||||||
}
|
}
|
||||||
impl InputMethod {
|
impl InputMethod {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -78,6 +84,7 @@ impl InputMethod {
|
|||||||
|
|
||||||
node.add_local_signal("capture", InputMethod::capture_flex);
|
node.add_local_signal("capture", InputMethod::capture_flex);
|
||||||
node.add_local_signal("set_datamap", InputMethod::set_datamap_flex);
|
node.add_local_signal("set_datamap", InputMethod::set_datamap_flex);
|
||||||
|
node.add_local_signal("set_handlers", InputMethod::set_handlers_flex);
|
||||||
|
|
||||||
let method = InputMethod {
|
let method = InputMethod {
|
||||||
node: Arc::downgrade(node),
|
node: Arc::downgrade(node),
|
||||||
@@ -87,26 +94,48 @@ impl InputMethod {
|
|||||||
specialization: Mutex::new(specialization),
|
specialization: Mutex::new(specialization),
|
||||||
captures: Registry::new(),
|
captures: Registry::new(),
|
||||||
datamap: Mutex::new(datamap),
|
datamap: Mutex::new(datamap),
|
||||||
|
handler_aliases: LifeLinkedNodeMap::default(),
|
||||||
|
handler_order: OnceCell::new(),
|
||||||
};
|
};
|
||||||
|
for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() {
|
||||||
|
method.handle_new_handler(&handler);
|
||||||
|
}
|
||||||
let method = INPUT_METHOD_REGISTRY.add(method);
|
let method = INPUT_METHOD_REGISTRY.add(method);
|
||||||
let _ = node.input_method.set(method.clone());
|
let _ = node.input_method.set(method.clone());
|
||||||
Ok(method)
|
Ok(method)
|
||||||
}
|
}
|
||||||
|
fn get(node: &Node) -> Result<Arc<Self>> {
|
||||||
|
node.get_aspect("Input Method", "input method", |n| &n.input_method)
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
fn capture_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
fn capture_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||||
let method = node.get_aspect("Input Method", "input method", |n| &n.input_method)?;
|
let method = InputMethod::get(node)?;
|
||||||
let handler_node = calling_client.get_node("Input Handler", deserialize(data)?)?;
|
let handler = InputHandler::find(&calling_client, deserialize(data)?)?;
|
||||||
let handler =
|
|
||||||
handler_node.get_aspect("Input Handler", "input handler", |n| &n.input_handler)?;
|
|
||||||
|
|
||||||
method.captures.add_raw(&handler);
|
method.captures.add_raw(&handler);
|
||||||
Ok(())
|
node.send_remote_signal("capture", data)
|
||||||
}
|
}
|
||||||
fn set_datamap_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
fn set_datamap_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||||
let method = node.get_aspect("Input Method", "input method", |n| &n.input_method)?;
|
let method = InputMethod::get(node)?;
|
||||||
method.datamap.lock().replace(Datamap::new(data.to_vec())?);
|
method.datamap.lock().replace(Datamap::new(data.to_vec())?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn set_handlers_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||||
|
let method = InputMethod::get(node)?;
|
||||||
|
let handler_paths: Vec<&str> = deserialize(data)?;
|
||||||
|
let handlers: Vec<Weak<InputHandler>> = handler_paths
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|p| InputHandler::find(&calling_client, p).ok())
|
||||||
|
.map(|h| Arc::downgrade(&h))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
*method
|
||||||
|
.handler_order
|
||||||
|
.get_or_init(|| Mutex::new(Vec::new()))
|
||||||
|
.lock() = handlers;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn compare_distance(&self, to: &Field) -> f32 {
|
fn compare_distance(&self, to: &Field) -> f32 {
|
||||||
self.specialization
|
self.specialization
|
||||||
@@ -116,6 +145,49 @@ impl InputMethod {
|
|||||||
fn true_distance(&self, to: &Field) -> f32 {
|
fn true_distance(&self, to: &Field) -> f32 {
|
||||||
self.specialization.lock().true_distance(&self.spatial, to)
|
self.specialization.lock().true_distance(&self.spatial, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_new_handler(&self, handler: &InputHandler) {
|
||||||
|
let Some(method_node) = self.node.upgrade() else { return };
|
||||||
|
let Some(method_client) = method_node.get_client() else { return };
|
||||||
|
let Some(handler_node) = handler.node.upgrade() else { return };
|
||||||
|
// Receiver itself
|
||||||
|
let Ok(handler_alias) = Alias::create(
|
||||||
|
&method_client,
|
||||||
|
method_node.get_path(),
|
||||||
|
handler.uid.as_str(),
|
||||||
|
&handler_node,
|
||||||
|
AliasInfo {
|
||||||
|
server_methods: vec!["getTransform"],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
) else {return};
|
||||||
|
self.handler_aliases
|
||||||
|
.add(handler.uid.clone(), &handler_alias);
|
||||||
|
|
||||||
|
if let Some(handler_field_node) = handler.field.spatial_ref().node.upgrade() {
|
||||||
|
// Handler's field
|
||||||
|
let Ok(rx_field_alias) = Alias::create(
|
||||||
|
&method_client,
|
||||||
|
handler_alias.get_path(),
|
||||||
|
"field",
|
||||||
|
&handler_field_node,
|
||||||
|
FIELD_ALIAS_INFO.clone(),
|
||||||
|
) else {return};
|
||||||
|
self.handler_aliases
|
||||||
|
.add(handler.uid.clone() + "-field", &rx_field_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
let Ok(data) = serialize(&handler.uid) else {return};
|
||||||
|
let _ = method_node.send_remote_signal("handler_created", &data);
|
||||||
|
}
|
||||||
|
fn handle_drop_handler(&self, handler: &InputHandler) {
|
||||||
|
let uid = handler.uid.as_str();
|
||||||
|
self.handler_aliases.remove(uid);
|
||||||
|
self.handler_aliases.remove(&(uid.to_string() + "-field"));
|
||||||
|
let Some(tx_node) = self.node.upgrade() else {return};
|
||||||
|
let Ok(data) = serialize(&uid) else {return};
|
||||||
|
let _ = tx_node.send_remote_signal("handler_destroyed", &data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Drop for InputMethod {
|
impl Drop for InputMethod {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@@ -137,7 +209,7 @@ impl DistanceLink {
|
|||||||
&method.uid,
|
&method.uid,
|
||||||
&method.node.upgrade()?,
|
&method.node.upgrade()?,
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_signals: vec!["capture"],
|
server_signals: vec!["capture"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -173,6 +245,7 @@ impl DistanceLink {
|
|||||||
|
|
||||||
pub struct InputHandler {
|
pub struct InputHandler {
|
||||||
enabled: Arc<AtomicBool>,
|
enabled: Arc<AtomicBool>,
|
||||||
|
uid: String,
|
||||||
node: Weak<Node>,
|
node: Weak<Node>,
|
||||||
spatial: Arc<Spatial>,
|
spatial: Arc<Spatial>,
|
||||||
field: Arc<Field>,
|
field: Arc<Field>,
|
||||||
@@ -187,15 +260,26 @@ impl InputHandler {
|
|||||||
|
|
||||||
let handler = InputHandler {
|
let handler = InputHandler {
|
||||||
enabled: node.enabled.clone(),
|
enabled: node.enabled.clone(),
|
||||||
|
uid: node.uid.clone(),
|
||||||
node: Arc::downgrade(node),
|
node: Arc::downgrade(node),
|
||||||
spatial: node.spatial.get().unwrap().clone(),
|
spatial: node.spatial.get().unwrap().clone(),
|
||||||
field: field.clone(),
|
field: field.clone(),
|
||||||
method_aliases: LifeLinkedNodeList::default(),
|
method_aliases: LifeLinkedNodeList::default(),
|
||||||
};
|
};
|
||||||
|
for method in INPUT_METHOD_REGISTRY.get_valid_contents() {
|
||||||
|
method.handle_new_handler(&handler);
|
||||||
|
}
|
||||||
let handler = INPUT_HANDLER_REGISTRY.add(handler);
|
let handler = INPUT_HANDLER_REGISTRY.add(handler);
|
||||||
let _ = node.input_handler.set(handler);
|
let _ = node.input_handler.set(handler);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn find(client: &Client, path: &str) -> Result<Arc<Self>> {
|
||||||
|
InputHandler::get(&*client.get_node("Input Handler", path)?)
|
||||||
|
}
|
||||||
|
fn get(node: &Node) -> Result<Arc<Self>> {
|
||||||
|
node.get_aspect("Input Handler", "input handler", |n| &n.input_handler)
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self, distance_link))]
|
#[instrument(level = "debug", skip(self, distance_link))]
|
||||||
fn send_input(&self, order: u32, distance_link: &DistanceLink, datamap: Datamap) {
|
fn send_input(&self, order: u32, distance_link: &DistanceLink, datamap: Datamap) {
|
||||||
@@ -211,12 +295,16 @@ impl PartialEq for InputHandler {
|
|||||||
impl Drop for InputHandler {
|
impl Drop for InputHandler {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
INPUT_HANDLER_REGISTRY.remove(self);
|
INPUT_HANDLER_REGISTRY.remove(self);
|
||||||
|
for method in INPUT_METHOD_REGISTRY.get_valid_contents() {
|
||||||
|
method.handle_drop_handler(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
pub fn create_interface(client: &Arc<Client>) -> Result<()> {
|
||||||
let node = Node::create(client, "", "input", false);
|
let node = Node::create(client, "", "input", false);
|
||||||
node.add_local_signal("create_input_handler", create_input_handler_flex);
|
node.add_local_signal("create_input_handler", create_input_handler_flex);
|
||||||
|
node.add_local_signal("create_input_method_pointer", pointer::create_pointer_flex);
|
||||||
node.add_local_signal("create_input_method_tip", tip::create_tip_flex);
|
node.add_local_signal("create_input_method_tip", tip::create_tip_flex);
|
||||||
node.add_to_scenegraph().map(|_| ())
|
node.add_to_scenegraph().map(|_| ())
|
||||||
}
|
}
|
||||||
@@ -261,25 +349,39 @@ pub fn process_input() {
|
|||||||
for method in methods {
|
for method in methods {
|
||||||
debug_span!("Process input method").in_scope(|| {
|
debug_span!("Process input method").in_scope(|| {
|
||||||
// Get all valid input handlers and convert them to DistanceLink objects
|
// Get all valid input handlers and convert them to DistanceLink objects
|
||||||
let mut distance_links: Vec<DistanceLink> = debug_span!("Generate distance links")
|
let distance_links: Vec<DistanceLink> = debug_span!("Generate distance links")
|
||||||
.in_scope(|| {
|
.in_scope(|| {
|
||||||
handlers
|
if let Some(handler_order) = method.handler_order.get() {
|
||||||
.iter()
|
let handler_order = handler_order.lock();
|
||||||
.filter(|handler| handler.enabled.load(Ordering::Relaxed))
|
handler_order
|
||||||
.filter_map(|handler| DistanceLink::from(method.clone(), handler.clone()))
|
.iter()
|
||||||
.collect()
|
.filter_map(|h| h.upgrade())
|
||||||
});
|
.filter(|handler| handler.enabled.load(Ordering::Relaxed))
|
||||||
|
.filter_map(|handler| DistanceLink::from(method.clone(), handler))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
let mut distance_links: Vec<_> = handlers
|
||||||
|
.iter()
|
||||||
|
.filter(|handler| handler.enabled.load(Ordering::Relaxed))
|
||||||
|
.filter_map(|handler| {
|
||||||
|
DistanceLink::from(method.clone(), handler.clone())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Sort the distance links by their distance in ascending order
|
// Sort the distance links by their distance in ascending order
|
||||||
debug_span!("Sort distance links").in_scope(|| {
|
debug_span!("Sort distance links").in_scope(|| {
|
||||||
distance_links.sort_unstable_by(|a, b| {
|
distance_links.sort_unstable_by(|a, b| {
|
||||||
a.distance.abs().partial_cmp(&b.distance.abs()).unwrap()
|
a.distance.abs().partial_cmp(&b.distance.abs()).unwrap()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
distance_links
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let captures = method.captures.take_valid_contents();
|
let captures = method.captures.take_valid_contents();
|
||||||
// Iterate over the distance links and send input to them
|
// Iterate over the distance links and send input to them
|
||||||
for (i, distance_link) in distance_links.iter().enumerate() {
|
for (i, distance_link) in distance_links.into_iter().enumerate() {
|
||||||
distance_link.send_input(i as u32, method.datamap.lock().clone().unwrap());
|
distance_link.send_input(i as u32, method.datamap.lock().clone().unwrap());
|
||||||
|
|
||||||
// If the current distance link is in the list of captured input handlers,
|
// If the current distance link is in the list of captured input handlers,
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
use super::{DistanceLink, InputSpecialization};
|
use super::{DistanceLink, InputSpecialization};
|
||||||
|
use crate::core::client::Client;
|
||||||
use crate::nodes::fields::{Field, Ray, RayMarchResult};
|
use crate::nodes::fields::{Field, Ray, RayMarchResult};
|
||||||
use crate::nodes::spatial::Spatial;
|
use crate::nodes::input::{InputMethod, InputType};
|
||||||
|
use crate::nodes::spatial::{find_spatial_parent, parse_transform, Spatial};
|
||||||
|
use crate::nodes::Node;
|
||||||
use glam::{vec3, Mat4};
|
use glam::{vec3, Mat4};
|
||||||
use stardust_xr::schemas::flat::{InputDataType, Pointer as FlatPointer};
|
use serde::Deserialize;
|
||||||
|
use stardust_xr::schemas::flat::{Datamap, InputDataType, Pointer as FlatPointer};
|
||||||
|
use stardust_xr::schemas::flex::deserialize;
|
||||||
|
use stardust_xr::values::Transform;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Pointer {}
|
pub struct Pointer;
|
||||||
// impl Default for Pointer {
|
// impl Default for Pointer {
|
||||||
// fn default() -> Self {
|
// fn default() -> Self {
|
||||||
// Pointer {
|
// Pointer {
|
||||||
@@ -53,3 +59,30 @@ impl InputSpecialization for Pointer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_pointer_flex(
|
||||||
|
_node: &Node,
|
||||||
|
calling_client: Arc<Client>,
|
||||||
|
data: &[u8],
|
||||||
|
) -> color_eyre::eyre::Result<()> {
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct CreatePointerInfo<'a> {
|
||||||
|
name: &'a str,
|
||||||
|
parent_path: &'a str,
|
||||||
|
transform: Transform,
|
||||||
|
datamap: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
let info: CreatePointerInfo = deserialize(data)?;
|
||||||
|
let node = Node::create(&calling_client, "/input/method/pointer", info.name, true);
|
||||||
|
let parent = find_spatial_parent(&calling_client, info.parent_path)?;
|
||||||
|
let transform = parse_transform(info.transform, true, true, false);
|
||||||
|
|
||||||
|
let node = node.add_to_scenegraph()?;
|
||||||
|
Spatial::add_to(&node, Some(parent), transform, false)?;
|
||||||
|
InputMethod::add_to(
|
||||||
|
&node,
|
||||||
|
InputType::Pointer(Pointer),
|
||||||
|
info.datamap.and_then(|datamap| Datamap::new(datamap).ok()),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,17 +131,17 @@ impl Item {
|
|||||||
name,
|
name,
|
||||||
&self.node.upgrade().unwrap(),
|
&self.node.upgrade().unwrap(),
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_signals: [
|
server_signals: [
|
||||||
&self.type_info.aliased_local_signals,
|
&self.type_info.aliased_local_signals,
|
||||||
ITEM_ALIAS_LOCAL_SIGNALS.as_slice(),
|
ITEM_ALIAS_LOCAL_SIGNALS.as_slice(),
|
||||||
]
|
]
|
||||||
.concat(),
|
.concat(),
|
||||||
local_methods: [
|
server_methods: [
|
||||||
&self.type_info.aliased_local_methods,
|
&self.type_info.aliased_local_methods,
|
||||||
ITEM_ALIAS_LOCAL_METHODS.as_slice(),
|
ITEM_ALIAS_LOCAL_METHODS.as_slice(),
|
||||||
]
|
]
|
||||||
.concat(),
|
.concat(),
|
||||||
remote_signals: [
|
client_signals: [
|
||||||
&self.type_info.aliased_remote_signals,
|
&self.type_info.aliased_remote_signals,
|
||||||
ITEM_ALIAS_REMOTE_SIGNALS.as_slice(),
|
ITEM_ALIAS_REMOTE_SIGNALS.as_slice(),
|
||||||
]
|
]
|
||||||
@@ -336,7 +336,7 @@ impl ItemAcceptor {
|
|||||||
&self.uid,
|
&self.uid,
|
||||||
acceptor_node,
|
acceptor_node,
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_signals: vec!["capture"],
|
server_signals: vec!["capture"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ impl Node {
|
|||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<(), ScenegraphError> {
|
) -> Result<(), ScenegraphError> {
|
||||||
if let Some(alias) = self.alias.get() {
|
if let Some(alias) = self.alias.get() {
|
||||||
if !alias.info.local_signals.iter().any(|e| e == &method) {
|
if !alias.info.server_signals.iter().any(|e| e == &method) {
|
||||||
return Err(ScenegraphError::SignalNotFound);
|
return Err(ScenegraphError::SignalNotFound);
|
||||||
}
|
}
|
||||||
alias
|
alias
|
||||||
@@ -208,7 +208,7 @@ impl Node {
|
|||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<Vec<u8>, ScenegraphError> {
|
) -> Result<Vec<u8>, ScenegraphError> {
|
||||||
if let Some(alias) = self.alias.get() {
|
if let Some(alias) = self.alias.get() {
|
||||||
if !alias.info.local_methods.iter().any(|e| e == &method) {
|
if !alias.info.server_methods.iter().any(|e| e == &method) {
|
||||||
return Err(ScenegraphError::MethodNotFound);
|
return Err(ScenegraphError::MethodNotFound);
|
||||||
}
|
}
|
||||||
alias
|
alias
|
||||||
@@ -234,7 +234,7 @@ impl Node {
|
|||||||
self.aliases
|
self.aliases
|
||||||
.get_valid_contents()
|
.get_valid_contents()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|alias| alias.info.remote_signals.iter().any(|e| e == &method))
|
.filter(|alias| alias.info.client_signals.iter().any(|e| e == &method))
|
||||||
.filter_map(|alias| alias.node.upgrade())
|
.filter_map(|alias| alias.node.upgrade())
|
||||||
.for_each(|node| {
|
.for_each(|node| {
|
||||||
let _ = node.send_remote_signal(method, data);
|
let _ = node.send_remote_signal(method, data);
|
||||||
|
|||||||
@@ -114,12 +114,12 @@ impl Zone {
|
|||||||
&zoneable.uid,
|
&zoneable.uid,
|
||||||
&zoneable.node.upgrade().unwrap(),
|
&zoneable.node.upgrade().unwrap(),
|
||||||
AliasInfo {
|
AliasInfo {
|
||||||
local_signals: vec![
|
server_signals: vec![
|
||||||
"set_transform",
|
"set_transform",
|
||||||
"set_spatial_parent",
|
"set_spatial_parent",
|
||||||
"set_spatial_parent_in_place",
|
"set_spatial_parent_in_place",
|
||||||
],
|
],
|
||||||
local_methods: vec!["get_transform"],
|
server_methods: vec!["get_transform"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user