private void UpdateHandData()

in Assets/MRTK/Providers/OpenXR/Scripts/MicrosoftArticulatedHand.cs [254:385]


        private void UpdateHandData(InputDevice inputDevice)
        {
            using (UpdateHandDataPerfMarker.Auto())
            {
                handMeshProvider?.UpdateHandMesh();

#if MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA)
                if (handTracker != null && handTracker.TryLocateHandJoints(FrameTime.OnUpdate, locations))
                {
                    foreach (HandJoint handJoint in HandJoints)
                    {
                        HandJointLocation handJointLocation = locations[(int)handJoint];

                        // We want input sources to follow the playspace, so fold in the playspace transform here to
                        // put the pose into world space.
#if MSFT_OPENXR_0_2_0_OR_NEWER
                        Vector3 position = MixedRealityPlayspace.TransformPoint(handJointLocation.Pose.position);
                        Quaternion rotation = MixedRealityPlayspace.Rotation * handJointLocation.Pose.rotation;

#else
                        Vector3 position = MixedRealityPlayspace.TransformPoint(handJointLocation.Position);
                        Quaternion rotation = MixedRealityPlayspace.Rotation * handJointLocation.Rotation;
#endif // MSFT_OPENXR_0_2_0_OR_NEWER

                        unityJointPoses[ConvertToTrackedHandJoint(handJoint)] = new MixedRealityPose(position, rotation);
                    }
#else
                if (inputDevice.TryGetFeatureValue(CommonUsages.handData, out Hand hand))
                {
                    foreach (HandFinger finger in handFingers)
                    {
                        if (hand.TryGetRootBone(out Bone rootBone))
                        {
                            ReadHandJoint(TrackedHandJoint.Wrist, rootBone);
                        }

                        if (hand.TryGetFingerBones(finger, fingerBones))
                        {
                            for (int i = 0; i < fingerBones.Count; i++)
                            {
                                ReadHandJoint(ConvertToTrackedHandJoint(finger, i), fingerBones[i]);
                            }
                        }
                    }
#endif // MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA)

                    handDefinition?.UpdateHandJoints(unityJointPoses);
                }
            }
        }

#if MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA)
        private TrackedHandJoint ConvertToTrackedHandJoint(HandJoint handJoint)
        {
            switch (handJoint)
            {
                case HandJoint.Palm: return TrackedHandJoint.Palm;
                case HandJoint.Wrist: return TrackedHandJoint.Wrist;

                case HandJoint.ThumbMetacarpal: return TrackedHandJoint.ThumbMetacarpalJoint;
                case HandJoint.ThumbProximal: return TrackedHandJoint.ThumbProximalJoint;
                case HandJoint.ThumbDistal: return TrackedHandJoint.ThumbDistalJoint;
                case HandJoint.ThumbTip: return TrackedHandJoint.ThumbTip;

                case HandJoint.IndexMetacarpal: return TrackedHandJoint.IndexMetacarpal;
                case HandJoint.IndexProximal: return TrackedHandJoint.IndexKnuckle;
                case HandJoint.IndexIntermediate: return TrackedHandJoint.IndexMiddleJoint;
                case HandJoint.IndexDistal: return TrackedHandJoint.IndexDistalJoint;
                case HandJoint.IndexTip: return TrackedHandJoint.IndexTip;

                case HandJoint.MiddleMetacarpal: return TrackedHandJoint.MiddleMetacarpal;
                case HandJoint.MiddleProximal: return TrackedHandJoint.MiddleKnuckle;
                case HandJoint.MiddleIntermediate: return TrackedHandJoint.MiddleMiddleJoint;
                case HandJoint.MiddleDistal: return TrackedHandJoint.MiddleDistalJoint;
                case HandJoint.MiddleTip: return TrackedHandJoint.MiddleTip;

                case HandJoint.RingMetacarpal: return TrackedHandJoint.RingMetacarpal;
                case HandJoint.RingProximal: return TrackedHandJoint.RingKnuckle;
                case HandJoint.RingIntermediate: return TrackedHandJoint.RingMiddleJoint;
                case HandJoint.RingDistal: return TrackedHandJoint.RingDistalJoint;
                case HandJoint.RingTip: return TrackedHandJoint.RingTip;

                case HandJoint.LittleMetacarpal: return TrackedHandJoint.PinkyMetacarpal;
                case HandJoint.LittleProximal: return TrackedHandJoint.PinkyKnuckle;
                case HandJoint.LittleIntermediate: return TrackedHandJoint.PinkyMiddleJoint;
                case HandJoint.LittleDistal: return TrackedHandJoint.PinkyDistalJoint;
                case HandJoint.LittleTip: return TrackedHandJoint.PinkyTip;

                default: return TrackedHandJoint.None;
            }
        }
#else
        private void ReadHandJoint(TrackedHandJoint trackedHandJoint, Bone bone)
        {
            bool positionAvailable = bone.TryGetPosition(out Vector3 position);
            bool rotationAvailable = bone.TryGetRotation(out Quaternion rotation);

            if (positionAvailable && rotationAvailable)
            {
                // We want input sources to follow the playspace, so fold in the playspace transform here to
                // put the pose into world space.
                position = MixedRealityPlayspace.TransformPoint(position);
                rotation = MixedRealityPlayspace.Rotation * rotation;

                unityJointPoses[trackedHandJoint] = new MixedRealityPose(position, rotation);
            }
        }

        /// <summary>
        /// Converts a Unity finger bone into an MRTK hand joint.
        /// </summary>
        /// <remarks>
        /// For HoloLens 2, Unity provides four joints for the thumb and five joints for other fingers, in index order of metacarpal (0) to tip (4).
        /// The wrist joint is provided as the hand root bone.
        /// </remarks>
        /// <param name="finger">The Unity classification of the current finger.</param>
        /// <param name="index">The Unity index of the current finger bone.</param>
        /// <returns>The current Unity finger bone converted into an MRTK joint.</returns>
        private TrackedHandJoint ConvertToTrackedHandJoint(HandFinger finger, int index)
        {
            switch (finger)
            {
                case HandFinger.Thumb: return TrackedHandJoint.ThumbMetacarpalJoint + index;
                case HandFinger.Index: return TrackedHandJoint.IndexMetacarpal + index;
                case HandFinger.Middle: return TrackedHandJoint.MiddleMetacarpal + index;
                case HandFinger.Ring: return TrackedHandJoint.RingMetacarpal + index;
                case HandFinger.Pinky: return TrackedHandJoint.PinkyMetacarpal + index;
                default: return TrackedHandJoint.None;
            }
        }
#endif // MSFT_OPENXR && (UNITY_STANDALONE_WIN || UNITY_WSA)
    }