remove XrSpatialTransform in favor of making XrSpace a Component and adding XrSpatialOffset

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2024-06-23 00:07:28 +02:00
parent 6003cc7ac6
commit b7c4a05482
5 changed files with 47 additions and 34 deletions

View File

@@ -13,7 +13,7 @@ use bevy_openxr::{
}; };
use bevy_xr::{ use bevy_xr::{
session::{session_available, XrSessionCreated}, session::{session_available, XrSessionCreated},
spaces::{XrSpace, XrSpatialTransform}, spaces::XrSpace,
types::XrPose, types::XrPose,
}; };
use openxr::Posef; use openxr::Posef;
@@ -136,7 +136,7 @@ fn spawn_hands(
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default() ..default()
}, },
XrSpatialTransform::from_space(left_space), left_space,
Controller, Controller,
)) ))
.id(); .id();
@@ -148,7 +148,7 @@ fn spawn_hands(
transform: Transform::from_xyz(0.0, 0.5, 0.0), transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default() ..default()
}, },
XrSpatialTransform::from_space(right_space), right_space,
Controller, Controller,
)) ))
.id(); .id();

View File

@@ -45,7 +45,7 @@ impl ToTransform for openxr::Posef {
impl ToXrPose for openxr::Posef { impl ToXrPose for openxr::Posef {
fn to_xr_pose(&self) -> XrPose { fn to_xr_pose(&self) -> XrPose {
XrPose { XrPose {
position: self.position.to_vec3(), translation: self.position.to_vec3(),
rotation: self.orientation.to_quat(), rotation: self.orientation.to_quat(),
} }
} }
@@ -54,7 +54,7 @@ impl ToPosef for XrPose {
fn to_posef(&self) -> openxr::Posef { fn to_posef(&self) -> openxr::Posef {
openxr::Posef { openxr::Posef {
orientation: self.rotation.to_quaternionf(), orientation: self.rotation.to_quaternionf(),
position: self.position.to_vector3f(), position: self.translation.to_vector3f(),
} }
} }
} }

View File

@@ -3,9 +3,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},
spaces::{ spaces::{XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpatialOffset},
XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpatialTransform,
},
types::XrPose, types::XrPose,
}; };
use openxr::{ use openxr::{
@@ -38,12 +36,12 @@ fn destroy_space_event(instance: Res<OxrInstance>, mut events: EventReader<XrDes
} }
} }
pub static OXR_DO_NOT_CALL_DESTOY_SPACE_FOR: Mutex<Option<HashSet<u64>>> = Mutex::new(None); pub static OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES: Mutex<Option<HashSet<u64>>> = Mutex::new(None);
pub static OXR_ORIGINAL_DESTOY_SPACE: Mutex<Option<openxr::sys::pfn::DestroySpace>> = pub static OXR_ORIGINAL_DESTOY_SPACE: Mutex<Option<openxr::sys::pfn::DestroySpace>> =
Mutex::new(None); Mutex::new(None);
fn patch_destroy_space(instance: ResMut<OxrInstance>) { fn patch_destroy_space(instance: ResMut<OxrInstance>) {
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
.lock() .lock()
.unwrap() .unwrap()
.replace(HashSet::new()); .replace(HashSet::new());
@@ -58,7 +56,7 @@ fn patch_destroy_space(instance: ResMut<OxrInstance>) {
} }
} }
unsafe extern "system" fn patched_destroy_space(space: openxr::sys::Space) -> openxr::sys::Result { unsafe extern "system" fn patched_destroy_space(space: openxr::sys::Space) -> openxr::sys::Result {
if !OXR_DO_NOT_CALL_DESTOY_SPACE_FOR if !OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
.lock() .lock()
.unwrap() .unwrap()
.as_ref() .as_ref()
@@ -82,14 +80,16 @@ fn update_spatial_transforms(
frame_state: Res<OxrFrameState>, frame_state: Res<OxrFrameState>,
mut query: Query<( mut query: Query<(
&mut Transform, &mut Transform,
&XrSpatialTransform, &XrSpace,
Option<&XrSpatialOffset>,
Option<&XrReferenceSpace>, Option<&XrReferenceSpace>,
)>, )>,
) { ) {
for (mut transform, spatial, ref_space) in &mut query { for (mut transform, space, offset, ref_space) in &mut query {
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(
&spatial.space, &space,
ref_space, ref_space,
if pipelined.is_some() { if pipelined.is_some() {
openxr::Time::from_nanos( openxr::Time::from_nanos(
@@ -104,16 +104,15 @@ fn update_spatial_transforms(
.location_flags .location_flags
.contains(SpaceLocationFlags::POSITION_VALID) .contains(SpaceLocationFlags::POSITION_VALID)
{ {
transform.translation = spatial transform.translation = offset
.offset .to_transform()
.transform_point(space_location.pose.position.to_vec3()) .transform_point(space_location.pose.position.to_vec3())
} }
if space_location if space_location
.location_flags .location_flags
.contains(SpaceLocationFlags::ORIENTATION_VALID) .contains(SpaceLocationFlags::ORIENTATION_VALID)
{ {
transform.rotation = transform.rotation = offset.rotation * space_location.pose.orientation.to_quat();
spatial.offset.rotation * space_location.pose.orientation.to_quat();
} }
} }
} }
@@ -287,7 +286,10 @@ pub fn locate_hand_joints_with_velocities(
}) })
} }
} }
pub fn destroy_space(instance: &openxr::Instance, space: sys::Space) -> openxr::Result<sys::Result> { pub fn destroy_space(
instance: &openxr::Instance,
space: sys::Space,
) -> openxr::Result<sys::Result> {
let result = unsafe { (instance.fp().destroy_space)(space) }; let result = unsafe { (instance.fp().destroy_space)(space) };
cvt(result) cvt(result)
} }
@@ -418,7 +420,7 @@ unsafe impl OxrSpaceExt for XrSpace {
fn from_raw_openxr_space(space: sys::Space) -> Self { fn from_raw_openxr_space(space: sys::Space) -> Self {
let raw = space.into_raw(); let raw = space.into_raw();
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
.lock() .lock()
.unwrap() .unwrap()
.as_mut() .as_mut()

View File

@@ -3,21 +3,19 @@ use bevy::{
render::{extract_component::ExtractComponent, extract_resource::ExtractResource}, render::{extract_component::ExtractComponent, extract_resource::ExtractResource},
}; };
use crate::types::XrPose;
/// Any Spaces will be invalid after the owning session exits /// Any Spaces will be invalid after the owning session exits
#[repr(transparent)] #[repr(transparent)]
#[derive(Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug)] #[derive(Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug, Component, ExtractComponent)]
pub struct XrSpace(u64); pub struct XrSpace(u64);
#[derive(Clone, Copy, PartialEq, Reflect, Debug, Component, ExtractComponent)] // Does repr(transparent) even make sense here?
pub struct XrSpatialTransform { #[repr(transparent)]
pub space: XrSpace, #[derive(
pub offset: Transform, Clone, Copy, PartialEq, Reflect, Debug, Component, ExtractComponent, Default, Deref, DerefMut,
} )]
impl XrSpatialTransform { pub struct XrSpatialOffset(pub XrPose);
pub const fn from_space(space: XrSpace) -> Self {
Self { space, offset: Transform::IDENTITY }
}
}
#[derive(Event, Clone, Copy, Deref, DerefMut)] #[derive(Event, Clone, Copy, Deref, DerefMut)]
pub struct XrDestroySpace(pub XrSpace); pub struct XrDestroySpace(pub XrSpace);

View File

@@ -1,13 +1,26 @@
use bevy::math::{Quat, Vec3}; use bevy::{
math::{Quat, Vec3},
reflect::Reflect,
transform::components::Transform,
};
#[derive(Clone, Copy, PartialEq, Reflect, Debug)]
pub struct XrPose { pub struct XrPose {
pub position: Vec3, pub translation: Vec3,
pub rotation: Quat, pub rotation: Quat,
} }
impl Default for XrPose {
fn default() -> Self {
Self::IDENTITY
}
}
impl XrPose { impl XrPose {
pub const IDENTITY: XrPose = XrPose { pub const IDENTITY: XrPose = XrPose {
position: Vec3::ZERO, translation: Vec3::ZERO,
rotation: Quat::IDENTITY, rotation: Quat::IDENTITY,
}; };
pub const fn to_transform(self) -> Transform {
Transform::from_translation(self.translation).with_rotation(self.rotation)
}
} }