feat(bevy_xr_utils): add GenericTracker component and implement XR_MNDX_xdev_space as a backend
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
23
crates/bevy_xr_utils/src/generic_tracker.rs
Normal file
23
crates/bevy_xr_utils/src/generic_tracker.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use bevy::{color::palettes::css, prelude::*};
|
||||
|
||||
#[derive(Clone, Copy, Component)]
|
||||
#[require(Transform)]
|
||||
pub struct GenericTracker;
|
||||
|
||||
pub struct GenericTrackerGizmoPlugin;
|
||||
|
||||
impl Plugin for GenericTrackerGizmoPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
draw_gizmos.after(TransformSystem::TransformPropagate),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_gizmos(query: Query<&GlobalTransform, With<GenericTracker>>, mut gizmos: Gizmos) {
|
||||
for transform in query {
|
||||
gizmos.axes(*transform, 0.05);
|
||||
gizmos.sphere(transform.to_isometry(), 0.05, css::PINK);
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,5 @@ pub mod tracking_utils;
|
||||
pub mod transform_utils;
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
pub mod xr_utils_actions;
|
||||
pub mod generic_tracker;
|
||||
pub mod mndx_xdev_spaces_trackers;
|
||||
|
||||
119
crates/bevy_xr_utils/src/mndx_xdev_spaces_trackers.rs
Normal file
119
crates/bevy_xr_utils/src/mndx_xdev_spaces_trackers.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use std::convert::identity;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_mod_openxr::{
|
||||
resources::{OxrInstance, OxrSystemId},
|
||||
session::OxrSession,
|
||||
spaces::OxrSpaceExt,
|
||||
};
|
||||
use bevy_mod_xr::{
|
||||
session::{XrPreDestroySession, XrSessionCreated},
|
||||
spaces::XrSpace,
|
||||
};
|
||||
use openxr_mndx_xdev_space::{InstanceXDevExtensionMNDX, SessionXDevExtensionMNDX, XDev, XDevList};
|
||||
|
||||
use crate::generic_tracker::GenericTracker;
|
||||
|
||||
pub struct MonadoXDevSpacesPlugin;
|
||||
impl Plugin for MonadoXDevSpacesPlugin {
|
||||
fn build(&self, _app: &mut App) {}
|
||||
fn finish(&self, app: &mut App) {
|
||||
let Some((instance, system_id)) =
|
||||
app.world()
|
||||
.get_resource::<OxrInstance>()
|
||||
.and_then(|instance| {
|
||||
app.world()
|
||||
.get_resource::<OxrSystemId>()
|
||||
.map(|system_id| (instance, system_id))
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
if !instance
|
||||
.supports_mndx_xdev_spaces(**system_id)
|
||||
.is_ok_and(identity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
app.add_systems(XrSessionCreated, session_created);
|
||||
app.add_systems(PreUpdate, update_xdev_list);
|
||||
app.add_systems(
|
||||
XrPreDestroySession,
|
||||
(despawn_xdev_trackers, |mut cmds: Commands| {
|
||||
cmds.remove_resource::<PrimaryXDevList>()
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn update_xdev_list(mut xdev_list: ResMut<PrimaryXDevList>, mut cmds: Commands) {
|
||||
let Ok(new_gen) = xdev_list
|
||||
.get_generation()
|
||||
.inspect_err(|err| error!("unable to get xdev list generation: {err}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
if new_gen != xdev_list.generation {
|
||||
xdev_list.generation = new_gen;
|
||||
cmds.run_system_cached(despawn_xdev_trackers);
|
||||
cmds.run_system_cached(create_xdev_trackers);
|
||||
}
|
||||
}
|
||||
|
||||
fn session_created(session: Res<OxrSession>, mut cmds: Commands) {
|
||||
let list = match session.get_xdev_list() {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
error!("unable to create xdev list: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
cmds.insert_resource(PrimaryXDevList {
|
||||
generation: list.get_generation().unwrap(),
|
||||
list,
|
||||
});
|
||||
cmds.run_system_cached(despawn_xdev_trackers);
|
||||
cmds.run_system_cached(create_xdev_trackers);
|
||||
}
|
||||
|
||||
fn despawn_xdev_trackers(
|
||||
xdev_query: Query<(Entity, &XrSpace), With<XDevTracker>>,
|
||||
mut cmds: Commands,
|
||||
session: Res<OxrSession>,
|
||||
) {
|
||||
for (e, space) in &xdev_query {
|
||||
cmds.entity(e).despawn();
|
||||
if let Err(err) = session.destroy_space(*space) {
|
||||
error!("unable to destroy xdev XrSpace: {err}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn create_xdev_trackers(xdev_list: Res<PrimaryXDevList>, mut cmds: Commands) {
|
||||
let xdevs = match xdev_list.enumerate_xdevs() {
|
||||
Err(err) => {
|
||||
error!("Unable to enumerate xdevs: {err}");
|
||||
return;
|
||||
}
|
||||
Ok(v) => v,
|
||||
};
|
||||
for xdev in xdevs
|
||||
.into_iter()
|
||||
.filter(XDev::can_create_space)
|
||||
.filter(|v| v.name().contains("Tracker"))
|
||||
{
|
||||
info!("new XDev Tracker: {}", xdev.name());
|
||||
let xr_space =
|
||||
XrSpace::from_openxr_space(xdev.create_space(openxr::Posef::IDENTITY).unwrap());
|
||||
cmds.spawn((xr_space, GenericTracker, XDevTracker));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Component, Debug)]
|
||||
pub struct XDevTracker;
|
||||
#[derive(Deref, DerefMut, Resource)]
|
||||
pub struct PrimaryXDevList {
|
||||
#[deref]
|
||||
pub list: XDevList,
|
||||
pub generation: u64,
|
||||
}
|
||||
Reference in New Issue
Block a user