2 #include <msp/vr/stereoview.h>
3 #include "openvrsystem.h"
9 Msp::GL::Matrix convert_matrix(const vr::HmdMatrix34_t &m)
11 Msp::GL::Matrix result;
12 for(unsigned i=0; i<3; ++i)
13 for(unsigned j=0; j<4; ++j)
14 result(i, j) = m.m[i][j];
24 unsigned OpenVRSystem::n_instances = 0;
26 OpenVRSystem::OpenVRSystem()
30 vr::EVRInitError init_err;
31 vr::VR_Init(&init_err, vr::VRApplication_Scene);
32 if(init_err!=vr::VRInitError_None)
33 throw runtime_error("OpenVR initialization failed");
37 vr::IVRCompositor *compositor = vr::VRCompositor();
39 throw runtime_error("OpenVR compositor initialization failed");
41 vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated);
44 OpenVRSystem::~OpenVRSystem()
50 bool OpenVRSystem::is_maybe_available()
52 return vr::VR_IsHmdPresent();
55 void OpenVRSystem::configure_view(StereoView &view) const
57 vr::IVRSystem *vr_sys = vr::VRSystem();
59 #if defined(__GNUC__) && defined(_WIN32)
60 /* Visual C++ passes the return value address as first stack parameter and
61 the this pointer in ecx. MinGW does the other way around. This trick
62 forces the function signature to match at machine code level. */
63 typedef void (vr::IVRSystem::*FuncPtr)(vr::HmdMatrix34_t *, vr::EVREye);
64 FuncPtr get_eye_to_head_transform = reinterpret_cast<FuncPtr>(&vr::IVRSystem::GetEyeToHeadTransform);
66 vr::HmdMatrix34_t left, right;
67 (vr_sys->*get_eye_to_head_transform)(&left, vr::Eye_Left);
68 (vr_sys->*get_eye_to_head_transform)(&right, vr::Eye_Right);
70 vr::HmdMatrix34_t left = vr_sys->GetEyeToHeadTransform(vr::Eye_Left);
71 vr::HmdMatrix34_t right = vr_sys->GetEyeToHeadTransform(vr::Eye_Right);
74 view.set_eye_matrices(convert_matrix(left), convert_matrix(right));
77 void OpenVRSystem::set_absolute_tracking(bool a)
79 vr::VRCompositor()->SetTrackingSpace(a ? vr::TrackingUniverseStanding : vr::TrackingUniverseSeated);
82 bool OpenVRSystem::get_absolute_tracking() const
84 return vr::VRCompositor()->GetTrackingSpace()==vr::TrackingUniverseStanding;
87 OpenVRCamera *OpenVRSystem::create_camera(const GL::Camera &bc)
89 return new OpenVRCamera(*this, bc);
92 OpenVRCombiner *OpenVRSystem::create_combiner(GL::View &v)
94 return new OpenVRCombiner(*this, v);
97 void OpenVRSystem::update_pose_matrices()
99 vector<vr::TrackedDevicePose_t> poses;
100 poses.resize(vr::k_unTrackedDeviceIndex_Hmd+1);
101 vr::VRCompositor()->WaitGetPoses(&poses[0], poses.size(), 0, 0);
103 vr::TrackedDevicePose_t &hmd_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
104 if(hmd_pose.bPoseIsValid)
105 hmd_matrix = convert_matrix(hmd_pose.mDeviceToAbsoluteTracking);