private async void WindowLoaded(object sender, RoutedEventArgs e)
        {
            // Step 1: Connect to Microsoft Gestures service
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, arg) => Dispatcher.Invoke(() => GesturesServiceStatus.Text = $"[{arg.Status}]");
            Closed += (s, arg) => _gesturesService?.Dispose();
            await _gesturesService.ConnectAsync();

            // Step 2: Define your custom gesture
            // Start with defining the first pose, ...
            var hold = new HandPose("Hold", new FingerPose(new[] { Finger.Thumb, Finger.Index }, FingerFlexion.Open, PoseDirection.Forward),
                                    new FingertipDistanceRelation(Finger.Index, RelativeDistance.NotTouching, Finger.Thumb),
                                    new FingertipPlacementRelation(Finger.Index, RelativePlacement.Above, Finger.Thumb));
            // ... define the second pose, ...
            var rotate = new HandPose("Rotate", new FingerPose(new[] { Finger.Thumb, Finger.Index }, FingerFlexion.Open, PoseDirection.Forward),
                                      new FingertipDistanceRelation(Finger.Index, RelativeDistance.NotTouching, Finger.Thumb),
                                      new FingertipPlacementRelation(Finger.Index, RelativePlacement.Right, Finger.Thumb));

            // ... finally define the gesture using the hand pose objects defined above forming a simple state machine: hold -> rotate
            _rotateGesture            = new Gesture("RotateRight", hold, rotate);
            _rotateGesture.Triggered += (s, args) => Dispatcher.Invoke(() => Arrow.RenderTransform = new RotateTransform(++_rotateTimes * 90, Arrow.ActualWidth / 2, Arrow.ActualHeight / 2));

            // Step 3: Register the gesture (When window focus is lost (gained) the service will automatically unregister (register) the gesture)
            //         To manually control the gesture registration, pass 'isGlobal: true' parameter in the function call below
            await _gesturesService.RegisterGesture(_rotateGesture);
        }
        private async void WindowLoaded(object sender, RoutedEventArgs windowLoadedArgs)
        {
            // In XAML, we have specified a 3D scene containing a cube. We would like to use our hand to control the camera in this scene.
            // The following gesture subscribes to the hand skeleton stream whenever our hand forms the pinch pose. The information in
            // the skeleton stream will be used to move the camera.

            // Data flow outline:
            // [GestureServiceEndpoint]-----Skeleton----->[PalmSmoother]-----SmoothedPositionDelta----->[SphericalCamera]

            // We would like to translate hand motion to camera motion. Because the palm position
            // values in the skeleton stream contain some jitter, we smooth them (using a moving-average window).
            _palmSmoother = new PalmSmoother();

            // Define the gesture so that when the hand forms a pinch pose register to the skeleton stream and pass it to the palm smoother.
            var pinchClose = new PinchPose("PinchClosePose", pinchSpread: false);

            pinchClose.Triggered += (s, args) => _gesturesService.RegisterToSkeleton((s1, args1) => _palmSmoother.Smooth(args1.DefaultHandSkeleton));
            _cameraPinch          = new Gesture("CameraPinch", new PinchPose("PinchOpenPose", pinchSpread: true),
                                                pinchClose,
                                                new PinchPose("PinchReleasePose", pinchSpread: true));
            _cameraPinch.IdleTriggered += (s, args) => _gesturesService.UnregisterFromSkeleton();

            // The smoothed palm position is used to rotate the camera.
            _sphericalCamera = new SphericalCamera(Camera, Dispatcher);
            _palmSmoother.SmoothedPositionChanged += (s, args) => _sphericalCamera.UpdateCamera(args.SmoothedPositionDelta);

            // Connect to the Gestures Service and register the gesture we've defined
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, arg) => Dispatcher.Invoke(() => GesturesServiceStatus.Text = $"[{arg.Status}]");
            await _gesturesService.ConnectAsync();

            await _gesturesService.RegisterGesture(_cameraPinch);
        }
