diff --git a/Cargo.toml b/Cargo.toml index fa118e0..c5d918a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,16 +32,17 @@ prisma = "0.1.1" slog = "2.7.0" slog-stdlog = "4.1.1" xkbcommon = { version = "0.5.0", default-features = false } -stardust-xr = "0.4.0" -stardust-xr-schemas = "1.0.0" +stardust-xr = "0.4.1" wayland-backend = "=0.1.0-beta.9" wayland-scanner = "=0.30.0-beta.9" directories = "4.0.1" +serde = { version = "1.0.145", features = ["derive"] } [dependencies.stereokit] +path = "../stereokit-rs" default-features = false features = ["linux-egl"] -version = "0.4.0" +version = "0.4.1" [dependencies.smithay] git = "https://github.com/technobaboo/smithay.git" diff --git a/src/core/resource.rs b/src/core/resource.rs index 082f7ff..1de30eb 100644 --- a/src/core/resource.rs +++ b/src/core/resource.rs @@ -1,4 +1,5 @@ -use anyhow::bail; +use anyhow::anyhow; +use serde::{de::Visitor, Deserialize}; use std::path::PathBuf; pub enum ResourceID { @@ -24,20 +25,47 @@ impl ResourceID { } } } - -pub fn parse_resource_id(reader: flexbuffers::Reader<&[u8]>) -> anyhow::Result { - let string = reader.get_str()?; - - Ok(if string.starts_with('/') { - let path = PathBuf::from(string); - path.metadata()?; - ResourceID::File(path) - } else if let Some((namespace, path)) = string.split_once(':') { - ResourceID::Namespaced { - namespace: namespace.to_string(), - path: PathBuf::from(path), - } - } else { - bail!("Invalid format for string"); - }) +impl<'de> Deserialize<'de> for ResourceID { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_any(ResourceVisitor) + } +} + +struct ResourceVisitor; +impl<'de> Visitor<'de> for ResourceVisitor { + type Value = ResourceID; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("A string containing an absolute path to file or \"[namespace]:[path]\" for a namespaced resource") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Ok(if v.starts_with('/') { + let path = PathBuf::from(v); + path.metadata().map_err(serde::de::Error::custom)?; + ResourceID::File(path) + } else if let Some((namespace, path)) = v.split_once(':') { + ResourceID::Namespaced { + namespace: namespace.to_string(), + path: PathBuf::from(path), + } + } else { + return Err(serde::de::Error::custom(anyhow!( + "Invalid format for string" + ))); + }) + } + + fn visit_string(self, v: String) -> Result + where + E: serde::de::Error, + { + self.visit_str(&v) + } } diff --git a/src/main.rs b/src/main.rs index 5801b81..cff5812 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use directories::ProjectDirs; use slog::Drain; use std::sync::Arc; use stereokit::input::Handed; +use stereokit::lifecycle::DepthMode; use stereokit::render::SphericalHarmonics; use stereokit::texture::Texture; use stereokit::{lifecycle::DisplayMode, Settings}; @@ -50,6 +51,7 @@ fn main() -> Result<()> { } else { DisplayMode::MixedReality }) + .depth_mode(DepthMode::D32) .init() .expect("StereoKit failed to initialize"); println!("Init StereoKit"); diff --git a/src/nodes/data.rs b/src/nodes/data.rs index 5594c4a..c8e9e52 100644 --- a/src/nodes/data.rs +++ b/src/nodes/data.rs @@ -7,7 +7,10 @@ use crate::core::registry::Registry; use anyhow::{anyhow, ensure, Result}; use glam::vec3a; use parking_lot::Mutex; -use stardust_xr::flex::flexbuffer_from_vector_arguments; +use serde::Deserialize; +use stardust_xr::schemas::flex::{deserialize, serialize}; +use stardust_xr::values::Transform; + use std::sync::{Arc, Weak}; static PULSE_SENDER_REGISTRY: Registry = Registry::new(); @@ -120,10 +123,10 @@ impl PulseSender { }) .collect(); distance_sorted_receivers.sort_by(|(d1, _), (d2, _)| d1.partial_cmp(d2).unwrap()); - - Ok(flexbuffer_from_vector_arguments(move |fbb| { - sender.aliases.clear(); - for (_, receiver) in distance_sorted_receivers.iter() { + sender.aliases.clear(); + let uids: Vec = distance_sorted_receivers + .into_iter() + .map(|(_, receiver)| { let receiver_alias = Node::create( &calling_client, node.get_path(), @@ -140,9 +143,12 @@ impl PulseSender { vec![], ); sender.aliases.add(Arc::downgrade(&receiver_alias)); - fbb.push(receiver.uid.as_str()); - } - })) + + receiver.uid.clone() + }) + .collect(); + + serialize(uids).map_err(|e| e.into()) } } impl Drop for PulseSender { @@ -239,16 +245,16 @@ pub fn create_pulse_sender_flex( calling_client: Arc, data: &[u8], ) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let flex_vec = root.get_vector()?; - let node = Node::create( - &calling_client, - "/data/sender", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; + #[derive(Deserialize)] + struct CreatePulseSenderInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + } + let info: CreatePulseSenderInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/data/sender", info.name, true); + let parent = get_spatial_parent_flex(&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)?; PulseSender::add_to(&node)?; @@ -270,19 +276,20 @@ pub fn create_pulse_receiver_flex( calling_client: Arc, data: &[u8], ) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let flex_vec = root.get_vector()?; - let node = Node::create( - &calling_client, - "/data/receiver", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; + #[derive(Deserialize)] + struct CreatePulseReceiverInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + field_path: &'a str, + } + let info: CreatePulseReceiverInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/data/sender", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, false)?; let field = calling_client .scenegraph - .get_node(flex_vec.idx(4).as_str()) + .get_node(info.field_path) .ok_or_else(|| anyhow!("Field not found"))? .field .get() diff --git a/src/nodes/drawable/model.rs b/src/nodes/drawable/model.rs index 66b2efd..e904678 100644 --- a/src/nodes/drawable/model.rs +++ b/src/nodes/drawable/model.rs @@ -2,7 +2,7 @@ use super::Node; use crate::core::client::Client; use crate::core::destroy_queue; use crate::core::registry::Registry; -use crate::core::resource::{parse_resource_id, ResourceID}; +use crate::core::resource::ResourceID; use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial}; use anyhow::{anyhow, bail, ensure, Result}; use flexbuffers::FlexBufferType; @@ -11,6 +11,9 @@ use parking_lot::Mutex; use prisma::{Rgb, Rgba}; use rustc_hash::FxHashMap; use send_wrapper::SendWrapper; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; +use stardust_xr::values::Transform; use std::fmt::Error; use std::path::PathBuf; use std::sync::Arc; @@ -164,18 +167,19 @@ pub fn draw_all(sk: &StereoKit, draw_ctx: &DrawContext) { } pub fn create_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create( - &calling_client, - "/drawable/model", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, true)?; - let resource_id = parse_resource_id(flex_vec.idx(3))?; + #[derive(Deserialize)] + struct CreateModelInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + resource: ResourceID, + } + let info: CreateModelInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/drawable/model", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, true)?; let node = node.add_to_scenegraph(); Spatial::add_to(&node, Some(parent), transform)?; - Model::add_to(&node, resource_id)?; + Model::add_to(&node, info.resource)?; Ok(()) } diff --git a/src/nodes/drawable/text.rs b/src/nodes/drawable/text.rs index 20f92fd..27c295b 100644 --- a/src/nodes/drawable/text.rs +++ b/src/nodes/drawable/text.rs @@ -1,23 +1,20 @@ use crate::{ - core::{ - client::Client, - destroy_queue, - registry::Registry, - resource::{parse_resource_id, ResourceID}, - }, + core::{client::Client, destroy_queue, registry::Registry, resource::ResourceID}, nodes::{ spatial::{get_spatial_parent_flex, parse_transform, Spatial}, Node, }, }; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{ensure, Result}; use glam::{vec3, Mat4, Vec2}; +use mint::Vector2; use once_cell::sync::OnceCell; use parking_lot::Mutex; -use prisma::{FromTuple, Rgb, Rgba}; +use prisma::{Flatten, Rgb, Rgba}; use send_wrapper::SendWrapper; -use stardust_xr::values::{parse_f32, parse_vec2}; -use std::{convert::TryFrom, path::PathBuf, sync::Arc}; +use serde::Deserialize; +use stardust_xr::{schemas::flex::deserialize, values::Transform}; +use std::{path::PathBuf, sync::Arc}; use stereokit::{ font::Font, lifecycle::DrawContext, @@ -52,7 +49,7 @@ impl Text { text: String, character_height: f32, text_align: TextAlign, - bounds: Option, + bounds: Option>, fit: TextFit, bounds_align: TextAlign, color: Rgba, @@ -77,7 +74,7 @@ impl Text { text, character_height, text_align, - bounds, + bounds: bounds.map(|b| b.into()), fit, bounds_align, color, @@ -175,45 +172,37 @@ pub fn draw_all(sk: &StereoKit, draw_ctx: &DrawContext) { } pub fn create_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create( - &calling_client, - "/drawable/text", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, true)?; - let text = flex_vec.index(3)?.get_str()?.to_string(); - let font_resource_id = parse_resource_id(flex_vec.index(4)?).ok(); - let character_height = flex_vec.index(5)?.get_f64()? as f32; - let text_align = TextAlign::from_bits(flex_vec.index(6)?.get_u64()? as u32) - .ok_or_else(|| anyhow!("Text align bitflag out of range"))?; - let bounds = parse_vec2(flex_vec.index(7)?).map(|bounds| bounds.into()); - let fit = TextFit::try_from(flex_vec.index(8)?.get_u64()? as u32)?; - let bounds_align = TextAlign::from_bits(flex_vec.index(9)?.get_u64()? as u32) - .ok_or_else(|| anyhow!("Bounds align bitflag out of range"))?; - let color_vec = flex_vec.index(10)?.get_vector()?; - let color = Rgba::from_tuple(( - ( - parse_f32(color_vec.index(0)?).ok_or_else(|| anyhow!("Value in color invalid"))?, - parse_f32(color_vec.index(0)?).ok_or_else(|| anyhow!("Value in color invalid"))?, - parse_f32(color_vec.index(0)?).ok_or_else(|| anyhow!("Value in color invalid"))?, - ), - parse_f32(color_vec.index(0)?).ok_or_else(|| anyhow!("Value in color invalid"))?, - )); + #[derive(Deserialize)] + struct CreateTextInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + text: String, + font_resource: Option, + character_height: f32, + text_align: TextAlign, + bounds: Option>, + fit: TextFit, + bounds_align: TextAlign, + color: [f32; 4], + } + let info: CreateTextInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/drawable/text", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, true)?; + let color = Rgba::from_slice(&info.color); let node = node.add_to_scenegraph(); Spatial::add_to(&node, Some(parent), transform)?; Text::add_to( &node, - font_resource_id, - text, - character_height, - text_align, - bounds, - fit, - bounds_align, + info.font_resource, + info.text, + info.character_height, + info.text_align, + info.bounds, + info.fit, + info.bounds_align, color, )?; Ok(()) diff --git a/src/nodes/fields/box.rs b/src/nodes/fields/box.rs index 30663d5..7664f35 100644 --- a/src/nodes/fields/box.rs +++ b/src/nodes/fields/box.rs @@ -1,10 +1,13 @@ use super::{Field, FieldTrait, Node}; use crate::core::client::Client; use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{ensure, Result}; use glam::{vec3, vec3a, Vec3, Vec3A}; +use mint::Vector3; use parking_lot::Mutex; -use stardust_xr::values::parse_vec3; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; +use stardust_xr::values::Transform; use std::sync::Arc; pub struct BoxField { @@ -13,7 +16,7 @@ pub struct BoxField { } impl BoxField { - pub fn add_to(node: &Arc, size: Vec3) -> Result<()> { + pub fn add_to(node: &Arc, size: Vector3) -> Result<()> { ensure!( node.spatial.get().is_some(), "Internal: Node does not have a spatial attached!" @@ -24,7 +27,7 @@ impl BoxField { ); let box_field = BoxField { space: node.spatial.get().unwrap().clone(), - size: Mutex::new(size), + size: Mutex::new(size.into()), }; box_field.add_field_methods(node); node.add_local_signal("setSize", BoxField::set_size_flex); @@ -32,15 +35,13 @@ impl BoxField { Ok(()) } - pub fn set_size(&self, size: Vec3) { - *self.size.lock() = size; + pub fn set_size(&self, size: Vector3) { + *self.size.lock() = size.into(); } pub fn set_size_flex(node: &Node, _calling_client: Arc, data: &[u8]) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let size = parse_vec3(root).ok_or_else(|| anyhow!("Size is invalid"))?; if let Field::Box(box_field) = node.field.get().unwrap().as_ref() { - box_field.set_size(size.into()); + box_field.set_size(deserialize(data)?); } Ok(()) } @@ -63,18 +64,19 @@ impl FieldTrait for BoxField { } pub fn create_box_field_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create( - &calling_client, - "/field", - flex_vec.index(0)?.get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; - let size = parse_vec3(flex_vec.index(3)?).ok_or_else(|| anyhow!("Size invalid"))?; + #[derive(Deserialize)] + struct CreateFieldInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + size: Vector3, + } + let info: CreateFieldInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/field", info.name, true); + let parent = get_spatial_parent_flex(&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)?; - BoxField::add_to(&node, size.into())?; + BoxField::add_to(&node, info.size)?; Ok(()) } diff --git a/src/nodes/fields/cylinder.rs b/src/nodes/fields/cylinder.rs index e484cd2..877f328 100644 --- a/src/nodes/fields/cylinder.rs +++ b/src/nodes/fields/cylinder.rs @@ -4,7 +4,9 @@ use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial}; use anyhow::{ensure, Result}; use glam::{swizzles::*, vec2, Vec3A}; use portable_atomic::AtomicF32; -use stardust_xr::values::parse_f32; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; +use stardust_xr::values::Transform; use std::sync::atomic::Ordering; use std::sync::Arc; @@ -42,12 +44,8 @@ impl CylinderField { } pub fn set_size_flex(node: &Node, _calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let length = - parse_f32(flex_vec.index(0)?).ok_or_else(|| anyhow::anyhow!("Invalid length"))?; - let radius = - parse_f32(flex_vec.index(1)?).ok_or_else(|| anyhow::anyhow!("Invalid radius"))?; if let Field::Cylinder(cylinder_field) = node.field.get().unwrap().as_ref() { + let (length, radius) = deserialize(data)?; cylinder_field.set_size(length, radius); } Ok(()) @@ -72,19 +70,20 @@ pub fn create_cylinder_field_flex( calling_client: Arc, data: &[u8], ) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create( - &calling_client, - "/field", - flex_vec.index(0)?.get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; - let length = parse_f32(flex_vec.index(3)?).ok_or_else(|| anyhow::anyhow!("Invalid length"))?; - let radius = parse_f32(flex_vec.index(4)?).ok_or_else(|| anyhow::anyhow!("Invalid radius"))?; + #[derive(Deserialize)] + struct CreateFieldInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + length: f32, + radius: f32, + } + let info: CreateFieldInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/field", info.name, true); + let parent = get_spatial_parent_flex(&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)?; - CylinderField::add_to(&node, dbg!(length), dbg!(radius))?; + CylinderField::add_to(&node, dbg!(info.length), dbg!(info.radius))?; Ok(()) } diff --git a/src/nodes/fields/mod.rs b/src/nodes/fields/mod.rs index ca1eb24..bdc7219 100644 --- a/src/nodes/fields/mod.rs +++ b/src/nodes/fields/mod.rs @@ -11,8 +11,9 @@ use super::Node; use crate::core::client::Client; use anyhow::{anyhow, Result}; use glam::{vec2, vec3a, Vec3, Vec3A}; -use stardust_xr::flex::FlexBuffable; -use stardust_xr::values::parse_vec3; +use mint::Vector3; +use serde::Deserialize; +use stardust_xr::schemas::flex::{deserialize, serialize}; use std::ops::Deref; use std::sync::Arc; @@ -69,65 +70,79 @@ pub trait FieldTrait { } fn field_distance_flex(node: &Node, calling_client: Arc, data: &[u8]) -> Result> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; + #[derive(Deserialize)] + struct FieldInfoArgs<'a> { + reference_space_path: &'a str, + point: Vector3, + } + let args: FieldInfoArgs = deserialize(data)?; let reference_space = calling_client .scenegraph - .get_node(flex_vec.idx(0).as_str()) + .get_node(args.reference_space_path) .ok_or_else(|| anyhow!("Reference space node does not exist"))? .spatial .get() .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .clone(); - let point = parse_vec3(flex_vec.idx(1)).ok_or_else(|| anyhow!("Point is invalid"))?; let distance = node .field .get() .unwrap() - .distance(reference_space.as_ref(), point.into()); - Ok(FlexBuffable::from(distance).build_singleton()) + .distance(reference_space.as_ref(), args.point.into()); + Ok(serialize(distance)?) } fn field_normal_flex(node: &Node, calling_client: Arc, data: &[u8]) -> Result> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; + #[derive(Deserialize)] + struct FieldInfoArgs<'a> { + reference_space_path: &'a str, + point: Vector3, + radius: Option, + } + let args: FieldInfoArgs = deserialize(data)?; let reference_space = calling_client .scenegraph - .get_node(flex_vec.idx(0).as_str()) + .get_node(args.reference_space_path) .ok_or_else(|| anyhow!("Reference space node does not exist"))? .spatial .get() .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .clone(); - let point = parse_vec3(flex_vec.idx(1)).ok_or_else(|| anyhow!("Point is invalid"))?; let normal = node.field.get().as_ref().unwrap().normal( reference_space.as_ref(), - point.into(), - 0.001_f32, + args.point.into(), + args.radius.unwrap_or(0.001), ); - Ok(FlexBuffable::from(mint::Vector3::from(normal)).build_singleton()) + Ok(serialize(mint::Vector3::from(normal))?) } fn field_closest_point_flex( node: &Node, calling_client: Arc, data: &[u8], ) -> Result> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; + #[derive(Deserialize)] + struct FieldInfoArgs<'a> { + reference_space_path: &'a str, + point: Vector3, + radius: Option, + } + let args: FieldInfoArgs = deserialize(data)?; let reference_space = calling_client .scenegraph - .get_node(flex_vec.idx(0).as_str()) + .get_node(args.reference_space_path) .ok_or_else(|| anyhow!("Reference space node does not exist"))? .spatial .get() .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .clone(); - let point = parse_vec3(flex_vec.idx(1)).ok_or_else(|| anyhow!("Point is invalid"))?; - let closest_point = - node.field - .get() - .unwrap() - .closest_point(reference_space.as_ref(), point.into(), 0.001_f32); - Ok(FlexBuffable::from(mint::Vector3::from(closest_point)).build_singleton()) + let closest_point = node.field.get().as_ref().unwrap().closest_point( + reference_space.as_ref(), + args.point.into(), + args.radius.unwrap_or(0.001), + ); + Ok(serialize(mint::Vector3::from(closest_point))?) } pub enum Field { diff --git a/src/nodes/fields/sphere.rs b/src/nodes/fields/sphere.rs index 48c0d95..313d230 100644 --- a/src/nodes/fields/sphere.rs +++ b/src/nodes/fields/sphere.rs @@ -1,10 +1,12 @@ use super::{Field, FieldTrait, Node}; use crate::core::client::Client; use crate::nodes::spatial::{get_spatial_parent_flex, Spatial}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{ensure, Result}; use glam::{Mat4, Vec3A}; +use mint::Vector3; use portable_atomic::AtomicF32; -use stardust_xr::values::parse_vec3; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; use std::sync::atomic::Ordering; use std::sync::Arc; @@ -66,16 +68,19 @@ pub fn create_sphere_field_flex( calling_client: Arc, data: &[u8], ) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create(&calling_client, "/field", flex_vec.idx(0).get_str()?, true); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = Mat4::from_translation( - parse_vec3(flex_vec.idx(2)) - .ok_or_else(|| anyhow!("Position not found"))? - .into(), - ); + #[derive(Deserialize)] + struct CreateFieldInfo<'a> { + name: &'a str, + parent_path: &'a str, + origin: Option>, + radius: f32, + } + let info: CreateFieldInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/field", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = Mat4::from_translation(info.origin.unwrap_or(Vector3::from([0.0; 3])).into()); let node = node.add_to_scenegraph(); Spatial::add_to(&node, Some(parent), transform)?; - SphereField::add_to(&node, flex_vec.idx(3).as_f32())?; + SphereField::add_to(&node, info.radius)?; Ok(()) } diff --git a/src/nodes/input/hand.rs b/src/nodes/input/hand.rs index 148eae7..aceb6eb 100644 --- a/src/nodes/input/hand.rs +++ b/src/nodes/input/hand.rs @@ -1,8 +1,7 @@ use crate::nodes::fields::Field; use crate::nodes::spatial::Spatial; use glam::{vec3a, Mat4}; -use stardust_xr_schemas::input_hand::HandT; -use stardust_xr_schemas::{common::JointT, input::InputDataRaw}; +use stardust_xr::schemas::{common::JointT, input::InputDataRaw, input_hand::HandT}; use std::sync::Arc; use super::{DistanceLink, InputSpecialization}; diff --git a/src/nodes/input/mod.rs b/src/nodes/input/mod.rs index 71dbca4..5ffefc7 100644 --- a/src/nodes/input/mod.rs +++ b/src/nodes/input/mod.rs @@ -16,7 +16,10 @@ use anyhow::{anyhow, ensure, Result}; use glam::Mat4; use nanoid::nanoid; use parking_lot::Mutex; -use stardust_xr_schemas::input::{InputData, InputDataArgs, InputDataRaw}; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; +use stardust_xr::schemas::input::{InputData, InputDataArgs, InputDataRaw}; +use stardust_xr::values::Transform; use std::ops::Deref; use std::sync::atomic::Ordering; use std::sync::{Arc, Weak}; @@ -213,19 +216,20 @@ pub fn create_input_handler_flex( calling_client: Arc, data: &[u8], ) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let flex_vec = root.get_vector()?; - let node = Node::create( - &calling_client, - "/input/handler", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.idx(2), true, true, false)?; + #[derive(Deserialize)] + struct CreateInputHandlerInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + field_path: &'a str, + } + let info: CreateInputHandlerInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/input/handler", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, false)?; let field = calling_client .scenegraph - .get_node(flex_vec.idx(3).as_str()) + .get_node(info.field_path) .ok_or_else(|| anyhow!("Field not found"))? .field .get() diff --git a/src/nodes/input/pointer.rs b/src/nodes/input/pointer.rs index f9ad9a8..aefd39c 100644 --- a/src/nodes/input/pointer.rs +++ b/src/nodes/input/pointer.rs @@ -2,8 +2,7 @@ use super::{DistanceLink, InputSpecialization}; use crate::nodes::fields::{ray_march, Field, Ray, RayMarchResult}; use crate::nodes::spatial::Spatial; use glam::{vec3, Mat4}; -use stardust_xr_schemas::input::InputDataRaw; -use stardust_xr_schemas::input_pointer; +use stardust_xr::schemas::{input::InputDataRaw, input_pointer}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; diff --git a/src/nodes/input/tip.rs b/src/nodes/input/tip.rs index da37e36..330822a 100644 --- a/src/nodes/input/tip.rs +++ b/src/nodes/input/tip.rs @@ -3,8 +3,7 @@ use crate::nodes::fields::Field; use crate::nodes::spatial::Spatial; use glam::{vec3a, Mat4}; use portable_atomic::AtomicF32; -use stardust_xr_schemas::input::InputDataRaw; -use stardust_xr_schemas::input_tip; +use stardust_xr::schemas::{input::InputDataRaw, input_tip}; use std::sync::atomic::Ordering; use std::sync::Arc; diff --git a/src/nodes/items/environment.rs b/src/nodes/items/environment.rs index 3d9d4bd..e2b0fdb 100644 --- a/src/nodes/items/environment.rs +++ b/src/nodes/items/environment.rs @@ -1,6 +1,17 @@ use super::{Item, ItemSpecialization, ItemType, ITEM_TYPE_INFO_ENVIRONMENT}; -use crate::{core::client::Client, nodes::Node}; +use crate::{ + core::client::{Client, INTERNAL_CLIENT}, + nodes::{ + spatial::{get_spatial_parent_flex, parse_transform, Spatial}, + Node, + }, +}; use anyhow::{anyhow, Result}; +use serde::Deserialize; +use stardust_xr::{ + schemas::flex::{deserialize, serialize}, + values::Transform, +}; use std::sync::Arc; pub struct EnvironmentItem { @@ -25,7 +36,50 @@ impl EnvironmentItem { } } impl ItemSpecialization for EnvironmentItem { - fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) { - vec.push(self.path.as_str()); + fn serialize_start_data(&self, id: &str) -> Vec { + serialize((id, self.path.as_str())).unwrap() } } + +pub(super) fn create_environment_item_flex( + _node: &Node, + calling_client: Arc, + data: &[u8], +) -> Result<()> { + #[derive(Deserialize)] + struct CreateEnvironmentItemInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + item_data: String, + } + let info: CreateEnvironmentItemInfo = deserialize(data)?; + let parent_name = format!("/item/{}/item/", ITEM_TYPE_INFO_ENVIRONMENT.type_name); + let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true); + let space = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, false)?; + let node = node.add_to_scenegraph(); + Spatial::add_to(&node, None, transform * space.global_transform())?; + EnvironmentItem::add_to(&node, info.item_data); + node.item + .get() + .unwrap() + .make_alias(&calling_client, &parent_name); + Ok(()) +} + +pub(super) fn create_environment_item_acceptor_flex( + _node: &Node, + calling_client: Arc, + data: &[u8], +) -> Result<()> { + super::create_item_acceptor_flex(calling_client, data, &ITEM_TYPE_INFO_ENVIRONMENT) +} + +pub(super) fn register_environment_item_ui_flex( + _node: &Node, + calling_client: Arc, + _data: &[u8], +) -> Result<()> { + super::register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_ENVIRONMENT) +} diff --git a/src/nodes/items/mod.rs b/src/nodes/items/mod.rs index 235781a..72fa299 100644 --- a/src/nodes/items/mod.rs +++ b/src/nodes/items/mod.rs @@ -13,7 +13,10 @@ use anyhow::{anyhow, ensure, Result}; use lazy_static::lazy_static; use nanoid::nanoid; use parking_lot::Mutex; -use stardust_xr::flex::flexbuffer_from_vector_arguments; +use serde::Deserialize; +use stardust_xr::schemas::flex::deserialize; +use stardust_xr::values::Transform; + use std::ops::Deref; use std::sync::{Arc, Weak}; @@ -155,7 +158,7 @@ impl Drop for Item { } pub trait ItemSpecialization { - fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder); + fn serialize_start_data(&self, id: &str) -> Vec; } pub enum ItemType { @@ -214,12 +217,7 @@ impl ItemUI { let _ = node.send_remote_signal( "create", - &flexbuffer_from_vector_arguments(|vec| { - vec.push(item.uid.as_str()); - let mut start_data_vec = vec.start_vector(); - item.specialization - .serialize_start_data(&mut start_data_vec); - }), + &item.specialization.serialize_start_data(&item.uid), ); } fn handle_destroy_item(&self, item: &Item) { @@ -324,72 +322,49 @@ impl Drop for ItemAcceptor { pub fn create_interface(client: &Arc) { let node = Node::create(client, "", "item", false); - node.add_local_signal("createEnvironmentItem", create_environment_item_flex); + node.add_local_signal( + "createEnvironmentItem", + environment::create_environment_item_flex, + ); node.add_local_signal( "registerEnvironmentItemUI", - register_environment_item_ui_flex, + environment::register_environment_item_ui_flex, ); node.add_local_signal("registerPanelItemUI", register_panel_item_ui_flex); node.add_local_signal( "createEnvironmentItemAcceptor", - create_environment_item_acceptor_flex, + environment::create_environment_item_acceptor_flex, ); node.add_to_scenegraph(); } -pub fn create_environment_item_flex( - _node: &Node, - calling_client: Arc, - data: &[u8], -) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let flex_vec = root.get_vector()?; - let parent_name = format!("/item/{}/item/", ITEM_TYPE_INFO_ENVIRONMENT.type_name); - let node = Node::create( - &INTERNAL_CLIENT, - &parent_name, - flex_vec.idx(0).get_str()?, - true, - ); - let space = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.idx(2), true, true, false)?; - let node = node.add_to_scenegraph(); - Spatial::add_to(&node, None, transform * space.global_transform())?; - EnvironmentItem::add_to(&node, flex_vec.idx(3).get_str()?.to_string()); - node.item - .get() - .unwrap() - .make_alias(&calling_client, &parent_name); - Ok(()) -} - -pub fn create_item_acceptor_flex( +pub(self) fn create_item_acceptor_flex( calling_client: Arc, data: &[u8], type_info: &'static TypeInfo, ) -> Result<()> { - let root = flexbuffers::Reader::get_root(data)?; - let flex_vec = root.get_vector()?; + #[derive(Deserialize)] + struct CreateItemAcceptorInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + field_path: &'a str, + } + let info: CreateItemAcceptorInfo = deserialize(data)?; let parent_name = format!("/item/{}/acceptor/", ITEM_TYPE_INFO_ENVIRONMENT.type_name); - let space = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; - let transform = parse_transform(flex_vec.idx(2), true, true, false)?; + let space = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, false)?; let field = calling_client .scenegraph - .get_node(flex_vec.idx(3).get_str()?) + .get_node(info.field_path) .ok_or_else(|| anyhow!("Field node not found"))?; let field = field .field .get() .ok_or_else(|| anyhow!("Field node is not a field"))?; - let node = Node::create( - &INTERNAL_CLIENT, - &parent_name, - flex_vec.idx(0).get_str()?, - true, - ) - .add_to_scenegraph(); - Spatial::add_to(&node, None, transform * space.global_transform())?; + let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true).add_to_scenegraph(); + Spatial::add_to(&node, Some(space), transform)?; ItemAcceptor::add_to(&node, type_info, Arc::downgrade(field)); node.item .get() @@ -398,14 +373,6 @@ pub fn create_item_acceptor_flex( Ok(()) } -pub fn create_environment_item_acceptor_flex( - _node: &Node, - calling_client: Arc, - data: &[u8], -) -> Result<()> { - create_item_acceptor_flex(calling_client, data, &ITEM_TYPE_INFO_ENVIRONMENT) -} - pub fn register_item_ui_flex( calling_client: Arc, type_info: &'static TypeInfo, @@ -414,11 +381,3 @@ pub fn register_item_ui_flex( ItemUI::add_to(&ui, type_info)?; Ok(()) } - -pub fn register_environment_item_ui_flex( - _node: &Node, - calling_client: Arc, - _data: &[u8], -) -> Result<()> { - register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_ENVIRONMENT) -} diff --git a/src/nodes/root.rs b/src/nodes/root.rs index d9fb9e8..63c2328 100644 --- a/src/nodes/root.rs +++ b/src/nodes/root.rs @@ -5,8 +5,8 @@ use crate::core::client::Client; use crate::core::registry::Registry; use anyhow::{anyhow, Result}; use glam::Mat4; -use stardust_xr::flex::flexbuffer_from_vector_arguments; -use std::path::PathBuf; +use stardust_xr::schemas::flex::{deserialize, serialize}; + use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -59,25 +59,17 @@ impl Root { } pub fn logic_step(delta: f64) { - let data = flexbuffer_from_vector_arguments(move |fbb| { - fbb.push(delta); - fbb.push(0_f64); - }); - for root in ROOT_REGISTRY.get_valid_contents() { - if root.logic_step.load(Ordering::Relaxed) { - let _ = root.node.send_remote_signal("logicStep", &data); + if let Ok(data) = serialize((delta, 0.0)) { + for root in ROOT_REGISTRY.get_valid_contents() { + if root.logic_step.load(Ordering::Relaxed) { + let _ = root.node.send_remote_signal("logicStep", &data); + } } } } fn set_base_prefixes(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - *calling_client.base_resource_prefixes.lock() = flex_vec - .iter() - .filter_map(|prefix| prefix.get_str().ok()) - .map(PathBuf::from) - .filter(|prefix| prefix.is_absolute()) - .collect(); + *calling_client.base_resource_prefixes.lock() = deserialize(data)?; Ok(()) } } diff --git a/src/nodes/spatial.rs b/src/nodes/spatial.rs index 26019d6..e730ac2 100644 --- a/src/nodes/spatial.rs +++ b/src/nodes/spatial.rs @@ -1,12 +1,13 @@ use super::Node; use crate::core::client::Client; use anyhow::{anyhow, ensure, Result}; -use glam::{Mat4, Quat, Vec3}; +use glam::{Mat4, Quat}; use mint::Vector3; use parking_lot::Mutex; -use stardust_xr::flex::flexbuffer_from_vector_arguments; -use stardust_xr::push_to_vec; -use stardust_xr::values::{parse_quat, parse_vec3}; + +use serde::Deserialize; +use stardust_xr::schemas::flex::{deserialize, serialize}; +use stardust_xr::values::Transform; use std::ptr; use std::sync::{Arc, Weak}; @@ -71,9 +72,7 @@ impl Spatial { pub fn set_local_transform_components( &self, reference_space: Option<&Spatial>, - pos: Option, - rot: Option, - scl: Option, + transform: Transform, ) { let reference_to_parent_transform = reference_space .map(|reference_space| { @@ -85,16 +84,16 @@ impl Spatial { let (mut reference_space_scl, mut reference_space_rot, mut reference_space_pos) = local_transform_in_reference_space.to_scale_rotation_translation(); - if let Some(pos) = pos { - reference_space_pos = pos + if let Some(pos) = transform.position { + reference_space_pos = pos.into() } - if let Some(rot) = rot { - reference_space_rot = rot + if let Some(rot) = transform.rotation { + reference_space_rot = rot.into() } else if reference_space_rot.is_nan() { reference_space_rot = Quat::IDENTITY; } - if let Some(scl) = scl { - reference_space_scl = scl + if let Some(scl) = transform.scale { + reference_space_scl = scl.into() } local_transform_in_reference_space = Mat4::from_scale_rotation_translation( @@ -158,14 +157,13 @@ impl Spatial { calling_client: Arc, data: &[u8], ) -> Result> { - let root = flexbuffers::Reader::get_root(data)?; let this_spatial = node .spatial .get() .ok_or_else(|| anyhow!("Node doesn't have a spatial?"))?; let relative_spatial = calling_client .scenegraph - .get_node(root.as_str()) + .get_node(deserialize(data)?) .ok_or_else(|| anyhow!("Space not found"))? .spatial .get() @@ -178,37 +176,37 @@ impl Spatial { ) .to_scale_rotation_translation(); - Ok(flexbuffer_from_vector_arguments(|vec| { - push_to_vec!( - vec, - mint::Vector3::from(position), - mint::Quaternion::from(rotation), - mint::Vector3::from(scale) - ); - })) + serialize(( + mint::Vector3::from(position), + mint::Quaternion::from(rotation), + mint::Vector3::from(scale), + )) + .map_err(|e| e.into()) } pub fn set_transform_flex(node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let reference_space_path = flex_vec.idx(0).as_str(); - let reference_space_transform = if reference_space_path.is_empty() { - None - } else { - Some( - calling_client + #[derive(Deserialize)] + struct TransformArgs<'a> { + reference_space_path: Option<&'a str>, + transform: Transform, + } + let transform_args: TransformArgs = deserialize(data)?; + let reference_space_transform = transform_args + .reference_space_path + .map(|path| -> Result> { + Ok(calling_client .scenegraph - .get_node(reference_space_path) + .get_node(path) .ok_or_else(|| anyhow!("Other spatial node not found"))? .spatial .get() .ok_or_else(|| anyhow!("Node is not a Spatial!"))? - .clone(), - ) - }; + .clone()) + }) + .transpose()?; + node.spatial.get().unwrap().set_local_transform_components( reference_space_transform.as_deref(), - parse_vec3(flex_vec.idx(1)).map(|v| v.into()), - parse_quat(flex_vec.idx(2)).map(|v| v.into()), - parse_vec3(flex_vec.idx(3)).map(|v| v.into()), + transform_args.transform, ); Ok(()) } @@ -217,10 +215,9 @@ impl Spatial { calling_client: Arc, data: &[u8], ) -> Result<()> { - let parent_path = flexbuffers::Reader::get_root(data)?.get_str()?; let parent = calling_client .scenegraph - .get_node(parent_path) + .get_node(deserialize(data)?) .ok_or_else(|| anyhow!("Parent node not found"))? .spatial .get() @@ -254,6 +251,32 @@ impl Spatial { } } +pub fn parse_transform( + transform: Transform, + translation: bool, + rotation: bool, + scale: bool, +) -> Result { + let translation = translation + .then_some(transform.position) + .flatten() + .unwrap_or_else(|| Vector3::from([0.0; 3])); + let rotation = rotation + .then_some(transform.rotation) + .flatten() + .unwrap_or_else(|| Quat::IDENTITY.into()); + let scale = scale + .then_some(transform.scale) + .flatten() + .unwrap_or_else(|| Vector3::from([1.0; 3])); + + Ok(Mat4::from_scale_rotation_translation( + scale.into(), + rotation.into(), + translation.into(), + )) +} + pub fn get_spatial_parent_flex( calling_client: &Arc, node_path: &str, @@ -267,32 +290,6 @@ pub fn get_spatial_parent_flex( .ok_or_else(|| anyhow!("Spatial parent node is not a spatial"))? .clone()) } -pub fn parse_transform( - reader: flexbuffers::Reader, - translation: bool, - rotation: bool, - scale: bool, -) -> Result { - let transform_vec = reader.get_vector()?; - let translation = translation - .then(|| parse_vec3(transform_vec.idx(0))) - .flatten() - .unwrap_or_else(|| Vector3::from([0.0; 3])); - let rotation = rotation - .then(|| parse_quat(transform_vec.idx(1))) - .flatten() - .unwrap_or_else(|| Quat::IDENTITY.into()); - let scale = scale - .then(|| parse_vec3(transform_vec.idx(2))) - .flatten() - .unwrap_or_else(|| Vector3::from([1.0; 3])); - - Ok(Mat4::from_scale_rotation_translation( - scale.into(), - rotation.into(), - translation.into(), - )) -} pub fn create_interface(client: &Arc) { let node = Node::create(client, "", "spatial", false); @@ -301,15 +298,16 @@ pub fn create_interface(client: &Arc) { } pub fn create_spatial_flex(_node: &Node, calling_client: Arc, data: &[u8]) -> Result<()> { - let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; - let node = Node::create( - &calling_client, - "/spatial/spatial", - flex_vec.idx(0).get_str()?, - true, - ); - let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; - let transform = parse_transform(flex_vec.index(2)?, true, true, true)?; + #[derive(Deserialize)] + struct CreateSpatialInfo<'a> { + name: &'a str, + parent_path: &'a str, + transform: Transform, + } + let info: CreateSpatialInfo = deserialize(data)?; + let node = Node::create(&calling_client, "/spatial/spatial", info.name, true); + let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?; + let transform = parse_transform(info.transform, true, true, true)?; let node = node.add_to_scenegraph(); Spatial::add_to(&node, Some(parent), transform)?; Ok(()) diff --git a/src/objects/input/mouse_pointer.rs b/src/objects/input/mouse_pointer.rs index 6aedc55..457ab59 100644 --- a/src/objects/input/mouse_pointer.rs +++ b/src/objects/input/mouse_pointer.rs @@ -3,6 +3,7 @@ use crate::nodes::{ spatial::Spatial, }; use glam::{vec3, Mat4}; +use stardust_xr::values::Transform; use std::sync::{Arc, Weak}; use stereokit::{input::Ray, StereoKit}; @@ -22,12 +23,13 @@ impl MousePointer { if let Some(ray) = Ray::from_mouse(sk.input_mouse()) { self.pointer.spatial.set_local_transform_components( None, - Some(ray.pos.into()), - Some(glam::Quat::from_rotation_arc( - vec3(0.0, 0.0, 1.0), - ray.dir.into(), - )), - None, + Transform { + position: Some(ray.pos.into()), + rotation: Some( + glam::Quat::from_rotation_arc(vec3(0.0, 0.0, 1.0), ray.dir.into()).into(), + ), + scale: None, + }, ); } } diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index a299e35..692b7b5 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -4,6 +4,7 @@ use crate::nodes::{ }; use glam::Mat4; use portable_atomic::Ordering; +use stardust_xr::values::Transform; use std::sync::{Arc, Weak}; use stereokit::{input::Handed, StereoKit}; @@ -28,9 +29,11 @@ impl SkController { if controller.tracked.is_active() { self.tip.spatial.set_local_transform_components( None, - Some(controller.pose.position.into()), - Some(controller.pose.orientation.into()), - None, + Transform { + position: Some(controller.pose.position.into()), + rotation: Some(controller.pose.orientation.into()), + scale: None, + }, ); } diff --git a/src/objects/input/sk_hand.rs b/src/objects/input/sk_hand.rs index be13e0a..845a38f 100644 --- a/src/objects/input/sk_hand.rs +++ b/src/objects/input/sk_hand.rs @@ -3,7 +3,7 @@ use crate::nodes::{ spatial::Spatial, }; use glam::Mat4; -use stardust_xr_schemas::{common::JointT, input_hand::HandT}; +use stardust_xr::schemas::{common::JointT, input_hand::HandT}; use std::sync::{Arc, Weak}; use stereokit::{ input::{Handed, Joint as SkJoint}, diff --git a/src/wayland/panel_item.rs b/src/wayland/panel_item.rs index b0b54dd..4ed0317 100644 --- a/src/wayland/panel_item.rs +++ b/src/wayland/panel_item.rs @@ -16,16 +16,15 @@ use crate::{ use anyhow::{anyhow, bail, Result}; use glam::Mat4; use lazy_static::lazy_static; +use mint::Vector2; use nanoid::nanoid; +use serde::Deserialize; use smithay::{ reexports::wayland_server::protocol::wl_pointer::{Axis, ButtonState}, utils::Size, wayland::{compositor::SurfaceData, shell::xdg::XdgToplevelSurfaceData}, }; -use stardust_xr::{ - flex::{flexbuffer_from_arguments, flexbuffer_from_vector_arguments}, - values::parse_vec2, -}; +use stardust_xr::schemas::flex::{deserialize, serialize}; use std::sync::{Arc, Weak}; use xkbcommon::xkb::{self, ffi::XKB_KEYMAP_FORMAT_TEXT_V1, Keymap}; @@ -191,13 +190,11 @@ impl PanelItem { pub fn resize(&self) { self.core_surface.upgrade().unwrap().with_data(|data| { - let _ = self.node.upgrade().unwrap().send_remote_signal( - "resize", - &flexbuffer_from_vector_arguments(|vec| { - vec.push(data.size.x); - vec.push(data.size.y); - }), - ); + let _ = self + .node + .upgrade() + .unwrap() + .send_remote_signal("resize", &serialize(data.size).unwrap()); }); } @@ -206,26 +203,13 @@ impl PanelItem { if !*cursor_changed { return; } - let mut data = flexbuffer_from_arguments(|flex| { - flex.build_singleton(()); - }); + let mut data = serialize(()).unwrap(); if let Some(cursor) = &*self.seat_data.cursor.lock() { let cursor = cursor.lock(); if let Some(core_surface) = cursor.core_surface.upgrade() { if let Some(mapped_data) = &*core_surface.mapped_data.lock() { - data = flexbuffer_from_vector_arguments(|vec| { - let mut size_vec = vec.start_vector(); - let size = mapped_data.size; - size_vec.push(size.x); - size_vec.push(size.y); - size_vec.end_vector(); - - let mut hotspot_vec = vec.start_vector(); - hotspot_vec.push(cursor.hotspot.x); - hotspot_vec.push(cursor.hotspot.y); - hotspot_vec.end_vector(); - }); + data = serialize((mapped_data.size, cursor.hotspot)).unwrap(); } else { return; }; @@ -318,6 +302,12 @@ impl PanelItem { } fn pointer_scroll_flex(node: &Node, _calling_client: Arc, data: &[u8]) -> Result<()> { + #[derive(Deserialize)] + struct PointerScrollArgs { + axis_continuous: Vector2, + axis_discrete: Option>, + } + let args: PointerScrollArgs = deserialize(data)?; if let ItemType::Panel(panel_item) = &node.item.get().unwrap().specialization { if let Some(pointer) = panel_item.seat_data.pointer() { if *panel_item.seat_data.pointer_active.lock() { @@ -327,12 +317,9 @@ impl PanelItem { pointer.axis_stop(0, Axis::HorizontalScroll); pointer.axis_stop(0, Axis::VerticalScroll); } else { - let flex_vec = flex.get_vector()?; - let axis_continuous_vec = parse_vec2(flex_vec.idx(0)) - .ok_or_else(|| anyhow!("No continuous axis vector!"))?; - pointer.axis(0, Axis::HorizontalScroll, axis_continuous_vec.x as f64); - pointer.axis(0, Axis::VerticalScroll, axis_continuous_vec.y as f64); - if let Some(axis_discrete_vec) = parse_vec2(flex_vec.idx(0)) { + pointer.axis(0, Axis::HorizontalScroll, args.axis_continuous.x as f64); + pointer.axis(0, Axis::VerticalScroll, args.axis_continuous.y as f64); + if let Some(axis_discrete_vec) = args.axis_discrete { pointer.axis_discrete( Axis::HorizontalScroll, axis_discrete_vec.x as i32, @@ -494,41 +481,22 @@ impl PanelItem { } } impl ItemSpecialization for PanelItem { - fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) { + fn serialize_start_data(&self, id: &str) -> Vec { // Panel size - { - let mut size_vec = vec.start_vector(); - self.core_surface.upgrade().unwrap().with_data(|data| { - size_vec.push(data.size.x); - size_vec.push(data.size.y); - }); - } + let panel_size = self + .core_surface + .upgrade() + .unwrap() + .with_data(|data| data.size); - // Cursor size and hotspot - if let Some(cursor) = &*self.seat_data.cursor.lock() { - let cursor = cursor.lock(); - if let Some(cursor_core_surface) = cursor.core_surface.upgrade() { - if let Some(mapped_data) = &*cursor_core_surface.mapped_data.lock() { - let mut cursor_vec = vec.start_vector(); - { - let mut cursor_size_vec = cursor_vec.start_vector(); - cursor_size_vec.push(mapped_data.size.x); - cursor_size_vec.push(mapped_data.size.y); - } - { - let mut cursor_hotspot_vec = cursor_vec.start_vector(); - cursor_hotspot_vec.push(cursor.hotspot.x); - cursor_hotspot_vec.push(cursor.hotspot.y); - } - } else { - vec.push(()); - } - } else { - vec.push(()); - } - } else { - vec.push(()); - } + let cursor_lock = (*self.seat_data.cursor.lock()).clone(); + let cursor_size = cursor_lock + .clone() + .and_then(|cursor| cursor.lock().core_surface.upgrade()) + .and_then(|surf| surf.with_data(|data| data.size)); + let cursor_hotspot = cursor_lock.map(|cursor| cursor.lock().hotspot); + + serialize((id, (panel_size, cursor_size, cursor_hotspot))).unwrap() } }