From d0f2b01a06ffe904faad14ae314f69773190800e Mon Sep 17 00:00:00 2001 From: ForTehLose Date: Tue, 3 Sep 2024 14:05:45 -0400 Subject: [PATCH] added an emulated local floor --- .../bevy_openxr/examples/common_entities.rs | 104 +++++++++++++++++- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/crates/bevy_openxr/examples/common_entities.rs b/crates/bevy_openxr/examples/common_entities.rs index 20c3da1..4c7ae4b 100644 --- a/crates/bevy_openxr/examples/common_entities.rs +++ b/crates/bevy_openxr/examples/common_entities.rs @@ -8,13 +8,14 @@ use bevy_mod_openxr::{ action_set_attaching::OxrAttachActionSet, action_set_syncing::{OxrActionSetSyncSet, OxrSyncActionSet}, add_xr_plugins, - resources::OxrInstance, + helper_traits::{ToQuat, ToVec3}, + resources::{OxrFrameState, OxrInstance, Pipelined}, session::OxrSession, - spaces::OxrSpaceExt, + spaces::{OxrSpaceExt, OxrSpaceLocationFlags, OxrSpaceSyncSet, OxrSpaceVelocityFlags}, }; use bevy_mod_xr::{ session::{session_available, session_running, XrSessionCreated, XrTrackingRoot}, - spaces::XrSpace, + spaces::{XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrVelocity}, types::XrPose, }; use openxr::Posef; @@ -37,6 +38,16 @@ fn main() { app.add_systems(XrSessionCreated, attach_set); app.add_systems(Startup, create_actions.run_if(session_available)); + //head space + app.add_systems( + PreUpdate, + update_head_transforms + .in_set(OxrSpaceSyncSet) + .run_if(session_running), + ); + //local floor emulated + app.add_systems(PreUpdate, update_local_floor.after(update_head_transforms)); + app.run(); } @@ -163,6 +174,91 @@ fn spawn_hands( right_space, )) .id(); + //head? + let head_space = session + .create_reference_space(openxr::ReferenceSpaceType::VIEW, Transform::IDENTITY) + .unwrap(); + let head = cmds + .spawn(( + PbrBundle { + mesh: meshes.add(Cuboid::new(0.2, 0.2, 0.2)), + material: materials.add(Color::srgb_u8(255, 144, 144)), + transform: Transform::from_xyz(0.0, 0.0, 0.0), + ..default() + }, + HeadXRSpace(head_space), + )) + .id(); + //local_floor? emulated + let local_floor = cmds + .spawn(( + PbrBundle { + mesh: meshes.add(Cuboid::new(0.5, 0.1, 0.5)), + material: materials.add(Color::srgb_u8(144, 255, 144)), + transform: Transform::from_xyz(0.0, 0.0, 0.0), + ..default() + }, + LocalFloor, + )) + .id(); - cmds.entity(root.single()).push_children(&[left, right]); + cmds.entity(root.single()) + .push_children(&[left, right, head, local_floor]); +} + +#[derive(Component)] +struct HeadXRSpace(XrReferenceSpace); + +#[allow(clippy::type_complexity)] +fn update_head_transforms( + session: Res, + default_ref_space: Res, + pipelined: Option>, + frame_state: Res, + mut query: Query<(&mut Transform, &HeadXRSpace, Option<&XrReferenceSpace>)>, +) { + for (mut transform, space, ref_space) in &mut query { + let ref_space = ref_space.unwrap_or(&default_ref_space); + let time = if pipelined.is_some() { + openxr::Time::from_nanos( + frame_state.predicted_display_time.as_nanos() + + frame_state.predicted_display_period.as_nanos(), + ) + } else { + frame_state.predicted_display_time + }; + let space_location = session.locate_space(&space.0, ref_space, time); + + if let Ok(space_location) = space_location { + let flags = OxrSpaceLocationFlags(space_location.location_flags); + if flags.pos_valid() { + transform.translation = space_location.pose.position.to_vec3(); + } + if flags.rot_valid() { + transform.rotation = space_location.pose.orientation.to_quat(); + } + } + } +} + +//emulated local_floor +#[derive(Component)] +struct LocalFloor; + +fn update_local_floor( + mut headSpace: Query<&mut Transform, (With, Without)>, + mut local_floor: Query<&mut Transform, (With, Without)>, +) { + let head_transform = headSpace.get_single_mut(); + match head_transform { + Ok(head) => { + let mut calc_floor = head.clone(); + calc_floor.translation.y = 0.0; + calc_floor.rotation = Quat::IDENTITY; + for (mut transform) in &mut local_floor { + *transform = calc_floor; + } + } + Err(_) => (), + } }