Middleware :
authorbastiena
Thu, 29 Mar 2012 14:39:21 +0200
changeset 13 50de8e8f44d7
parent 12 a446351f08c0
child 14 10d5199d9874
Middleware : Began to create a curve segmenter based on cutting on local extremums. Remove joint arguments on hand quit events to notify Processing when skeleton is not detected anymore.
middleware/src/App.config
middleware/src/Debug/DebugParameters.xaml
middleware/src/Debug/DebugParameters.xaml.cs
middleware/src/Debug/DebugWindow.xaml.cs
middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs
middleware/src/Tracking/Events/LeftHandQuitListener.cs
middleware/src/Tracking/Events/RightHandQuitEventArgs.cs
middleware/src/Tracking/Events/RightHandQuitListener.cs
middleware/src/Tracking/KinectMain.cs
middleware/src/Tracking/ModeManagement.cs
middleware/src/Tracking/Search/Comparator.cs
middleware/src/Tracking/Search/Constructor.cs
middleware/src/Tracking/Search/Curve.cs
middleware/src/Tracking/Search/Dictionnary.cs
middleware/src/Tracking/Search/Segment.cs
middleware/src/Tracking/Search/Segmenter.cs
middleware/src/Tracking/Search/Structure.cs
middleware/src/Trakers.csproj
--- a/middleware/src/App.config	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/App.config	Thu Mar 29 14:39:21 2012 +0200
@@ -10,5 +10,8 @@
     <add key="connexionPort" value="80"/>
     <add key="timerElapsing" value="1000"/>
     <add key="imagesToShow" value="25"/>
+    <add key="takenPoints" value="10"/>
+    <add key="directionChangeTresholdXY" value="10"/>
+    <add key="directionChangeTresholdZ" value="0,01"/>
   </appSettings>
 </configuration>
\ No newline at end of file
--- a/middleware/src/Debug/DebugParameters.xaml	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugParameters.xaml	Thu Mar 29 14:39:21 2012 +0200
@@ -99,6 +99,30 @@
                         </Grid>
                     </StackPanel>
                 </TabItem>
+                <TabItem Header="Recherche">
+                    <StackPanel>
+                        <Label Content="Courbes de recherche :" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" />
+                        <Grid>
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="30" />
+                                <RowDefinition Height="30" />
+                                <RowDefinition Height="30" />
+                            </Grid.RowDefinitions>
+                            <Grid.ColumnDefinitions>
+                                <ColumnDefinition Width="50*" />
+                                <ColumnDefinition Width="50*" />
+                            </Grid.ColumnDefinitions>
+
+                            <!-- Paramètres de la recherche de courbes. -->
+                            <Label Grid.Row="0" Grid.Column="0" Content="On prend 1/N pts :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+                            <TextBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Name="takenPointsTB" VerticalAlignment="Top" Width="120" />
+                            <Label Grid.Row="1" Grid.Column="0" Content="Seuil cut XY :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+                            <TextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Name="directionChangeTresholdXYTB" VerticalAlignment="Top" Width="120" />
+                            <Label Grid.Row="2" Grid.Column="0" Content="Seuil cut Z :" HorizontalAlignment="Left" VerticalAlignment="Top" />
+                            <TextBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Name="directionChangeTresholdZTB" VerticalAlignment="Top" Width="120" />
+                        </Grid>
+                    </StackPanel>
+                </TabItem>
             </TabControl>
 
             <Button Content="Modifier" Click="Button_Click" />
--- a/middleware/src/Debug/DebugParameters.xaml.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugParameters.xaml.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -71,6 +71,9 @@
             connexionPortTB.Text = kinectMain.getConnexionPort().ToString();
             timerElapsingTB.Text = kinectMain.getTimerElapsing().ToString();
             imagesToShowTB.Text = kinectMain.getImagesToShow().ToString();
