Monado OpenXR Runtime
context.hpp
Go to the documentation of this file.
1// Copyright 2023, Shawn Wallace
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief SteamVR driver context - implements xrt_tracking_origin and IVRDriverContext.
6 * @author Shawn Wallace <yungwallace@live.com>
7 * @ingroup drv_steamvr_lh
8 */
9
10#pragma once
11
12#include <unordered_map>
13#include <memory>
14#include <optional>
15#include <chrono>
16#include <deque>
17#include <mutex>
18
19#include "openvr_driver.h"
20
21#include "settings.hpp"
22#include "resources.hpp"
23#include "iobuffer.hpp"
24#include "driver_manager.hpp"
25#include "server.hpp"
26#include "blockqueue.hpp"
27#include "paths.hpp"
28
29#include "xrt/xrt_tracking.h"
30
31struct xrt_input;
32class Device;
34class Context final : public xrt_tracking_origin,
35 public vr::IVRDriverContext,
36 public vr::IVRServerDriverHost,
37 public vr::IVRDriverInput,
38 public vr::IVRProperties,
39 public vr::IVRDriverLog,
40 public std::enable_shared_from_this<Context>
41
42{
43public:
44 Settings settings;
45
46private:
47 Resources resources;
48 IOBuffer iobuf;
49 DriverManager man;
50 Server server;
51 BlockQueue blockqueue;
52 Paths paths;
53
54 uint64_t current_frame{0};
55
56 std::vector<vr::VRInputComponentHandle_t> handles;
57 std::unordered_map<vr::VRInputComponentHandle_t, xrt_input *> handle_to_input;
58 struct Vec2Components
59 {
60 vr::VRInputComponentHandle_t x;
61 vr::VRInputComponentHandle_t y;
62 };
63 std::unordered_map<vr::VRInputComponentHandle_t, Vec2Components *> vec2_inputs;
64 std::unordered_map<xrt_input *, std::unique_ptr<Vec2Components>> vec2_input_to_components;
65 std::unordered_map<vr::VRInputComponentHandle_t, ControllerDevice *> skeleton_to_controller;
66
67 struct Event
68 {
69 std::chrono::steady_clock::time_point insert_time;
70 vr::VREvent_t inner;
71 };
72 std::deque<Event> events;
73 std::mutex event_queue_mut;
74
75 Device *
76 prop_container_to_device(vr::PropertyContainerHandle_t handle);
77
78 vr::EVRInputError
79 create_component_common(vr::PropertyContainerHandle_t container,
80 const char *name,
81 vr::VRInputComponentHandle_t *handle);
82
83 xrt_input *
84 update_component_common(vr::VRInputComponentHandle_t handle,
85 double offset,
86 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now());
87
88 bool
89 setup_hmd(const char *serial, vr::ITrackedDeviceServerDriver *driver);
90
91 bool
92 setup_controller(const char *serial, vr::ITrackedDeviceServerDriver *driver);
93 std::vector<vr::IServerTrackedDeviceProvider *> providers;
94
95 inline vr::VRInputComponentHandle_t
96 new_handle()
97 {
98 vr::VRInputComponentHandle_t h = handles.size() + 1;
99 handles.push_back(h);
100 return h;
101 }
102
103public:
104 Context(const std::string &steam_install, const std::string &steamvr_install, u_logging_level level);
105
106 // These are owned by monado, context is destroyed when these are destroyed
107 class HmdDevice *hmd{nullptr};
108 class ControllerDevice *controller[16]{nullptr};
109 const u_logging_level log_level;
110
111 ~Context();
112
113 [[nodiscard]] static std::shared_ptr<Context>
114 create(const std::string &steam_install,
115 const std::string &steamvr_install,
116 std::vector<vr::IServerTrackedDeviceProvider *> providers);
117
118 void
119 run_frame();
120
121 void
122 maybe_run_frame(uint64_t new_frame);
123
124 void
125 add_haptic_event(vr::VREvent_HapticVibration_t event);
126
127 void
128 add_vendor_event(vr::EVREventType type, const vr::VREvent_Data_t &data = {})
129 {
130 VendorSpecificEvent(0, type, data, 0);
131 }
132
133 void
134 Log(const char *pchLogMessage) override;
135
136 /***** IVRDriverContext methods *****/
137
138 void *
139 GetGenericInterface(const char *pchInterfaceVersion, vr::EVRInitError *peError) override;
140
141 vr::DriverHandle_t
142 GetDriverHandle() override;
143
144 /***** IVRServerDriverHost methods *****/
145 bool
146 TrackedDeviceAdded(const char *pchDeviceSerialNumber,
147 vr::ETrackedDeviceClass eDeviceClass,
148 vr::ITrackedDeviceServerDriver *pDriver) override;
149
150 void
151 TrackedDevicePoseUpdated(uint32_t unWhichDevice,
152 const vr::DriverPose_t &newPose,
153 uint32_t unPoseStructSize) override;
154
155 void
156 VsyncEvent(double vsyncTimeOffsetSeconds) override;
157
158 void
159 VendorSpecificEvent(uint32_t unWhichDevice,
160 vr::EVREventType eventType,
161 const vr::VREvent_Data_t &eventData,
162 double eventTimeOffset) override;
163
164 bool
165 IsExiting() override;
166
167 bool
168 PollNextEvent(vr::VREvent_t *pEvent, uint32_t uncbVREvent) override;
169
170 void
171 GetRawTrackedDevicePoses(float fPredictedSecondsFromNow,
172 vr::TrackedDevicePose_t *pTrackedDevicePoseArray,
173 uint32_t unTrackedDevicePoseArrayCount) override;
174
175 void
176 RequestRestart(const char *pchLocalizedReason,
177 const char *pchExecutableToStart,
178 const char *pchArguments,
179 const char *pchWorkingDirectory) override;
180
181 uint32_t
182 GetFrameTimings(vr::Compositor_FrameTiming *pTiming, uint32_t nFrames) override;
183
184 void
185 SetDisplayEyeToHead(uint32_t unWhichDevice,
186 const vr::HmdMatrix34_t &eyeToHeadLeft,
187 const vr::HmdMatrix34_t &eyeToHeadRight) override;
188
189 void
190 SetDisplayProjectionRaw(uint32_t unWhichDevice,
191 const vr::HmdRect2_t &eyeLeft,
192 const vr::HmdRect2_t &eyeRight) override;
193
194 void
195 SetRecommendedRenderTargetSize(uint32_t unWhichDevice, uint32_t nWidth, uint32_t nHeight) override;
196
197 /***** IVRDriverInput methods *****/
198
199 vr::EVRInputError
200 CreateBooleanComponent(vr::PropertyContainerHandle_t ulContainer,
201 const char *pchName,
202 vr::VRInputComponentHandle_t *pHandle) override;
203
204 vr::EVRInputError
205 UpdateBooleanComponent(vr::VRInputComponentHandle_t ulComponent, bool bNewValue, double fTimeOffset) override;
206
207 vr::EVRInputError
208 CreateScalarComponent(vr::PropertyContainerHandle_t ulContainer,
209 const char *pchName,
210 vr::VRInputComponentHandle_t *pHandle,
211 vr::EVRScalarType eType,
212 vr::EVRScalarUnits eUnits) override;
213
214 vr::EVRInputError
215 UpdateScalarComponent(vr::VRInputComponentHandle_t ulComponent, float fNewValue, double fTimeOffset) override;
216
217 vr::EVRInputError
218 CreateHapticComponent(vr::PropertyContainerHandle_t ulContainer,
219 const char *pchName,
220 vr::VRInputComponentHandle_t *pHandle) override;
221
222 vr::EVRInputError
223 CreateSkeletonComponent(vr::PropertyContainerHandle_t ulContainer,
224 const char *pchName,
225 const char *pchSkeletonPath,
226 const char *pchBasePosePath,
227 vr::EVRSkeletalTrackingLevel eSkeletalTrackingLevel,
228 const vr::VRBoneTransform_t *pGripLimitTransforms,
229 uint32_t unGripLimitTransformCount,
230 vr::VRInputComponentHandle_t *pHandle) override;
231
232 vr::EVRInputError
233 UpdateSkeletonComponent(vr::VRInputComponentHandle_t ulComponent,
234 vr::EVRSkeletalMotionRange eMotionRange,
235 const vr::VRBoneTransform_t *pTransforms,
236 uint32_t unTransformCount) override;
237
238 /***** IVRProperties methods *****/
239
240 vr::ETrackedPropertyError
241 ReadPropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
242 vr::PropertyRead_t *pBatch,
243 uint32_t unBatchEntryCount) override;
244
245 vr::ETrackedPropertyError
246 WritePropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
247 vr::PropertyWrite_t *pBatch,
248 uint32_t unBatchEntryCount) override;
249
250 const char *
251 GetPropErrorNameFromEnum(vr::ETrackedPropertyError error) override;
252
253 vr::PropertyContainerHandle_t
254 TrackedDeviceToPropertyContainer(vr::TrackedDeviceIndex_t nDevice) override;
255};
OpenVR IVRBlockQueue interface header.
This interface is missing in the C++ header but present in the C one, and the lighthouse driver requi...
Definition: blockqueue.hpp:43
Definition: context.hpp:42
static std::shared_ptr< Context > create(const std::string &steam_install, const std::string &steamvr_install, std::vector< vr::IServerTrackedDeviceProvider * > providers)
Since only the devices will live after our get_devices function is called, we make our Context a shar...
Definition: steamvr_lh.cpp:109
Definition: device.hpp:228
Definition: device.hpp:68
Definition: driver_manager.hpp:15
Definition: device.hpp:149
Definition: iobuffer.hpp:15
This interface is missing in the C++ header but present in the C one, and the lighthouse driver requi...
Definition: paths.hpp:21
Definition: resources.hpp:16
An internal interface utilized by the lighthouse driver.
Definition: server.hpp:15
Definition: settings.hpp:18
OpenVR IVRDriverManager interface header.
u_logging_level
Logging level enum.
Definition: u_logging.h:45
OpenVR IVRIOBuffer interface header.
OpenVR IVRPaths interface header.
OpenVR IVRResources interface header.
OpenVR IVRServer internal interface header.
OpenVR IVRSettings interface header.
struct xrt_hmd_parts * hmd
Null if this device does not interface with the users head.
Definition: xrt_device.h:321
A single named input, that sits on a xrt_device.
Definition: xrt_device.h:188
A tracking system or device origin.
Definition: xrt_tracking.h:75
char name[256]
For debugging.
Definition: xrt_tracking.h:77
enum xrt_tracking_type type
What can the state tracker expect from this tracking system.
Definition: xrt_tracking.h:80
Header defining the tracking system integration in Monado.