added an emulated local floor
This commit is contained in:
@@ -8,13 +8,14 @@ use bevy_mod_openxr::{
|
|||||||
action_set_attaching::OxrAttachActionSet,
|
action_set_attaching::OxrAttachActionSet,
|
||||||
action_set_syncing::{OxrActionSetSyncSet, OxrSyncActionSet},
|
action_set_syncing::{OxrActionSetSyncSet, OxrSyncActionSet},
|
||||||
add_xr_plugins,
|
add_xr_plugins,
|
||||||
resources::OxrInstance,
|
helper_traits::{ToQuat, ToVec3},
|
||||||
|
resources::{OxrFrameState, OxrInstance, Pipelined},
|
||||||
session::OxrSession,
|
session::OxrSession,
|
||||||
spaces::OxrSpaceExt,
|
spaces::{OxrSpaceExt, OxrSpaceLocationFlags, OxrSpaceSyncSet, OxrSpaceVelocityFlags},
|
||||||
};
|
};
|
||||||
use bevy_mod_xr::{
|
use bevy_mod_xr::{
|
||||||
session::{session_available, session_running, XrSessionCreated, XrTrackingRoot},
|
session::{session_available, session_running, XrSessionCreated, XrTrackingRoot},
|
||||||
spaces::XrSpace,
|
spaces::{XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrVelocity},
|
||||||
types::XrPose,
|
types::XrPose,
|
||||||
};
|
};
|
||||||
use openxr::Posef;
|
use openxr::Posef;
|
||||||
@@ -37,6 +38,16 @@ fn main() {
|
|||||||
app.add_systems(XrSessionCreated, attach_set);
|
app.add_systems(XrSessionCreated, attach_set);
|
||||||
app.add_systems(Startup, create_actions.run_if(session_available));
|
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();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +174,91 @@ fn spawn_hands(
|
|||||||
right_space,
|
right_space,
|
||||||
))
|
))
|
||||||
.id();
|
.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<OxrSession>,
|
||||||
|
default_ref_space: Res<XrPrimaryReferenceSpace>,
|
||||||
|
pipelined: Option<Res<Pipelined>>,
|
||||||
|
frame_state: Res<OxrFrameState>,
|
||||||
|
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<HeadXRSpace>, Without<LocalFloor>)>,
|
||||||
|
mut local_floor: Query<&mut Transform, (With<LocalFloor>, Without<HeadXRSpace>)>,
|
||||||
|
) {
|
||||||
|
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(_) => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user