Exemplo n.º 1
0
 public static void CalculateElbowLength(HandBinder handBinder)
 {
     if (handBinder.BoundHand.elbow.boundTransform != null && handBinder.BoundHand.wrist.boundTransform != null)
     {
         handBinder.ElbowLength = (handBinder.BoundHand.wrist.boundTransform.position - handBinder.BoundHand.elbow.boundTransform.position).magnitude;
     }
 }
Exemplo n.º 2
0
        /// <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)
        {
            Transform indexBone  = handBinder.BoundHand.fingers[(int)Finger.FingerType.TYPE_INDEX].boundBones[(int)Bone.BoneType.TYPE_PROXIMAL].boundTransform;
            Transform middleBone = handBinder.BoundHand.fingers[(int)Finger.FingerType.TYPE_MIDDLE].boundBones[(int)Bone.BoneType.TYPE_PROXIMAL].boundTransform;
            Transform 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)
            {
                //Calculate model's rotation
                var forward = (middleBone.position - wrist.position);
                var right   = (indexBone.position - pinkyBone.position);
                if (handBinder.Handedness == Chirality.Right)
                {
                    right = -right;
                }
                var up = Vector3.Cross(forward, right);
                Vector3.OrthoNormalize(ref up, ref forward, ref right);
                var modelRotation = Quaternion.LookRotation(forward, up);

                //Calculate the difference between the Calculated hand basis and the wrists rotation
                handBinder.WristRotationOffset = (Quaternion.Inverse(modelRotation) * wrist.transform.rotation).eulerAngles;
                //Assuming the fingers have been created using the same rotation axis as the wrist
                handBinder.GlobalFingerRotationOffset = handBinder.WristRotationOffset;
            }
        }
        /// <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;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Draw extra gizmos in the scene to help the user while they edit variables
        /// </summary>
        private void OnSceneGUI()
        {
            myTarget = (HandBinder)target;

            if (myTarget.LeapHand == null)
            {
                return;
            }

            DrawLeapHandGizmos();
            DrawLeapBasis();
            DrawModelHandGizmos();
            DrawModelHandBasis();
        }
Exemplo n.º 5
0
        private void OnEnable()
        {
            serializedObject.Update();
            myTarget = (HandBinder)target;

            if (myTarget.gameObject.name.ToUpper().Contains("Left".ToUpper()))
            {
                myTarget.Handedness = Unity.Chirality.Left;
            }
            if (myTarget.gameObject.name.ToUpper().Contains("Right".ToUpper()))
            {
                myTarget.Handedness = Unity.Chirality.Right;
            }

            SetSerializedProperties();
        }