+            takenPointsTB.Text = kinectMain.getTakenPoints().ToString();
+            directionChangeTresholdXYTB.Text = kinectMain.getTakenPoints().ToString();
+            directionChangeTresholdZTB.Text = kinectMain.getTakenPoints().ToString();
         }
 
         /*
@@ -90,10 +93,14 @@
                 int connexionPort = int.Parse(connexionPortTB.Text);
                 int timerElapsing = int.Parse(timerElapsingTB.Text);
                 int imagesToShow = int.Parse(imagesToShowTB.Text);
+                int takenPoints = int.Parse(takenPointsTB.Text);
+                int directionChangeTresholdXY = int.Parse(directionChangeTresholdXYTB.Text);
+                float directionChangeTresholdZ = float.Parse(directionChangeTresholdZTB.Text);
 
                 if (maxDistHands <= 0f || minDistHands <= 0f || maxDistHands > maxDist || minDistHands > maxDist ||
                 minDistHands >= maxDistHands || zeroPoint < maxDistHands || minDistHands < minDist ||
-                zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1)
+                zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1 ||
+                takenPoints <= 0 || directionChangeTresholdXY < 0 || directionChangeTresholdZ < 0)
                 {
                     ExceptionInParametersLbl.Content = rm.GetString("loadParametersIncorrect");
                 }
@@ -108,6 +115,9 @@
                     kinectMain.setConnexionPort(connexionPort);
                     kinectMain.setTimerElapsing(timerElapsing);
                     kinectMain.setImagesToShow(imagesToShow);
+                    kinectMain.setTakenPoints(takenPoints);
+                    kinectMain.setDirectionChangeTresholdXY(directionChangeTresholdXY);
+                    kinectMain.setDirectionChangeTresholdZ(directionChangeTresholdZ);
 
                     kinectMain.updateParameters();
                     ExceptionInParametersLbl.Content = null;
--- a/middleware/src/Debug/DebugWindow.xaml.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Debug/DebugWindow.xaml.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -509,8 +509,6 @@
             R8.Fill = System.Windows.Media.Brushes.DarkGray;
             R9.Fill = System.Windows.Media.Brushes.DarkGray;
             R10.Fill = System.Windows.Media.Brushes.DarkGray;
-            LeftHand.Background = System.Windows.Media.Brushes.DarkGray;
-            RightHand.Background = System.Windows.Media.Brushes.DarkGray;
         }
 
         /*
--- a/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -30,18 +30,14 @@
 {
     public class LeftHandQuitEventArgs : EventArgs
     {
-        public readonly Joint handJoint;
-        public readonly float position;
         public readonly Debug.DebugWindow debug;
         public readonly Server server;
 
         /*
-        * Constructeur : Il prend le noeud de la main, sa position, l'affichage de debug et le serveur TUIO.
+        * Constructeur : Il prend l'affichage de debug et le serveur TUIO.
         */
-        public LeftHandQuitEventArgs(Joint joint, float pos, Debug.DebugWindow _debug, Server _server)
+        public LeftHandQuitEventArgs(Debug.DebugWindow _debug, Server _server)
         {
-            handJoint = joint;
-            position = pos;
             debug = _debug;
             server = _server;
         }
