using System; using Unity.Collections; namespace UnityEngine.XR.Hands { /// /// Represents a hand from an . Do not create /// this yourself - get hand objects from the /// and properties of the . /// /// /// See [Hand tracking](xref:xrhands-tracking-data) for a description of the hand data model /// and how to access the tracking data. /// public struct XRHand : IEquatable { /// /// Retrieves an by its ID. /// /// /// The joint data is stored in an internal native array that isn't copied if you /// make a shallow copy of an XRHand object. This native array is modified each time /// A hand update occurs. Calling this function from a /// copied XRHand retrieves the latest hand data, not the data from when the /// hand object was copied. To take a snapshot of the joint data for use later, you must /// copy each individual object. /// /// ID of the required joint. /// The corresponding the ID passed in. public XRHandJoint GetJoint(XRHandJointID id) => m_Joints[id.ToIndex()]; internal NativeArray m_Joints; /// /// Root pose for the hand. /// /// Located at the wrist joint, the forward vector of the hand points in the direction /// of the fingers. public Pose rootPose => m_RootPose; internal Pose m_RootPose; /// /// Represents which hand this is. /// /// Right, left, or invalid. public Handedness handedness => m_Handedness; Handedness m_Handedness; /// /// Whether the subsystem is currently tracking this hand's root pose and joints. /// /// Indicates the tracking status as of the last hand data update. public bool isTracked { get; internal set; } /// /// Returns a string representation of the XRHand. /// /// /// String representation of the value. /// public override string ToString() { return m_Handedness + " XRHand"; } /// /// Tests for equality. /// /// The to compare against. /// /// Returns if the underlying native pointers are /// the same. Returns otherwise. /// public bool Equals(XRHand other) { return m_Joints == other.m_Joints && m_RootPose == other.m_RootPose && m_Handedness == other.m_Handedness && isTracked == other.isTracked; } /// /// Tests for equality. /// /// An to compare against. /// /// Returns if is an /// and it compares equal to this one using /// . /// public override bool Equals(object obj) => obj is XRHand other && Equals(other); /// /// Computes a hash code from all fields of XRHand. /// /// Returns a hash code of this object. public override int GetHashCode() { unchecked { int hash = m_Joints.GetHashCode(); hash = hash * 486187739 + m_RootPose.GetHashCode(); hash = hash * 486187739 + m_Handedness.GetHashCode(); hash = hash * 486187739 + isTracked.GetHashCode(); return hash; } } /// /// Tests for equality. Same as . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// Returns the same value as . public static bool operator ==(XRHand lhs, XRHand rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Same as ! /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// Returns the negation of . public static bool operator !=(XRHand lhs, XRHand rhs) => !lhs.Equals(rhs); internal XRHand(Handedness handedness, Allocator allocator) { m_RootPose = Pose.identity; m_Handedness = handedness; m_Joints = new NativeArray(XRHandJointID.EndMarker.ToIndex(), allocator); isTracked = false; } internal void Dispose() { if (m_Joints.IsCreated) m_Joints.Dispose(); } } }