Exemple #1
0
        void Update()
        {
            if (!EditorApplication.isPlaying && SupportsEditorPersistence())
            {
                Transform           editorPoseSpace;
                LeapServiceProvider leapServiceProvider = FindObjectOfType <LeapServiceProvider>();
                LeapTransform       poseTransform       = LeapTransform.Identity;
                if (leapServiceProvider != null)
                {
                    editorPoseSpace = leapServiceProvider.transform;
                    poseTransform   = TestHandFactory.GetTestPoseLeftHandTransform(leapServiceProvider.editTimePose);
                }
                else
                {
                    editorPoseSpace = transform;
                }

                Hand hand = TestHandFactory.MakeTestHand(Handedness == Chirality.Left, poseTransform).TransformedCopy(UnityMatrixExtension.GetLeapMatrix(editorPoseSpace));
                //Hand hand = TestHandFactory.MakeTestHand(0, 0, Handedness == Chirality.Left).TransformedCopy(UnityMatrixExtension.GetLeapMatrix(editorPoseSpace));

                if (GetLeapHand() == null)
                {
                    SetLeapHand(hand);
                    InitHand();
                    BeginHand();
                    UpdateHand();
                }
                else
                {
                    SetLeapHand(hand);
                    UpdateHand();
                }
            }
        }
        /// <summary>
        /// Estimate the rotation offset needed to get the rigged hand into the same orientation as the leap hand
        /// </summary>
        public static void EstimateWristRotationOffset(HandBinder handBinder)
        {
            //Try to using the meta first
            Transform indexBone  = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_INDEX].boundBones[(int)Bone.BoneType.TYPE_METACARPAL].boundTransform;
            Transform middleBone = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_MIDDLE].boundBones[(int)Bone.BoneType.TYPE_METACARPAL].boundTransform;
            Transform pinkyBone  = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_PINKY].boundBones[(int)Bone.BoneType.TYPE_METACARPAL].boundTransform;

            //If the meta does not exist, use the proximal bones
            if (indexBone == null || middleBone == null || pinkyBone == null)
            {
                indexBone  = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_INDEX].boundBones[(int)Bone.BoneType.TYPE_PROXIMAL].boundTransform;
                middleBone = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_MIDDLE].boundBones[(int)Bone.BoneType.TYPE_PROXIMAL].boundTransform;
                pinkyBone  = handBinder.boundHand.fingers[(int)Finger.FingerType.TYPE_PINKY].boundBones[(int)Bone.BoneType.TYPE_PROXIMAL].boundTransform;
            }

            Transform wrist = handBinder.boundHand.wrist.boundTransform;

            if (middleBone != null && indexBone != null && pinkyBone != null && wrist != null)
            {
                //Get the Direction from the middle finger to the wrist
                Vector3 wristForward = middleBone.position - wrist.position;
                //Get the Direction from the Proximal pinky finger to the Proximal Index finger
                Vector3 wristRight = indexBone.position - pinkyBone.position;

                //Swap the direction based on left and right hands
                if (handBinder.Handedness == Chirality.Right)
                {
                    wristRight = -wristRight;
                }

                //Get the direciton that goes outwards from the back of the hand
                Vector3 wristUp = Vector3.Cross(wristForward, wristRight);

                //Make the vectors orthoginal to eacother, this is the basis for the model hand
                Vector3.OrthoNormalize(ref wristRight, ref wristUp, ref wristForward);

                //Create a new leap hand based off the Desktop hand pose
                Hand hand = TestHandFactory.MakeTestHand(handBinder.Handedness == Chirality.Left, unitType: TestHandFactory.UnitType.LeapUnits);
                hand.Transform(TestHandFactory.GetTestPoseLeftHandTransform(TestHandFactory.TestHandPose.DesktopModeA));
                Quaternion leapRotation = hand.Rotation.ToQuaternion();

                //Get the rotation of the calculated hand Basis
                Quaternion modelRotation = Quaternion.LookRotation(wristForward, wristUp);

                //Now calculate the difference between the models rotation and the leaps rotation
                Quaternion wristRotationDifference = Quaternion.Inverse(modelRotation) * leapRotation;
                Vector3    wristRelativeDifference = (Quaternion.Inverse(wrist.rotation) * wristRotationDifference).eulerAngles;

                //Round to the nearest 90 degrees
                wristRelativeDifference.x = Mathf.Round(wristRelativeDifference.x / 90) * 90;
                wristRelativeDifference.y = Mathf.Round(wristRelativeDifference.y / 90) * 90;
                wristRelativeDifference.z = Mathf.Round(wristRelativeDifference.z / 90) * 90;

                //Assign these values to the hand binder
                handBinder.GlobalFingerRotationOffset      = wristRelativeDifference;
                handBinder.boundHand.wrist.offset.rotation = wristRelativeDifference;
            }
        }