refactor: make all flex stuff use serde
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
|||||||
@@ -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,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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},
|
||||||
|
|||||||
@@ -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(());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user