Exemplo n.º 6
0
            /// <summary>
            /// Turn the bound handBinder bones into a flattened array
            /// </summary>
            /// <param name="handBinder"></param>
            /// <returns></returns>
            static public Transform[] FlattenHandBinderTransforms(HandBinder handBinder)
            {
                var bones = new List <Transform>();
                int index = 0;

                for (int FINGERID = 0; FINGERID < handBinder.BoundHand.fingers.Length; FINGERID++)
                {
                    for (int BONEID = 0; BONEID < handBinder.BoundHand.fingers[FINGERID].boundBones.Length; BONEID++)
                    {
                        var BONE = handBinder.BoundHand.fingers[FINGERID].boundBones[BONEID];
                        bones.Add(BONE.boundTransform);
                        index++;
                    }
                    index++;
                }
                bones.Add(handBinder.BoundHand.wrist.boundTransform);
                return(bones.ToArray());
            }
        /// <summary>
        /// This function is used to search the HandBinder scipts children transforms to auto assign them for the user
        /// </summary>
        /// <param name="handBinder">The binder that the found transforms will get assigned too</param>
        public static void AutoRig(HandBinder handBinder)
        {
            handBinder.ResetHand();
            BoneDefinitions boneDefinitions = null;

            //Check to see if we have an autorigger Definitions scriptable object
            if (handBinder.CustomBoneDefinitions == null)
            {
                boneDefinitions = new BoneDefinitions();
            }
            else
            {
                boneDefinitions = handBinder.CustomBoneDefinitions.BoneDefinitions;
            }

            //Get all children of the hand
            var children = GetAllChildren(handBinder.transform);

            var thumbBones  = SelectBones(children, boneDefinitions.DefinitionThumb, true);
            var indexBones  = SelectBones(children, boneDefinitions.DefinitionIndex);
            var middleBones = SelectBones(children, boneDefinitions.DefinitionMiddle);
            var ringBones   = SelectBones(children, boneDefinitions.DefinitionRing);
            var pinkyBones  = SelectBones(children, boneDefinitions.DefinitionPinky);
            var wrist       = SelectBones(children, boneDefinitions.DefinitionWrist).FirstOrDefault();
            var Elbow       = SelectBones(children, boneDefinitions.DefinitionElbow).FirstOrDefault();

            handBinder.boundHand.fingers[0].boundBones = AssignUnityBone(thumbBones);
            handBinder.boundHand.fingers[1].boundBones = AssignUnityBone(indexBones);
            handBinder.boundHand.fingers[2].boundBones = AssignUnityBone(middleBones);
            handBinder.boundHand.fingers[3].boundBones = AssignUnityBone(ringBones);
            handBinder.boundHand.fingers[4].boundBones = AssignUnityBone(pinkyBones);
            handBinder.boundHand.wrist = AssignBoundBone(wrist);
            handBinder.boundHand.elbow = AssignBoundBone(Elbow);
            if (wrist != null && Elbow != null)
            {
                handBinder.elbowLength = (wrist.position - Elbow.position).magnitude;
            }

            EstimateWristRotationOffset(handBinder);

            handBinder.UpdateHand();
            handBinder.DebugModelTransforms = true;
            handBinder.SetEditorPose        = true;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Makes a new leap hand so we can use it to set an editor pose
        /// </summary>
        /// <param name="binder"></param>
        private void MakeLeapHand(HandBinder binder)
        {
            LeapProvider provider = null;

            //First try to get the provider from a parent HandModelManager
            if (binder.transform.parent != null)
            {
                var manager = binder.transform.parent.GetComponent <HandModelManager>();
                if (manager != null)
                {
                    provider = manager.leapProvider;
                }
            }

            //If not found, use any old provider from the Hands.Provider getter
            if (provider == null)
            {
                provider = Hands.Provider;
            }

            Hand hand = null;

            //If we found a provider, pull the hand from that
            if (provider != null)
            {
                var frame = provider.CurrentFrame;

                if (frame != null)
                {
                    hand = frame.Get(binder.Handedness);
                }
            }

            //If we still have a null hand, construct one manually
            if (hand == null)
            {
                hand = TestHandFactory.MakeTestHand(binder.Handedness == Chirality.Left, unitType: TestHandFactory.UnitType.LeapUnits);
                hand.Transform(binder.transform.GetLeapMatrix());
            }

            binder.LeapHand = hand;
        }
Exemplo n.º 9
0
        /// <summary>
        /// This function is used to search the child Transforms of the HandBinder script to automatically try and assign them for the user
        /// </summary>
        /// <param name="handBinder">The HandBinder that the found Transform target will get assigned to</param>
        public static void AutoBind(HandBinder handBinder)
        {
            handBinder.ResetHand();
            BoneNameDefinitions boneDefinitions = new BoneNameDefinitions();

            //Get all children of the hand
            var children = new List <Transform>();

            children.Add(handBinder.transform);
            children.AddRange(GetAllChildren(handBinder.transform));

            var thumbBones  = SortBones(SelectBones(children, boneDefinitions.DefinitionThumb), false, true);
            var indexBones  = SortBones(SelectBones(children, boneDefinitions.DefinitionIndex), handBinder.UseMetaBones);
            var middleBones = SortBones(SelectBones(children, boneDefinitions.DefinitionMiddle), handBinder.UseMetaBones);
            var ringBones   = SortBones(SelectBones(children, boneDefinitions.DefinitionRing), handBinder.UseMetaBones);
            var pinkyBones  = SortBones(SelectBones(children, boneDefinitions.DefinitionPinky), handBinder.UseMetaBones);
            var wrist       = SelectBones(children, boneDefinitions.DefinitionWrist).FirstOrDefault();
            var elbow       = SelectBones(children, boneDefinitions.DefinitionElbow).FirstOrDefault();

            handBinder.BoundHand.fingers[0].boundBones = AssignTransformToBoundBone(thumbBones);
            handBinder.BoundHand.fingers[1].boundBones = AssignTransformToBoundBone(indexBones);
            handBinder.BoundHand.fingers[2].boundBones = AssignTransformToBoundBone(middleBones);
            handBinder.BoundHand.fingers[3].boundBones = AssignTransformToBoundBone(ringBones);
            handBinder.BoundHand.fingers[4].boundBones = AssignTransformToBoundBone(pinkyBones);
            handBinder.BoundHand.wrist = AssignBoundBone(wrist);
            handBinder.BoundHand.elbow = AssignBoundBone(elbow);

            if (wrist != null && elbow != null)
            {
                handBinder.ElbowLength = (wrist.position - elbow.position).magnitude;
            }

            EstimateWristRotationOffset(handBinder);
            CalculateElbowLength(handBinder);

            handBinder.GetLeapHand();
            handBinder.UpdateHand();
            handBinder.DebugModelTransforms = true;
            handBinder.SetEditorPose        = true;
        }
Exemplo n.º 10
0
 /// <summary>
 /// Set up the Editor textures and reference to the hand binder
 /// </summary>
 /// <param name="handBinderRef"></param>
 public void SetUp(ref HandBinder handBinderRef)
 {
     handBinder  = handBinderRef;
     dividerLine = Resources.Load <Texture>("EditorDividerline");
     editorSkin  = Resources.Load <GUISkin>("UltraleapEditorStyle");
 }
Exemplo n.º 11
0
        /// <summary>
        /// Draw extra gizmos in the scene to help the user while they edit variables
        /// </summary>
        private void OnSceneGUI()
        {
            myTarget = (HandBinder)target;

            if (myTarget == null)
            {
                return;
            }

            //Update the editor pose, this will only get called when the object is selected.
            if (!Application.isPlaying)
            {
                EditorHandPose();
            }

            //Draw the leap hand
            if (myTarget.DebugLeapHand)
            {
                Handles.color = leapHandDebugCol;
                foreach (var finger in myTarget.LeapHand.Fingers)
                {
                    var index = 0;

                    foreach (var bone in finger.bones)
                    {
                        Handles.SphereHandleCap(-1, bone.PrevJoint.ToVector3(), Quaternion.identity, myTarget.GizmoSize, EventType.Repaint);
                        if ((index + 1) <= finger.bones.Length - 1)
                        {
                            Handles.DrawLine(finger.bones[index].PrevJoint.ToVector3(), finger.bones[index + 1].PrevJoint.ToVector3());
                        }

                        if (DebugLeapRotationAxis.boolValue)
                        {
                            DrawLeapBasis(bone, gizmoSize.floatValue * 4);
                        }
                        index++;
                    }
                }

                Handles.SphereHandleCap(-1, myTarget.LeapHand.WristPosition.ToVector3(), Quaternion.identity, myTarget.GizmoSize, EventType.Repaint);

                var elbowPosition = myTarget.LeapHand.WristPosition.ToVector3() - (myTarget.LeapHand.Arm.Basis.zBasis.ToVector3().normalized *myTarget.elbowLength);
                Handles.SphereHandleCap(-1, elbowPosition, Quaternion.identity, myTarget.GizmoSize, EventType.Repaint);
                Handles.DrawLine(elbowPosition, myTarget.LeapHand.WristPosition.ToVector3());
            }

            //Draw the bound Gameobjects
            if (myTarget.DebugModelTransforms)
            {
                Handles.color = handModelDebugCol;
                for (int finger = 0; finger < myTarget.boundHand.fingers.Length; finger++)
                {
                    for (int bone = 0; bone < myTarget.boundHand.fingers[finger].boundBones.Length; bone++)
                    {
                        var target = myTarget.boundHand.fingers[finger].boundBones[bone].boundTransform;
                        if (target != null)
                        {
                            if (myTarget.DebugModelTransforms)
                            {
                                Handles.DrawWireDisc(target.position, target.right, gizmoSize.floatValue);
                                Handles.DrawWireDisc(target.position, target.up, gizmoSize.floatValue);
                                Handles.DrawWireDisc(target.position, target.forward, gizmoSize.floatValue);
                            }

                            if (DebugModelRotationAxis.boolValue)
                            {
                                DrawTransformBasis(target, gizmoSize.floatValue * 4);
                            }
                        }
                    }
                }
            }
        }