Example #3
0
        private static async Task RegisterGestures(string gesturesServiceHostName)
        {
            // Step 1: Connect to Microsoft Gestures service
            _gesturesService = GesturesServiceEndpointFactory.Create(gesturesServiceHostName);
            _gesturesService.StatusChanged += (s, arg) => Console.Title = $"GesturesServiceStatus [{arg.Status}]";
            await _gesturesService.ConnectAsync();

            // Step 2: Define bunch of custom Gestures, each detection of the gesture will emit some message into the console
            await RegisterRotateRightGesture();
            await RegisterDropTheMicGesture();
            await RegisterLikeGesture();
        }
Example #4
0
        private async void WindowLoaded(object sender, RoutedEventArgs windowLoadedArgs)
        {
            IndexPosition  = new FingerPosition(this.Canvas, this.Dispatcher, this.IndexEllipse, Finger.Index);
            ThumbPosition  = new FingerPosition(this.Canvas, this.Dispatcher, this.ThumbEllipse, Finger.Thumb);
            MiddlePosition = new FingerPosition(this.Canvas, this.Dispatcher, this.MiddleEllipse, Finger.Middle);
            RingPosition   = new FingerPosition(this.Canvas, this.Dispatcher, this.RingEllipse, Finger.Ring);
            PinkyPosition  = new FingerPosition(this.Canvas, this.Dispatcher, this.PinkyEllipse, Finger.Pinky);

            _gesturesService = GesturesServiceEndpointFactory.Create();
            await _gesturesService.ConnectAsync();

            await _gesturesService.RegisterToSkeleton(SkeletonHandler);
        }
Example #5
0
        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            GesturesService = GesturesServiceEndpointFactory.Create();
            GesturesService.StatusChanged    += GesturesService_StatusChanged;
            GesturesService.WarningLog       += GesturesService_WarningLog;
            GesturesService.ConnectionClosed += GesturesService_ConnectionClosed;

            GesturesCombo.ItemsSource = GestureHelper.Gestures().OrderBy(g => g.Name);

            if (!await GesturesService.ConnectAsync())
            {
                MessageBox.Show("Errore durante la connessione al Gesture Service!");
            }
        }
