+++ /dev/null
-#include <openvr.h>
-#include <msp/vr/stereoview.h>
-#include "openvrdevice.h"
-
-using namespace std;
-
-namespace {
-
-Msp::GL::Matrix convert_matrix(const vr::HmdMatrix34_t &m)
-{
- Msp::GL::Matrix result;
- for(unsigned i=0; i<3; ++i)
- for(unsigned j=0; j<4; ++j)
- result(i, j) = m.m[i][j];
- return result;
-}
-
-}
-
-
-namespace Msp {
-namespace VR {
-
-unsigned OpenVRDevice::n_instances = 0;
-
-OpenVRDevice::OpenVRDevice()
-{
- if(!n_instances)
- {
- vr::EVRInitError init_err;
- vr::VR_Init(&init_err, vr::VRApplication_Scene);
- if(init_err!=vr::VRInitError_None)
- throw runtime_error("OpenVR initialization failed");
- }
- ++n_instances;
-
- vr::IVRCompositor *compositor = vr::VRCompositor();
- if(!compositor)
- throw runtime_error("OpenVR compositor initialization failed");
-
- vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated);
-}
-
-OpenVRDevice::~OpenVRDevice()
-{
- if(!--n_instances)
- vr::VR_Shutdown();
-}
-
-void OpenVRDevice::configure_view(StereoView &view) const
-{
- vr::IVRSystem *vr_sys = vr::VRSystem();
-
-#if defined(__GNUC__) && defined(_WIN32)
- /* Visual C++ passes the return value address as first stack parameter and
- the this pointer in ecx. MinGW does the other way around. This trick
- forces the function signature to match at machine code level. */
- typedef void (vr::IVRSystem::*FuncPtr)(vr::HmdMatrix34_t *, vr::EVREye);
- FuncPtr get_eye_to_head_transform = reinterpret_cast<FuncPtr>(&vr::IVRSystem::GetEyeToHeadTransform);
-
- vr::HmdMatrix34_t left, right;
- (vr_sys->*get_eye_to_head_transform)(&left, vr::Eye_Left);
- (vr_sys->*get_eye_to_head_transform)(&right, vr::Eye_Right);
-#else
- vr::HmdMatrix34_t left = vr_sys->GetEyeToHeadTransform(vr::Eye_Left);
- vr::HmdMatrix34_t right = vr_sys->GetEyeToHeadTransform(vr::Eye_Right);
-#endif
-
- view.set_eye_matrices(convert_matrix(left), convert_matrix(right));
-}
-
-OpenVRCamera *OpenVRDevice::create_camera(const GL::Camera &bc)
-{
- return new OpenVRCamera(*this, bc);
-}
-
-OpenVRCombiner *OpenVRDevice::create_combiner(GL::View &v)
-{
- return new OpenVRCombiner(*this, v);
-}
-
-void OpenVRDevice::update_pose_matrices()
-{
- vector<vr::TrackedDevicePose_t> poses;
- poses.resize(vr::k_unTrackedDeviceIndex_Hmd+1);
- vr::VRCompositor()->WaitGetPoses(&poses[0], poses.size(), 0, 0);
-
- vr::TrackedDevicePose_t &hmd_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
- if(hmd_pose.bPoseIsValid)
- hmd_matrix = convert_matrix(hmd_pose.mDeviceToAbsoluteTracking);
-}
-
-} // namespace VR
-} // namespace Msp