31 QSSG_ASSERT_X(!m_initialized,
"Handtracking is already initialized!",
return);
33 m_isHandTrackingSupported = ar_hand_tracking_provider_is_supported();
34 if (m_isHandTrackingSupported) {
35 ar_hand_tracking_configuration_t handTrackingConfiguration = ar_hand_tracking_configuration_create();
36 m_handTrackingProvider = ar_hand_tracking_provider_create(handTrackingConfiguration);
37 ar_data_providers_add_data_provider(dataProviders, m_handTrackingProvider);
39 qWarning(
"Hand tracking is not supported on this device.");
42 qDebug() <<
Q_FUNC_INFO <<
", Handtracking supported: " << m_isHandTrackingSupported;
92static bool setupJoint(ar_hand_skeleton_joint_name_t jointName,
const ar_hand_skeleton_t handSkeleton,
const simd_float4x4 handTransform,
QVector3D &jointPosition,
QQuaternion &jointRotation)
94 bool isTracked =
false;
95 ar_skeleton_joint_t joint = ar_hand_skeleton_get_joint_named(handSkeleton, jointName);
96 if (joint !=
nullptr) {
97 if (ar_skeleton_joint_is_tracked(joint)) {
98 simd_float4x4 jointTransform = ar_skeleton_joint_get_anchor_from_joint_transform(joint);
99 jointTransform = simd_mul(handTransform, jointTransform);
101 QMatrix4x4 transform{jointTransform.columns[0].x, jointTransform.columns[1].x, jointTransform.columns[2].x, jointTransform.columns[3].x,
102 jointTransform.columns[0].y, jointTransform.columns[1].y, jointTransform.columns[2].y, jointTransform.columns[3].y,
103 jointTransform.columns[0].z, jointTransform.columns[1].z, jointTransform.columns[2].z, jointTransform.columns[3].z,
104 0.0f, 0.0f, 0.0f, 1.0f};
113 jointPosition = jp * 100.0f;
132 ar_hand_skeleton_joint_name_forearm_arm,
135 ar_hand_skeleton_joint_name_wrist,
136 ar_hand_skeleton_joint_name_forearm_wrist,
139 ar_hand_skeleton_joint_name_thumb_knuckle,
140 ar_hand_skeleton_joint_name_thumb_intermediate_base,
141 ar_hand_skeleton_joint_name_thumb_intermediate_tip,
142 ar_hand_skeleton_joint_name_thumb_tip,
145 ar_hand_skeleton_joint_name_index_finger_metacarpal,
146 ar_hand_skeleton_joint_name_index_finger_knuckle,
147 ar_hand_skeleton_joint_name_index_finger_intermediate_base,
148 ar_hand_skeleton_joint_name_index_finger_intermediate_tip,
149 ar_hand_skeleton_joint_name_index_finger_tip,
152 ar_hand_skeleton_joint_name_middle_finger_metacarpal,
153 ar_hand_skeleton_joint_name_middle_finger_knuckle,
154 ar_hand_skeleton_joint_name_middle_finger_intermediate_base,
155 ar_hand_skeleton_joint_name_middle_finger_intermediate_tip,
156 ar_hand_skeleton_joint_name_middle_finger_tip,
159 ar_hand_skeleton_joint_name_ring_finger_metacarpal,
160 ar_hand_skeleton_joint_name_ring_finger_knuckle,
161 ar_hand_skeleton_joint_name_ring_finger_intermediate_base,
162 ar_hand_skeleton_joint_name_ring_finger_intermediate_tip,
163 ar_hand_skeleton_joint_name_ring_finger_tip,
166 ar_hand_skeleton_joint_name_little_finger_metacarpal,
167 ar_hand_skeleton_joint_name_little_finger_knuckle,
168 ar_hand_skeleton_joint_name_little_finger_intermediate_base,
169 ar_hand_skeleton_joint_name_little_finger_intermediate_tip,
170 ar_hand_skeleton_joint_name_little_finger_tip,
197 if (!m_isHandTrackingSupported)
200 QSSG_ASSERT(m_handTrackingProvider !=
nullptr,
return);
201 QSSG_ASSERT(m_handAnchors[Hand::LeftHand] !=
nullptr && m_handAnchors[Hand::RightHand] !=
nullptr,
return);
203 ar_hand_tracking_provider_get_latest_anchors(m_handTrackingProvider, m_handAnchors[Hand::LeftHand], m_handAnchors[Hand::RightHand]);
206 ar_hand_skeleton_t handSkeletons[2] {};
207 uint64_t handJointCount = 0;
208 for (
const auto hand : { Hand::LeftHand, Hand::RightHand }) {
209 handSkeletons[hand] = ar_hand_anchor_get_hand_skeleton(m_handAnchors[hand]);
210 handJointCount =
qMax(handJointCount, ar_hand_skeleton_get_joint_count(handSkeletons[hand]));
215 QSSG_CHECK(handJointCount <=
size_t(jointNames.size()));
217 for (
const auto hand : { Hand::LeftHand, Hand::RightHand }) {
218 const auto handSkeleton = handSkeletons[hand];
219 if (handSkeleton ==
nullptr) {
220 m_handInputState[hand]->setIsHandTracking(
false);
225 auto &jpositions = jcache[hand].positions;
226 auto &jrotations = jcache[hand].rotations;
231 ar_skeleton_joint_t wristJoinOrigin = ar_hand_skeleton_get_joint_named(handSkeleton, ar_hand_skeleton_joint_name_wrist);
232 const bool isWristTracked = ar_skeleton_joint_is_tracked(wristJoinOrigin);
235 const simd_float4x4 handTransform = ar_anchor_get_origin_from_anchor_transform(m_handAnchors[hand]);
238 for (
auto jointName : jointNames) {
241 if (
setupJoint(jointName, handSkeleton, handTransform, jointPosition, jointRotation)) {
242 jpositions.append(jointPosition);
243 jrotations.append(jointRotation);
249 m_handInputState[hand]->
setIsActive(isWristTracked);