Example #6
0
        // It registers the all the gestures that can be used.
        private static async Task RegisterGestures()
        {
            // Step 1: Connect to Microsoft Gestures service
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, arg) => Console.Title = $"Next! ServiceStatus [{arg.Status}]";
            await _gesturesService.ConnectAsync();

            // Step 2: Define bunch of custom Gestures
            await RegisterFingerSnapGesture();
            await RegisterRotateRightGesture();
            await RegisterRotateLeftGesture();
            await RegisterRotateRightLeftHandGesture();
            await RegisterRotateLeftLeftHandGesture();
        }
        public async Task Init()
        {
            // Step1: Define the Rock-Paper-Scissors gestures
            // Create a pose for 'Rock'...
            var rockPose = new HandPose("RockPose", new FingerPose(new AllFingersContext(), FingerFlexion.Folded));

            rockPose.Triggered += (s, arg) => UserStrategyChanged?.Invoke(GameStrategy.Rock);

            // ...another for 'Paper'...
            var paperPose = new HandPose("PaperPose", new PalmPose(new AnyHandContext(), PoseDirection.Left | PoseDirection.Right, PoseDirection.Forward),
                                         new FingerPose(new AllFingersContext(), FingerFlexion.Open));

            paperPose.Triggered += (s, arg) => UserStrategyChanged?.Invoke(GameStrategy.Paper);

            // ...and last one for 'Scissors'...
            var scissorsPose = new HandPose("ScissorsPose", new FingerPose(new[] { Finger.Index, Finger.Middle }, FingerFlexion.Open),
                                            new FingertipDistanceRelation(Finger.Index, RelativeDistance.NotTouching, Finger.Middle),
                                            new FingerPose(new[] { Finger.Ring, Finger.Pinky }, FingerFlexion.Folded));

            scissorsPose.Triggered += (s, arg) => UserStrategyChanged?.Invoke(GameStrategy.Scissors);

            // ...a PassThroughtGestureSegment is a structural gesture segment that provides a way to simplify a gesture state machine construction by 'short-circuiting'
            // between gesture segments connectd to it and gesture segements it connects to. It helps reduce the number of SubPaths that needs to be defined.
            // Very handy when you need to define a Clique (see https://en.wikipedia.org/wiki/Clique_(graph_theory)#1)
            // as in this case where Rock, Paper and Scissors are all connected to each other...
            var epsilonState = new PassThroughGestureSegment("Epsilon");

            // ...this pose is an artificial stop pose. Namely, we want to keep the gesture detector in one of the pose states without ending the gesture so we add this
            // pose as a pose that completes the gesture assuming the user will not perform it frequently.
            // As long as the user continues to perform the 'Rock', 'Paper' or 'Scissors' poses we will remain within the gesture's state machine.
            var giveUpPose = new HandPose("GiveUpPose", new PalmPose(new AnyHandContext(), PoseDirection.Forward, PoseDirection.Up),
                                          new FingerPose(new AllFingersContext(), FingerFlexion.Open));

            _gameGesture = new Gesture("RockPaperScissorGesture", epsilonState, giveUpPose);
            // ...add a sub path back and forth from the PassthroughGestureSegment to the various poses
            _gameGesture.AddSubPath(epsilonState, rockPose, epsilonState);
            _gameGesture.AddSubPath(epsilonState, paperPose, epsilonState);
            _gameGesture.AddSubPath(epsilonState, scissorsPose, epsilonState);

            // In case the user performs a pose that is not one of the game poses the gesture resets and this event will trigger
            _gameGesture.IdleTriggered += (s, arg) => UserStrategyChanged?.Invoke(GameStrategy.None);

            // Step2: Connect to Gesture Detection Service, route StatusChanged event to the UI and register the gesture
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (oldStatus, newStatus) => GesturesDetectionStatusChanged?.Invoke(oldStatus, newStatus);
            await _gesturesService.ConnectAsync();

            await _gesturesService.RegisterGesture(_gameGesture);
        }
