From: Mikko Rasa Date: Mon, 3 Oct 2016 12:35:38 +0000 (+0300) Subject: Rename DisplayDevice to System X-Git-Url: http://git.tdb.fi/?p=libs%2Fvr.git;a=commitdiff_plain;h=b6de7d24475dec8f5d6b8148a69cf8b561bc0761 Rename DisplayDevice to System Motion controllers are going to be supported too so the top-level class shouldn't be tied to display. --- diff --git a/source/displaydevice.cpp b/source/displaydevice.cpp deleted file mode 100644 index 5e11266..0000000 --- a/source/displaydevice.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "displaydevice.h" -#ifdef WITH_OPENVR -#include "openvr/openvrdevice.h" -#endif -#ifdef WITH_LIBOVR -#include "ovr/oculusriftdevice.h" -#endif - -using namespace std; - -namespace Msp { -namespace VR { - -DisplayDevice *DisplayDevice::create_device(const string &type) -{ -#ifdef WITH_OPENVR - if(type=="openvr") - return new OpenVRDevice; -#endif -#ifdef WITH_LIBOVR - if(type=="libovr") - return new OculusRiftDevice; -#endif - throw invalid_argument(format("device type '%s' not supported", type)); -} - -} // namespace VR -} // namespace Msp diff --git a/source/displaydevice.h b/source/displaydevice.h deleted file mode 100644 index 46dfbae..0000000 --- a/source/displaydevice.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef MSP_VR_DISPLAYDEVICE_H_ -#define MSP_VR_DISPLAYDEVICE_H_ - -#include -#include -#include - -namespace Msp { -namespace VR { - -class HeadTrackingCamera; -class StereoCombiner; -class StereoView; - -class DisplayDevice -{ -protected: - DisplayDevice() { } -public: - virtual ~DisplayDevice() { } - - static DisplayDevice *create_device(const std::string &); - - virtual void configure_window(Graphics::Window &) const = 0; - virtual void configure_view(StereoView &) const = 0; - virtual HeadTrackingCamera *create_camera(const GL::Camera &) = 0; - virtual StereoCombiner *create_combiner(GL::View &) = 0; -}; - -} // namespace VR -} // namespace Msp - -#endif diff --git a/source/openvr/openvrcamera.cpp b/source/openvr/openvrcamera.cpp index 6166d3a..d6a0fe6 100644 --- a/source/openvr/openvrcamera.cpp +++ b/source/openvr/openvrcamera.cpp @@ -1,11 +1,11 @@ #include #include "openvrcamera.h" -#include "openvrdevice.h" +#include "openvrsystem.h" namespace Msp { namespace VR { -OpenVRCamera::OpenVRCamera(const OpenVRDevice &d, const GL::Camera &c): +OpenVRCamera::OpenVRCamera(const OpenVRSystem &d, const GL::Camera &c): HeadTrackingCamera(c), device(d) { } diff --git a/source/openvr/openvrcamera.h b/source/openvr/openvrcamera.h index ff86817..ab14d3d 100644 --- a/source/openvr/openvrcamera.h +++ b/source/openvr/openvrcamera.h @@ -6,15 +6,15 @@ namespace Msp { namespace VR { -class OpenVRDevice; +class OpenVRSystem; class OpenVRCamera: public HeadTrackingCamera { private: - const OpenVRDevice &device; + const OpenVRSystem &device; public: - OpenVRCamera(const OpenVRDevice &, const GL::Camera &); + OpenVRCamera(const OpenVRSystem &, const GL::Camera &); virtual void reset_tracking(); virtual void update(); diff --git a/source/openvr/openvrcombiner.cpp b/source/openvr/openvrcombiner.cpp index 9bdf4b0..fa5a8ac 100644 --- a/source/openvr/openvrcombiner.cpp +++ b/source/openvr/openvrcombiner.cpp @@ -1,6 +1,6 @@ #include #include "openvrcombiner.h" -#include "openvrdevice.h" +#include "openvrsystem.h" namespace Msp { namespace VR { @@ -11,7 +11,7 @@ struct OpenVRCombiner::Private }; -OpenVRCombiner::OpenVRCombiner(OpenVRDevice &d, GL::View &v): +OpenVRCombiner::OpenVRCombiner(OpenVRSystem &d, GL::View &v): device(d), view(v) { diff --git a/source/openvr/openvrcombiner.h b/source/openvr/openvrcombiner.h index 58a24c9..94ccce3 100644 --- a/source/openvr/openvrcombiner.h +++ b/source/openvr/openvrcombiner.h @@ -7,18 +7,18 @@ namespace Msp { namespace VR { -class OpenVRDevice; +class OpenVRSystem; class OpenVRCombiner: public StereoCombiner { private: struct Private; - OpenVRDevice &device; + OpenVRSystem &device; GL::View &view; public: - OpenVRCombiner(OpenVRDevice &, GL::View &); + OpenVRCombiner(OpenVRSystem &, GL::View &); virtual void prepare() const; virtual void render(const GL::Texture2D &, const GL::Texture2D &) const; diff --git a/source/openvr/openvrdevice.cpp b/source/openvr/openvrdevice.cpp deleted file mode 100644 index b4ff20b..0000000 --- a/source/openvr/openvrdevice.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#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(&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 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 diff --git a/source/openvr/openvrdevice.h b/source/openvr/openvrdevice.h deleted file mode 100644 index ee00942..0000000 --- a/source/openvr/openvrdevice.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MSP_VR_OPENVRDEVICE_H_ -#define MSP_VR_OPENVRDEVICE_H_ - -#include -#include -#include "openvrcamera.h" -#include "openvrcombiner.h" - -namespace Msp { -namespace VR { - -class OpenVRDevice: public DisplayDevice -{ -private: - GL::Matrix hmd_matrix; - - static unsigned n_instances; - -public: - OpenVRDevice(); - ~OpenVRDevice(); - - virtual void configure_window(Graphics::Window &) const { } - virtual void configure_view(StereoView &) const; - virtual OpenVRCamera *create_camera(const GL::Camera &); - virtual OpenVRCombiner *create_combiner(GL::View &); - - void update_pose_matrices(); - const GL::Matrix &get_hmd_matrix() const { return hmd_matrix; } -}; - -} // namespace VR -} // namespace Msp - -#endif 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 diff --git a/source/openvr/openvrsystem.h b/source/openvr/openvrsystem.h new file mode 100644 index 0000000..98ad556 --- /dev/null +++ b/source/openvr/openvrsystem.h @@ -0,0 +1,35 @@ +#ifndef MSP_VR_OPENVRSYSTEM_H_ +#define MSP_VR_OPENVRSYSTEM_H_ + +#include +#include +#include "openvrcamera.h" +#include "openvrcombiner.h" + +namespace Msp { +namespace VR { + +class OpenVRSystem: public System +{ +private: + GL::Matrix hmd_matrix; + + static unsigned n_instances; + +public: + OpenVRSystem(); + ~OpenVRSystem(); + + virtual void configure_window(Graphics::Window &) const { } + virtual void configure_view(StereoView &) const; + virtual OpenVRCamera *create_camera(const GL::Camera &); + virtual OpenVRCombiner *create_combiner(GL::View &); + + void update_pose_matrices(); + const GL::Matrix &get_hmd_matrix() const { return hmd_matrix; } +}; + +} // namespace VR +} // namespace Msp + +#endif diff --git a/source/ovr/oculusriftcamera.cpp b/source/ovr/oculusriftcamera.cpp index 713ae3c..4da732b 100644 --- a/source/ovr/oculusriftcamera.cpp +++ b/source/ovr/oculusriftcamera.cpp @@ -1,11 +1,11 @@ #include "oculusriftcamera.h" -#include "oculusriftdevice.h" -#include "oculusriftdevice_private.h" +#include "oculusriftsystem.h" +#include "oculusriftsystem_private.h" namespace Msp { namespace VR { -OculusRiftCamera::OculusRiftCamera(const OculusRiftDevice &d, const GL::Camera &c): +OculusRiftCamera::OculusRiftCamera(const OculusRiftSystem &d, const GL::Camera &c): HeadTrackingCamera(c), device(d) { diff --git a/source/ovr/oculusriftcamera.h b/source/ovr/oculusriftcamera.h index b6acae1..6abb116 100644 --- a/source/ovr/oculusriftcamera.h +++ b/source/ovr/oculusriftcamera.h @@ -6,15 +6,15 @@ namespace Msp { namespace VR { -class OculusRiftDevice; +class OculusRiftSystem; class OculusRiftCamera: public HeadTrackingCamera { private: - const OculusRiftDevice &device; + const OculusRiftSystem &device; public: - OculusRiftCamera(const OculusRiftDevice &, const GL::Camera &); + OculusRiftCamera(const OculusRiftSystem &, const GL::Camera &); virtual void reset_tracking(); virtual void update(); diff --git a/source/ovr/oculusriftcombiner.cpp b/source/ovr/oculusriftcombiner.cpp index 2d40ea9..e0c2c4d 100644 --- a/source/ovr/oculusriftcombiner.cpp +++ b/source/ovr/oculusriftcombiner.cpp @@ -1,8 +1,8 @@ #include #include #include "oculusriftcombiner.h" -#include "oculusriftdevice.h" -#include "oculusriftdevice_private.h" +#include "oculusriftsystem.h" +#include "oculusriftsystem_private.h" using namespace std; @@ -81,7 +81,7 @@ struct OculusRiftCombiner::Frustum: StereoCombiner::Frustum }; -OculusRiftCombiner::OculusRiftCombiner(OculusRiftDevice &d, GL::View &v): +OculusRiftCombiner::OculusRiftCombiner(OculusRiftSystem &d, GL::View &v): device(d), view(v), left_mesh((GL::VERTEX2, GL::TEXCOORD2,0, GL::TEXCOORD2,1, GL::TEXCOORD2,2, GL::TEXCOORD2,3)), diff --git a/source/ovr/oculusriftcombiner.h b/source/ovr/oculusriftcombiner.h index 14f0e4c..418c569 100644 --- a/source/ovr/oculusriftcombiner.h +++ b/source/ovr/oculusriftcombiner.h @@ -10,7 +10,7 @@ namespace Msp { namespace VR { -class OculusRiftDevice; +class OculusRiftSystem; /** Presents a stereo view in a way suitable for an Oculus Rift HMD. All distances @@ -21,7 +21,7 @@ class OculusRiftCombiner: public StereoCombiner private: struct Frustum; - OculusRiftDevice &device; + OculusRiftSystem &device; GL::View &view; GL::Mesh left_mesh; GL::Mesh right_mesh; @@ -30,7 +30,7 @@ private: mutable GL::ProgramData right_shdata; public: - OculusRiftCombiner(OculusRiftDevice &, GL::View &); + OculusRiftCombiner(OculusRiftSystem &, GL::View &); virtual void prepare() const; virtual void render(const GL::Texture2D &, const GL::Texture2D &) const; diff --git a/source/ovr/oculusriftdevice.cpp b/source/ovr/oculusriftdevice.cpp deleted file mode 100644 index 38fd20e..0000000 --- a/source/ovr/oculusriftdevice.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include "oculusriftdevice.h" -#include "oculusriftdevice_private.h" - -using namespace std; - -namespace Msp { -namespace VR { - -unsigned OculusRiftDevice::n_instances = 0; - -OculusRiftDevice::OculusRiftDevice(): - priv(new Private), - frame_index(0) -{ - if(!n_instances) - ovr_Initialize(); - ++n_instances; - - priv->ovr_hmd = ovrHmd_Create(0); - if(!priv->ovr_hmd) - { - delete priv; - throw runtime_error("rift hmd not found"); - } -} - -OculusRiftDevice::~OculusRiftDevice() -{ - ovrHmd_Destroy(priv->ovr_hmd); - delete priv; - - --n_instances; - if(!n_instances) - ovr_Shutdown(); -} - -void OculusRiftDevice::configure_window(Graphics::Window &window) const -{ - Graphics::WindowOptions win_opts = window.get_options(); - win_opts.width = priv->ovr_hmd->Resolution.w; - win_opts.height = priv->ovr_hmd->Resolution.h; - - const list &monitors = window.get_display().get_monitors(); - string hmd_name = priv->ovr_hmd->ProductName; - for(list::const_iterator i=monitors.begin(); i!=monitors.end(); ++i) - if(hmd_name.find(i->name)!=string::npos) - { - win_opts.fullscreen = true; - win_opts.fullscreen_monitor = &*i; - win_opts.fullscreen_exclusive = false; - } - - window.reconfigure(win_opts); -} - -void OculusRiftDevice::configure_view(StereoView &view) const -{ - ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]); - ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]); - const ovrVector3f &l = left_desc.HmdToEyeViewOffset; - const ovrVector3f &r = right_desc.HmdToEyeViewOffset; - view.set_eye_matrices(GL::Matrix::translation(GL::Vector3(l.x, l.y, l.z)), GL::Matrix::translation(GL::Vector3(r.x, r.y, r.z))); -} - -OculusRiftCamera *OculusRiftDevice::create_camera(const GL::Camera &bc) -{ - return new OculusRiftCamera(*this, bc); -} - -OculusRiftCombiner *OculusRiftDevice::create_combiner(GL::View &view) -{ - return new OculusRiftCombiner(*this, view); -} - -void OculusRiftDevice::begin_frame() -{ - priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index); - timing_active = true; -} - -void OculusRiftDevice::end_frame() -{ - glFinish(); - ovrHmd_EndFrameTiming(priv->ovr_hmd); - timing_active = false; -} - -double OculusRiftDevice::get_tracking_time() const -{ - if(!timing_active) - throw logic_error("timing not active"); - return priv->frame_timing.ScanoutMidpointSeconds; -} - -double OculusRiftDevice::get_timewarp_time() const -{ - if(!timing_active) - throw logic_error("timing not active"); - return priv->frame_timing.TimewarpPointSeconds; -} - -double OculusRiftDevice::get_current_time() const -{ - return ovr_GetTimeInSeconds(); -} - -} // namespace VR -} // namespace Msp diff --git a/source/ovr/oculusriftdevice.h b/source/ovr/oculusriftdevice.h deleted file mode 100644 index 02f8016..0000000 --- a/source/ovr/oculusriftdevice.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef MSP_VR_OCULUSRIFTDEVICE_H_ -#define MSP_VR_OCULUSRIFTDEVICE_H_ - -#include -#include "oculusriftcamera.h" -#include "oculusriftcombiner.h" - -namespace Msp { -namespace VR { - -class OculusRiftDevice: public DisplayDevice -{ -public: - struct Private; - -private: - Private *priv; - unsigned frame_index; - bool timing_active; - - static unsigned n_instances; - -public: - OculusRiftDevice(); - virtual ~OculusRiftDevice(); - - const Private &get_private() const { return *priv; } - - virtual void configure_window(Graphics::Window &) const; - virtual void configure_view(StereoView &) const; - virtual OculusRiftCamera *create_camera(const GL::Camera &); - virtual OculusRiftCombiner *create_combiner(GL::View &); - - void begin_frame(); - void end_frame(); - bool is_timing_active() const { return timing_active; } - double get_tracking_time() const; - double get_timewarp_time() const; - double get_current_time() const; -}; - -} // namespace VR -} // namespace Msp - -#endif diff --git a/source/ovr/oculusriftdevice_private.h b/source/ovr/oculusriftdevice_private.h deleted file mode 100644 index 26587ff..0000000 --- a/source/ovr/oculusriftdevice_private.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_ -#define MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_ - -#include -#include "oculusriftdevice.h" - -namespace Msp { -namespace VR { - -struct OculusRiftDevice::Private -{ - ovrHmd ovr_hmd; - ovrFrameTiming frame_timing; -}; - -} // namespace VR -} // namespace Msp - -#endif diff --git a/source/ovr/oculusriftsystem.cpp b/source/ovr/oculusriftsystem.cpp new file mode 100644 index 0000000..4a85383 --- /dev/null +++ b/source/ovr/oculusriftsystem.cpp @@ -0,0 +1,110 @@ +#include +#include +#include "oculusriftsystem.h" +#include "oculusriftsystem_private.h" + +using namespace std; + +namespace Msp { +namespace VR { + +unsigned OculusRiftSystem::n_instances = 0; + +OculusRiftSystem::OculusRiftSystem(): + priv(new Private), + frame_index(0) +{ + if(!n_instances) + ovr_Initialize(); + ++n_instances; + + priv->ovr_hmd = ovrHmd_Create(0); + if(!priv->ovr_hmd) + { + delete priv; + throw runtime_error("rift hmd not found"); + } +} + +OculusRiftSystem::~OculusRiftSystem() +{ + ovrHmd_Destroy(priv->ovr_hmd); + delete priv; + + --n_instances; + if(!n_instances) + ovr_Shutdown(); +} + +void OculusRiftSystem::configure_window(Graphics::Window &window) const +{ + Graphics::WindowOptions win_opts = window.get_options(); + win_opts.width = priv->ovr_hmd->Resolution.w; + win_opts.height = priv->ovr_hmd->Resolution.h; + + const list &monitors = window.get_display().get_monitors(); + string hmd_name = priv->ovr_hmd->ProductName; + for(list::const_iterator i=monitors.begin(); i!=monitors.end(); ++i) + if(hmd_name.find(i->name)!=string::npos) + { + win_opts.fullscreen = true; + win_opts.fullscreen_monitor = &*i; + win_opts.fullscreen_exclusive = false; + } + + window.reconfigure(win_opts); +} + +void OculusRiftSystem::configure_view(StereoView &view) const +{ + ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]); + ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]); + const ovrVector3f &l = left_desc.HmdToEyeViewOffset; + const ovrVector3f &r = right_desc.HmdToEyeViewOffset; + view.set_eye_matrices(GL::Matrix::translation(GL::Vector3(l.x, l.y, l.z)), GL::Matrix::translation(GL::Vector3(r.x, r.y, r.z))); +} + +OculusRiftCamera *OculusRiftSystem::create_camera(const GL::Camera &bc) +{ + return new OculusRiftCamera(*this, bc); +} + +OculusRiftCombiner *OculusRiftSystem::create_combiner(GL::View &view) +{ + return new OculusRiftCombiner(*this, view); +} + +void OculusRiftSystem::begin_frame() +{ + priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index); + timing_active = true; +} + +void OculusRiftSystem::end_frame() +{ + glFinish(); + ovrHmd_EndFrameTiming(priv->ovr_hmd); + timing_active = false; +} + +double OculusRiftSystem::get_tracking_time() const +{ + if(!timing_active) + throw logic_error("timing not active"); + return priv->frame_timing.ScanoutMidpointSeconds; +} + +double OculusRiftSystem::get_timewarp_time() const +{ + if(!timing_active) + throw logic_error("timing not active"); + return priv->frame_timing.TimewarpPointSeconds; +} + +double OculusRiftSystem::get_current_time() const +{ + return ovr_GetTimeInSeconds(); +} + +} // namespace VR +} // namespace Msp diff --git a/source/ovr/oculusriftsystem.h b/source/ovr/oculusriftsystem.h new file mode 100644 index 0000000..20a4a5e --- /dev/null +++ b/source/ovr/oculusriftsystem.h @@ -0,0 +1,45 @@ +#ifndef MSP_VR_OCULUSRIFTSYSTEM_H_ +#define MSP_VR_OCULUSRIFTSYSTEM_H_ + +#include +#include "oculusriftcamera.h" +#include "oculusriftcombiner.h" + +namespace Msp { +namespace VR { + +class OculusRiftSystem: public System +{ +public: + struct Private; + +private: + Private *priv; + unsigned frame_index; + bool timing_active; + + static unsigned n_instances; + +public: + OculusRiftSystem(); + virtual ~OculusRiftSystem(); + + const Private &get_private() const { return *priv; } + + virtual void configure_window(Graphics::Window &) const; + virtual void configure_view(StereoView &) const; + virtual OculusRiftCamera *create_camera(const GL::Camera &); + virtual OculusRiftCombiner *create_combiner(GL::View &); + + void begin_frame(); + void end_frame(); + bool is_timing_active() const { return timing_active; } + double get_tracking_time() const; + double get_timewarp_time() const; + double get_current_time() const; +}; + +} // namespace VR +} // namespace Msp + +#endif diff --git a/source/ovr/oculusriftsystem_private.h b/source/ovr/oculusriftsystem_private.h new file mode 100644 index 0000000..2f91fdf --- /dev/null +++ b/source/ovr/oculusriftsystem_private.h @@ -0,0 +1,19 @@ +#ifndef MSP_VR_OCULUSRIFTSYSTEM_PRIVATE_H_ +#define MSP_VR_OCULUSRIFTSYSTEM_PRIVATE_H_ + +#include +#include "oculusriftsystem.h" + +namespace Msp { +namespace VR { + +struct OculusRiftSystem::Private +{ + ovrHmd ovr_hmd; + ovrFrameTiming frame_timing; +}; + +} // namespace VR +} // namespace Msp + +#endif diff --git a/source/system.cpp b/source/system.cpp new file mode 100644 index 0000000..436862e --- /dev/null +++ b/source/system.cpp @@ -0,0 +1,29 @@ +#include +#include "system.h" +#ifdef WITH_OPENVR +#include "openvr/openvrsystem.h" +#endif +#ifdef WITH_LIBOVR +#include "ovr/oculusriftsystem.h" +#endif + +using namespace std; + +namespace Msp { +namespace VR { + +System *System::create(const string &type) +{ +#ifdef WITH_OPENVR + if(type=="openvr") + return new OpenVRSystem; +#endif +#ifdef WITH_LIBOVR + if(type=="libovr") + return new OculusRiftSystem; +#endif + throw invalid_argument(format("system '%s' not supported", type)); +} + +} // namespace VR +} // namespace Msp diff --git a/source/system.h b/source/system.h new file mode 100644 index 0000000..0610e29 --- /dev/null +++ b/source/system.h @@ -0,0 +1,33 @@ +#ifndef MSP_VR_SYSTEM_H_ +#define MSP_VR_SYSTEM_H_ + +#include +#include +#include + +namespace Msp { +namespace VR { + +class HeadTrackingCamera; +class StereoCombiner; +class StereoView; + +class System +{ +protected: + System() { } +public: + virtual ~System() { } + + static System *create(const std::string &); + + virtual void configure_window(Graphics::Window &) const = 0; + virtual void configure_view(StereoView &) const = 0; + virtual HeadTrackingCamera *create_camera(const GL::Camera &) = 0; + virtual StereoCombiner *create_combiner(GL::View &) = 0; +}; + +} // namespace VR +} // namespace Msp + +#endif