Skip to content

Commit

Permalink
Merge pull request #158 from Schmarni-Dev/is_openxr-xr_flags
Browse files Browse the repository at this point in the history
Backend Specific RunConditions and Space Flags in xr crate
  • Loading branch information
Schmarni-Dev authored Oct 20, 2024
2 parents aea1cc6 + ac972dd commit 302a455
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ bevy = { version = "0.14.0", default-features = false, features = [
"bevy_render",
"bevy_core_pipeline",
"bevy_winit",
"bevy_pbr",
"x11",
] }
7 changes: 4 additions & 3 deletions crates/bevy_openxr/src/openxr/action_set_syncing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::session::OxrSession;
use crate::{openxr_session_running, session::OxrSession};
use bevy::prelude::*;
use bevy_mod_xr::session::session_running;

#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct OxrActionSetSyncSet;
Expand All @@ -10,7 +9,9 @@ impl Plugin for OxrActionSyncingPlugin {
app.add_event::<OxrSyncActionSet>();
app.add_systems(
PreUpdate,
sync_sets.in_set(OxrActionSetSyncSet).run_if(session_running), // .in_set(OxrPreUpdateSet::SyncActions),
sync_sets
.in_set(OxrActionSetSyncSet)
.run_if(openxr_session_running),
);
}
}
Expand Down
44 changes: 36 additions & 8 deletions crates/bevy_openxr/src/openxr/features/handtracking.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use bevy::prelude::*;
use bevy_mod_xr::hands::{HandBone, HandBoneRadius};
use bevy_mod_xr::hands::{LeftHand, RightHand, XrHandBoneEntities, HAND_JOINT_COUNT};
use bevy_mod_xr::session::{XrPreDestroySession, XrSessionCreated, XrTrackingRoot};
use bevy_mod_xr::spaces::{XrPrimaryReferenceSpace, XrReferenceSpace, XrVelocity};
use bevy_mod_xr::{
hands::{HandBone, HandBoneRadius},
session::session_running,
use bevy_mod_xr::spaces::{
XrPrimaryReferenceSpace, XrReferenceSpace, XrSpaceLocationFlags, XrSpaceVelocityFlags,
XrVelocity,
};
use openxr::{SpaceLocationFlags, SpaceVelocityFlags};

use crate::helper_traits::ToVec3;
use crate::openxr_session_running;
use crate::resources::OxrFrameState;
use crate::resources::Pipelined;
use crate::session::OxrSession;
Expand All @@ -27,7 +28,7 @@ impl Default for HandTrackingPlugin {

impl Plugin for HandTrackingPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, locate_hands.run_if(session_running));
app.add_systems(PreUpdate, locate_hands.run_if(openxr_session_running));
if self.default_hands {
app.add_systems(XrPreDestroySession, clean_up_default_hands)
.add_systems(XrSessionCreated, spawn_default_hands);
Expand All @@ -49,6 +50,7 @@ pub fn spawn_hand_bones<T: Bundle + Clone>(
bone,
HandBoneRadius(0.0),
OxrSpaceLocationFlags(openxr::SpaceLocationFlags::default()),
XrSpaceLocationFlags::default(),
))
.insert(bundle.clone())
.id();
Expand Down Expand Up @@ -140,7 +142,9 @@ fn locate_hands(
&mut Transform,
Option<&mut XrVelocity>,
&mut OxrSpaceLocationFlags,
&mut XrSpaceLocationFlags,
Option<&mut OxrSpaceVelocityFlags>,
Option<&mut XrSpaceVelocityFlags>,
)>,
pipelined: Option<Res<Pipelined>>,
) {
Expand All @@ -161,13 +165,21 @@ fn locate_hands(
let ref_space = ref_space.map(|v| &v.0).unwrap_or(&default_ref_space.0);
let mut clear_flags = || {
for e in hand_entities.0.iter() {
let Ok((_, _, _, _, mut flags, vel_flags)) = bone_query.get_mut(*e) else {
let Ok((_, _, _, _, mut flags, mut xr_flags, vel_flags, xr_vel_flags)) =
bone_query.get_mut(*e)
else {
continue;
};
flags.0 = SpaceLocationFlags::EMPTY;
if let Some(mut flags) = vel_flags {
flags.0 = SpaceVelocityFlags::EMPTY;
}
xr_flags.position_tracked = false;
xr_flags.rotation_tracked = false;
if let Some(mut flags) = xr_vel_flags {
flags.linear_valid = false;
flags.angular_valid = false;
}
}
};
let (joints, vels) = if wants_velocities {
Expand Down Expand Up @@ -217,8 +229,16 @@ fn locate_hands(
continue;
}
};
for (bone, mut bone_radius, mut transform, velocity, mut location_flags, velocity_flags) in
bone_entities
for (
bone,
mut bone_radius,
mut transform,
velocity,
mut location_flags,
mut xr_location_flags,
velocity_flags,
xr_velocity_flags,
) in bone_entities
{
let joint = joints[*bone as usize];
if let Some(mut velocity) = velocity {
Expand All @@ -230,6 +250,10 @@ fn locate_hands(
error!("somehow got a hand bone with an XrVelocity component, but without velocity flags");
continue;
};
let Some(mut xr_vel_flags) = xr_velocity_flags else {
error!("somehow got a hand bone with an XrVelocity component, but without velocity flags");
continue;
};
let vel = vels[*bone as usize];
let flags = OxrSpaceVelocityFlags(vel.velocity_flags);
if flags.linear_valid() {
Expand All @@ -238,6 +262,8 @@ fn locate_hands(
if flags.angular_valid() {
velocity.angular = vel.angular_velocity.to_vec3();
}
xr_vel_flags.linear_valid = flags.linear_valid();
xr_vel_flags.angular_valid = flags.angular_valid();
*vel_flags = flags;
}

Expand All @@ -255,6 +281,8 @@ fn locate_hands(
transform.rotation.z = joint.pose.orientation.z;
transform.rotation.w = joint.pose.orientation.w;
}
xr_location_flags.position_tracked = flags.pos_valid() && flags.pos_tracked();
xr_location_flags.rotation_tracked = flags.rot_valid() && flags.rot_tracked();
*location_flags = flags;
}
}
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_openxr/src/openxr/features/overlay.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{mem, ptr};

use bevy::prelude::*;
use bevy_mod_xr::session::session_available;
use openxr::sys;

use crate::{
next_chain::{OxrNextChainStructBase, OxrNextChainStructProvider},
openxr::exts::OxrEnabledExtensions,
openxr_session_available,
session::{OxrSessionCreateNextChain, OxrSessionCreateNextProvider},
};

Expand All @@ -16,7 +16,10 @@ impl Plugin for OxrOverlayPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_event::<OxrOverlaySessionEvent>();
app.init_resource::<OxrOverlaySettings>();
app.add_systems(First, add_overlay_info_to_chain.run_if(session_available));
app.add_systems(
First,
add_overlay_info_to_chain.run_if(openxr_session_available),
);
}
}

Expand Down
2 changes: 0 additions & 2 deletions crates/bevy_openxr/src/openxr/init.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::sync::atomic::Ordering;
use std::sync::Arc;

use bevy::ecs::system::RunSystemOnce;
use bevy::prelude::*;
use bevy::render::extract_resource::ExtractResource;
use bevy::render::extract_resource::ExtractResourcePlugin;
use bevy::render::renderer::RenderAdapter;
use bevy::render::renderer::RenderAdapterInfo;
Expand Down
22 changes: 21 additions & 1 deletion crates/bevy_openxr/src/openxr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// use actions::XrActionPlugin;
use bevy::{
app::{PluginGroup, PluginGroupBuilder},
prelude::Res,
render::RenderPlugin,
utils::default,
window::{PresentMode, Window, WindowPlugin},
};
use bevy_mod_xr::camera::XrCameraPlugin;
use bevy_mod_xr::session::XrSessionPlugin;
use bevy_mod_xr::{camera::XrCameraPlugin, session::XrState};
use init::OxrInitPlugin;
use render::OxrRenderPlugin;
use resources::OxrInstance;
use session::OxrSession;

use self::{
features::{handtracking::HandTrackingPlugin, passthrough::OxrPassthroughPlugin},
Expand All @@ -33,6 +36,23 @@ pub mod session;
pub mod spaces;
pub mod types;

/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the OpenXR session is available.
pub fn openxr_session_available(
status: Option<Res<XrState>>,
instance: Option<Res<OxrInstance>>,
) -> bool {
status.is_some_and(|s| *s != XrState::Unavailable) && instance.is_some()
}

/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the OpenXR is running.
/// use this when working with OpenXR specific things
pub fn openxr_session_running(
status: Option<Res<XrState>>,
session: Option<Res<OxrSession>>,
) -> bool {
matches!(status.as_deref(), Some(XrState::Running)) & session.is_some()
}

pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder {
plugins
.build()
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_openxr/src/openxr/reference_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy_mod_xr::{
spaces::{XrPrimaryReferenceSpace, XrReferenceSpace},
};

use crate::{init::create_xr_session, session::OxrSession};
use crate::session::OxrSession;

pub struct OxrReferenceSpacePlugin {
pub default_primary_ref_space: openxr::ReferenceSpaceType,
Expand Down
37 changes: 28 additions & 9 deletions crates/bevy_openxr/src/openxr/spaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use std::{mem::MaybeUninit, ptr, sync::Mutex};

use bevy::{prelude::*, utils::hashbrown::HashSet};
use bevy_mod_xr::{
session::{session_available, session_running, XrFirst, XrHandleEvents},
spaces::{XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrVelocity},
session::{XrFirst, XrHandleEvents},
spaces::{
XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpaceLocationFlags,
XrSpaceVelocityFlags, XrVelocity,
},
types::XrPose,
};
use openxr::{
Expand All @@ -13,6 +16,7 @@ use openxr::{

use crate::{
helper_traits::{ToPosef, ToQuat, ToVec3},
openxr_session_available, openxr_session_running,
resources::{OxrFrameState, OxrInstance, Pipelined},
session::OxrSession,
};
Expand All @@ -24,7 +28,10 @@ pub struct OxrSpaceSyncSet;
pub struct OxrSpacePatchingPlugin;
impl Plugin for OxrSpacePatchingPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, patch_destroy_space.run_if(session_available));
app.add_systems(
Startup,
patch_destroy_space.run_if(openxr_session_available),
);
}
}

Expand All @@ -36,13 +43,13 @@ impl Plugin for OxrSpatialPlugin {
XrFirst,
destroy_space_event
.before(XrHandleEvents::Poll)
.run_if(session_available),
.run_if(openxr_session_available),
)
.add_systems(
PreUpdate,
update_space_transforms
.in_set(OxrSpaceSyncSet)
.run_if(session_running),
.run_if(openxr_session_running),
)
.observe(add_location_flags)
.observe(add_velocity_flags);
Expand Down Expand Up @@ -151,16 +158,20 @@ fn update_space_transforms(
Option<&mut XrVelocity>,
Option<&XrReferenceSpace>,
&mut OxrSpaceLocationFlags,
&mut XrSpaceLocationFlags,
Option<&mut OxrSpaceVelocityFlags>,
Option<&mut XrSpaceVelocityFlags>,
)>,
) {
for (
mut transform,
space,
velocity,
ref_space,
mut space_location_flags,
space_velocity_flags,
mut oxr_space_location_flags,
mut xr_space_location_flags,
oxr_space_velocity_flags,
xr_space_velocity_flags,
) in &mut query
{
let ref_space = ref_space.unwrap_or(&default_ref_space);
Expand All @@ -182,11 +193,17 @@ fn update_space_transforms(
if flags.linear_valid() {
velocity.linear = space_velocity.linear_velocity.to_vec3();
}
let Some(mut vel_flags) = space_velocity_flags else {
let Some(mut vel_flags) = oxr_space_velocity_flags else {
error!("XrVelocity without OxrSpaceVelocityFlags");
return;
};
let Some(mut xr_vel_flags) = xr_space_velocity_flags else {
error!("XrVelocity without XrSpaceVelocityFlags");
return;
};
*vel_flags = flags;
xr_vel_flags.linear_valid = vel_flags.linear_valid();
xr_vel_flags.angular_valid = vel_flags.angular_valid();
Ok(location)
}
Err(err) => Err(err),
Expand All @@ -202,7 +219,9 @@ fn update_space_transforms(
if flags.rot_valid() {
transform.rotation = space_location.pose.orientation.to_quat();
}
*space_location_flags = flags;
*oxr_space_location_flags = flags;
xr_space_location_flags.position_tracked = flags.pos_valid() && flags.pos_tracked();
xr_space_location_flags.rotation_tracked = flags.rot_valid() && flags.rot_tracked();
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_xr/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ pub fn status_changed_to(
}

/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is available. Returns true as long as [`XrState`] exists and isn't [`Unavailable`](XrStatus::Unavailable).
/// When using backend specific resources use the backend specific condition
pub fn session_available(status: Option<Res<XrState>>) -> bool {
status.is_some_and(|s| *s != XrState::Unavailable)
}
Expand All @@ -282,7 +283,8 @@ pub fn session_ready_or_running(status: Option<Res<XrState>>) -> bool {
matches!(status.as_deref(), Some(XrState::Ready | XrState::Running))
}

/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is running
/// A [`Condition`](bevy::ecs::schedule::Condition) system that says if the XR session is running.
/// When using backend specific resources use the backend specific condition
pub fn session_running(status: Option<Res<XrState>>) -> bool {
matches!(status.as_deref(), Some(XrState::Running))
}
Expand Down
Loading

0 comments on commit 302a455

Please sign in to comment.