Example #8
0
        public async Task Init()
        {
            // Set the gesture service
            _gesturesService = GesturesServiceEndpointFactory.Create("localhost");
            _gesturesService.StatusChanged += (oldVal, newVal) => GesturesDetectionStatusChanged?.Invoke(oldVal, newVal);
            await _gesturesService.ConnectAsync();


            var hurufI = new HandPose(
                "Huruf_I",
                new PalmPose(Hand.RightHand, PoseDirection.Up | PoseDirection.Forward),
                new FingerPose(new[] { Finger.Pinky }, FingerFlexion.Open),
                new FingerPose(new[] { Finger.Index, Finger.Ring, Finger.Middle }, FingerFlexion.Folded));

            hurufI.Triggered += (s, arg) => GestureChanged?.Invoke(arg.GestureSegment.Name);

            var piece = new HandPose(
                "Piece",
                new PalmPose(Hand.RightHand, PoseDirection.Up | PoseDirection.Forward),
                new FingerPose(new[] { Finger.Index, Finger.Middle }, FingerFlexion.Open),
                new FingerPose(new[] { Finger.Pinky, Finger.Ring, }, FingerFlexion.Folded));

            piece.Triggered += (s, arg) => GestureChanged?.Invoke(arg.GestureSegment.Name);

            var baik = new HandPose(
                "baik",
                new PalmPose(Hand.RightHand, PoseDirection.Left | PoseDirection.Forward),
                new FingerPose(new[] { Finger.Ring, Finger.Pinky, Finger.Middle }, FingerFlexion.OpenStretched),
                new FingerPose(new[] { Finger.Index, Finger.Thumb, }, FingerFlexion.Folded));

            baik.Triggered += (s, arg) => GestureChanged?.Invoke(arg.GestureSegment.Name);


            var alphabetGesture = new PassThroughGestureSegment("performing_state");

            _detectedGesture = new Gesture("Sample_Gesture", alphabetGesture);
            _detectedGesture.AddSubPath(alphabetGesture, hurufI, alphabetGesture);
            _detectedGesture.AddSubPath(alphabetGesture, piece, alphabetGesture);
            _detectedGesture.AddSubPath(alphabetGesture, baik, alphabetGesture);


            await _gesturesService.RegisterGesture(_detectedGesture, isGlobal : true);

            await RegisterLikeGesture();
            await RegisterThankYouGesture();
        }
        private async void WindowLoaded(object sender, RoutedEventArgs e)
        {
            // Step 1: Connect to Microsoft Gestures service
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, args) => Dispatcher.Invoke(() => GeturesServiceStatus.Text = $"[{args.Status}]");
            Closed += (s, args) => _gesturesService?.Dispose();
            await _gesturesService.ConnectAsync();

            // Step 2: Define the RewindGesture gesture as follows:
            //  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
            //  │          │    │          │    │          │    │          │    │          │    │          │    │          │
            //  │   Idle   │ -> │  Spread  │ -> │  Pause   │ -> │  Rewind  │ -> │KeepRewind│ -> │ Release  │ -> │   Idle   │
            //  │          │    │(unpinch) │    │ (pinch)  │    │  (left)  │    │ (pinch)  │    │(unpinch) │    │          │
            //  └──────────┘    └──────────┘    └────┬─────┘    └──────────┘    └──────────┘    └──────────┘    └──────────┘
            //                                       │                                               ^
            //                                       └───────────────────────────────────────────────┘
            //
            // Whenever the gesture returns to the Idle state, playback will resume
            //
            var spreadPose = GeneratePinchPose("Spread", true);
            var pausePose  = GeneratePinchPose("Pause");

            pausePose.Triggered += (s, args) => Dispatcher.Invoke(() => VideoStatus.Text = "⏸");

            var rewindMotion = new HandMotion("Rewind", new PalmMotion(VerticalMotionSegment.Left));

            rewindMotion.Triggered += (s, args) => Dispatcher.Invoke(() => VideoStatus.Text = "⏪");

            var keepRewindingPose = GeneratePinchPose("KeepRewind");
            var releasePose       = GeneratePinchPose("Release", true);

            // Then define the gesture by concatenating the previous objects to form a simple state machine
            _rewindGesture = new Gesture("RewindGesture", spreadPose, pausePose, rewindMotion, keepRewindingPose, releasePose);
            // Detect if the user releases the pinch-grab hold in order to resume the playback
            _rewindGesture.AddSubPath(pausePose, releasePose);

            // Continue playing the video when the gesture resets (either successful or aborted)
            _rewindGesture.Triggered     += (s, args) => Dispatcher.Invoke(() => VideoStatus.Text = "▶");
            _rewindGesture.IdleTriggered += (s, args) => Dispatcher.Invoke(() => VideoStatus.Text = "▶");

            // Step 3: Register the gesture (When window focus is lost (gained) the service will automatically unregister (register) the gesture)
            //         To manually control the gesture registration, pass 'isGlobal: true' parameter in the function call below
            await _gesturesService.RegisterGesture(_rewindGesture);
        }
