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 vr::IServerTrackedDeviceProvider *provider;
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
115protected:
116 Context(const std::string &steam_install, const std::string &steamvr_install, u_logging_level level);
117
118public:
119 // These are owned by monado, context is destroyed when these are destroyed
120 class HmdDevice *hmd{nullptr};
121 class ControllerDevice *controller[16]{nullptr};
122 const u_logging_level log_level;
123
124 ~Context();
125
126 [[nodiscard]] static std::shared_ptr<Context>
127 create(const std::string &steam_install,
128 const std::string &steamvr_install,
129 vr::IServerTrackedDeviceProvider *p);
130
131 void
132 maybe_run_frame(uint64_t new_frame);
133
134 void
135 add_haptic_event(vr::VREvent_HapticVibration_t event);
136
137 void
138 Log(const char *pchLogMessage) override;
139
140 /***** IVRDriverContext methods *****/
141
142 void *
143 GetGenericInterface(const char *pchInterfaceVersion, vr::EVRInitError *peError) override;
144
145 vr::DriverHandle_t
146 GetDriverHandle() override;
147
148 /***** IVRServerDriverHost methods *****/
149 bool
150 TrackedDeviceAdded(const char *pchDeviceSerialNumber,
151 vr::ETrackedDeviceClass eDeviceClass,
152 vr::ITrackedDeviceServerDriver *pDriver) override;
153
154 void
155 TrackedDevicePoseUpdated(uint32_t unWhichDevice,
156 const vr::DriverPose_t &newPose,
157 uint32_t unPoseStructSize) override;
158
159 void
160 VsyncEvent(double vsyncTimeOffsetSeconds) override;
161
162 void
163 VendorSpecificEvent(uint32_t unWhichDevice,
164 vr::EVREventType eventType,
165 const vr::VREvent_Data_t &eventData,
166 double eventTimeOffset) override;
167
168 bool
169 IsExiting() override;
170
171 bool
172 PollNextEvent(vr::VREvent_t *pEvent, uint32_t uncbVREvent) override;
173
174 void
175 GetRawTrackedDevicePoses(float fPredictedSecondsFromNow,
176 vr::TrackedDevicePose_t *pTrackedDevicePoseArray,
177 uint32_t unTrackedDevicePoseArrayCount) override;
178
179 void
180 RequestRestart(const char *pchLocalizedReason,
181 const char *pchExecutableToStart,
182 const char *pchArguments,
183 const char *pchWorkingDirectory) override;
184
185 uint32_t
186 GetFrameTimings(vr::Compositor_FrameTiming *pTiming, uint32_t nFrames) override;
187
188 void
189 SetDisplayEyeToHead(uint32_t unWhichDevice,
190 const vr::HmdMatrix34_t &eyeToHeadLeft,
191 const vr::HmdMatrix34_t &eyeToHeadRight) override;
192
193 void
194 SetDisplayProjectionRaw(uint32_t unWhichDevice,
195 const vr::HmdRect2_t &eyeLeft,
196 const vr::HmdRect2_t &eyeRight) override;
197
198 void
199 SetRecommendedRenderTargetSize(uint32_t unWhichDevice, uint32_t nWidth, uint32_t nHeight) override;
200
201 /***** IVRDriverInput methods *****/
202
203 vr::EVRInputError
204 CreateBooleanComponent(vr::PropertyContainerHandle_t ulContainer,
205 const char *pchName,
206 vr::VRInputComponentHandle_t *pHandle) override;
207
208 vr::EVRInputError
209 UpdateBooleanComponent(vr::VRInputComponentHandle_t ulComponent, bool bNewValue, double fTimeOffset) override;
210
211 vr::EVRInputError
212 CreateScalarComponent(vr::PropertyContainerHandle_t ulContainer,
213 const char *pchName,
214 vr::VRInputComponentHandle_t *pHandle,
215 vr::EVRScalarType eType,
216 vr::EVRScalarUnits eUnits) override;
217
218 vr::EVRInputError
219 UpdateScalarComponent(vr::VRInputComponentHandle_t ulComponent, float fNewValue, double fTimeOffset) override;
220
221 vr::EVRInputError
222 CreateHapticComponent(vr::PropertyContainerHandle_t ulContainer,
223 const char *pchName,
224 vr::VRInputComponentHandle_t *pHandle) override;
225
226 vr::EVRInputError
227 CreateSkeletonComponent(vr::PropertyContainerHandle_t ulContainer,
228 const char *pchName,
229 const char *pchSkeletonPath,
230 const char *pchBasePosePath,
231 vr::EVRSkeletalTrackingLevel eSkeletalTrackingLevel,
232 const vr::VRBoneTransform_t *pGripLimitTransforms,
233 uint32_t unGripLimitTransformCount,
234 vr::VRInputComponentHandle_t *pHandle) override;
235
236 vr::EVRInputError
237 UpdateSkeletonComponent(vr::VRInputComponentHandle_t ulComponent,
238 vr::EVRSkeletalMotionRange eMotionRange,
239 const vr::VRBoneTransform_t *pTransforms,
240 uint32_t unTransformCount) override;
241
242 /***** IVRProperties methods *****/
243
244 vr::ETrackedPropertyError
245 ReadPropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
246 vr::PropertyRead_t *pBatch,
247 uint32_t unBatchEntryCount) override;
248
249 vr::ETrackedPropertyError
250 WritePropertyBatch(vr::PropertyContainerHandle_t ulContainerHandle,
251 vr::PropertyWrite_t *pBatch,
252 uint32_t unBatchEntryCount) override;
253
254 const char *
255 GetPropErrorNameFromEnum(vr::ETrackedPropertyError error) override;
256
257 vr::PropertyContainerHandle_t
258 TrackedDeviceToPropertyContainer(vr::TrackedDeviceIndex_t nDevice) override;
259};
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, vr::IServerTrackedDeviceProvider *p)
Since only the devices will live after our get_devices function is called, we make our Context a shar...
Definition: steamvr_lh.cpp:71
Definition: device.hpp:149
Definition: device.hpp:40
Definition: driver_manager.hpp:15
Definition: device.hpp:95
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:40
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:242
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
struct xrt_pose offset
Read and written to by the state-tracker using the device(s) this tracking system is tracking.
Definition: xrt_tracking.h:82
Header defining the tracking system integration in Monado.