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