/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use euclid::RigidTransform3D; use crate::Native; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub struct HandSpace; #[derive(Clone, Debug, Default)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub struct Hand { pub wrist: Option, pub thumb_metacarpal: Option, pub thumb_phalanx_proximal: Option, pub thumb_phalanx_distal: Option, pub thumb_phalanx_tip: Option, pub index: Finger, pub middle: Finger, pub ring: Finger, pub little: Finger, } #[derive(Clone, Debug, Default)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub struct Finger { pub metacarpal: Option, pub phalanx_proximal: Option, pub phalanx_intermediate: Option, pub phalanx_distal: Option, pub phalanx_tip: Option, } #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub struct JointFrame { pub pose: RigidTransform3D, pub radius: f32, } impl Default for JointFrame { fn default() -> Self { Self { pose: RigidTransform3D::identity(), radius: 0., } } } impl Hand { pub fn map(&self, map: impl (Fn(&Option, Joint) -> Option) + Copy) -> Hand { Hand { wrist: map(&self.wrist, Joint::Wrist), thumb_metacarpal: map(&self.thumb_metacarpal, Joint::ThumbMetacarpal), thumb_phalanx_proximal: map(&self.thumb_phalanx_proximal, Joint::ThumbPhalanxProximal), thumb_phalanx_distal: map(&self.thumb_phalanx_distal, Joint::ThumbPhalanxDistal), thumb_phalanx_tip: map(&self.thumb_phalanx_tip, Joint::ThumbPhalanxTip), index: self.index.map(|f, j| map(f, Joint::Index(j))), middle: self.middle.map(|f, j| map(f, Joint::Middle(j))), ring: self.ring.map(|f, j| map(f, Joint::Ring(j))), little: self.little.map(|f, j| map(f, Joint::Little(j))), } } pub fn get(&self, joint: Joint) -> Option<&J> { match joint { Joint::Wrist => self.wrist.as_ref(), Joint::ThumbMetacarpal => self.thumb_metacarpal.as_ref(), Joint::ThumbPhalanxProximal => self.thumb_phalanx_proximal.as_ref(), Joint::ThumbPhalanxDistal => self.thumb_phalanx_distal.as_ref(), Joint::ThumbPhalanxTip => self.thumb_phalanx_tip.as_ref(), Joint::Index(f) => self.index.get(f), Joint::Middle(f) => self.middle.get(f), Joint::Ring(f) => self.ring.get(f), Joint::Little(f) => self.little.get(f), } } } impl Finger { pub fn map(&self, map: impl (Fn(&Option, FingerJoint) -> Option) + Copy) -> Finger { Finger { metacarpal: map(&self.metacarpal, FingerJoint::Metacarpal), phalanx_proximal: map(&self.phalanx_proximal, FingerJoint::PhalanxProximal), phalanx_intermediate: map(&self.phalanx_intermediate, FingerJoint::PhalanxIntermediate), phalanx_distal: map(&self.phalanx_distal, FingerJoint::PhalanxDistal), phalanx_tip: map(&self.phalanx_tip, FingerJoint::PhalanxTip), } } pub fn get(&self, joint: FingerJoint) -> Option<&J> { match joint { FingerJoint::Metacarpal => self.metacarpal.as_ref(), FingerJoint::PhalanxProximal => self.phalanx_proximal.as_ref(), FingerJoint::PhalanxIntermediate => self.phalanx_intermediate.as_ref(), FingerJoint::PhalanxDistal => self.phalanx_distal.as_ref(), FingerJoint::PhalanxTip => self.phalanx_tip.as_ref(), } } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub enum FingerJoint { Metacarpal, PhalanxProximal, PhalanxIntermediate, PhalanxDistal, PhalanxTip, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] pub enum Joint { Wrist, ThumbMetacarpal, ThumbPhalanxProximal, ThumbPhalanxDistal, ThumbPhalanxTip, Index(FingerJoint), Middle(FingerJoint), Ring(FingerJoint), Little(FingerJoint), }