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