Struct Hand

Source
#[repr(C)]
pub struct Hand {
Show 13 fields pub fingers: [[HandJoint; 5]; 5], pub wrist: Pose, pub palm: Pose, pub aim: Pose, pub pinch_pt: Vec3, pub handed: Handed, pub tracked: BtnState, pub pinch: BtnState, pub grip: BtnState, pub aim_ready: BtnState, pub size: f32, pub pinch_activation: f32, pub grip_activation: f32,
}
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);
        }
    }
);
screenshot
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

Source

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

Source

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

Source

pub fn is_gripped(&self) -> bool

Source

pub fn is_just_gripped(&self) -> bool

Have the fingers just been gripped this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustGripped.html

Source

pub fn is_just_ungripped(&self) -> bool

Have the fingers just stopped being gripped this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUngripped.html

Source

pub fn is_pinched(&self) -> bool

Source

pub fn is_just_pinched(&self) -> bool

Have the fingers just been pinched this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustPinched.html

Source

pub fn is_just_unpinched(&self) -> bool

Have the fingers just stopped being pinched this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUnpinched.html

Source

pub fn is_tracked(&self) -> bool

Is the hand being tracked by the sensors right now? https://stereokit.net/Pages/StereoKit/Hand/IsTracked.html

Source

pub fn is_just_tracked(&self) -> bool

Has the hand just started being tracked this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustTracked.html

Source

pub fn is_just_untracked(&self) -> bool

Has the hand just stopped being tracked this frame? https://stereokit.net/Pages/StereoKit/Hand/IsJustUntracked.html

Source

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())
Source

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§

Source§

impl Clone for Hand

Source§

fn clone(&self) -> Hand

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Hand

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Copy for Hand

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more