using System.Collections; using System.Collections.Generic; using UnityEngine; using Unity.Collections; using System; using Unity.Jobs; namespace Ximmerse.XR.InputSystems { /// /// State the left / right hand /// public enum HandnessType : byte { Left = 0, Right = 1, } /// /// hand tracking info. /// [Serializable] public struct HandTrackingInfo : IDisposable { /// /// The hand tracking frame time stamp. /// public long Timestamp; /// /// is currently valid tracking state ? /// public bool IsValid; /// /// Currently tracking left or right hand. /// For T3D, one hand per frame. /// public HandnessType Handness; /// /// Palm center world position /// public Vector3 PalmPosition; /// /// The palm delta position in world space. /// public Vector3 PalmDeltaPosition; /// /// Palm velocity. /// public Vector3 PalmVelocity; /// /// Palm surface world normal ray /// public Vector3 PalmNormal; /// /// Palm scale. /// public Vector3 PalmScale; /// /// Palm world rotation /// public Quaternion PalmRotation; /// /// The palm's local position relative to main camera's parent transform. /// public Vector3 PalmLocalPosition; /// /// The palm's local rotation relative to main camera's parent transform. /// public Quaternion PalmLocalRotation; /// /// The palm's local normal relative to main camera's parent transform. /// public Vector3 PalmLocalNormal; /// /// Thumb tracking info /// public RawFingerTrackingInfo ThumbFinger; /// /// Index tracking info /// public RawFingerTrackingInfo IndexFinger; /// /// Middle tracking info /// public RawFingerTrackingInfo MiddleFinger; /// /// Ring tracking info /// public RawFingerTrackingInfo RingFinger; /// /// Little finger info /// public RawFingerTrackingInfo LittleFinger; /// /// The current gesture type of open hand/fist. /// public GestureType_Fist_OpenHand gestureFistOpenHand; /// /// The current gesture type of grisp /// public GestureType_Grisp gestureGrisp; /// /// The gesture type from native plugin. /// -1 for invalid status. /// public int NativeGestureType; public bool IsTracking; internal void UpdateProperties() { ThumbFinger.UpdateInternalProperties(); IndexFinger.UpdateInternalProperties(); MiddleFinger.UpdateInternalProperties(); RingFinger.UpdateInternalProperties(); LittleFinger.UpdateInternalProperties(); } public void Dispose() { ThumbFinger.Dispose(); IndexFinger.Dispose(); MiddleFinger.Dispose(); RingFinger.Dispose(); LittleFinger.Dispose(); } internal void CopyFrom (HandTrackingInfo other) { Timestamp = other.Timestamp; IsValid = other.IsValid; Handness = other.Handness; PalmPosition = other.PalmPosition; PalmDeltaPosition = other.PalmDeltaPosition; PalmNormal = other.PalmNormal; PalmScale = other.PalmScale; PalmRotation = other.PalmRotation; PalmLocalPosition = other.PalmLocalPosition; PalmLocalRotation = other.PalmLocalRotation; PalmLocalNormal = other.PalmLocalNormal; ThumbFinger.CopyFrom(other.ThumbFinger); IndexFinger.CopyFrom(other.IndexFinger); MiddleFinger.CopyFrom(other.MiddleFinger); RingFinger.CopyFrom(other.RingFinger); LittleFinger.CopyFrom(other.LittleFinger); gestureFistOpenHand = other.gestureFistOpenHand; gestureGrisp = other.gestureGrisp; NativeGestureType = other.NativeGestureType; } } /// /// The raw finger data. /// [Serializable] public struct RawFingerTrackingInfo : IDisposable { /// /// Position nodes of each finger joint. /// public NativeArray Positions; /// /// Local position of the each finger joint. /// public NativeArray LocalPositions; /// /// Finger straightness factor. /// /// 1 means straight, 0 means bended. /// /// public float straightness; /// /// finger bendess factor. /// public float bendness; internal float bendnessRangeMin, bendnessRangeMax; internal void UpdateInternalProperties() { if (Positions.Length == 3) { Vector3 dir21 = (Positions[2] - Positions[1]).normalized; Vector3 dir10 = (Positions[1] - Positions[0]).normalized; this.straightness = Mathf.Abs(Vector3.Dot(dir21, dir10)); } else if (Positions.Length == 4) { Vector3 dir32 = (Positions[3] - Positions[2]).normalized; Vector3 dir21 = (Positions[2] - Positions[1]).normalized; Vector3 dir10 = (Positions[1] - Positions[0]).normalized; this.straightness = Mathf.Abs(Vector3.Dot(dir32, dir21)) * Mathf.Abs(Vector3.Dot(dir21, dir10)); } this.bendness = Mathf.Clamp01((1 - Mathf.InverseLerp(bendnessRangeMin, bendnessRangeMax, straightness) - bendnessRangeMin) / (bendnessRangeMax - bendnessRangeMin)); } internal RawFingerTrackingInfo(int positionCapacity) { bendnessRangeMin = bendnessRangeMax = 0; straightness = 0; bendness = 0; Positions = new NativeArray(positionCapacity, Allocator.Persistent); LocalPositions = new NativeArray(positionCapacity, Allocator.Persistent); } public void Dispose() { if (Positions.IsCreated) { Positions.Dispose(); } if(LocalPositions.IsCreated) { LocalPositions.Dispose(); } } public void CopyFrom (RawFingerTrackingInfo other) { Positions.CopyFrom(other.Positions); LocalPositions.CopyFrom(other.LocalPositions); straightness = other.straightness; bendness = other.bendness; bendnessRangeMin = other.bendnessRangeMin; bendnessRangeMax = other.bendnessRangeMax; } } }