From be9296588e025aa5ad20381761201adc6b6fb5ba Mon Sep 17 00:00:00 2001 From: Nova Date: Thu, 2 Jun 2022 16:24:47 -0400 Subject: [PATCH] feat(spatial): setTransform local signal --- Cargo.toml | 2 +- src/core/scenegraph.rs | 9 ++++++--- src/nodes/core.rs | 22 +++++++++++++++------ src/nodes/spatial.rs | 44 ++++++++++++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fbbb477..76c8045 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,8 @@ version = "0.9.0" libstardustxr = {path = "../libstardustxr-rs"} anyhow = "1.0.57" ctrlc = "3.2.2" -euler = {version = "0.4.0", features = ["mint"]} flexbuffers = "2.0.0" +glam = {version = "0.20.5", features = ["mint"]} mint = "0.5.9" mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]} rccell = "0.1.3" diff --git a/src/core/scenegraph.rs b/src/core/scenegraph.rs index b5efb58..00c8f60 100644 --- a/src/core/scenegraph.rs +++ b/src/core/scenegraph.rs @@ -3,10 +3,11 @@ use crate::nodes::spatial::Spatial; use anyhow::Result; use libstardustxr::scenegraph; use libstardustxr::scenegraph::ScenegraphError; -use rccell::RcCell; +use rccell::{RcCell, WeakCell}; use std::collections::HashMap; pub struct Scenegraph<'a> { + client: WeakCell>, pub spatial_nodes: HashMap>>, } @@ -15,6 +16,7 @@ impl<'a> Scenegraph<'a> { // root: Spatial::new(Some(client), "/", Default::default()), // hmd: Spatial::new(Some(client), "/hmd", Default::default()), Scenegraph { + client: client.downgrade(), spatial_nodes: HashMap::new(), } } @@ -23,6 +25,7 @@ impl<'a> Scenegraph<'a> { impl<'a> Default for Scenegraph<'a> { fn default() -> Self { Scenegraph { + client: WeakCell::new(), spatial_nodes: HashMap::new(), } } @@ -35,7 +38,7 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { .ok_or(ScenegraphError::NodeNotFound)? .borrow() .node - .send_local_signal(method, data) + .send_local_signal(self.client.upgrade().unwrap(), method, data) .map_err(|_| ScenegraphError::MethodNotFound) } fn execute_method( @@ -49,7 +52,7 @@ impl<'a> scenegraph::Scenegraph for Scenegraph<'a> { .ok_or(ScenegraphError::NodeNotFound)? .borrow() .node - .execute_local_method(method, data) + .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 5ec256e..3e391cf 100644 --- a/src/nodes/core.rs +++ b/src/nodes/core.rs @@ -3,8 +3,8 @@ use anyhow::{anyhow, ensure, Result}; use rccell::{RcCell, WeakCell}; use std::{collections::HashMap, vec::Vec}; -pub type Signal<'a> = Box Result<()> + 'a>; -pub type Method<'a> = Box Result> + 'a>; +pub type Signal<'a> = Box, &[u8]) -> Result<()> + 'a>; +pub type Method<'a> = Box, &[u8]) -> Result> + 'a>; pub struct Node<'a> { client: WeakCell>, @@ -48,15 +48,25 @@ impl<'a> Node<'a> { self.local_signals.insert(method.to_string(), signal); } - pub fn send_local_signal(&self, method: &str, data: &[u8]) -> Result<()> { + pub fn send_local_signal( + &self, + calling_client: RcCell, + method: &str, + data: &[u8], + ) -> Result<()> { self.local_signals .get(method) - .ok_or_else(|| anyhow!("Signal {} not found", method))?(data) + .ok_or_else(|| anyhow!("Signal {} not found", method))?(calling_client, data) } - pub fn execute_local_method(&self, method: &str, data: &[u8]) -> Result> { + pub fn execute_local_method( + &self, + calling_client: RcCell, + method: &str, + data: &[u8], + ) -> Result> { self.local_methods .get(method) - .ok_or_else(|| anyhow!("Method {} not found", method))?(data) + .ok_or_else(|| anyhow!("Method {} not found", method))?(calling_client, data) } pub fn send_remote_signal(&self, method: &str, data: &[u8]) -> Result<()> { self.get_client() diff --git a/src/nodes/spatial.rs b/src/nodes/spatial.rs index f7ea361..332408d 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,22 +1,21 @@ use super::core::Node; use crate::core::client::Client; use anyhow::{anyhow, Result}; -// use euler::Mat4; +use glam::{Mat4, Quat, Vec3}; use libstardustxr::{flex_to_quat, flex_to_vec3}; -use mint::RowMatrix4; use rccell::{RcCell, WeakCell}; pub struct Spatial<'a> { pub node: Node<'a>, parent: WeakCell>, - transform: RowMatrix4, + transform: Mat4, } impl<'a> Spatial<'a> { pub fn new( client: WeakCell>, path: &str, - transform: RowMatrix4, + transform: Mat4, ) -> Result> { let spatial = RcCell::new(Spatial { node: Node::from_path(client.clone(), path, true).unwrap(), @@ -26,9 +25,10 @@ impl<'a> Spatial<'a> { 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( "setTransform", - Box::new(move |data| { + Box::new(move |calling_client, data| { let root = flexbuffers::Reader::get_root(data)?; let flex_vec = root.get_vector()?; let spatial = captured_spatial @@ -39,11 +39,19 @@ impl<'a> Spatial<'a> { .borrow() .get_scenegraph() .spatial_nodes - .get(flex_vec.idx(1).as_str()) - .ok_or(anyhow!("Spatial not found"))?; + .get(flex_vec.idx(0).as_str()) + .ok_or(anyhow!("Spatial not found"))? + .clone(); 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, + ); Ok(()) }), ); @@ -57,18 +65,24 @@ impl<'a> Spatial<'a> { Ok(weak_spatial) } - pub fn local_transform(&self) -> RowMatrix4 { + pub fn local_transform(&self) -> Mat4 { self.transform } - pub fn global_transform(&self) -> RowMatrix4 { - todo!() - // match self.parent.upgrade() { - // Some(value) => Mat4::from(value.borrow().global_transform()) * self.transform, - // None => self.transform, - // } + pub fn global_transform(&self) -> Mat4 { + match self.parent.upgrade() { + Some(value) => value.borrow().global_transform() * self.transform, + None => self.transform, + } } - pub fn set_transform_components(&mut self) { + pub fn set_transform_components( + &mut self, + calling_client: RcCell, + relative_space: RcCell, + pos: Option>, + rot: Option>, + scl: Option>, + ) { todo!() }