Processing:
New examples implemented :
Fluid, Smoke, Interaction examples.
Split in one file for the main instructions, one for TUIO stuff.
License headers added.
/*
* This file is part of the TraKERS\Middleware package.
*
* (c) IRI <http://www.iri.centrepompidou.fr/>
*
* For the full copyright and license information, please view the LICENSE_MIDDLEWARE
* file that was distributed with this source code.
*/
/*
* 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;
using Trakers.Debug;
using System.Resources;
using System.Reflection;
namespace Trakers.Communication
{
public class Server
{
//Serveur TUIO, provenant de la DLL TuioServer créé par Bespoke.
private TuioServer server;
//Affichage de debug.
private DebugWindow debug;
//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;
//Intervalle minimum entre les gestures.
private int timerElapsing;
//Timer.
private System.Timers.Timer _timer;
//Gestionnaire de ressources.
private ResourceManager rm;
/*
* 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, DebugWindow _debug)
{
debug = _debug;
rm = new ResourceManager("Trakers.Properties.resources", Assembly.GetExecutingAssembly());
//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;
try
{
//On démarre le serveur TUIO.
server = new TuioServer(host, port);
//On initialise le threadPool (appelé toutes les N ms).
ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
//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);
}
catch (Exception)
{
debug.ExceptionLbl.Content = rm.GetString("serverCantStart");
}
}
/*
* 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)
{
//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)
{
//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));
rightHandCursorCreated = true;
}
//S'il existe, on le met simplement à jour.
else
{
server.UpdateTuioCursor(1, SkeletonPointToPoint3D(e.handJoint.Position));
}
}
/*
* Méthode appelée lors d'une notification de type : main gauche sortie du champ.
*/
public void LeftHandQuit(object sender, LeftHandQuitEventArgs e)
{
//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)
{
//Si le curseur de la main droite existe, alors on le supprime.
if (rightHandCursorCreated)
{
server.DeleteTuioCursor(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";
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(2, 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(2);
}
}
}
}
}