feat(objects): implement hmd spatial again (i forgor)
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -52,6 +52,7 @@ use nodes::drawable::lines::LinesNodePlugin;
|
|||||||
use nodes::drawable::model::ModelNodePlugin;
|
use nodes::drawable::model::ModelNodePlugin;
|
||||||
use nodes::drawable::text::TextNodePlugin;
|
use nodes::drawable::text::TextNodePlugin;
|
||||||
use nodes::spatial::SpatialNodePlugin;
|
use nodes::spatial::SpatialNodePlugin;
|
||||||
|
use objects::hmd::HmdPlugin;
|
||||||
use objects::input::mouse_pointer::FlatscreenInputPlugin;
|
use objects::input::mouse_pointer::FlatscreenInputPlugin;
|
||||||
use objects::input::oxr_controller::ControllerPlugin;
|
use objects::input::oxr_controller::ControllerPlugin;
|
||||||
use objects::input::oxr_hand::HandPlugin;
|
use objects::input::oxr_hand::HandPlugin;
|
||||||
@@ -173,6 +174,8 @@ async fn main() -> Result<AppExit, JoinError> {
|
|||||||
let dbus_connection = Connection::session()
|
let dbus_connection = Connection::session()
|
||||||
.await
|
.await
|
||||||
.expect("Could not open dbus session");
|
.expect("Could not open dbus session");
|
||||||
|
// why is this requested here? should there be a specific server bus name that we check
|
||||||
|
// instead?
|
||||||
dbus_connection
|
dbus_connection
|
||||||
.request_name("org.stardustxr.HMD")
|
.request_name("org.stardustxr.HMD")
|
||||||
.await
|
.await
|
||||||
@@ -393,7 +396,7 @@ fn bevy_loop(
|
|||||||
AudioNodePlugin,
|
AudioNodePlugin,
|
||||||
));
|
));
|
||||||
// object plugins
|
// object plugins
|
||||||
app.add_plugins((PlaySpacePlugin, HandPlugin, ControllerPlugin));
|
app.add_plugins((PlaySpacePlugin, HandPlugin, ControllerPlugin, HmdPlugin));
|
||||||
// feature plugins
|
// feature plugins
|
||||||
app.add_plugins(WaylandPlugin);
|
app.add_plugins(WaylandPlugin);
|
||||||
app.add_systems(PostStartup, move || {
|
app.add_systems(PostStartup, move || {
|
||||||
|
|||||||
108
src/objects/hmd.rs
Normal file
108
src/objects/hmd.rs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_mod_openxr::{
|
||||||
|
helper_traits::{ToQuat as _, ToVec3 as _},
|
||||||
|
resources::OxrFrameState,
|
||||||
|
session::OxrSession,
|
||||||
|
};
|
||||||
|
use bevy_mod_xr::{
|
||||||
|
session::{XrPreDestroySession, XrSessionCreated, session_running},
|
||||||
|
spaces::{XrPrimaryReferenceSpace, XrSpace},
|
||||||
|
};
|
||||||
|
use openxr::SpaceLocationFlags;
|
||||||
|
|
||||||
|
use crate::{DbusConnection, PreFrameWait, nodes::spatial::Spatial};
|
||||||
|
|
||||||
|
use super::{ObjectHandle, SpatialRef, input::mouse_pointer::FlatscreenCam};
|
||||||
|
|
||||||
|
pub struct HmdPlugin;
|
||||||
|
impl Plugin for HmdPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(XrPreDestroySession, destroy_view_space);
|
||||||
|
app.add_systems(XrSessionCreated, create_view_space);
|
||||||
|
app.add_systems(PreFrameWait, update_xr.run_if(session_running));
|
||||||
|
app.add_systems(PreFrameWait, update_flat.run_if(not(session_running)));
|
||||||
|
app.add_systems(Startup, setup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(connection: Res<DbusConnection>, mut cmds: Commands) {
|
||||||
|
let (spatial, _spatial_handle) = SpatialRef::create(&connection, "/org/stardustxr/HMD");
|
||||||
|
let hmd = Hmd {
|
||||||
|
spatial,
|
||||||
|
_spatial_handle,
|
||||||
|
space: None,
|
||||||
|
};
|
||||||
|
cmds.insert_resource(hmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_view_space(session: Res<OxrSession>, mut hmd: ResMut<Hmd>) {
|
||||||
|
let space = session
|
||||||
|
.create_reference_space(openxr::ReferenceSpaceType::VIEW, Transform::IDENTITY)
|
||||||
|
.inspect_err(|err| error!("failed to create View XrSpace"))
|
||||||
|
.ok();
|
||||||
|
hmd.space = space.map(|v| v.0);
|
||||||
|
}
|
||||||
|
fn destroy_view_space(session: Res<OxrSession>, mut cmds: Commands, mut hmd: ResMut<Hmd>) {
|
||||||
|
let Some(space) = hmd.space.take() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
session.destroy_space(space);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct Hmd {
|
||||||
|
spatial: Arc<Spatial>,
|
||||||
|
_spatial_handle: ObjectHandle<SpatialRef>,
|
||||||
|
space: Option<XrSpace>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_flat(cam: Single<&GlobalTransform, With<FlatscreenCam>>, hmd: Res<Hmd>) {
|
||||||
|
// this shouldn't be parented to anything, so global and local spaces should be the same
|
||||||
|
hmd.spatial.set_local_transform(cam.compute_matrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_xr(
|
||||||
|
session: Option<Res<OxrSession>>,
|
||||||
|
ref_space: Option<Res<XrPrimaryReferenceSpace>>,
|
||||||
|
hmd: Res<Hmd>,
|
||||||
|
state: Option<Res<OxrFrameState>>,
|
||||||
|
) {
|
||||||
|
let (Some(session), Some(view), Some(ref_space), Some(state)) =
|
||||||
|
(session, hmd.space, ref_space, state)
|
||||||
|
else {
|
||||||
|
// tokio::task::spawn({
|
||||||
|
// let handle = hmd.tracked_handle.clone();
|
||||||
|
// async move {
|
||||||
|
// handle.set_tracked(false);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
// this won't be correct with pipelined rendering
|
||||||
|
let location = session
|
||||||
|
.locate_space(&view, &ref_space, state.predicted_display_time)
|
||||||
|
.inspect_err(|err| error!("Error while Locating OpenXR Stage Space {err}"));
|
||||||
|
if let Ok(location) = location {
|
||||||
|
let is_tracked = location
|
||||||
|
.location_flags
|
||||||
|
.contains(SpaceLocationFlags::POSITION_VALID | SpaceLocationFlags::POSITION_TRACKED)
|
||||||
|
|| location.location_flags.contains(
|
||||||
|
SpaceLocationFlags::ORIENTATION_VALID | SpaceLocationFlags::ORIENTATION_TRACKED,
|
||||||
|
);
|
||||||
|
// tokio::task::spawn({
|
||||||
|
// let handle = play_space.tracked_handle.clone();
|
||||||
|
// async move {
|
||||||
|
// handle.set_tracked(is_tracked);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
if is_tracked {
|
||||||
|
hmd.spatial
|
||||||
|
.set_local_transform(Mat4::from_rotation_translation(
|
||||||
|
location.pose.orientation.to_quat(),
|
||||||
|
location.pose.position.to_vec3(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ impl Plugin for FlatscreenInputPlugin {
|
|||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
#[require(Camera3d)]
|
#[require(Camera3d)]
|
||||||
struct FlatscreenCam;
|
pub struct FlatscreenCam;
|
||||||
|
|
||||||
fn setup(mut cmds: Commands) {
|
fn setup(mut cmds: Commands) {
|
||||||
let Ok(pointer) =
|
let Ok(pointer) =
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use zbus::{Connection, interface, object_server::Interface, zvariant::OwnedObjec
|
|||||||
|
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod play_space;
|
pub mod play_space;
|
||||||
|
pub mod hmd;
|
||||||
|
|
||||||
pub struct ObjectHandle<I: Interface>(Connection, OwnedObjectPath, PhantomData<I>);
|
pub struct ObjectHandle<I: Interface>(Connection, OwnedObjectPath, PhantomData<I>);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user