Example #10
0
        private static async Task RegisterGestures(string gesturesServiceHostName)
        {
            // Step 1: Connect to Microsoft Gestures service
            _gesturesService = GesturesServiceEndpointFactory.Create(gesturesServiceHostName);
            _gesturesService.StatusChanged += (s, arg) => Console.Title = $"GesturesServiceStatus [{arg.Status}]";
            await _gesturesService.ConnectAsync();

            // Step 2: Define bunch of custom Gestures, each detection of the gesture will emit some message into the console
            await RegisterOneFingerGesture();
            await RegisterTwoFingerGesture();
            await RegisterThreeFingerGesture();
            await RegisterFourFingerGesture();
            await RegisterOpenGesture();
            await RegisterCloseGesture();
            await RegisterRotateUp1Gesture();
            await RegisterRotateUp2Gesture();
            await RegisterRotateDown1Gesture();
            await RegisterRotateDown2Gesture();
        }
Example #11
0
        private async void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Globals.Ribbons.GesturesRibbon.txtStatus.Text = EndpointStatus.Disconnected.ToString();

            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, args) => Globals.Ribbons.GesturesRibbon.txtStatus.Text = args.Status.ToString();
            await _gesturesService.ConnectAsync();

            // Share Gesture
            _shareGesture            = new ThreeUnpinchGesture("ShareAsAttachment");
            _shareGesture.Triggered += OnShareWithGesture;
            await _gesturesService.RegisterGesture(_shareGesture);

            // Start Presentation
            _explodeGesture            = new ExplodeGesture("StartPresentation");
            _explodeGesture.Triggered += OnStartPresentation;
            await _gesturesService.RegisterGesture(_explodeGesture);

            // Advance to next Slide Gesture
            _tapGesture            = new TapGesture("NextSlide");
            _tapGesture.Triggered += OnNextSlide;
            await _gesturesService.RegisterGesture(_tapGesture);
        }
