diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index 00c8f60..ccd585c 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -1,5 +1,5 @@ use crate::core::client::Client; -use crate::nodes::spatial::Spatial; +use crate::nodes::core::Node; use anyhow::Result; use libstardustxr::scenegraph; use libstardustxr::scenegraph::ScenegraphError; @@ -8,7 +8,7 @@ use std::collections::HashMap; pub struct Scenegraph<'a> { client: WeakCell>, - pub spatial_nodes: HashMap>>, + pub nodes: HashMap>>, } impl<'a> Scenegraph<'a> { @@ -17,7 +17,7 @@ impl<'a> Scenegraph<'a> { // hmd: Spatial::new(Some(client), "/hmd", Default::default()), Scenegraph { client: client.downgrade(), - spatial_nodes: HashMap::new(), + nodes: HashMap::new(), } } } @@ -26,18 +26,17 @@ impl<'a> Default for Scenegraph<'a> { fn default() -> Self { Scenegraph { client: WeakCell::new(), - spatial_nodes: HashMap::new(), + nodes: HashMap::new(), } } } impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { fn send_signal(&self, path: &str, method: &str, data: &[u8]) -> Result<(), ScenegraphError> { - self.spatial_nodes + self.nodes .get(path) .ok_or(ScenegraphError::NodeNotFound)? .borrow() - .node .send_local_signal(self.client.upgrade().unwrap(), method, data) .map_err(|_| ScenegraphError::MethodNotFound) } @@ -47,11 +46,10 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { method: &str, data: &[u8], ) -> Result, ScenegraphError> { - self.spatial_nodes + self.nodes .get(path) .ok_or(ScenegraphError::NodeNotFound)? .borrow() - .node .execute_local_method(self.client.upgrade().unwrap(), method, data) .map_err(|_| ScenegraphError::MethodNotFound) } diff --git a/src/nodes/core.rs b/src/nodes/core.rs index 3e391cf..f29f313 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -1,4 +1,5 @@ use crate::core::client::Client; +use crate::nodes::spatial::Spatial; use anyhow::{anyhow, ensure, Result}; use rccell::{RcCell, WeakCell}; use std::{collections::HashMap, vec::Vec}; @@ -13,6 +14,8 @@ pub struct Node<'a> { local_signals: HashMap>, local_methods: HashMap>, destroyable: bool, + + pub spatial: Option>, } impl<'a> Node<'a> { @@ -41,6 +44,7 @@ impl<'a> Node<'a> { local_signals: HashMap::new(), local_methods: HashMap::new(), destroyable, + spatial: None, }) } @@ -54,9 +58,11 @@ impl<'a> Node<'a> { method: &str, data: &[u8], ) -> Result<()> { - self.local_signals + let signal = self + .local_signals .get(method) - .ok_or_else(|| anyhow!("Signal {} not found", method))?(calling_client, data) + .ok_or_else(|| anyhow!("Signal {} not found", method))?; + signal(calling_client, data) } pub fn execute_local_method( &self, diff --git a/src/nodes/spatial.rs b/src/nodes/spatial.rs index 332408d..db0ddde 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,68 +1,58 @@ use super::core::Node; use crate::core::client::Client; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, ensure, Result}; use glam::{Mat4, Quat, Vec3}; use libstardustxr::{flex_to_quat, flex_to_vec3}; use rccell::{RcCell, WeakCell}; pub struct Spatial<'a> { - pub node: Node<'a>, - parent: WeakCell>, + node: WeakCell>, + parent: WeakCell>, transform: Mat4, } impl<'a> Spatial<'a> { - pub fn new( - client: WeakCell>, - path: &str, - transform: Mat4, - ) -> Result> { - let spatial = RcCell::new(Spatial { - node: Node::from_path(client.clone(), path, true).unwrap(), + pub fn new(node: RcCell>, transform: Mat4) -> Self { + let spatial = Spatial { + node: node.downgrade(), parent: WeakCell::new(), transform, - }); - let weak_spatial = spatial.downgrade(); - let captured_spatial = weak_spatial.clone(); - let captured_client = client.clone(); - // node_add_local_signal!(node, "setTransform", Spatial::set_transform_components); - spatial.borrow_mut().node.add_local_signal( + }; + let node_captured = node.clone(); + node.borrow_mut().add_local_signal( "setTransform", Box::new(move |calling_client, data| { let root = flexbuffers::Reader::get_root(data)?; let flex_vec = root.get_vector()?; - let spatial = captured_spatial - .upgrade() - .ok_or(anyhow!("Invalid spatial"))?; - let client = captured_client.upgrade().ok_or(anyhow!("Invalid client"))?; - let other_spatial = client + // let node = node. + let client = node_captured + .borrow() + .get_client() + .ok_or(anyhow!("Node somehow has no client!"))?; + let other_spatial = calling_client .borrow() .get_scenegraph() - .spatial_nodes + .nodes .get(flex_vec.idx(0).as_str()) - .ok_or(anyhow!("Spatial not found"))? + .ok_or(anyhow!("Spatial node not found"))? .clone(); + ensure!( + other_spatial.borrow().spatial.is_some(), + "Node is not a Spatial!" + ); let pos = flex_to_vec3!(flex_vec.idx(1)); let rot = flex_to_quat!(flex_vec.idx(2)); let scl = flex_to_vec3!(flex_vec.idx(3)); - spatial.borrow_mut().set_transform_components( - client, - other_spatial, - pos.into(), - rot, - scl, - ); + node_captured + .borrow_mut() + .spatial + .as_mut() + .unwrap() + .set_transform_components(client, other_spatial, pos.into(), rot, scl); Ok(()) }), ); - client - .upgrade() - .unwrap() - .borrow_mut() - .get_scenegraph_mut() - .spatial_nodes - .insert(path.to_string(), spatial); - Ok(weak_spatial) + spatial } pub fn local_transform(&self) -> Mat4 { @@ -70,7 +60,9 @@ impl<'a> Spatial<'a> { } pub fn global_transform(&self) -> Mat4 { match self.parent.upgrade() { - Some(value) => value.borrow().global_transform() * self.transform, + Some(value) => { + value.borrow().spatial.as_ref().unwrap().global_transform() * self.transform + } None => self.transform, } } @@ -78,7 +70,7 @@ impl<'a> Spatial<'a> { pub fn set_transform_components( &mut self, calling_client: RcCell, - relative_space: RcCell, + relative_space: RcCell, pos: Option>, rot: Option>, scl: Option>,