//Initialize bones public void InitializeBones() { leapMetacarpal = new LeapBone(finger.Bone(Bone.BoneType.TYPE_METACARPAL)); leapProximal = new LeapBone(finger.Bone(Bone.BoneType.TYPE_PROXIMAL)); leapIntermediate = new LeapBone(finger.Bone(Bone.BoneType.TYPE_INTERMEDIATE)); leapDistal = new LeapBone(finger.Bone(Bone.BoneType.TYPE_DISTAL)); }
private char DoASLTest_B(Leap.Hand hand) { float fingerThreshold = 1400; Leap.FingerList fingers = hand.Fingers; Leap.Finger pinky = fingers[(int)Leap.Finger.FingerType.TYPE_PINKY]; Leap.Finger ring = fingers[(int)Leap.Finger.FingerType.TYPE_RING]; Leap.Finger middle = fingers[(int)Leap.Finger.FingerType.TYPE_MIDDLE]; Leap.Finger index = fingers[(int)Leap.Finger.FingerType.TYPE_INDEX]; Leap.Finger thumb = fingers[(int)Leap.Finger.FingerType.TYPE_THUMB]; Vector3 pinkyPos = ToVector3(pinky.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); Vector3 ringPos = ToVector3(ring.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); Vector3 middlePos = ToVector3(middle.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); Vector3 indexPos = ToVector3(index.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); if ((pinkyPos - ringPos).sqrMagnitude < fingerThreshold && (ringPos - middlePos).sqrMagnitude < fingerThreshold && (middlePos - indexPos).sqrMagnitude < fingerThreshold) { return('B'); } return(INVALID_ASL_LETTER); }
// Return true if the finger and the thumb's tip are near. private bool IsNearFromThumb(Finger finger, Finger thumb) { Vector fingerBase = finger.Bone(Bone.BoneType.TYPE_METACARPAL).Center; Vector baseToFingerTip = finger.TipPosition - fingerBase; Vector baseToThumbTip = thumb.TipPosition - fingerBase; float distance = baseToFingerTip.Cross(baseToThumbTip).Magnitude / baseToFingerTip.Magnitude; return distance < 40F; }
private void setFingerBasePositions_Relative(Hand hand) { Leap.Finger index = hand.Fingers.Where(f => f.Type == Finger.FingerType.TYPE_INDEX).FirstOrDefault(); Leap.Finger middle = hand.Fingers.Where(f => f.Type == Finger.FingerType.TYPE_MIDDLE).FirstOrDefault(); Leap.Finger ring = hand.Fingers.Where(f => f.Type == Finger.FingerType.TYPE_RING).FirstOrDefault(); Leap.Finger pinky = hand.Fingers.Where(f => f.Type == Finger.FingerType.TYPE_PINKY).FirstOrDefault(); IndexBasePos_Relative = new Vec3(HandTransform.TransformPoint(index.Bone(Bone.BoneType.TYPE_METACARPAL).PrevJoint)) / FingerLengths[Finger.FingerType.TYPE_INDEX]; MiddleBasePos_Relative = new Vec3(HandTransform.TransformPoint(middle.Bone(Bone.BoneType.TYPE_METACARPAL).PrevJoint)) / FingerLengths[Finger.FingerType.TYPE_MIDDLE]; RingBasePos_Relative = new Vec3(HandTransform.TransformPoint(ring.Bone(Bone.BoneType.TYPE_METACARPAL).PrevJoint)) / FingerLengths[Finger.FingerType.TYPE_RING]; PinkyBasePos_Relative = new Vec3(HandTransform.TransformPoint(pinky.Bone(Bone.BoneType.TYPE_METACARPAL).PrevJoint)) / FingerLengths[Finger.FingerType.TYPE_PINKY]; }
/*--------------------------------------------------------------------------------------------*/ public void Rebuild(Finger pLeapFinger) { if ( pLeapFinger == null ) { IsAvailable = false; Position = Vector3.zero; Rotation = Quaternion.identity; return; } Bone bone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); IsAvailable = true; Position = pLeapFinger.TipPosition.ToUnityScaled(); Rotation = LeapInputMenu.CalcQuaternion(bone.Basis); }
private void DrawFingerBones(Leap.Finger oFinger, InteractionBox interactionBox, DrawingContext drawingContext) { Bone bone; foreach (Bone.BoneType boneType in (Bone.BoneType[])Enum.GetValues(typeof(Bone.BoneType))) { bone = oFinger.Bone(boneType); Leap.Vector startPosition = interactionBox.NormalizePoint(bone.PrevJoint); Leap.Vector endPosition = interactionBox.NormalizePoint(bone.NextJoint); Point posStart = this.ToScreen(startPosition); Point posEnd = this.ToScreen(endPosition); double dX1 = posStart.X; double dY1 = posStart.Y; double dX2 = posEnd.X; double dY2 = posEnd.Y; drawingContext.DrawLine(new Pen() { Brush = new SolidColorBrush(Colors.Blue), Thickness = 1 }, new Point(dX1, dY1), new Point(dX2, dY2)); Pen oPen = new Pen(); if (boneType == Bone.BoneType.TYPE_PROXIMAL) { drawingContext.DrawEllipse(new SolidColorBrush(Colors.Gold), oPen, new Point(dX1, dY1), 6, 6); } else if (boneType == Bone.BoneType.TYPE_METACARPAL) { drawingContext.DrawEllipse(new SolidColorBrush(Colors.Black), oPen, new Point(dX1, dY1), 6, 6); } else if (boneType == Bone.BoneType.TYPE_INTERMEDIATE) { drawingContext.DrawEllipse(new SolidColorBrush(Colors.DarkGreen), oPen, new Point(dX1, dY1), 6, 6); } else if (boneType == Bone.BoneType.TYPE_DISTAL) { drawingContext.DrawEllipse(new SolidColorBrush(Colors.Red), oPen, new Point(dX1, dY1), 6, 6); drawingContext.DrawEllipse(new SolidColorBrush(Colors.Red), oPen, new Point(dX2, dY2), 12, 12); } } }
public SerializableFinger(Finger f) { Type = f.Type; _bones = new SerializableBone[4]; for (int i = 0; i < 4; ++i) { _bones[i] = new Leap.SerializableBone(f.Bone((Bone.BoneType)i)); } _frameId = 0; //Private Id = f.Id; HandId = f.HandId; TipPosition = new SerializableVector(f.TipPosition); TipVelocity = new SerializableVector(f.TipVelocity); Direction = new SerializableVector(f.Direction); Width = f.Width; Length = f.Length; IsExtended = f.IsExtended; StabilizedTipPosition = new SerializableVector(f.StabilizedTipPosition); TimeVisible = f.TimeVisible; }
protected PinchState GetNewPinchState() { HandModel hand_model = GetComponent <HandModel>(); Leap.Hand leap_hand = hand_model.GetLeapHand(); Leap.Vector leap_thumb_tip = leap_hand.Fingers[0].TipPosition; float closest_distance = Mathf.Infinity; // Check thumb tip distance to joints on all other fingers. // If it's close enough, you're pinching. for (int i = 1; i < HandModel.NUM_FINGERS; ++i) { Leap.Finger finger = leap_hand.Fingers[i]; for (int j = 0; j < FingerModel.NUM_BONES; ++j) { Leap.Vector leap_joint_position = finger.Bone((Leap.Bone.BoneType)j).NextJoint; float thumb_tip_distance = leap_joint_position.DistanceTo(leap_thumb_tip); closest_distance = Mathf.Min(closest_distance, thumb_tip_distance); } } // Scale trigger distance by thumb proximal bone length. float proximal_length = leap_hand.Fingers[0].Bone(Leap.Bone.BoneType.TYPE_PROXIMAL).Length; float trigger_distance = proximal_length * grabTriggerDistance; float release_distance = proximal_length * releaseTriggerDistance; if (closest_distance <= trigger_distance) { return(PinchState.kPinched); } if (closest_distance <= release_distance && pinch_state_ != PinchState.kReleased && !ObjectReleaseBreak(current_pinch_position_)) { return(PinchState.kReleasing); } return(PinchState.kReleased); }
//Functions to recieve bone position of a finger public Vector3 getMetacarpalPosition(Leap.Finger finger) { return(finger.Bone(Leap.Bone.BoneType.TYPE_METACARPAL).Center.ToVector3()); }
public Vector3 getProximalPosition(Leap.Finger finger) { return(finger.Bone(Leap.Bone.BoneType.TYPE_PROXIMAL).Center.ToVector3()); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateCursorsWithFinger(Hand pLeapHand, Finger pLeapFinger) { CursorType cursorType = GetFingerCursorType(pLeapHand.IsLeft, pLeapFinger.Type); if ( !CursorDataProvider.HasCursorData(cursorType) ) { return; } Vector tipPos = (UseStabilizedPositions ? pLeapFinger.StabilizedTipPosition: pLeapFinger.TipPosition); Bone distalBone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); Vector3 tipWorldPos = tipPos.ToVector3(); Vector3 boneWorldPos = distalBone.Center.ToVector3(); Vector3 extendedWorldPos = tipWorldPos; if ( ExtendFingertipDistance != 0 ) { extendedWorldPos += (tipWorldPos-boneWorldPos).normalized*ExtendFingertipDistance; } IHoverCursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(extendedWorldPos); data.SetWorldRotation(distalBone.Basis.CalculateRotation()*RotationFix); data.SetSize(pLeapFinger.Width); data.SetUsedByInput(true); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateCursorsWithFinger(Hand pLeapHand, Finger pLeapFinger) { CursorType cursorType = GetFingerCursorType(pLeapHand.IsLeft, pLeapFinger.Type); if ( !CursorDataProvider.HasCursorData(cursorType) ) { return; } Transform leapTx = LeapControl.transform; Vector tipPos = (UseStabilizedPositions ? pLeapFinger.StabilizedTipPosition: pLeapFinger.TipPosition); Bone distalBone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); Vector3 tipWorldPos = leapTx.TransformPoint(tipPos.ToUnityScaled()); Vector3 boneWorldPos = leapTx.TransformPoint(distalBone.Center.ToUnityScaled()); Vector3 extendedWorldPos = tipWorldPos; if ( ExtendFingertipDistance != 0 ) { extendedWorldPos += (tipWorldPos-boneWorldPos).normalized*ExtendFingertipDistance; } IHoverCursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(extendedWorldPos); data.SetWorldRotation(leapTx.rotation*distalBone.Basis.Rotation()*RotationFix); data.SetSize(pLeapFinger.Width*UnityVectorExtension.INPUT_SCALE); data.SetUsedByInput(true); }
private char DoASLTest_HKRUV(Leap.Hand hand) { float equalDistanceThreshold = 7; float fingerPointThreshold = 12; float fingersApartThreshold = 25; float angleThreshold = 45; Leap.FingerList fingers = hand.Fingers; Leap.Finger index = fingers[(int)Leap.Finger.FingerType.TYPE_INDEX]; Leap.Finger middle = fingers[(int)Leap.Finger.FingerType.TYPE_MIDDLE]; Leap.Finger ring = fingers[(int)Leap.Finger.FingerType.TYPE_RING]; Leap.Finger thumb = fingers[(int)Leap.Finger.FingerType.TYPE_THUMB]; Vector3 indexPos = ToVector3(index.Bone(Leap.Bone.BoneType.TYPE_PROXIMAL).Center); Vector3 middlePos = ToVector3(middle.Bone(Leap.Bone.BoneType.TYPE_PROXIMAL).Center); Vector3 thumbPos = ToVector3(thumb.StabilizedTipPosition); float thumbToIndex = Vector3.Distance(indexPos, thumbPos); float thumbToMiddle = Vector3.Distance(middlePos, thumbPos); Vector3 indexDir = ToVector3(index.Direction); Vector3 middleDir = ToVector3(middle.Direction); Vector3 thumbDir = ToVector3(thumb.Direction); Vector3 palmDirection = ToVector3(hand.Direction); Vector3 palmNormal = ToVector3(hand.PalmNormal); Vector3 sidePalmFacing = Vector3.Cross(palmNormal, palmDirection); float angleTestH = Vector3.Angle((hand.IsLeft) ? Vector3.up : Vector3.down, sidePalmFacing); float indexAngle = Vector3.Angle(middleDir, indexDir); float thumbAngle = Vector3.Angle(Vector3.up, thumbDir); Debug.Log(thumbAngle + " " + indexAngle + " (" + thumbToIndex + ", " + thumbToMiddle + ")"); // HRU test - Index and Middle are touching if (AreTwoFingersInContact(MyFingerType.TYPE_INDEX, MyFingerType.TYPE_MIDDLE, hand, fingersApartThreshold)) { // H Test - Hand is tilted if (angleTestH < angleThreshold) { return('H'); } // R Test - Index crosses Middle else if (indexAngle > fingerPointThreshold) { return('R'); } // Otherwise, it must be U else { return('U'); } } // K Test - Index apart from Middle, and Thumb equidistant to Index and Middle //else if (thumbAngle < angleThreshold * 0.5f) else if (Mathf.Abs(thumbToIndex - thumbToMiddle) < equalDistanceThreshold) { return('K'); } // V Test - Index apart from Middle, Thumb not pointing up // *Note, Thumb is not UP according to First-Pass return('V'); }
private char DoASLTest_AEMNST(Leap.Hand hand) { // TODO: Add The Proper Letter Detection Here // Would be doing this if Leap Motion proved accurate enough... //float fingerThreshold = 30; //float angleAlignmentThreshold = 15; //float pinkyThreshold = 15; //float closestFingerThreshold = 10; Leap.FingerList fingers = hand.Fingers; //Leap.Finger pinky = fingers[(int)Leap.Finger.FingerType.TYPE_PINKY]; //Leap.Finger ring = fingers[(int)Leap.Finger.FingerType.TYPE_RING]; //Leap.Finger middle = fingers[(int)Leap.Finger.FingerType.TYPE_MIDDLE]; Leap.Finger index = fingers[(int)Leap.Finger.FingerType.TYPE_INDEX]; Leap.Finger thumb = fingers[(int)Leap.Finger.FingerType.TYPE_THUMB]; { // Test For 'A' float distance; Vector3 point1 = ToVector3(index.TipPosition); Vector3 point2 = ToVector3(index.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).PrevJoint); Vector3 point3 = ToVector3(index.Bone(Leap.Bone.BoneType.TYPE_METACARPAL).PrevJoint); Vector3 vector1 = point1 - point2; Vector3 vector2 = point3 - point2; Vector3 N = Vector3.Cross(vector1, vector2); Vector3 w = ToVector3(thumb.TipPosition) - point2; Vector3 projection = Vector3.Project(w, N); distance = projection.magnitude; distance *= (projection.normalized == N.normalized) ? 1.0f : -1.0f; distance *= (hand.IsRight) ? 1.0f : -1.0f; if (distance > 0) { return('A'); } } // Test for 'O' float theO_Threshold = 40; Leap.Finger middle = fingers[(int)Leap.Finger.FingerType.TYPE_MIDDLE]; Vector3 middlePos = ToVector3(middle.TipPosition); Vector3 thumbPos = ToVector3(thumb.TipPosition); float dist = Vector3.Distance(middlePos, thumbPos); if (dist < theO_Threshold) { return('O'); } else { // Otherwise, not worth getting the rest. . . return(INVALID_ASL_LETTER); } /* * Vector3 pinkyPos = ToVector3(pinky.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); * Vector3 ringPos = ToVector3(ring.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); * Vector3 middlePos = ToVector3(middle.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); * Vector3 indexPos = ToVector3(index.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).NextJoint); * Vector3 thumbPos = ToVector3(thumb.TipPosition); * Vector3 palmPos = ToVector3(hand.PalmPosition); * * Vector3 middleToThumb = thumbPos - middlePos; * Vector3 indexToThumb = thumbPos - indexPos; * Vector3 indexToMiddle = middlePos - indexPos; * * float middleToThumbDist = middleToThumb.sqrMagnitude; * * if (AreTwoFingersInContact(MyFingerType.TYPE_PINKY, MyFingerType.TYPE_THUMB, hand, pinkyThreshold)) * { * return 'E'; * } * * // Check Based on distance from Bone * float pinkyToThumbDist = Vector3.Distance(pinkyPos, thumbPos); * float ringToThumbDist = Vector3.Distance(ringPos, thumbPos); * middleToThumbDist = Mathf.Sqrt(middleToThumbDist); * float indexToThumbDist = indexToThumb.magnitude; * * // Test for what the thumb is closest to * MyFingerType fingerClosest = MyFingerType.TYPE_PINKY; * float currentClosest = pinkyToThumbDist; * if (ringToThumbDist < currentClosest) * { * fingerClosest = MyFingerType.TYPE_RING; * currentClosest = ringToThumbDist; * } * if (middleToThumbDist < currentClosest) * { * fingerClosest = MyFingerType.TYPE_MIDDLE; * currentClosest = middleToThumbDist; * } * if (indexToThumbDist < currentClosest) * { * fingerClosest = MyFingerType.TYPE_INDEX; * currentClosest = indexToThumbDist; * } * * // Near Pinky = E * // Near Ring = M * // Near Middle = N, S * // Near Index = T, A * if (currentClosest < closestFingerThreshold) * { * switch (fingerClosest) * { * case MyFingerType.TYPE_PINKY: return 'E'; * case MyFingerType.TYPE_RING: * case MyFingerType.TYPE_MIDDLE: * case MyFingerType.TYPE_INDEX: return 'O'; * } * } * return INVALID_ASL_LETTER;*/ }
public float[] getFingerAbsoluteData() { float[] ret = null; bool hasLeftHand = false; foreach (Hand hand in handController.Frame().Hands) { if (hand.IsLeft) { hasLeftHand = true; Bone bone0 = hand.Fingers[0].Bone(Bone.BoneType.TYPE_DISTAL); //大拇指 Bone bone1 = hand.Fingers[hand.Fingers.Count - 1].Bone(Bone.BoneType.TYPE_DISTAL); //小拇指 //Debug.LogError(bone0.PrevJoint.x.ToString() + "," + bone1.PrevJoint.x.ToString() + ". a-b = " +(bone0.PrevJoint.x - bone1.PrevJoint.x).ToString()); if (bone0.PrevJoint.x - bone1.PrevJoint.x > 0) //手心向下 { setenceWatch.Stop(); setenceWatch.Reset(); if (wordWatch.IsRunning) { if (wordWatch.ElapsedMilliseconds >= eraseWordTime) { //Debug.LogError("erase a word" + wordWatch.ElapsedMilliseconds.ToString()); int count = predicts.Count; if (count > 0) { predicts.RemoveAt(count - 1); } wordWatch.Stop(); wordWatch.Reset(); } } else { wordWatch.Start(); } } else //手心向上 { wordWatch.Stop(); wordWatch.Reset(); if (setenceWatch.IsRunning) { if (setenceWatch.ElapsedMilliseconds >= eraseSetenceTime) { //Debug.LogError("erase a setence" + setenceWatch.ElapsedMilliseconds.ToString()); predicts.Clear(); setenceWatch.Stop(); setenceWatch.Reset(); } } else { setenceWatch.Start(); } } break; } else if (hand.IsRight) { if (ret == null) { ret = new float[DIMENSION]; } ret[0] = hand.PalmPosition.x; ret[1] = hand.PalmPosition.y; ret[2] = hand.PalmPosition.z; for (int i = 0; i < hand.Fingers.Count; i++) { Leap.Finger finger = hand.Fingers[i]; Bone bone1 = finger.Bone(Bone.BoneType.TYPE_DISTAL); //末梢 Bone bone2 = finger.Bone(Bone.BoneType.TYPE_INTERMEDIATE); //中间的 Bone bone3 = finger.Bone(Bone.BoneType.TYPE_PROXIMAL); Bone bone4 = finger.Bone(Bone.BoneType.TYPE_METACARPAL); ret[i * 12 + 3] = bone1.PrevJoint.x; ret[i * 12 + 4] = bone1.PrevJoint.y; ret[i * 12 + 5] = bone1.PrevJoint.z; ret[i * 12 + 6] = bone2.PrevJoint.x; ret[i * 12 + 7] = bone2.PrevJoint.y; ret[i * 12 + 8] = bone2.PrevJoint.z; ret[i * 12 + 9] = bone3.PrevJoint.x; ret[i * 12 + 10] = bone3.PrevJoint.y; ret[i * 12 + 11] = bone3.PrevJoint.z; ret[i * 12 + 12] = bone4.PrevJoint.x; ret[i * 12 + 13] = bone4.PrevJoint.y; ret[i * 12 + 14] = bone4.PrevJoint.z; } } } if (!hasLeftHand) { wordWatch.Stop(); wordWatch.Reset(); setenceWatch.Stop(); setenceWatch.Reset(); } return(ret); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateCursorsWithFinger(Hand pLeapHand, Finger pLeapFinger) { CursorType cursorType = GetFingerCursorType(pLeapHand.IsLeft, pLeapFinger.Type); if ( !CursorDataProvider.HasCursorData(cursorType) ) { return; } Vector tipPos = (UseStabilizedPositions ? pLeapFinger.StabilizedTipPosition: pLeapFinger.TipPosition); Bone distalBone = pLeapFinger.Bone(Bone.BoneType.TYPE_DISTAL); IHoverCursorDataForInput data = CursorDataProvider.GetCursorDataForInput(cursorType); data.SetWorldPosition(tipPos.ToVector3()); data.SetWorldRotation(distalBone.Basis.CalculateRotation()*RotationFix); data.SetSize(pLeapFinger.Width); data.SetUsedByInput(true); }
public Vector3 getIntermediatePosition(Leap.Finger finger) { return(finger.Bone(Leap.Bone.BoneType.TYPE_INTERMEDIATE).Center.ToVector3()); }
public Vector3 getDistalPosition(Leap.Finger finger) { return(finger.Bone(Leap.Bone.BoneType.TYPE_DISTAL).Center.ToVector3()); }
private static SerializableFinger ToSerializableFinger(Finger leapFinger) { return new SerializableFinger { handId = leapFinger.HandId, fingerId = leapFinger.Id, timeVisible = leapFinger.TimeVisible, tipPosition = ToSerializableVector(leapFinger.TipPosition), tipVelocity = ToSerializableVector(leapFinger.TipVelocity), direction = ToSerializableVector(leapFinger.Direction), stabilizedTipPosition = ToSerializableVector(leapFinger.StabilizedTipPosition), width = leapFinger.Width, length = leapFinger.Length, isExtended = leapFinger.IsExtended, type = leapFinger.Type, metacarpal = ToSerializableBone(leapFinger.Bone(Bone.BoneType.TYPE_METACARPAL)), proximal = ToSerializableBone(leapFinger.Bone(Bone.BoneType.TYPE_PROXIMAL)), intermediate = ToSerializableBone(leapFinger.Bone(Bone.BoneType.TYPE_INTERMEDIATE)), distal = ToSerializableBone(leapFinger.Bone(Bone.BoneType.TYPE_DISTAL)), }; }