VTK  9.3.0
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 <memory>
26#include <string>
27#include <vector>
28
29VTK_ABI_NAMESPACE_BEGIN
31
32class VTKRENDERINGOPENXR_EXPORT vtkOpenXRManager
33{
34public:
36
40 {
41 static vtkOpenXRManager UniqueInstance;
42 return UniqueInstance;
43 }
45
47 {
48 DebugOutput = 0,
49 WarningOutput = 1,
50 ErrorOutput = 2
51 };
52
54
58 bool XrCheckOutput(OutputLevel level, const XrResult&, const std::string& message);
60
62
66 void PrintSystemProperties(XrSystemProperties* system_properties);
68 void PrintViewConfigViewInfo(const std::vector<XrViewConfigurationView>&);
71
73
80
82
85 void Finalize();
87
89
92 std::tuple<uint32_t, uint32_t> GetRecommendedImageRectSize();
94
96
101
105 uint32_t GetViewCount()
106 {
107 return static_cast<uint32_t>(this->RenderResources->ConfigViews.size());
108 }
109
111
117
119
125 const XrPosef* GetViewPose(uint32_t eye)
126 {
127 if (eye >= this->GetViewCount())
128 {
129 return nullptr;
130 }
131 return &(this->RenderResources->Views[eye].pose);
132 }
134
136
141 const XrFovf* GetProjectionFov(uint32_t eye)
142 {
143 if (eye >= this->GetViewCount())
144 {
145 return nullptr;
146 }
147 return &(this->RenderResources->Views[eye].fov);
148 }
150
152
155 bool IsDepthExtensionSupported() { return this->OptionalExtensions.DepthExtensionSupported; }
157
159
164 bool GetShouldRenderCurrentFrame() { return this->ShouldRenderCurrentFrame; }
166
168
174
176
179 const XrSession& GetSession() { return this->Session; }
181
183
186 const XrInstance& GetXrRuntimeInstance() { return this->Instance; }
188
190
194 bool IsSessionRunning() { return this->SessionRunning; }
196
198
205
207
213 bool PrepareRendering(uint32_t eye, void* colorTextureId, void* depthTextureId);
215
217
221 void ReleaseSwapchainImage(uint32_t eye);
223
225
229 bool EndFrame();
231
233
236 bool PollEvent(XrEventDataBuffer& eventData);
238
240
243 XrPath GetXrPath(const std::string& path);
245
246 const std::array<XrPath, 2>& GetSubactionPaths() { return this->SubactionPaths; }
247
249
252 bool CreateActionSet(const std::string& actionSetName, const std::string& localizedActionSetName);
254
256
260 bool SelectActiveActionSet(unsigned int index);
262
264
269
271
276
277 struct Action_t;
278
280
286 Action_t& actionT, const std::string& name, const std::string& localizedName);
288
290
294 const std::string& profile, std::vector<XrActionSuggestedBinding>& actionSuggestedBindings);
296
298
304
306
313 bool UpdateActionData(Action_t& action_t, int hand);
315
321 bool ApplyVibration(const Action_t& actionT, int hand, float amplitude = 0.5f,
322 float duration = 25000000.0f, float frequency = XR_FREQUENCY_UNSPECIFIED);
323
325 {
326 Inactive = -1,
327 Left = 0,
328 Right = 1,
329 Head = 2,
330 Generic = 3,
331 NumberOfControllers = 4
332 };
333
334 struct Action_t
335 {
336 XrAction Action;
337 XrActionType ActionType;
338
339 union {
340 XrActionStateFloat _float;
341 XrActionStateBoolean _boolean;
342 XrActionStatePose _pose;
343 XrActionStateVector2f _vec2f;
344 } States[ControllerIndex::NumberOfControllers];
345
346 XrSpace PoseSpaces[ControllerIndex::NumberOfControllers];
347 XrSpaceLocation PoseLocations[ControllerIndex::NumberOfControllers];
348 XrSpaceVelocity PoseVelocities[ControllerIndex::NumberOfControllers];
349 };
350
352
355 void SetGraphicsStrategy(vtkOpenXRManagerGraphics* gs) { this->GraphicsStrategy = gs; }
356 vtkOpenXRManagerGraphics* GetGraphicsStrategy() { return this->GraphicsStrategy; }
358
360
363 void SetConnectionStrategy(vtkOpenXRManagerConnection* cs) { this->ConnectionStrategy = cs; }
364 vtkOpenXRManagerConnection* GetConnectionStrategy() { return this->ConnectionStrategy; }
366
367protected:
369 ~vtkOpenXRManager() = default;
370
372
378 std::vector<const char*> SelectExtensions();
380
382
387
389
394
396
402
404
411
413
419
421
427
429
435 std::tuple<int64_t, int64_t> SelectSwapchainPixelFormats();
437
438 struct Swapchain_t;
439
441
445 Swapchain_t CreateSwapchain(int64_t format, uint32_t width, uint32_t height, uint32_t sampleCount,
446 XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags);
448
450
455
457
459
462 bool CreateOneActionSpace(const XrAction& action, const XrPath& subactionPath,
463 const XrPosef& poseInActionSpace, XrSpace& space);
465
467
472
474
478 uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain& swapchainHandle);
480
481 // Currently VTK only supports HeadMountedDisplay (HMD)
482 constexpr static XrFormFactor FormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
483
484 // Pick the view type to be stereo rather than mono or anything else
485 constexpr static XrViewConfigurationType ViewType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
486
487 // PRIMARY_STEREO view configuration always has 2 views
488 constexpr static uint32_t StereoViewCount = 2;
489
490 // Three available types: VIEW, LOCAL and STAGE. We use LOCAL space which
491 // establishes a world-locked origin, rather than VIEW space, which tracks the
492 // view origin.
493 XrReferenceSpaceType ReferenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
494
495 // Communication with the runtime happens through this instance
496 XrInstance Instance;
497
498 // A system is defined by an id and is used to create a session
499 XrSystemId SystemId;
500
501 XrSession Session;
502 XrSessionState SessionState;
504
505 // At the end of a frame, we must select en environment blend mode
506 // to tell the runtime how we want to blend the image with the user's
507 // view of the physical world. For example, in VR, we will generally
508 // choose XR_ENVIRONMENT_BLEND_MODE_OPAQUE while AR will generally
509 // choose XR_ENVIRONMENT_BLEND_MODE_ADDITIVE or XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND
510 XrEnvironmentBlendMode EnvironmentBlendMode;
511
512 // Non optional extension
513 bool RenderingBackendExtensionSupported = false;
514
516
520 struct
521 {
522 bool DepthExtensionSupported{ false };
523 bool ControllerModelExtensionSupported{ false };
524 bool UnboundedRefSpaceSupported{ false };
525 bool SpatialAnchorSupported{ false };
526 bool HandInteractionSupported{ false };
527 bool HandTrackingSupported{ false };
528 bool RemotingSupported{ false };
529 } OptionalExtensions;
531
537 {
538 XrSwapchain Swapchain;
539 int64_t Format{ 0 };
540 uint32_t Width{ 0 };
541 uint32_t Height{ 0 };
542 };
543
545
552 {
553 XrViewState ViewState{ XR_TYPE_VIEW_STATE };
554 // Each physical Display/Eye is described by a view
555 std::vector<XrView> Views;
556 // One configuration view per view : this store
557 std::vector<XrViewConfigurationView> ConfigViews;
558
559 std::vector<Swapchain_t> ColorSwapchains;
560 std::vector<Swapchain_t> DepthSwapchains;
561
562 std::vector<XrCompositionLayerProjectionView> ProjectionLayerViews;
563 std::vector<XrCompositionLayerDepthInfoKHR> DepthInfoViews;
564 };
565 std::unique_ptr<RenderResources_t> RenderResources{};
567
568 // There is one subaction path for each hand.
569 std::array<XrPath, 2> SubactionPaths;
570
571 std::vector<XrActionSet> ActionSets;
572 XrActionSet* ActiveActionSet = nullptr;
573
579
580 bool SessionRunning = false;
581 // After each WaitAndBeginFrame, the OpenXR runtime may inform us that
582 // the current frame should not be rendered. Store it to avoid a render
583 bool ShouldRenderCurrentFrame = false;
584 // If true, the function UpdateActionData will store
585 // pose velocities for pose actions
586 bool StorePoseVelocities = false;
587
589
591
592private:
593 vtkOpenXRManager(const vtkOpenXRManager&) = delete;
594 void operator=(const vtkOpenXRManager&) = delete;
595};
596
597VTK_ABI_NAMESPACE_END
598#endif
599// 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.