The open source OpenXR runtime
1// Copyright 2019-2020, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Hand Tracking API interface.
6 * @author Christoph Haag <christoph.haag@collabora.com>
7 * @author Daniel Willmott <web@dan-w.com>
8 * @author Nick Klingensmith <programmerpichu@gmail.com>
9 * @ingroup aux_tracking
10 */
11
12#include "u_hand_tracking.h"
13
14#include "math/m_mathinclude.h"
15#include "math/m_api.h"
16#include "math/m_space.h"
17#include "math/m_vec3.h"
18#include "math/m_api.h"
19
20#include "util/u_time.h"
21
22
23bool
24u_hand_joint_is_metacarpal(enum xrt_hand_joint joint)
25{
26 return joint == XRT_HAND_JOINT_LITTLE_METACARPAL || joint == XRT_HAND_JOINT_RING_METACARPAL ||
27 joint == XRT_HAND_JOINT_MIDDLE_METACARPAL || joint == XRT_HAND_JOINT_INDEX_METACARPAL ||
28 joint == XRT_HAND_JOINT_THUMB_METACARPAL;
29}
30
31bool
32u_hand_joint_is_proximal(enum xrt_hand_joint joint)
33{
34 return joint == XRT_HAND_JOINT_LITTLE_PROXIMAL || joint == XRT_HAND_JOINT_RING_PROXIMAL ||
35 joint == XRT_HAND_JOINT_MIDDLE_PROXIMAL || joint == XRT_HAND_JOINT_INDEX_PROXIMAL ||
36 joint == XRT_HAND_JOINT_THUMB_PROXIMAL;
37}
38
39bool
40u_hand_joint_is_intermediate(enum xrt_hand_joint joint)
41{
42 return joint == XRT_HAND_JOINT_LITTLE_INTERMEDIATE || joint == XRT_HAND_JOINT_RING_INTERMEDIATE ||
43 joint == XRT_HAND_JOINT_MIDDLE_INTERMEDIATE || joint == XRT_HAND_JOINT_INDEX_INTERMEDIATE;
44}
45
46bool
47u_hand_joint_is_distal(enum xrt_hand_joint joint)
48{
49 return joint == XRT_HAND_JOINT_LITTLE_DISTAL || joint == XRT_HAND_JOINT_RING_DISTAL ||
50 joint == XRT_HAND_JOINT_MIDDLE_DISTAL || joint == XRT_HAND_JOINT_INDEX_DISTAL ||
51 joint == XRT_HAND_JOINT_THUMB_DISTAL;
52}
53
54bool
55u_hand_joint_is_tip(enum xrt_hand_joint joint)
56{
57 return joint == XRT_HAND_JOINT_LITTLE_TIP || joint == XRT_HAND_JOINT_RING_TIP ||
58 joint == XRT_HAND_JOINT_MIDDLE_TIP || joint == XRT_HAND_JOINT_INDEX_TIP ||
59 joint == XRT_HAND_JOINT_THUMB_TIP;
60}
61
62bool
63u_hand_joint_is_thumb(enum xrt_hand_joint joint)
64{
65 return joint == XRT_HAND_JOINT_THUMB_METACARPAL || joint == XRT_HAND_JOINT_THUMB_PROXIMAL ||
66 joint == XRT_HAND_JOINT_THUMB_DISTAL || joint == XRT_HAND_JOINT_THUMB_TIP;
67}
68
69void
70u_hand_joints_apply_joint_width(struct xrt_hand_joint_set *set)
71{
72 // Thanks to Nick Klingensmith for this idea
73 struct xrt_hand_joint_value *gr = set->values.hand_joint_set_default;
74
75 static const float finger_joint_size[5] = {0.022f, 0.021f, 0.022f, 0.021f, 0.02f};
76 static const float hand_finger_size[5] = {1.0f, 1.0f, 0.83f, 0.75f};
77
78 static const float thumb_size[4] = {0.016f, 0.014f, 0.012f, 0.012f};
79 float mul = 1.0f;
80
81
82 for (int i = XRT_HAND_JOINT_THUMB_METACARPAL; i <= XRT_HAND_JOINT_THUMB_TIP; i++) {
83 int j = i - XRT_HAND_JOINT_THUMB_METACARPAL;
84 gr[i].radius = thumb_size[j] * mul;
85 }
86
87 for (int finger = 0; finger < 4; finger++) {
88 for (int joint = 0; joint < 5; joint++) {
89 int set_idx = finger * 5 + joint + XRT_HAND_JOINT_INDEX_METACARPAL;
90 float val = finger_joint_size[joint] * hand_finger_size[finger] * .5 * mul;
91 gr[set_idx].radius = val;
92 }
93 }
94 // The radius of each joint is the distance from the joint to the skin in meters. -OpenXR spec.
95 set->values.hand_joint_set_default[XRT_HAND_JOINT_PALM].radius =
96 .032f * .5f; // Measured my palm thickness with calipers
97 set->values.hand_joint_set_default[XRT_HAND_JOINT_WRIST].radius =
98 .040f * .5f; // Measured my wrist thickness with calipers
99}