--- a/middleware/src/Tracking/Events/LeftHandQuitListener.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/LeftHandQuitListener.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -36,7 +36,6 @@
         */
         public void ShowOnScreen(object o, LeftHandQuitEventArgs e)
         {
-            Joint handJoint = e.handJoint;
             //On l'indique dans le debug.
             e.debug.showLeftHandRect(false);
             e.debug.showLeftHandCoord("");
--- a/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -30,18 +30,14 @@
 {
     public class RightHandQuitEventArgs : EventArgs
     {
-        public readonly Joint handJoint;
-        public readonly float position;
         public readonly Debug.DebugWindow debug;
         public readonly Server server;
 
         /*
-        * Constructeur : Il prend le noeud de la main, sa position, l'affichage de debug et le serveur TUIO.
+        * Constructeur : Il prend l'affichage de debug et le serveur TUIO.
         */
-        public RightHandQuitEventArgs(Joint joint, float pos, Debug.DebugWindow _debug, Server _server)
+        public RightHandQuitEventArgs(Debug.DebugWindow _debug, Server _server)
         {
-            handJoint = joint;
-            position = pos;
             debug = _debug;
             server = _server;
         }
--- a/middleware/src/Tracking/Events/RightHandQuitListener.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/Events/RightHandQuitListener.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -36,7 +36,6 @@
         */
         public void ShowOnScreen(object o, RightHandQuitEventArgs e)
         {
-            Joint handJoint = e.handJoint;
             //On l'indique dans le debug.
             e.debug.showRightHandRect(false);
             e.debug.showRightHandCoord("");
--- a/middleware/src/Tracking/KinectMain.cs	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Tracking/KinectMain.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -20,6 +20,7 @@
  * noeuds de son squelette. Lance des événements lorsque la main gauche/droite entre dans/quitte le champ.
  * Envoie des données au sous-module de debug de manière a afficher un retour visuel sur la position de l'utilisateur,
  * son squelette, la détection de ses mains.
+ * Découpe l'interaction avec le middleware en différents modes.
  */
 
 using System;
@@ -67,8 +68,6 @@
     public delegate void JumpHandler(object o, JumpEventArgs e);
     //Il s'agit de la fonction permettant d'appeler les fonctions des événements de proximité.
     public delegate void UserPositionHandler(object o, UserPositionEventArgs e);
-    //Il s'agit de la fonctoin permettant de notifier le serveur en cas de changement de mode.
-    public delegate void ModChangeHandler(object o, ModChangeEventArgs e);
 
     public class KinectMain
     {
@@ -97,6 +96,9 @@
         private float maxDist;
         private float zeroPoint;
         private int imagesToShow;
+        private int takenPoints;
+        private int directionChangeTresholdXY;
+        private float directionChangeTresholdZ;
 
         //Temps de rafraichissement pour le timer (Détection de gesture dans le serveur TUIO).
         private int timerElapsing;
@@ -104,6 +106,9 @@
         //Serveur TUIO pour la connexion du Middleware vers le Front Atelier.
         private Server server;
 
+        //Gestionnaire de modes.
+        private ModeManagement modeManagement;
+
         //Les événements des mains pour la recherche.
         public static event LeftHandTrackedHandler LeftHandTrackedEvent;
         public static event RightHandTrackedHandler RightHandTrackedEvent;
@@ -117,8 +122,6 @@
         public static event JumpHandler JumpEvent;
         //L'événement l'utilisateur se déplace dans la zone de détection.
         public static event UserPositionHandler UserPositionEvent;
-        //L'événement on change de mode.
-        public static event ModChangeHandler ModChangeEvent;
 
         private string connexionHost;
         private int connexionPort;
@@ -148,6 +151,9 @@
                 connexionPort = 80;
                 timerElapsing = 1000;
                 imagesToShow = 25;
+                takenPoints = 10;
+                directionChangeTresholdXY = 10;
+                directionChangeTresholdZ = 0.01f;
             }
 
             //On crée la fenêtre de debug.
@@ -245,12 +251,11 @@
             UserPositionListener userPositionListener = new UserPositionListener();
             UserPositionEvent += new UserPositionHandler(userPositionListener.ShowOnScreen);
 
-            //Fonction appelée lorsqu'on change de mode.
-            ModChangeListener modChangeListener = new ModChangeListener();
-            ModChangeEvent += new ModChangeHandler(modChangeListener.ShowOnScreen);
-
             //On connecte le serveur à l'adresse locale sur le port 80.
             server = new Server(connexionHost, connexionPort, timerElapsing, debug);
+
+            //On crée le gestionnaire de modes.
+            modeManagement = new ModeManagement(this, server, debug);
         }
 
         /*
@@ -400,7 +405,7 @@
                 //Si la main gauche quitte le champ, on lance l'événement approprié.
                 else
                 {
-                    LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(handLeft, handLeft.Position.Z, debug, server);
+                    LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
                     OnLeftHandQuitEvent(leftHandQuitEvent);
                 }
                 //Si la main droite est dans le champ, on lance l'événement approprié.
@@ -412,7 +417,7 @@
                 //Si la main droite quitte le champ, on lance l'événement approprié.
                 else
                 {
-                    RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(handRight, handRight.Position.Z, debug, server);
+                    RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
                     OnRightHandQuitEvent(rightHandQuitEvent);
                 }
 
@@ -459,6 +464,8 @@
                     float proximity = userPositionDetector.CalcProximity(first.Position.Z);
                     int numberOfImages = userPositionDetector.ImagesToShow(proximity, imagesToShow);
 
+                    modeManagement.DetectProximityBasedModes(proximity, numberOfImages);
+
                     if (proximity > 0f)
                     {
                         UserPositionEventArgs userPositionEvent = new UserPositionEventArgs(debug, server, proximity, numberOfImages);
@@ -467,6 +474,10 @@
                     else
                     {
                         debug.hideSkeleton();
+                        LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
+                        OnLeftHandQuitEvent(leftHandQuitEvent);
+                        RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
+                        OnRightHandQuitEvent(rightHandQuitEvent);
                     }
                 }
 
@@ -475,7 +486,13 @@
                 debug.showSkeleton(hipCenter, spine, shoulderCenter, head, shoulderLeft, elbowLeft, wristLeft, handLeft, shoulderRight, elbowRight, wristRight, handRight, hipLeft, kneeLeft, ankleLeft, footLeft, hipRight, kneeRight, ankleRight, footRight);
             }
             else
+            {
                 debug.hideSkeleton();
+                LeftHandQuitEventArgs leftHandQuitEvent = new LeftHandQuitEventArgs(debug, server);
+                OnLeftHandQuitEvent(leftHandQuitEvent);
+                RightHandQuitEventArgs rightHandQuitEvent = new RightHandQuitEventArgs(debug, server);
+                OnRightHandQuitEvent(rightHandQuitEvent);
+            }
         }
 
         /*
@@ -560,15 +577,6 @@
         }
 
         /*
-        *  Initialise l'événement et fait appel aux fonctions du listener quand on change de mode.
-        */
-        public static void OnModChangeEvent(ModChangeEventArgs e)
-        {
-            if (ModChangeEvent != null)
-                ModChangeEvent(new object(), e);
-        }
-
-        /*
         *  Méthode de chargement des paramètres (position du champ de recherche...).
         */
         public bool loadParameters()
@@ -584,6 +592,9 @@
                 connexionPort = int.Parse(ConfigurationManager.AppSettings["connexionPort"]);
                 timerElapsing = int.Parse(ConfigurationManager.AppSettings["timerElapsing"]);
                 imagesToShow = int.Parse(ConfigurationManager.AppSettings["imagesToShow"]);
+                takenPoints = int.Parse(ConfigurationManager.AppSettings["takenPoints"]);
+                directionChangeTresholdXY = int.Parse(ConfigurationManager.AppSettings["directionChangeTresholdXY"]);
+                directionChangeTresholdZ = (float)double.Parse(ConfigurationManager.AppSettings["directionChangeTresholdZ"]);
             }
             catch (Exception)
             {
@@ -592,7 +603,8 @@
 
             if (maxDistHands <= 0f || minDistHands <= 0f || maxDistHands > maxDist || minDistHands > maxDist ||
                 minDistHands >= maxDistHands || zeroPoint < maxDistHands || minDistHands < minDist ||
-                zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1)
+                zeroPoint >= maxDist || connexionPort < 0 || timerElapsing < 0 || imagesToShow < 1 ||
+                takenPoints <= 0 || directionChangeTresholdXY < 0 || directionChangeTresholdZ < 0)
             {
                 debug.ExceptionLbl.Content = rm.GetString("loadParametersIncorrect");
                 return false;
@@ -606,6 +618,7 @@
         public void updateParameters()
         {
             userPositionDetector.setParams(minDist, maxDist, minDistHands, maxDistHands, zeroPoint);
+            //segmenter.setParams(takenPoints, directionChangeTresholdXY, directionChangeTresholdZ);
 
             //On récupère la config.
             Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
@@ -628,6 +641,12 @@
             config.AppSettings.Settings.Add("timerElapsing", timerElapsing.ToString());
             config.AppSettings.Settings.Remove("imagesToShow");
             config.AppSettings.Settings.Add("imagesToShow", imagesToShow.ToString());
+            config.AppSettings.Settings.Remove("takenPoints");
+            config.AppSettings.Settings.Add("takenPoints", takenPoints.ToString());
+            config.AppSettings.Settings.Remove("directionChangeTresholdXY");
+            config.AppSettings.Settings.Add("directionChangeTresholdXY", directionChangeTresholdXY.ToString());
+            config.AppSettings.Settings.Remove("directionChangeTresholdZ");
+            config.AppSettings.Settings.Add("directionChangeTresholdZ", directionChangeTresholdZ.ToString());
 
             //Sauvegarde la configuration.
             config.Save(ConfigurationSaveMode.Modified);
@@ -673,6 +692,18 @@
         {
             imagesToShow = _imagesToShow;
         }
+        public void setTakenPoints(int _takenPoints)
+        {
+            takenPoints = _takenPoints;
+        }
+        public void setDirectionChangeTresholdXY(int _directionChangeTresholdXY)
+        {
+            directionChangeTresholdXY = _directionChangeTresholdXY;
+        }
+        public void setDirectionChangeTresholdZ(float _directionChangeTresholdZ)
+        {
+            directionChangeTresholdZ = _directionChangeTresholdZ;
+        }
 
         public float getMinDistHands()
         {
@@ -710,5 +741,17 @@
         {
             return imagesToShow;
         }
+        public int getTakenPoints()
+        {
+            return takenPoints;
+        }
+        public int getDirectionChangeTresholdXY()
+        {
+            return directionChangeTresholdXY;
+        }
+        public float getDirectionChangeTresholdZ()
+        {
+            return directionChangeTresholdZ;
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/ModeManagement.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,161 @@
+/*
+* 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 : Tracking
+ * Classe : ModeManagement
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Permet de gérer les différents modes qui découpent l'interaction avec le middleware.
+ * Découpe l'interaction avec le middleware en différents modes.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Trakers.Communication;
+using Trakers.Tracking.Events;
+using Trakers.Debug;
+
+namespace Trakers.Tracking
+{
+    public class ModeManagement
+    {
+        //Il s'agit de la fonctoin permettant de notifier le serveur en cas de changement de mode.
+        public delegate void ModChangeHandler(object o, ModChangeEventArgs e);
+        //L'événement on change de mode.
+        public static event ModChangeHandler ModChangeEvent;
+        
+        //Accès au module d'interaction principal.
+        private KinectMain kinectMain;
+        //Accès au debug.
+        private DebugWindow debug;
+        //Accès au serveur.
+        private Server server;
+        //La liste des modes.
+        public enum Mode {NO_USER, USER_INCOMING, MOSAIC, FILTER, VIDEO, TIMELINE, SEARCH};
+        //Mode actuel.
+        private Mode currentMode;
+
+        /*
+        *  Constructeur qui prend en paramètres le module principal et le serveur.
+        */
+        public ModeManagement(KinectMain _kinectMain, Server _server, DebugWindow _debug)
+        {
+            kinectMain = _kinectMain;
+            server = _server;
+            debug = _debug;
+            currentMode = Mode.NO_USER;
+
+            //Fonction appelée lorsqu'on change de mode.
+            ModChangeListener modChangeListener = new ModChangeListener();
+            ModChangeEvent += new ModChangeHandler(modChangeListener.ShowOnScreen);
+        }
+
+        /*
+        *  Détecte tout changement de mode en se basant sur la proximité de l'utilisateur.
+        */
+        public void DetectProximityBasedModes(float proximity, int numberOfImages)
+        {
+            //Si l'utilisateur se déplace dans la zone de détection.
+            //On traite le problème en plusieurs limites, on discrétise la zone.
+            //On considère qu'il n'y a pas d'utilisateur si sa proximité est trop faible.
+            if (proximity < 10f && currentMode != Mode.NO_USER)
+            {
+                currentMode = Mode.NO_USER;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "NO_USER");
+                OnModChangeEvent(modChangeEvent);
+            }
+            //S'il n'est pas encore au point d'interaction maximale, on considère qu'il est en chemin.
+            else if (proximity >= 10f && proximity < 100f)
+            {
+                currentMode = Mode.USER_INCOMING;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "USER_INCOMING");
+                OnModChangeEvent(modChangeEvent);
+            }
+            //S'il est arrivé au point, il a la mosaïque complète.
+            else
+            {
+                currentMode = Mode.MOSAIC;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "MOSAIC");
+                OnModChangeEvent(modChangeEvent);
+            }
+        }
+
+        /*
+        *  Détecte si l'utilisateur veut filtrer la mosaïque.
+        */
+        public void DetectFilterMode()
+        {
+            //Ne fonctionne que si on se trouve dans la mosaïque.
+            if (currentMode == Mode.MOSAIC)
+            {
+                currentMode = Mode.FILTER;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "FILTER");
+                OnModChangeEvent(modChangeEvent);
+            }
+        }
+
+        /*
+        *  Détecte si l'utilisateur veut entrer dans une vidéo.
+        */
+        public void DetectVideoMode()
+        {
+            //Si on vient de la mosaïque, d'un filtrage, de la timeline ou d'une recherche, on peut entrer.
+            if (currentMode == Mode.MOSAIC || currentMode == Mode.FILTER ||
+            currentMode == Mode.TIMELINE || currentMode == Mode.SEARCH)
+            {
+                currentMode = Mode.VIDEO;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "VIDEO");
+                OnModChangeEvent(modChangeEvent);
+            }
+        }
+
+        /*
+        *  Détecte si l'utilisateur veut entrer dans la timeline.
+        */
+        public void DetectTimeLineMode()
+        {
+            //Si on est dans une vidéo, on peut entrer.
+            if (currentMode == Mode.VIDEO)
+            {
+                currentMode = Mode.TIMELINE;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "TIMELINE");
+                OnModChangeEvent(modChangeEvent);
+            }
+        }
+
+        /*
+        *  Détecte si l'utilisateur veut effectuer une recherche dans cette vidéo.
+        */
+        public void DetectSearchMode()
+        {
+            //Si on est dans une vidéo, on peut entrer.
+            if (currentMode == Mode.VIDEO)
+            {
+                currentMode = Mode.SEARCH;
+                ModChangeEventArgs modChangeEvent = new ModChangeEventArgs(debug, server, "SEARCH");
+                OnModChangeEvent(modChangeEvent);
+            }
+        }
+
+        /*
+        *  Initialise l'événement et fait appel aux fonctions du listener quand on change de mode.
+        */
+        public static void OnModChangeEvent(ModChangeEventArgs e)
+        {
+            if (ModChangeEvent != null)
+                ModChangeEvent(new object(), e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Comparator.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 : Search
+ * Classe : Comparator
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Permet de comparer une courbe tracée avec un dictionnaire.
+ * La comparaison se fait sur les segments de chaque courbe, ce qui permet d'avancer dans l'arbre du
+ * dictionnaire et de présenter des complétions potentielles.
+ * Lors d'une comparaison entre deux structures de courbes, chaque segment est comparé un à un, ensuite,
+ * c'est l'ensemble de la structure qui est comparée à l'autre (afin d'éviter les problèmes de changement
+ * d'échelle partielle).
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+    public class Comparator
+    {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Constructor.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,38 @@
+/*
+* 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 : Search
+ * Classe : Constructor
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Construit une structure au fur et à mesure que ses segments sont tracés.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+    public class Constructor
+    {
+        /*public double Bernstein(int i, int k, double t)
+        {
+            if(i == 0 && k == 0)
+                return 1;
+
+        }*/
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Curve.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 : Search
+ * Classe : Curve
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit l'objet de courbe en lui-même, composé d'une ou deux structures et
+ * d'un pictogramme le représentant.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+    public class Curve
+    {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Dictionnary.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,31 @@
+/*
+* 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 : Search
+ * Classe : Dictionnary
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Dictionnaire sous forme d'arbre contenant les courbes répertoriées pour la recherche.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+    public class Dictionnary
+    {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Segment.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,36 @@
+/*
+* 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 : Search
+ * Classe : Segment
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit un composant de structure de courbe.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Media.Media3D;
+
+namespace Trakers.Tracking.Search
+{
+    public class Segment
+    {
+        //Points de la courbe réelle.
+        private List<double> knots;
+        //Points de contrôle.
+        private List<Point3D> P;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Segmenter.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,284 @@
+/*
+* 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 : Search
+ * Classe : Segmenter
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Permet d'extraire à la volée les segments du tracé en cours.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Media.Media3D;
+
+namespace Trakers.Tracking.Search
+{
+    public class Segmenter
+    {
+        //Accès à la classe de détection principale pour les paramètres.
+        private KinectMain kinectMain;
+        //Stocke les positions d'une main au cours du temps.
+        private List<Point3D> handPointerHistory;
+        //Point précédent.
+        private Point3D prevPt;
+        //Ratio : on prend 1/ratio points.
+        private int ratio;
+        //Indique le numéro du point actuellement enregistré (pour le ratio).
+        private int currentPointNumber;
+        //Extremums enregistrés parmi les 3 axes pour détecter les changements de sens.
+        private double Xmax, Ymax, Zmax;
+        private double Xmin, Ymin, Zmin;
+        //On établit une distance en nombre de points entre le point actuel l'extremum 
+        //local détecté dans les 3 axes (pour copier le segment : points de 0 à id de l'extremum).
+        private int distToXmax, distToYmax, distToZmax;
+        private int distToXmin, distToYmin, distToZmin;
+        //Points critiques.
+        private Point3D minPt, maxPt;
+        //Tendance actuelle du tracé.
+        private bool XtowardRight, YtowardUp, ZtowardFront;
+        //Limites de différences à partir desquelles .
+        private int directionChangeTresholdXY;
+        private float directionChangeTresholdZ;
+
+        /*
+        *  Initialisation du segmenter.
+        *  Coupe une courbe en deux dès qu'il repère un changement important de trajectoire.
+        */
+        public Segmenter(int _ratio, KinectMain _kinectMain)
+        {
+            kinectMain = _kinectMain;
+            directionChangeTresholdXY = kinectMain.getDirectionChangeTresholdXY();
+            directionChangeTresholdZ = kinectMain.getDirectionChangeTresholdZ();
+            handPointerHistory = new List<Point3D>();
+            ratio = _ratio;
+            currentPointNumber = 1;
+            prevPt = new Point3D(0, 0, 0);
+
+            Xmax = Ymax = Zmax = Xmin = Ymin = Zmin = -1;
+            distToXmax = distToYmax = distToZmax = distToXmin = distToYmin = distToZmin = -1;
+        }
+
+        /*
+         * Getters et setters.
+         */
+        public void SetRatio(int _ratio)
+        {
+            ratio = _ratio;
+        }
+        public void SetDirectionChangeTresholdXY(int _directionChangeTresholdXY)
+        {
+            directionChangeTresholdXY = _directionChangeTresholdXY;
+        }
+        public void SetDirectionChangeTresholdZ(float _directionChangeTresholdZ)
+        {
+            directionChangeTresholdZ = _directionChangeTresholdZ;
+        }
+
+        public int GetRatio()
+        {
+            return ratio;
+        }
+        public int SetDirectionChangeTresholdXY()
+        {
+            return directionChangeTresholdXY;
+        }
+        public float SetDirectionChangeTresholdZ()
+        {
+            return directionChangeTresholdZ;
+        }
+
+        /*
+         * On charge tous les paramètres d'un coup.
+         */
+        public void setParams(int _ratio, int _directionChangeTresholdXY, float _directionChangeTresholdZ)
+        {
+            ratio = _ratio;
+            directionChangeTresholdXY = _directionChangeTresholdXY;
+            directionChangeTresholdZ = _directionChangeTresholdZ;
+        }
+
+        /*
+         * Enregistre le point passé en paramètre d'après le ratio.
+         */
+        public void RecordPoint(Point3D pt)
+        {
+            //Indique l'ID du point à couper.
+            int whereToCut;
+            //Si le ratio est excédé, on peut enregistrer.
+            if (currentPointNumber > ratio)
+                currentPointNumber = 1;
+            
+            //Si le point précédent est à une position différente du point actuel.
+            if(prevPt.X != pt.X || prevPt.Y != pt.Y || prevPt.Z != pt.Z)
+            {
+                //Si le numéro est 1 (début ou ratio atteint), on enregistre.
+                if(currentPointNumber == 1)
+                    handPointerHistory.Add(pt);
+
+                //Si le point précédent a été initialisé avec un vrai point.
+                if (prevPt.X > 0 && prevPt.Y > 0 && prevPt.Z > 0)
+                {
+                    //Appel aux detecteurs d'extremums.
+                    if ((whereToCut = DetectDirectionChangeAtXAxis(pt)) > 0)
+                        Segment(whereToCut);
+                    else if((whereToCut = DetectDirectionChangeAtYAxis(pt)) > 0)
+                        Segment(whereToCut);
+                    else if ((whereToCut = DetectDirectionChangeAtZAxis(pt)) > 0)
+                        Segment(whereToCut);
+                }
+                //On met à jour le point précédent.
+                prevPt = pt;
+                //On passe au numéro suivant (jusqu'à atteindre le ration plus tard).
+                currentPointNumber++;
+            }
+        }
+
+        /*
+         * Détecte un changement de sens (extremum) dans l'axe X.
+         */
+        public int DetectDirectionChangeAtXAxis(Point3D pt)
+        {
+            //ID où couper en cas d'extremum.
+            int whereToCut = -1;
+
+            //Mise à jour des extremums.
+            if (Xmax == -1 || Xmax < pt.X)
+            {
+                //Si le point est plus grand en X que Xmax, alors il est remplacé et on réinitialise la
+                //distance au dernier maximum en X.
+                Xmax = pt.X;
+                maxPt = pt;
+                distToXmax = 0;
+            }
+            else
+                distToXmax++;
+            if (Xmin == -1 || Xmin > pt.X)
+            {
+                //Si le point est plus petit en X que Xmin, alors il est remplacé et on réinitialise la
+                //distance au dernier minimum en X.
+                Xmin = pt.X;
+                minPt = pt;
+                distToXmin = 0;
+            }
+            else
+                distToXmin++;
+
+            //Si X max est plus grand que la position actuelle additionnée du seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Xmax > pt.X + directionChangeTresholdXY && maxPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToXmax;
+            //Si X min est plus petit que la position actuelle à laquelle on a retiré le seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Xmin < pt.X - directionChangeTresholdXY && minPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToXmin;
+
+            return whereToCut;
+        }
+
+        /*
+         * Détecte un changement de sens (extremum) dans l'axe Y.
+         */
+        public int DetectDirectionChangeAtYAxis(Point3D pt)
+        {
+            //ID où couper en cas d'extremum.
+            int whereToCut = -1;
+
+            //Mise à jour des extremums.
+            if (Ymax == -1 || Ymax < pt.Y)
+            {
+                //Si le point est plus grand en Y que Ymax, alors il est remplacé et on réinitialise la
+                //distance au dernier maximum en Y.
+                Ymax = pt.Y;
+                maxPt = pt;
+                distToYmax = 0;
+            }
+            else
+                distToYmax++;
+            if (Ymin == -1 || Ymin > pt.Y)
+            {
+                //Si le point est plus petit en Y que Ymin, alors il est remplacé et on réinitialise la
+                //distance au dernier minimum en Y.
+                Ymin = pt.Y;
+                minPt = pt;
+                distToYmin = 0;
+            }
+            else
+                distToYmin++;
+
+            //Si Y max est plus grand que la position actuelle additionnée du seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Ymax > pt.Y + directionChangeTresholdXY && maxPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToYmax;
+            //Si Y min est plus petit que la position actuelle à laquelle on a retiré le seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Ymin < pt.Y - directionChangeTresholdXY && minPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToYmin;
+
+            return whereToCut;
+        }
+
+        /*
+         * Détecte un changement de sens (extremum) dans l'axe Z.
+         */
+        public int DetectDirectionChangeAtZAxis(Point3D pt)
+        {
+            //ID où couper en cas d'extremum.
+            int whereToCut = -1;
+
+            //Mise à jour des extremums.
+            if (Zmax == -1 || Zmax < pt.Z)
+            {
+                //Si le point est plus grand en Z que Ymax, alors il est remplacé et on réinitialise la
+                //distance au dernier maximum en Z.
+                Zmax = pt.Z;
+                maxPt = pt;
+                distToZmax = 0;
+            }
+            else
+                distToZmax++;
+            if (Zmin == -1 || Zmin > pt.Z)
+            {
+                //Si le point est plus petit en Z que Zmin, alors il est remplacé et on réinitialise la
+                //distance au dernier minimum en Z.
+                Zmin = pt.Z;
+                minPt = pt;
+                distToZmin = 0;
+            }
+            else
+                distToZmin++;
+
+            //Si Z max est plus grand que la position actuelle additionnée du seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Zmax > pt.Z + directionChangeTresholdXY && maxPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToZmax;
+            //Si Z min est plus petit que la position actuelle à laquelle on a retiré le seuil
+            //et que l'extremum n'est pas le premier point sauvegardé.
+            if (Zmin < pt.Z - directionChangeTresholdXY && minPt != handPointerHistory.First())
+                whereToCut = currentPointNumber - distToZmin;
+
+            return whereToCut;
+        }
+
+        /*
+         * Découpe le tracé en cours en segment allant du premier point au premier extremum trouvé.
+         */
+        public void Segment(int whereToCut)
+        {
+            handPointerHistory.RemoveRange(0, whereToCut);
+            currentPointNumber -= whereToCut;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/middleware/src/Tracking/Search/Structure.cs	Thu Mar 29 14:39:21 2012 +0200
@@ -0,0 +1,32 @@
+/*
+* 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 : Search
+ * Classe : Structure
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit la structure d'une courbe d'un point de vue algorithmique.
+ * Ce sont ces structures là qui seront comparées par la suite.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Trakers.Tracking.Search
+{
+    public class Structure
+    {
+    }
+}
--- a/middleware/src/Trakers.csproj	Mon Mar 26 16:23:14 2012 +0200
+++ b/middleware/src/Trakers.csproj	Thu Mar 29 14:39:21 2012 +0200
@@ -130,12 +130,22 @@
     <Compile Include="Tracking\Events\RightHandTrackedListener.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Tracking\ModeManagement.cs" />
+    <Compile Include="Tracking\Search\Comparator.cs" />
+    <Compile Include="Tracking\Search\Constructor.cs" />
+    <Compile Include="Tracking\Search\Curve.cs" />
+    <Compile Include="Tracking\Search\Dictionnary.cs" />
+    <Compile Include="Tracking\Search\Segment.cs" />
+    <Compile Include="Tracking\Search\Segmenter.cs" />
+    <Compile Include="Tracking\Search\Structure.cs" />
     <EmbeddedResource Include="Properties\Resources.resx">
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </EmbeddedResource>
-    <None Include="App.config" />
+    <None Include="App.config">
+      <SubType>Designer</SubType>
+    </None>
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -152,6 +162,7 @@
       <SubType>Designer</SubType>
     </Page>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.