X-Git-Url: http://git.tdb.fi/?p=libs%2Fvr.git;a=blobdiff_plain;f=source%2Fopenvr%2Fopenvrsystem.cpp;fp=source%2Fopenvr%2Fopenvrsystem.cpp;h=ec6b418d0a455a9e5f4fb5d7273a6a6e54cc5f8b;hp=0000000000000000000000000000000000000000;hb=b6de7d24475dec8f5d6b8148a69cf8b561bc0761;hpb=c07c707c480f4e989caee17541187f08f136d216 diff --git a/source/openvr/openvrsystem.cpp b/source/openvr/openvrsystem.cpp new file mode 100644 index 0000000..ec6b418 --- /dev/null +++ b/source/openvr/openvrsystem.cpp @@ -0,0 +1,94 @@ +#include +#include +#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(&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 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