#[repr(C)]pub struct Hand {}
Expand description
Information about a hand! https://stereokit.net/Pages/StereoKit/Hand.html
see also Input::hand
§Examples
use stereokit_rust::{system::{Hierarchy, Input, Handed, FingerId, JointId}, util::named_colors,
maths::{Vec3, Quat, Pose, Matrix}, mesh::Mesh, material::Material};
let hand = Input::hand(Handed::Left);
let thumb_tip = hand.get(FingerId::Thumb, JointId::Tip);
let sphere = Mesh::generate_sphere(1.0, Some(12));
let mut material_sphere = Material::pbr().copy();
let main_transform = Matrix::t_r([0.0, -0.05, 0.88], [0.0, 210.0, 0.0]);
filename_scr = "screenshots/hand.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
for finger in 0..5 {
for joint in 0..5 {
let joint_pose = hand.get_u(finger, joint);
let transform = Matrix::t_s(joint_pose.position, Vec3::ONE * joint_pose.radius);
Hierarchy::push(token, main_transform, None);
sphere.draw(token, &material_sphere, transform, Some(named_colors::BLACK.into()), None);
Hierarchy::pop(token);
}
}
);

use stereokit_rust::{system::{Input, Handed, FingerId, JointId, BtnState, Hand, HandJoint},
maths::{Vec3, Quat, Pose}};
let hand = Input::hand(Handed::Left);
let thumb_tip = hand.get(FingerId::Thumb, JointId::Tip);
assert_eq!(thumb_tip.position, Vec3 { x: -0.072, y: 0.028, z: -0.055 });
let hand = Input::hand(Handed::Right);
let thumb_tip = hand.get(FingerId::Thumb, JointId::Tip);
let thumb_tip2 = hand.get_u(0,4);
let thumb_tip3 = hand.fingers[FingerId::Thumb as usize][JointId::Tip as usize];
assert_eq!(thumb_tip.position, Vec3 { x: 0.072, y: 0.028, z: -0.055 });
assert_eq!(thumb_tip, thumb_tip2);
assert_eq!(thumb_tip, thumb_tip3);
assert_eq!(hand.wrist, Pose::ZERO);
assert_eq!(hand.palm, Pose::IDENTITY);
assert_eq!(hand.aim, Pose::ZERO);
assert_eq!(hand.pinch_pt, Vec3::ZERO);
assert_eq!(hand.handed, Handed::Right);
assert_eq!(hand.tracked, BtnState::Inactive);
assert_eq!(hand.pinch, BtnState::Inactive);
assert_eq!(hand.grip, BtnState::Inactive);
assert_eq!(hand.aim_ready, BtnState::Inactive);
assert_eq!(hand.is_gripped(), false);
assert_eq!(hand.is_just_gripped(), false);
assert_eq!(hand.is_just_ungripped(), false);
assert_eq!(hand.is_pinched(), false);
assert_eq!(hand.is_just_pinched(), false);
assert_eq!(hand.is_just_unpinched(), false);
assert_eq!(hand.is_tracked(), false);
assert_eq!(hand.is_just_tracked(), false);
assert_eq!(hand.is_just_untracked(), false);
Fields§
§fingers: [[HandJoint; 5]; 5]
This is a 2D array with 25 HandJoints. You can get the right joint by finger*5 + joint
wrist: Pose
Pose of the wrist. TODO: Not populated right now.
palm: Pose
The position and orientation of the palm! Position is specifically defined as the middle of the middle finger’s root (metacarpal) bone. For orientation, Forward is the direction the flat of the palm is facing, “Iron Man” style. X+ is to the outside of the right hand, and to the inside of the left hand.
aim: Pose
A pose an orientation representing where the hand is pointing to. This may be provided by the OpenXR runtime, or be a fallback provided by StereoKit. Typically this starts and the index finger’s primary knuckle, and points in the same direction as a line drawn from the shoulder to the knuckle.
pinch_pt: Vec3
This is an approximation of where the center of a ‘pinch’ gesture occurs, and is used internally by StereoKit for some tasks, such as UI. For simulated hands, this position will give you the most stable pinch location possible. For real hands, it’ll be pretty close to the stablest point you’ll get. This is especially important for when the user begins and ends their pinch action, as you’ll often see a lot of extra movement in the fingers then.
handed: Handed
Is this a right hand, or a left hand?
tracked: BtnState
Is the hand being tracked by the sensors right now?
pinch: BtnState
Is the hand making a pinch gesture right now? Finger and thumb together.
grip: BtnState
Is the hand making a grip gesture right now? Fingers next to the palm.
aim_ready: BtnState
This is a filter state for when the hand is ready to interact with something at a distance. This often factors into account palm direction, as well as distance from the body, and the current pinch and tracked state.
size: f32
This is the size of the hand, calculated by measuring the length of the middle finger! This is calculated by adding the distances between each joint, then adding the joint radius of the root and tip. This value is recalculated at relatively frequent intervals, and can vary by as much as a centimeter.
pinch_activation: f32
What percentage of activation is the pinch gesture right now? Where 0 is a hand in an outstretched resting position, and 1 is fingers touching, within a device error tolerant threshold.
grip_activation: f32
What percentage of activation is the grip gesture right now? Where 0 is a hand in an outstretched resting position, and 1 is ring finger touching the base of the palm, within a device error tolerant threshold.
Implementations§
Source§impl Hand
impl Hand
Sourcepub fn get(&self, finger: FingerId, joint: JointId) -> HandJoint
pub fn get(&self, finger: FingerId, joint: JointId) -> HandJoint
Returns the joint information of the indicated hand joint! This also includes fingertips as a ‘joint’. This is the same as the [] operator. Note that for thumbs, there are only 4 ‘joints’ in reality, so StereoKit has JointId.Root and JointId.KnuckleMajor as the same pose, so JointId.Tip is still the tip of the thumb! https://stereokit.net/Pages/StereoKit/Hand/Get.html
Sourcepub fn get_u(&self, finger: usize, joint: usize) -> HandJoint
pub fn get_u(&self, finger: usize, joint: usize) -> HandJoint
Returns the joint information of the indicated hand joint! This also includes fingertips as a ‘joint’. This is the same as the [] operator. Note that for thumbs, there are only 4 ‘joints’ in reality, so StereoKit has JointId.Root and JointId.KnuckleMajor as the same pose, so JointId.Tip is still the tip of the thumb! https://stereokit.net/Pages/StereoKit/Hand/Get.html
Sourcepub fn is_gripped(&self) -> bool
pub fn is_gripped(&self) -> bool
Are the fingers currently gripped? https://stereokit.net/Pages/StereoKit/Hand/IsGripped.html
Sourcepub fn is_just_gripped(&self) -> bool
pub fn is_just_gripped(&self) -> bool
Have the fingers just been gripped this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustGripped.html
Sourcepub fn is_just_ungripped(&self) -> bool
pub fn is_just_ungripped(&self) -> bool
Have the fingers just stopped being gripped this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUngripped.html
Sourcepub fn is_pinched(&self) -> bool
pub fn is_pinched(&self) -> bool
Are the fingers currently pinched? https://stereokit.net/Pages/StereoKit/Hand/IsPinched.html
Sourcepub fn is_just_pinched(&self) -> bool
pub fn is_just_pinched(&self) -> bool
Have the fingers just been pinched this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustPinched.html
Sourcepub fn is_just_unpinched(&self) -> bool
pub fn is_just_unpinched(&self) -> bool
Have the fingers just stopped being pinched this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUnpinched.html
Sourcepub fn is_tracked(&self) -> bool
pub fn is_tracked(&self) -> bool
Is the hand being tracked by the sensors right now? https://stereokit.net/Pages/StereoKit/Hand/IsTracked.html
Sourcepub fn is_just_tracked(&self) -> bool
pub fn is_just_tracked(&self) -> bool
Has the hand just started being tracked this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustTracked.html
Sourcepub fn is_just_untracked(&self) -> bool
pub fn is_just_untracked(&self) -> bool
Has the hand just stopped being tracked this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUntracked.html
Sourcepub fn material(&mut self, material: impl AsRef<Material>) -> &mut Self
pub fn material(&mut self, material: impl AsRef<Material>) -> &mut Self
Set the Material used to render the hand! The default material uses an offset of 10 to ensure it gets drawn overtop of other elements. https://stereokit.net/Pages/StereoKit/Hand/Material.html
see also input_hand_material
§Examples
use stereokit_rust::{system::{Input, Handed, Hand}, material::Material, util::Color128};
let mut hand = Input::hand(Handed::Right);
let mut material = Material::hand().copy();
material.color_tint(Color128::new(0.8, 0.5, 0.1, 1.0));
hand.material(&material);
assert_ne!(material, Material::hand())
Sourcepub fn visible(&mut self, visible: bool) -> &mut Self
pub fn visible(&mut self, visible: bool) -> &mut Self
Sets whether or not StereoKit should render this hand for you. Turn this to false if you’re going to render your own, or don’t need the hand itself to be visible. https://stereokit.net/Pages/StereoKit/Hand/Visible.html
see also input_hand_visible
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Hand
impl RefUnwindSafe for Hand
impl Send for Hand
impl Sync for Hand
impl Unpin for Hand
impl UnwindSafe for Hand
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.