refactor: make all flex stuff use serde

This commit is contained in:
Nova
2022-10-13 00:14:06 -04:00
parent 9d9d51ddeb
commit a421b27e0c
22 changed files with 460 additions and 431 deletions

View File

@@ -32,16 +32,17 @@ prisma = "0.1.1"
slog = "2.7.0" slog = "2.7.0"
slog-stdlog = "4.1.1" slog-stdlog = "4.1.1"
xkbcommon = { version = "0.5.0", default-features = false } xkbcommon = { version = "0.5.0", default-features = false }
stardust-xr = "0.4.0" stardust-xr = "0.4.1"
stardust-xr-schemas = "1.0.0"
wayland-backend = "=0.1.0-beta.9" wayland-backend = "=0.1.0-beta.9"
wayland-scanner = "=0.30.0-beta.9" wayland-scanner = "=0.30.0-beta.9"
directories = "4.0.1" directories = "4.0.1"
serde = { version = "1.0.145", features = ["derive"] }
[dependencies.stereokit] [dependencies.stereokit]
path = "../stereokit-rs"
default-features = false default-features = false
features = ["linux-egl"] features = ["linux-egl"]
version = "0.4.0" version = "0.4.1"
[dependencies.smithay] [dependencies.smithay]
git = "https://github.com/technobaboo/smithay.git" git = "https://github.com/technobaboo/smithay.git"

View File

@@ -1,4 +1,5 @@
use anyhow::bail; use anyhow::anyhow;
use serde::{de::Visitor, Deserialize};
use std::path::PathBuf; use std::path::PathBuf;
pub enum ResourceID { pub enum ResourceID {
@@ -24,20 +25,47 @@ impl ResourceID {
} }
} }
} }
impl<'de> Deserialize<'de> for ResourceID {
pub fn parse_resource_id(reader: flexbuffers::Reader<&[u8]>) -> anyhow::Result<ResourceID> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
let string = reader.get_str()?; where
D: serde::Deserializer<'de>,
Ok(if string.starts_with('/') { {
let path = PathBuf::from(string); deserializer.deserialize_any(ResourceVisitor)
path.metadata()?; }
ResourceID::File(path) }
} else if let Some((namespace, path)) = string.split_once(':') {
ResourceID::Namespaced { struct ResourceVisitor;
namespace: namespace.to_string(), impl<'de> Visitor<'de> for ResourceVisitor {
path: PathBuf::from(path), type Value = ResourceID;
}
} else { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
bail!("Invalid format for string"); formatter.write_str("A string containing an absolute path to file or \"[namespace]:[path]\" for a namespaced resource")
}) }
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
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<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v)
}
} }

View File

@@ -17,6 +17,7 @@ use directories::ProjectDirs;
use slog::Drain; use slog::Drain;
use std::sync::Arc; use std::sync::Arc;
use stereokit::input::Handed; use stereokit::input::Handed;
use stereokit::lifecycle::DepthMode;
use stereokit::render::SphericalHarmonics; use stereokit::render::SphericalHarmonics;
use stereokit::texture::Texture; use stereokit::texture::Texture;
use stereokit::{lifecycle::DisplayMode, Settings}; use stereokit::{lifecycle::DisplayMode, Settings};
@@ -50,6 +51,7 @@ fn main() -> Result<()> {
} else { } else {
DisplayMode::MixedReality DisplayMode::MixedReality
}) })
.depth_mode(DepthMode::D32)
.init() .init()
.expect("StereoKit failed to initialize"); .expect("StereoKit failed to initialize");
println!("Init StereoKit"); println!("Init StereoKit");

View File

