middleware/src/Debug/DebugWindow.xaml.cs
author bastiena
Thu, 15 Mar 2012 13:33:21 +0100
changeset 3 92f19af39024
parent 0 6fefd4afe506
child 5 d40f84d77db4
permissions -rw-r--r--
Middleware : Swipe & Push & Jump(Experimental) Detectors ant events added Server modified for gesture detection TUIO Server C# Modified : Hand cursors redirected to /TUIO/3DCur channel New kind of OSC message created (TuioString) for gesture detection, using /TUIO/_siP channel. TUIO Processing Java Modified : Hand cursors redirected to /TUIO/3DCur channel New kind of OSC message created (TuioString) for gesture detection, using /TUIO/_siP channel. Front Processing : Mask added and modifications in the drawing process New front for gesture detection (just showing a text message in the mask for the moment)

/*
 * Projet : TraKERS
 * Module : MIDDLEWARE
 * Sous-Module : Debug
 * Classe : DebugWindow
 * 
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
 * 
 * Fonctionnalités : Reçoit des notifications des sous-modules Tracking, Communication et Exception.
 * Intéragit avec la fenêtre XAML de debug de façon à afficher un rendu visuel.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
using System.Windows.Media.Media3D;
using Microsoft.Kinect;

using Coding4Fun.Kinect.Wpf;

using Trakers.Tracking;
using System.Threading;
using Trakers.Tracking.Events;
using Trakers.Tracking.Gestures;

namespace Trakers.Debug
{
    public partial class DebugWindow : Window
    {
        //Membre permettant d'atteindre la classe KinectMain du sous-module Tracking.
        private KinectMain kinectMain;
        //Tableau contenant une image en couleurs.
        private byte[] colorPixelData;
        //Indique si la kinect est allumée/éteinte.
        private bool on;
        //Indique si la fenêtre de debug est actuellement en cours de fermeture.
        private bool closing;

        /*
        * Constructeur : Affiche la fenêtre de debug en lui passant en paramètre une instanciation de la
        * classe KinectMain.
        * Au départ, la kinect est éteinte.
        */
        public DebugWindow(KinectMain main)
        {
            InitializeComponent();
            kinectMain = main;
            on = false;
            closing = false;
        }

        /*
        * Getter pour le membre indiquant la fermeture de la fenêtre de debug.
        */
        public bool isClosing()
        {
            return closing;
        }

        /*
        * Est appelée à la fermeture de la fenêtre.
        */
        private void Window_Closed(object sender, EventArgs e)
        {
            closing = true;
            //On éteint la Kinect (pour éviter qu'elle reste allumée même lorsque le programme est éteint).
            kinectMain.KinectClose();
        }

        /*
        * Bouton ON/OFF.
        */
        private void Switch_Click(object sender, RoutedEventArgs e)
        {
            //S'il valait faux, il vaut vrai maintenant et inversement.
            on = !on;
            //Si la kinect est allumée.
            if (on)
            {
                //Il affiche OFF (pour éteindre la kinect).
                Switch.Content = "OFF";
                //On vide le label des exceptions.
                ExceptionLbl.Content = "";
                //On initialise la Kinect.
                kinectMain.KinectInitialization();
            }
            else
            {
                //Il affiche ON (pour allumer la kinect).
                Switch.Content = "ON";
                //On remet à zéro tous les éléments du retour visuel.
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
                DistanceLbl.Content = "Distance :";
                LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
                LeftHand.Content = "";
                RightHand.Background = System.Windows.Media.Brushes.DarkGray;
                RightHand.Content = "";
                DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1);
                //On éteint la Kinect.
                kinectMain.KinectClose();
            }
        }

        /*
        *  Récupère le flux video et met à jour le rendu visuel de debug.
        */
        public void RefreshVideo(AllFramesReadyEventArgs e)
        {
            bool receivedData = false;
            ColorImageFrame colorImageFrameData;
            using (colorImageFrameData = e.OpenColorImageFrame())
            {
                //Si on ne reçoit pas de trames de la kinect.
                if (colorImageFrameData == null)
                {
                    //L'image est supprimée.
                    DebugImage.Source = null;
                }
                //Si le tableau stockant l'image en cours est nul.
                if (colorPixelData == null)
                    //On alloue un nouveau tableau.
                    colorPixelData = new byte[colorImageFrameData.PixelDataLength];
                else
                {
                    //Sinon on met à jour le tableau en copiant le contenu de la trame dans le tableau.
                    colorImageFrameData.CopyPixelDataTo(colorPixelData);
                    receivedData = true;
                }
            }
            //Si on a des données dans le tableau et que la kinect est allumée.
            if (receivedData && on)
            {
                /*for (int i = 0; i < colorPixelData.Length; i += colorImageFrameData.BytesPerPixel)
                {
                    byte gray = Math.Min(colorPixelData[i], colorPixelData[i + 1]);
                    gray = Math.Min(gray, colorPixelData[i + 2]);
                    colorPixelData[i] = gray;
                    colorPixelData[i + 1] = gray;

                    colorPixelData[i] = colorPixelData[i + 1];
                    colorPixelData[i + 1] = colorPixelData[i];
                    colorPixelData[i + 2] = (byte)~colorPixelData[i + 2];
                }*/

                //On met à jour l'image de la caméra.
                DebugImage.Source = BitmapSource.Create(colorImageFrameData.Width, colorImageFrameData.Height, 96, 96, PixelFormats.Bgr32, null, colorPixelData, colorImageFrameData.Width * colorImageFrameData.BytesPerPixel);
                DebugImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                DebugImage.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                DebugImage.Stretch = Stretch.Fill;
            }
        }

        /*
        * Affiche la distance de l'utilisateur dans le rendu visuel.
        * Sous forme de nombre en m et de rectangles changeant de couleur en fonction de la distance.
        */
        public void showDistance(float distance)
        {
            DistanceLbl.Content = "Distance : " + distance;

            /*R1.Fill = System.Windows.Media.Brushes.Transparent;
            R2.Fill = System.Windows.Media.Brushes.Transparent;
            R3.Fill = System.Windows.Media.Brushes.Transparent;
            R4.Fill = System.Windows.Media.Brushes.Transparent;*/

            /*if (distance > 0 && distance < 1)
            {
                R1.Fill = System.Windows.Media.Brushes.Red;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
            }
            else if (distance > 1 && distance < 2)
            {
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.Orange;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
            }
            else if (distance > 2 && distance < 3)
            {
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.Yellow;
                R4.Fill = System.Windows.Media.Brushes.DarkGray;
            }
            else if (distance > 3 && distance < 4)
            {
                R1.Fill = System.Windows.Media.Brushes.DarkGray;
                R2.Fill = System.Windows.Media.Brushes.DarkGray;
                R3.Fill = System.Windows.Media.Brushes.DarkGray;
                R4.Fill = System.Windows.Media.Brushes.White;
            }*/
        }

        /*
        * Affiche la détection de la main droite via un label.
        */
        public void showRightHandRect(bool show)
        {
            if (show)
                RightHand.Background = System.Windows.Media.Brushes.Blue;
            else
                RightHand.Background = System.Windows.Media.Brushes.DarkGray;
        }

        /*
        * Affiche la détection de la main gauche via un label.
        */
        public void showLeftHandRect(bool show)
        {
            if (show)
                LeftHand.Background = System.Windows.Media.Brushes.Blue;
            else
                LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
        }

        /*
        * Dessine les noeuds du squelette dans le rendu visuel.
        */
        public void drawJoints(JointCollection joints, Skeleton first)
        {
            //On enlève tout élément du Canvas à part l'image, de manière à mettre à jour la position du squelette. 
            DebugCanvas.Children.RemoveRange(1, DebugCanvas.Children.Count - 1);

            //Pour chaque noeud.
            foreach (Joint joint in first.Joints)
            {
                //On crée une ellipse de taille 20 et de largeur 20.
                Ellipse node = new Ellipse();
                node.Height = 20;
                node.Width = 20;

                //S'il s'agit d'un noeud de tête, on le colorie en rouge, sinon en bleu.
                if (joint.JointType == JointType.Head)
                    node.Fill = System.Windows.Media.Brushes.Red;
                else if(joint.JointType == JointType.ShoulderCenter)
                    node.Fill = System.Windows.Media.Brushes.Green;
                else if(joint.JointType == JointType.HipCenter)
                    node.Fill = System.Windows.Media.Brushes.Green;
                else if (joint.JointType == JointType.HandRight)
                    node.Fill = System.Windows.Media.Brushes.Red;
                else
                    node.Fill = System.Windows.Media.Brushes.Blue;

                //On met à la bonne échelle les coordonnées des positions des noeuds.
                Joint scaledJoint = Coding4Fun.Kinect.Wpf.SkeletalExtensions.ScaleTo(joint, 600, 400, 0.75f, 0.75f);

                //On positionne le noeud dans le Canvas, et on l'ajoute.
                Canvas.SetLeft(node, scaledJoint.Position.X);
                Canvas.SetTop(node, scaledJoint.Position.Y);
                DebugCanvas.Children.Add(node);
            }
        }

        /*
        * Dessine un os, en ayant en paramètres deux noeuds.
        */
        public void drawBone(Joint j1, Joint j2)
        {
            //On crée une nouvelle ligne verte d'épaisseur 8 entre les deux noeuds et on l'ajoute au Canvas.
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Green;
            line.X1 = j1.Position.X;
            line.X2 = j2.Position.X;
            line.Y1 = j1.Position.Y;
            line.Y2 = j2.Position.Y;
            line.StrokeThickness = 8;
            DebugCanvas.Children.Add(line);
            ExceptionLbl.Content = DebugCanvas.Children.Count;
        }

        /*
        * Dessine le squelette (ensemble des os), en ayant en paramètres tous les noeuds.
        */
        public void showSkeleton(Joint hipCenter, Joint spine, Joint shoulderCenter, Joint head, Joint shoulderLeft, Joint elbowLeft, Joint wristLeft, Joint handLeft, Joint shoulderRight, Joint elbowRight, Joint wristRight, Joint handRight, Joint hipLeft, Joint kneeLeft, Joint ankleLeft, Joint footLeft, Joint hipRight, Joint kneeRight, Joint ankleRight, Joint footRight)
        {
            //On met les noeuds deux par deux en fonction de leur position dans le squelette.
            drawBone(head, shoulderCenter);
            drawBone(shoulderCenter, shoulderLeft);
            drawBone(shoulderLeft, elbowLeft);
            drawBone(elbowLeft, wristLeft);
            drawBone(wristLeft, handLeft);
            drawBone(shoulderCenter, shoulderRight);
            drawBone(shoulderRight, elbowRight);
            drawBone(elbowRight, wristRight);
            drawBone(wristRight, handRight);
            drawBone(shoulderCenter, spine);
            drawBone(spine, hipCenter);
            drawBone(hipCenter, hipLeft);
            drawBone(hipLeft, kneeLeft);
            drawBone(kneeLeft, ankleLeft);
            drawBone(ankleLeft, footLeft);
            drawBone(hipCenter, hipRight);
            drawBone(hipRight, kneeRight);
            drawBone(kneeRight, ankleRight);
            drawBone(ankleRight, footRight);
        }

        /*
        * Affiche la position de la main gauche dans le rendu visuel.
        */
        public void showLeftHandCoord(String coord)
        {
            LeftHand.Content = coord;
        }

        /*
        * Affiche la position de la main gauche dans le rendu visuel.
        */
        public void showRightHandCoord(String coord)
        {
            RightHand.Content = coord;
        }

        public void showSwipe(SwipeEventArgs e)
        {
            if(e.direction == Tracking.Gestures.SwipeDetector.Direction.LEFT)
                ExceptionLbl.Background = System.Windows.Media.Brushes.Red;
            else if(e.direction == Tracking.Gestures.SwipeDetector.Direction.RIGHT)
                ExceptionLbl.Background = System.Windows.Media.Brushes.Purple;
        }

        public void showPush(PushEventArgs e)
        {
            if (e.direction == Tracking.Gestures.PushDetector.Direction.PUSH)
            {
                if(e.hand == Tracking.Gestures.PushDetector.Hand.LEFT)
                    LeftHand.Background = System.Windows.Media.Brushes.White;
                else if(e.hand == Tracking.Gestures.PushDetector.Hand.RIGHT)
                    RightHand.Background = System.Windows.Media.Brushes.White;
                else
                {
                    LeftHand.Background = System.Windows.Media.Brushes.White;
                    RightHand.Background = System.Windows.Media.Brushes.White;
                }
            }
            else
            {
                if (e.hand == Tracking.Gestures.PushDetector.Hand.LEFT)
                    LeftHand.Background = System.Windows.Media.Brushes.Black;
                else if (e.hand == Tracking.Gestures.PushDetector.Hand.RIGHT)
                    RightHand.Background = System.Windows.Media.Brushes.Black;
                else
                {
                    LeftHand.Background = System.Windows.Media.Brushes.Black;
                    RightHand.Background = System.Windows.Media.Brushes.Black;
                }
            }
        }
    }
}