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