Exemple #1
0
        void newFrameHandler(object sender, FrameEventArgs eventArgs)
        {
            Frame frame = eventArgs.frame;

            fpsDisplay.Content = frame.CurrentFramesPerSecond.ToString();
            if (frame.Hands.Count > 0)
            {
                Hand hand = frame.Hands[0];

                string handType = hand.IsLeft ? "Left" : "Right";


                // fingers
                Finger thumb   = hand.Fingers[0];
                Finger pointer = hand.Fingers[1];
                Finger middle  = hand.Fingers[2];
                Finger ring    = hand.Fingers[3];
                Finger pinky   = hand.Fingers[4];

                handTypeDisplay.Content = hand.IsLeft ? "left" : "right";

                Arm         arm           = hand.Arm;
                Leap.Vector armDirection  = arm.Direction;
                Leap.Vector handDirection = hand.Direction;

                double angleRadians = armDirection.AngleTo(handDirection);
                double angleDegrees = Math.Round(angleRadians * 180 / Math.PI);
                currentAngle = angleDegrees;
                calculateAverageAngle();
                this.angleDisplay.Content = currentAverageAngle.ToString();

                if (recording == true)
                {
                    DateTime currentTime = DateTime.Now;
                    int      elapsedTime = Convert.ToInt32(((TimeSpan)(currentTime - startRecording)).TotalMilliseconds);
                    timeDisplay.Content = elapsedTime.ToString();
                    string line = "timestamp: " + elapsedTime.ToString() + " | hand: " + handType + " | angle: " + currentAverageAngle.ToString();
                    if (firstFrame == true)
                    {
                        using (StreamWriter recordFile = new StreamWriter(@"C:\Users\casch\Documents\Work\Uni\Studienarbeit\Implementierung\C#\wfe.txt"))
                        {
                            recordFile.WriteLine(line);
                        };

                        firstFrame = false;
                    }
                    else
                    {
                        using (StreamWriter recordFile = new StreamWriter(@"C:\Users\casch\Documents\Work\Uni\Studienarbeit\Implementierung\C#\wfe.txt", true))
                        {
                            recordFile.WriteLine(line);
                        };
                    }
                }
            }

            controller.RequestImages(frame.Id, Leap.Image.ImageType.DEFAULT, imagedata);
        }
        public override void OnFrame(Controller controller)
        {
            using (var frame = controller.Frame())
            {
                Vector A = new Vector(2, 0, 0);
                Vector B = new Vector(4, 2, 0);
                double rads = Math.Round(A.AngleTo(B), 2);
                Console.WriteLine("Radians " + rads);
                Console.WriteLine("Degrees " + Math.Round(rads*180/Math.PI, 2));

                //Console.WriteLine("Thumb: " + Math.Round(frame.Fingers[0].Length / 10, 2) + "cm");
                //Console.WriteLine("Index: " + Math.Round(frame.Fingers[1].Length / 10, 2) + "cm");
                //Console.WriteLine("Middle: " + Math.Round(frame.Fingers[2].Length / 10, 2) + "cm");
                //Console.WriteLine("Ring: " + Math.Round(frame.Fingers[3].Length / 10, 2) + "cm");
                //Console.WriteLine("Pinky: " + Math.Round(frame.Fingers[4].Length / 10, 2) + "cm\n");
            }
            Console.ReadLine();

            //Thread.Sleep(2000);

            //using (var frame = controller.Frame())
            //{
            //    _now = frame.Timestamp;
            //    _timeDifference = _now - _previous;

            //    if (frame.Hands.IsEmpty || _timeDifference < 5000)
            //    {
            //        return;
            //    }

            //    _previous = frame.Timestamp;

            //    if (frame.Gestures().Count > 0 && OnGesturesMade != null)
            //    {
            //        OnGesturesMade(frame.Gestures());
            //    }

            //    if (frame.Fingers.Count > 0 && OnFingersRegistered != null)
            //    {
            //        OnFingersRegistered(frame.Fingers);
            //    }
            //}
        }
    bool VerDirToYAxis(Vector dir, float threshold)
    {
        bool isVer = false;

        float radian = dir.AngleTo(Vector.YAxis);

        if(radian>threshold && radian<(Mathf.PI - threshold))
        {
            isVer = true;
        }
        return isVer;
    }
    // Update is called once per frame
    void Update()
    {
        mFrame = leapController.Frame();
        int fingerCount = 0;

        if (numbersGestureRegistered || closeFistRegistered || openFistRegistered ||
            keytapGestureRegistered || twoFingerKeytapRegistered || threeFingerKeytapRegistered ||
            screentapGestureRegistered || twoFingerScreentapRegistered || threeFingerScreentapRegistered || steeringWheelRegistered)
        {
            fingerCount = GetFingerCount();
        }

        foreach (Leap.Gesture gesture in mFrame.Gestures())
        {
            switch (gesture.Type)
            {
            case Leap.Gesture.GestureType.TYPECIRCLE:
                if (circleGestureRegistered)
                {
                    BuiltInGestureRecognised(gesture, EasyLeapGestureType.TYPECIRCLE);
                    onCircleGestureRecognized();
                }
                break;

            case Leap.Gesture.GestureType.TYPESWIPE:
                if (swipeGestureRegistered)
                {
                    BuiltInGestureRecognised(gesture, EasyLeapGestureType.TYPESWIPE);
                }
                break;

            case Leap.Gesture.GestureType.TYPEKEYTAP:
                if (keytapGestureRegistered && fingerCount == 1)
                {
                    BuiltInGestureRecognised(gesture, EasyLeapGestureType.TYPEKEYTAP);
                }
                if (twoFingerKeytapRegistered && fingerCount == 2)
                {
                    BuiltInImprovedGestureRecognised(gesture, EasyLeapGestureType.TWO_FINGERS_KEYTAP);
                }
                if (threeFingerKeytapRegistered && fingerCount == 3)
                {
                    BuiltInImprovedGestureRecognised(gesture, EasyLeapGestureType.THREE_FINGERS_KEYTAP);
                }
                break;

            case Leap.Gesture.GestureType.TYPESCREENTAP:
                if (screentapGestureRegistered && fingerCount == 1)
                {
                    BuiltInGestureRecognised(gesture, EasyLeapGestureType.TYPESCREENTAP);
                }
                if (twoFingerScreentapRegistered && fingerCount == 2)
                {
                    BuiltInImprovedGestureRecognised(gesture, EasyLeapGestureType.TWO_FINGERS_SCREENTAP);
                }
                if (threeFingerScreentapRegistered && fingerCount == 3)
                {
                    BuiltInImprovedGestureRecognised(gesture, EasyLeapGestureType.THREE_FINGERS_SCREENTAP);
                }
                break;
            }
        }
        if (mFrame.Gestures().Count == 0)
        {
            ClearDraggingGestures();
        }

        if (numbersGestureRegistered || closeFistRegistered || openFistRegistered)
        {
            switch (fingerCount)
            {
            case 0:
                // NO FINGERS
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.DEFAULT);
                }
                if (closeFistRegistered)
                {
                    if (mFrame.Hands.Count == 1)
                    {
                        if (PalmIsHorizontal(mFrame.Hands[0]))
                        {
                            CloseFistGestureRecognised(EasyLeapGestureState.STATESTOP);
                        }
                    }
                    else
                    {
                        CloseFistGestureRecognised(EasyLeapGestureState.STATEINVALID);
                    }
                }
                if (openFistRegistered)
                {
                    if (mFrame.Hands.Count == 1)
                    {
                        if (PalmIsHorizontal(mFrame.Hands[0]))
                        {
                            OpenFistGestureRecognised(EasyLeapGestureState.STATESTART);
                        }
                    }
                    else
                    {
                        OpenFistGestureRecognised(EasyLeapGestureState.STATEINVALID);
                    }
                }
                break;

            case 1:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.ONE);
                }
                break;

            case 2:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.TWO);
                }
                break;

            case 3:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.THREE);
                }
                break;

            case 4:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.FOUR);
                }
                break;

            case 5:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.FIVE);
                }
                if (closeFistRegistered && mFrame.Hands.Count == 1)
                {
                    CloseFistGestureRecognised(EasyLeapGestureState.STATESTART);
                }
                if (openFistRegistered)
                {
                    OpenFistGestureRecognised(EasyLeapGestureState.STATESTOP);
                }
                break;

            case 6:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.SIX);
                }
                break;

            case 7:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.SEVEN);
                }
                break;

            case 8:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.EIGHT);
                }
                break;

            case 9:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.NINE);
                }
                break;

            case 10:
                if (numbersGestureRegistered)
                {
                    NumbersGestureRecognised(EasyLeapGestureType.TEN);
                }
                break;
            }
        }

        if (pushGestureRegistered || pullGestureRegistered)
        {
            if (mFrame.Hands.Count == 1)
            {
                if (pushGestureRegistered)
                {
                    if (mFrame.Hands[0].PalmVelocity.y < -EasyLeapGesture.MinPushPullVelocity)
                    {
                        PushGestureRecognised(EasyLeapGestureState.STATESTART);
                    }
                    else
                    {
                        PushGestureRecognised(EasyLeapGestureState.STATEINVALID);
                    }
                }
                if (pullGestureRegistered)
                {
                    if (mFrame.Hands[0].PalmVelocity.y > EasyLeapGesture.MinPushPullVelocity)
                    {
                        PullGestureRecognised(EasyLeapGestureState.STATESTART);
                    }
                    else
                    {
                        PullGestureRecognised(EasyLeapGestureState.STATEINVALID);
                    }
                }
            }
            else
            {
                PushGestureRecognised(EasyLeapGestureState.STATEINVALID);
                PullGestureRecognised(EasyLeapGestureState.STATEINVALID);
            }
        }

        if (doubleInwardsSwipeGestureRegistered || doubleOutwardsSwipeGestureRegistered)
        {
            if (mFrame.Hands.Count == 2)
            {
                bool leftHandSwipeIn  = (PalmIsHorizontal(mFrame.Hands.Leftmost)) && mFrame.Hands.Leftmost.PalmVelocity.x > EasyLeapGesture.MinSwipeVelocity;
                bool rightHandSwipeIn = (PalmIsHorizontal(mFrame.Hands.Rightmost)) && mFrame.Hands.Rightmost.PalmVelocity.x < -EasyLeapGesture.MinSwipeVelocity;
                if (doubleInwardsSwipeGestureRegistered && (leftHandSwipeIn && rightHandSwipeIn))
                {
                    if (mFrame.Hands[0].StabilizedPalmPosition.DistanceTo(mFrame.Hands[1].StabilizedPalmPosition) < EasyLeapGesture.MaxPalmDistance)
                    {
                        DoubleInwardsSwipeRecognised(EasyLeapGestureState.STATESTART);
                    }
                }
                else
                {
                    DoubleInwardsSwipeRecognised(EasyLeapGestureState.STATEINVALID);
                }
                bool leftHandSwipeOut  = (PalmIsHorizontal(mFrame.Hands.Leftmost)) && mFrame.Hands.Leftmost.PalmVelocity.x < -EasyLeapGesture.MinSwipeVelocity;
                bool rightHandSwipeOut = (PalmIsHorizontal(mFrame.Hands.Rightmost)) && mFrame.Hands.Rightmost.PalmVelocity.x > EasyLeapGesture.MinSwipeVelocity;
                if (doubleOutwardsSwipeGestureRegistered && leftHandSwipeOut && rightHandSwipeOut)
                {
                    if (mFrame.Hands[0].StabilizedPalmPosition.DistanceTo(mFrame.Hands[1].StabilizedPalmPosition) > EasyLeapGesture.MaxPalmDistance)
                    {
                        DoubleOutwardsSwipeRecognised(EasyLeapGestureState.STATESTART);
                    }
                }
                else
                {
                    DoubleOutwardsSwipeRecognised(EasyLeapGestureState.STATEINVALID);
                }
            }
        }

        if (clapGestureRegistered)
        {
            if (mFrame.Hands.Count == 2)
            {
                bool leftHandSwipeIn  = (!PalmIsHorizontal(mFrame.Hands.Leftmost)) && mFrame.Hands.Leftmost.PalmVelocity.x > EasyLeapGesture.MinClapVelocity;
                bool rightHandSwipeIn = (!PalmIsHorizontal(mFrame.Hands.Rightmost)) && mFrame.Hands.Rightmost.PalmVelocity.x < -EasyLeapGesture.MinClapVelocity;
                if (leftHandSwipeIn && rightHandSwipeIn)
                {
                    if (mFrame.Hands[0].StabilizedPalmPosition.DistanceTo(mFrame.Hands[1].StabilizedPalmPosition) < EasyLeapGesture.MaxPalmClapDistance)
                    {
                        ClapRecognised(EasyLeapGestureState.STATESTART);
                    }
                }
                else
                {
                    ClapRecognised(EasyLeapGestureState.STATEINVALID);
                }
            }
        }

        if (steeringWheelRegistered)
        {
            float palmsAngle = (mFrame.Hands.Leftmost.PalmNormal.AngleTo(mFrame.Hands.Rightmost.PalmNormal) * Mathf.Rad2Deg);
            if (mFrame.Hands.Count >= 1 && fingerCount < 2 && (palmsAngle > 110 || palmsAngle < 70))
            {
                Leap.Vector leftMost    = mFrame.Hands.Leftmost.StabilizedPalmPosition;
                Leap.Vector rightMost   = mFrame.Hands.Rightmost.StabilizedPalmPosition;
                Leap.Vector steerVector = (leftMost - rightMost).Normalized;
                //steerVector.z = 0;
                float angle = steerVector.AngleTo(Leap.Vector.Left) * Mathf.Rad2Deg * (leftMost.y > rightMost.y ? 1 : -1);
                SteeringWheelRecognised(angle, Mathf.Abs(leftMost.z) - Mathf.Abs(rightMost.z));
            }
        }

        // Send gestures detected to all registered gesture listeners
        SendGesturesToListeners();
    }
 /// <summary>
 /// 判定一个摊开手掌的状态是否是水平向前
 /// </summary>
 /// <returns><c>true</c>, if and forward open hand was hored, <c>false</c> otherwise.</returns>
 bool IsHorAndForwardOpenHand(Vector palmDir,Vector fingerDir )
 {
     bool isHorAndForward = false;
     if( fingerDir.AngleTo(-Vector.ZAxis) < ForwardThreshold &&
         palmDir.AngleTo(-Vector.YAxis) < DownThreshold )
     {
         isHorAndForward=true;
     }
     return isHorAndForward;
 }
    // Update is called once per frame
    void Update()
    {
        int clickIndex;
        //这里的判定本该分成预备状态、运动状态、终结状态。但是对于点击来讲,这三个状态的手势判定条件都相同(手势相同、阈值相同)
        //所以现在都用同一个控制器来表示

        if (EnterClickState(out clickIndex))
        {
            //初始状态
            if(!m_IsEnteredClick)
            {
                //标记进入点击状态,记录初始位置
                m_IsEnteredClick = true;
                m_EnterPos = m_HandData.FingerDatas[clickIndex][Finger.FingerType.TYPE_INDEX].m_Point.m_Position;
                m_PreviousPos = m_EnterPos;

                //延迟触发初始事件
                StartCoroutine(EnterClickDelay());
            }
            //非初始状态
            else
            //不是反弹状态
            if(!m_IsEnteredBackClick)
            {
                m_DeepClickingTime+=Time.deltaTime;
                //是否进入一次位置判定
                if (m_DeepClickingTime > CheckTimeStep)
                {
                    m_DeepClickingTime = 0f;
                    //收集当前手指索引的食指指尖位置数据
                    Vector indexFingerTipPos = m_HandData.FingerDatas[clickIndex][Finger.FingerType.TYPE_INDEX].m_Point.m_Position;
                    m_Off = indexFingerTipPos - m_PreviousPos;

                    //是向前点击状态,偏移向量与-z轴(Leap坐标系)的夹角小于某个阈值
                    if(m_Off.AngleTo(-Vector.ZAxis)<DeepClickRadianThreshold)
                    //if (indexFingerTipPos.z < m_PreviousPos.z)
                    {
                        float deep = m_EnterPos.z - indexFingerTipPos.z;
                        //是反弹状态
                        if( deep > DeepThreshold )
                        {
                            //标记进入了反弹状态,记录反弹状态的位置
                            m_IsEnteredBackClick = true;
                            m_EnterBackPos = indexFingerTipPos;
                            if(m_OnBackFunc != null)
                            {
                               // print("aaa");
                                m_OnBackFunc();
                            }
                        }
                    }
                    //不是前进状态
                    else
                    {
                        //手势匹配失败,重置变量
                        ResetClickState();
                    }
                    //更新m_PreviousPos的位置
                    m_PreviousPos = indexFingerTipPos;
                }
            }
            else //进入了返回状态
            {
                m_BackClickingTime+=Time.deltaTime;
                //进入位置判定
                if ( m_BackClickingTime > CheckTimeStep )
                {
                    m_BackClickingTime = 0f;
                    Vector indexFingerTipPos = m_HandData.FingerDatas[clickIndex][Finger.FingerType.TYPE_INDEX].m_Point.m_Position;
                    //是后退状态
                    if (m_PreviousPos.z < indexFingerTipPos.z)
                    {
                        float backDeep = indexFingerTipPos.z - m_EnterBackPos.z;
                        //满足了反弹阈值
                        if( backDeep > BackThreshold )
                        {
                            print("Clicked");
                            //触发事件,重置状态
                            if (m_OnClicked!=null)
                            {
                                print("Clicked()");
                                m_OnClicked();
                            }
                            ResetClickState();
                        }
                    }
                }
            }
        }
        //不是手指点击状态
        else
        {
            ResetClickState();
            m_IsEnteredClick = false;
        }
    }
    /// <summary>
    /// 判定一个手指指向是否是点击前方
    /// 这里阈值的判定与其说是+x轴,倒不如说是距离yz面的夹角程度更直接,但实现方式上选择了+x轴。
    /// </summary>
    /// <param name="dir"></param>
    /// <param name="threshold">表示距离+x的夹角,标准是90度</param>
    bool IsPointAsClickForwardDir(Vector dir,float threshold)
    {
        bool IsPointAsClick = false;
        float radian = dir.AngleTo(Vector.Right);

        if (radian > threshold && radian < Mathf.PI - threshold)
        {
            IsPointAsClick = true;
        }
        return IsPointAsClick;
    }