diff --git a/alvr/client_core/src/lib.rs b/alvr/client_core/src/lib.rs index d36cb4f0ba..cd80159ffa 100644 --- a/alvr/client_core/src/lib.rs +++ b/alvr/client_core/src/lib.rs @@ -217,8 +217,8 @@ impl ClientCoreContext { if let Some(sender) = &mut *self.connection_context.control_sender.lock() { sender .send(&ClientControlPacket::ViewsConfig(ViewsConfig { + pose: [views[0].pose, views[1].pose], fov: [views[0].fov, views[1].fov], - ipd_m: (views[0].pose.position - views[1].pose.position).length(), })) .ok(); } diff --git a/alvr/packets/src/lib.rs b/alvr/packets/src/lib.rs index e03bd49606..142c8c2e83 100644 --- a/alvr/packets/src/lib.rs +++ b/alvr/packets/src/lib.rs @@ -216,8 +216,7 @@ pub enum ServerControlPacket { #[derive(Serialize, Deserialize, Clone)] pub struct ViewsConfig { - // Note: the head-to-eye transform is always a translation along the x axis - pub ipd_m: f32, + pub pose: [Pose; 2], pub fov: [Fov; 2], } diff --git a/alvr/server_core/src/connection.rs b/alvr/server_core/src/connection.rs index c7fb50846d..34c1bb708e 100644 --- a/alvr/server_core/src/connection.rs +++ b/alvr/server_core/src/connection.rs @@ -10,12 +10,12 @@ use crate::{ use alvr_adb::{WiredConnection, WiredConnectionStatus}; use alvr_common::{ con_bail, dbg_connection, debug, error, - glam::{Quat, UVec2, Vec2, Vec3}, + glam::{UVec2, Vec2}, info, parking_lot::{Condvar, Mutex, RwLock}, settings_schema::Switch, - warn, AnyhowToCon, ConResult, ConnectionError, ConnectionState, LifecycleState, Pose, - BUTTON_INFO, CONTROLLER_PROFILE_INFO, QUEST_CONTROLLER_PROFILE_PATH, + warn, AnyhowToCon, ConResult, ConnectionError, ConnectionState, LifecycleState, BUTTON_INFO, + CONTROLLER_PROFILE_INFO, QUEST_CONTROLLER_PROFILE_PATH, }; use alvr_events::{AdbEvent, ButtonEvent, EventType}; use alvr_packets::{ @@ -1214,16 +1214,7 @@ fn connection_pipeline( ClientControlPacket::ViewsConfig(config) => { ctx.events_sender .send(ServerCoreEvent::ViewsConfig(ViewsConfig { - local_view_transforms: [ - Pose { - position: Vec3::new(-config.ipd_m / 2., 0., 0.), - orientation: Quat::IDENTITY, - }, - Pose { - position: Vec3::new(config.ipd_m / 2., 0., 0.), - orientation: Quat::IDENTITY, - }, - ], + local_view_transforms: config.pose, fov: config.fov, })) .ok(); diff --git a/alvr/server_openvr/cpp/alvr_server/HMD.cpp b/alvr/server_openvr/cpp/alvr_server/HMD.cpp index 608be70c36..33f92d261a 100644 --- a/alvr/server_openvr/cpp/alvr_server/HMD.cpp +++ b/alvr/server_openvr/cpp/alvr_server/HMD.cpp @@ -18,9 +18,6 @@ #include "platform/linux/CEncoder.h" #endif -const vr::HmdMatrix34_t MATRIX_IDENTITY - = { { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 } } }; - vr::HmdRect2_t fov_to_projection(FfiFov fov) { auto proj_bounds = vr::HmdRect2_t {}; proj_bounds.vTopLeft.v[0] = tanf(fov.left); @@ -31,6 +28,17 @@ vr::HmdRect2_t fov_to_projection(FfiFov fov) { return proj_bounds; } +vr::HmdMatrix34_t pose_to_transform(FfiPose pose) { + vr::HmdMatrix34_t transform; + HmdMatrix_QuatToMat( + pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z, &transform + ); + transform.m[0][3] = pose.position[0]; + transform.m[1][3] = pose.position[1]; + transform.m[2][3] = pose.position[2]; + return transform; +} + Hmd::Hmd() : TrackedDevice( HEAD_ID, @@ -42,11 +50,13 @@ Hmd::Hmd() Debug("Hmd::constructor"); auto dummy_fov = FfiFov { -1.0, 1.0, 1.0, -1.0 }; + auto identity_pose = FfiPose { { 0, 0, 0, 1 }, { 0, 0, 0 } }; this->views_config = FfiViewsConfig {}; - this->views_config.ipd_m = 0.063; this->views_config.fov[0] = dummy_fov; this->views_config.fov[1] = dummy_fov; + this->views_config.pose[0] = identity_pose; + this->views_config.pose[1] = identity_pose; m_poseHistory = std::make_shared(); @@ -286,10 +296,9 @@ void Hmd::SetViewsConfig(FfiViewsConfig config) { // The OpenXR spec defines the HMD position as the midpoint // between the eyes, so conversion to this is handled by the // client. - auto left_transform = MATRIX_IDENTITY; - left_transform.m[0][3] = -config.ipd_m / 2.0; - auto right_transform = MATRIX_IDENTITY; - right_transform.m[0][3] = config.ipd_m / 2.0; + auto left_transform = pose_to_transform(config.pose[0]); + auto right_transform = pose_to_transform(config.pose[1]); + vr::VRServerDriverHost()->SetDisplayEyeToHead(object_id, left_transform, right_transform); auto left_proj = fov_to_projection(config.fov[0]); diff --git a/alvr/server_openvr/cpp/alvr_server/bindings.h b/alvr/server_openvr/cpp/alvr_server/bindings.h index 6dcf36963c..22ea48025d 100644 --- a/alvr/server_openvr/cpp/alvr_server/bindings.h +++ b/alvr/server_openvr/cpp/alvr_server/bindings.h @@ -14,6 +14,11 @@ struct FfiQuat { float w; }; +struct FfiPose { + FfiQuat orientation; + float position[3]; +}; + struct FfiHandSkeleton { float jointPositions[31][3]; FfiQuat jointRotations[31]; @@ -62,7 +67,7 @@ struct FfiOpenvrProperty { struct FfiViewsConfig { FfiFov fov[2]; - float ipd_m; + FfiPose pose[2]; }; enum FfiButtonType { diff --git a/alvr/server_openvr/src/lib.rs b/alvr/server_openvr/src/lib.rs index 5070822827..c380641a0b 100644 --- a/alvr/server_openvr/src/lib.rs +++ b/alvr/server_openvr/src/lib.rs @@ -84,9 +84,20 @@ fn event_loop(events_receiver: mpsc::Receiver) { down: config.fov[1].down, }, ], - // todo: send full matrix to steamvr - ipd_m: config.local_view_transforms[1].position.x - - config.local_view_transforms[0].position.x, + pose: [ + FfiPose { + orientation: tracking::to_ffi_quat( + config.local_view_transforms[0].orientation, + ), + position: config.local_view_transforms[0].position.to_array(), + }, + FfiPose { + orientation: tracking::to_ffi_quat( + config.local_view_transforms[1].orientation, + ), + position: config.local_view_transforms[1].position.to_array(), + }, + ], }); }, ServerCoreEvent::Tracking { sample_timestamp } => { diff --git a/alvr/server_openvr/src/tracking.rs b/alvr/server_openvr/src/tracking.rs index 2d11022254..90a7b3eb97 100644 --- a/alvr/server_openvr/src/tracking.rs +++ b/alvr/server_openvr/src/tracking.rs @@ -26,7 +26,7 @@ pub static BODY_TRACKER_IDS: Lazy<[u64; 8]> = Lazy::new(|| { ] }); -fn to_ffi_quat(quat: Quat) -> FfiQuat { +pub fn to_ffi_quat(quat: Quat) -> FfiQuat { FfiQuat { x: quat.x, y: quat.y,