OPENXR Scol plugin
sOpenXR.h
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2022 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25#ifndef S_OPEN_XR_H
26#define S_OPEN_XR_H
27
28#include <scolPlugin.h>
29
34#ifdef _WIN32
35#include <unknwn.h>
36
37#if defined(XR_USE_GRAPHICS_API_D3D11)
38# include <d3d11.h>
39#endif
40
41#endif // _WIN32
42
43#include "vrmaths.h"
44
45#include <vector>
46#include <boost/thread.hpp>
47#include <boost/bind/bind.hpp>
48#include <string>
49
50#include "platform.h"
51#include "renderer.h"
52#include "openxr/openxr.h"
53#include "openxr/openxr_platform.h"
54
55bool xr_result(XrInstance instance, XrResult result, const char* format, ...);
56
57enum VrController
58{
59 Left = 0,
60 Right = 1
61};
62
63enum VrEye
64{
65 LeftEye = 0,
66 RightEye = 1,
67 Undefined
68};
69
70static XrPosef identity_pose = { {0.0, 0.0, 0.0, 1.0}, {0.0, 0.0, 0.0} };
71
72#define MAX_VR_CONTROLLERS 2
73#define MAX_HAND_JOINTS XR_HAND_JOINT_LITTLE_TIP_EXT + 1
74
75//TODO check SO3 config in usm.ini for renderer type
76
77enum ExtensionType
78{
79 EXTENSION_NONE = 0,
80 EXTENSION_HAND_TRACKING = 1,
81 EXTENSION_PASSTHROUGH = 2
82};
83
84enum ControllerType
85{
86 CLASSIC_CONTROLLER = 0,
87 HANDS_CONTROLLER = 1,
88 HTCVIVE_CONTROLLER = 2,
89 VALVE_INDEX_CONTROLLER = 3,
90 OCULUS_TOUCH_CONTROLLER = 4,
91 MS_MOTION_CONTROLLER = 5,
92 PICO_NEO3_CONTROLLER = 6,
93 PICO_PICO4_CONTROLLER = 7
94};
95
96enum ControllerButtons
97{
98 btnA = 0,
99 btnB = 1,
100 btnRThumb = 2,
101 btnX = 3,
102 btnY = 4,
103 btnLThumb = 5,
104 btnGrip = 6,
105 btnTrigger = 7,
106 btnMenu = 8,
107 btnSize = 9
108};
109
110enum ControllerTouch
111{
112 touchA = 0,
113 touchB = 1,
114 touchRThumb = 2,
115 touchX = 3,
116 touchY = 4,
117 touchLThumb = 5,
118 touchThumbUp = 6,
119 touchTrigger = 7,
120 touchIndexPointing = 8,
121 touchSize = 9
122};
123
124enum ControllerAnalog
125{
126 analogPadX = 0,
127 analogPadY = 1,
128 analogTrigger = 2,
129 analogGrip = 3,
130 analogSize = 4
131};
132
133struct Position {
134 Vector3 position;
135 Quaternion rotation;
136 bool valid;
137};
138
140 XrActionSet actionSet{ XR_NULL_HANDLE };
141 std::vector<XrAction> buttonAction;
142 std::vector<XrAction> touchAction;
143 std::vector<XrAction> analogAction;
144 std::vector<std::vector<bool> > buttonStates;
145 std::vector<std::vector<bool> > touchStates;
146 std::vector<std::vector<float> > analogStates;
147
148 XrAction poseAction{ XR_NULL_HANDLE };
149 XrAction vibrateAction{ XR_NULL_HANDLE };
150
151 std::array<XrPath, MAX_VR_CONTROLLERS> handSubactionPath;
152 std::array<XrSpace, MAX_VR_CONTROLLERS> handSpace;
153 std::array<float, MAX_VR_CONTROLLERS> handScale = { {1.0f, 1.0f} };
154 std::array<XrBool32, MAX_VR_CONTROLLERS> handActive;
155 std::array<bool, MAX_VR_CONTROLLERS> handVisible;
156 std::array<Vector3, MAX_VR_CONTROLLERS> handPos;
157 std::array<Quaternion, MAX_VR_CONTROLLERS> handQuat;
158 std::array<Vector3, MAX_VR_CONTROLLERS> handVelocity;
159 std::array<Vector3, MAX_VR_CONTROLLERS> handAngularVelocity;
160};
161
166{
167public:
168protected:
169 bool mConnected;
170
171private:
172 static sOpenXr* _singleton;
173
174 std::string mAppName;
175 std::shared_ptr<IPlatform> mPlatform;
176 std::shared_ptr<IRenderer> mRenderer;
177 RenderSystem mRendererType;
178 XrInstance mInstance;
179 XrSession mSession;
180 XrSystemId mSystemId;
181 XrSessionState mState;
182 XrViewConfigurationType mViewType;
183 XrSpace mPlaySpace;
184 XrSpace mViewSpace;
185 std::string mDeviceName;
186 // Each physical Display/Eye is described by a view
187 std::vector<XrView> mViews;
188 std::vector<XrViewConfigurationView> mViewconfigViews;
189 std::vector<XrCompositionLayerProjectionView> mProjectionViews;
190 XrEnvironmentBlendMode mBlendMode;
191 int mExtensionsEnable;
192
193 // one swapchain per view. Using only one and rendering l/r to the same image is also possible.
194 std::vector<XrSwapchain> mSwapchains;
195 std::vector<Vector2i> mSwapchainsSize;
196 InputState mInput;
197
198 // hand tracking extension data
199 struct
200 {
201 bool supported;
202 bool gestures;
203 // whether the current VR system in use has hand tracking
204 bool system_supported;
205 PFN_xrLocateHandJointsEXT pfnLocateHandJointsEXT;
206 std::array<XrHandTrackerEXT, 2> trackers;
207 std::array<std::array<Position, MAX_HAND_JOINTS>, 2> bones;
208 } mHandTracking;
209
210 struct
211 {
212 bool supported;
213 bool available;
214 XrPassthroughFB passthroughFeature;
215 XrPassthroughLayerFB passthroughLayer;
216 PFN_xrCreatePassthroughFB pfnXrCreatePassthroughFBX;
217 PFN_xrDestroyPassthroughFB pfnXrDestroyPassthroughFBX;
218 PFN_xrCreatePassthroughLayerFB pfnXrCreatePassthroughLayerFBX;
219 PFN_xrPassthroughStartFB pfnXrPassthroughStartFBX;
220 PFN_xrPassthroughPauseFB pfnXrPassthroughPauseFBX;
221 PFN_xrPassthroughLayerPauseFB pfnXrPassthroughLayerResumeFBX;
222 PFN_xrPassthroughLayerResumeFB pfnXrPassthroughLayerPauseFBX;
223 PFN_xrDestroyPassthroughLayerFB pfnXrDestroyPassthroughLayerFBX;
224 PFN_xrPassthroughLayerSetStyleFB pfnXrPassthroughLayerSetStyleFB;
225 } mPassthroughFB;
226
227 struct
228 {
229 bool supported;
230 XrPassthroughHTC passthroughFeature;
231 XrCompositionLayerPassthroughHTC passthroughLayer;
232 PFN_xrCreatePassthroughHTC pfnXrCreatePassthroughHTC;
233 PFN_xrDestroyPassthroughHTC pfnXrDestroyPassthroughHTC;
234 } mPassthroughHTC;
235
236 struct
237 {
238 bool supported;
239 } mPicoController;
240
241 ControllerType mLastControllerType;
242 std::array<ControllerType, MAX_VR_CONTROLLERS> mControllerType;
243 Quaternion mPreviousHmdQuat;
244 Vector3 mPreviousHmdPos;
245 std::array<float, 2> mFov;
246 long long mFrameIndex;
247 float mLastIPD;
248 bool mPaused;
249 XrTime mPredictedDisplayTime;
250 float mScaleRatio;
251 bool mSessionRunning;
252 bool mRequestRestart;
253 bool mPoseValid;
254 bool mPassthroughEnable;
255 bool mSkipNextFrame;
256 bool mIsPico;
257public:
261 sOpenXr(RenderSystem rsys = XR_OPENGL_RENDERER, float scaleRatio = 1.0f);
262
266 ~sOpenXr();
267
268 static sOpenXr* CreateInstance(RenderSystem rsys = XR_OPENGL_RENDERER, float scale = 1.0f);
269 static sOpenXr* GetInstance();
270 static void Kill();
271
272 XrInstance GetXrInstance();
273 XrSession GetXrSession();
274 bool Connect();
275 void Disconnect();
276 bool IsConnected();
277 bool IsVisible();
278 void SetScaleRatio(float ratio);
279 bool GetHmdOrientation(Quaternion &quat);
280 bool GetHmdPosition(Vector3 &vec);
281 XrTime GetPredictedDisplayTime();
282 void SetExtensions(int extensions);
283 int GetExtensions();
284 std::string GetHmdName();
285 bool GetProjectionMatrix(VrEye eye, float nearclip, float farclip, Matrix4 &mat);
286 bool GetStereoTextureSize(unsigned int &w, unsigned int &h);
287 float GetStereoConfigFovY();
288 float GetStereoConfigIPD();
289 bool Update();
290 void UpdateTextures(SCOL_PTR_TYPE leftTexture, SCOL_PTR_TYPE rightTexture);
291 void SetState(bool state);
292
293 bool GetControllerVisibility(int id);
294 Vector3 GetControllerPosition(int id);
295 Quaternion GetControllerOrientation(int id);
296 Vector3 GetControllerVelocity(int id);
297 Vector3 GetControllerAngularVelocity(int id);
298 void SetControllerVibration(int id, float value);
299
300 std::vector<bool> GetControllerButtonsState(int id);
301 std::vector<bool> GetControllerTouchesState(int id);
302 std::vector<float> GetControllerAnalogState(int id);
303 std::array<Position, MAX_HAND_JOINTS> GetControllerBones(int id, bool &ret);
304 int GetControllerType(int id);
305 bool IsPassthroughSupported();
306 bool SetPassthroughState(bool state);
307 RenderSystem GetRenderer();
308 void SetRenderer(RenderSystem renderer);
309 void SetAppName(std::string name);
310 bool SetSceneBlendMode(XrEnvironmentBlendMode mode);
311protected:
312 void printSupportedViewConfigs();
313 void printViewconfigViewInfo();
314 void printReferenceSpaces();
315private:
316 bool initialize();
317 void cleanup();
318 bool processEvents();
319 void processActions();
320 bool initControllers();
321 void updateControllers(XrFrameState frameState);
322 void getControllerOffset(ControllerType type, VrController side, bool skeletal, Vector3 &vec, Quaternion &quat);
323 bool updatePassthrough();
324 bool createPassthrough();
325 void cleanPassthrough();
326};
327
328#endif