webxr_api/
hand.rs

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