VTK  9.7.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
15 #ifndef vtkOpenXRManager_h
16 #define vtkOpenXRManager_h
17 
18 #include "vtkABINamespace.h"
19 #include "vtkRenderingOpenXRModule.h" // needed for exports
20 
21 #include "vtkNew.h"
22 #include "vtkOpenXR.h"
25 #include "vtkOpenXRRenderWindow.h"
26 #include "vtkSmartPointer.h"
27 
28 #include <array>
29 #include <cstdint>
30 #include <memory>
31 #include <string>
32 #include <vector>
33 
34 VTK_ABI_NAMESPACE_BEGIN
37 VTK_ABI_NAMESPACE_END
38 
39 namespace vtk::detail
40 {
41 VTK_ABI_NAMESPACE_BEGIN
42 class VTKRENDERINGOPENXR_EXPORT vtkOpenXRManager
43 {
44 public:
46 
50  {
51  static vtkOpenXRManager UniqueInstance;
52  return UniqueInstance;
53  }
55 
57  {
58  DebugOutput = 0,
59  WarningOutput = 1,
60  ErrorOutput = 2
61  };
62 
64 
68  bool XrCheckOutput(OutputLevel level, const XrResult&, const std::string& message);
70 
72 
75  void PrintInstanceProperties();
76  void PrintSystemProperties(XrSystemProperties* system_properties);
77  void PrintSupportedViewConfigs();
78  void PrintViewConfigViewInfo(const std::vector<XrViewConfigurationView>&);
79  bool PrintReferenceSpaces();
81 
83 
90  bool Initialize(vtkOpenXRRenderWindow* xrWindow);
92 
94 
99  void Finalize();
101 
103 
106  std::tuple<uint32_t, uint32_t> GetRecommendedImageRectSize();
108 
110 
113  uint32_t GetRecommendedSampleCount();
115 
119  uint32_t GetViewCount()
120  {
121  return static_cast<uint32_t>(this->RenderResources->ConfigViews.size());
122  }
123 
125 
129  std::string GetOpenXRPropertiesAsString();
131 
133 
139  const XrPosef* GetViewPose(uint32_t eye)
140  {
141  if (eye >= this->GetViewCount())
142  {
143  return nullptr;
144  }
145  return &(this->RenderResources->Views[eye].pose);
146  }
148 
150 
155  const XrFovf* GetProjectionFov(uint32_t eye)
156  {
157  if (eye >= this->GetViewCount())
158  {
159  return nullptr;
160  }
161  return &(this->RenderResources->Views[eye].fov);
162  }
164 
166 
171  bool IsDepthExtensionSupported() { return this->OptionalExtensions.DepthExtensionSupported; }
173 
180  {
181  return this->OptionalExtensions.SceneUnderstandingSupported;
182  }
183 
185 
190  bool GetShouldRenderCurrentFrame() { return this->ShouldRenderCurrentFrame; }
192 
194 
198  bool BeginSession();
200 
202 
205  const XrSession& GetSession() { return this->Session; }
207 
209 
212  const XrInstance& GetXrRuntimeInstance() { return this->Instance; }
214 
216 
220  bool IsSessionRunning() { return this->SessionRunning; }
222 
224 
229  bool WaitAndBeginFrame();
231 
233 
239  bool PrepareRendering(vtkOpenXRRenderWindow* win, void* colorTextureId, void* depthTextureId);
241 
243 
247  void ReleaseSwapchainImage(uint32_t eye);
249 
251 
255  bool EndFrame();
257 
259 
262  bool PollEvent(XrEventDataBuffer& eventData);
264 
266 
269  XrPath GetXrPath(const std::string& path);
271 
272  const std::array<XrPath, 2>& GetSubactionPaths() { return this->SubactionPaths; }
273 
275 
278  bool CreateActionSet(const std::string& actionSetName, const std::string& localizedActionSetName);
280 
282 
286  bool SelectActiveActionSet(unsigned int index);
288 
290 
293  bool AttachSessionActionSets();
295 
297 
300  void DestroyActionSets();
302 
303  struct Action_t;
304 
306 
311  bool CreateOneAction(
312  Action_t& actionT, const std::string& name, const std::string& localizedName);
314 
316 
319  bool SuggestActions(
320  const std::string& profile, std::vector<XrActionSuggestedBinding>& actionSuggestedBindings);
322 
324 
328  bool SyncActions();
330 
332 
339  bool UpdateActionData(Action_t& action_t, int hand);
341 
347  bool ApplyVibration(const Action_t& actionT, int hand, float amplitude = 0.5,
348  float duration = 25000000.0, float frequency = XR_FREQUENCY_UNSPECIFIED);
349 
351  {
352  Inactive = -1,
353  Left = 0,
354  Right = 1,
355  Head = 2,
356  Generic = 3,
357  NumberOfControllers = 4
358  };
359 
360  struct Action_t
361  {
362  XrAction Action;
363  XrActionType ActionType;
364 
365  union
366  {
367  XrActionStateFloat _float;
368  XrActionStateBoolean _boolean;
369  XrActionStatePose _pose;
370  XrActionStateVector2f _vec2f;
371  } States[ControllerIndex::NumberOfControllers];
372 
373  XrSpace PoseSpaces[ControllerIndex::NumberOfControllers];
374  XrSpaceLocation PoseLocations[ControllerIndex::NumberOfControllers];
375  XrSpaceVelocity PoseVelocities[ControllerIndex::NumberOfControllers];
376  };
377 
379 
382  void SetGraphicsStrategy(vtkOpenXRManagerGraphics* gs) { this->GraphicsStrategy = gs; }
383  vtkOpenXRManagerGraphics* GetGraphicsStrategy() { return this->GraphicsStrategy; }
385 
387 
390  void SetConnectionStrategy(vtkOpenXRManagerConnection* cs) { this->ConnectionStrategy = cs; }
391  vtkOpenXRManagerConnection* GetConnectionStrategy() { return this->ConnectionStrategy; }
393 
397  XrSystemId GetSystemID() const { return this->SystemId; }
398 
402  XrSpace GetReferenceSpace() const { return this->ReferenceSpace; }
403 
409  XrTime GetPredictedDisplayTime() const { return this->PredictedDisplayTime; }
410 
411 protected:
413  ~vtkOpenXRManager() = default;
414 
416 
421  bool CreateInstance(vtkOpenXRRenderWindow* window);
422  std::vector<const char*> SelectExtensions(vtkOpenXRRenderWindow* window);
424 
426 
429  void PrintOptionalExtensions();
431 
433 
436  bool CreateSystem();
438 
440 
444  bool CreateSystemProperties();
446 
448 
453  bool CreateSession();
455 
457 
461  bool CreateSwapchains();
463 
465 
469  bool CreateConfigViews();
471 
473 
479  std::tuple<int64_t, int64_t> SelectSwapchainPixelFormats();
481 
482  struct Swapchain_t;
483 
485 
489  Swapchain_t CreateSwapchain(int64_t format, uint32_t width, uint32_t height, uint32_t sampleCount,
490  XrSwapchainCreateFlags createFlags, XrSwapchainUsageFlags usageFlags);
492 
494 
497  bool CreateReferenceSpace();
499 
500  bool LoadControllerModels();
501 
503 
506  bool CreateOneActionSpace(const XrAction& action, const XrPath& subactionPath,
507  const XrPosef& poseInActionSpace, XrSpace& space);
509 
511 
514  bool CreateSubactionPaths();
516 
518 
522  uint32_t WaitAndAcquireSwapchainImage(const XrSwapchain& swapchainHandle);
524 
525  // Currently VTK only supports HeadMountedDisplay (HMD)
526  constexpr static XrFormFactor FormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
527 
528  // Pick the view type to be stereo rather than mono or anything else
529  constexpr static XrViewConfigurationType ViewType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
530 
531  // PRIMARY_STEREO view configuration always has 2 views
532  constexpr static uint32_t StereoViewCount = 2;
533 
534  // Three available types: VIEW, LOCAL and STAGE. We use LOCAL space which
535  // establishes a world-locked origin, rather than VIEW space, which tracks the
536  // view origin.
537  XrReferenceSpaceType ReferenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
538 
539  // Communication with the runtime happens through this instance
540  XrInstance Instance;
541 
542  // A system is defined by an id and is used to create a session
543  XrSystemId SystemId;
544 
545  XrSession Session;
546  XrSessionState SessionState;
547  XrSpace ReferenceSpace;
548 
549  // At the end of a frame, we must select en environment blend mode
550  // to tell the runtime how we want to blend the image with the user's
551  // view of the physical world. For example, in VR, we will generally
552  // choose XR_ENVIRONMENT_BLEND_MODE_OPAQUE while AR will generally
553  // choose XR_ENVIRONMENT_BLEND_MODE_ADDITIVE or XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND
554  XrEnvironmentBlendMode EnvironmentBlendMode;
555 
556  // Non optional extension
557  bool RenderingBackendExtensionSupported = false;
558 
560 
564  struct
565  {
566  bool DepthExtensionSupported{ false };
567  bool ControllerModelExtensionSupported{ false };
568  bool UnboundedRefSpaceSupported{ false };
569  bool SpatialAnchorSupported{ false };
570  bool HandInteractionSupported{ false };
571  bool HandTrackingSupported{ false };
572  bool RemotingSupported{ false };
573  bool SceneUnderstandingSupported{ false };
574  bool SceneMarkerSupported{ false };
575  } OptionalExtensions;
577 
582  struct Swapchain_t
583  {
584  XrSwapchain Swapchain;
585  int64_t Format{ 0 };
586  uint32_t Width{ 0 };
587  uint32_t Height{ 0 };
588  };
589 
591 
598  {
599  XrViewState ViewState{ XR_TYPE_VIEW_STATE };
600  // Each physical Display/Eye is described by a view
601  std::vector<XrView> Views;
602  // One configuration view per view : this store
603  std::vector<XrViewConfigurationView> ConfigViews;
604 
605  std::vector<Swapchain_t> ColorSwapchains;
606  std::vector<Swapchain_t> DepthSwapchains;
607 
608  std::vector<XrCompositionLayerProjectionView> ProjectionLayerViews;
609  std::vector<XrCompositionLayerDepthInfoKHR> DepthInfoViews;
610  };
611  std::unique_ptr<RenderResources_t> RenderResources;
613 
614  // There is one subaction path for each hand.
615  std::array<XrPath, 2> SubactionPaths;
616 
617  std::vector<XrActionSet> ActionSets;
618  XrActionSet* ActiveActionSet = nullptr;
619 
625 
626  bool SessionRunning = false;
627  // Following each WaitAndBeginFrame operation, the OpenXR runtime may indicate
628  // whether the current frame should be rendered using the `XrFrameState.shouldRender`
629  // property. We store this information to optimize rendering and prevent unnecessary
630  // render calls. For further details, refer to:
631  // https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrFrameState.html
632  bool ShouldRenderCurrentFrame = false;
633  // If true, the function UpdateActionData will store
634  // pose velocities for pose actions
635  bool StorePoseVelocities = false;
636 
638 
640 
641 private:
642  vtkOpenXRManager(const vtkOpenXRManager&) = delete;
643  void operator=(const vtkOpenXRManager&) = delete;
644 };
645 VTK_ABI_NAMESPACE_END
646 } // namespace vtk::detail
647 
648 #endif
649 // VTK-HeaderTest-Exclude: vtkOpenXRManager.h
OpenGL rendering window.
Singleton class that holds a collection of utility functions and member variables to communicate with...
std::unique_ptr< RenderResources_t > RenderResources
std::vector< XrActionSet > ActionSets
std::vector< XrViewConfigurationView > ConfigViews
const std::array< XrPath, 2 > & GetSubactionPaths()
void SetConnectionStrategy(vtkOpenXRManagerConnection *cs)
Set/Get the connection strategy.
void SetGraphicsStrategy(vtkOpenXRManagerGraphics *gs)
Set/Get the rendering backend strategy.
uint32_t GetViewCount()
Return the number of OpenXR views (typically one per physical display / eye)
static vtkOpenXRManager & GetInstance()
Return the singleton instance.
std::array< XrPath, 2 > SubactionPaths
XrTime GetPredictedDisplayTime() const
Return runtime predicted display time for next frame.
Swapchain structure storing information common to all rendering backend.
const XrSession & GetSession()
Return the OpenXR Session.
XrSpace GetReferenceSpace() const
Return XrSpace associated with the XrSession.
XrTime PredictedDisplayTime
Store the frame predicted display time in WaitAndBeginFrame To get the action data at this time and t...
std::vector< XrCompositionLayerDepthInfoKHR > DepthInfoViews
vtkOpenXRManagerGraphics * GetGraphicsStrategy()
Set/Get the rendering backend strategy.
bool IsSessionRunning()
Return true if the OpenXR session is currently running, ie.
XrEnvironmentBlendMode EnvironmentBlendMode
This struct stores all needed information to render the images and send it to the user We can't make ...
bool GetShouldRenderCurrentFrame()
Return true if the current frame should be rendered.
vtkSmartPointer< vtkOpenXRManagerGraphics > GraphicsStrategy
vtkOpenXRManagerConnection * GetConnectionStrategy()
Set/Get the connection strategy.
const XrPosef * GetViewPose(uint32_t eye)
Returns a pointer to the view pose that contains the view orientation and position for the specified ...
OpenXR manager graphics implementation.
OpenXR manager connection no-op implementation.
std::vector< XrCompositionLayerProjectionView > ProjectionLayerViews
const XrInstance & GetXrRuntimeInstance()
Return the instance used to communicate with the runtime.
vtkSmartPointer< vtkOpenXRManagerConnection > ConnectionStrategy
XrSystemId GetSystemID() const
Return OpenXR System ID associated with the XrSession.
bool IsSceneUnderstandingSupported()
Return true if the runtime supports the scene understanding extension.
bool IsDepthExtensionSupported()
Return true if the runtime supports the depth extension.
vtkOpenXRSceneObserver is a wrapper around OpenXR scene understanding extensions
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...
Defines the OpenXR types and extensions common to all platforms.
OpenXR rendering window.