refactor: remove stereokit dependency and fix all warnings

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2025-06-29 12:04:45 +02:00
committed by Nova King
parent cc8b9c0378
commit 5a5695f2cc
15 changed files with 35 additions and 599 deletions

86
Cargo.lock generated
View File

@@ -77,7 +77,7 @@ dependencies = [
"accesskit",
"accesskit_macos",
"accesskit_windows",
"raw-window-handle 0.6.2",
"raw-window-handle",
"winit",
]
@@ -173,17 +173,6 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d"
[[package]]
name = "android_logger"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b07e8e73d720a1f2e4b6014766e6039fd2e96a4fa44e2a78d0e1fa2ff49826"
dependencies = [
"android_log-sys",
"env_filter",
"log",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -1653,7 +1642,7 @@ dependencies = [
"bevy_reflect",
"bevy_utils",
"log",
"raw-window-handle 0.6.2",
"raw-window-handle",
"serde",
"smol_str",
]
@@ -1685,7 +1674,7 @@ dependencies = [
"bytemuck",
"cfg-if",
"crossbeam-channel",
"raw-window-handle 0.6.2",
"raw-window-handle",
"serde",
"tracing",
"wasm-bindgen",
@@ -2401,12 +2390,6 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "cty"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
[[package]]
name = "cursor-icon"
version = "1.2.0"
@@ -2703,16 +2686,6 @@ dependencies = [
"syn 2.0.103",
]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "equivalent"
version = "1.0.2"
@@ -4175,9 +4148,7 @@ dependencies = [
"log",
"ndk-sys 0.6.0+11769913",
"num_enum 0.7.3",
"raw-window-handle 0.4.3",
"raw-window-handle 0.5.2",
"raw-window-handle 0.6.2",
"raw-window-handle",
"thiserror 1.0.69",
]
@@ -5191,21 +5162,6 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684"
[[package]]
name = "raw-window-handle"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41"
dependencies = [
"cty",
]
[[package]]
name = "raw-window-handle"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]]
name = "raw-window-handle"
version = "0.6.2"
@@ -5835,7 +5791,6 @@ dependencies = [
"smithay",
"stardust-xr",
"stardust-xr-server-codegen",
"stereokit-rust",
"thiserror 2.0.12",
"tokio",
"toml",
@@ -5866,31 +5821,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stereokit-macros"
version = "0.1.0"
source = "git+https://github.com/mvvvv/StereoKit-rust.git?rev=73ffaae6f42aa369e599a6ea0391f77840d682d8#73ffaae6f42aa369e599a6ea0391f77840d682d8"
[[package]]
name = "stereokit-rust"
version = "0.1.0"
source = "git+https://github.com/mvvvv/StereoKit-rust.git?rev=73ffaae6f42aa369e599a6ea0391f77840d682d8#73ffaae6f42aa369e599a6ea0391f77840d682d8"
dependencies = [
"android-activity",
"android_logger",
"bitflags 2.9.1",
"cmake",
"glam",
"jni 0.21.1",
"log",
"ndk 0.9.0",
"ndk-context",
"ndk-sys 0.6.0+11769913",
"openxr-sys",
"stereokit-macros",
"thiserror 2.0.12",
]
[[package]]
name = "strict-num"
version = "0.1.1"
@@ -6950,7 +6880,7 @@ dependencies = [
"naga",
"parking_lot 0.12.4",
"profiling",
"raw-window-handle 0.6.2",
"raw-window-handle",
"smallvec",
"static_assertions",
"wasm-bindgen",
@@ -6978,7 +6908,7 @@ dependencies = [
"once_cell",
"parking_lot 0.12.4",
"profiling",
"raw-window-handle 0.6.2",
"raw-window-handle",
"rustc-hash 1.1.0",
"smallvec",
"thiserror 2.0.12",
@@ -7020,7 +6950,7 @@ dependencies = [
"parking_lot 0.12.4",
"profiling",
"range-alloc",
"raw-window-handle 0.6.2",
"raw-window-handle",
"renderdoc-sys",
"rustc-hash 1.1.0",
"smallvec",
@@ -7632,7 +7562,7 @@ dependencies = [
"orbclient",
"percent-encoding",
"pin-project",
"raw-window-handle 0.6.2",
"raw-window-handle",
"redox_syscall 0.4.1",
"rustix 0.38.44",
"sctk-adwaita",

View File

@@ -108,12 +108,6 @@ default-features = false
features = ["desktop", "backend_drm", "renderer_gl", "wayland_frontend"]
optional = true
[dependencies.stereokit-rust]
git = "https://github.com/mvvvv/StereoKit-rust.git"
rev = "73ffaae6f42aa369e599a6ea0391f77840d682d8"
features = ["no-event-loop"]
default-features = false
[dependencies.stardust-xr]
workspace = true

View File

@@ -26,7 +26,7 @@ use std::{
time::Instant,
};
use tokio::{net::UnixStream, sync::watch, task::JoinHandle};
use tracing::{info, warn};
use tracing::info;
lazy_static! {
pub static ref CLIENTS: OwnedRegistry<Client> = OwnedRegistry::new();
@@ -86,7 +86,7 @@ impl Client {
pub fn from_connection(connection: UnixStream) -> Result<Arc<Self>> {
let pid = connection.peer_cred().ok().and_then(|c| c.pid());
let env = pid.and_then(|pid| get_env(pid).ok());
let exe = pid.and_then(|pid| fs::read_link(format!("/proc/{}/exe", pid)).ok());
let exe = pid.and_then(|pid| fs::read_link(format!("/proc/{pid}/exe")).ok());
info!(
pid,
exe = exe

View File

@@ -8,7 +8,6 @@ use stardust_xr::{
flexbuffers::{DeserializationError, ReaderError},
},
};
use stereokit_rust::StereoKitError;
use thiserror::Error;
pub type Result<T, E = ServerError> = std::result::Result<T, E>;
@@ -29,8 +28,6 @@ pub enum ServerError {
DeserializationError(#[from] DeserializationError),
#[error("Reader error: {0}")]
ReaderError(#[from] ReaderError),
#[error("StereoKit error: {0}")]
StereoKitError(#[from] StereoKitError),
#[error("Aspect {} does not exist for node", 0.to_string())]
NoAspect(TypeId),
#[error("{0}")]

View File

@@ -7,8 +7,7 @@ mod session;
mod wayland;
use crate::core::destroy_queue;
use crate::nodes::items::camera;
use crate::nodes::{drawable, input};
use crate::nodes::input;
use bevy::MinimalPlugins;
use bevy::a11y::AccessibilityPlugin;
@@ -52,7 +51,6 @@ use nodes::drawable::lines::LinesNodePlugin;
use nodes::drawable::model::ModelNodePlugin;
use nodes::drawable::text::TextNodePlugin;
use nodes::spatial::SpatialNodePlugin;
use objects::ServerObjects;
use objects::input::mouse_pointer::FlatscreenInputPlugin;
use objects::input::sk_controller::ControllerPlugin;
use objects::input::sk_hand::HandPlugin;
@@ -64,20 +62,11 @@ use stardust_xr::server;
use std::ops::DerefMut as _;
use std::path::PathBuf;
use std::sync::{Arc, OnceLock};
use std::time::Duration;
use stereokit_rust::material::Material;
use stereokit_rust::shader::Shader;
use stereokit_rust::sk::{
AppMode, DepthMode, DisplayBlend, OriginMode, QuitReason, SkSettings, sk_quit,
};
use stereokit_rust::system::{Handed, Input, LogLevel, Renderer};
use stereokit_rust::tex::{SHCubemap, Tex, TexFormat, TexType};
use stereokit_rust::ui::Ui;
use stereokit_rust::util::{Color128, SphericalHarmonics, Time};
use tokio::net::UnixListener;
use tokio::sync::Notify;
use tokio::task::JoinError;
use tracing::metadata::LevelFilter;
use tracing::{debug_span, error, info};
use tracing::{error, info};
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
use zbus::Connection;
use zbus::fdo::ObjectManager;
@@ -123,14 +112,7 @@ static STARDUST_INSTANCE: OnceLock<String> = OnceLock::new();
// #[tokio::main(flavor = "current_thread")]
#[tokio::main]
async fn main() {
// let mut out = Vec::new();
// for i in 0..8 {
// for base in [0, 8, 1, 8, 9, 1] {
// out.push(base + i as u16);
// }
// }
// panic!("{out:?}");
async fn main() -> Result<AppExit, JoinError> {
color_eyre::install().unwrap();
let registry = tracing_subscriber::registry();
@@ -222,15 +204,15 @@ async fn main() {
"Couldn't make the object registry to find all objects with given interfaces in d-bus",
);
let sk_ready_notifier = Arc::new(Notify::new());
let stereokit_loop = tokio::task::spawn_blocking({
let sk_ready_notifier = sk_ready_notifier.clone();
let ready_notifier = Arc::new(Notify::new());
let io_loop = tokio::task::spawn_blocking({
let ready_notifier = ready_notifier.clone();
let project_dirs = project_dirs.clone();
let cli_args = cli_args.clone();
let dbus_connection = dbus_connection.clone();
move || {
bevy_loop(
sk_ready_notifier,
ready_notifier,
project_dirs,
cli_args,
dbus_connection,
@@ -238,16 +220,12 @@ async fn main() {
)
}
});
sk_ready_notifier.notified().await;
ready_notifier.notified().await;
let mut startup_children = project_dirs
.as_ref()
.map(|project_dirs| launch_start(&cli_args, project_dirs))
.unwrap_or_default();
tokio::select! {
_ = stereokit_loop => (),
_ = tokio::signal::ctrl_c() => unsafe {sk_quit(QuitReason::SystemClose)},
}
let return_value = io_loop.await;
info!("Stopping...");
if let Some(project_dirs) = project_dirs {
save_session(&project_dirs).await;
@@ -257,10 +235,11 @@ async fn main() {
}
info!("Cleanly shut down Stardust");
return_value
}
static DEFAULT_SKYTEX: OnceLock<Tex> = OnceLock::new();
static DEFAULT_SKYLIGHT: OnceLock<SphericalHarmonics> = OnceLock::new();
// static DEFAULT_SKYTEX: OnceLock<Tex> = OnceLock::new();
// static DEFAULT_SKYLIGHT: OnceLock<SphericalHarmonics> = OnceLock::new();
#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]
pub struct PreFrameWait;
@@ -271,11 +250,11 @@ pub struct DbusConnection(Connection);
fn bevy_loop(
ready_notifier: Arc<Notify>,
project_dirs: Option<ProjectDirs>,
_project_dirs: Option<ProjectDirs>,
args: CliArgs,
dbus_connection: Connection,
object_registry: ObjectRegistry,
) {
) -> AppExit {
let mut app = App::new();
app.insert_resource(DbusConnection(dbus_connection));
app.add_plugins(AssetPlugin {
@@ -376,8 +355,7 @@ fn bevy_loop(
},
bevy_sk::skytext::SphericalHarmonicsPlugin,
));
app.add_plugins(HandGizmosPlugin);
// app.add_plugins(MeshTextPlugin);
// app.add_plugins(HandGizmosPlugin);
app.init_asset::<Font>().init_asset_loader::<FontLoader>();
if let Some(priority) = args.overlay_priority {
app.insert_resource(OxrOverlaySettings {
@@ -423,7 +401,7 @@ fn bevy_loop(
.in_set(XrHandleEvents::FrameLoop),
);
app.run();
app.run()
}
fn update_cameras(mut camera: Query<&mut Projection, (With<Camera3d>,)>) {
for mut projection in &mut camera {
@@ -465,6 +443,7 @@ fn xr_step(world: &mut World) {
let should_wait = world
.run_system_cached(should_run_frame_loop)
.unwrap_or(false);
// we might want to do an adaptive sleep when not OpenXR waiting
if should_wait {
world.resource_scope::<OxrFrameWaiter, _>(|world, mut waiter| {
let state = waiter
@@ -484,137 +463,3 @@ fn xr_step(world: &mut World) {
// drawable::draw(token);
// audio::update();
}
fn stereokit_loop(
sk_ready_notifier: Arc<Notify>,
project_dirs: Option<ProjectDirs>,
args: CliArgs,
dbus_connection: Connection,
object_registry: ObjectRegistry,
) {
let sk = SkSettings::default()
.app_name("Stardust XR")
.blend_preference(DisplayBlend::AnyTransparent)
.mode(if args.flatscreen {
AppMode::Simulator
} else {
AppMode::XR
})
.depth_mode(DepthMode::D32)
.log_filter(match EnvFilter::from_default_env().max_level_hint() {
Some(LevelFilter::ERROR) => LogLevel::Error,
Some(LevelFilter::WARN) => LogLevel::Warning,
Some(LevelFilter::INFO) => LogLevel::Inform,
Some(LevelFilter::DEBUG) => LogLevel::Diagnostic,
Some(LevelFilter::TRACE) => LogLevel::Diagnostic,
Some(LevelFilter::OFF) => LogLevel::None,
None => LogLevel::Warning,
})
.overlay_app(args.overlay_priority.is_some())
.overlay_priority(args.overlay_priority.unwrap_or(u32::MAX))
.disable_desktop_input_window(true)
.origin(OriginMode::Local)
.init()
.expect("StereoKit failed to initialize");
info!("Init StereoKit");
Renderer::multisample(0);
Material::default().shader(Shader::pbr_clip());
Ui::enable_far_interact(false);
let left_hand_material = Material::find("default/material_hand").unwrap();
let mut right_hand_material = left_hand_material.copy();
right_hand_material.id("right_hand");
Input::hand_material(Handed::Right, Some(Material::find("right_hand").unwrap()));
Input::hand_visible(Handed::Left, false);
Input::hand_visible(Handed::Right, false);
// Skytex/light stuff
{
let _ = DEFAULT_SKYTEX.set(Tex::gen_color(
Color128::BLACK,
1,
1,
TexType::Cubemap,
TexFormat::RGBA32,
));
let _ = DEFAULT_SKYLIGHT.set(Renderer::get_skylight());
if let Some(sky) = project_dirs
.as_ref()
.map(|dirs| dirs.config_dir().join("skytex.hdr"))
.filter(|f| f.exists())
.and_then(|p| SHCubemap::from_cubemap(p, true, 100).ok())
{
sky.render_as_sky();
} else {
Renderer::skytex(DEFAULT_SKYTEX.get().unwrap());
}
}
#[cfg(feature = "wayland")]
let mut wayland = wayland::Wayland::new().expect("Could not initialize wayland");
#[cfg(feature = "wayland")]
wayland.make_context_current();
sk_ready_notifier.notify_waiters();
info!("Stardust ready!");
let mut objects = ServerObjects::new(
dbus_connection.clone(),
&sk,
[left_hand_material, right_hand_material],
args.disable_controllers,
args.disable_hands,
);
let mut last_frame_delta = Duration::ZERO;
let mut sleep_duration = Duration::ZERO;
while let Some(token) = sk.step() {
let _span = debug_span!("StereoKit step");
let _span = _span.enter();
camera::update(token);
#[cfg(feature = "wayland")]
wayland.frame_event();
destroy_queue::clear();
objects.update(&sk, token, &dbus_connection, &object_registry);
input::process_input();
nodes::root::Root::send_frame_events(Time::get_step_unscaled());
adaptive_sleep(
&mut last_frame_delta,
&mut sleep_duration,
Duration::from_micros(250),
);
tick_internal_client();
#[cfg(feature = "wayland")]
wayland.update();
drawable::draw(token);
// audio::update();
}
info!("Cleanly shut down StereoKit");
}
fn adaptive_sleep(
last_frame_delta: &mut Duration,
sleep_duration: &mut Duration,
sleep_duration_increase: Duration,
) {
let frame_delta = Duration::from_secs_f64(Time::get_step_unscaled());
if *last_frame_delta < frame_delta {
if let Some(frame_delta_delta) = frame_delta.checked_sub(*last_frame_delta) {
if let Some(new_sleep_duration) = sleep_duration.checked_sub(frame_delta_delta) {
*sleep_duration = new_sleep_duration;
}
}
} else {
*sleep_duration += sleep_duration_increase;
}
debug_span!("Sleep", ?sleep_duration, ?frame_delta, ?last_frame_delta).in_scope(|| {
*last_frame_delta = frame_delta;
std::thread::sleep(*sleep_duration); // to give clients a chance to even update anything before drawing
});
}

View File

@@ -1,6 +1,6 @@
pub mod lines;
pub mod model;
pub mod shaders;
// pub mod shaders;
pub mod text;
use self::{lines::Lines, model::Model, text::Text};
@@ -8,43 +8,13 @@ use super::{
Aspect, AspectIdentifier, Node,
spatial::{Spatial, Transform},
};
use crate::{DEFAULT_SKYLIGHT, nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO};
use crate::{
DEFAULT_SKYTEX,
core::{client::Client, error::Result, resource::get_resource_file},
};
use crate::core::{client::Client, error::Result, resource::get_resource_file};
use crate::nodes::spatial::SPATIAL_ASPECT_ALIAS_INFO;
use color_eyre::eyre::eyre;
use model::ModelPart;
use parking_lot::Mutex;
use stardust_xr::values::ResourceID;
use std::{ffi::OsStr, path::PathBuf, sync::Arc};
use stereokit_rust::{sk::MainThreadToken, system::Renderer, tex::SHCubemap};
// #[instrument(level = "debug", skip(sk))]
pub fn draw(token: &MainThreadToken) {
match QUEUED_SKYTEX.lock().take() {
Some(Some(skytex)) => {
if let Ok(skytex) = SHCubemap::from_cubemap(skytex, true, 100) {
Renderer::skytex(skytex.tex);
}
}
Some(None) => {
Renderer::skytex(DEFAULT_SKYTEX.get().unwrap());
}
None => {}
}
match QUEUED_SKYLIGHT.lock().take() {
Some(Some(skylight)) => {
if let Ok(skylight) = SHCubemap::from_cubemap(skylight, true, 100) {
Renderer::skylight(skylight.sh);
}
}
Some(None) => {
Renderer::skylight(*DEFAULT_SKYLIGHT.get().unwrap());
}
None => {}
}
}
static QUEUED_SKYLIGHT: Mutex<Option<Option<PathBuf>>> = Mutex::new(None);
static QUEUED_SKYTEX: Mutex<Option<Option<PathBuf>>> = Mutex::new(None);

View File

@@ -1,3 +1,4 @@
#![allow(dead_code)]
use super::{Item, ItemType, create_item_acceptor_flex, register_item_ui_flex};
use crate::bail;
use crate::core::error::Result;
@@ -9,7 +10,7 @@ use crate::{
core::{client::Client, registry::Registry, scenegraph::MethodResponseSender},
nodes::{
Message, Node,
drawable::{model::ModelPart, shaders::UNLIT_SHADER_BYTES},
drawable::model::ModelPart,
items::TypeInfo,
spatial::{Spatial, Transform},
},
@@ -21,19 +22,6 @@ use parking_lot::Mutex;
use stardust_xr::schemas::flex::{deserialize, serialize};
use std::sync::Arc;
use std::sync::OnceLock;
use stereokit_rust::{
material::{Material, Transparency},
shader::Shader,
sk::MainThreadToken,
system::Renderer,
tex::{Tex, TexFormat, TexType},
util::Color128,
};
pub struct TexWrapper(pub Tex);
unsafe impl Send for TexWrapper {}
unsafe impl Sync for TexWrapper {}
stardust_xr_server_codegen::codegen_item_camera_protocol!();
lazy_static! {
@@ -64,7 +52,6 @@ struct FrameInfo {
pub struct CameraItem {
space: Arc<Spatial>,
frame_info: Mutex<FrameInfo>,
sk_tex: OnceLock<TexWrapper>,
applied_to: Registry<ModelPart>,
apply_to: Registry<ModelPart>,
}
@@ -77,7 +64,6 @@ impl CameraItem {
proj_matrix,
px_size,
}),
sk_tex: OnceLock::new(),
applied_to: Registry::new(),
apply_to: Registry::new(),
});
@@ -122,41 +108,6 @@ impl CameraItem {
pub fn send_acceptor_item_created(&self, node: &Node, item: &Arc<Node>) {
let _ = camera_item_acceptor_client::capture_item(node, item);
}
pub fn update(&self, token: &MainThreadToken) {
let frame_info = self.frame_info.lock();
let sk_tex = self.sk_tex.get_or_init(|| {
TexWrapper(Tex::gen_color(
Color128::default(),
frame_info.px_size.x as i32,
frame_info.px_size.y as i32,
TexType::Rendertarget,
TexFormat::RGBA32Linear,
))
});
// let sk_mat = self.sk_mat.get_or_init(|| {
// let shader = Shader::from_memory(UNLIT_SHADER_BYTES).unwrap();
// let mut mat = Material::new(&shader, None);
// mat.get_all_param_info().set_texture("diffuse", &sk_tex.0);
// mat.transparency(Transparency::Blend);
// Arc::new(MaterialWrapper(mat))
// });
for model_part in self.apply_to.take_valid_contents() {
// model_part.replace_material(sk_mat.clone())
}
if !self.applied_to.is_empty() {
Renderer::render_to(
token,
&sk_tex.0,
self.space.global_transform(),
frame_info.proj_matrix,
None,
None,
None,
)
}
}
}
impl AspectIdentifier for CameraItem {
impl_aspect_for_camera_item_aspect_id! {}
@@ -188,15 +139,6 @@ impl CameraItemAcceptorAspect for CameraItemAcceptor {
}
}
pub fn update(token: &MainThreadToken) {
for camera in ITEM_TYPE_INFO_CAMERA.items.get_valid_contents() {
let ItemType::Camera(camera) = &camera.specialization else {
continue;
};
camera.update(token);
}
}
impl InterfaceAspect for Interface {
#[doc = "Create a camera item at a specific location"]
fn create_camera_item(

View File

@@ -133,6 +133,7 @@ impl Drop for Item {
}
}
#[cfg_attr(not(feature = "wayland"), allow(dead_code))]
pub enum ItemType {
Camera(Arc<CameraItem>),
Panel(Arc<dyn PanelItemTrait>),

View File

@@ -102,6 +102,7 @@ pub struct PanelItem<B: Backend> {
pub backend: Box<B>,
}
impl<B: Backend> PanelItem<B> {
#[cfg_attr(not(feature = "wayland"), allow(dead_code))]
pub fn create(backend: Box<B>, pid: Option<i32>) -> (Arc<Node>, Arc<PanelItem<B>>) {
debug!(?pid, "Create panel item");

View File

@@ -12,7 +12,6 @@ use glam::{Mat4, vec3};
use serde::{Deserialize, Serialize};
use stardust_xr::values::Datamap;
use std::sync::Arc;
use stereokit_rust::system::Input;
#[derive(Default, Deserialize, Serialize)]
pub struct EyeDatamap {
@@ -49,58 +48,4 @@ impl EyePointer {
pointer,
})
}
pub fn update(&self) {
let ray = Input::get_eyes();
self.spatial
.set_local_transform(Mat4::from_rotation_translation(
ray.orientation.into(),
ray.position.into(),
));
{
// Set pointer input datamap
*self.pointer.datamap.lock() = Datamap::from_typed(EyeDatamap { eye: 2 }).unwrap();
}
// send input to all the input handlers that are the closest to the ray as possible
let rx = INPUT_HANDLER_REGISTRY
.get_valid_contents()
.into_iter()
// filter out all the disabled handlers
.filter(|handler| {
let Some(node) = handler.spatial.node() else {
return false;
};
node.enabled()
})
// ray march to all the enabled handlers' fields
.map(|handler| {
let result = handler.field.ray_march(Ray {
origin: vec3(0.0, 0.0, 0.0),
direction: vec3(0.0, 0.0, -1.0),
space: self.spatial.clone(),
});
(vec![handler], result)
})
// make sure the field isn't at the pointer origin and that it's being hit
.filter(|(_, result)| result.deepest_point_distance > 0.01 && result.min_distance < 0.0)
// .inspect(|(_, result)| {
// dbg!(result);
// })
// now collect all handlers that are same distance if they're the closest
.reduce(|(mut handlers_a, result_a), (handlers_b, result_b)| {
if (result_a.deepest_point_distance - result_b.deepest_point_distance).abs() < 0.001
{
// distance is basically the same
handlers_a.extend(handlers_b);
(handlers_a, result_a)
} else if result_a.deepest_point_distance < result_b.deepest_point_distance {
(handlers_a, result_a)
} else {
(handlers_b, result_b)
}
})
.map(|(rx, _)| rx)
.unwrap_or_default();
self.pointer.set_handler_order(rx.iter());
}
}

View File

@@ -29,7 +29,6 @@ use stardust_xr::{
values::Datamap,
};
use std::sync::Arc;
use stereokit_rust::system::{Input, Key};
use tokio::task::JoinSet;
use tokio::time::{Duration, timeout};
use xkbcommon_rs::{Context, Keymap, KeymapFormat, xkb_keymap::CompileFlags};

View File

@@ -40,12 +40,6 @@ use std::{
str::FromStr,
sync::Arc,
};
use stereokit_rust::{
material::Material,
sk::MainThreadToken,
system::{Handed, Input},
util::Color128,
};
use zbus::Connection;
pub struct ControllerPlugin;
const CURSOR_MODEL_PATH: &str = "/tmp/stardust_server/models/cursor.glb";

View File

@@ -25,10 +25,6 @@ use openxr::{HandJointLocation, SpaceLocationFlags};
use serde::{Deserialize, Serialize};
use stardust_xr::values::Datamap;
use std::sync::Arc;
use stereokit_rust::material::Material;
use stereokit_rust::sk::{DisplayMode, MainThreadToken, Sk};
use stereokit_rust::system::{HandJoint, HandSource, Handed, Input, LinePoint, Lines};
use stereokit_rust::util::Color128;
use zbus::Connection;
use super::{CaptureManager, get_sorted_handlers};
@@ -372,11 +368,3 @@ impl SkHand {
.set_handler_order(sorted_handlers.iter().map(|(handler, _)| handler));
}
}
fn joint_to_line_point(joint: &Joint, color: Color128) -> LinePoint {
LinePoint {
pt: Vec3::from(joint.position).into(),
thickness: joint.radius * 2.0,
color: color.into(),
}
}

View File

@@ -20,180 +20,11 @@ use std::{
marker::PhantomData,
sync::{Arc, atomic::Ordering},
};
use stereokit_rust::{
material::Material,
sk::{DisplayMode, MainThreadToken, Sk},
system::{Handed, Input, Key, World},
util::Device,
};
use zbus::{Connection, interface, object_server::Interface, zvariant::OwnedObjectPath};
pub mod input;
pub mod play_space;
enum Inputs {
XR {
// controller_left: SkController,
// controller_right: SkController,
// hand_left: SkHand,
// hand_right: SkHand,
eye_pointer: Option<EyePointer>,
},
MousePointer(MousePointer),
// Controllers((SkController, SkController)),
// Hands {
// left: SkHand,
// right: SkHand,
// },
}
pub struct ServerObjects {
connection: Connection,
hmd: (Arc<Spatial>, ObjectHandle<SpatialRef>),
play_space: Option<(Arc<Spatial>, ObjectHandle<SpatialRef>)>,
hand_materials: [Material; 2],
inputs: Inputs,
disable_controllers: bool,
disable_hands: bool,
}
impl ServerObjects {
pub fn new(
connection: Connection,
sk: &Sk,
hand_materials: [Material; 2],
disable_controllers: bool,
disable_hands: bool,
) -> ServerObjects {
let hmd = SpatialRef::create(&connection, "/org/stardustxr/HMD");
let play_space = Some(SpatialRef::create(&connection, "/org/stardustxr/PlaySpace"));
if play_space.is_some() {
let dbus_connection = connection.clone();
tokio::task::spawn(async move {
let play_space_data = Arc::new(RwLock::default());
PlaySpaceBounds::create(&dbus_connection, play_space_data).await;
dbus_connection
.request_name("org.stardustxr.PlaySpace")
.await
.unwrap();
});
}
tokio::task::spawn({
let connection = connection.clone();
async move {
connection
.request_name("org.stardustxr.Controllers")
.await
.unwrap();
connection
.request_name("org.stardustxr.Hands")
.await
.unwrap();
}
});
let inputs = if sk.get_active_display_mode() == DisplayMode::MixedReality {
Inputs::XR {
// hand_left: SkHand::new(&connection, Handed::Left).unwrap(),
// hand_right: SkHand::new(&connection, Handed::Right).unwrap(),
eye_pointer: Device::has_eye_gaze()
.then(EyePointer::new)
.transpose()
.unwrap(),
}
} else {
Inputs::MousePointer(MousePointer::new().unwrap())
};
ServerObjects {
connection,
hmd,
play_space,
hand_materials,
inputs,
disable_controllers,
disable_hands,
}
}
pub fn update(
&mut self,
sk: &Sk,
token: &MainThreadToken,
dbus_connection: &Connection,
object_registry: &ObjectRegistry,
) {
let hmd_pose = Input::get_head();
self.hmd
.0
.set_local_transform(Mat4::from_scale_rotation_translation(
vec3(1.0, 1.0, 1.0),
hmd_pose.orientation.into(),
hmd_pose.position.into(),
));
if let Some(play_space) = self.play_space.as_ref() {
let pose = World::get_bounds_pose();
play_space
.0
.set_local_transform(Mat4::from_rotation_translation(
pose.orientation.into(),
pose.position.into(),
));
}
#[allow(clippy::collapsible_if)]
if sk.get_active_display_mode() != DisplayMode::MixedReality {
if Input::key(Key::F6).is_just_inactive() {
self.inputs = Inputs::MousePointer(MousePointer::new().unwrap());
}
// if Input::key(Key::F7).is_just_inactive() {
// self.inputs = Inputs::Controllers((
// SkController::new(Handed::Left).unwrap(),
// SkController::new(Handed::Right).unwrap(),
// ));
// }
// if Input::key(Key::F8).is_just_inactive() {
// self.inputs = Inputs::Hands {
// left: SkHand::new(&self.connection, Handed::Left).unwrap(),
// right: SkHand::new(&self.connection, Handed::Right).unwrap(),
// };
// }
}
match &mut self.inputs {
Inputs::XR {
// controller_left,
// controller_right,
eye_pointer,
} => {
// if !self.disable_controllers {
// controller_left.update(token);
// controller_right.update(token);
// }
Input::hand_visible(Handed::Left, !self.disable_hands);
Input::hand_visible(Handed::Right, !self.disable_hands);
// if !self.disable_hands {
// hand_left.update(sk, token, &mut self.hand_materials[0]);
// hand_right.update(sk, token, &mut self.hand_materials[1]);
// }
if let Some(eye_pointer) = eye_pointer {
eye_pointer.update();
}
}
Inputs::MousePointer(mouse_pointer) => {} // Inputs::Controllers((left, right)) => {
// left.update(token);
// right.update(token);
// }
// Inputs::Hands { left, right } => {
// left.update(sk, token, &mut self.hand_materials[0]);
// right.update(sk, token, &mut self.hand_materials[1]);
// }
}
}
}
pub struct ObjectHandle<I: Interface>(Connection, OwnedObjectPath, PhantomData<I>);
impl<I: Interface> Clone for ObjectHandle<I> {

View File

@@ -12,7 +12,6 @@ use bevy_mod_xr::{
};
use openxr::SpaceLocationFlags;
use parking_lot::RwLock;
use stereokit_rust::system::World;
use zbus::{Connection, ObjectServer, interface};
use crate::{DbusConnection, PreFrameWait, nodes::spatial::Spatial};