Add functions to use absolute tracking
[libs/vr.git] / source / libovr / libovrsystem.cpp
1 #include <msp/graphics/display.h>
2 #include <msp/vr/stereoview.h>
3 #include "libovrsystem.h"
4 #include "libovrsystem_private.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace VR {
10
11 unsigned LibOVRSystem::n_instances = 0;
12
13 LibOVRSystem::LibOVRSystem():
14         priv(new Private),
15         frame_index(0)
16 {
17         if(!n_instances)
18                 ovr_Initialize();
19         ++n_instances;
20
21         priv->ovr_hmd = ovrHmd_Create(0);
22         if(!priv->ovr_hmd)
23         {
24                 delete priv;
25                 // XXX decrement n_instances
26                 throw runtime_error("rift hmd not found");
27         }
28 }
29
30 LibOVRSystem::~LibOVRSystem()
31 {
32         ovrHmd_Destroy(priv->ovr_hmd);
33         delete priv;
34
35         --n_instances;
36         if(!n_instances)
37                 ovr_Shutdown();
38 }
39
40 void LibOVRSystem::configure_window(Graphics::Window &window) const
41 {
42         Graphics::WindowOptions win_opts = window.get_options();
43         win_opts.width = priv->ovr_hmd->Resolution.w;
44         win_opts.height = priv->ovr_hmd->Resolution.h;
45
46         const list<Graphics::Monitor> &monitors = window.get_display().get_monitors();
47         string hmd_name = priv->ovr_hmd->ProductName;
48         for(list<Graphics::Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
49                 if(hmd_name.find(i->name)!=string::npos)
50                 {
51                         win_opts.fullscreen = true;
52                         win_opts.fullscreen_monitor = &*i;
53                         win_opts.fullscreen_exclusive = false;
54                 }
55
56         window.reconfigure(win_opts);
57 }
58
59 void LibOVRSystem::configure_view(StereoView &view) const
60 {
61         ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
62         ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
63         const ovrVector3f &l = left_desc.HmdToEyeViewOffset;
64         const ovrVector3f &r = right_desc.HmdToEyeViewOffset;
65         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)));
66 }
67
68 void LibOVRSystem::set_absolute_tracking(bool a)
69 {
70         if(a)
71                 throw invalid_argument("absolute tracking not supported");
72 }
73
74 LibOVRCamera *LibOVRSystem::create_camera(const GL::Camera &bc)
75 {
76         return new LibOVRCamera(*this, bc);
77 }
78
79 LibOVRCombiner *LibOVRSystem::create_combiner(GL::View &view)
80 {
81         return new LibOVRCombiner(*this, view);
82 }
83
84 void LibOVRSystem::begin_frame()
85 {
86         priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index);
87         timing_active = true;
88 }
89
90 void LibOVRSystem::end_frame()
91 {
92         glFinish();
93         ovrHmd_EndFrameTiming(priv->ovr_hmd);
94         timing_active = false;
95 }
96
97 double LibOVRSystem::get_tracking_time() const
98 {
99         if(!timing_active)
100                 throw logic_error("timing not active");
101         return priv->frame_timing.ScanoutMidpointSeconds;
102 }
103
104 double LibOVRSystem::get_timewarp_time() const
105 {
106         if(!timing_active)
107                 throw logic_error("timing not active");
108         return priv->frame_timing.TimewarpPointSeconds;
109 }
110
111 double LibOVRSystem::get_current_time() const
112 {
113         return ovr_GetTimeInSeconds();
114 }
115
116 } // namespace VR
117 } // namespace Msp