fix: offset tracking at startup to center properly
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ mod core;
|
||||
mod nodes;
|
||||
mod objects;
|
||||
mod session;
|
||||
pub mod tracking_offset;
|
||||
#[cfg(feature = "wayland")]
|
||||
mod wayland;
|
||||
|
||||
@@ -70,6 +71,7 @@ use tokio::task::JoinError;
|
||||
use tracing::metadata::LevelFilter;
|
||||
use tracing::{error, info};
|
||||
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
|
||||
use tracking_offset::TrackingOffsetPlugin;
|
||||
use wayland::{Wayland, WaylandPlugin};
|
||||
use zbus::Connection;
|
||||
use zbus::fdo::ObjectManager;
|
||||
@@ -398,7 +400,7 @@ fn bevy_loop(
|
||||
// object plugins
|
||||
app.add_plugins((PlaySpacePlugin, HandPlugin, ControllerPlugin, HmdPlugin));
|
||||
// feature plugins
|
||||
app.add_plugins(WaylandPlugin);
|
||||
app.add_plugins((WaylandPlugin, TrackingOffsetPlugin));
|
||||
app.add_systems(PostStartup, move || {
|
||||
ready_notifier.notify_waiters();
|
||||
});
|
||||
|
||||
82
src/tracking_offset.rs
Normal file
82
src/tracking_offset.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
use bevy::{
|
||||
app::{Plugin, Update},
|
||||
ecs::{
|
||||
resource::Resource,
|
||||
schedule::{Condition, IntoScheduleConfigs, common_conditions::resource_exists},
|
||||
system::{Commands, Res, ResMut},
|
||||
},
|
||||
transform::components::Transform,
|
||||
};
|
||||
use bevy_mod_openxr::{
|
||||
helper_traits::ToTransform as _,
|
||||
poll_events::{OxrEventHandlerExt, OxrEventIn},
|
||||
resources::OxrFrameState,
|
||||
session::OxrSession,
|
||||
};
|
||||
use bevy_mod_xr::{session::XrSessionCreated, spaces::XrPrimaryReferenceSpace};
|
||||
use glam::{Quat, Vec3};
|
||||
use openxr::ReferenceSpaceType;
|
||||
|
||||
pub struct TrackingRootOffsetPlugin;
|
||||
|
||||
impl Plugin for TrackingRootOffsetPlugin {
|
||||
fn build(&self, app: &mut bevy::app::App) {
|
||||
app.add_oxr_event_handler(reset_offset);
|
||||
app.add_systems(XrSessionCreated, |mut cmds: Commands| {
|
||||
cmds.insert_resource(OffsetTag);
|
||||
});
|
||||
app.add_systems(
|
||||
Update,
|
||||
offset.run_if(resource_exists::<OffsetTag>.and(resource_exists::<OxrFrameState>)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct OffsetTag;
|
||||
|
||||
fn reset_offset(
|
||||
oxr_event: OxrEventIn,
|
||||
mut ref_space: ResMut<XrPrimaryReferenceSpace>,
|
||||
session: Res<OxrSession>,
|
||||
) {
|
||||
if let openxr::Event::ReferenceSpaceChangePending(v) = *oxr_event
|
||||
&& v.reference_space_type() == ReferenceSpaceType::LOCAL
|
||||
{
|
||||
let space = session
|
||||
.create_reference_space(ReferenceSpaceType::LOCAL, Transform::IDENTITY)
|
||||
.unwrap();
|
||||
session.destroy_space(ref_space.0.0).unwrap();
|
||||
ref_space.0 = space;
|
||||
}
|
||||
}
|
||||
|
||||
fn offset(
|
||||
session: Res<OxrSession>,
|
||||
state: Res<OxrFrameState>,
|
||||
mut primary_ref_space: ResMut<XrPrimaryReferenceSpace>,
|
||||
mut cmds: Commands,
|
||||
) {
|
||||
cmds.remove_resource::<OffsetTag>();
|
||||
let local = session
|
||||
.create_reference_space(ReferenceSpaceType::LOCAL, Transform::IDENTITY)
|
||||
.unwrap();
|
||||
let view = session
|
||||
.create_reference_space(ReferenceSpaceType::VIEW, Transform::IDENTITY)
|
||||
.unwrap();
|
||||
let view_pose = session
|
||||
.locate_space(&view, &local, state.predicted_display_time)
|
||||
.unwrap()
|
||||
.pose
|
||||
.to_transform();
|
||||
let offset = view_pose.with_rotation(Quat::from_axis_angle(
|
||||
Vec3::Y,
|
||||
view_pose.rotation.to_euler(glam::EulerRot::XYZ).1,
|
||||
));
|
||||
let offset = Transform::from_matrix(offset.compute_matrix());
|
||||
let local_offset = session
|
||||
.create_reference_space(ReferenceSpaceType::LOCAL, offset)
|
||||
.unwrap();
|
||||
session.destroy_space(primary_ref_space.0.0).unwrap();
|
||||
primary_ref_space.0 = local_offset;
|
||||
}
|
||||
Reference in New Issue
Block a user