Monado OpenXR Runtime
Loading...
Searching...
No Matches
hg_hand_size_opt.hpp
Go to the documentation of this file.
1// Copyright 2022-2026, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Mercury hand size optimization heuristics
6 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
7 * @author Jakob Bornecrantz <jakob@collabora.com>
8 * @author Moshi Turner <moshiturner@protonmail.com>
9 * @ingroup tracking
10 */
11
12#include "kine_common.hpp"
13#include <span>
14
15namespace xrt::tracking::hand::mercury {
16
17namespace detail {} // namespace detail
18
19constexpr uint32_t kNumHands = 2;
20constexpr uint32_t kNumViews = 2;
21
22/*!
23 * Hides the details of how hand size refinement/optimization is managed.
24 *
25 */
27{
28public:
29 HandSizeRefinement() = default;
30
31 /// Should the hand size be optimized (normally)
32 bool
33 isOptimizing() const noexcept
34 {
35 return data.optimizing;
36 }
37
38 /// Y component of hand size refinement schedule.
39 float
40 getHandSizeErrorMul() const noexcept
41 {
42 return data.hand_size_refinement_schedule_y;
43 }
44
45 /// Return the current target hand size
46 float
47 getTargetHandSize() const noexcept
48 {
49 return data.target_hand_size;
50 }
51
52 /// Per-hand data that goes in a per-view structure
54 {
55 bool foundROIthisFrame = false;
56 };
57
58 /// Per-view input data structure
59 struct ViewData
60 {
61 ViewHandData viewHand[kNumHands];
62 };
63
64 /// Per-hand input data structure
65 struct HandData
66 {
67 bool this_frame_hand_detected = false;
68 bool hand_seen_before = false;
69 };
70
71 /*!
72 * Perform the updates for a single frame before running the optimizer.
73 *
74 * @param[in] views Per-view data
75 * @param[in] hands Per-hand data over all views
76 * @param[out] out_target_hand_size Populated with the current target hand size, used as optimizer input among
77 * other things.
78 *
79 * @return true if the optimizer should optimize hand size
80 */
81 bool
82 framePreOptimizer(std::span<const ViewData, kNumViews> views, std::span<const HandData, kNumHands> hands);
83
84 /*!
85 * Call after your optimizer run for a single hand.
86 *
87 * Accumulates per-hand data and also advances the schedule.
88 *
89 * @param hand_size Hand size output from the optimizer
90 * @param reprojection_error Reprojection error from the optimizer
91 * @param input Some keypoint estimator outputs
92 */
93 void
94 frameHandPostOptimizer(float hand_size, float reprojection_error, const one_frame_input &input);
95
96 /*!
97 * Finish processing for a frame, once no more hands are left.
98 *
99 * Updates target hand size if applicable.
100 */
101 void
102 framePost();
103
104 /// Reset state after a new user is found
105 void
106 newUserEvent();
107
108 /// Pointers that the debug gui wants
109 void
110 get_refinement_schedule_ptrs(float *&hand_size_refinement_schedule_x, float *&hand_size_refinement_schedule_y)
111 {
112 hand_size_refinement_schedule_x = &this->data.hand_size_refinement_schedule_x;
113 hand_size_refinement_schedule_y = &this->data.hand_size_refinement_schedule_y;
114 }
115
116private:
117 struct HandSizeRefinementData
118 {
119 float hand_size_refinement_schedule_x = 0;
120 float hand_size_refinement_schedule_y = 0;
121 bool optimizing = true;
122 float target_hand_size = STANDARD_HAND_SIZE;
123 };
124
125 /// State data reset on a new user event
126 HandSizeRefinementData data{};
127
128 struct FrameData
129 {
130 float m_accum_hand_size = 0;
131 uint8_t num_hands = 0;
132 bool any_hands_are_only_visible_in_one_view = false;
133 };
134
135 /// State data only used for a single frame
136 FrameData frameData{};
137};
138
139
140} // namespace xrt::tracking::hand::mercury
Hides the details of how hand size refinement/optimization is managed.
Definition hg_hand_size_opt.hpp:27
bool isOptimizing() const noexcept
Should the hand size be optimized (normally)
Definition hg_hand_size_opt.hpp:33
void get_refinement_schedule_ptrs(float *&hand_size_refinement_schedule_x, float *&hand_size_refinement_schedule_y)
Pointers that the debug gui wants.
Definition hg_hand_size_opt.hpp:110
float getHandSizeErrorMul() const noexcept
Y component of hand size refinement schedule.
Definition hg_hand_size_opt.hpp:40
bool framePreOptimizer(std::span< const ViewData, kNumViews > views, std::span< const HandData, kNumHands > hands)
Perform the updates for a single frame before running the optimizer.
Definition hg_hand_size_opt.cpp:17
void newUserEvent()
Reset state after a new user is found.
Definition hg_hand_size_opt.cpp:95
void frameHandPostOptimizer(float hand_size, float reprojection_error, const one_frame_input &input)
Call after your optimizer run for a single hand.
Definition hg_hand_size_opt.cpp:77
float getTargetHandSize() const noexcept
Return the current target hand size.
Definition hg_hand_size_opt.hpp:47
void framePost()
Finish processing for a frame, once no more hands are left.
Definition hg_hand_size_opt.cpp:87
Random common stuff for Mercury kinematic optimizers.
Per-hand input data structure.
Definition hg_hand_size_opt.hpp:66
Per-view input data structure.
Definition hg_hand_size_opt.hpp:60
Per-hand data that goes in a per-view structure.
Definition hg_hand_size_opt.hpp:54