stardust_xr_fusion/
objects.rs1#![allow(async_fn_in_trait)]
2
3use crate::{
4 client::ClientHandle,
5 fields::{Field, FieldAspect, FieldRef},
6 node::NodeResult,
7 spatial::{Spatial, SpatialAspect, SpatialRef},
8};
9use interfaces::FieldRefProxy;
10pub use stardust_xr::schemas::dbus::*;
11use stardust_xr::{
12 schemas::{
13 dbus::interfaces::{PlaySpaceProxy, SpatialRefProxy},
14 zbus::Connection,
15 },
16 values::Vector2,
17};
18use std::sync::Arc;
19
20pub trait SpatialRefProxyExt {
21 async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<SpatialRef>;
22}
23impl SpatialRefProxyExt for SpatialRefProxy<'_> {
24 async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<SpatialRef> {
25 let uid = self.uid().await.ok()?;
26 SpatialRef::import(stardust_client, uid).await.ok()
27 }
28}
29pub struct SpatialObject(u64, Spatial);
30impl SpatialObject {
31 pub async fn new(spatial: Spatial) -> NodeResult<Self> {
32 Ok(Self(spatial.export_spatial().await?, spatial))
33 }
34}
35#[zbus::interface(name = "org.stardustxr.SpatialRef")]
36impl SpatialObject {
37 #[zbus(property)]
38 async fn uid(&self) -> u64 {
39 self.0
40 }
41}
42
43pub trait FieldRefProxyExt {
44 async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<FieldRef>;
45}
46impl FieldRefProxyExt for FieldRefProxy<'_> {
47 async fn import(&self, stardust_client: &Arc<ClientHandle>) -> Option<FieldRef> {
48 let uid = self.uid().await.ok()?;
49 FieldRef::import(stardust_client, uid).await.ok()
50 }
51}
52pub struct FieldObject(u64, Field);
53impl FieldObject {
54 pub async fn new(field: Field) -> NodeResult<Self> {
55 Ok(Self(field.export_field().await?, field))
56 }
57}
58#[zbus::interface(name = "org.stardustxr.FieldRef")]
59impl FieldObject {
60 #[zbus(property)]
61 async fn uid(&self) -> u64 {
62 self.0
63 }
64}
65
66pub async fn hmd(client: &Arc<ClientHandle>) -> Option<SpatialRef> {
67 let connection = Connection::session().await.ok()?;
68 let spatial_ref =
69 SpatialRefProxy::new(&connection, "org.stardustxr.HMD", "/org/stardustxr/HMD")
70 .await
71 .ok()?;
72 spatial_ref.import(client).await
73}
74
75#[tokio::test]
76async fn fusion_objects_hmd() {
77 use crate::spatial::SpatialRefAspect;
78
79 let client = crate::Client::connect().await.unwrap();
80 let client_handle = client.handle();
81 client.async_event_loop();
82
83 let hmd = hmd(&client_handle).await.unwrap();
84 assert!(hmd.get_transform(client_handle.get_root()).await.is_ok())
85}
86
87pub struct PlaySpace {
88 pub spatial: SpatialRef,
89 pub bounds_polygon: Vec<Vector2<f32>>,
90}
91pub async fn play_space(client: &Arc<ClientHandle>) -> Option<PlaySpace> {
92 let connection = Connection::session().await.ok()?;
93 let spatial_proxy = SpatialRefProxy::new(
94 &connection,
95 "org.stardustxr.PlaySpace",
96 "/org/stardustxr/PlaySpace",
97 )
98 .await
99 .ok()?;
100 let spatial = spatial_proxy.import(client).await?;
101 let play_space_proxy = PlaySpaceProxy::new(&connection).await.ok()?;
102 let bounds_polygon = play_space_proxy.bounds().await.ok()?;
103 Some(PlaySpace {
104 spatial,
105 bounds_polygon: bounds_polygon
106 .into_iter()
107 .map(|(x, y)| [x as f32, y as f32].into())
108 .collect(),
109 })
110}