VTK  9.4.20250102
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
33
34class VTKRENDERINGOPENXR_EXPORT vtkOpenXRManager
35{
36public:
38
42 {
43 static vtkOpenXRManager UniqueInstance;
44 return UniqueInstance;
45 }
47
49 {
50 DebugOutput = 0,
51 WarningOutput = 1,
52 ErrorOutput = 2
53 };
54
56
60 bool XrCheckOutput(OutputLevel level, const XrResult&, const std::string& message);
62
66 struct VTKRENDERINGOPENXR_EXPORT InstanceVersion
67 {
68 std::uint16_t Major{};
69 std::uint16_t Minor{};
70 std::uint32_t Patch{};
71 };
72
78
80
84 void PrintSystemProperties(XrSystemProperties* system_properties);
86 void PrintViewConfigViewInfo(const std::vector<XrViewConfigurationView>&);
89
91
98
100
103 void Finalize();
105
107
110 std::tuple<uint32_t, uint32_t> GetRecommendedImageRectSize();
112
114
119
123 uint32_t GetViewCount()
124 {
125 return static_cast<uint32_t>(this->RenderResources->ConfigViews.size());
126 }
127
129
135
137
143 const XrPosef* GetViewPose(uint32_t eye)
144 {
145 if (eye >= this->GetViewCount())
146 {
147 return nullptr;
148 }
149 return &(this->RenderResources->Views[eye].pose);
150 }
152
154
159 const XrFovf* GetProjectionFov(uint32_t eye)
160 {
161 if (eye >= this->GetViewCount())
162 {
163 return nullptr;
164 }
165 return &(this->RenderResources->Views[eye].fov);
166 }
168
170
173 bool IsDepthExtensionSupported() { return this->OptionalExtensions.DepthExtensionSupported; }
175
177
182 bool GetShouldRenderCurrentFrame() { return this->ShouldRenderCurrentFrame; }
184
186
192
194
197 const XrSession& GetSession() { return this->Session; }
199
201
204 const XrInstance& GetXrRuntimeInstance() { return this->Instance; }
206
208
212 bool IsSessionRunning() { return this->SessionRunning; }
214
216
223
225
231 bool PrepareRendering(vtkOpenXRRenderWindow* win, void* colorTextureId, void* depthTextureId);
233
235
239 void ReleaseSwapchainImage(uint32_t eye);
241
243
247 bool EndFrame();
249
251
254 bool PollEvent(XrEventDataBuffer& eventData);
256
258
261 XrPath GetXrPath(const std::string& path);
263
264 const std::array<XrPath, 2>& GetSubactionPaths() { return this->SubactionPaths; }
265
267
270 bool CreateActionSet(const std::string& actionSetName, const std::string& localizedActionSetName);
272
274
278 bool SelectActiveActionSet(unsigned int index);
280
282
287
289
294
295 struct Action_t;
296
298
304 Action_t& actionT, const std::string& name, const std::string& localizedName);
306
308
312 const std::string& profile, std::vector<XrActionSuggestedBinding>& actionSuggestedBindings);
314
316
322
324
331 bool UpdateActionData(Action_t& action_t, int hand);
333
339 bool ApplyVibration(const Action_t& actionT, int hand, float amplitude = 0.5f,
340 float duration = 25000000.0f, float frequency = XR_FREQUENCY_UNSPECIFIED);
341
343 {
344 Inactive = -1,
345 Left = 0,
346 Right = 1,
347 Head = 2,
348 Generic = 3,
349 NumberOfControllers = 4
350 };
351
352 struct Action_t
353 {
354 XrAction Action;
355 XrActionType ActionType;
356
357 union
358 {
359 XrActionStateFloat _float;
360 XrActionStateBoolean _boolean;
361 XrActionStatePose _pose;
362 XrActionStateVector2f _vec2f;
363 } States[ControllerIndex::NumberOfControllers];
364
365 XrSpace PoseSpaces[ControllerIndex::NumberOfControllers];
366 XrSpaceLocation PoseLocations[ControllerIndex::NumberOfControllers];
367 XrSpaceVelocity PoseVelocities[ControllerIndex::NumberOfControllers];
368 };
369
371
374 void SetGraphicsStrategy(vtkOpenXRManagerGraphics* gs) { this->GraphicsStrategy = gs; }
375 vtkOpenXRManagerGraphics* GetGraphicsStrategy() { return this->GraphicsStrategy; }
377
379
382 void SetConnectionStrategy(vtkOpenXRManagerConnection* cs) { this->ConnectionStrategy = cs; }
383 vtkOpenXRManagerConnection* GetConnectionStrategy() { return this->ConnectionStrategy; }
385
387
402 void SetUseDepthExtension(bool value) { this->UseDepthExtension = value; }
403 bool GetUseDepthExtension() const { return this->UseDepthExtension; }
405
406protected:
408 ~vtkOpenXRManager() = default;
409
411
417 std::vector<const char*> SelectExtensions();
419
421
426
428
433
435
441
443
450
452
458
460
466
468
474 std::tuple<int64_t, int64_t> SelectSwapchainPixelFormats();
476
477 struct Swapchain_t;
478
480
484 Swapchain_t CreateSwapchain(int64_t format, uint32_t width, uint32_t height, uint32_t sampleCount,
485 XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags);
487
489
494
496
498
501 bool CreateOneActionSpace(const XrAction& action, const XrPath& subactionPath,
502 const XrPosef& poseInActionSpace, XrSpace& space);
504
506
511
513
517 uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain& swapchainHandle);
519
520 // Currently VTK only supports HeadMountedDisplay (HMD)
521 constexpr static XrFormFactor FormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
522
523 // Pick the view type to be stereo rather than mono or anything else
524 constexpr static XrViewConfigurationType ViewType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
525
526 // PRIMARY_STEREO view configuration always has 2 views
527 constexpr static uint32_t StereoViewCount = 2;
528
529 // Three available types: VIEW, LOCAL and STAGE. We use LOCAL space which
530 // establishes a world-locked origin, rather than VIEW space, which tracks the
531 // view origin.
532 XrReferenceSpaceType ReferenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
533
534 // Communication with the runtime happens through this instance
535 XrInstance Instance;
536
537 // A system is defined by an id and is used to create a session
538 XrSystemId SystemId;
539
540 XrSession Session;
541 XrSessionState SessionState;
543
544 // At the end of a frame, we must select en environment blend mode
545 // to tell the runtime how we want to blend the image with the user's
546 // view of the physical world. For example, in VR, we will generally
547 // choose XR_ENVIRONMENT_BLEND_MODE_OPAQUE while AR will generally
548 // choose XR_ENVIRONMENT_BLEND_MODE_ADDITIVE or XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND
549 XrEnvironmentBlendMode EnvironmentBlendMode;
550
551 // Non optional extension
552 bool RenderingBackendExtensionSupported = false;
553
555
559 struct
560 {
561 bool DepthExtensionSupported{ false };
562 bool ControllerModelExtensionSupported{ false };
563 bool UnboundedRefSpaceSupported{ false };
564 bool SpatialAnchorSupported{ false };
565 bool HandInteractionSupported{ false };
566 bool HandTrackingSupported{ false };
567 bool RemotingSupported{ false };
568 } OptionalExtensions;
570
576 {
577 XrSwapchain Swapchain;
578 int64_t Format{ 0 };
579 uint32_t Width{ 0 };
580 uint32_t Height{ 0 };
581 };
582
584
591 {
592 XrViewState ViewState{ XR_TYPE_VIEW_STATE };
593 // Each physical Display/Eye is described by a view
594 std::vector<XrView> Views;
595 // One configuration view per view : this store
596 std::vector<XrViewConfigurationView> ConfigViews;
597
598 std::vector<Swapchain_t> ColorSwapchains;
599 std::vector<Swapchain_t> DepthSwapchains;
600
601 std::vector<XrCompositionLayerProjectionView> ProjectionLayerViews;
602 std::vector<XrCompositionLayerDepthInfoKHR> DepthInfoViews;
603 };
604 std::unique_ptr<RenderResources_t> RenderResources{};
606
607 // There is one subaction path for each hand.
608 std::array<XrPath, 2> SubactionPaths;
609
610 std::vector<XrActionSet> ActionSets;
611 XrActionSet* ActiveActionSet = nullptr;
612
618
619 bool UseDepthExtension = false;
620 bool SessionRunning = false;
621 // Following each WaitAndBeginFrame operation, the OpenXR runtime may indicate
622 // whether the current frame should be rendered using the `XrFrameState.shouldRender`
623 // property. We store this information to optimize rendering and prevent unnecessary
624 // render calls. For further details, refer to:
625 // https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrFrameState.html
626 bool ShouldRenderCurrentFrame = false;
627 // If true, the function UpdateActionData will store
628 // pose velocities for pose actions
629 bool StorePoseVelocities = false;
630
632
634
635private:
636 vtkOpenXRManager(const vtkOpenXRManager&) = delete;
637 void operator=(const vtkOpenXRManager&) = delete;
638};
639
640VTK_ABI_NAMESPACE_END
641#endif
642// 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.
static InstanceVersion QueryInstanceVersion(vtkOpenXRManagerConnection *cs)
Utility function to get XrInstance runtime version for given ConnectionStrategy This function creates...
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,...
void SetUseDepthExtension(bool value)
Enable or disable XR_KHR_composition_layer_depth extension even when it is available.
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.
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 PrepareRendering(vtkOpenXRRenderWindow *win, void *colorTextureId, void *depthTextureId)
Prepare the rendering resources for the specified eye and store in colorTextureId and in depthTexture...
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 GetUseDepthExtension() const
Enable or disable XR_KHR_composition_layer_depth extension even when it is available.
bool PrintReferenceSpaces()
Utility functions to print information about OpenXR manager internal structures.
std::vector< const char * > SelectExtensions()
OpenXR Instance creation.
vtkSmartPointer< vtkOpenXRManagerGraphics > GraphicsStrategy
OpenXR rendering window.
Hold a reference to a vtkObjectBase instance.
XrActionStateVector2f _vec2f
XrActionStateBoolean _boolean
Structure representing OpenXR instance version.
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.