@@ -52,6 +52,7 @@ pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder {
|
|||||||
.add(action_set_syncing::OxrActionSyncingPlugin)
|
.add(action_set_syncing::OxrActionSyncingPlugin)
|
||||||
.add(features::overlay::OxrOverlayPlugin)
|
.add(features::overlay::OxrOverlayPlugin)
|
||||||
.add(spaces::OxrSpatialPlugin)
|
.add(spaces::OxrSpatialPlugin)
|
||||||
|
.add(spaces::OxrSpacePatchingPlugin)
|
||||||
// .add(XrActionPlugin)
|
// .add(XrActionPlugin)
|
||||||
// we should probably handle the exiting ourselfs so that we can correctly end the
|
// we should probably handle the exiting ourselfs so that we can correctly end the
|
||||||
// session and instance
|
// session and instance
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ use bevy::{
|
|||||||
render::{
|
render::{
|
||||||
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
extract_resource::{ExtractResource, ExtractResourcePlugin},
|
||||||
RenderApp,
|
RenderApp,
|
||||||
},
|
}, utils::HashSet,
|
||||||
};
|
};
|
||||||
use bevy_xr::{
|
use bevy_xr::{
|
||||||
session::{XrSessionCreated, XrSessionExiting},
|
session::{XrSessionCreated, XrSessionExiting},
|
||||||
spaces::{XrPrimaryReferenceSpace, XrReferenceSpace},
|
spaces::{XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::session::OxrSession;
|
use crate::{resources::OxrInstance, session::OxrSession};
|
||||||
|
|
||||||
pub struct OxrReferenceSpacePlugin {
|
pub struct OxrReferenceSpacePlugin {
|
||||||
pub default_primary_ref_space: openxr::ReferenceSpaceType,
|
pub default_primary_ref_space: openxr::ReferenceSpaceType,
|
||||||
@@ -48,10 +48,23 @@ impl Plugin for OxrReferenceSpacePlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cleanup(mut cmds: Commands, query: Query<Entity, With<XrReferenceSpace>>) {
|
fn cleanup(
|
||||||
|
query: Query<(Entity, &XrReferenceSpace)>,
|
||||||
|
mut cmds: Commands,
|
||||||
|
instance: Res<OxrInstance>,
|
||||||
|
ref_space: Option<Res<XrPrimaryReferenceSpace>>,
|
||||||
|
) {
|
||||||
|
let mut to_destroy = HashSet::<XrSpace>::new();
|
||||||
|
if let Some(space) = ref_space {
|
||||||
|
to_destroy.insert(***space);
|
||||||
|
}
|
||||||
cmds.remove_resource::<XrPrimaryReferenceSpace>();
|
cmds.remove_resource::<XrPrimaryReferenceSpace>();
|
||||||
for e in &query {
|
for (e, space) in &query {
|
||||||
cmds.entity(e).remove::<XrReferenceSpace>();
|
cmds.entity(e).remove::<XrReferenceSpace>();
|
||||||
|
to_destroy.insert(**space);
|
||||||
|
}
|
||||||
|
for space in to_destroy.into_iter() {
|
||||||
|
let _ = instance.destroy_space(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::{mem::MaybeUninit, ptr, sync::Mutex};
|
|||||||
|
|
||||||
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
||||||
use bevy_xr::{
|
use bevy_xr::{
|
||||||
session::{session_available, session_running},
|
session::{session_available, session_running, XrSessionExiting},
|
||||||
spaces::{XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpatialOffset},
|
spaces::{XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpatialOffset},
|
||||||
types::XrPose,
|
types::XrPose,
|
||||||
};
|
};
|
||||||
@@ -18,20 +18,43 @@ use crate::{
|
|||||||
session::OxrSession,
|
session::OxrSession,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// VERY IMPORTENT!! only disable when you know what you are doing
|
||||||
|
pub struct OxrSpacePatchingPlugin;
|
||||||
|
impl Plugin for OxrSpacePatchingPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(Startup, patch_destroy_space.run_if(session_available));
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct OxrSpatialPlugin;
|
pub struct OxrSpatialPlugin;
|
||||||
impl Plugin for OxrSpatialPlugin {
|
impl Plugin for OxrSpatialPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_event::<XrDestroySpace>();
|
app.add_event::<XrDestroySpace>();
|
||||||
app.add_systems(PreUpdate, update_spatial_transforms.run_if(session_running));
|
|
||||||
app.add_systems(Startup, patch_destroy_space.run_if(session_available));
|
app.add_systems(Startup, patch_destroy_space.run_if(session_available));
|
||||||
app.add_systems(OxrLast, destroy_space_event.before(OxrHandleEvents));
|
app.add_systems(OxrLast, destroy_space_event.before(OxrHandleEvents));
|
||||||
|
app.add_systems(XrSessionExiting, destroy_space_components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy_space_components(
|
||||||
|
query: Query<(Entity, &XrSpace)>,
|
||||||
|
mut cmds: Commands,
|
||||||
|
mut sender: EventWriter<XrDestroySpace>,
|
||||||
|
) {
|
||||||
|
let mut to_destroy = HashSet::<XrSpace>::new();
|
||||||
|
for (e, space) in &query {
|
||||||
|
to_destroy.insert(*space);
|
||||||
|
cmds.entity(e).remove::<XrSpace>();
|
||||||
|
}
|
||||||
|
for space in to_destroy.into_iter() {
|
||||||
|
sender.send(XrDestroySpace(space));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_space_event(instance: Res<OxrInstance>, mut events: EventReader<XrDestroySpace>) {
|
fn destroy_space_event(instance: Res<OxrInstance>, mut events: EventReader<XrDestroySpace>) {
|
||||||
for space in events.read() {
|
for space in events.read() {
|
||||||
unsafe {
|
match instance.destroy_space(space.0) {
|
||||||
(instance.fp().destroy_space)(space.as_raw_openxr_space());
|
Ok(_) => (),
|
||||||
|
Err(err) => warn!("error while destroying space: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +112,7 @@ fn update_spatial_transforms(
|
|||||||
let offset = offset.copied().unwrap_or_default();
|
let offset = offset.copied().unwrap_or_default();
|
||||||
let ref_space = ref_space.unwrap_or(&default_ref_space);
|
let ref_space = ref_space.unwrap_or(&default_ref_space);
|
||||||
if let Ok(space_location) = session.locate_space(
|
if let Ok(space_location) = session.locate_space(
|
||||||
&space,
|
space,
|
||||||
ref_space,
|
ref_space,
|
||||||
if pipelined.is_some() {
|
if pipelined.is_some() {
|
||||||
openxr::Time::from_nanos(
|
openxr::Time::from_nanos(
|
||||||
@@ -290,15 +313,29 @@ pub fn destroy_space(
|
|||||||
instance: &openxr::Instance,
|
instance: &openxr::Instance,
|
||||||
space: sys::Space,
|
space: sys::Space,
|
||||||
) -> openxr::Result<sys::Result> {
|
) -> openxr::Result<sys::Result> {
|
||||||
|
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&space.into_raw());
|
||||||
let result = unsafe { (instance.fp().destroy_space)(space) };
|
let result = unsafe { (instance.fp().destroy_space)(space) };
|
||||||
cvt(result)
|
cvt(result)
|
||||||
}
|
}
|
||||||
impl OxrSession {
|
impl OxrSession {
|
||||||
pub fn destroy_space(&self, space: XrSpace) {
|
pub fn allow_auto_destruct_of_openxr_space(&self, space: &openxr::Space) {
|
||||||
let _ = destroy_space(self.instance(), space.as_raw_openxr_space());
|
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&space.as_raw().into_raw());
|
||||||
}
|
}
|
||||||
pub fn destroy_openxr_space(&self, space: openxr::Space) {
|
pub fn destroy_space(&self, space: XrSpace) -> openxr::Result<sys::Result> {
|
||||||
let _ = destroy_space(self.instance(), space.as_raw());
|
destroy_space(self.instance(), space.as_raw_openxr_space())
|
||||||
|
}
|
||||||
|
pub fn destroy_openxr_space(&self, space: openxr::Space) -> openxr::Result<sys::Result> {
|
||||||
|
destroy_space(self.instance(), space.as_raw())
|
||||||
}
|
}
|
||||||
pub fn locate_views(
|
pub fn locate_views(
|
||||||
&self,
|
&self,
|
||||||
@@ -368,6 +405,20 @@ impl OxrSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl OxrInstance {
|
impl OxrInstance {
|
||||||
|
pub fn allow_auto_destruct_of_openxr_space(&self, space: &openxr::Space) {
|
||||||
|
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&space.as_raw().into_raw());
|
||||||
|
}
|
||||||
|
pub fn destroy_space(&self, space: XrSpace) -> openxr::Result<sys::Result> {
|
||||||
|
destroy_space(self, space.as_raw_openxr_space())
|
||||||
|
}
|
||||||
|
pub fn destroy_openxr_space(&self, space: openxr::Space) -> openxr::Result<sys::Result> {
|
||||||
|
destroy_space(self, space.as_raw())
|
||||||
|
}
|
||||||
pub fn locate_space(
|
pub fn locate_space(
|
||||||
&self,
|
&self,
|
||||||
space: &XrSpace,
|
space: &XrSpace,
|
||||||
|
|||||||
Reference in New Issue
Block a user