Ocean
TrackedController.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_OPENXR_TRACKED_CONTROLLER_H
9 #define META_OCEAN_PLATFORM_META_QUEST_OPENXR_TRACKED_CONTROLLER_H
10 
12 
13 #include "ocean/base/Timestamp.h"
14 
16 
19 
20 namespace Ocean
21 {
22 
23 namespace Platform
24 {
25 
26 namespace Meta
27 {
28 
29 namespace Quest
30 {
31 
32 namespace OpenXR
33 {
34 
35 /**
36  * This class implements a wrapper for tracker controllers.
37  * @ingroup platformmetaquestopenxr
38  */
39 class OCEAN_PLATFORM_META_QUEST_OPENXR_EXPORT TrackedController
40 {
41  public:
42 
43  /**
44  * Definition of individual button types, may be a combintation of several buttons.
45  */
46  enum ButtonType : uint32_t
47  {
48  /// No button.
49  BT_NONE = 0u,
50 
51  /// The left X button.
52  BT_LEFT_X = 1u << 0u,
53  /// The left Y button.
54  BT_LEFT_Y = 1u << 1u,
55  /// The left trigger button.
56  BT_LEFT_TRIGGER = 1u << 2u,
57  /// The left grip button.
58  BT_LEFT_GRIP = 1u << 3u,
59  /// The left menu button.
60  BT_LEFT_MENU = 1u << 4u,
61  /// The left joystick button.
62  BT_LEFT_JOYSTICK = 1u << 5u,
63 
64  /// The right A button.
65  BT_RIGHT_A = 1u << 6u,
66  /// The right B button.
67  BT_RIGHT_B = 1u << 7u,
68  /// The right trigger button.
69  BT_RIGHT_TRIGGER = 1u << 8u,
70  /// The right grip button.
71  BT_RIGHT_GRIP = 1u << 9u,
72  /// The right system button (aka Oculus button).
73  BT_RIGHT_SYSTEM = 1u << 10u,
74  /// The right joystick button.
75  BT_RIGHT_JOYSTICK = 1u << 11u,
76 
77  /// All left buttons.
78  BT_LEFT_ALL = BT_LEFT_X | BT_LEFT_Y | BT_LEFT_TRIGGER | BT_LEFT_GRIP | BT_LEFT_MENU | BT_LEFT_JOYSTICK,
79 
80  /// All right buttons.
81  BT_RIGHT_ALL = BT_RIGHT_A | BT_RIGHT_B | BT_RIGHT_TRIGGER | BT_RIGHT_GRIP | BT_RIGHT_SYSTEM | BT_RIGHT_JOYSTICK,
82 
83  /// The end button bit, must not be used
84  BT_END = 1u << 12u,
85  };
86 
87  /**
88  * Definition of individual controller types.
89  */
90  enum ControllerType : uint32_t
91  {
92  /// An undefined controller type.
93  CT_UNDEFINED = 0u,
94  /// A left controller.
95  CT_LEFT = 1u << 0u,
96  /// A right controller.
97  CT_RIGHT = 1u << 1u,
98  /// A left controller or a right controller.
99  CT_LEFT_OR_RIGHT = CT_LEFT | CT_RIGHT
100  };
101 
102  /**
103  * Definition of a vector holding controller types.
104  */
105  typedef std::vector<ControllerType> ControllerTypes;
106 
107  protected:
108 
109  /**
110  * Definition of internal action types e.g., for vector or pose states.
111  */
112  enum ActionType : uint32_t
113  {
114  /// The left aim pose.
115  AT_LEFT_AIM = BT_END,
116  /// The left grip pose.
118  /// The right aim pose.
120  /// The right grip pose.
122 
123  /// The left joystick vector state.
125  /// The right joystick vector state.
127 
128  /// The left vibration output.
130  /// The right vibration output.
131  AT_RIGHT_VIBRATION
132  };
133 
134  /**
135  * Definition of an unordered map mapping button types to OpenXR boolean states.
136  */
137  typedef std::unordered_map<ButtonType, XrActionStateBoolean> XrActionStateMap;
138 
139  /// The number of controllers.
140  static constexpr size_t numberControllers_ = 2;
141 
142  public:
143 
144  /**
145  * Default constructor.
146  */
147  TrackedController() = default;
148 
149  /**
150  * Destructs this tracked controller object and releases all associated resources.
151  */
153 
154  /**
155  * Move constructor.
156  * @param trackedController The object to be moved
157  */
158  inline TrackedController(TrackedController&& trackedController);
159 
160  /**
161  * Initializes this controller object.
162  * @param session The OpenXR session to be used, must be valid
163  * @return True, if succeeded
164  */
165  inline bool initialize(const Platform::OpenXR::Session& session);
166 
167  /**
168  * Initializes this controller object.
169  * @param xrInstance The OpenXR instance to be used, must be valid
170  * @param xrSession The OpenXR session to be used, must be valid
171  * @return True, if succeeded
172  */
173  bool initialize(const XrInstance& xrInstance, const XrSession& xrSession);
174 
175  /**
176  * Updates the states of this object, must be called once for each new frame.
177  * @param baseSpace The base space in which the controller will be located, must be valid
178  * @param xrPredictedDisplayTime The predicted display time
179  * @return True, if succeeded
180  */
181  bool update(const XrSpace& baseSpace, const XrTime& xrPredictedDisplayTime);
182 
183  /**
184  * Returns all buttons which have been pressed recently (in the last frame).
185  * Beware: Call update() once for each frame, before calling this function.
186  * @param controllerType The type of the controller for which the state will be returned
187  * @return The buttons recently pressed
188  * @see update().
189  */
190  ButtonType buttonsPressed(const ControllerType controllerType = CT_LEFT_OR_RIGHT) const;
191 
192  /**
193  * Returns all buttons which have been released recently (in the last frame).
194  * Beware: Call update() once for each frame, before calling this function.
195  * @param controllerType The type of the controller for which the state will be returned
196  * @return The buttons recently released
197  * @see update().
198  */
199  ButtonType buttonsReleased(const ControllerType controllerType = CT_LEFT_OR_RIGHT) const;
200 
201  /**
202  * Returns all buttons which are currently pressed.
203  * Beware: Call update() once for each frame, before calling this function.
204  * @param controllerType The type of the controller for which the state will be returned
205  * @return The buttons crrently pressed
206  * @see update().
207  */
208  ButtonType buttonsState(const ControllerType controllerType = CT_LEFT_OR_RIGHT) const;
209 
210  /**
211  * Returns the tilt of the joystick buttons
212  * The tilt values range from -1.0 (left/up) to +1.0 (right/down). The value is set to 0.0, if the magnitude of the vector is < 0.1.
213  * @param controllerType The type of the controller for which the state will be returned, must be CT_LEFT or CT_RIGHT
214  * @return The tilt vector of the select joystick button, with range [-1, -1] x [1, 1]
215  */
216  Vector2 joystickTilt(const ControllerType controllerType) const;
217 
218  /**
219  * Queries the pose of a controller.
220  * @param controllerType The type of the controller for which the pose will be returned, must be CT_LEFT or CT_RIGHT
221  * @param baseSpace_T_controllerAim Optional resulting transformation between the controller's aim pose and the base space, nullptr if not of interest
222  * @param baseSpace_T_controllerGrap Optional resulting transformation between the controller's grap pose and the base space, nullptr if not of interest
223  * @return True, if pose transformation(s) could be determined
224  * @see update().
225  */
226  bool pose(const ControllerType controllerType, HomogenousMatrix4* baseSpace_T_controllerAim = nullptr, HomogenousMatrix4* baseSpace_T_controllerGrap = nullptr) const;
227 
228  /**
229  * Set the haptic vibration for the next frame.
230  * @param controllerType The controller type for which the vibration level will be set, can be CT_LEFT, or CT_RIGHT, or CT_LEFT_OR_RIGHT
231  * @param duration The duration of the vibration, in seconds, with range (0, infinity), 0 to use a short haptics pulse of minimal supported duration
232  * @param frequency The frequency in Hz, with range (0, infinity), 0 to use the default frequency
233  * @param intensity The vibration intensity, with range [0, 1]
234  * @return True, if succeeded
235  */
236  bool setVibration(const ControllerType controllerType, const double duration, const float frequency, const float intensity);
237 
238  /**
239  * Returns the controller types of all controllers currently active and handheld (e.g., with tiny movements, button or joystick changes).
240  * If a dominant controller type is defined, the dominante controller type will be returned first followed by the other type if active.
241  * @param dominantControllerType The dominant controller type, RCT_RIGHT to treat left and right equal, CT_LEFT_OR_RIGHT to return types with an undefined order
242  * @return The types of devices currently active and handheld
243  */
244  ControllerTypes activeHandheldControllers(const ControllerType dominantControllerType = CT_RIGHT) const;
245 
246  /**
247  * The action set used to determine the tracked controller states.
248  * @return The action set
249  */
250  inline Platform::OpenXR::SharedActionSet actionSet() const;
251 
252  /**
253  * Releases this tracked controller object.
254  * The entire object will be set to an invalid state.
255  */
256  void release();
257 
258  /**
259  * Returns whether this tracked controller object has been initialized and can be used.
260  * @return True, if valid and ready to use
261  */
262  bool isValid() const;
263 
264  /**
265  * Move operator.
266  * @param trackedController The object to be moved
267  * @return Reference to this object
268  */
270 
271  /**
272  * Translates button states to readable strings.
273  * @param buttons The button states
274  * @param translatedButtons The resulting translated readable strings of the individual buttons
275  */
276  static void translateButtons(const ButtonType buttons, std::vector<std::string>& translatedButtons);
277 
278  protected:
279 
280  /**
281  * Disabled copy constructor.
282  */
284 
285  /**
286  * Disabled assign operator.
287  * @return Reference to this object
288  */
290 
291  protected:
292 
293  /// The OpenXR session.
294  XrSession xrSession_ = XR_NULL_HANDLE;
295 
296  /// The OpenXR action set used to determine the controller states.
298 
299  /// The OpenXR space of the left aim pose.
301 
302  /// The OpenXR space of the left grip pose.
304 
305  /// The OpenXR space of the right aim pose.
307 
308  /// The OpenXR space of the right grip pose.
310 
311  /// The map mapping button types to boolean states.
313 
314  /// The current button states.
315  ButtonType buttonsState_ = BT_NONE;
316 
317  /// The buttons pressed since the last update.
318  ButtonType buttonsPressed_ = BT_NONE;
319 
320  /// The buttons released since the last update.
321  ButtonType buttonsReleased_ = BT_NONE;
322 
323  /// The transformation between left aim pose and the base space, invalid if unknown.
324  HomogenousMatrix4 baseSpace_T_leftAim_ = HomogenousMatrix4(false);
325 
326  /// The transformation between left grip pose and the base space, invalid if unknown.
327  HomogenousMatrix4 baseSpace_T_leftGrip_ = HomogenousMatrix4(false);
328 
329  /// The transformation between right aim pose and the base space, invalid if unknown.
330  HomogenousMatrix4 baseSpace_T_rightAim_ = HomogenousMatrix4(false);
331 
332  /// The transformation between right grip pose and the base space, invalid if unknown.
333  HomogenousMatrix4 baseSpace_T_rightGrip_ = HomogenousMatrix4(false);
334 
335  /// Tilt vector of the joystick button on the left controller.
336  Vector2 joystickVectorLeft_ = Vector2(0, 0);
337 
338  /// Tilt vector of the joystick button on the right controller.
339  Vector2 joystickVectorRight_ = Vector2(0, 0);
340 
341  /// The haptic vibration objects for the left and right controller.
342  XrHapticVibration xrHapticVibrations_[numberControllers_] = {};
343 
344  /// The types of controllers currently active and handheld.
346 
347  /// The timestamp when the left controller was active the last time.
349 
350  /// The timestamp when the right controller was active the last time.
352 
353  /// The lock object.
354  mutable Lock lock_;
355 };
356 
358 {
359  *this = std::move(trackedController);
360 }
361 
363 {
364  ocean_assert(session.isValid());
365 
366  return initialize(session.xrInstance(), session);
367 }
368 
370 {
371  const ScopedLock scopedLock(lock_);
372 
373  ocean_assert(isValid());
374 
375  return actionSet_;
376 }
377 
378 }
379 
380 }
381 
382 }
383 
384 }
385 
386 }
387 
388 #endif // META_OCEAN_PLATFORM_META_QUEST_OPENXR_TRACKED_CONTROLLER_H
This class implements a recursive lock object.
Definition: Lock.h:31
This class implements a wrapper for tracker controllers.
Definition: TrackedController.h:40
bool initialize(const XrInstance &xrInstance, const XrSession &xrSession)
Initializes this controller object.
TrackedController & operator=(const TrackedController &)=delete
Disabled assign operator.
TrackedController(const TrackedController &)=delete
Disabled copy constructor.
Timestamp rightControllerActiveTimestamp_
The timestamp when the right controller was active the last time.
Definition: TrackedController.h:351
XrActionStateMap xrActionStateMap_
The map mapping button types to boolean states.
Definition: TrackedController.h:312
ButtonType buttonsReleased(const ControllerType controllerType=CT_LEFT_OR_RIGHT) const
Returns all buttons which have been released recently (in the last frame).
Platform::OpenXR::SharedActionSet actionSet() const
The action set used to determine the tracked controller states.
Definition: TrackedController.h:369
ControllerTypes activeHandheldControllers_
The types of controllers currently active and handheld.
Definition: TrackedController.h:345
Lock lock_
The lock object.
Definition: TrackedController.h:354
std::unordered_map< ButtonType, XrActionStateBoolean > XrActionStateMap
Definition of an unordered map mapping button types to OpenXR boolean states.
Definition: TrackedController.h:137
~TrackedController()
Destructs this tracked controller object and releases all associated resources.
static void translateButtons(const ButtonType buttons, std::vector< std::string > &translatedButtons)
Translates button states to readable strings.
ActionType
Definition of internal action types e.g., for vector or pose states.
Definition: TrackedController.h:113
@ AT_RIGHT_JOYSTICK_VECTOR
The right joystick vector state.
Definition: TrackedController.h:126
@ AT_LEFT_JOYSTICK_VECTOR
The left joystick vector state.
Definition: TrackedController.h:124
@ AT_LEFT_VIBRATION
The left vibration output.
Definition: TrackedController.h:129
@ AT_RIGHT_GRIP
The right grip pose.
Definition: TrackedController.h:121
@ AT_RIGHT_AIM
The right aim pose.
Definition: TrackedController.h:119
@ AT_LEFT_GRIP
The left grip pose.
Definition: TrackedController.h:117
Timestamp leftControllerActiveTimestamp_
The timestamp when the left controller was active the last time.
Definition: TrackedController.h:348
ButtonType buttonsPressed(const ControllerType controllerType=CT_LEFT_OR_RIGHT) const
Returns all buttons which have been pressed recently (in the last frame).
TrackedController & operator=(TrackedController &&trackedController)
Move operator.
bool isValid() const
Returns whether this tracked controller object has been initialized and can be used.
Platform::OpenXR::ScopedXrSpace spaceLeftGrip_
The OpenXR space of the left grip pose.
Definition: TrackedController.h:303
ButtonType buttonsState(const ControllerType controllerType=CT_LEFT_OR_RIGHT) const
Returns all buttons which are currently pressed.
ControllerTypes activeHandheldControllers(const ControllerType dominantControllerType=CT_RIGHT) const
Returns the controller types of all controllers currently active and handheld (e.g....
ControllerType
Definition of individual controller types.
Definition: TrackedController.h:91
Platform::OpenXR::ScopedXrSpace spaceLeftAim_
The OpenXR space of the left aim pose.
Definition: TrackedController.h:300
Platform::OpenXR::SharedActionSet actionSet_
The OpenXR action set used to determine the controller states.
Definition: TrackedController.h:297
Platform::OpenXR::ScopedXrSpace spaceRightGrip_
The OpenXR space of the right grip pose.
Definition: TrackedController.h:309
Platform::OpenXR::ScopedXrSpace spaceRightAim_
The OpenXR space of the right aim pose.
Definition: TrackedController.h:306
bool initialize(const Platform::OpenXR::Session &session)
Initializes this controller object.
Definition: TrackedController.h:362
ButtonType
Definition of individual button types, may be a combintation of several buttons.
Definition: TrackedController.h:47
bool setVibration(const ControllerType controllerType, const double duration, const float frequency, const float intensity)
Set the haptic vibration for the next frame.
void release()
Releases this tracked controller object.
bool update(const XrSpace &baseSpace, const XrTime &xrPredictedDisplayTime)
Updates the states of this object, must be called once for each new frame.
bool pose(const ControllerType controllerType, HomogenousMatrix4 *baseSpace_T_controllerAim=nullptr, HomogenousMatrix4 *baseSpace_T_controllerGrap=nullptr) const
Queries the pose of a controller.
std::vector< ControllerType > ControllerTypes
Definition of a vector holding controller types.
Definition: TrackedController.h:105
Vector2 joystickTilt(const ControllerType controllerType) const
Returns the tilt of the joystick buttons The tilt values range from -1.0 (left/up) to +1....
This class wraps an OpenXR session.
Definition: Session.h:32
XrInstance xrInstance() const
Returns the OpenXR instance associated with this session.
Definition: Session.h:359
bool isValid() const
Returns whether this object holds a valid OpenXR instance.
This class implements a scoped lock object for recursive lock objects.
Definition: Lock.h:135
This class implements a timestamp.
Definition: Timestamp.h:36
HomogenousMatrixT4< Scalar > HomogenousMatrix4
Definition of the HomogenousMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag eit...
Definition: HomogenousMatrix4.h:37
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
std::shared_ptr< ActionSet > SharedActionSet
Definition of a shared pointer holding an ActionSet object.
Definition: ActionSet.h:26
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15