VTK  9.3.1
vtkOpenXRManager.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
13#ifndef vtkOpenXRManager_h
14#define vtkOpenXRManager_h
15
16#include "vtkRenderingOpenXRModule.h" // needed for exports
17
18#include "vtkNew.h"
19#include "vtkOpenXR.h"
22#include "vtkSmartPointer.h"
23
24#include <array>
25#include <cstdint>
26#include <memory>
27#include <string>
28#include <vector>
29
30VTK_ABI_NAMESPACE_BEGIN
32
33class VTKRENDERINGOPENXR_EXPORT vtkOpenXRManager
34{
35public:
37
41 {
42 static vtkOpenXRManager UniqueInstance;
43 return UniqueInstance;
44 }
46
48 {
49 DebugOutput = 0,
50 WarningOutput = 1,
51 ErrorOutput = 2
52 };
53
55
59 bool XrCheckOutput(OutputLevel level, const XrResult&, const std::string& message);
61
63
67 void PrintSystemProperties(XrSystemProperties* system_properties);
69 void PrintViewConfigViewInfo(const std::vector<XrViewConfigurationView>&);
72
74
81
83
86 void Finalize();
88
90
93 std::tuple<uint32_t, uint32_t> GetRecommendedImageRectSize();
95
97
102
106 uint32_t GetViewCount()
107 {
108 return static_cast<uint32_t>(this->RenderResources->ConfigViews.size());
109 }
110
112
118
120
126 const XrPosef* GetViewPose(uint32_t eye)
127 {
128 if (eye >= this->GetViewCount())
129 {
130 return nullptr;
131 }
132 return &(this->RenderResources->Views[eye].pose);
133 }
135
137
142 const XrFovf* GetProjectionFov(uint32_t eye)
143 {
144 if (eye >= this->GetViewCount())
145 {
146 return nullptr;
147 }
148 return &(this->RenderResources->Views[eye].fov);
149 }
151
153
156 bool IsDepthExtensionSupported() { return this->OptionalExtensions.DepthExtensionSupported; }
158
160
165 bool GetShouldRenderCurrentFrame() { return this->ShouldRenderCurrentFrame; }
167
169
175
177
180 const XrSession& GetSession() { return this->Session; }
182
184
187 const XrInstance& GetXrRuntimeInstance() { return this->Instance; }
189
191
195 bool IsSessionRunning() { return this->SessionRunning; }
197
199
206
208
214 bool PrepareRendering(uint32_t eye, void* colorTextureId, void* depthTextureId);
216
218
222 void ReleaseSwapchainImage(uint32_t eye);
224
226
230 bool EndFrame();
232
234
237 bool PollEvent(XrEventDataBuffer& eventData);
239
241
244 XrPath GetXrPath(const std::string& path);
246
247 const std::array<XrPath, 2>& GetSubactionPaths() { return this->SubactionPaths; }
248
250
253 bool CreateActionSet(const std::string& actionSetName, const std::string& localizedActionSetName);
255
257
261 bool SelectActiveActionSet(unsigned int index);
263
265
270
272
277
278 struct Action_t;
279
281
287 Action_t& actionT, const std::string& name, const std::string& localizedName);
289
291
295 const std::string& profile, std::vector<XrActionSuggestedBinding>& actionSuggestedBindings);
297
299
305
307
314 bool UpdateActionData(Action_t& action_t, int hand);
316
322 bool ApplyVibration(const Action_t& actionT, int hand, float amplitude = 0.5f,
323 float duration = 25000000.0f, float frequency = XR_FREQUENCY_UNSPECIFIED);
324
326 {
327 Inactive = -1,
328 Left = 0,
329 Right = 1,
330 Head = 2,
331 Generic = 3,
332 NumberOfControllers = 4
333 };
334
335 struct Action_t
336 {
337 XrAction Action;
338 XrActionType ActionType;
339
340 union {
341 XrActionStateFloat _float;
342 XrActionStateBoolean _boolean;
343 XrActionStatePose _pose;
344 XrActionStateVector2f _vec2f;
345 } States[ControllerIndex::NumberOfControllers];
346
347 XrSpace PoseSpaces[ControllerIndex::NumberOfControllers];
348 XrSpaceLocation PoseLocations[ControllerIndex::NumberOfControllers];
349 XrSpaceVelocity PoseVelocities[ControllerIndex::NumberOfControllers];
350 };
351
353
356 void SetGraphicsStrategy(vtkOpenXRManagerGraphics* gs) { this->GraphicsStrategy = gs; }
357 vtkOpenXRManagerGraphics* GetGraphicsStrategy() { return this->GraphicsStrategy; }
359
361
364 void SetConnectionStrategy(vtkOpenXRManagerConnection* cs) { this->ConnectionStrategy = cs; }
365 vtkOpenXRManagerConnection* GetConnectionStrategy() { return this->ConnectionStrategy; }
367
368protected:
370 ~vtkOpenXRManager() = default;
371
373
379 std::vector<const char*> SelectExtensions();
381
383
388
390
395
397
403
405
412
414
420
422
428
430
436 std::tuple<int64_t, int64_t> SelectSwapchainPixelFormats();
438
439 struct Swapchain_t;
440
442
446 Swapchain_t CreateSwapchain(int64_t format, uint32_t width, uint32_t height, uint32_t sampleCount,
447 XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags);
449
451
456
458
460
463 bool CreateOneActionSpace(const XrAction& action, const XrPath& subactionPath,
464 const XrPosef& poseInActionSpace, XrSpace& space);
466
468
473
475
479 uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain& swapchainHandle);
481
482 // Currently VTK only supports HeadMountedDisplay (HMD)
483 constexpr static XrFormFactor FormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
484
485 // Pick the view type to be stereo rather than mono or anything else
486 constexpr static XrViewConfigurationType ViewType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
487
488 // PRIMARY_STEREO view configuration always has 2 views
489 constexpr static uint32_t StereoViewCount = 2;
490
491 // Three available types: VIEW, LOCAL and STAGE. We use LOCAL space which
492 // establishes a world-locked origin, rather than VIEW space, which tracks the
493 // view origin.
494 XrReferenceSpaceType ReferenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
495
496 // Communication with the runtime happens through this instance
497 XrInstance Instance;
498
499 // A system is defined by an id and is used to create a session
500 XrSystemId SystemId;
501
502 XrSession Session;
503 XrSessionState SessionState;
505
506 // At the end of a frame, we must select en environment blend mode
507 // to tell the runtime how we want to blend the image with the user's
508 // view of the physical world. For example, in VR, we will generally
509 // choose XR_ENVIRONMENT_BLEND_MODE_OPAQUE while AR will generally
510 // choose XR_ENVIRONMENT_BLEND_MODE_ADDITIVE or XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND
511 XrEnvironmentBlendMode EnvironmentBlendMode;
512
513 // Non optional extension
514 bool RenderingBackendExtensionSupported = false;
515
517
521 struct
522 {
523 bool DepthExtensionSupported{ false };
524 bool ControllerModelExtensionSupported{ false };
525 bool UnboundedRefSpaceSupported{ false };
526 bool SpatialAnchorSupported{ false };
527 bool HandInteractionSupported{ false };
528 bool HandTrackingSupported{ false };
529 bool RemotingSupported{ false };
530 } OptionalExtensions;
532
538 {
539 XrSwapchain Swapchain;
540 int64_t Format{ 0 };
541 uint32_t Width{ 0 };
542 uint32_t Height{ 0 };
543 };
544
546
553 {
554 XrViewState ViewState{ XR_TYPE_VIEW_STATE };
555 // Each physical Display/Eye is described by a view
556 std::vector<XrView> Views;
557 // One configuration view per view : this store
558 std::vector<XrViewConfigurationView> ConfigViews;
559
560 std::vector<Swapchain_t> ColorSwapchains;
561 std::vector<Swapchain_t> DepthSwapchains;
562
563 std::vector<XrCompositionLayerProjectionView> ProjectionLayerViews;
564 std::vector<XrCompositionLayerDepthInfoKHR> DepthInfoViews;
565 };
566 std::unique_ptr<RenderResources_t> RenderResources{};
568
569 // There is one subaction path for each hand.
570 std::array<XrPath, 2> SubactionPaths;
571
572 std::vector<XrActionSet> ActionSets;
573 XrActionSet* ActiveActionSet = nullptr;
574
580
581 bool SessionRunning = false;
582 // After each WaitAndBeginFrame, the OpenXR runtime may inform us that
583 // the current frame should not be rendered. Store it to avoid a render
584 bool ShouldRenderCurrentFrame = false;
585 // If true, the function UpdateActionData will store
586 // pose velocities for pose actions
587 bool StorePoseVelocities = false;
588
590
592
593private:
594 vtkOpenXRManager(const vtkOpenXRManager&) = delete;
595 void operator=(const vtkOpenXRManager&) = delete;
596};
597
598VTK_ABI_NAMESPACE_END
599#endif
600// VTK-HeaderTest-Exclude: vtkOpenXRManager.h
OpenGL rendering window.
OpenXR manager connection no-op implementation.
OpenXR manager graphics implementation.
Singleton class that holds a collection of utility functions and member variables to communicate with...
const XrInstance & GetXrRuntimeInstance()
Return the instance used to communicate with the runtime.
void PrintViewConfigViewInfo(const std::vector< XrViewConfigurationView > &)
Utility functions to print information about OpenXR manager internal structures.
bool CreateOneActionSpace(const XrAction &action, const XrPath &subactionPath, const XrPosef &poseInActionSpace, XrSpace &space)
For pose actions, we must create an action space to locate it.
XrTime PredictedDisplayTime
Store the frame predicted display time in WaitAndBeginFrame To get the action data at this time and t...
bool Initialize(vtkOpenGLRenderWindow *)
Initialize the OpenXR SDK to render images in a virtual reality device.
bool BeginSession()
Start the OpenXR session.
void PrintOptionalExtensions()
Print the optional extensions which were found and enabled.
const XrPosef * GetViewPose(uint32_t eye)
Returns a pointer to the view pose that contains the view orientation and position for the specified ...
bool GetShouldRenderCurrentFrame()
Return true if the current frame should be rendered.
vtkOpenXRManagerGraphics * GetGraphicsStrategy()
Set/Get the rendering backend strategy.
void PrintInstanceProperties()
Utility functions to print information about OpenXR manager internal structures.
void PrintSystemProperties(XrSystemProperties *system_properties)
Utility functions to print information about OpenXR manager internal structures.
bool WaitAndBeginFrame()
This function is used to start a frame.
std::tuple< int64_t, int64_t > SelectSwapchainPixelFormats()
During the creation of the swapchains, we need to check the runtime available pixels formats,...
bool AttachSessionActionSets()
Attach all action sets in the ActionSets vector to the session.
~vtkOpenXRManager()=default
bool IsSessionRunning()
Return true if the OpenXR session is currently running, ie.
const XrFovf * GetProjectionFov(uint32_t eye)
Returns a pointer to the projection field of view for the specified eye, or nullptr if eye exceeds or...
bool CreateSystem()
OpenXR System creation.
bool CreateReferenceSpace()
Creates the reference space of type ReferenceSpaceType that will be used to locate views.
void SetGraphicsStrategy(vtkOpenXRManagerGraphics *gs)
Set/Get the rendering backend strategy.
bool IsDepthExtensionSupported()
Return true if the runtime supports the depth extension.
std::tuple< uint32_t, uint32_t > GetRecommendedImageRectSize()
Return as a tuple the OpenXR recommended texture size to be sent to the device.
uint32_t GetViewCount()
Return the number of OpenXR views (typically one per physical display / eye)
XrPath GetXrPath(const std::string &path)
Get the XrPath from the well-formed string path.
uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain &swapchainHandle)
When preparing the rendering for an eye, we must ask the runtime for a texture to draw in it.
vtkSmartPointer< vtkOpenXRManagerConnection > ConnectionStrategy
vtkOpenXRManagerConnection * GetConnectionStrategy()
Set/Get the connection strategy.
bool EndFrame()
Submit the composition layers for the predicted display time of the current frame.
bool CreateInstance()
OpenXR Instance creation.
bool PollEvent(XrEventDataBuffer &eventData)
Store in eventData the result of xrPollEvent.
static vtkOpenXRManager & GetInstance()
Return the singleton instance.
bool CreateOneAction(Action_t &actionT, const std::string &name, const std::string &localizedName)
Creates one action with name name and localizedName localizedName and store the action handle inside ...
uint32_t GetRecommendedSampleCount()
Return the recommended swapchain sample count.
std::array< XrPath, 2 > SubactionPaths
bool ApplyVibration(const Action_t &actionT, int hand, float amplitude=0.5f, float duration=25000000.0f, float frequency=XR_FREQUENCY_UNSPECIFIED)
Apply haptic vibration action to emit vibration on hand to emit on amplitude 0.0 to 1....
bool SyncActions()
Update the action states using the active action set.
bool CreateActionSet(const std::string &actionSetName, const std::string &localizedActionSetName)
Creates an action set and add it to the vector of action sets.
Swapchain_t CreateSwapchain(int64_t format, uint32_t width, uint32_t height, uint32_t sampleCount, XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags)
Create an XrSwapchain handle used to present rendered image to the user with the given parameters for...
bool CreateSystemProperties()
Enable system properties such as hand tracking, and choose environment blend modes.
bool PrepareRendering(uint32_t eye, void *colorTextureId, void *depthTextureId)
Prepare the rendering resources for the specified eye and store in colorTextureId and in depthTexture...
std::string GetOpenXRPropertiesAsString()
Return the OpenXR properties as a string, with format "RuntimeName MAJOR.MINOR.PATCH".
void Finalize()
End the OpenXR session and destroy it and the OpenXR instance.
bool XrCheckOutput(OutputLevel level, const XrResult &, const std::string &message)
Utility function to check the XrResult, print the result message as a debug, warning or error message...
void SetConnectionStrategy(vtkOpenXRManagerConnection *cs)
Set/Get the connection strategy.
void ReleaseSwapchainImage(uint32_t eye)
When the rendering in a swapchain image is done, it must be released with this function.
bool SelectActiveActionSet(unsigned int index)
Selects the current active action set from the ActionSets vector using its index.
bool CreateConfigViews()
There is one configuration view per view, and it contains the recommended texture resolution in pixel...
XrSessionState SessionState
bool CreateSwapchains()
Swapchaines creation : there is one swapchain per view / display.
void DestroyActionSets()
Iterate over and destroy all action sets that have been created.
bool CreateSession()
Create the session and pass the GraphicsBinding to the next pointer of the XrSessionCreateInfo.
std::vector< XrActionSet > ActionSets
const XrSession & GetSession()
Return the OpenXR Session.
void PrintSupportedViewConfigs()
Utility functions to print information about OpenXR manager internal structures.
const std::array< XrPath, 2 > & GetSubactionPaths()
XrEnvironmentBlendMode EnvironmentBlendMode
bool LoadControllerModels()
bool UpdateActionData(Action_t &action_t, int hand)
Update the action data and store it in action_t.States for one hand.
bool SuggestActions(const std::string &profile, std::vector< XrActionSuggestedBinding > &actionSuggestedBindings)
Suggest actions stored in actionSuggestedBindings for the interaction profile profile.
bool CreateSubactionPaths()
Creates one subaction path for each hand.
bool PrintReferenceSpaces()
Utility functions to print information about OpenXR manager internal structures.
std::vector< const char * > SelectExtensions()
OpenXR Instance creation.
vtkSmartPointer< vtkOpenXRManagerGraphics > GraphicsStrategy
Hold a reference to a vtkObjectBase instance.
XrActionStateVector2f _vec2f
XrActionStateBoolean _boolean
This struct stores all needed information to render the images and send it to the user We can't make ...
std::vector< Swapchain_t > ColorSwapchains
std::vector< XrViewConfigurationView > ConfigViews
std::vector< Swapchain_t > DepthSwapchains
std::vector< XrCompositionLayerProjectionView > ProjectionLayerViews
std::vector< XrCompositionLayerDepthInfoKHR > DepthInfoViews
Swapchain structure storing information common to all rendering backend.
Defines the OpenXR types and extensions common to all platforms.