1use euclid::RigidTransform3D;
6
7use crate::Native;
8
9#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
10#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
11pub struct HandSpace;
12
13#[derive(Clone, Debug, Default)]
14#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
15pub struct Hand<J> {
16 pub wrist: Option<J>,
17 pub thumb_metacarpal: Option<J>,
18 pub thumb_phalanx_proximal: Option<J>,
19 pub thumb_phalanx_distal: Option<J>,
20 pub thumb_phalanx_tip: Option<J>,
21 pub index: Finger<J>,
22 pub middle: Finger<J>,
23 pub ring: Finger<J>,
24 pub little: Finger<J>,
25}
26
27#[derive(Clone, Debug, Default)]
28#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
29pub struct Finger<J> {
30 pub metacarpal: Option<J>,
31 pub phalanx_proximal: Option<J>,
32 pub phalanx_intermediate: Option<J>,
33 pub phalanx_distal: Option<J>,
34 pub phalanx_tip: Option<J>,
35}
36
37#[derive(Clone, Copy, Debug)]
38#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
39pub struct JointFrame {
40 pub pose: RigidTransform3D<f32, HandSpace, Native>,
41 pub radius: f32,
42}
43
44impl Default for JointFrame {
45 fn default() -> Self {
46 Self {
47 pose: RigidTransform3D::identity(),
48 radius: 0.,
49 }
50 }
51}
52
53impl<J> Hand<J> {
54 pub fn map<R>(&self, map: impl (Fn(&Option<J>, Joint) -> Option<R>) + Copy) -> Hand<R> {
55 Hand {
56 wrist: map(&self.wrist, Joint::Wrist),
57 thumb_metacarpal: map(&self.thumb_metacarpal, Joint::ThumbMetacarpal),
58 thumb_phalanx_proximal: map(&self.thumb_phalanx_proximal, Joint::ThumbPhalanxProximal),
59 thumb_phalanx_distal: map(&self.thumb_phalanx_distal, Joint::ThumbPhalanxDistal),
60 thumb_phalanx_tip: map(&self.thumb_phalanx_tip, Joint::ThumbPhalanxTip),
61 index: self.index.map(|f, j| map(f, Joint::Index(j))),
62 middle: self.middle.map(|f, j| map(f, Joint::Middle(j))),
63 ring: self.ring.map(|f, j| map(f, Joint::Ring(j))),
64 little: self.little.map(|f, j| map(f, Joint::Little(j))),
65 }
66 }
67
68 pub fn get(&self, joint: Joint) -> Option<&J> {
69 match joint {
70 Joint::Wrist => self.wrist.as_ref(),
71 Joint::ThumbMetacarpal => self.thumb_metacarpal.as_ref(),
72 Joint::ThumbPhalanxProximal => self.thumb_phalanx_proximal.as_ref(),
73 Joint::ThumbPhalanxDistal => self.thumb_phalanx_distal.as_ref(),
74 Joint::ThumbPhalanxTip => self.thumb_phalanx_tip.as_ref(),
75 Joint::Index(f) => self.index.get(f),
76 Joint::Middle(f) => self.middle.get(f),
77 Joint::Ring(f) => self.ring.get(f),
78 Joint::Little(f) => self.little.get(f),
79 }
80 }
81}
82
83impl<J> Finger<J> {
84 pub fn map<R>(&self, map: impl (Fn(&Option<J>, FingerJoint) -> Option<R>) + Copy) -> Finger<R> {
85 Finger {
86 metacarpal: map(&self.metacarpal, FingerJoint::Metacarpal),
87 phalanx_proximal: map(&self.phalanx_proximal, FingerJoint::PhalanxProximal),
88 phalanx_intermediate: map(&self.phalanx_intermediate, FingerJoint::PhalanxIntermediate),
89 phalanx_distal: map(&self.phalanx_distal, FingerJoint::PhalanxDistal),
90 phalanx_tip: map(&self.phalanx_tip, FingerJoint::PhalanxTip),
91 }
92 }
93
94 pub fn get(&self, joint: FingerJoint) -> Option<&J> {
95 match joint {
96 FingerJoint::Metacarpal => self.metacarpal.as_ref(),
97 FingerJoint::PhalanxProximal => self.phalanx_proximal.as_ref(),
98 FingerJoint::PhalanxIntermediate => self.phalanx_intermediate.as_ref(),
99 FingerJoint::PhalanxDistal => self.phalanx_distal.as_ref(),
100 FingerJoint::PhalanxTip => self.phalanx_tip.as_ref(),
101 }
102 }
103}
104
105#[derive(Clone, Copy, Debug, Eq, PartialEq)]
106#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
107pub enum FingerJoint {
108 Metacarpal,
109 PhalanxProximal,
110 PhalanxIntermediate,
111 PhalanxDistal,
112 PhalanxTip,
113}
114
115#[derive(Clone, Copy, Debug, Eq, PartialEq)]
116#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))]
117pub enum Joint {
118 Wrist,
119 ThumbMetacarpal,
120 ThumbPhalanxProximal,
121 ThumbPhalanxDistal,
122 ThumbPhalanxTip,
123 Index(FingerJoint),
124 Middle(FingerJoint),
125 Ring(FingerJoint),
126 Little(FingerJoint),
127}