VTK  9.2.6
vtkOpenXRManager.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkOpenXRManager.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
25 #ifndef vtkOpenXRManager_h
26 #define vtkOpenXRManager_h
27 
28 #include "vtkRenderingOpenXRModule.h" // needed for exports
29 
30 #include "vtkOpenXR.h"
31 #include "vtkSystemIncludes.h"
32 
33 #include <array>
34 #include <memory>
35 #include <string>
36 #include <vector>
37 
39 
40 class VTKRENDERINGOPENXR_EXPORT vtkOpenXRManager
41 {
42 public:
44 
48  {
49  static vtkOpenXRManager UniqueInstance;
50  return UniqueInstance;
51  }
53 
55 
59  bool XrCheckError(const XrResult&, const std::string& message);
61 
63 
67  bool XrCheckWarn(const XrResult&, const std::string& message);
69 
71 
75  void PrintSystemProperties(XrSystemProperties* system_properties);
77  void PrintViewConfigViewInfo(const std::vector<XrViewConfigurationView>&);
80 
82 
89 
91 
94  void Finalize();
96 
98 
101  std::tuple<uint32_t, uint32_t> GetRecommendedImageRectSize();
103 
107  uint32_t GetViewCount()
108  {
109  return static_cast<uint32_t>(this->RenderResources->ConfigViews.size());
110  }
111 
113 
119 
121 
127  const XrPosef* GetViewPose(uint32_t eye)
128  {
129  if (eye >= this->GetViewCount())
130  {
131  return nullptr;
132  }
133  return &(this->RenderResources->Views[eye].pose);
134  }
136 
138 
143  const XrFovf* GetProjectionFov(uint32_t eye)
144  {
145  if (eye >= this->GetViewCount())
146  {
147  return nullptr;
148  }
149  return &(this->RenderResources->Views[eye].fov);
150  }
152 
154 
157  bool IsDepthExtensionSupported() { return this->OptionalExtensions.DepthExtensionSupported; }
159 
161 
166  bool GetShouldRenderCurrentFrame() { return this->ShouldRenderCurrentFrame; }
168 
170 
174  bool BeginSession();
176 
178 
181  const XrSession& GetSession() { return this->Session; }
183 
185 
188  const XrInstance& GetXrRuntimeInstance() { return this->Instance; }
190 
192 
196  bool IsSessionRunning() { return this->SessionRunning; }
198 
200 
207 
209 
215  bool PrepareRendering(uint32_t eye, GLuint& colorTextureId, GLuint& depthTextureId);
217 
219 
223  void ReleaseSwapchainImage(uint32_t eye);
225 
227 
231  bool EndFrame();
233 
235 
238  bool PollEvent(XrEventDataBuffer& eventData);
240 
242 
245  XrPath GetXrPath(const std::string& path);
247 
248  const std::array<XrPath, 2>& GetSubactionPaths() { return this->SubactionPaths; }
249 
251 
254  bool CreateActionSet(const std::string& actionSetName, const std::string& localizedActionSetName);
256 
258 
262  bool SelectActiveActionSet(unsigned int index);
264 
266 
271 
273 
278 
279  struct Action_t;
280 
282 
288  Action_t& actionT, const std::string& name, const std::string& localizedName);
290 
292 
296  const std::string& profile, std::vector<XrActionSuggestedBinding>& actionSuggestedBindings);
298 
300 
304  bool SyncActions();
306 
308 
315  bool UpdateActionData(Action_t& action_t, const int hand);
317 
323  bool ApplyVibration(const Action_t& actionT, const int hand, const float amplitude = 0.5f,
324  const float duration = 25000000.0f, const float frequency = XR_FREQUENCY_UNSPECIFIED);
325 
327  {
328  Inactive = -1,
329  Left = 0,
330  Right = 1,
331  Head = 2,
332  Generic = 3,
333  NumberOfControllers = 4
334  };
335 
336  struct Action_t
337  {
338  XrAction Action;
339  XrActionType ActionType;
340 
341  union {
342  XrActionStateFloat _float;
343  XrActionStateBoolean _boolean;
344  XrActionStatePose _pose;
345  XrActionStateVector2f _vec2f;
346  } States[ControllerIndex::NumberOfControllers];
347 
348  XrSpace PoseSpaces[ControllerIndex::NumberOfControllers];
349  XrSpaceLocation PoseLocations[ControllerIndex::NumberOfControllers];
350  XrSpaceVelocity PoseVelocities[ControllerIndex::NumberOfControllers];
351  };
352 
353 protected:
354  vtkOpenXRManager() = default;
355  ~vtkOpenXRManager() = default;
356 
358 
364  std::vector<const char*> SelectExtensions();
366 
368 
373 
375 
378  bool CreateSystem();
380 
382 
388 
390 
398 
400 
407 
409 
415 
417 
423 
425 
432  std::tuple<int64_t, int64_t> SelectSwapchainPixelFormats();
433  const std::vector<int64_t>& GetSupportedColorFormats();
434  const std::vector<int64_t>& GetSupportedDepthFormats();
436 
437  struct SwapchainOpenGL_t;
438 
440 
444  SwapchainOpenGL_t CreateSwapchainOpenGL(int64_t format, uint32_t width, uint32_t height,
445  uint32_t sampleCount, XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags);
447 
449 
454 
456 
458 
461  bool CreateOneActionSpace(const XrAction& action, const XrPath& subactionPath,
462  const XrPosef& poseInActionSpace, XrSpace& space);
464 
466 
471 
473 
477  uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain& swapchainHandle);
479 
480  // Currently VTK only supports HeadMountedDisplay (HMD)
481  constexpr static XrFormFactor FormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
482 
483  // Pick the view type to be stereo rather than mono or anything else
484  constexpr static XrViewConfigurationType ViewType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
485 
486  // PRIMARY_STEREO view configuration always has 2 views
487  constexpr static uint32_t StereoViewCount = 2;
488 
489  // Three available types: VIEW, LOCAL and STAGE. We use LOCAL space which
490  // establishes a world-locked origin, rather than VIEW space, which tracks the
491  // view origin.
492  constexpr static XrReferenceSpaceType ReferenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
493 
494  // Communication with the runtime happens through this instance
495  XrInstance Instance;
496 
497  // A system is defined by an id and is used to create a session
498  XrSystemId SystemId;
499 
500  XrSession Session;
501  XrSessionState SessionState;
502  XrSpace ReferenceSpace;
503 
504  // At the end of a frame, we must select en environment blend mode
505  // to tell the runtime how we want to blend the image with the user's
506  // view of the physical world. For example, in VR, we will generally
507  // choose XR_ENVIRONMENT_BLEND_MODE_OPAQUE while AR will generally
508  // choose XR_ENVIRONMENT_BLEND_MODE_ADDITIVE or XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND
509  XrEnvironmentBlendMode EnvironmentBlendMode;
510 
511  // See vtkXrExtensions.h
513 
514  // Non optional extension
515  bool HasOpenGLExtension = false;
516 
518 
522  struct
523  {
524  bool DepthExtensionSupported{ false };
525  bool ControllerModelExtensionSupported{ false };
526  bool UnboundedRefSpaceSupported{ false };
527  bool SpatialAnchorSupported{ false };
528  bool HandTrackingSupported{ false };
529  } OptionalExtensions;
531 
532  std::shared_ptr<void> GraphicsBinding;
533 
538  {
539  XrSwapchain Swapchain;
540  int64_t Format{ GL_NONE };
541  uint32_t Width{ 0 };
542  uint32_t Height{ 0 };
543  std::vector<XrSwapchainImageOpenGLKHR> Images;
544  };
545 
547 
554  {
555  XrViewState ViewState{ XR_TYPE_VIEW_STATE };
556  // Each physical Display/Eye is described by a view
557  std::vector<XrView> Views;
558  // One configuration view per view : this store
559  std::vector<XrViewConfigurationView> ConfigViews;
560 
561  std::vector<SwapchainOpenGL_t> ColorSwapchains;
562  std::vector<SwapchainOpenGL_t> DepthSwapchains;
563 
564  std::vector<XrCompositionLayerProjectionView> ProjectionLayerViews;
565  std::vector<XrCompositionLayerDepthInfoKHR> DepthInfoViews;
566  };
567  std::unique_ptr<RenderResources_t> RenderResources{};
569 
570  // There is one subaction path for each hand.
571  std::array<XrPath, 2> SubactionPaths;
572 
573  std::vector<XrActionSet> ActionSets;
574  XrActionSet* ActiveActionSet = nullptr;
575 
581 
582  bool SessionRunning = false;
583  // After each WaitAndBeginFrame, the OpenXR runtime may inform us that
584  // the current frame should not be rendered. Store it to avoid a render
585  bool ShouldRenderCurrentFrame = false;
586  // If true, the function UpdateActionData will store
587  // pose velocities for pose actions
588  bool StorePoseVelocities = false;
589 
590 private:
591  vtkOpenXRManager(const vtkOpenXRManager&) = delete;
592  void operator=(const vtkOpenXRManager&) = delete;
593 };
594 
595 #endif
596 // VTK-HeaderTest-Exclude: vtkOpenXRManager.h
OpenGL rendering window.
Singleton class that holds a collection of utility functions and member variables to communicate with...
const std::vector< int64_t > & GetSupportedDepthFormats()
void PrintViewConfigViewInfo(const std::vector< XrViewConfigurationView > &)
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.
bool GetShouldRenderCurrentFrame()
Return true if the current frame should be rendered.
void PrintInstanceProperties()
Utility functions to print information about OpenXR manager internal structures.
void PrintSystemProperties(XrSystemProperties *system_properties)
bool WaitAndBeginFrame()
This function is used to start a frame.
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.
bool CreateSystem()
OpenXR System creation.
bool CheckGraphicsRequirements()
OpenXR requires checking graphics requirements before creating a session.
bool CreateReferenceSpace()
Creates the reference space of type ReferenceSpaceType that will be used to locate views.
bool IsDepthExtensionSupported()
Return true if the runtime supports the depth extension.
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.
const XrPosef * GetViewPose(uint32_t eye)
Returns a pointer to the view pose that contains the view orientation and position for the specified ...
const std::array< XrPath, 2 > & GetSubactionPaths()
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.
xr::ExtensionDispatchTable Extensions
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 ...
std::array< XrPath, 2 > SubactionPaths
vtkOpenXRManager()=default
bool SyncActions()
Update the action states using the active action set.
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 CreateGraphicsBinding(vtkOpenGLRenderWindow *helperWindow)
Create the graphics binding and store it in GraphicsBindings ptr.
bool CreateActionSet(const std::string &actionSetName, const std::string &localizedActionSetName)
Creates an action set and add it to the vector of action sets.
bool XrCheckWarn(const XrResult &, const std::string &message)
Utility function to check the XrResult, print the result message and raise a warning if the result fa...
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.
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
std::shared_ptr< void > GraphicsBinding
bool ApplyVibration(const Action_t &actionT, const int hand, const float amplitude=0.5f, const float duration=25000000.0f, const float frequency=XR_FREQUENCY_UNSPECIFIED)
Apply haptic vibration action to emit vibration on hand to emit on amplitude 0.0 to 1....
std::vector< const char * > SelectExtensions()
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 UpdateActionData(Action_t &action_t, const int hand)
Update the action data and store it in action_t.States for one hand.
bool CreateSession()
Create the session and pass the GraphicsBinding to the next pointer of the XrSessionCreateInfo.
std::vector< XrActionSet > ActionSets
SwapchainOpenGL_t CreateSwapchainOpenGL(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...
void PrintSupportedViewConfigs()
std::tuple< int64_t, int64_t > SelectSwapchainPixelFormats()
During the creation of the swapchains, we need to check the runtime available pixels formats,...
XrEnvironmentBlendMode EnvironmentBlendMode
bool LoadControllerModels()
bool SuggestActions(const std::string &profile, std::vector< XrActionSuggestedBinding > &actionSuggestedBindings)
Suggest actions stored in actionSuggestedBindings for the interaction profile profile.
std::tuple< uint32_t, uint32_t > GetRecommendedImageRectSize()
Return as a tuple the OpenXR recommended texture size to be sent to the device.
const XrInstance & GetXrRuntimeInstance()
Return the instance used to communicate with the runtime.
bool CreateSubactionPaths()
Creates one subaction path for each hand.
bool PrintReferenceSpaces()
static vtkOpenXRManager & GetInstance()
Return the singleton instance.
bool PrepareRendering(uint32_t eye, GLuint &colorTextureId, GLuint &depthTextureId)
Prepare the rendering resources for the specified eye and store in colorTextureId and in depthTexture...
const std::vector< int64_t > & GetSupportedColorFormats()
const XrSession & GetSession()
Return the OpenXR Session.
bool XrCheckError(const XrResult &, const std::string &message)
Utility function to check the XrResult, print the result message and raise an error if the result fai...
@ profile
Definition: vtkX3D.h:457
@ frequency
Definition: vtkX3D.h:365
@ height
Definition: vtkX3D.h:260
@ name
Definition: vtkX3D.h:225
@ index
Definition: vtkX3D.h:252
@ string
Definition: vtkX3D.h:496
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< XrViewConfigurationView > ConfigViews
std::vector< SwapchainOpenGL_t > DepthSwapchains
std::vector< XrCompositionLayerProjectionView > ProjectionLayerViews
std::vector< SwapchainOpenGL_t > ColorSwapchains
std::vector< XrCompositionLayerDepthInfoKHR > DepthInfoViews
Swapchain structure for OpenGL backend.
std::vector< XrSwapchainImageOpenGLKHR > Images