Ocean
application/VRControllerVisualizer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_PLATFORM_META_QUEST_APPLICATION_VR_CONTROLLER_VISUALIZER_H
9 #define META_OCEAN_PLATFORM_META_QUEST_APPLICATION_VR_CONTROLLER_VISUALIZER_H
10 
13 
15 
16 #include "ocean/rendering/Engine.h"
19 
20 namespace Ocean
21 {
22 
23 namespace Platform
24 {
25 
26 namespace Meta
27 {
28 
29 namespace Quest
30 {
31 
32 namespace Application
33 {
34 
35 /**
36  * This class implements helper functions allowing to visualize the controllers of Quest headsets in an Ocean-based VR application (e.g., VRNativeApplication).
37  * @see VRNativeApplication.
38  * @ingroup platformmetaquestapplication
39  */
40 class OCEAN_PLATFORM_META_QUEST_APPLICATION_EXPORT VRControllerVisualizer : public VRVisualizer
41 {
42  public:
43 
44  /**
45  * Identifier for the different controllers
46  */
47  enum ControllerType : uint32_t
48  {
49  /// Identifier of the controller for the left hand
50  CT_LEFT = 0u,
51  /// Identifier of the controller for the right hand
52  CT_RIGHT
53  };
54 
55  /**
56  * This class implements a scoped state object allowing to reset all states of a visualizer.
57  * The state can be stored locally or states can be pushed onto a stack.
58  * @see pushState(), popState().
59  */
61  {
62  public:
63 
64  /**
65  * Default constructor.
66  */
67  ScopedState() = default;
68 
69  /**
70  * Creates a new state object.
71  * @param vrControllerVisualizer The visualizer to which this new object belongs
72  */
73  ScopedState(VRControllerVisualizer& vrControllerVisualizer);
74 
75  /**
76  * Move constructor.
77  * @param scopedState The state object to be moved
78  */
79  ScopedState(ScopedState&& scopedState);
80 
81  /**
82  * Destructs this object and releases the state.
83  */
85 
86  /**
87  * Explicitly releases this state.
88  * The properties of the owning visualizer will be reset to the situation when the state was created.
89  */
90  void release();
91 
92  /**
93  * Move operator.
94  * @param scopedState The state object to be moved
95  * @return Reference to this object
96  */
98 
99  protected:
100 
101  /**
102  * Disabled copy constructor.
103  */
104  ScopedState(const ScopedState&) = delete;
105 
106  /**
107  * Disabled assign operator.
108  * @return The reference to this object
109  */
110  ScopedState& operator=(const ScopedState&) = delete;
111 
112  protected:
113 
114  /// The visualizer to which this state object belongs.
115  VRControllerVisualizer* vrControllerVisualizer_ = nullptr;
116 
117  /// True, if the controllers where shown when this object was created.
118  bool wasShown_ = false;
119 
120  /// The length of the controller ray, when this object was created.
121  Scalar controllerRayLength_ = Scalar(0);
122  };
123 
124  /**
125  * Definition of a vector holding state objects.
126  */
127  typedef std::vector<ScopedState> ScopedStates;
128 
129  public:
130 
131  /**
132  * Default constructor, creates a new invalid visualizer.
133  */
135 
136  /**
137  * Creates a new controller visualizer and initializes the object with a given rendering engine and associated framebuffer and load the models from the specified files
138  * Rendering engine and framebuffer are necessary so that the rendering objects (like Scene, Transform, Texture2D) can be created and attached to the existing rendering objects.
139  * @param engine The rendering engine to be used, must be valid
140  * @param framebuffer The framebuffer to be used, must be valid
141  * @param leftRenderModelFilename The path to file that contains the render model of the left controller, must be valid
142  * @param rightRenderModelFilename The path to file that contains the render model of the left controller, must be valid
143  */
144  inline VRControllerVisualizer(const Rendering::EngineRef& engine, const Rendering::FramebufferRef framebuffer, const std::string& leftRenderModelFilename, const std::string& rightRenderModelFilename);
145 
146  /**
147  * Creates a new controller visualizer and initializes the object with a given rendering engine and associated framebuffer and load the models from the specified files
148  * Rendering engine and framebuffer are necessary so that the rendering objects (like Scene, Transform, Texture2D) can be created and attached to the existing rendering objects.
149  * This function is looking the files in the directory `renderModelDirectoryName`:
150  * <pre>
151  * | Device Type | Controller Type | Expected filename |
152  * |--------------------+-----------------+------------------------------|
153  * | Device::DT_QUEST | CT_LEFT | quest_controller_left.obj |
154  * | Device::DT_QUEST | CT_RIGHT | quest_controller_right.obj |
155  * | Device::DT_QUEST_2 | CT_LEFT | quest2_controller_left.obj |
156  * | Device::DT_QUEST_2 | CT_RIGHT | quest2_controller_right.obj |
157  * | Device::DT_QUEST_3 | CT_LEFT | quest3_controller_left.obj |
158  * | Device::DT_QUEST_3 | CT_RIGHT | quest3_controller_right.obj |
159  * </pre>
160  * @param engine The rendering engine to be used, must be valid
161  * @param framebuffer The framebuffer to be used, must be valid
162  * @param deviceType The device type that this object will be configured for, must not be `Device::DT_UNKNOWN`
163  * @param renderModelDirectoryName The location where render models for the specified device type will be loaded from, must be valid
164  */
165  inline VRControllerVisualizer(const Rendering::EngineRef& engine, const Rendering::FramebufferRef framebuffer, const Device::DeviceType deviceType, const std::string& renderModelDirectoryName);
166 
167  /**
168  * Move constructor
169  * @param vrControllerVisualizer Another instance of the controller visualizer that will be moved to this instance
170  */
171  inline VRControllerVisualizer(VRControllerVisualizer&& vrControllerVisualizer);
172 
173  /**
174  * Destructor
175  */
177 
178  /**
179  * Shows the controllers.
180  * @see hide().
181  */
182  inline void show();
183 
184  /**
185  * Hides the controllers.
186  * @see show().
187  */
188  inline void hide();
189 
190  /**
191  * Returns whether the controllers are shown.
192  * @return True, if succeeded
193  */
194  inline bool isShown() const;
195 
196  /**
197  * Returns the length of the controller ray.
198  * By default, the controller ray is not visible.
199  * @return The length of the controller ray, in meter, the ray is hidden for value 0, with range [0, infinity)
200  * @see setControllerRayLength().
201  */
202  inline Scalar controllerRayLength() const;
203 
204  /**
205  * Sets the length of the controller ray.
206  * @param length The length of the controller ray, in meter, the ray will be hidden for value 0, with range [0, infinity)
207  */
208  inline void setControllerRayLength(const Scalar length);
209 
210  /**
211  * Visualizes a controller of an Oculus headset at a specific location in the virtual environment (defined in relation to the world).
212  * A previous visualization can be updated by specifying the same controller again in conjunction with a new transformation.
213  * Beware: The visualizer must be created with a valid engine and framebuffer before usage.
214  * @param controllerType The identifier of the controller that will updated
215  * @param world_T_controller The transformation at which the controller will be displayed, transforming controller to world, invalid if the controller is currently not tracked
216  * @param controllerRayLength Optional explicit parameter used for the length of the controller ray, will be hidden for value 0, -1 to use the length as defined in controllerRayLength()
217  */
218  void visualizeControllerInWorld(const ControllerType controllerType, const HomogenousMatrix4& world_T_controller, const Scalar controllerRayLength = -1);
219 
220  /**
221  * Pushes a new configuration state to the stack.
222  * Each push needs to be balanced with a pop.
223  * @see popState().
224  */
225  inline void pushState();
226 
227  /**
228  * Pops the most recent state from the stack and resets the visualizer's configuration accordingly.
229  */
230  inline void popState();
231 
232  /**
233  * Releases this visualizer and all associated resources.
234  */
235  void release();
236 
237  /**
238  * Move-assignment operator
239  * @param vrControllerVisualizer Another instance of the controller visualizer that will be moved to this instance
240  */
242 
243  protected:
244 
245  /**
246  * Disabled copy constructor
247  */
249 
250  /**
251  * Loads the render models from the specified files
252  * @param leftRenderModelFilename The path to file that contains the render model of the left controller, must be valid
253  * @param rightRenderModelFilename The path to file that contains the render model of the left controller, must be valid
254  * @return True if the models have been loaded successfully
255  */
256  bool loadModels(const std::string& leftRenderModelFilename, const std::string& rightRenderModelFilename);
257 
258  /**
259  * Loads the render models from the specified files
260  * @param deviceType The device type that this object will be configured for, must not be `Device::DT_UNKNOWN`
261  * @param renderModelDirectoryName The location where render models for the specified device type will be loaded from, must be valid
262  * @return True if the models have been loaded successfully
263  */
264  bool loadModels(const Device::DeviceType deviceType, const std::string& renderModelDirectoryName);
265 
266  /**
267  * Disabled copy-assignment operator
268  * @return Reference to this object
269  */
271 
272  protected:
273 
274  /// The type of the device.
276 
277  /// The scene object of the renderer;
279 
280  /// The scene object of the renderer;
282 
283  /// The transformation of the left controller ray
285 
286  /// The transformation of the right controller ray
288 
289  /// True, if the controllers are visualized; False, if the controllers are hidden.
290  std::atomic<bool> isShown_;
291 
292  /// The length of the controller ray, in meter, the ray will be hidden for value 0, with range [0, infinity).
293  std::atomic<Scalar> controllerRayLength_ = Scalar(0);
294 
295  /// A stack of visualization states.
297 };
298 
299 inline VRControllerVisualizer::VRControllerVisualizer(const Rendering::EngineRef& engine, const Rendering::FramebufferRef framebuffer, const std::string& leftRenderModelFilename, const std::string& rightRenderModelFilename) :
300  VRVisualizer(engine, framebuffer),
301  isShown_(true),
302  controllerRayLength_(0)
303 {
304  ocean_assert(!leftRenderModelFilename.empty() && !rightRenderModelFilename.empty());
305  if (!loadModels(leftRenderModelFilename, rightRenderModelFilename))
306  {
307  Log::error() << "Failed to load the render models of the controllers";
308  }
309 }
310 
311 inline VRControllerVisualizer::VRControllerVisualizer(const Rendering::EngineRef& engine, const Rendering::FramebufferRef framebuffer, const Device::DeviceType deviceType, const std::string& renderModelDirectoryName) :
312  VRVisualizer(engine, framebuffer),
313  isShown_(true),
314  controllerRayLength_(0)
315 {
316  ocean_assert(deviceType != Device::DT_UNKNOWN);
317  ocean_assert(!renderModelDirectoryName.empty());
318 
319  if (loadModels(deviceType, renderModelDirectoryName))
320  {
321  deviceType_ = deviceType;
322  }
323  else
324  {
325  Log::error() << "Failed to load the render models of the controllers";
326  }
327 }
328 
331 {
332  *this = std::move(vrControllerVisualizer);
333 }
334 
336 {
337  isShown_ = true;
338 }
339 
341 {
342  isShown_ = false;
343 }
344 
346 {
347  return isShown_;
348 }
349 
351 {
352  return controllerRayLength_;
353 }
354 
356 {
357  controllerRayLength_ = length;
358 }
359 
361 {
362  const ScopedLock scopedLock(lock_);
363 
364  stateStack_.emplace_back(*this);
365 }
366 
368 {
369  const ScopedLock scopedLock(lock_);
370 
371  ocean_assert(!stateStack_.empty());
372 
373  stateStack_.pop_back();
374 }
375 
376 #ifdef OCEAN_PLATFORM_META_QUEST_OPENXR_USE_EXTERNAL_CONTROLLER_MODEL_FILE
377 
378 /**
379  * Returns the model file for an external controller.
380  * @param deviceType The device type associated with the external controller, must be valid
381  * @param leftModelFile The resulting model file for the left controller
382  * @param rightModelFile The resulting model file for the right controller
383  * @return True, if succeeded
384  */
385 bool VRControllerVisualizer_externalControllerModelFiles(const uint32_t deviceType, std::string& leftModelFile, std::string& rightModelFile);
386 
387 #endif // OCEAN_PLATFORM_META_QUEST_OPENXR_USE_EXTERNAL_CONTROLLER_MODEL_FILE
388 
389 }
390 
391 }
392 
393 }
394 
395 }
396 
397 }
398 
399 #endif // META_OCEAN_PLATFORM_META_QUEST_APPLICATION_VR_CONTROLLER_VISUALIZER_H
static MessageObject error()
Returns the message for error messages.
Definition: Messenger.h:1074
This class implements a scoped state object allowing to reset all states of a visualizer.
Definition: application/VRControllerVisualizer.h:61
ScopedState & operator=(ScopedState &&scopedState)
Move operator.
ScopedState(VRControllerVisualizer &vrControllerVisualizer)
Creates a new state object.
ScopedState & operator=(const ScopedState &)=delete
Disabled assign operator.
ScopedState(const ScopedState &)=delete
Disabled copy constructor.
This class implements helper functions allowing to visualize the controllers of Quest headsets in an ...
Definition: application/VRControllerVisualizer.h:41
Rendering::SceneRef leftControllerScene_
The scene object of the renderer;.
Definition: application/VRControllerVisualizer.h:278
bool loadModels(const std::string &leftRenderModelFilename, const std::string &rightRenderModelFilename)
Loads the render models from the specified files.
Rendering::TransformRef rightControllerRayTransform_
The transformation of the right controller ray.
Definition: application/VRControllerVisualizer.h:287
void visualizeControllerInWorld(const ControllerType controllerType, const HomogenousMatrix4 &world_T_controller, const Scalar controllerRayLength=-1)
Visualizes a controller of an Oculus headset at a specific location in the virtual environment (defin...
Scalar controllerRayLength() const
Returns the length of the controller ray.
Definition: application/VRControllerVisualizer.h:350
void pushState()
Pushes a new configuration state to the stack.
Definition: application/VRControllerVisualizer.h:360
VRControllerVisualizer(const VRControllerVisualizer &)=delete
Disabled copy constructor.
void popState()
Pops the most recent state from the stack and resets the visualizer's configuration accordingly.
Definition: application/VRControllerVisualizer.h:367
void setControllerRayLength(const Scalar length)
Sets the length of the controller ray.
Definition: application/VRControllerVisualizer.h:355
VRControllerVisualizer()=default
Default constructor, creates a new invalid visualizer.
std::vector< ScopedState > ScopedStates
Definition of a vector holding state objects.
Definition: application/VRControllerVisualizer.h:127
bool loadModels(const Device::DeviceType deviceType, const std::string &renderModelDirectoryName)
Loads the render models from the specified files.
Device::DeviceType deviceType_
The type of the device.
Definition: application/VRControllerVisualizer.h:275
Rendering::TransformRef leftControllerRayTransform_
The transformation of the left controller ray.
Definition: application/VRControllerVisualizer.h:284
ControllerType
Identifier for the different controllers.
Definition: application/VRControllerVisualizer.h:48
Rendering::SceneRef rightControllerScene_
The scene object of the renderer;.
Definition: application/VRControllerVisualizer.h:281
void show()
Shows the controllers.
Definition: application/VRControllerVisualizer.h:335
void release()
Releases this visualizer and all associated resources.
VRControllerVisualizer & operator=(const VRControllerVisualizer &)=delete
Disabled copy-assignment operator.
bool isShown() const
Returns whether the controllers are shown.
Definition: application/VRControllerVisualizer.h:345
VRControllerVisualizer & operator=(VRControllerVisualizer &&vrControllerVisualizer)
Move-assignment operator.
std::atomic< Scalar > controllerRayLength_
The length of the controller ray, in meter, the ray will be hidden for value 0, with range [0,...
Definition: application/VRControllerVisualizer.h:293
void hide()
Hides the controllers.
Definition: application/VRControllerVisualizer.h:340
ScopedStates stateStack_
A stack of visualization states.
Definition: application/VRControllerVisualizer.h:296
std::atomic< bool > isShown_
True, if the controllers are visualized; False, if the controllers are hidden.
Definition: application/VRControllerVisualizer.h:290
This class implements the base class for all VR visualizers allowing to visualize e....
Definition: VRVisualizer.h:43
Lock lock_
The visualizer's lock.
Definition: VRVisualizer.h:170
DeviceType
Definition of individual device types.
Definition: platform/meta/quest/Device.h:37
@ DT_UNKNOWN
Unknown device.
Definition: platform/meta/quest/Device.h:39
This class implements a scoped lock object for recursive lock objects.
Definition: Lock.h:135
float Scalar
Definition of a scalar type.
Definition: Math.h:128
bool VRControllerVisualizer_externalControllerModelFiles(const uint32_t deviceType, std::string &leftModelFile, std::string &rightModelFile)
Returns the model file for an external controller.
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15