diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-01-30 20:07:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-30 19:07:35 +0000 |
commit | 534e78db5331fbfbad7e60d72a88e9aacdc11ee4 (patch) | |
tree | 3bcd217e0e7b7fd0c91d5406a81ea241ffc4ce06 /components/shared/webxr/hand.rs | |
parent | 64b40ea70065f949d1e281bd046c56d50312f2a7 (diff) | |
download | servo-534e78db5331fbfbad7e60d72a88e9aacdc11ee4.tar.gz servo-534e78db5331fbfbad7e60d72a88e9aacdc11ee4.zip |
Merge webxr repository (#35228)
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/shared/webxr/hand.rs')
-rw-r--r-- | components/shared/webxr/hand.rs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/components/shared/webxr/hand.rs b/components/shared/webxr/hand.rs new file mode 100644 index 00000000000..fa6e8fafe80 --- /dev/null +++ b/components/shared/webxr/hand.rs @@ -0,0 +1,122 @@ +use crate::Native; +use euclid::RigidTransform3D; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[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<J> { + pub wrist: Option<J>, + pub thumb_metacarpal: Option<J>, + pub thumb_phalanx_proximal: Option<J>, + pub thumb_phalanx_distal: Option<J>, + pub thumb_phalanx_tip: Option<J>, + pub index: Finger<J>, + pub middle: Finger<J>, + pub ring: Finger<J>, + pub little: Finger<J>, +} + +#[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] +pub struct Finger<J> { + pub metacarpal: Option<J>, + pub phalanx_proximal: Option<J>, + pub phalanx_intermediate: Option<J>, + pub phalanx_distal: Option<J>, + pub phalanx_tip: Option<J>, +} + +#[derive(Copy, Clone, Debug)] +#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] +pub struct JointFrame { + pub pose: RigidTransform3D<f32, HandSpace, Native>, + pub radius: f32, +} + +impl Default for JointFrame { + fn default() -> Self { + Self { + pose: RigidTransform3D::identity(), + radius: 0., + } + } +} + +impl<J> Hand<J> { + pub fn map<R>(&self, map: impl (Fn(&Option<J>, Joint) -> Option<R>) + Copy) -> Hand<R> { + 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<J> Finger<J> { + pub fn map<R>(&self, map: impl (Fn(&Option<J>, FingerJoint) -> Option<R>) + Copy) -> Finger<R> { + 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(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "ipc", derive(serde::Serialize, serde::Deserialize))] +pub enum FingerJoint { + Metacarpal, + PhalanxProximal, + PhalanxIntermediate, + PhalanxDistal, + PhalanxTip, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[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), +} |