From fa0eedd8824412768937677cb549ba4cf64683f1 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Mon, 16 Dec 2024 06:00:29 +0100 Subject: [PATCH] refactor: very close to compiling, controllers should almost compile Signed-off-by: Schmarni --- src/bevy_plugin.rs | 15 +- src/main.rs | 96 +++++--- src/nodes/items/camera.rs | 21 +- src/nodes/items/mod.rs | 11 +- src/objects/input/sk_controller.rs | 371 ++++++++++++++++++++++------- 5 files changed, 373 insertions(+), 141 deletions(-) diff --git a/src/bevy_plugin.rs b/src/bevy_plugin.rs index c38808a..d727618 100644 --- a/src/bevy_plugin.rs +++ b/src/bevy_plugin.rs @@ -1,6 +1,8 @@ use bevy::{ - app::MainScheduleOrder, asset::embedded_asset, ecs::schedule::ScheduleLabel, - math::bounding::Aabb3d, prelude::*, + app::MainScheduleOrder, + ecs::schedule::{ExecutorKind, ScheduleLabel}, + math::bounding::Aabb3d, + prelude::*, }; use bevy_mod_openxr::session::OxrSession; use bevy_mod_xr::session::{session_available, XrSessionCreated}; @@ -11,6 +13,11 @@ use crate::objects::Inputs; pub struct StardustBevyPlugin; +#[derive(Resource, Deref)] +pub struct DbusConnection(pub zbus::Connection); + +#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone)] +pub struct InputUpdate; impl Plugin for StardustBevyPlugin { fn build(&self, app: &mut App) { app.init_schedule(StardustExtract); @@ -19,7 +26,9 @@ impl Plugin for StardustBevyPlugin { labels.insert(labels.len() - 2, StardustExtract.intern()); app.add_systems(Startup, spawn_camera.run_if(not(session_available))); app.add_systems(XrSessionCreated, make_view_space); - embedded_asset!(app, "src/objects/input", "objects/input/cursor.glb"); + let mut schedule = Schedule::new(InputUpdate); + schedule.set_executor_kind(ExecutorKind::Simple); + app.add_schedule(schedule); } } diff --git a/src/main.rs b/src/main.rs index bf22a7f..2f70c4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,15 +4,16 @@ mod core; mod nodes; mod objects; pub mod oxr_render_plugin; +pub mod oxr_sync_actionset; mod session; #[cfg(feature = "wayland")] mod wayland; use crate::core::destroy_queue; -use crate::nodes::items::camera; +// use crate::nodes::items::camera; use crate::nodes::{audio, drawable, input}; -use bevy::app::{App, Startup, Update}; +use bevy::app::{App, PluginGroup, Startup, Update}; use bevy::asset::{AssetServer, Handle}; use bevy::core_pipeline::Skybox; use bevy::image::Image; @@ -24,7 +25,7 @@ use bevy::prelude::{ use bevy::render::pipelined_rendering::PipelinedRenderingPlugin; use bevy::time::Time; use bevy::DefaultPlugins; -use bevy_mod_openxr::add_xr_plugins; +use bevy_mod_openxr::action_set_syncing::{OxrActionSyncingPlugin, OxrSyncActionSet}; use bevy_mod_openxr::exts::OxrExtensions; use bevy_mod_openxr::features::overlay::{OxrOverlaySessionEvent, OxrOverlaySettings}; use bevy_mod_openxr::init::{should_run_frame_loop, OxrInitPlugin}; @@ -32,13 +33,18 @@ use bevy_mod_openxr::render::{update_cameras, OxrRenderPlugin}; use bevy_mod_openxr::resources::{OxrFrameState, OxrFrameWaiter, OxrGraphicsInfo}; use bevy_mod_openxr::session::OxrSession; use bevy_mod_openxr::types::{AppInfo, Version}; +use bevy_mod_openxr::{add_xr_plugins, openxr_session_running}; use bevy_mod_xr::session::{XrFirst, XrSessionCreated, XrSessionPlugin}; -use bevy_plugin::StardustBevyPlugin; +use bevy_plugin::{DbusConnection, InputUpdate, StardustBevyPlugin}; use clap::Parser; use core::client::Client; use core::task; use directories::ProjectDirs; +use nodes::audio::StardustSoundPlugin; use nodes::drawable::lines::BevyLinesPlugin; +use nodes::drawable::model::StardustModelPlugin; +use nodes::drawable::text::StardustTextPlugin; +use objects::input::sk_controller::StardustControllerPlugin; use objects::ServerObjects; use once_cell::sync::OnceCell; use openxr::OverlaySessionCreateFlagsEXTX; @@ -52,7 +58,7 @@ use std::time::Duration; use tokio::net::UnixListener; use tokio::sync::Notify; use tracing::metadata::LevelFilter; -use tracing::{debug_span, error, info}; +use tracing::{debug_span, error, info, warn}; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; use zbus::fdo::ObjectManager; use zbus::Connection; @@ -209,7 +215,9 @@ fn stereokit_loop( object_registry: ObjectRegistry, ) { let mut bevy_app = App::new(); - let base = DefaultPlugins::build(DefaultPlugins).disable::(); + let base = (DefaultPlugins) + .build() + .disable::(); if args.flatscreen { bevy_app.add_plugins(base); } else { @@ -236,6 +244,7 @@ fn stereokit_loop( ..Default::default() }) .disable::() + .disable::() .add_after::(StardustOxrRenderPlugin), ); if let Some(priority) = args.overlay_priority { @@ -244,22 +253,32 @@ fn stereokit_loop( flags: OverlaySessionCreateFlagsEXTX::EMPTY, }); } + bevy_app.add_event::(); } bevy_app.add_plugins(StardustBevyPlugin); - bevy_app.add_plugins(BevyLinesPlugin); + bevy_app.add_plugins(( + BevyLinesPlugin, + StardustModelPlugin, + StardustTextPlugin, + StardustSoundPlugin, + StardustControllerPlugin, + )); #[derive(Resource)] struct SkyTexture(Handle); // Skytex/light stuff - bevy_app.add_systems(Startup, |assests: Res, mut cmds: Commands| { - if let Some(sky) = project_dirs - .as_ref() - .map(|dirs| dirs.config_dir().join("skytex.hdr")) - .filter(|f| f.exists()) - .map(|p| assests.load(p)) - { - cmds.insert_resource(SkyTexture(sky)); - } - }); + bevy_app.add_systems( + Startup, + move |assests: Res, mut cmds: Commands| { + if let Some(sky) = project_dirs + .as_ref() + .map(|dirs| dirs.config_dir().join("skytex.hdr")) + .filter(|f| f.exists()) + .map(|p| assests.load(p)) + { + cmds.insert_resource(SkyTexture(sky)); + } + }, + ); #[derive(Resource)] struct RenderBackground(bool); fn update_background( @@ -291,6 +310,7 @@ fn stereokit_loop( Update, update_background.run_if(on_event::), ); + bevy_app.insert_resource(DbusConnection(dbus_connection.clone())); #[cfg(feature = "wayland")] let mut wayland = wayland::Wayland::new().expect("Could not initialize wayland"); @@ -300,9 +320,21 @@ fn stereokit_loop( info!("Stardust ready!"); let mut objects = ServerObjects::new(dbus_connection.clone()); + fn sync_sets(session: Res, mut events: EventReader) { + let sets = events + .read() + .map(|v| &v.0) + .map(openxr::ActiveActionSet::new) + .collect::>(); + if sets.is_empty() { + return; + } + + if let Err(err) = session.sync_actions(&sets) { + warn!("error while syncing actionsets: {}", err.to_string()); + } + } - let mut last_frame_delta = Duration::ZERO; - let mut sleep_duration = Duration::ZERO; debug_span!("bevy").in_scope(|| loop { let _span = debug_span!("Bevy step"); let _span = _span.enter(); @@ -313,33 +345,43 @@ fn stereokit_loop( destroy_queue::clear(); let world = bevy_app.world_mut(); - let session = world.remove_resource::(); - let time = world.get_resource::().map(|s| { - openxr::Time::from_nanos( + let time = world.get_resource_mut::().map(|mut s| { + let t = openxr::Time::from_nanos( s.predicted_display_time.as_nanos() + s.predicted_display_period.as_nanos(), - ) + ); + s.predicted_display_time = t; + t }); + world.run_schedule(XrFirst); + if world + .run_system_cached(openxr_session_running) + .unwrap_or(true) + { + world.run_system_cached(sync_sets); + } + world.run_schedule(InputUpdate); + let session = world.remove_resource::(); objects.update(session.as_deref(), time); + if let Some(session) = session { + world.insert_resource(session); + } input::process_input(); nodes::root::Root::send_frame_events(world.resource::