@@ -7,7 +7,10 @@ use crate::core::registry::Registry;
use anyhow::{anyhow, ensure, Result}; use anyhow::{anyhow, ensure, Result};
use glam::vec3a; use glam::vec3a;
use parking_lot::Mutex; 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}; use std::sync::{Arc, Weak};
static PULSE_SENDER_REGISTRY: Registry<PulseSender> = Registry::new(); static PULSE_SENDER_REGISTRY: Registry<PulseSender> = Registry::new();
@@ -120,10 +123,10 @@ impl PulseSender {
}) })
.collect(); .collect();
distance_sorted_receivers.sort_by(|(d1, _), (d2, _)| d1.partial_cmp(d2).unwrap()); distance_sorted_receivers.sort_by(|(d1, _), (d2, _)| d1.partial_cmp(d2).unwrap());
sender.aliases.clear();
Ok(flexbuffer_from_vector_arguments(move |fbb| { let uids: Vec<String> = distance_sorted_receivers
sender.aliases.clear(); .into_iter()
for (_, receiver) in distance_sorted_receivers.iter() { .map(|(_, receiver)| {
let receiver_alias = Node::create( let receiver_alias = Node::create(
&calling_client, &calling_client,
node.get_path(), node.get_path(),
@@ -140,9 +143,12 @@ impl PulseSender {
vec![], vec![],
); );
sender.aliases.add(Arc::downgrade(&receiver_alias)); 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 { impl Drop for PulseSender {
@@ -239,16 +245,16 @@ pub fn create_pulse_sender_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let root = flexbuffers::Reader::get_root(data)?; #[derive(Deserialize)]
let flex_vec = root.get_vector()?; struct CreatePulseSenderInfo<'a> {
let node = Node::create( name: &'a str,
&calling_client, parent_path: &'a str,
"/data/sender", transform: Transform,
flex_vec.idx(0).get_str()?, }
true, let info: CreatePulseSenderInfo = deserialize(data)?;
); let node = Node::create(&calling_client, "/data/sender", info.name, true);
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; let transform = parse_transform(info.transform, true, true, false)?;
let node = node.add_to_scenegraph(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
PulseSender::add_to(&node)?; PulseSender::add_to(&node)?;
@@ -270,19 +276,20 @@ pub fn create_pulse_receiver_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let root = flexbuffers::Reader::get_root(data)?; #[derive(Deserialize)]
let flex_vec = root.get_vector()?; struct CreatePulseReceiverInfo<'a> {
let node = Node::create( name: &'a str,
&calling_client, parent_path: &'a str,
"/data/receiver", transform: Transform,
flex_vec.idx(0).get_str()?, field_path: &'a str,
true, }
); let info: CreatePulseReceiverInfo = deserialize(data)?;
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; let node = Node::create(&calling_client, "/data/sender", info.name, true);
let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client let field = calling_client
.scenegraph .scenegraph
.get_node(flex_vec.idx(4).as_str()) .get_node(info.field_path)
.ok_or_else(|| anyhow!("Field not found"))? .ok_or_else(|| anyhow!("Field not found"))?
.field .field
.get() .get()

View File

@@ -2,7 +2,7 @@ use super::Node;
use crate::core::client::Client; use crate::core::client::Client;
use crate::core::destroy_queue; use crate::core::destroy_queue;
use crate::core::registry::Registry; 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 crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use anyhow::{anyhow, bail, ensure, Result}; use anyhow::{anyhow, bail, ensure, Result};
use flexbuffers::FlexBufferType; use flexbuffers::FlexBufferType;
@@ -11,6 +11,9 @@ use parking_lot::Mutex;
use prisma::{Rgb, Rgba}; use prisma::{Rgb, Rgba};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use send_wrapper::SendWrapper; use send_wrapper::SendWrapper;
use serde::Deserialize;
use stardust_xr::schemas::flex::deserialize;
use stardust_xr::values::Transform;
use std::fmt::Error; use std::fmt::Error;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc; 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<Client>, data: &[u8]) -> Result<()> { pub fn create_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create( struct CreateModelInfo<'a> {
&calling_client, name: &'a str,
"/drawable/model", parent_path: &'a str,
flex_vec.idx(0).get_str()?, transform: Transform,
true, resource: ResourceID,
); }
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; let info: CreateModelInfo = deserialize(data)?;
let transform = parse_transform(flex_vec.index(2)?, true, true, true)?; let node = Node::create(&calling_client, "/drawable/model", info.name, true);
let resource_id = parse_resource_id(flex_vec.idx(3))?; 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(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
Model::add_to(&node, resource_id)?; Model::add_to(&node, info.resource)?;
Ok(()) Ok(())
} }

View File

@@ -1,23 +1,20 @@
use crate::{ use crate::{
core::{ core::{client::Client, destroy_queue, registry::Registry, resource::ResourceID},
client::Client,
destroy_queue,
registry::Registry,
resource::{parse_resource_id, ResourceID},
},
nodes::{ nodes::{
spatial::{get_spatial_parent_flex, parse_transform, Spatial}, spatial::{get_spatial_parent_flex, parse_transform, Spatial},
Node, Node,
}, },
}; };
use anyhow::{anyhow, ensure, Result}; use anyhow::{ensure, Result};
use glam::{vec3, Mat4, Vec2}; use glam::{vec3, Mat4, Vec2};
use mint::Vector2;
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use parking_lot::Mutex; use parking_lot::Mutex;
use prisma::{FromTuple, Rgb, Rgba}; use prisma::{Flatten, Rgb, Rgba};
use send_wrapper::SendWrapper; use send_wrapper::SendWrapper;
use stardust_xr::values::{parse_f32, parse_vec2}; use serde::Deserialize;
use std::{convert::TryFrom, path::PathBuf, sync::Arc}; use stardust_xr::{schemas::flex::deserialize, values::Transform};
use std::{path::PathBuf, sync::Arc};
use stereokit::{ use stereokit::{
font::Font, font::Font,
lifecycle::DrawContext, lifecycle::DrawContext,
@@ -52,7 +49,7 @@ impl Text {
text: String, text: String,
character_height: f32, character_height: f32,
text_align: TextAlign, text_align: TextAlign,
bounds: Option<Vec2>, bounds: Option<Vector2<f32>>,
fit: TextFit, fit: TextFit,
bounds_align: TextAlign, bounds_align: TextAlign,
color: Rgba<f32>, color: Rgba<f32>,
@@ -77,7 +74,7 @@ impl Text {
text, text,
character_height, character_height,
text_align, text_align,
bounds, bounds: bounds.map(|b| b.into()),
fit, fit,
bounds_align, bounds_align,
color, color,
@@ -175,45 +172,37 @@ pub fn draw_all(sk: &StereoKit, draw_ctx: &DrawContext) {
} }
pub fn create_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn create_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create( struct CreateTextInfo<'a> {
&calling_client, name: &'a str,
"/drawable/text", parent_path: &'a str,
flex_vec.idx(0).get_str()?, transform: Transform,
true, text: String,
); font_resource: Option<ResourceID>,
let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; character_height: f32,
let transform = parse_transform(flex_vec.index(2)?, true, true, true)?; text_align: TextAlign,
let text = flex_vec.index(3)?.get_str()?.to_string(); bounds: Option<Vector2<f32>>,
let font_resource_id = parse_resource_id(flex_vec.index(4)?).ok(); fit: TextFit,
let character_height = flex_vec.index(5)?.get_f64()? as f32; bounds_align: TextAlign,
let text_align = TextAlign::from_bits(flex_vec.index(6)?.get_u64()? as u32) color: [f32; 4],
.ok_or_else(|| anyhow!("Text align bitflag out of range"))?; }
let bounds = parse_vec2(flex_vec.index(7)?).map(|bounds| bounds.into()); let info: CreateTextInfo = deserialize(data)?;
let fit = TextFit::try_from(flex_vec.index(8)?.get_u64()? as u32)?; let node = Node::create(&calling_client, "/drawable/text", info.name, true);
let bounds_align = TextAlign::from_bits(flex_vec.index(9)?.get_u64()? as u32) let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
.ok_or_else(|| anyhow!("Bounds align bitflag out of range"))?; let transform = parse_transform(info.transform, true, true, true)?;
let color_vec = flex_vec.index(10)?.get_vector()?; let color = Rgba::from_slice(&info.color);
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"))?,
));
let node = node.add_to_scenegraph(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
Text::add_to( Text::add_to(
&node, &node,
font_resource_id, info.font_resource,
text, info.text,
character_height, info.character_height,
text_align, info.text_align,
bounds, info.bounds,
fit, info.fit,
bounds_align, info.bounds_align,
color, color,
)?; )?;
Ok(()) Ok(())

View File

@@ -1,10 +1,13 @@
use super::{Field, FieldTrait, Node}; use super::{Field, FieldTrait, Node};
use crate::core::client::Client; use crate::core::client::Client;
use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial}; 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 glam::{vec3, vec3a, Vec3, Vec3A};
use mint::Vector3;
use parking_lot::Mutex; 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; use std::sync::Arc;
pub struct BoxField { pub struct BoxField {
@@ -13,7 +16,7 @@ pub struct BoxField {
} }
impl BoxField { impl BoxField {
pub fn add_to(node: &Arc<Node>, size: Vec3) -> Result<()> { pub fn add_to(node: &Arc<Node>, size: Vector3<f32>) -> Result<()> {
ensure!( ensure!(
node.spatial.get().is_some(), node.spatial.get().is_some(),
"Internal: Node does not have a spatial attached!" "Internal: Node does not have a spatial attached!"
@@ -24,7 +27,7 @@ impl BoxField {
); );
let box_field = BoxField { let box_field = BoxField {
space: node.spatial.get().unwrap().clone(), space: node.spatial.get().unwrap().clone(),
size: Mutex::new(size), size: Mutex::new(size.into()),
}; };
box_field.add_field_methods(node); box_field.add_field_methods(node);
node.add_local_signal("setSize", BoxField::set_size_flex); node.add_local_signal("setSize", BoxField::set_size_flex);
@@ -32,15 +35,13 @@ impl BoxField {
Ok(()) Ok(())
} }
pub fn set_size(&self, size: Vec3) { pub fn set_size(&self, size: Vector3<f32>) {
*self.size.lock() = size; *self.size.lock() = size.into();
} }
pub fn set_size_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn set_size_flex(node: &Node, _calling_client: Arc<Client>, 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() { 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(()) Ok(())
} }
@@ -63,18 +64,19 @@ impl FieldTrait for BoxField {
} }
pub fn create_box_field_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn create_box_field_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create( struct CreateFieldInfo<'a> {
&calling_client, name: &'a str,
"/field", parent_path: &'a str,
flex_vec.index(0)?.get_str()?, transform: Transform,
true, size: Vector3<f32>,
); }
let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; let info: CreateFieldInfo = deserialize(data)?;
let transform = parse_transform(flex_vec.index(2)?, true, true, false)?; let node = Node::create(&calling_client, "/field", info.name, true);
let size = parse_vec3(flex_vec.index(3)?).ok_or_else(|| anyhow!("Size invalid"))?; 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(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
BoxField::add_to(&node, size.into())?; BoxField::add_to(&node, info.size)?;
Ok(()) Ok(())
} }

View File

@@ -4,7 +4,9 @@ use crate::nodes::spatial::{get_spatial_parent_flex, parse_transform, Spatial};
use anyhow::{ensure, Result}; use anyhow::{ensure, Result};
use glam::{swizzles::*, vec2, Vec3A}; use glam::{swizzles::*, vec2, Vec3A};
use portable_atomic::AtomicF32; 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::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
@@ -42,12 +44,8 @@ impl CylinderField {
} }
pub fn set_size_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn set_size_flex(node: &Node, _calling_client: Arc<Client>, 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() { if let Field::Cylinder(cylinder_field) = node.field.get().unwrap().as_ref() {
let (length, radius) = deserialize(data)?;
cylinder_field.set_size(length, radius); cylinder_field.set_size(length, radius);
} }
Ok(()) Ok(())
@@ -72,19 +70,20 @@ pub fn create_cylinder_field_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create( struct CreateFieldInfo<'a> {
&calling_client, name: &'a str,
"/field", parent_path: &'a str,
flex_vec.index(0)?.get_str()?, transform: Transform,
true, length: f32,
); radius: f32,
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 info: CreateFieldInfo = deserialize(data)?;
let length = parse_f32(flex_vec.index(3)?).ok_or_else(|| anyhow::anyhow!("Invalid length"))?; let node = Node::create(&calling_client, "/field", info.name, true);
let radius = parse_f32(flex_vec.index(4)?).ok_or_else(|| anyhow::anyhow!("Invalid radius"))?; 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(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; 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(()) Ok(())
} }

View File

@@ -11,8 +11,9 @@ use super::Node;
use crate::core::client::Client; use crate::core::client::Client;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use glam::{vec2, vec3a, Vec3, Vec3A}; use glam::{vec2, vec3a, Vec3, Vec3A};
use stardust_xr::flex::FlexBuffable; use mint::Vector3;
use stardust_xr::values::parse_vec3; use serde::Deserialize;
use stardust_xr::schemas::flex::{deserialize, serialize};
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
@@ -69,65 +70,79 @@ pub trait FieldTrait {
} }
fn field_distance_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<Vec<u8>> { fn field_distance_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<Vec<u8>> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
struct FieldInfoArgs<'a> {
reference_space_path: &'a str,
point: Vector3<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client let reference_space = calling_client
.scenegraph .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"))? .ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial .spatial
.get() .get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone(); .clone();
let point = parse_vec3(flex_vec.idx(1)).ok_or_else(|| anyhow!("Point is invalid"))?;
let distance = node let distance = node
.field .field
.get() .get()
.unwrap() .unwrap()
.distance(reference_space.as_ref(), point.into()); .distance(reference_space.as_ref(), args.point.into());
Ok(FlexBuffable::from(distance).build_singleton()) Ok(serialize(distance)?)
} }
fn field_normal_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<Vec<u8>> { fn field_normal_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<Vec<u8>> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
struct FieldInfoArgs<'a> {
reference_space_path: &'a str,
point: Vector3<f32>,
radius: Option<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client let reference_space = calling_client
.scenegraph .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"))? .ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial .spatial
.get() .get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone(); .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( let normal = node.field.get().as_ref().unwrap().normal(
reference_space.as_ref(), reference_space.as_ref(),
point.into(), args.point.into(),
0.001_f32, 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( fn field_closest_point_flex(
node: &Node, node: &Node,
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<Vec<u8>> { ) -> Result<Vec<u8>> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
struct FieldInfoArgs<'a> {
reference_space_path: &'a str,
point: Vector3<f32>,
radius: Option<f32>,
}
let args: FieldInfoArgs = deserialize(data)?;
let reference_space = calling_client let reference_space = calling_client
.scenegraph .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"))? .ok_or_else(|| anyhow!("Reference space node does not exist"))?
.spatial .spatial
.get() .get()
.ok_or_else(|| anyhow!("Reference space node does not have a spatial"))? .ok_or_else(|| anyhow!("Reference space node does not have a spatial"))?
.clone(); .clone();
let point = parse_vec3(flex_vec.idx(1)).ok_or_else(|| anyhow!("Point is invalid"))?;
let closest_point = let closest_point = node.field.get().as_ref().unwrap().closest_point(
node.field reference_space.as_ref(),
.get() args.point.into(),
.unwrap() args.radius.unwrap_or(0.001),
.closest_point(reference_space.as_ref(), point.into(), 0.001_f32); );
Ok(FlexBuffable::from(mint::Vector3::from(closest_point)).build_singleton()) Ok(serialize(mint::Vector3::from(closest_point))?)
} }
pub enum Field { pub enum Field {

View File

@@ -1,10 +1,12 @@
use super::{Field, FieldTrait, Node}; use super::{Field, FieldTrait, Node};
use crate::core::client::Client; use crate::core::client::Client;
use crate::nodes::spatial::{get_spatial_parent_flex, Spatial}; use crate::nodes::spatial::{get_spatial_parent_flex, Spatial};
use anyhow::{anyhow, ensure, Result}; use anyhow::{ensure, Result};
use glam::{Mat4, Vec3A}; use glam::{Mat4, Vec3A};
use mint::Vector3;
use portable_atomic::AtomicF32; 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::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
@@ -66,16 +68,19 @@ pub fn create_sphere_field_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create(&calling_client, "/field", flex_vec.idx(0).get_str()?, true); struct CreateFieldInfo<'a> {
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; name: &'a str,
let transform = Mat4::from_translation( parent_path: &'a str,
parse_vec3(flex_vec.idx(2)) origin: Option<Vector3<f32>>,
.ok_or_else(|| anyhow!("Position not found"))? radius: f32,
.into(), }
); 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(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
SphereField::add_to(&node, flex_vec.idx(3).as_f32())?; SphereField::add_to(&node, info.radius)?;
Ok(()) Ok(())
} }

View File

@@ -1,8 +1,7 @@
use crate::nodes::fields::Field; use crate::nodes::fields::Field;
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3a, Mat4}; use glam::{vec3a, Mat4};
use stardust_xr_schemas::input_hand::HandT; use stardust_xr::schemas::{common::JointT, input::InputDataRaw, input_hand::HandT};
use stardust_xr_schemas::{common::JointT, input::InputDataRaw};
use std::sync::Arc; use std::sync::Arc;
use super::{DistanceLink, InputSpecialization}; use super::{DistanceLink, InputSpecialization};

View File

@@ -16,7 +16,10 @@ use anyhow::{anyhow, ensure, Result};
use glam::Mat4; use glam::Mat4;
use nanoid::nanoid; use nanoid::nanoid;
use parking_lot::Mutex; 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::ops::Deref;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
@@ -213,19 +216,20 @@ pub fn create_input_handler_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let root = flexbuffers::Reader::get_root(data)?; #[derive(Deserialize)]
let flex_vec = root.get_vector()?; struct CreateInputHandlerInfo<'a> {
let node = Node::create( name: &'a str,
&calling_client, parent_path: &'a str,
"/input/handler", transform: Transform,
flex_vec.idx(0).get_str()?, field_path: &'a str,
true, }
); let info: CreateInputHandlerInfo = deserialize(data)?;
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?; let node = Node::create(&calling_client, "/input/handler", info.name, true);
let transform = parse_transform(flex_vec.idx(2), true, true, false)?; let parent = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client let field = calling_client
.scenegraph .scenegraph
.get_node(flex_vec.idx(3).as_str()) .get_node(info.field_path)
.ok_or_else(|| anyhow!("Field not found"))? .ok_or_else(|| anyhow!("Field not found"))?
.field .field
.get() .get()

View File

@@ -2,8 +2,7 @@ use super::{DistanceLink, InputSpecialization};
use crate::nodes::fields::{ray_march, Field, Ray, RayMarchResult}; use crate::nodes::fields::{ray_march, Field, Ray, RayMarchResult};
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3, Mat4}; use glam::{vec3, Mat4};
use stardust_xr_schemas::input::InputDataRaw; use stardust_xr::schemas::{input::InputDataRaw, input_pointer};
use stardust_xr_schemas::input_pointer;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;

View File

@@ -3,8 +3,7 @@ use crate::nodes::fields::Field;
use crate::nodes::spatial::Spatial; use crate::nodes::spatial::Spatial;
use glam::{vec3a, Mat4}; use glam::{vec3a, Mat4};
use portable_atomic::AtomicF32; use portable_atomic::AtomicF32;
use stardust_xr_schemas::input::InputDataRaw; use stardust_xr::schemas::{input::InputDataRaw, input_tip};
use stardust_xr_schemas::input_tip;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;

View File

@@ -1,6 +1,17 @@
use super::{Item, ItemSpecialization, ItemType, ITEM_TYPE_INFO_ENVIRONMENT}; 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 anyhow::{anyhow, Result};
use serde::Deserialize;
use stardust_xr::{
schemas::flex::{deserialize, serialize},
values::Transform,
};
use std::sync::Arc; use std::sync::Arc;
pub struct EnvironmentItem { pub struct EnvironmentItem {
@@ -25,7 +36,50 @@ impl EnvironmentItem {
} }
} }
impl ItemSpecialization for EnvironmentItem { impl ItemSpecialization for EnvironmentItem {
fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) { fn serialize_start_data(&self, id: &str) -> Vec<u8> {
vec.push(self.path.as_str()); serialize((id, self.path.as_str())).unwrap()
} }
} }
pub(super) fn create_environment_item_flex(
_node: &Node,
calling_client: Arc<Client>,
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<Client>,
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<Client>,
_data: &[u8],
) -> Result<()> {
super::register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_ENVIRONMENT)
}

View File

@@ -13,7 +13,10 @@ use anyhow::{anyhow, ensure, Result};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use nanoid::nanoid; use nanoid::nanoid;
use parking_lot::Mutex; 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::ops::Deref;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
@@ -155,7 +158,7 @@ impl Drop for Item {
} }
pub trait ItemSpecialization { pub trait ItemSpecialization {
fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder); fn serialize_start_data(&self, id: &str) -> Vec<u8>;
} }
pub enum ItemType { pub enum ItemType {
@@ -214,12 +217,7 @@ impl ItemUI {
let _ = node.send_remote_signal( let _ = node.send_remote_signal(
"create", "create",
&flexbuffer_from_vector_arguments(|vec| { &item.specialization.serialize_start_data(&item.uid),
vec.push(item.uid.as_str());
let mut start_data_vec = vec.start_vector();
item.specialization
.serialize_start_data(&mut start_data_vec);
}),
); );
} }
fn handle_destroy_item(&self, item: &Item) { fn handle_destroy_item(&self, item: &Item) {
@@ -324,72 +322,49 @@ impl Drop for ItemAcceptor {
pub fn create_interface(client: &Arc<Client>) { pub fn create_interface(client: &Arc<Client>) {
let node = Node::create(client, "", "item", false); 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( node.add_local_signal(
"registerEnvironmentItemUI", "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("registerPanelItemUI", register_panel_item_ui_flex);
node.add_local_signal( node.add_local_signal(
"createEnvironmentItemAcceptor", "createEnvironmentItemAcceptor",
create_environment_item_acceptor_flex, environment::create_environment_item_acceptor_flex,
); );
node.add_to_scenegraph(); node.add_to_scenegraph();
} }
pub fn create_environment_item_flex( pub(self) fn create_item_acceptor_flex(
_node: &Node,
calling_client: Arc<Client>,
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(
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
type_info: &'static TypeInfo, type_info: &'static TypeInfo,
) -> Result<()> { ) -> Result<()> {
let root = flexbuffers::Reader::get_root(data)?; #[derive(Deserialize)]
let flex_vec = root.get_vector()?; 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 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 space = get_spatial_parent_flex(&calling_client, info.parent_path)?;
let transform = parse_transform(flex_vec.idx(2), true, true, false)?; let transform = parse_transform(info.transform, true, true, false)?;
let field = calling_client let field = calling_client
.scenegraph .scenegraph
.get_node(flex_vec.idx(3).get_str()?) .get_node(info.field_path)
.ok_or_else(|| anyhow!("Field node not found"))?; .ok_or_else(|| anyhow!("Field node not found"))?;
let field = field let field = field
.field .field
.get() .get()
.ok_or_else(|| anyhow!("Field node is not a field"))?; .ok_or_else(|| anyhow!("Field node is not a field"))?;
let node = Node::create( let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, true).add_to_scenegraph();
&INTERNAL_CLIENT, Spatial::add_to(&node, Some(space), transform)?;
&parent_name,
flex_vec.idx(0).get_str()?,
true,
)
.add_to_scenegraph();
Spatial::add_to(&node, None, transform * space.global_transform())?;
ItemAcceptor::add_to(&node, type_info, Arc::downgrade(field)); ItemAcceptor::add_to(&node, type_info, Arc::downgrade(field));
node.item node.item
.get() .get()
@@ -398,14 +373,6 @@ pub fn create_item_acceptor_flex(
Ok(()) Ok(())
} }
pub fn create_environment_item_acceptor_flex(
_node: &Node,
calling_client: Arc<Client>,
data: &[u8],
) -> Result<()> {
create_item_acceptor_flex(calling_client, data, &ITEM_TYPE_INFO_ENVIRONMENT)
}
pub fn register_item_ui_flex( pub fn register_item_ui_flex(
calling_client: Arc<Client>, calling_client: Arc<Client>,
type_info: &'static TypeInfo, type_info: &'static TypeInfo,
@@ -414,11 +381,3 @@ pub fn register_item_ui_flex(
ItemUI::add_to(&ui, type_info)?; ItemUI::add_to(&ui, type_info)?;
Ok(()) Ok(())
} }
pub fn register_environment_item_ui_flex(
_node: &Node,
calling_client: Arc<Client>,
_data: &[u8],
) -> Result<()> {
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_ENVIRONMENT)
}

View File

@@ -5,8 +5,8 @@ use crate::core::client::Client;
use crate::core::registry::Registry; use crate::core::registry::Registry;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use glam::Mat4; use glam::Mat4;
use stardust_xr::flex::flexbuffer_from_vector_arguments; use stardust_xr::schemas::flex::{deserialize, serialize};
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@@ -59,25 +59,17 @@ impl Root {
} }
pub fn logic_step(delta: f64) { pub fn logic_step(delta: f64) {
let data = flexbuffer_from_vector_arguments(move |fbb| { if let Ok(data) = serialize((delta, 0.0)) {
fbb.push(delta); for root in ROOT_REGISTRY.get_valid_contents() {
fbb.push(0_f64); if root.logic_step.load(Ordering::Relaxed) {
}); let _ = root.node.send_remote_signal("logicStep", &data);
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<Client>, data: &[u8]) -> Result<()> { fn set_base_prefixes(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; *calling_client.base_resource_prefixes.lock() = deserialize(data)?;
*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();
Ok(()) Ok(())
} }
} }

View File

@@ -1,12 +1,13 @@
use super::Node; use super::Node;
use crate::core::client::Client; use crate::core::client::Client;
use anyhow::{anyhow, ensure, Result}; use anyhow::{anyhow, ensure, Result};
use glam::{Mat4, Quat, Vec3}; use glam::{Mat4, Quat};
use mint::Vector3; use mint::Vector3;
use parking_lot::Mutex; use parking_lot::Mutex;
use stardust_xr::flex::flexbuffer_from_vector_arguments;
use stardust_xr::push_to_vec; use serde::Deserialize;
use stardust_xr::values::{parse_quat, parse_vec3}; use stardust_xr::schemas::flex::{deserialize, serialize};
use stardust_xr::values::Transform;
use std::ptr; use std::ptr;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
@@ -71,9 +72,7 @@ impl Spatial {
pub fn set_local_transform_components( pub fn set_local_transform_components(
&self, &self,
reference_space: Option<&Spatial>, reference_space: Option<&Spatial>,
pos: Option<Vec3>, transform: Transform,
rot: Option<Quat>,
scl: Option<Vec3>,
) { ) {
let reference_to_parent_transform = reference_space let reference_to_parent_transform = reference_space
.map(|reference_space| { .map(|reference_space| {
@@ -85,16 +84,16 @@ impl Spatial {
let (mut reference_space_scl, mut reference_space_rot, mut reference_space_pos) = let (mut reference_space_scl, mut reference_space_rot, mut reference_space_pos) =
local_transform_in_reference_space.to_scale_rotation_translation(); local_transform_in_reference_space.to_scale_rotation_translation();
if let Some(pos) = pos { if let Some(pos) = transform.position {
reference_space_pos = pos reference_space_pos = pos.into()
} }
if let Some(rot) = rot { if let Some(rot) = transform.rotation {
reference_space_rot = rot reference_space_rot = rot.into()
} else if reference_space_rot.is_nan() { } else if reference_space_rot.is_nan() {
reference_space_rot = Quat::IDENTITY; reference_space_rot = Quat::IDENTITY;
} }
if let Some(scl) = scl { if let Some(scl) = transform.scale {
reference_space_scl = scl reference_space_scl = scl.into()
} }
local_transform_in_reference_space = Mat4::from_scale_rotation_translation( local_transform_in_reference_space = Mat4::from_scale_rotation_translation(
@@ -158,14 +157,13 @@ impl Spatial {
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<Vec<u8>> { ) -> Result<Vec<u8>> {
let root = flexbuffers::Reader::get_root(data)?;
let this_spatial = node let this_spatial = node
.spatial .spatial
.get() .get()
.ok_or_else(|| anyhow!("Node doesn't have a spatial?"))?; .ok_or_else(|| anyhow!("Node doesn't have a spatial?"))?;
let relative_spatial = calling_client let relative_spatial = calling_client
.scenegraph .scenegraph
.get_node(root.as_str()) .get_node(deserialize(data)?)
.ok_or_else(|| anyhow!("Space not found"))? .ok_or_else(|| anyhow!("Space not found"))?
.spatial .spatial
.get() .get()
@@ -178,37 +176,37 @@ impl Spatial {
) )
.to_scale_rotation_translation(); .to_scale_rotation_translation();
Ok(flexbuffer_from_vector_arguments(|vec| { serialize((
push_to_vec!( mint::Vector3::from(position),
vec, mint::Quaternion::from(rotation),
mint::Vector3::from(position), mint::Vector3::from(scale),
mint::Quaternion::from(rotation), ))
mint::Vector3::from(scale) .map_err(|e| e.into())
);
}))
} }
pub fn set_transform_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn set_transform_flex(node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let reference_space_path = flex_vec.idx(0).as_str(); struct TransformArgs<'a> {
let reference_space_transform = if reference_space_path.is_empty() { reference_space_path: Option<&'a str>,
None transform: Transform,
} else { }
Some( let transform_args: TransformArgs = deserialize(data)?;
calling_client let reference_space_transform = transform_args
.reference_space_path
.map(|path| -> Result<Arc<Spatial>> {
Ok(calling_client
.scenegraph .scenegraph
.get_node(reference_space_path) .get_node(path)
.ok_or_else(|| anyhow!("Other spatial node not found"))? .ok_or_else(|| anyhow!("Other spatial node not found"))?
.spatial .spatial
.get() .get()
.ok_or_else(|| anyhow!("Node is not a Spatial!"))? .ok_or_else(|| anyhow!("Node is not a Spatial!"))?
.clone(), .clone())
) })
}; .transpose()?;
node.spatial.get().unwrap().set_local_transform_components( node.spatial.get().unwrap().set_local_transform_components(
reference_space_transform.as_deref(), reference_space_transform.as_deref(),
parse_vec3(flex_vec.idx(1)).map(|v| v.into()), transform_args.transform,
parse_quat(flex_vec.idx(2)).map(|v| v.into()),
parse_vec3(flex_vec.idx(3)).map(|v| v.into()),
); );
Ok(()) Ok(())
} }
@@ -217,10 +215,9 @@ impl Spatial {
calling_client: Arc<Client>, calling_client: Arc<Client>,
data: &[u8], data: &[u8],
) -> Result<()> { ) -> Result<()> {
let parent_path = flexbuffers::Reader::get_root(data)?.get_str()?;
let parent = calling_client let parent = calling_client
.scenegraph .scenegraph
.get_node(parent_path) .get_node(deserialize(data)?)
.ok_or_else(|| anyhow!("Parent node not found"))? .ok_or_else(|| anyhow!("Parent node not found"))?
.spatial .spatial
.get() .get()
@@ -254,6 +251,32 @@ impl Spatial {
} }
} }
pub fn parse_transform(
transform: Transform,
translation: bool,
rotation: bool,
scale: bool,
) -> Result<Mat4> {
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( pub fn get_spatial_parent_flex(
calling_client: &Arc<Client>, calling_client: &Arc<Client>,
node_path: &str, node_path: &str,
@@ -267,32 +290,6 @@ pub fn get_spatial_parent_flex(
.ok_or_else(|| anyhow!("Spatial parent node is not a spatial"))? .ok_or_else(|| anyhow!("Spatial parent node is not a spatial"))?
.clone()) .clone())
} }
pub fn parse_transform<B: flexbuffers::Buffer>(
reader: flexbuffers::Reader<B>,
translation: bool,
rotation: bool,
scale: bool,
) -> Result<Mat4> {
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<Client>) { pub fn create_interface(client: &Arc<Client>) {
let node = Node::create(client, "", "spatial", false); let node = Node::create(client, "", "spatial", false);
@@ -301,15 +298,16 @@ pub fn create_interface(client: &Arc<Client>) {
} }
pub fn create_spatial_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> { pub fn create_spatial_flex(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?; #[derive(Deserialize)]
let node = Node::create( struct CreateSpatialInfo<'a> {
&calling_client, name: &'a str,
"/spatial/spatial", parent_path: &'a str,
flex_vec.idx(0).get_str()?, transform: Transform,
true, }
); let info: CreateSpatialInfo = deserialize(data)?;
let parent = get_spatial_parent_flex(&calling_client, flex_vec.index(1)?.get_str()?)?; let node = Node::create(&calling_client, "/spatial/spatial", info.name, true);
let transform = parse_transform(flex_vec.index(2)?, true, true, 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(); let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?; Spatial::add_to(&node, Some(parent), transform)?;
Ok(()) Ok(())

View File

@@ -3,6 +3,7 @@ use crate::nodes::{
spatial::Spatial, spatial::Spatial,
}; };
use glam::{vec3, Mat4}; use glam::{vec3, Mat4};
use stardust_xr::values::Transform;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use stereokit::{input::Ray, StereoKit}; use stereokit::{input::Ray, StereoKit};
@@ -22,12 +23,13 @@ impl MousePointer {
if let Some(ray) = Ray::from_mouse(sk.input_mouse()) { if let Some(ray) = Ray::from_mouse(sk.input_mouse()) {
self.pointer.spatial.set_local_transform_components( self.pointer.spatial.set_local_transform_components(
None, None,
Some(ray.pos.into()), Transform {
Some(glam::Quat::from_rotation_arc( position: Some(ray.pos.into()),
vec3(0.0, 0.0, 1.0), rotation: Some(
ray.dir.into(), glam::Quat::from_rotation_arc(vec3(0.0, 0.0, 1.0), ray.dir.into()).into(),
)), ),
None, scale: None,
},
); );
} }
} }

View File

@@ -4,6 +4,7 @@ use crate::nodes::{
}; };
use glam::Mat4; use glam::Mat4;
use portable_atomic::Ordering; use portable_atomic::Ordering;
use stardust_xr::values::Transform;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use stereokit::{input::Handed, StereoKit}; use stereokit::{input::Handed, StereoKit};
@@ -28,9 +29,11 @@ impl SkController {
if controller.tracked.is_active() { if controller.tracked.is_active() {
self.tip.spatial.set_local_transform_components( self.tip.spatial.set_local_transform_components(
None, None,
Some(controller.pose.position.into()), Transform {
Some(controller.pose.orientation.into()), position: Some(controller.pose.position.into()),
None, rotation: Some(controller.pose.orientation.into()),
scale: None,
},
); );
} }

View File

@@ -3,7 +3,7 @@ use crate::nodes::{
spatial::Spatial, spatial::Spatial,
}; };
use glam::Mat4; 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 std::sync::{Arc, Weak};
use stereokit::{ use stereokit::{
input::{Handed, Joint as SkJoint}, input::{Handed, Joint as SkJoint},

View File

@@ -16,16 +16,15 @@ use crate::{
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use glam::Mat4; use glam::Mat4;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use mint::Vector2;
use nanoid::nanoid; use nanoid::nanoid;
use serde::Deserialize;
use smithay::{ use smithay::{
reexports::wayland_server::protocol::wl_pointer::{Axis, ButtonState}, reexports::wayland_server::protocol::wl_pointer::{Axis, ButtonState},
utils::Size, utils::Size,
wayland::{compositor::SurfaceData, shell::xdg::XdgToplevelSurfaceData}, wayland::{compositor::SurfaceData, shell::xdg::XdgToplevelSurfaceData},
}; };
use stardust_xr::{ use stardust_xr::schemas::flex::{deserialize, serialize};
flex::{flexbuffer_from_arguments, flexbuffer_from_vector_arguments},
values::parse_vec2,
};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use xkbcommon::xkb::{self, ffi::XKB_KEYMAP_FORMAT_TEXT_V1, Keymap}; use xkbcommon::xkb::{self, ffi::XKB_KEYMAP_FORMAT_TEXT_V1, Keymap};
@@ -191,13 +190,11 @@ impl PanelItem {
pub fn resize(&self) { pub fn resize(&self) {
self.core_surface.upgrade().unwrap().with_data(|data| { self.core_surface.upgrade().unwrap().with_data(|data| {
let _ = self.node.upgrade().unwrap().send_remote_signal( let _ = self
"resize", .node
&flexbuffer_from_vector_arguments(|vec| { .upgrade()
vec.push(data.size.x); .unwrap()
vec.push(data.size.y); .send_remote_signal("resize", &serialize(data.size).unwrap());
}),
);
}); });
} }
@@ -206,26 +203,13 @@ impl PanelItem {
if !*cursor_changed { if !*cursor_changed {
return; return;
} }
let mut data = flexbuffer_from_arguments(|flex| { let mut data = serialize(()).unwrap();
flex.build_singleton(());
});
if let Some(cursor) = &*self.seat_data.cursor.lock() { if let Some(cursor) = &*self.seat_data.cursor.lock() {
let cursor = cursor.lock(); let cursor = cursor.lock();
if let Some(core_surface) = cursor.core_surface.upgrade() { if let Some(core_surface) = cursor.core_surface.upgrade() {
if let Some(mapped_data) = &*core_surface.mapped_data.lock() { if let Some(mapped_data) = &*core_surface.mapped_data.lock() {
data = flexbuffer_from_vector_arguments(|vec| { data = serialize((mapped_data.size, cursor.hotspot)).unwrap();
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();
});
} else { } else {
return; return;
}; };
@@ -318,6 +302,12 @@ impl PanelItem {
} }
fn pointer_scroll_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> { fn pointer_scroll_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
#[derive(Deserialize)]
struct PointerScrollArgs {
axis_continuous: Vector2<f32>,
axis_discrete: Option<Vector2<f32>>,
}
let args: PointerScrollArgs = deserialize(data)?;
if let ItemType::Panel(panel_item) = &node.item.get().unwrap().specialization { if let ItemType::Panel(panel_item) = &node.item.get().unwrap().specialization {
if let Some(pointer) = panel_item.seat_data.pointer() { if let Some(pointer) = panel_item.seat_data.pointer() {
if *panel_item.seat_data.pointer_active.lock() { 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::HorizontalScroll);
pointer.axis_stop(0, Axis::VerticalScroll); pointer.axis_stop(0, Axis::VerticalScroll);
} else { } else {
let flex_vec = flex.get_vector()?; pointer.axis(0, Axis::HorizontalScroll, args.axis_continuous.x as f64);
let axis_continuous_vec = parse_vec2(flex_vec.idx(0)) pointer.axis(0, Axis::VerticalScroll, args.axis_continuous.y as f64);
.ok_or_else(|| anyhow!("No continuous axis vector!"))?; if let Some(axis_discrete_vec) = args.axis_discrete {
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_discrete( pointer.axis_discrete(
Axis::HorizontalScroll, Axis::HorizontalScroll,
axis_discrete_vec.x as i32, axis_discrete_vec.x as i32,
@@ -494,41 +481,22 @@ impl PanelItem {
} }
} }
impl ItemSpecialization for PanelItem { impl ItemSpecialization for PanelItem {
fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) { fn serialize_start_data(&self, id: &str) -> Vec<u8> {
// Panel size // Panel size
{ let panel_size = self
let mut size_vec = vec.start_vector(); .core_surface
self.core_surface.upgrade().unwrap().with_data(|data| { .upgrade()
size_vec.push(data.size.x); .unwrap()
size_vec.push(data.size.y); .with_data(|data| data.size);
});
}
// Cursor size and hotspot let cursor_lock = (*self.seat_data.cursor.lock()).clone();
if let Some(cursor) = &*self.seat_data.cursor.lock() { let cursor_size = cursor_lock
let cursor = cursor.lock(); .clone()
if let Some(cursor_core_surface) = cursor.core_surface.upgrade() { .and_then(|cursor| cursor.lock().core_surface.upgrade())
if let Some(mapped_data) = &*cursor_core_surface.mapped_data.lock() { .and_then(|surf| surf.with_data(|data| data.size));
let mut cursor_vec = vec.start_vector(); let cursor_hotspot = cursor_lock.map(|cursor| cursor.lock().hotspot);
{
let mut cursor_size_vec = cursor_vec.start_vector(); serialize((id, (panel_size, cursor_size, cursor_hotspot))).unwrap()
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(());
}
} }
} }