/** * The scale factor derived from this hand's motion between the current frame * and the specified frame. * * The scale factor is always positive. A value of 1.0 indicates no * scaling took place. Values between 0.0 and 1.0 indicate contraction * and values greater than 1.0 indicate expansion. * * \include Hand_scaleFactor.txt * * The Leap Motion software derives scaling from the relative inward or outward motion of * a hand and its associated fingers (independent of translation * and rotation). * * If a corresponding Hand object is not found in sinceFrame, or if either * this frame or sinceFrame are invalid Frame objects, then this method * returns 1.0. * * @param sinceFrame The starting frame for computing the relative scaling. * @returns A positive value representing the heuristically determined * scaling change ratio of the hand between the current frame and that * specified in the sinceFrame parameter. * @since 1.0 */ public float ScaleFactor(Frame sinceFrame) { Hand sinceHand = sinceFrame.Hand(this.Id); if (!sinceHand.IsValid) { return(1.0f); } float thisFactor = 1 - Math.Max(this.PinchStrength, this.GrabStrength); float sinceFactor = 1 - Math.Max(sinceHand.PinchStrength, sinceHand.GrabStrength); if (thisFactor < Leap.Constants.EPSILON && sinceFactor < Leap.Constants.EPSILON) { return(1.0f); } //Contraction if (thisFactor > sinceFactor && thisFactor > Leap.Constants.EPSILON) { return((thisFactor - sinceFactor) / thisFactor); } //Expansion if (sinceFactor > thisFactor && sinceFactor > Leap.Constants.EPSILON) { return((sinceFactor - thisFactor) / sinceFactor); } return(1.0f); }
/** * The transform matrix expressing the rotation derived from the change * in orientation of this hand, and any associated fingers, * between the current frame and the specified frame. * * \include Hand_rotationMatrix.txt * * If a corresponding Hand object is not found in sinceFrame, or if either * this frame or sinceFrame are invalid Frame objects, then this method * returns an identity matrix. * * @param sinceFrame The starting frame for computing the relative rotation. * @returns A transformation Matrix representing the heuristically determined * rotational change of the hand between the current frame and that specified * in the sinceFrame parameter. * @since 1.0 */ public Matrix RotationMatrix(Frame sinceFrame) { Hand sinceHand = sinceFrame.Hand(this.Id); if (!sinceHand.IsValid) { return(Matrix.Identity); } return(this.Basis * sinceHand.Basis.RigidInverse()); }
/** * * /** * The change of position of this hand between the current frame and * the specified frame. * * The returned translation vector provides the magnitude and direction of * the movement in millimeters. * * \include Hand_translation.txt * * If a corresponding Hand object is not found in sinceFrame, or if either * this frame or sinceFrame are invalid Frame objects, then this method * returns a zero vector. * * @param sinceFrame The starting frame for computing the translation. * @returns A Vector representing the heuristically determined change in * hand position between the current frame and that specified in the * sinceFrame parameter. * @since 1.0 */ public Vector Translation(Frame sinceFrame) { Hand sinceHand = sinceFrame.Hand(this.Id); if (!sinceHand.IsValid) { return(Vector.Zero); } return(this.PalmPosition - sinceHand.PalmPosition); }
void Update() { if(leapInitialized && leapController != null) { Leap.Frame frame = leapController.Frame(); if(frame.IsValid && (frame.Id != lastFrameID)) { leapFrame = frame; lastFrameID = leapFrame.Id; leapFrameCounter++; // fix unfinished leap gesture progress if(fCircleProgress > 0f && fCircleProgress < 1f) fCircleProgress = 0f; if(fSwipeProgress > 0f && fSwipeProgress < 1f) fSwipeProgress = 0f; if(fKeyTapProgress > 0f && fKeyTapProgress < 1f) fKeyTapProgress = 0f; if(fScreenTapProgress > 0f && fScreenTapProgress < 1f) fScreenTapProgress = 0f; // get a suitable pointable leapPointable = leapFrame.Pointable(leapPointableID); if(!leapPointable.IsValid) leapPointable = leapFrame.Pointables.Frontmost; Leap.Vector stabilizedPosition = Leap.Vector.Zero; Leap.Hand handPrim = leapFrame.Hands.Count > 0 ? leapFrame.Hands[leapFrame.Hands.Count - 1] : null; if(leapPointable != null && leapPointable.IsValid && leapPointable.Hand != null && leapPointable.Hand.IsValid && handPrim != null && leapPointable.Hand.Id == handPrim.Id) { leapPointableID = leapPointable.Id; leapPointableHandID = leapPointable.Hand != null && leapPointable.Hand.IsValid ? leapPointable.Hand.Id : 0; leapPointablePos = LeapToUnity(leapPointable.StabilizedTipPosition, true); leapPointableDir = LeapToUnity(leapPointable.Direction, false); //leapPointableQuat = Quaternion.LookRotation(leapPointableDir); leapPointableZone = leapPointable.TouchZone; //stabilizedPosition = leapPointable.StabilizedTipPosition; leapHand = leapPointable.Hand; leapHandID = leapHand.Id; } else { leapPointableID = 0; leapPointable = null; // get leap hand leapHand = leapFrame.Hand(leapHandID); if(leapHand == null || !leapHand.IsValid) { leapHandID = 0; if(leapFrame.Hands.Count > 0) { for(int i = leapFrame.Hands.Count - 1; i >= 0; i--) { leapHand = leapFrame.Hands[i]; if(leapHand.IsValid /**&& leapHand.Fingers.Count > 0*/) { leapHandID = leapHand.Id; break; } } } } } if(leapHandID != 0) { leapHandPos = LeapToUnity(leapHand.StabilizedPalmPosition, true); stabilizedPosition = leapHand.StabilizedPalmPosition; leapHandFingersCount = leapHand.Fingers.Count; } // estimate the cursor coordinates if(stabilizedPosition != Leap.Vector.Zero) { Leap.InteractionBox iBox = frame.InteractionBox; Leap.Vector normalizedPosition = iBox.NormalizePoint(stabilizedPosition); cursorNormalPos.x = normalizedPosition.x; cursorNormalPos.y = normalizedPosition.y; cursorScreenPos.x = cursorNormalPos.x * UnityEngine.Screen.width; cursorScreenPos.y = cursorNormalPos.y * UnityEngine.Screen.height; } // do fingers count filter if(leapHandID != fingersCountHandID) { fingersCountHandID = leapHandID; fingersCountPrev = -1; fingersCountPrevPrev = -1; handGripDetected = false; fingersCountFilter.Reset(); } if(leapHandID != 0) { fingersCountFiltered = leapHandFingersCount; fingersCountFilter.UpdateFilter(ref fingersCountFiltered); if((leapFrameCounter - handGripFrameCounter) >= FramesToSkip) { handGripFrameCounter = leapFrameCounter; int fingersCountNow = (int)(fingersCountFiltered + 0.5f); //int fingersCountNow = leapHandFingersCount; if(fingersCountPrev == fingersCountPrevPrev) { if(!handGripDetected) { if(fingersCountNow < fingersCountPrev) { Finger leftFinger = leapHand.Finger(leapHandLFingerId); Finger rightFinger = leapHand.Finger(leapHandRFingerId); bool bThumbOff = !LeftHandedUser ? leapHandLFingerId != 0 && (leftFinger == null || !leftFinger.IsValid) : leapHandRFingerId != 0 && (rightFinger == null || !rightFinger.IsValid); if(bThumbOff) { handGripDetected = true; handGripFingersCount = fingersCountPrev; } } else { leapHandLFingerId = leapHand != null && leapHand.Fingers.Count > 0 ? leapHand.Fingers.Leftmost.Id : 0; leapHandRFingerId = leapHand != null && leapHand.Fingers.Count > 0 ? leapHand.Fingers.Rightmost.Id : 0; } } else { if(fingersCountNow >= fingersCountPrev/**handGripFingersCount*/) { Finger leftFinger = leapHand.Finger(leapHandLFingerId); Finger rightFinger = leapHand.Finger(leapHandRFingerId); bool bThumbOn = !LeftHandedUser ? (leftFinger != null && leftFinger.IsValid) : (rightFinger != null && rightFinger.IsValid); if(bThumbOn || fingersCountNow >= handGripFingersCount) { handGripDetected = false; } } else if(leapHand == null || !leapHand.IsValid) { // stop pinching if the hand is lost handGripDetected = false; } } } fingersCountPrevPrev = fingersCountPrev; fingersCountPrev = fingersCountNow; } } if(Time.realtimeSinceStartup >= gestureTrackingAtTime) { GestureList gestures = frame.Gestures (); for (int i = 0; i < gestures.Count; i++) { Gesture gesture = gestures[i]; switch (gesture.Type) { case Gesture.GestureType.TYPECIRCLE: CircleGesture circle = new CircleGesture(gesture); if((leapFrameCounter - iCircleFrameCounter) >= FramesToSkip && iCircleGestureID != circle.Id && circle.State == Gesture.GestureState.STATESTOP) { iCircleFrameCounter = leapFrameCounter; iCircleGestureID = circle.Id; fCircleProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } else if(circle.Progress < 1f) { fCircleProgress = circle.Progress; } break; case Gesture.GestureType.TYPESWIPE: SwipeGesture swipe = new SwipeGesture(gesture); if((leapFrameCounter - iSwipeFrameCounter) >= FramesToSkip && iSwipeGestureID != swipe.Id && swipe.State == Gesture.GestureState.STATESTOP) { iSwipeFrameCounter = leapFrameCounter; iSwipeGestureID = swipe.Id; fSwipeProgress = 1f; // swipe.Progress gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; leapSwipeDir = LeapToUnity(swipe.Direction, false); leapSwipeSpeed = LeapToUnity(swipe.Position - swipe.StartPosition, true); if(swipe.DurationSeconds != 0) leapSwipeSpeed /= swipe.DurationSeconds; else leapSwipeSpeed = Vector3.zero; } else if(swipe.State != Gesture.GestureState.STATESTOP) { fSwipeProgress = 0.5f; } break; case Gesture.GestureType.TYPEKEYTAP: KeyTapGesture keytap = new KeyTapGesture (gesture); if((leapFrameCounter - iKeyTapFrameCounter) >= FramesToSkip && iKeyTapGestureID != keytap.Id && keytap.State == Gesture.GestureState.STATESTOP) { iKeyTapFrameCounter = leapFrameCounter; iKeyTapGestureID = keytap.Id; fKeyTapProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } else if(keytap.Progress < 1f) { fKeyTapProgress = keytap.Progress; } break; case Gesture.GestureType.TYPESCREENTAP: ScreenTapGesture screentap = new ScreenTapGesture (gesture); if((leapFrameCounter - iScreenTapFrameCounter) >= FramesToSkip && iScreenTapGestureID != screentap.Id && screentap.State == Gesture.GestureState.STATESTOP) { iScreenTapFrameCounter = leapFrameCounter; iScreenTapGestureID = screentap.Id; fScreenTapProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } else if(screentap.Progress < 1f) { fScreenTapProgress = screentap.Progress; } break; default: Debug.LogError("Unknown gesture type."); break; } } // check for extra gestures int listGestureSize = extraGesturesData.Count; float timestampNow = Time.realtimeSinceStartup; for(int g = 0; g < listGestureSize; g++) { LeapExtraGestures.ExtraGestureData gestureData = extraGesturesData[g]; if(timestampNow >= gestureData.startTrackingAtTime) { LeapExtraGestures.CheckForGesture(ref gestureData, Time.realtimeSinceStartup, this); extraGesturesData[g] = gestureData; if(gestureData.complete) { gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } } } } if(DebugCamera) { DoDisplayFingers(); } } } }
void Update() { if(leapInitialized && leapController != null) { Leap.Frame frame = leapController.Frame(); if(frame.IsValid && (frame.Id != lastFrameID)) { leapFrame = frame; lastFrameID = leapFrame.Id; leapFrameCounter++; // get the prime hand leapHand = leapFrame.Hand(leapHandID); if(leapHand == null || !leapHand.IsValid) { leapHand = GetFrontmostHand(); leapHandID = leapHand != null && leapHand.IsValid ? leapHand.Id : 0; } leapPointable = leapFrame.Pointable(leapPointableID); if(leapPointable == null || !leapPointable.IsValid) { leapPointable = leapHand.IsValid ? GetPointingFigner(leapHand) : leapFrame.Pointables.Frontmost; leapPointableID = leapPointable != null && leapPointable.IsValid ? leapPointable.Id : 0; leapPointableHandID = leapPointable != null && leapPointable.IsValid && leapPointable.Hand.IsValid ? leapPointable.Hand.Id : 0; } if(leapPointable != null && leapPointable.IsValid && leapPointable.Hand != null && leapPointable.Hand.IsValid && leapHand != null && leapHand.IsValid && leapPointable.Hand.Id == leapHand.Id) { leapPointablePos = LeapToUnity(leapPointable.StabilizedTipPosition, true); leapPointableDir = LeapToUnity(leapPointable.Direction, false); } else { leapPointable = null; leapPointableID = 0; leapPointableHandID = 0; } Leap.Vector stabilizedPosition = Leap.Vector.Zero; if(leapHandID != 0) { leapHandPos = LeapToUnity(leapHand.StabilizedPalmPosition, true); stabilizedPosition = leapHand.StabilizedPalmPosition; leapHandFingersCount = leapHand.Fingers.Count; bool bCurrentHandGrip = handGripDetected; handGripDetected = !isHandOpen(leapHand); handReleaseDetected = !handGripDetected; } else { leapHandFingersCount = 0; handGripDetected = false; handReleaseDetected = false; } if(stabilizedPosition.MagnitudeSquared != 0f) { Leap.InteractionBox iBox = frame.InteractionBox; Leap.Vector normalizedPosition = iBox.NormalizePoint(stabilizedPosition); cursorNormalPos.x = normalizedPosition.x; cursorNormalPos.y = normalizedPosition.y; cursorScreenPos.x = cursorNormalPos.x * UnityEngine.Screen.width; cursorScreenPos.y = cursorNormalPos.y * UnityEngine.Screen.height; } } } }
private void HandsController_HandsDetected(object sender, HandCollection e) { // Display the results! if (e.HandRight != null) { // Draw contour. foreach (var point in e.HandRight.ContourDepth) { DrawEllipse(point, Brushes.Blue, 2.0); } // Draw fingers. foreach (var finger in e.HandRight.Fingers) { DrawEllipse(finger.DepthPoint, Brushes.White, 4.0); } //added by lu for calib if (!calib_finished) { if (e.HandRight.Fingers.Count == 5)// if there are five fingers than than do calibration { //do_calib //first get fingers from leap Controller controller = new Controller(); Leap.Frame leapframe = controller.Frame(); if (leapframe.Fingers.Count == 5) { if (MessageBox.Show("Is the data qualified?", "Calibration", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { //then sort the fingers of kinect Sort_Kinect_Points(e.HandRight.Fingers); for (int i = 0; i < 5; i++) { Matrix <float> leapfinger_m = new Matrix <float>(3, 1); leapfinger_m[0, 0] = leapframe.Fingers[i].StabilizedTipPosition.x; leapfinger_m[1, 0] = leapframe.Fingers[i].StabilizedTipPosition.y; leapfinger_m[2, 0] = leapframe.Fingers[i].StabilizedTipPosition.z; l_list.Add(leapfinger_m); } int k_list_num = k_list.Count(); int l_list_num = l_list.Count(); using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"F:\\calib_data\\calib_data.txt", true)) { for (int write_num = 5; write_num > 0; write_num--) { file.Write(k_list[k_list_num - write_num].X + " "); file.Write(k_list[k_list_num - write_num].Y + " "); file.Write(k_list[k_list_num - write_num].Z + " "); file.Write(l_list[l_list_num - write_num][0, 0] + " "); file.Write(l_list[l_list_num - write_num][1, 0] + " "); file.Write(l_list[l_list_num - write_num][2, 0] + "\r\n"); } } //calibration bool calib_done = do_calib(k_list, l_list); if (calib_done) { List <Matrix <float> > points_test = transform_points(leapframe.Fingers, leapframe.Hand(0)); for (int pointn = 0; pointn < points_test.Count(); pointn++) { DrawEllipse(points_test[pointn], Brushes.Red, 5.0); } if (MessageBox.Show("Is calibration finished?", "Calibration", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { calib_finished = true; using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"F:\\calib_data\\calib_matrix.txt", true)) { file.WriteLine(R[0, 0]); file.WriteLine(R[0, 1]); file.WriteLine(R[0, 2]); file.WriteLine(R[1, 0]); file.WriteLine(R[1, 1]); file.WriteLine(R[1, 2]); file.WriteLine(R[2, 0]); file.WriteLine(R[2, 1]); file.WriteLine(R[2, 2]); file.WriteLine(T[0, 0]); file.WriteLine(T[1, 0]); file.WriteLine(T[2, 0]); } } else { calib_finished = false; } } } else { return; } } } } else { frame_freeze = true; //draw_leap Controller controller = new Controller(); Leap.Frame leapframe = controller.Frame(); if (leapframe.Fingers.Count() != 0) { Leap.Hand leap_hand = leapframe.Hands.First(); List <Matrix <float> > points_kl = transform_points(leapframe.Fingers, leap_hand); for (int pointn = 0; pointn < 5; pointn++) { DrawEllipse(points_kl[pointn], Brushes.Red, 5.0); // 0 ~ 4 fingertips } DrawEllipse(points_kl[5], Brushes.BlueViolet, 7.0); //palm position for (int pointn = 6; pointn < points_kl.Count(); pointn++) { DrawEllipse(points_kl[pointn], Brushes.Yellow, 3.0);// finger bones } //MessageBox.Show("projection done!"); if (MessageBox.Show("Start adjusting?", "Projection done!", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { adjust.Show(); return; } else { } } frame_freeze = false; } } }
void Update() { if(leapInitialized && leapController != null) { Leap.Frame frame = leapController.Frame(); if(frame.IsValid && (frame.Id != lastFrameID)) { leapFrame = frame; lastFrameID = leapFrame.Id; leapFrameCounter++; // // fix unfinished leap gesture progress // if(fCircleProgress > 0f && fCircleProgress < 1f) // fCircleProgress = 0f; // if(fSwipeProgress > 0f && fSwipeProgress < 1f) // fSwipeProgress = 0f; // if(fKeyTapProgress > 0f && fKeyTapProgress < 1f) // fKeyTapProgress = 0f; // if(fScreenTapProgress > 0f && fScreenTapProgress < 1f) // fScreenTapProgress = 0f; // get the prime hand leapHand = leapFrame.Hand(leapHandID); if(leapHand == null || !leapHand.IsValid) { leapHand = GetFrontmostHand(); leapHandID = leapHand != null && leapHand.IsValid ? leapHand.Id : 0; } // get the prime pointable leapPointable = leapFrame.Pointable(leapPointableID); if(leapPointable == null || !leapPointable.IsValid) { leapPointable = leapHand.IsValid ? GetPointingFigner(leapHand) : leapFrame.Pointables.Frontmost; leapPointableID = leapPointable != null && leapPointable.IsValid ? leapPointable.Id : 0; leapPointableHandID = leapPointable != null && leapPointable.IsValid && leapPointable.Hand.IsValid ? leapPointable.Hand.Id : 0; } if(leapPointable != null && leapPointable.IsValid && leapPointable.Hand != null && leapPointable.Hand.IsValid && leapHand != null && leapHand.IsValid && leapPointable.Hand.Id == leapHand.Id) { leapPointablePos = LeapToUnity(leapPointable.StabilizedTipPosition, true); leapPointableDir = LeapToUnity(leapPointable.Direction, false); //leapPointableQuat = Quaternion.LookRotation(leapPointableDir); } else { leapPointable = null; leapPointableID = 0; leapPointableHandID = 0; } Leap.Vector stabilizedPosition = Leap.Vector.Zero; if(leapHandID != 0) { leapHandPos = LeapToUnity(leapHand.StabilizedPalmPosition, true); stabilizedPosition = leapHand.StabilizedPalmPosition; leapHandFingersCount = leapHand.Fingers.Count; bool bCurrentHandGrip = handGripDetected; handGripDetected = !isHandOpen(leapHand); handReleaseDetected = !handGripDetected; if(controlMouseCursor) { if(!bCurrentHandGrip && handGripDetected) { MouseControl.MouseDrag(); } else if(bCurrentHandGrip && handReleaseDetected) { MouseControl.MouseRelease(); } } } else { if(controlMouseCursor && handGripDetected) { MouseControl.MouseRelease(); } leapHandFingersCount = 0; handGripDetected = false; handReleaseDetected = false; } // estimate the cursor coordinates if(stabilizedPosition.MagnitudeSquared != 0f) { Leap.InteractionBox iBox = frame.InteractionBox; Leap.Vector normalizedPosition = iBox.NormalizePoint(stabilizedPosition); cursorNormalPos.x = normalizedPosition.x; cursorNormalPos.y = normalizedPosition.y; cursorScreenPos.x = cursorNormalPos.x * UnityEngine.Screen.width; cursorScreenPos.y = cursorNormalPos.y * UnityEngine.Screen.height; if(controlMouseCursor) { MouseControl.MouseMove(cursorNormalPos); } } // Gesture analysis GestureList gestures = frame.Gestures (); for (int i = 0; i < gestures.Count; i++) { Gesture gesture = gestures[i]; if(Time.realtimeSinceStartup < gestureTrackingAtTime) continue; switch (gesture.Type) { case Gesture.GestureType.TYPECIRCLE: CircleGesture circle = new CircleGesture(gesture); if(iCircleGestureID != circle.Id && circle.State == Gesture.GestureState.STATESTOP) { iCircleGestureID = circle.Id; fCircleProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } else if(circle.Progress < 1f) { fCircleProgress = circle.Progress; } break; case Gesture.GestureType.TYPESWIPE: SwipeGesture swipe = new SwipeGesture(gesture); if(iSwipeGestureID != swipe.Id && swipe.State == Gesture.GestureState.STATESTOP) { iSwipeGestureID = swipe.Id; fSwipeProgress = 1f; // swipe.Progress gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; leapSwipeDir = LeapToUnity(swipe.Direction, false); leapSwipeSpeed = LeapToUnity(swipe.Position - swipe.StartPosition, true); if(swipe.DurationSeconds != 0) leapSwipeSpeed /= swipe.DurationSeconds; else leapSwipeSpeed = Vector3.zero; } else if(swipe.State != Gesture.GestureState.STATESTOP) { fSwipeProgress = 0.5f; } break; case Gesture.GestureType.TYPEKEYTAP: KeyTapGesture keytap = new KeyTapGesture (gesture); // if(iKeyTapGestureID != keytap.Id && // keytap.State == Gesture.GestureState.STATESTOP) { iKeyTapGestureID = keytap.Id; fKeyTapProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } // else if(keytap.Progress < 1f) // { // fKeyTapProgress = keytap.Progress; // } break; case Gesture.GestureType.TYPESCREENTAP: ScreenTapGesture screentap = new ScreenTapGesture (gesture); // if(iScreenTapGestureID != screentap.Id && // screentap.State == Gesture.GestureState.STATESTOP) { iScreenTapGestureID = screentap.Id; fScreenTapProgress = 1f; gestureTrackingAtTime = Time.realtimeSinceStartup + MinTimeBetweenGestures; } // else if(screentap.Progress < 1f) // { // fScreenTapProgress = screentap.Progress; // } break; default: Debug.LogError("Unknown gesture type."); break; } } if(DebugCamera) { DoDisplayFingers(); } } } }