add a system to suggest action bindings and a system to attach action sets to the session

This commit is contained in:
Schmarni
2024-04-29 02:41:51 +02:00
parent b2b40ba95a
commit 27871ccd0b
3 changed files with 26 additions and 8 deletions

View File

@@ -24,6 +24,7 @@ use bevy_xr::session::DestroyXrSession;
use bevy_xr::session::EndXrSession; use bevy_xr::session::EndXrSession;
use bevy_xr::session::XrSharedStatus; use bevy_xr::session::XrSharedStatus;
use bevy_xr::session::XrStatus; use bevy_xr::session::XrStatus;
use bevy_xr::session::XrStatusChanged;
use crate::error::OxrError; use crate::error::OxrError;
use crate::graphics::*; use crate::graphics::*;
@@ -334,17 +335,15 @@ fn init_xr_session(
preferred preferred
} else { } else {
if let Some(config) = view_configuration_views.first() { view_configuration_views.first().map(|config| {
Some(( (
UVec2::new( UVec2::new(
config.recommended_image_rect_width, config.recommended_image_rect_width,
config.recommended_image_rect_height, config.recommended_image_rect_height,
), ),
*config, *config,
)) )
} else { })
None
}
} }
.ok_or(OxrError::NoAvailableViewConfiguration)?; .ok_or(OxrError::NoAvailableViewConfiguration)?;
@@ -499,7 +498,11 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
} }
/// Polls any OpenXR events and handles them accordingly /// Polls any OpenXR events and handles them accordingly
pub fn poll_events(instance: Res<OxrInstance>, status: Res<XrSharedStatus>) { pub fn poll_events(
instance: Res<OxrInstance>,
status: Res<XrSharedStatus>,
mut changed_event: EventWriter<XrStatusChanged>,
) {
let _span = info_span!("xr_poll_events"); let _span = info_span!("xr_poll_events");
let mut buffer = Default::default(); let mut buffer = Default::default();
while let Some(event) = instance while let Some(event) = instance
@@ -525,7 +528,7 @@ pub fn poll_events(instance: Res<OxrInstance>, status: Res<XrSharedStatus>) {
SessionState::EXITING | SessionState::LOSS_PENDING => XrStatus::Exiting, SessionState::EXITING | SessionState::LOSS_PENDING => XrStatus::Exiting,
_ => unreachable!(), _ => unreachable!(),
}; };
changed_event.send(XrStatusChanged(new_status));
status.set(new_status); status.set(new_status);
} }
InstanceLossPending(_) => {} InstanceLossPending(_) => {}

View File

@@ -19,6 +19,8 @@ pub mod layer_builder;
pub mod render; pub mod render;
pub mod resources; pub mod resources;
pub mod types; pub mod types;
pub mod action_binding;
pub mod action_set_attaching;
pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder { pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder {
plugins plugins
@@ -37,6 +39,8 @@ pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder {
}) })
.add(OxrRenderPlugin) .add(OxrRenderPlugin)
.add(XrCameraPlugin) .add(XrCameraPlugin)
.add(action_set_attaching::OxrActionAttachingPlugin)
.add(action_binding::OxrActionBindingPlugin)
// .add(XrActionPlugin) // .add(XrActionPlugin)
.set(WindowPlugin { .set(WindowPlugin {
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]

View File

@@ -10,6 +10,7 @@ impl Plugin for XrSessionPlugin {
.add_event::<DestroyXrSession>() .add_event::<DestroyXrSession>()
.add_event::<BeginXrSession>() .add_event::<BeginXrSession>()
.add_event::<EndXrSession>() .add_event::<EndXrSession>()
.add_event::<XrStatusChanged>()
.add_systems( .add_systems(
PreUpdate, PreUpdate,
handle_session.run_if(resource_exists::<XrSharedStatus>), handle_session.run_if(resource_exists::<XrSharedStatus>),
@@ -17,6 +18,9 @@ impl Plugin for XrSessionPlugin {
} }
} }
#[derive(Event, Clone, Copy, Deref)]
pub struct XrStatusChanged(pub XrStatus);
#[derive(Resource, Clone)] #[derive(Resource, Clone)]
pub struct XrSharedStatus(Arc<RwLock<XrStatus>>); pub struct XrSharedStatus(Arc<RwLock<XrStatus>>);
@@ -84,6 +88,13 @@ pub fn handle_session(
*previous_status = Some(current_status); *previous_status = Some(current_status);
} }
/// A [`Condition`](bevy::ecs::schedule::Condition) that allows the system to run when the xr status changed to a specific [`XrStatus`].
pub fn status_changed_to(status: XrStatus) -> impl FnMut(EventReader<XrStatusChanged>) -> bool + Clone {
move |mut reader: EventReader<XrStatusChanged>| {
reader.read().count() > 0 && reader.read().any(|new_status| new_status.0 == status)
}
}
/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is available. Returns true as long as [`XrStatus`] exists and isn't [`Unavailable`](XrStatus::Unavailable). /// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is available. Returns true as long as [`XrStatus`] exists and isn't [`Unavailable`](XrStatus::Unavailable).
pub fn session_available(status: Option<Res<XrSharedStatus>>) -> bool { pub fn session_available(status: Option<Res<XrSharedStatus>>) -> bool {
status.is_some_and(|s| s.get() != XrStatus::Unavailable) status.is_some_and(|s| s.get() != XrStatus::Unavailable)