middleware/src/Communication/Server.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 : Communication
 * Classe : Server
 * 
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
 * 
 * Fonctionnalités : Reçoit des notifications du module sous-module Tracking.
 * Traduit les notifications sous forme de messages OSC et les envoie au Front Atelier.
 * Forme des messages :
 * - Notification de main dans le champ de recherche : Point3D indiquant la position de la main dans l'espace.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Tuio;
using System.Windows;
using Microsoft.Kinect;
using Trakers.Tracking;
using System.Windows.Media.Media3D;
using Trakers.Tracking.Events;
using System.Timers;

namespace Trakers.Communication
{
    public class Server
    {
        //Serveur TUIO, provenant de la DLL TuioServer créé par Bespoke.
        private TuioServer server;

        //Permet de savoir si un curseur pour la main gauche/droite a été créé.
        private bool leftHandCursorCreated;
        private bool rightHandCursorCreated;
        private bool messageCreated;
        private bool gestureLocked;

        private int timerElapsing;

        System.Timers.Timer _timer;

        /*
        * Constructeur : On initialise le serveur avec une adresse et un port, au début les curseurs
        * ne sont pas créés et on indique au ThreadPool une fonction de callback de manière à vérifier
        * s'il reçoit des notifications.
        */
        public Server(String host, int port, int _timerElapsing)
        {
            //On démarre le serveur TUIO.
            server = new TuioServer(host, port);
            //On initialise le threadPool (appelé toutes les N ms).
            ThreadPool.QueueUserWorkItem(ThreadPoolCallback);

            //Au départ, aucune main n'est dans le champ de recherche et aucune gesture n'est détectée.
            leftHandCursorCreated = false;
            rightHandCursorCreated = false;
            messageCreated = false;
            gestureLocked = false;

            timerElapsing = _timerElapsing;

            //On instancie le timer à N ms.
            _timer = new System.Timers.Timer(timerElapsing);
            //Dès que le timer est expiré, on appelle _timer_Elapsed.
            _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
        }

        /*
        * Getter du serveur.
        */
        public TuioServer getServer()
        {
            return server;
        }

        /*
         * Méthode appelée à l'expiration du timer.
         */
        public void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //On débloque la détection de gesture.
            gestureLocked = false;
            //On arrête le timer.
            _timer.Stop();
        }

        /*
        * Méthode appelée lors d'une notification de type : main gauche entrée dans le champ.
        */
        public void LeftHandTracked(object sender, LeftHandTrackedEventArgs e)
        {
            return;
            //Si le curseur de la main gauche n'est pas créé, alors on le crée.
            if (!leftHandCursorCreated)
            {
                server.AddTuioCursor(0, SkeletonPointToPoint3D(e.handJoint.Position));
                leftHandCursorCreated = true;
            }
            //S'il existe, on le met simplement à jour.
            else
            {
                server.UpdateTuioCursor(0, SkeletonPointToPoint3D(e.handJoint.Position));
            }
        }

        /*
        * Méthode appelée lors d'une notification de type : main droite entrée dans le champ.
        */
        public void RightHandTracked(object sender, RightHandTrackedEventArgs e)
        {
            return;
            //Si le curseur de la main droite n'est pas créé, alors on le crée.
            if (!rightHandCursorCreated)
            {
                server.AddTuioCursor(1, SkeletonPointToPoint3D(e.handJoint.Position));
                //server.AddTuioString(1, "BOO");
                rightHandCursorCreated = true;
            }
            //S'il existe, on le met simplement à jour.
            else
            {
                server.UpdateTuioCursor(1, SkeletonPointToPoint3D(e.handJoint.Position));
                //server.UpdateTuioString(1, "BOO");
            }
        }

        /*
        * Méthode appelée lors d'une notification de type : main gauche sortie du champ.
        */
        public void LeftHandQuit(object sender, LeftHandQuitEventArgs e)
        {
            return;
            //Si le curseur de la main gauche existe, alors on le supprime.
            if (leftHandCursorCreated)
            {
                server.DeleteTuioCursor(0);
                leftHandCursorCreated = false;
            }
        }

        /*
        * Méthode appelée lors d'une notification de type : main droite sortie du champ.
        */
        public void RightHandQuit(object sender, RightHandQuitEventArgs e)
        {
            return;
            //Si le curseur de la main droite existe, alors on le supprime.
            if (rightHandCursorCreated)
            {
                server.DeleteTuioCursor(1);
                //server.DeleteTuioString(1);
                rightHandCursorCreated = false;
            }
        }

        /*
        * Méthode appelée lors d'une notification de type : l'utilisateur fait un swipe.
        */
        public void Swipe(object sender, SwipeEventArgs e)
        {
            if (e.direction == Tracking.Gestures.SwipeDetector.Direction.LEFT)
                GesturePerformed("SWIPE LEFT");
            else if (e.direction == Tracking.Gestures.SwipeDetector.Direction.RIGHT)
                GesturePerformed("SWIPE RIGHT");
        }

        /*
        * Méthode appelée lors d'une notification de type : l'utilisateur fait un push/pull.
        */
        public void Pull(object sender, PushEventArgs e)
        {
            if(e.hand == Tracking.Gestures.PushDetector.Hand.NONE)
                return;

            String pushPull = "", hand = "";
            if (e.direction == Tracking.Gestures.PushDetector.Direction.PUSH)
                pushPull = "PUSH";
            else
                pushPull = "PULL";

            if (e.hand == Tracking.Gestures.PushDetector.Hand.LEFT)
                hand = "LEFT";
            else if (e.hand == Tracking.Gestures.PushDetector.Hand.RIGHT)
                hand = "RIGHT";
            else
                hand = "BOTH";

            Console.Out.WriteLine(pushPull + "-" + hand);

            GesturePerformed(pushPull + "-" + hand);
        }

        /*
        * Méthode appelée lorsqu'une gesture a été détectée et que l'événement approprié a été lancé.
        */
        public void GesturePerformed(String code)
        {
            //Si une gesture a été effectuée, on bloque un certain temps.
            if (!gestureLocked)
            {
                gestureLocked = true;
                
                //On crée un message contenant le code à envoyer.
                if (!messageCreated)
                {
                    messageCreated = true;
                    server.AddTuioString(1, code);
                    //On démarre le timer.
                    _timer.Start();
                }
            }
        }

        /*
        * Permet de convertir un point de position de noeud en Point3D.
        */
        private Point3D SkeletonPointToPoint3D(SkeletonPoint p)
        {
            return new Point3D((double)p.X, (double)p.Y, (double)p.Z);
        }

        /*
        * Méthode de callback vérifiant toutes les 25 ms les nouvelles notifications.
        * Il est à noter que si le temps de rafraîchissement des trop rapide, les messages n'ont pas
        * le temps d'être envoyés.
        */
        private void ThreadPoolCallback(Object threadContext)
        {
            while (true)
            {
                //On initialise le message OSC.
                server.InitFrame();
                //On l'envoie au client (au host et au port spécifiés dans le constructeur).
                server.CommitFrame();
                //On attend 25 ms.
                Thread.Sleep(25);

                //Si une gesture a été effectuée et que le délai d'attente est expiré.
                if (messageCreated && !gestureLocked)
                {
                    //On débloque la détection de gesture et on supprime l'objet envoyant les messages OSC de gesture.
                    messageCreated = false;
                    server.DeleteTuioString(1);
                }
            }
        }
    }
}