Example #12
0
        public async Task Init()
        {
            var pausePose = new HandPose("PausePose", new PalmPose(new AnyHandContext(), PoseDirection.Forward, PoseDirection.Up),
                                         new FingerPose(new AllFingersContext(), FingerFlexion.Open, PoseDirection.Up));

            //pausePose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureType.Pause.ToString()));
            pausePose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.PLAYER_PAUSE));

            var selectPose = new HandPose("selectPose", new PalmPose(new AnyHandContext(), PoseDirection.Left, PoseDirection.Forward),
                                          new FingerPose(Finger.Index, FingerFlexion.OpenStretched, PoseDirection.Forward),
                                          new FingerPose(new AllFingersContext(new [] { Finger.Middle, Finger.Ring, Finger.Pinky }), PoseDirection.Backward));

            selectPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_SELECT));

            var menuPose = new HandPose("menuPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Down),
                                        new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring }), FingerFlexion.OpenStretched, PoseDirection.Down),
                                        new FingerPose(new AllFingersContext(new [] { Finger.Thumb, Finger.Pinky }), FingerFlexion.Folded)
                                        );

            //menuPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(GestureType.Menu);
            menuPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_HOME));

            var contextPose = new HandPose("contextPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Up),
                                           new FingerPose(new AllFingersContext(new[] { Finger.Thumb, Finger.Pinky }), FingerFlexion.Open),
                                           new FingerPose(new AllFingersContext(new[] { Finger.Middle, Finger.Index, Finger.Ring }), FingerFlexion.Folded));

            contextPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_CONTEXTMENU));

            var backPose = new HandPose("BackPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Left),
                                        new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Open, PoseDirection.Left));

            backPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_BACK));

            var leftPose = new HandPose("LeftPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Left),
                                        new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.OpenStretched, PoseDirection.Left),
                                        new FingerPose(new AllFingersContext(new[] { Finger.Ring, Finger.Pinky }), FingerFlexion.Folded));

            leftPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_PREVIOUS));

            var leftStopPose = new HandPose("LeftStopPose", new PalmPose(new AnyHandContext()),
                                            new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Folded));

            var rightPose = new HandPose("RightPose", new PalmPose(new AnyHandContext(), PoseDirection.Forward, PoseDirection.Right),
                                         new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.OpenStretched, PoseDirection.Right),
                                         new FingerPose(new AllFingersContext(new[] { Finger.Ring, Finger.Pinky }), FingerFlexion.Folded));

            rightPose.Triggered += (s, arg) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_NEXT));

            var rightStopPose = new HandPose("RightStopPose", new PalmPose(new AnyHandContext()),
                                             new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Folded));

            var volumeUpPose = new HandPose("VolumeUpPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Up),
                                            new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Open, PoseDirection.Up),
                                            new FingerPose(new AllFingersContext(new[] { Finger.Thumb, Finger.Ring, Finger.Pinky }), FingerFlexion.Folded));

            volumeUpPose.Triggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.VOLUME_UP));

            var volumeUpStop = new HandPose("VolumeUpStopPose", new PalmPose(new AnyHandContext()),
                                            new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Folded));

            _volumeUpGesture = new Gesture("VolumeUpGesture", volumeUpPose, volumeUpStop);
            _volumeUpGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.VOLUME_DONE));

            var volumeDownPose = new HandPose("VolumeDownPose", new PalmPose(new AnyHandContext(), PoseDirection.Backward, PoseDirection.Down),
                                              new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Open, PoseDirection.Down),
                                              new FingerPose(new AllFingersContext(new[] { Finger.Thumb, Finger.Ring, Finger.Pinky }), FingerFlexion.Folded));

            volumeDownPose.Triggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.VOLUME_DOWN));

            var volumeDownStop = new HandPose("VolumeDownStopPose", new PalmPose(new AnyHandContext()),
                                              new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle }), FingerFlexion.Folded));

            _volumeDownGesture = new Gesture("VolumeDownGesture", volumeDownPose, volumeDownStop);
            _volumeDownGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.VOLUME_DONE));

            var pinchPoseRewind  = GeneratePinchPose("PinchPoseRewind");
            var pinchPoseForward = GeneratePinchPose("PinchPoseForward");

            var rewindMotion = new HandMotion("RewindMotion", new PalmMotion(VerticalMotionSegment.Left));

            rewindMotion.Triggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.PLAYER_REWIND));

            var forwardMotion = new HandMotion("ForwardMotion", new PalmMotion(VerticalMotionSegment.Right));

            forwardMotion.Triggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.PLAYER_FORWARD));

            var keepRewindingPose  = GeneratePinchPose("KeepRewindPose");
            var keepForwardingPose = GeneratePinchPose("KeepForwardingPose");

            var releasePoseRewind  = GeneratePinchPose("ReleasePoseRewind", true);
            var releasePoseForward = GeneratePinchPose("ReleasePoseForward", true);

            _rewindGesture = new Gesture("RewindGesture", pinchPoseRewind, rewindMotion, keepRewindingPose, releasePoseRewind);
            _rewindGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.PLAYER_SEEKDONE));

            _forwardGesture = new Gesture("ForwardGesture", pinchPoseForward, forwardMotion, keepForwardingPose, releasePoseForward);
            _forwardGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.PLAYER_SEEKDONE));

            var downStartPose = new HandPose("DownStartPose", new PalmPose(new AnyHandContext(), PoseDirection.Up, PoseDirection.Forward),
                                             new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Open, PoseDirection.Forward),
                                             new FingerPose(Finger.Thumb, FingerFlexion.Open, PoseDirection.Right));

            var downClamPose = new HandPose("DownClamPose", new PalmPose(new AnyHandContext(), PoseDirection.Up, PoseDirection.Forward),
                                            new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Folded, PoseDirection.Backward)
                                            // new FingerPose(Finger.Thumb, FingerFlexion.Open, PoseDirection.Right));
                                            );

            var downStopPose = new HandPose("DownStopPose", new PalmPose(new AnyHandContext()),
                                            new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Open));

            downClamPose.Triggered     += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_DOWN));
            _downGesture                = new Gesture("DownGesture", downStartPose, downClamPose, downStopPose);
            _downGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_SCROLLDONE));

            var upStartPose = new HandPose("UpStartPose", new PalmPose(new AnyHandContext(), PoseDirection.Down, PoseDirection.Forward),
                                           new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Open, PoseDirection.Forward),
                                           new FingerPose(Finger.Thumb, FingerFlexion.Open, PoseDirection.Left));

            var upClamPose = new HandPose("UpClamPose", new PalmPose(new AnyHandContext(), PoseDirection.Down, PoseDirection.Forward),
                                          new FingerPose(new AllFingersContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Folded, PoseDirection.Backward)
                                          // new FingerPose(Finger.Thumb, FingerFlexion.Open, PoseDirection.Left));
                                          );

            var upStopPose = new HandPose("UpStopPose", new PalmPose(new AnyHandContext()),
                                          new FingerPose(new AnyFingerContext(new[] { Finger.Index, Finger.Middle, Finger.Ring, Finger.Pinky }), FingerFlexion.Open));

            upClamPose.Triggered     += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_UP));
            _upGesture                = new Gesture("UpGesture", upStartPose, upClamPose, upStopPose);
            _upGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_SCROLLDONE));

            _pauseGesture   = new Gesture("PauseGesture", pausePose, GenerateSpacerPose("PauseSpacer"));
            _selectGesture  = new Gesture("SelectGesture", selectPose, GenerateSpacerPose("SelectSpacer"));
            _menuGesture    = new Gesture("MenuGesture", menuPose, GenerateSpacerPose("MenuSpacer"));
            _contextGesture = new Gesture("ContextGesture", contextPose, GenerateSpacerPose("ContextSpacer"));
            _backGesture    = new Gesture("BackGesture", backPose, GenerateSpacerPose("BackSpacer"));
            _leftGesture    = new Gesture("LeftGesture", leftPose, leftStopPose);
            _rightGesture   = new Gesture("RightGesture", rightPose, rightStopPose);

            _leftGesture.IdleTriggered  += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_SCROLLDONE));
            _rightGesture.IdleTriggered += (s, args) => KinectActionRecognized?.Invoke(this, new KinectRecognizedActionEventArgs(KinectActionRecognizedSource.Gesture, GestureAction.INPUT_SCROLLDONE));

            // Step2: Connect to Gesture Service, route StatusChanged event to the UI and register the gesture
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (oldStatus, newStatus) => GesturesDetectionStatusChanged?.Invoke(oldStatus, newStatus);
            await _gesturesService.ConnectAsync();

            await _gesturesService.RegisterGesture(_pauseGesture, true);

            await _gesturesService.RegisterGesture(_selectGesture, true);

            await _gesturesService.RegisterGesture(_rewindGesture, true);

            await _gesturesService.RegisterGesture(_forwardGesture, true);

            await _gesturesService.RegisterGesture(_menuGesture, true);

            await _gesturesService.RegisterGesture(_contextGesture, true);

            await _gesturesService.RegisterGesture(_backGesture, true);

            await _gesturesService.RegisterGesture(_downGesture, true);

            await _gesturesService.RegisterGesture(_upGesture, true);

            await _gesturesService.RegisterGesture(_leftGesture, true);

            await _gesturesService.RegisterGesture(_rightGesture, true);

            await _gesturesService.RegisterGesture(_volumeDownGesture, true);

            await _gesturesService.RegisterGesture(_volumeUpGesture, true);
        }
        public async Task Initialize()
        {
            _gesturesService = GesturesServiceEndpointFactory.Create();
            _gesturesService.StatusChanged += (s, args) => StatusChanged?.Invoke(s, args);
            await _gesturesService.ConnectAsync();

            _dismissNotificationGesture            = new DismissGesture("DismissCall");
            _dismissNotificationGesture.Triggered += async(s, args) => {
                DismissNotification?.Invoke(s, args);
                await _gesturesService.UnregisterGesture(_answerCallGesture);

                await _gesturesService.UnregisterGesture(_dismissNotificationGesture);
            };
            // Phone Gestures
            _hangUpGesture            = new HangUpGesture("HangUpCall");
            _hangUpGesture.Triggered += async(s, args) => {
                HangUpCall?.Invoke(s, args);
                await _gesturesService.UnregisterGesture(_hangUpGesture);
            };

            _answerCallGesture            = new Gesture("AnswerCall", new OnPhonePose("OnPhoneDown", PoseDirection.Down), new OnPhonePose("OnPhoneLeft", PoseDirection.Left));
            _answerCallGesture.Triggered += async(s, args) => {
                AnswerCall?.Invoke(s, args);
                await _gesturesService.UnregisterGesture(_answerCallGesture);

                await _gesturesService.UnregisterGesture(_dismissNotificationGesture);

                await Task.Delay(1000).ContinueWith(async t =>
                {
                    await _gesturesService.RegisterGesture(_hangUpGesture);
                });
            };

            // Source Selection Gestures
            _selectSourceGesture            = new TapGesture("SelectSource");
            _selectSourceGesture.Triggered += (s, args) => {
                _currentSource = (_currentSource + 1) % 4;
                switch (_currentSource)
                {
                case 0:
                    SelectSourcePhone?.Invoke(s, args);
                    break;

                case 1:
                    SelectSourceRadio?.Invoke(s, args);
                    break;

                case 2:
                    SelectSourceMedia?.Invoke(s, args);
                    break;

                case 3:
                    SelectSourceUsb?.Invoke(s, args);
                    break;
                }
            };
            await _gesturesService.RegisterGesture(_selectSourceGesture);

            // Volume Gestures
            _volumeToggleMuteGesture            = new Gesture("VolumeToggleMute", new ClamPose("ClamOpen", clamOpen: true), new ClamPose("ClamClose", clamOpen: false));
            _volumeToggleMuteGesture.Triggered += (s, args) => VolumeToggleMute?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_volumeToggleMuteGesture);

            _volumeUpGesture            = new Gesture("VolumeUp", new PointingFingerPose("Point"), new HandMotion("ClockwiseCircle", new[] { VerticalMotionSegment.ClockwiseArcRightUpward, VerticalMotionSegment.ClockwiseArcRightDownward, VerticalMotionSegment.ClockwiseArcLeftDownward, VerticalMotionSegment.ClockwiseArcLeftUpward }));
            _volumeUpGesture.Triggered += (s, args) => VolumeUp?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_volumeUpGesture);

            _volumeDownGesture            = new Gesture("VolumeDown", new PointingFingerPose("Point"), new HandMotion("CounterClockwiseCircle", new[] { VerticalMotionSegment.CounterClockwiseArcRightDownward, VerticalMotionSegment.CounterClockwiseArcRightUpward, VerticalMotionSegment.CounterClockwiseArcLeftUpward, VerticalMotionSegment.CounterClockwiseArcLeftDownward }));
            _volumeDownGesture.Triggered += (s, args) => VolumeDown?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_volumeDownGesture);

            // Next Channel
            _nextChannelGesture            = GenerateSwipeGesure("SwipeLeft", PoseDirection.Left);
            _nextChannelGesture.Triggered += (s, args) => NextChannel?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_nextChannelGesture);

            // Control A/C
            _tempratureUpGesture            = GenerateSwipeGesure("SwipeUp", PoseDirection.Up);
            _tempratureUpGesture.Triggered += (s, args) => TemperatureUp?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_tempratureUpGesture);

            _tempratureDownGesture            = GenerateSwipeGesure("SwipeDown", PoseDirection.Down);
            _tempratureDownGesture.Triggered += (s, args) => TemperatureDown?.Invoke(s, args);
            await _gesturesService.RegisterGesture(_tempratureDownGesture);
        }