]> git.tdb.fi Git - libs/vr.git/blobdiff - source/openvr/openvrsystem.cpp
Rename DisplayDevice to System
[libs/vr.git] / source / openvr / openvrsystem.cpp
diff --git a/source/openvr/openvrsystem.cpp b/source/openvr/openvrsystem.cpp
new file mode 100644 (file)
index 0000000..ec6b418
--- /dev/null
@@ -0,0 +1,94 @@
+#include <openvr.h>
+#include <msp/vr/stereoview.h>
+#include "openvrsystem.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 OpenVRSystem::n_instances = 0;
+
+OpenVRSystem::OpenVRSystem()
+{
+       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);
+}
+
+OpenVRSystem::~OpenVRSystem()
+{
+       if(!--n_instances)
+               vr::VR_Shutdown();
+}
+
+void OpenVRSystem::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 *OpenVRSystem::create_camera(const GL::Camera &bc)
+{
+       return new OpenVRCamera(*this, bc);
+}
+
+OpenVRCombiner *OpenVRSystem::create_combiner(GL::View &v)
+{
+       return new OpenVRCombiner(*this, v);
+}
+
+void OpenVRSystem::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