Middleware :
authorbastiena
Thu, 15 Mar 2012 13:33:21 +0100
changeset 3 92f19af39024
parent 2 11234537653b
child 4 f4e52a4c34b3
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)
.hgignore
front_processing/extern/TUIO_JAVA/src/TUIO/TuioClient.java
front_processing/extern/TUIO_JAVA/src/TUIO/TuioContainer.java
front_processing/extern/TUIO_JAVA/src/TUIO/TuioCursor.java
front_processing/extern/TUIO_JAVA/src/TUIO/TuioListener.java
front_processing/extern/TUIO_JAVA/src/TUIO/TuioPoint.java
front_processing/extern/TUIO_JAVA/src/TUIO/TuioString.java
front_processing/extern/TUIO_JAVA/src/TuioDemo.java
front_processing/extern/TUIO_JAVA/src/TuioDemoComponent.java
front_processing/extern/TUIO_JAVA/src/TuioDump.java
front_processing/extern/TUIO_JAVA/src/compile.bat
front_processing/src/Trakers/Trakers.pde
middleware/extern/TuioServer/TuioServer/Tuio.csproj
middleware/extern/TuioServer/TuioServer/TuioServer.cs
middleware/src/App.config
middleware/src/Communication/Server.cs
middleware/src/Debug/DebugWindow.xaml
middleware/src/Debug/DebugWindow.xaml.cs
middleware/src/MainClass.cs
middleware/src/Properties/Resources.Designer.cs
middleware/src/Properties/Resources.resx
middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs
middleware/src/Tracking/Events/LeftHandQuitListener.cs
middleware/src/Tracking/Events/LeftHandTrackedEventArgs.cs
middleware/src/Tracking/Events/LeftHandTrackedListener.cs
middleware/src/Tracking/Events/RightHandQuitEventArgs.cs
middleware/src/Tracking/Events/RightHandQuitListener.cs
middleware/src/Tracking/Events/RightHandTrackedEventArgs.cs
middleware/src/Tracking/Events/RightHandTrackedListener.cs
middleware/src/Tracking/Events/SwipeEventArgs.cs
middleware/src/Tracking/Gestures/GestureDetector.cs
middleware/src/Tracking/Gestures/SwipeDetector.cs
middleware/src/Tracking/KinectMain.cs
middleware/src/Trakers.csproj
--- a/.hgignore	Fri Mar 09 18:15:12 2012 +0100
+++ b/.hgignore	Thu Mar 15 13:33:21 2012 +0100
@@ -3,3 +3,6 @@
 syntax: glob
 *.suo
 middleware/lib/TuioServer.dll
+front_processing/src/Trakers_gestures/code/*
+front_processing/src/Trakers/code/*
+front_processing/extern/TUIO_PROCESSING/library/*
--- a/front_processing/extern/TUIO_JAVA/src/TUIO/TuioClient.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioClient.java	Thu Mar 15 13:33:21 2012 +0100
@@ -38,6 +38,8 @@
  */ 
 public class TuioClient implements OSCListener {
 	
+	public String comm;
+	
 	private int port = 3333;
 	private OSCPortIn oscPort;
 	private boolean connected = false;
@@ -47,13 +49,20 @@
 	private Hashtable<Long,TuioCursor> cursorList = new Hashtable<Long,TuioCursor>();
 	private Vector<Long> aliveCursorList = new Vector<Long>();
 	private Vector<Long> newCursorList = new Vector<Long>();
+	private Hashtable<Long,TuioString> stringList = new Hashtable<Long,TuioString>();
+	private Vector<Long> aliveStringList = new Vector<Long>();
+	private Vector<Long> newStringList = new Vector<Long>();
 
 	private Vector<TuioObject> frameObjects = new Vector<TuioObject>();
 	private Vector<TuioCursor> frameCursors = new Vector<TuioCursor>();
+	private Vector<TuioString> frameStrings = new Vector<TuioString>();
 
 	private Vector<TuioCursor> freeCursorList = new Vector<TuioCursor>();
 	private int maxCursorID = -1;
 	
+	private Vector<TuioString> freeStringList = new Vector<TuioString>();
+	private int maxStringID = -1;
+	
 	private long currentFrame = 0;
 	private TuioTime currentTime;
 
@@ -86,7 +95,8 @@
 		try {
 			oscPort = new OSCPortIn(port);
 			oscPort.addListener("/tuio/2Dobj",this);
-			oscPort.addListener("/tuio/2Dcur",this);
+			oscPort.addListener("/tuio/3Dcur",this);
+			oscPort.addListener("/tuio/_siP",this);
 			oscPort.startListening();
 			connected = true;
 		} catch (Exception e) {
@@ -153,7 +163,16 @@
 	 */
 	public Vector<TuioCursor> getTuioCursors() {
 		return new Vector<TuioCursor>(cursorList.values());
-	}	
+	}
+	
+	/**
+	 * Returns a Vector of all currently active TuioStrings
+	 *
+	 * @return  a Vector of all currently active TuioStrings
+	 */
+	public Vector<TuioString> getTuioStrings() {
+		return new Vector<TuioString>(stringList.values());
+	}
 
 	/**
 	 * Returns the TuioObject corresponding to the provided Session ID
@@ -173,6 +192,16 @@
 	 */
 	public TuioCursor getTuioCursor(long s_id) {
 		return cursorList.get(s_id);
+	}
+
+	/**
+	 * Returns the TuioString corresponding to the provided Session ID
+	 * or NULL if the Session ID does not refer to an active TuioString
+	 *
+	 * @return  an active TuioString corresponding to the provided Session ID or NULL
+	 */
+	public TuioString getTuioString(long s_id) {
+		return stringList.get(s_id);
 	}	
 
 	/**
@@ -305,30 +334,31 @@
 				}
 				frameObjects.clear();
 			}
-		} else if (address.equals("/tuio/2Dcur")) {
+		} else if (address.equals("/tuio/3Dcur")) {
 
 			if (command.equals("set")) {
 
 				long s_id  = ((Integer)args[1]).longValue();
 				float xpos = ((Float)args[2]).floatValue();
 				float ypos = ((Float)args[3]).floatValue();
-				float xspeed = ((Float)args[4]).floatValue();
-				float yspeed = ((Float)args[5]).floatValue();
-				float maccel = ((Float)args[6]).floatValue();
+				float zpos = ((Float)args[4]).floatValue();
+				float xspeed = ((Float)args[5]).floatValue();
+				float yspeed = ((Float)args[6]).floatValue();
+				float maccel = ((Float)args[7]).floatValue();
 				
 				if (cursorList.get(s_id) == null) {
 									
-					TuioCursor addCursor = new TuioCursor(s_id, -1 ,xpos,ypos);
+					TuioCursor addCursor = new TuioCursor(s_id, -1 ,xpos,ypos,zpos);
 					frameCursors.addElement(addCursor);
 					
 				} else {
 				
 					TuioCursor tcur = cursorList.get(s_id);
 					if (tcur==null) return;
-					if ((tcur.xpos!=xpos) || (tcur.ypos!=ypos) || (tcur.x_speed!=xspeed) || (tcur.y_speed!=yspeed) || (tcur.motion_accel!=maccel)) {
+					if ((tcur.xpos!=xpos) || (tcur.ypos!=ypos) || (tcur.zpos!=zpos) || (tcur.x_speed!=xspeed) || (tcur.y_speed!=yspeed) || (tcur.motion_accel!=maccel)) {
 
-						TuioCursor updateCursor = new TuioCursor(s_id,tcur.getCursorID(),xpos,ypos);
-						updateCursor.update(xpos,ypos,xspeed,yspeed,maccel);
+						TuioCursor updateCursor = new TuioCursor(s_id,tcur.getCursorID(),xpos,ypos,zpos);
+						updateCursor.update(xpos,ypos,zpos,xspeed,yspeed,maccel);
 						frameCursors.addElement(updateCursor);
 					}
 				}
@@ -420,7 +450,7 @@
 									freeCursorList.removeElement(closestCursor);
 								} else maxCursorID = c_id;		
 								
-								TuioCursor addCursor = new TuioCursor(currentTime,tcur.getSessionID(),c_id,tcur.getX(),tcur.getY());
+								TuioCursor addCursor = new TuioCursor(currentTime,tcur.getSessionID(),c_id,tcur.getX(),tcur.getY(),tcur.getZ());
 								cursorList.put(addCursor.getSessionID(),addCursor);
 								
 								for (int i=0;i<listenerList.size();i++) {
@@ -432,10 +462,10 @@
 							default:
 								
 								TuioCursor updateCursor = cursorList.get(tcur.getSessionID());
-								if ( (tcur.getX()!=updateCursor.getX() && tcur.getXSpeed()==0) || (tcur.getY()!=updateCursor.getY() && tcur.getYSpeed()==0) )
-									updateCursor.update(currentTime,tcur.getX(),tcur.getY());
+								if ( (tcur.getX()!=updateCursor.getX() && tcur.getXSpeed()==0) || (tcur.getY()!=updateCursor.getY() && tcur.getYSpeed()==0) || (tcur.getZ()!=updateCursor.getZ()) )
+									updateCursor.update(currentTime,tcur.getX(),tcur.getY(),tcur.getZ());
 								else 
-									updateCursor.update(currentTime,tcur.getX(),tcur.getY(),tcur.getXSpeed(),tcur.getYSpeed(),tcur.getMotionAccel());
+									updateCursor.update(currentTime,tcur.getX(),tcur.getY(),tcur.getZ(),tcur.getXSpeed(),tcur.getYSpeed(),tcur.getMotionAccel());
 									
 								for (int i=0;i<listenerList.size();i++) {
 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
@@ -457,7 +487,157 @@
 				
 				frameCursors.clear();
 			} 
+		} else if (address.equals("/tuio/_siP")) {
 
+			if (command.equals("set")) {
+
+				long s_id  = ((Integer)args[1]).longValue();
+				String msg = args[2].toString();
+				
+				if (stringList.get(s_id) == null) {
+									
+					TuioString addString = new TuioString(s_id, -1, msg);
+					frameStrings.addElement(addString);
+					
+				} else {
+				
+					TuioString tstr = stringList.get(s_id);
+					if (tstr==null) return;
+					if (!tstr.getMessage().equals(msg)) {
+
+						TuioString updateString = new TuioString(s_id,tstr.getStringID(),msg);
+						updateString.update(msg);
+						frameStrings.addElement(updateString);
+					}
+				}
+				
+				//System.out.println("set cur " + s_id+" "+xpos+" "+ypos+" "+xspeed+" "+yspeed+" "+maccel);
+				
+			} else if (command.equals("alive")) {
+	
+				newStringList.clear();
+				for (int i=1;i<args.length;i++) {
+					// get the message content
+					long s_id = ((Integer)args[i]).longValue();
+					newStringList.addElement(s_id);
+					// reduce the cursor list to the lost cursors
+					if (aliveStringList.contains(s_id)) 
+						aliveStringList.removeElement(s_id);
+				}
+				
+				// remove the remaining cursors
+				for (int i=0;i<aliveStringList.size();i++) {
+					TuioString removeString = stringList.get(aliveStringList.elementAt(i));
+					if (removeString==null) continue;
+					removeString.remove(currentTime);
+					frameStrings.addElement(removeString);
+				}
+								
+			} else if (command.equals("fseq")) {
+				long fseq = ((Integer)args[1]).longValue();
+				boolean lateFrame = false;
+				
+				if (fseq>0) {
+					if (fseq>currentFrame) currentTime = TuioTime.getSessionTime();
+					if ((fseq>=currentFrame) || ((currentFrame-fseq)>100)) currentFrame = fseq;
+					else lateFrame = true;
+				} else if (TuioTime.getSessionTime().subtract(currentTime).getTotalMilliseconds()>100) {
+					currentTime = TuioTime.getSessionTime();
+				}
+				if (!lateFrame) {
+
+					Enumeration<TuioString> frameEnum = frameStrings.elements();
+					while(frameEnum.hasMoreElements()) {
+						TuioString tstr = frameEnum.nextElement();
+						
+						switch (tstr.getTuioState()) {
+							case TuioString.TUIO_REMOVED:
+							
+								TuioString removeString = tstr;
+								removeString.remove(currentTime);
+								
+								for (int i=0;i<listenerList.size();i++) {
+									TuioListener listener = (TuioListener)listenerList.elementAt(i);
+									if (listener!=null) listener.removeTuioString(removeString);
+								}
+
+								stringList.remove(removeString.getSessionID());
+
+								if (removeString.getStringID()==maxStringID) {
+									maxStringID = -1;
+									if (stringList.size()>0) {
+										Enumeration<TuioString> slist = stringList.elements();
+										while (slist.hasMoreElements()) {
+											int sl_id = slist.nextElement().getStringID();
+											if (sl_id>maxStringID) maxStringID=sl_id;
+										}
+										
+										Enumeration<TuioString> flist = freeStringList.elements();
+										while (flist.hasMoreElements()) {
+											int sl_id = flist.nextElement().getStringID();
+											if (sl_id>=maxStringID) freeStringList.removeElement(sl_id);
+										}
+									} else freeStringList.clear();
+								} else if (removeString.getStringID()<maxStringID) {
+									freeStringList.addElement(removeString);
+								}
+								
+								break;
+
+							case TuioString.TUIO_ADDED:
+
+								int sl_id = stringList.size();
+								if ((stringList.size()<=maxStringID) && (freeStringList.size()>0)) {
+									TuioString closestString = freeStringList.firstElement();
+									Enumeration<TuioString> testList = freeStringList.elements();
+									while (testList.hasMoreElements()) {
+										TuioString testString = testList.nextElement();
+										//if (testString.getDistance(tstr)<closestString.getDistance(tstr))
+										closestString = testString;
+									}
+									sl_id = closestString.getStringID();
+									freeStringList.removeElement(closestString);
+								} else maxStringID = sl_id;		
+								
+								TuioString addString = new TuioString(currentTime,tstr.getSessionID(),sl_id,tstr.getMessage());
+								stringList.put(addString.getSessionID(),addString);
+								
+								for (int i=0;i<listenerList.size();i++) {
+									TuioListener listener = (TuioListener)listenerList.elementAt(i);
+									if (listener!=null) listener.addTuioString(addString);
+								}
+								break;
+								
+							default:
+								
+								TuioString updateString = stringList.get(tstr.getSessionID());
+								if ( tstr.getMessage()!=updateString.getMessage() )
+									updateString.update(currentTime,tstr.getMessage());
+								else 
+									updateString.update(currentTime,tstr.getMessage());
+									
+								for (int i=0;i<listenerList.size();i++) {
+									TuioListener listener = (TuioListener)listenerList.elementAt(i);
+									if (listener!=null) listener.updateTuioString(updateString);
+								}
+						}
+					}
+					
+					for (int i=0;i<listenerList.size();i++) {
+						TuioListener listener = (TuioListener)listenerList.elementAt(i);
+						if (listener!=null) listener.refresh(new TuioTime(currentTime));
+					}
+					
+					Vector<Long> buffer = aliveStringList;
+					aliveStringList = newStringList;
+					// recycling the vector
+					newStringList = buffer;				
+				}
+				
+				frameStrings.clear();
+			} 
 		}
+		
+		
 	}
 }
--- a/front_processing/extern/TUIO_JAVA/src/TUIO/TuioContainer.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioContainer.java	Thu Mar 15 13:33:21 2012 +0100
@@ -103,6 +103,30 @@
 	}
 	
 	/**
+	 * This constructor takes a TuioTime argument and assigns it along with the provided 
+	 * Session ID, X, Y and Z coordinate to the newly created TuioContainer.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	si	the Session ID to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	TuioContainer(TuioTime ttime, long si, float xp, float yp, float zp) {
+		super(ttime,xp,yp, zp);
+		
+		session_id = si;
+		x_speed = 0.0f;
+		y_speed = 0.0f;
+		motion_speed = 0.0f;
+		motion_accel = 0.0f;
+		
+		path = new Vector<TuioPoint>();
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
+		state = TUIO_ADDED;
+	}
+	
+	/**
 	 * This constructor takes the provided Session ID, X and Y coordinate 
 	 * and assigs these values to the newly created TuioContainer.
 	 *
@@ -125,6 +149,29 @@
 	}
 	
 	/**
+	 * This constructor takes the provided Session ID, X, Y and Z coordinate 
+	 * and assigs these values to the newly created TuioContainer.
+	 *
+	 * @param	si	the Session ID to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	TuioContainer(long si, float xp, float yp, float zp) {
+		super(xp,yp,zp);
+		
+		session_id = si;
+		x_speed = 0.0f;
+		y_speed = 0.0f;
+		motion_speed = 0.0f;
+		motion_accel = 0.0f;
+		
+		path = new Vector<TuioPoint>();
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
+		state = TUIO_ADDED;
+	}
+	
+	/**
 	 * This constructor takes the atttibutes of the provided TuioContainer 
 	 * and assigs these values to the newly created TuioContainer.
 	 *
@@ -140,7 +187,7 @@
 		motion_accel = 0.0f;
 		
 		path = new Vector<TuioPoint>();
-		path.addElement(new TuioPoint(currentTime,xpos,ypos));
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
 		state = TUIO_ADDED;
 	}
 	
@@ -176,11 +223,44 @@
 	}
 	
 	/**
+	 * Takes a TuioTime argument and assigns it along with the provided 
+	 * X, Y and Z coordinate to the private TuioContainer attributes.
+	 * The speed and accleration values are calculated accordingly.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public void update(TuioTime ttime, float xp, float yp, float zp) {
+		TuioPoint lastPoint = path.lastElement();
+		super.update(ttime,xp,yp,zp);
+		
+		TuioTime diffTime = currentTime.subtract(lastPoint.getTuioTime());
+		float dt = diffTime.getTotalMilliseconds()/1000.0f;
+		float dx = this.xpos - lastPoint.getX();
+		float dy = this.ypos - lastPoint.getY();
+		float dz = this.zpos - lastPoint.getZ();
+		float dist = (float)Math.sqrt(dx*dx+dy*dy+dz*dz);
+		float last_motion_speed = this.motion_speed;
+		
+		this.x_speed = dx/dt;
+		this.y_speed = dy/dt;
+		this.motion_speed = dist/dt;
+		this.motion_accel = (motion_speed - last_motion_speed)/dt;
+		
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
+		if (motion_accel>0) state = TUIO_ACCELERATING;
+		else if (motion_accel<0) state = TUIO_DECELERATING;
+		else state = TUIO_STOPPED;
+	}
+	
+	/**
 	 * This method is used to calculate the speed and acceleration values of
 	 * TuioContainers with unchanged positions.
 	 */
 	public void stop(TuioTime ttime) {
-		update(ttime,xpos,ypos);
+		update(ttime,xpos,ypos,zpos);
 	}
 	
 	/**
@@ -208,6 +288,31 @@
 	}
 	
 	/**
+	 * Takes a TuioTime argument and assigns it along with the provided 
+	 * X, Y and Z coordinate, X and Y velocity and acceleration
+	 * to the private TuioContainer attributes.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 * @param	xs	the X velocity to assign
+	 * @param	ys	the Y velocity to assign
+	 * @param	ma	the acceleration to assign
+	 */
+	public void update(TuioTime ttime, float xp, float yp, float zp , float xs, float ys, float ma) {
+		super.update(ttime,xp,yp,zp);
+		x_speed = xs;
+		y_speed = ys;
+		motion_speed = (float)Math.sqrt(x_speed*x_speed+y_speed*y_speed);
+		motion_accel = ma;
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
+		if (motion_accel>0) state = TUIO_ACCELERATING;
+		else if (motion_accel<0) state = TUIO_DECELERATING;
+		else state = TUIO_STOPPED;
+	}
+	
+	/**
 	 * Assigns the provided X and Y coordinate, X and Y velocity and acceleration
 	 * to the private TuioContainer attributes. The TuioTime time stamp remains unchanged.
 	 *
@@ -230,6 +335,29 @@
 	}
 	
 	/**
+	 * Assigns the provided X, Y and Z coordinate, X and Y velocity and acceleration
+	 * to the private TuioContainer attributes. The TuioTime time stamp remains unchanged.
+	 *
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 * @param	xs	the X velocity to assign
+	 * @param	ys	the Y velocity to assign
+	 * @param	ma	the acceleration to assign
+	 */
+	public void update(float xp, float yp, float zp,float xs,float ys,float ma) {
+		super.update(xp,yp,zp);
+		x_speed = xs;
+		y_speed = ys;
+		motion_speed = (float)Math.sqrt(x_speed*x_speed+y_speed*y_speed);
+		motion_accel = ma;
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
+		if (motion_accel>0) state = TUIO_ACCELERATING;
+		else if (motion_accel<0) state = TUIO_DECELERATING;
+		else state = TUIO_STOPPED;
+	}
+	
+	/**
 	 * Takes the atttibutes of the provided TuioContainer 
 	 * and assigs these values to this TuioContainer.
 	 * The TuioTime time stamp of this TuioContainer remains unchanged.
@@ -242,7 +370,7 @@
 		y_speed = tcon.getYSpeed();
 		motion_speed = tcon.getMotionSpeed();
 		motion_accel = tcon.getMotionAccel();
-		path.addElement(new TuioPoint(currentTime,xpos,ypos));
+		path.addElement(new TuioPoint(currentTime,xpos,ypos,zpos));
 		if (motion_accel>0) state = TUIO_ACCELERATING;
 		else if (motion_accel<0) state = TUIO_DECELERATING;
 		else state = TUIO_STOPPED;
@@ -288,7 +416,7 @@
 	 * @return	the position of this TuioContainer
 	 */
 	public TuioPoint getPosition() {
-		return new TuioPoint(xpos,ypos);
+		return new TuioPoint(xpos,ypos,zpos);
 	}
 	
 	/**
--- a/front_processing/extern/TUIO_JAVA/src/TUIO/TuioCursor.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioCursor.java	Thu Mar 15 13:33:21 2012 +0100
@@ -49,6 +49,22 @@
 	}
 	
 	/**
+	 * This constructor takes a TuioTime argument and assigns it along  with the provided 
+	 * Session ID, Cursor ID, X, Y and Z coordinate to the newly created TuioCursor.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	si	the Session ID  to assign
+	 * @param	ci	the Cursor ID  to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public TuioCursor (TuioTime ttime, long si, int ci, float xp, float yp, float zp) {
+		super(ttime, si,xp,yp,zp);
+		this.cursor_id = ci;
+	}
+	
+	/**
 	 * This constructor takes the provided Session ID, Cursor ID, X and Y coordinate 
 	 * and assigs these values to the newly created TuioCursor.
 	 *
@@ -61,6 +77,21 @@
 		super(si,xp,yp);
 		this.cursor_id = ci;
 	}
+	
+	/**
+	 * This constructor takes the provided Session ID, Cursor ID, X, Y and Z coordinate 
+	 * and assigs these values to the newly created TuioCursor.
+	 *
+	 * @param	si	the Session ID  to assign
+	 * @param	ci	the Cursor ID  to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public TuioCursor (long si, int ci, float xp, float yp, float zp) {
+		super(si,xp,yp,zp);
+		this.cursor_id = ci;
+	}
 
 	/**
 	 * This constructor takes the atttibutes of the provided TuioCursor 
--- a/front_processing/extern/TUIO_JAVA/src/TUIO/TuioListener.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioListener.java	Thu Mar 15 13:33:21 2012 +0100
@@ -82,6 +82,27 @@
 	public void removeTuioCursor(TuioCursor tcur);
 	
 	/**
+	 * This callback method is invoked by the TuioClient when a new TuioString is added to the session.   
+	 *
+	 * @param  tstr  the TuioString reference associated to the addTuioString event
+	 */
+	public void addTuioString(TuioString tstr);
+
+	/**
+	 * This callback method is invoked by the TuioClient when an existing TuioString is updated during the session.   
+	 *
+	 * @param  tstr  the TuioString reference associated to the updateTuioString event
+	 */
+	public void updateTuioString(TuioString tstr);
+
+	/**
+	 * This callback method is invoked by the TuioClient when an existing TuioString is removed from the session.   
+	 *
+	 * @param  tstr  the TuioString reference associated to the removeTuioString event
+	 */
+	public void removeTuioString(TuioString tstr);
+	
+	/**
 	 * This callback method is invoked by the TuioClient to mark the end of a received TUIO message bundle.   
 	 *
 	 * @param  ftime  the TuioTime associated to the current TUIO message bundle
--- a/front_processing/extern/TUIO_JAVA/src/TUIO/TuioPoint.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioPoint.java	Thu Mar 15 13:33:21 2012 +0100
@@ -30,6 +30,8 @@
  */ 
 public class TuioPoint {
 	
+	public String comm;
+	
 	/**
 	 * X coordinate, representated as a floating point value in a range of 0..1  
 	 */
@@ -39,6 +41,10 @@
 	 */
 	protected float ypos;
 	/**
+	 * Z coordinate, representated as a floating point value in a range of 0..1  
+	 */
+	protected float zpos;
+	/**
 	 * The time stamp of the last update represented as TuioTime (time since session start)
 	 */
 	protected TuioTime currentTime;
@@ -54,6 +60,7 @@
 	public TuioPoint() {
 		xpos = 0.0f;
 		ypos = 0.0f;
+		zpos = 0.0f;
 		currentTime = TuioTime.getSessionTime();
 		startTime = new TuioTime(currentTime);
 	}
@@ -68,6 +75,23 @@
 	public TuioPoint(float xp, float yp) {
 		xpos = xp;
 		ypos = yp;
+		zpos = 0.0f;
+		currentTime = TuioTime.getSessionTime();
+		startTime = new TuioTime(currentTime);
+	}
+	
+	/**
+	 * This constructor takes three floating point coordinate arguments and sets   
+	 * its coordinate attributes to these values and its time stamp to the current session time.
+	 *
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public TuioPoint(float xp, float yp, float zp) {
+		xpos = xp;
+		ypos = yp;
+		zpos = zp;
 		currentTime = TuioTime.getSessionTime();
 		startTime = new TuioTime(currentTime);
 	}
@@ -81,6 +105,7 @@
 	public TuioPoint(TuioPoint tpoint) {
 		xpos = tpoint.getX();
 		ypos = tpoint.getY();
+		zpos = tpoint.getZ();
 		currentTime = TuioTime.getSessionTime();
 		startTime = new TuioTime(currentTime);
 	}
@@ -96,6 +121,24 @@
 	public TuioPoint(TuioTime ttime, float xp, float yp) {
 		xpos = xp;
 		ypos = yp;
+		zpos = 0.0f;
+		currentTime = new TuioTime(ttime);
+		startTime = new TuioTime(currentTime);
+	}
+	
+	/**
+	 * This constructor takes a TuioTime object and three floating point coordinate arguments and sets   
+	 * its coordinate attributes to these values and its time stamp to the provided TUIO time object.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public TuioPoint(TuioTime ttime, float xp, float yp, float zp) {
+		xpos = xp;
+		ypos = yp;
+		zpos = zp;
 		currentTime = new TuioTime(ttime);
 		startTime = new TuioTime(currentTime);
 	}
@@ -109,6 +152,7 @@
 	public void update(TuioPoint tpoint) {
 		xpos = tpoint.getX();
 		ypos = tpoint.getY();
+		zpos = tpoint.getZ();
 	}
 
 	/**
@@ -124,6 +168,20 @@
 	}
 	
 	/**
+	 * Takes three floating point coordinate arguments and updates its coordinate attributes 
+	 * to the coordinates of the provided TuioPoint and leaves its time stamp unchanged.
+	 *
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public void update(float xp, float yp, float zp) {
+		xpos = xp;
+		ypos = yp;
+		zpos = zp;
+	}
+	
+	/**
 	 * Takes a TuioTime object and two floating point coordinate arguments and updates its coordinate attributes 
 	 * to the coordinates of the provided TuioPoint and its time stamp to the provided TUIO time object.
 	 *
@@ -138,6 +196,22 @@
 	}
 	
 	/**
+	 * Takes a TuioTime object and three floating point coordinate arguments and updates its coordinate attributes 
+	 * to the coordinates of the provided TuioPoint and its time stamp to the provided TUIO time object.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 * @param	zp	the Z coordinate to assign
+	 */
+	public void update(TuioTime ttime, float xp, float yp, float zp) {
+		xpos = xp;
+		ypos = yp;
+		zpos = zp;
+		currentTime = new TuioTime(ttime);
+	}
+	
+	/**
 	 * Returns the X coordinate of this TuioPoint. 
 	 * @return	the X coordinate of this TuioPoint
 	 */
@@ -154,6 +228,14 @@
 	}
 	
 	/**
+	 * Returns the Z coordinate of this TuioPoint. 
+	 * @return	the Z coordinate of this TuioPoint
+	 */
+	public float getZ() {
+		return zpos;
+	}
+	
+	/**
 	 * Returns the distance to the provided coordinates 
 	 *
 	 * @param	xp	the X coordinate of the distant point
@@ -165,6 +247,21 @@
 		float dy = ypos-yp;
 		return (float)Math.sqrt(dx*dx+dy*dy);
 	}
+	
+	/**
+	 * Returns the distance to the provided coordinates 
+	 *
+	 * @param	xp	the X coordinate of the distant point
+	 * @param	yp	the Y coordinate of the distant point
+	 * @param	zp	the Y coordinate of the distant point
+	 * @return	the distance to the provided coordinates
+	 */
+	public float getDistance(float xp, float yp, float zp) {
+		float dx = xpos-xp;
+		float dy = ypos-yp;
+		float dz = zpos-zp;
+		return (float)Math.sqrt(dx*dx+dy*dy+dz*dz);
+	}
 
 	/**
 	 * Returns the distance to the provided TuioPoint 
@@ -173,7 +270,7 @@
 	 * @return	the distance to the provided TuioPoint
 	 */
 	public float getDistance(TuioPoint tpoint) {
-		return getDistance(tpoint.getX(),tpoint.getY());
+		return getDistance(tpoint.getX(),tpoint.getY(), tpoint.getZ());
 	}
 
 	/**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_processing/extern/TUIO_JAVA/src/TUIO/TuioString.java	Thu Mar 15 13:33:21 2012 +0100
@@ -0,0 +1,189 @@
+/*
+Added by alexandre.bastien@iri.centrepompidou.fr
+*/
+
+package TUIO;
+
+/**
+ * The TuioCursor class encapsulates /tuio/_siP TUIO strings.
+ *
+ */ 
+public class TuioString {
+
+	/**
+	 * The unique session ID number that is assigned to each TUIO string.
+	 */ 
+	protected long session_id;
+
+	/**
+	 * The individual string ID number that is assigned to each TuioString.
+	 */ 
+	protected int string_id;
+	
+	/**
+	 * The individual string message that is assigned to each TuioString.
+	 */ 
+	protected String message;
+	
+	/**
+	 * The time stamp of the last update represented as TuioTime (time since session start)
+	 */
+	protected TuioTime currentTime;
+	/**
+	 * The creation time of this TuioString represented as TuioTime (time since session start)
+	 */
+	protected TuioTime startTime;
+	
+	/**
+	 * Defines the ADDED state.
+	 */ 
+	public static final int TUIO_ADDED = 0;
+	/**
+	 * Defines the REMOVED state.
+	 */ 
+	public static final int TUIO_REMOVED = 4;
+	/**
+	 * Reflects the current state of the TuioString
+	 */ 
+	protected int state;
+	
+	/**
+	 * This constructor takes a TuioTime argument and assigns it along  with the provided 
+	 * Session ID, String ID and a message to the newly created TuioString.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	si	the Session ID  to assign
+	 * @param	sti	the String ID  to assign
+	 * @param	msg the message to assign
+	 */
+	public TuioString (TuioTime ttime, long si, int sti, String msg) {
+		this.session_id = si;
+		this.string_id = sti;
+		this.message = msg;
+		currentTime = new TuioTime(ttime);
+		startTime = new TuioTime(currentTime);
+	}
+	
+	/**
+	 * This constructor takes the provided Session ID, String ID and message 
+	 * and assigs these values to the newly created TuioString.
+	 *
+	 * @param	si	the Session ID  to assign
+	 * @param	sti	the String ID  to assign
+	 * @param	msg	the message to assign
+	 */
+	public TuioString (long si, int sti, String msg) {
+		this.session_id = si;
+		this.string_id = sti;
+		this.message = msg;
+		currentTime = TuioTime.getSessionTime();
+		startTime = new TuioTime(currentTime);
+	}
+	
+	/**
+	 * This constructor takes the atttibutes of the provided TuioCursor 
+	 * and assigs these values to the newly created TuioCursor.
+	 *
+	 * @param	tcur	the TuioCursor to assign
+	 */
+	public TuioString (TuioString tstr) {
+		this.session_id = tstr.getSessionID();
+		this.string_id = tstr.getStringID();
+		this.message = tstr.getMessage();
+		currentTime = new TuioTime(tstr.getCurrentTime());
+		startTime = new TuioTime(currentTime);
+	}
+
+	/**
+	 * Takes a TuioTime argument and assigns it along with the provided 
+	 * message to the private TuioString attributes.
+	 * The speed and accleration values are calculated accordingly.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	message2 the message to assign
+	 */
+	public void update(TuioTime ttime, String message2) {
+		currentTime = new TuioTime(ttime);
+		message = message2;
+	}
+	
+	/**
+	 * This method is used to update the TuioTime of a TuioString while keeping the same * * * message.
+	 */
+	public void stop(TuioTime ttime) {
+		update(ttime,message);
+	}
+	
+	/**
+	 * Takes the atttibutes of the provided TuioString 
+	 * and assigs these values to this TuioString.
+	 * The TuioTime time stamp of this TuioString remains unchanged.
+	 *
+	 * @param	tstr	the TuioString to assign
+	 */
+	public void update (TuioString tstr) {
+		message = tstr.getMessage();
+	}
+	
+	/**
+	 * Takes the message provided
+	 * and assigs its value to this TuioString.
+	 * The TuioTime time stamp of this TuioString remains unchanged.
+	 *
+	 * @param	msg	the message to assign
+	 */
+	public void update (String msg) {
+		message = msg;
+	}
+	
+	/**
+	 * Assigns the REMOVE state to this TuioString and sets
+	 * its TuioTime time stamp to the provided TuioTime argument.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 */
+	public void remove(TuioTime ttime) {
+		currentTime = new TuioTime(ttime);
+		state = TUIO_REMOVED;
+	}
+	
+	/**
+	 * Returns the Session ID of this TuioString.
+	 * @return	the Session ID of this TuioString
+	 */
+	public long getSessionID() {
+		return session_id;
+	}
+	
+	/**
+	 * Returns the String ID of this TuioString.
+	 * @return	the String ID of this TuioString
+	 */
+	public int getStringID() {
+		return string_id;
+	}
+	
+	/**
+	 * Returns the Message of this TuioString.
+	 * @return	the Message of this TuioString
+	 */
+	public String getMessage() {
+		return message;
+	}
+	
+	/**
+	 * Returns the Current Time of this TuioString.
+	 * @return	the Current Time of this TuioString
+	 */
+	public TuioTime getCurrentTime() {
+		return currentTime;
+	}
+	
+	/**
+	 * Returns the TUIO state of this TuioString.
+	 * @return	the TUIO state of this TuioString
+	 */
+	public int getTuioState() {
+		return state;
+	}
+}
--- a/front_processing/extern/TUIO_JAVA/src/TuioDemo.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TuioDemo.java	Thu Mar 15 13:33:21 2012 +0100
@@ -123,7 +123,7 @@
 				}
 				break;
 			case 0:
-				client = new TuioClient();
+				client = new TuioClient(80);
 				break;
 			default: 
 				System.out.println("usage: java TuioDemo [port]");
--- a/front_processing/extern/TUIO_JAVA/src/TuioDemoComponent.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TuioDemoComponent.java	Thu Mar 15 13:33:21 2012 +0100
@@ -31,6 +31,7 @@
 
 	private Hashtable<Long,TuioDemoObject> objectList = new Hashtable<Long,TuioDemoObject>();
 	private Hashtable<Long,TuioCursor> cursorList = new Hashtable<Long,TuioCursor>();
+	private Hashtable<Long,TuioString> stringList = new Hashtable<Long,TuioString>();
 
 	public static final int finger_size = 15;
 	public static final int object_size = 60;
@@ -98,6 +99,34 @@
 		if (verbose) 
 			System.out.println("del cur "+tcur.getCursorID()+" ("+tcur.getSessionID()+")"); 
 	}
+	
+	public void addTuioString(TuioString tstr) {
+	
+		if (!stringList.containsKey(tstr.getSessionID())) {
+			stringList.put(tstr.getSessionID(), tstr);
+			repaint();
+		}
+		
+		if (verbose) 
+			System.out.println("add str "+tstr.getStringID()+" ("+tstr.getSessionID()+") "+tstr.getMessage());	
+	}
+
+	public void updateTuioString(TuioString tstr) {
+
+		repaint();
+		
+		if (verbose) 
+			System.out.println("set str "+tstr.getStringID()+" ("+tstr.getSessionID()+") "+tstr.getMessage()); 
+	}
+	
+	public void removeTuioString(TuioString tstr) {
+	
+		stringList.remove(tstr.getSessionID());	
+		repaint();
+		
+		if (verbose) 
+			System.out.println("del str "+tstr.getStringID()+" ("+tstr.getSessionID()+")"); 
+	}
 
 	public void refresh(TuioTime frameTime) {
 		repaint();
--- a/front_processing/extern/TUIO_JAVA/src/TuioDump.java	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/TuioDump.java	Thu Mar 15 13:33:21 2012 +0100
@@ -51,6 +51,18 @@
 		System.out.println("del cur "+tcur.getCursorID()+" ("+tcur.getSessionID()+")");	
 	}
 	
+	public void addTuioString(TuioString tstr) {
+		System.out.println("add str "+tstr.getStringID()+" ("+tstr.getSessionID()+") "+tstr.getMessage());	
+	}
+
+	public void updateTuioString(TuioString tstr) {
+		System.out.println("set str "+tstr.getStringID()+" ("+tstr.getSessionID()+") "+tstr.getMessage());
+	}
+	
+	public void removeTuioString(TuioString tstr) {
+		System.out.println("del str "+tstr.getStringID()+" ("+tstr.getSessionID()+")");	
+	}
+	
 	public void refresh(TuioTime frameTime) {
 		//System.out.println("refresh "+frameTime.getTotalMilliseconds());
 	}
--- a/front_processing/extern/TUIO_JAVA/src/compile.bat	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/extern/TUIO_JAVA/src/compile.bat	Thu Mar 15 13:33:21 2012 +0100
@@ -1,6 +1,4 @@
-cd src
 javac -O -source 1.5 -target 1.5 -cp . *.java TUIO\*.java com\illposed\osc\*.java
 jar cfm ..\TuioDemo.jar manifest.inc *.class TUIO\*.class com\illposed\osc\*.class com\illposed\osc\utility\*.class
 jar cf ..\libTUIO.jar TUIO\*.class com\illposed\osc\*.class com\illposed\osc\utility\*.class
 del *.class TUIO\*.class com\illposed\osc\*.class com\illposed\osc\utility\*.class
-cd ..
--- a/front_processing/src/Trakers/Trakers.pde	Fri Mar 09 18:15:12 2012 +0100
+++ b/front_processing/src/Trakers/Trakers.pde	Thu Mar 15 13:33:21 2012 +0100
@@ -1,4 +1,5 @@
 import TUIO.*;
+//import TrakersNavierStokes;
 TuioProcessing tuioClient;
 boolean oneHandLeft;
 
@@ -8,7 +9,7 @@
 void setup()
 {
     size (640, 480);
-    background(255);
+    showMask();
     tuioClient = new TuioProcessing(this, 80);
     textAlign(CENTER);
     imageMode(CENTER);
@@ -31,14 +32,41 @@
 void tuioInput()
 {
     noFill();
-    rect(0, 0, 50, 50);
+    //rect(0, 0, 50, 50);
   
     Vector tuioCursorList = tuioClient.getTuioCursors();
-    
+
+    if(tuioCursorList.size() <= 0)
+    {
+        showMask();
+        text("Les mains sont trop loin ou trop près.", width/2 - 20, 20);
+        text("Je ne détecte aucune main.", width/2 - 20, 40);
+    }
+        
     if(tuioCursorList.size() == 1)
+    {
         handleOneHand((TuioCursor)tuioCursorList.elementAt(0));
+        fill(255);
+        text("Les mains sont dans la zone de captation.", width/2 - 20, 20);
+        text("Je détecte une main.", width/2 - 20, 40);
+    }
     else if(tuioCursorList.size() == 2)
+    {
         handleBothHands(tuioCursorList);
+        fill(255);
+        text("Les mains sont dans la zone de captation.", width/2 - 20, 20);
+        text("Je détecte les deux mains.", width/2 - 20, 40);
+    }
+}
+
+/*FONCTION DE GENERATION DU MASQUE
+Entrée :
+Sortie : Place des rectangles autour de la zone de dessin*/
+void showMask()
+{
+    background(0);
+    fill(255);
+    rect(0, 80, width, height-130);
 }
 
 /*FONCTION DE GESTION DES COURBES POUR UNE MAIN DETECTEE
@@ -46,9 +74,8 @@
 Sortie : Appel aux différentes fonctions de dessin si un message est reçu*/
 void handleOneHand(TuioCursor handCursor)
 {
-    fill(0, 0, 255);
-    rect(0, 0, 50, 50);
-    
+    showMask();
+
     Vector pointList = handCursor.getPath();
     for (int j=0;j<pointList.size();j++)
     {
@@ -66,9 +93,8 @@
 Sortie : Appel aux différentes fonctions de dessin si un message est reçu*/
 void handleBothHands(Vector tuioCursorList)
 {
-    fill(0);
-    rect(0, 0, 50, 50);
-    
+    showMask();
+
     TuioCursor handLeftCursor = (TuioCursor)tuioCursorList.elementAt(0);
     TuioCursor rightLeftCursor = (TuioCursor)tuioCursorList.elementAt(1);
     Vector handLeftPointList = handLeftCursor.getPath();
@@ -105,13 +131,27 @@
 Sortie : Le point est dessiné avec une épaisseur et une luminosité dépendant de Z*/
 void drawEllipse(float x, float y, float z, boolean leftHand)
 {
-    float weight = map(z, 1, 2, 50, 1);
-    float redColor = map(z, 1, 2, 255, 80);
+
+    fill(0, 0, 255);
+    stroke(0,0,0);
+
+    float weight = map(z, 1, 1.5, 50, 1);
+    float redColor = map(z, 1, 1.5, 255, 80);
+    
     if(leftHand)
         fill(redColor,0,0);
     else
         fill(0,redColor,0);
-    ellipse(x, y, weight, weight);
-}
- 
-
+    
+    if(weight < 30)
+    {
+        //strokeWeight(0);
+    }
+    else
+    {
+        fill(0, 0, redColor);
+    }
+    
+    
+    ellipse(x+20, y+100, weight, weight);
+}
--- a/middleware/extern/TuioServer/TuioServer/Tuio.csproj	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/extern/TuioServer/TuioServer/Tuio.csproj	Thu Mar 15 13:33:21 2012 +0100
@@ -48,6 +48,7 @@
     <Compile Include="TuioCursor.cs" />
     <Compile Include="TuioServer.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TuioString.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
--- a/middleware/extern/TuioServer/TuioServer/TuioServer.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/extern/TuioServer/TuioServer/TuioServer.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -25,9 +25,8 @@
     {
         #region constants
         
-        private const string _cursorAddressPattern = "/tuio/2Dcur";
-
-        private const string _objectAddressPattern = "/tuio/2Dobj"; 
+        private const string _cursorAddressPattern = "/tuio/3Dcur";
+        private const string _stringAddressPattern = "/tuio/_siP";
 
         #endregion
 
@@ -36,6 +35,7 @@
         private IPEndPoint _ipEndPoint;
 
         private Dictionary<int, TuioCursor> _cursors;
+        private Dictionary<int, TuioString> _strings;
 
         private int _currentFrame;
 
@@ -56,6 +56,7 @@
         public TuioServer(string host, int port)
         {
             _cursors = new Dictionary<int, TuioCursor>();
+            _strings = new Dictionary<int, TuioString>();
             _ipEndPoint = new IPEndPoint(IPAddress.Parse(host), port);
             _currentFrame = 0;
         }
@@ -77,7 +78,8 @@
         /// </summary>
         public void CommitFrame()
         {
-            GetFrameBundle().Send(_ipEndPoint);
+            GetCursorFrameBundle().Send(_ipEndPoint);
+            GetStringFrameBundle().Send(_ipEndPoint);
         }
 
         #endregion
@@ -120,21 +122,59 @@
 
         #endregion
 
-        #region osc message assembly
+        #region string related methods
+
+        /// <summary>
+        /// Adds a TUIO string. A new id, not used before, must be provided.
+        /// </summary>
+        /// <param name="id">New id</param>
+        /// <param name="message">msg</param>
+        public void AddTuioString(int id, String msg)
+        {
+            lock (_strings)
+                if (!_strings.ContainsKey(id))
+                    _strings.Add(id, new TuioString(id, msg));
+        }
 
-        private OscBundle GetFrameBundle()
+        /// <summary>
+        /// Updates a TUIO string. An id of an existing string must be provided.
+        /// </summary>
+        /// <param name="id">Id</param>
+        /// <param name="message">msg</param>
+        public void UpdateTuioString(int id, String msg)
+        {
+            TuioString _string;
+            if (_strings.TryGetValue(id, out _string))
+                _string.message = msg;
+        }
+
+        /// <summary>
+        /// Deletes a TUIO string. An id of an existing string must be provided.
+        /// </summary>
+        /// <param name="id">Id</param>
+        public void DeleteTuioString(int id)
+        {
+            lock (_strings)
+                _strings.Remove(id);
+        }
+
+        #endregion
+
+        #region osc message assembly for cursors
+
+        private OscBundle GetCursorFrameBundle()
         {
             OscBundle bundle = new OscBundle(_ipEndPoint);
 
-            bundle.Append(GetAliveMessage());
+            bundle.Append(GetCursorAliveMessage());
             foreach (OscMessage msg in GetCursorMessages())
                 bundle.Append(msg);
-            bundle.Append(GetSequenceMessage());
+            bundle.Append(GetCursorSequenceMessage());
 
             return bundle;
         }
 
-        private OscMessage GetAliveMessage()
+        private OscMessage GetCursorAliveMessage()
         {
             OscMessage msg = new OscMessage(_ipEndPoint, _cursorAddressPattern);
 
@@ -146,7 +186,7 @@
             return msg;
         }
 
-        private OscMessage GetSequenceMessage()
+        private OscMessage GetCursorSequenceMessage()
         {
             OscMessage msg = new OscMessage(_ipEndPoint, _cursorAddressPattern);
 
@@ -184,5 +224,65 @@
         }
 
         #endregion
+
+        #region osc message assembly for strings
+
+        private OscBundle GetStringFrameBundle()
+        {
+            OscBundle bundle = new OscBundle(_ipEndPoint);
+
+            bundle.Append(GetStringAliveMessage());
+            foreach (OscMessage msg in GetStringMessages())
+                bundle.Append(msg);
+            bundle.Append(GetStringSequenceMessage());
+
+            return bundle;
+        }
+
+        private OscMessage GetStringAliveMessage()
+        {
+            OscMessage msg = new OscMessage(_ipEndPoint, _stringAddressPattern);
+
+            msg.Append("alive");
+            lock (_cursors)
+                foreach (TuioString _string in _strings.Values)
+                    msg.Append((Int32)_string.Id);
+
+            return msg;
+        }
+
+        private OscMessage GetStringSequenceMessage()
+        {
+            OscMessage msg = new OscMessage(_ipEndPoint, _stringAddressPattern);
+
+            msg.Append("fseq");
+            msg.Append((Int32)_currentFrame);
+
+            return msg;
+        }
+
+        private OscMessage GetStringMessage(TuioString _string)
+        {
+            OscMessage msg = new OscMessage(_ipEndPoint, _stringAddressPattern);
+
+            msg.Append("set");
+            msg.Append((Int32)_string.Id);
+            msg.Append((String)_string.message);
+
+            return msg;
+        }
+
+        private IEnumerable<OscMessage> GetStringMessages()
+        {
+            List<OscMessage> msgs = new List<OscMessage>();
+
+            lock (_strings)
+                foreach (TuioString _string in _strings.Values)
+                    msgs.Add(GetStringMessage(_string));
+
+            return msgs.AsEnumerable();
+        }
+
+        #endregion
     }
 }
--- a/middleware/src/App.config	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/App.config	Thu Mar 15 13:33:21 2012 +0100
@@ -1,7 +1,30 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <configuration>
   <appSettings>
-    <add key="searchMinDistance" value="1"/>
-    <add key="searchMaxDistance" value="2"/>
+    <add key="searchMinDistance" value="1,0"/>
+    <add key="searchMaxDistance" value="1,5"/>
+    <add key="connexionHost" value="127.0.0.1"/>
+    <add key="connexionPort" value="80"/>
+    <add key="hipCenterID" value="0"/>
+    <add key="spineID" value="1"/>
+    <add key="shoulderCenterID" value="2"/>
+    <add key="headID" value="3"/>
+    <add key="shoulderLeftID" value="4"/>
+    <add key="elbowLeftID" value="5"/>
+    <add key="wristLeftID" value="6"/>
+    <add key="handLeftID" value="7"/>
+    <add key="shoulderRightID" value="8"/>
+    <add key="elbowRightID" value="9"/>
+    <add key="wristRightID" value="10"/>
+    <add key="handRightID" value="11"/>
+    <add key="hipLeftID" value="12"/>
+    <add key="kneeLeftID" value="13"/>
+    <add key="ankleLeftID" value="14"/>
+    <add key="footLeftID" value="15"/>
+    <add key="hipRightID" value="16"/>
+    <add key="kneeRightID" value="17"/>
+    <add key="ankleRightID" value="18"/>
+    <add key="footRightID" value="19"/>
+    <add key="timerElapsing" value="1000"/>
   </appSettings>
 </configuration>
\ No newline at end of file
--- a/middleware/src/Communication/Server.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Communication/Server.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
  * Sous-Module : Communication
  * Classe : Server
@@ -26,6 +26,7 @@
 using Trakers.Tracking;
 using System.Windows.Media.Media3D;
 using Trakers.Tracking.Events;
+using System.Timers;
 
 namespace Trakers.Communication
 {
@@ -37,18 +38,37 @@
         //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)
+        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;
-            ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
+            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);
         }
 
         /*
@@ -60,10 +80,22 @@
         }
 
         /*
+         * 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)
             {
@@ -82,16 +114,19 @@
         */
         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");
             }
         }
 
@@ -100,6 +135,7 @@
         */
         public void LeftHandQuit(object sender, LeftHandQuitEventArgs e)
         {
+            return;
             //Si le curseur de la main gauche existe, alors on le supprime.
             if (leftHandCursorCreated)
             {
@@ -113,15 +149,75 @@
         */
         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)
@@ -144,6 +240,14 @@
                 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);
+                }
             }
         }
     }
--- a/middleware/src/Debug/DebugWindow.xaml	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Debug/DebugWindow.xaml	Thu Mar 15 13:33:21 2012 +0100
@@ -1,5 +1,5 @@
 <!--
-Projet : KINECT PROJECTS
+Projet : TraKERS
 Module : MIDDLEWARE
 Sous-Module : Debug
 Classe : Debug
@@ -52,14 +52,21 @@
         <!-- 0-1 m : Rouge. 1-2 : Orange. 2-3 : Jaune. 3-4 : Blanc. -->
         <StackPanel Grid.Row="0" Grid.Column="1" Name="List">
             <Label Name="DistanceLbl" Content="Distance :" />
-            <Label Name="D1" Content="0 &lt; D &lt; 1" />
+            <Rectangle Name="R1" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R2" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R3" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R4" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R5" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R6" Height="50" Fill="DarkGray" />
+            <Rectangle Name="R7" Height="50" Fill="DarkGray" />
+            <!--<Label Name="D1" Content="0 &lt; D &lt; 1" />
             <Rectangle Name="R1" Height="70" Fill="DarkGray" />
             <Label Name="D2" Content="1 &lt; D &lt; 2" />
             <Rectangle Name="R2" Height="70" Fill="DarkGray" />
             <Label Name="D3" Content="2 &lt; D &lt; 3" />
             <Rectangle Name="R3" Height="70" Fill="DarkGray" />
             <Label Name="D4" Content="3 &lt; D &lt; 4" />
-            <Rectangle Name="R4" Height="70" Fill="DarkGray" />
+            <Rectangle Name="R4" Height="70" Fill="DarkGray" />-->
         </StackPanel>
     </Grid>
 </Window>
--- a/middleware/src/Debug/DebugWindow.xaml.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Debug/DebugWindow.xaml.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
  * Sous-Module : Debug
  * Classe : DebugWindow
@@ -31,6 +31,8 @@
 
 using Trakers.Tracking;
 using System.Threading;
+using Trakers.Tracking.Events;
+using Trakers.Tracking.Gestures;
 
 namespace Trakers.Debug
 {
@@ -142,6 +144,18 @@
             //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;
@@ -158,7 +172,12 @@
         {
             DistanceLbl.Content = "Distance : " + distance;
 
-            if (distance > 0 && distance < 1)
+            /*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;
@@ -185,7 +204,7 @@
                 R2.Fill = System.Windows.Media.Brushes.DarkGray;
                 R3.Fill = System.Windows.Media.Brushes.DarkGray;
                 R4.Fill = System.Windows.Media.Brushes.White;
-            }
+            }*/
         }
 
         /*
@@ -262,6 +281,7 @@
             line.Y2 = j2.Position.Y;
             line.StrokeThickness = 8;
             DebugCanvas.Children.Add(line);
+            ExceptionLbl.Content = DebugCanvas.Children.Count;
         }
 
         /*
@@ -307,9 +327,40 @@
             RightHand.Content = coord;
         }
 
-        public void showSwipe()
+        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)
         {
-            ExceptionLbl.Background = System.Windows.Media.Brushes.Red;
+            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;
+                }
+            }
         }
     }
 }
--- a/middleware/src/MainClass.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/MainClass.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
  * Classe : MainClass
  * 
@@ -21,6 +21,9 @@
 using System.Drawing;
 using System.Threading;
 using System.IO;
+using System.Resources;
+using System.Reflection;
+using Tuio;
 
 namespace Trakers
 {
@@ -29,7 +32,21 @@
         [STAThread]
         public static void Main()
         {
-            KinectMain kinectMain = new KinectMain();
+            //Crée le gestionnaire de ressources.
+            ResourceManager rm = new ResourceManager("Trakers.Properties.resources", Assembly.GetExecutingAssembly());
+            //Fait appel à la classe qui gère la Kinect.
+            KinectMain kinectMain = new KinectMain(rm);
+
+            /*TuioServer s = new TuioServer("127.0.0.1", 80);
+
+            s.AddTuioCursor(0, new Point3D(100, 100, 1));
+            for (int i = 0; i < 10000; i++)
+            {
+                Thread.Sleep(100);
+                s.UpdateTuioCursor(0, new Point3D(100, 100, 1));
+                Console.Out.WriteLine("ref");
+            }
+            s.DeleteTuioCursor(0);*/
         }
     }
 }
--- a/middleware/src/Properties/Resources.Designer.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Properties/Resources.Designer.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -59,5 +59,32 @@
                 resourceCulture = value;
             }
         }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Kinect non connectée..
+        /// </summary>
+        internal static string kinectNotConnected {
+            get {
+                return ResourceManager.GetString("kinectNotConnected", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Impossible de charger les paramètres. Paramètres par défaut..
+        /// </summary>
+        internal static string loadParametersFail {
+            get {
+                return ResourceManager.GetString("loadParametersFail", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Paramètres incorrects. Paramètres par défaut..
+        /// </summary>
+        internal static string loadParametersIncorrect {
+            get {
+                return ResourceManager.GetString("loadParametersIncorrect", resourceCulture);
+            }
+        }
     }
 }
--- a/middleware/src/Properties/Resources.resx	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Properties/Resources.resx	Thu Mar 15 13:33:21 2012 +0100
@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
@@ -68,9 +69,10 @@
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="name" use="required" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
@@ -85,9 +87,10 @@
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">
@@ -109,9 +112,21 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+  <data name="kinectNotConnected" xml:space="preserve">
+    <value>Kinect non connectée.</value>
+    <comment>S'affiche si la Kinect n'est pas connectée.</comment>
+  </data>
+  <data name="loadParametersFail" xml:space="preserve">
+    <value>Impossible de charger les paramètres. Paramètres par défaut.</value>
+    <comment>S'affiche si les paramètres ne peuvent être chargés à cause d'un problème inconnu.</comment>
+  </data>
+  <data name="loadParametersIncorrect" xml:space="preserve">
+    <value>Paramètres incorrects. Paramètres par défaut.</value>
+    <comment>S'affiche si les paramètres sont incorrects.</comment>
+  </data>
 </root>
\ No newline at end of file
--- a/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/LeftHandQuitEventArgs.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,7 +1,7 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : LeftHandQuitEventArgs
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
--- a/middleware/src/Tracking/Events/LeftHandQuitListener.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/LeftHandQuitListener.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,13 +1,13 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : LeftHandQuitListener
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
  * 
  * Fonctionnalités : Ce listener écoute l'événement du type : La main gauche est sortie du champ.
- * Il contient le code a être éxecuté au cas cet événement survient, à savoir :
+ * Il contient le code a être éxecuté au cas où cet événement survient, à savoir :
  * - On affiche un visuel dans le debug.
  * - On notifie le serveur TUIO.
  */
--- a/middleware/src/Tracking/Events/LeftHandTrackedEventArgs.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/LeftHandTrackedEventArgs.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,7 +1,7 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : LeftHandTrackedEventArgs
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
--- a/middleware/src/Tracking/Events/LeftHandTrackedListener.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/LeftHandTrackedListener.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,13 +1,13 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : LeftHandTrackedListener
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
  * 
  * Fonctionnalités : Ce listener écoute l'événement du type : La main gauche est entrée dans le champ.
- * Il contient le code a être éxecuté au cas cet événement survient, à savoir :
+ * Il contient le code a être éxecuté au cas où cet événement survient, à savoir :
  * - On affiche un visuel dans le debug.
  * - On notifie le serveur TUIO.
  */
--- a/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/RightHandQuitEventArgs.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,7 +1,7 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : RightHandQuitEventArgs
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
--- a/middleware/src/Tracking/Events/RightHandQuitListener.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/RightHandQuitListener.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,13 +1,13 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : RightHandQuitListener
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
  * 
  * Fonctionnalités : Ce listener écoute l'événement du type : La main droite est sortie du champ.
- * Il contient le code a être éxecuté au cas cet événement survient, à savoir :
+ * Il contient le code a être éxecuté au cas où cet événement survient, à savoir :
  * - On affiche un visuel dans le debug.
  * - On notifie le serveur TUIO.
  */
--- a/middleware/src/Tracking/Events/RightHandTrackedEventArgs.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/RightHandTrackedEventArgs.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,7 +1,7 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : RightHandTrackedEventArgs
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
--- a/middleware/src/Tracking/Events/RightHandTrackedListener.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/RightHandTrackedListener.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,13 +1,13 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
- * Sous-Module : Tracking
+ * Sous-Module : Tracking/Events
  * Classe : RightHandTrackedListener
  * 
  * Auteur : alexandre.bastien@iri.centrepompidou.fr
  * 
  * Fonctionnalités : Ce listener écoute l'événement du type : La main droite est entrée dans le champ.
- * Il contient le code a être éxecuté au cas cet événement survient, à savoir :
+ * Il contient le code a être éxecuté au cas où cet événement survient, à savoir :
  * - On affiche un visuel dans le debug.
  * - On notifie le serveur TUIO.
  */
--- a/middleware/src/Tracking/Events/SwipeEventArgs.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Events/SwipeEventArgs.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,4 +1,16 @@
-using System;
+/*
+ * Projet : TraKERS
+ * Module : MIDDLEWARE
+ * Sous-Module : Tracking/Events
+ * Classe : SwipeEventArgs
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Cette classe contient les membres utilisés lors de l'appel au listener correspondant
+ * à l'événement : L'utilisateur a effectué un swipe.
+ */
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
--- a/middleware/src/Tracking/Gestures/GestureDetector.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Gestures/GestureDetector.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,4 +1,18 @@
-using System;
+/*
+ * Projet : TraKERS
+ * Module : MIDDLEWARE
+ * Sous-Module : Tracking/Gestures
+ * Classe : GestureDetector
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Reçoit les positions des noeuds envoyés par la classe de manipulation de la Kinect
+ * et les stocke dans un historique.
+ * Contient également des variables propres à toute gesture : distance de référence, point de départ,
+ * durée de la gesture, FPS et nombre de frames à traiter.
+ */
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -10,10 +24,10 @@
     public class GestureDetector
     {
         //Historique des positions du squelette.
-        protected List<List<Joint>> history = new List<List<Joint>>();
+        protected static List<List<Joint>> history = new List<List<Joint>>();
         //protected JointCollection previousSkeleton;
 
-        //Voici les ID des noeuds d'un squelette.
+        //Voici les ID des noeuds d'un squelette : variables magiques en attente de factorisation.
         protected int hipCenterID = 0, spineID = 1, shoulderCenterID = 2, headID = 3;
         protected int shoulderLeftID = 4, elbowLeftID = 5, wristLeftID = 6, handLeftID = 7;
         protected int shoulderRightID = 8, elbowRightID = 9, wristRightID = 10, handRightID = 11;
@@ -83,22 +97,14 @@
 
         //Stocke les gestes du skelette pour ~3 seconds (si on prend en compte que le framerate de la Kinect
         //est de ~30 fps.
-        public void UpdateSkeletonHistory(List<Joint> latestSkeleton)
+        public static void UpdateSkeletonHistory(List<Joint> latestSkeleton)
         {
-            /*if (previousSkeleton == null)
-                previousSkeleton = latestSkeleton;
-            else if (previousSkeleton != latestSkeleton)
-            {*/
-                history.Add(latestSkeleton);
-                /*if (history.Count > 3)
-                {
-                    System.Console.WriteLine(history[0][0].Position.X + " " + history[1][0].Position.X + " " + history[2][0].Position.X);
-                }*/
-                if (history.Count > 90)
-                {
-                    history.RemoveAt(0);
-                }
-            //}
+            history.Add(latestSkeleton);
+                
+            if (history.Count > 90)
+            {
+                history.RemoveAt(0);
+            }
         }
 
         /*public bool CheckForHandWave()
--- a/middleware/src/Tracking/Gestures/SwipeDetector.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/Gestures/SwipeDetector.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,4 +1,16 @@
-using System;
+/*
+ * Projet : TraKERS
+ * Module : MIDDLEWARE
+ * Sous-Module : Tracking/Gestures
+ * Classe : SwipeDetector
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Permet de détecter si l'utilisateur a effectué un Swipe, en se basant sur
+ * des règles appliquées à la positions des noeuds dans le temps.
+ */
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -10,8 +22,11 @@
     {
         public enum Direction {LEFT, RIGHT, TOP, DOWN};
 
-        public SwipeDetector() : base()
+        Debug.DebugWindow debug;
+
+        public SwipeDetector(Debug.DebugWindow _d) : base()
         {
+            debug = _d;
             gesturePeriod = (float)0.5;
             indexesPerSecond = 30;
             indexesToCheck = (int)(gesturePeriod * indexesPerSecond);
@@ -28,57 +43,150 @@
         public bool CheckForSwipeLeft()
         {
             //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
-            //List<Skeleton> history = new List<Skeleton>(history);
-
-            /*for (int i = 0; i < history.Count; i++)
-                System.Console.Out.WriteLine(history[i].Joints.ElementAt(handRightID).Position.X);
-            System.Console.Out.WriteLine("========================");*/
+            List<List<Joint>> localHistory = new List<List<Joint>>(history);
 
             //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
-            if (history.Count < indexesToCheck+1)
+            if (localHistory.Count < indexesToCheck+1)
                 return false;
-            //Console.ReadLine();
-
+            
             //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
-            refDistance = Math.Abs(history[0][spineID].Position.Y - history[0][shoulderCenterID].Position.Y);
+            refDistance = Math.Abs(localHistory[0][spineID].Position.Y - localHistory[0][shoulderCenterID].Position.Y);
             //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
-            startPoint = history[history.Count - indexesToCheck][handRightID].Position;
+            startPoint = localHistory[localHistory.Count - indexesToCheck][handRightID].Position;
 
             //De la position p1 à pn, on suit l'algorithme.
-            Console.Out.WriteLine("=================================");
-            for (int i = history.Count - indexesToCheck + 1; i < history.Count; i++)
+            for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++)
             {
-                System.Console.Out.WriteLine("hand:head " + history[i][handRightID].Position.Y + " <= " + history[i][headID].Position.Y + " && "
-                + "hand:hip " + history[i][handRightID].Position.Y + " >= " + history[i][hipCenterID].Position.Y + " && "
-                + "handX:handX-1 " + history[i][handRightID].Position.X + " <= " + history[i - 1][handRightID].Position.X + " && "
-                + "hand0:handN " + Math.Abs(history[i][handRightID].Position.Y - startPoint.Y) + " <= " + refDistance / 2);
+                //Debug temporaire pour vérifier la validité de certaines contraintes durant la gesture.
+               /*if (localHistory[i][handRightID].Position.Y > localHistory[i][headID].Position.Y)
+                    debug.R1.Fill = System.Windows.Media.Brushes.Blue;
+                else
+                    debug.R1.Fill = System.Windows.Media.Brushes.DarkGray;
+
+                if(localHistory[i][handRightID].Position.Y < localHistory[i][hipCenterID].Position.Y)
+                    debug.R2.Fill = System.Windows.Media.Brushes.Blue;
+                else
+                    debug.R2.Fill = System.Windows.Media.Brushes.DarkGray;
 
-                //Si la position Y de la main est supérieure à celle de l'épaule
-                //OU si la position Y de la main est inférieure à celle de la hanche
+                if(localHistory[i][handRightID].Position.X < localHistory[i - 1][handRightID].Position.X)
+                    debug.R3.Fill = System.Windows.Media.Brushes.Blue;
+                else
+                    debug.R3.Fill = System.Windows.Media.Brushes.DarkGray;
+
+                if(Math.Abs(localHistory[i][handRightID].Position.Y - startPoint.Y) < refDistance/2)
+                    debug.R4.Fill = System.Windows.Media.Brushes.Blue;
+                else
+                    debug.R4.Fill = System.Windows.Media.Brushes.DarkGray;*/
+
+                //Si la position Y de la main est plus haute que la tête
+                //OU si la position Y de la main est plus basse que la hanche
                 //OU si la nouvelle position X de la main est à droite de la précédente
                 //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
                 //Alors on retourne faux.
-                if (history[i][handRightID].Position.Y > history[i][headID].Position.Y ||
-                history[i][handRightID].Position.Y < history[i][hipCenterID].Position.Y ||
-                history[i][handRightID].Position.X > history[i - 1][handRightID].Position.X ||
-                Math.Abs(history[i][handRightID].Position.Y - startPoint.Y) > refDistance/2)
+                if (localHistory[i][handRightID].Position.Y < localHistory[i][headID].Position.Y ||
+                localHistory[i][handRightID].Position.Y > localHistory[i][hipCenterID].Position.Y ||
+                localHistory[i][handRightID].Position.X > localHistory[i - 1][handRightID].Position.X ||
+                Math.Abs(localHistory[i][handRightID].Position.Y - startPoint.Y) > refDistance/2)
                     return false;
             }
-            Console.Out.WriteLine("=================================");
-            Console.ReadLine();
+
             //Si la distance horizontale du geste a été plus courte que la distance N
             //Alors on retourne faux.
-            float dist = (history[history.Count - 1][handRightID].Position.X - history[history.Count - indexesToCheck][handRightID].Position.X);
+            //float dist = (localHistory[localHistory.Count - 1][handRightID].Position.X - localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X);
             
-            //System.Console.Out.WriteLine(history[0].Joints.ElementAt(handRightID).Position.X + " " + history[1].Joints.ElementAt(handRightID).Position.X + " " + history[2].Joints.ElementAt(handRightID).Position.X);
-            //System.Console.Out.WriteLine(history[0].Joints.ElementAt(handRightID).Position.X + " " + history[1].Joints.ElementAt(handRightID).Position.X + " " + history[2].Joints.ElementAt(handRightID).Position.X);
-            System.Console.Out.WriteLine(Math.Abs(history[0][handRightID].Position.X - history[history.Count - indexesToCheck][handRightID].Position.X) + " < " + refDistance*1.5);
-            if (Math.Abs(history[0][handRightID].Position.X - history[history.Count - indexesToCheck][handRightID].Position.X) < refDistance*1.5)
+            if (Math.Abs(localHistory[0][handRightID].Position.X - localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X) < refDistance/2)
+                return false;
+
+            //Si la dernière position de la main droite est sur le côté droit du corps
+            //OU si la première position calculée de la main droite est sur le côté gauche du corps
+            //Alors on retourne faux.
+            if(localHistory[localHistory.Count - 1][handRightID].Position.X > localHistory[localHistory.Count - 1][hipCenterID].Position.X ||
+               localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X < localHistory[localHistory.Count - 1][hipCenterID].Position.X)
+                return false;
+
+            //System.Console.Out.WriteLine(Math.Abs(localHistory[0][handRightID].Position.X - localHistory[localHistory.Count - indexesToCheck][handRightID].Position.X) + " < " + refDistance/2);
+            //On supprime l'historique local.
+            localHistory.Clear();
+            //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe left ont été remplies.
+            return true;
+        }
+
+        /*
+         * Lit les noeuds de l'historique du squelette afin de détecter un Swipe right.
+         * Règles :
+         * Se fait avec la main gauche.
+         * Chaque nouvelle position de la main doit être à la droite de la précédente.
+         * Chaque nouvelle position de la main ne doit pas s'éloigner verticalement de plus d'une certaine distance.
+         * Le geste doit mesurer horizontalement une certaine distance.
+         */
+        public bool CheckForSwipeRight()
+        {
+            //Crée un historique de squelette local, puisque l'historique est mis à jour toutes les ~1/30 s.
+            List<List<Joint>> localHistory = new List<List<Joint>>(history);
+
+            //Si il n'y a pas assez de positions dans l'historique local pour vérifier le geste.
+            if (localHistory.Count < indexesToCheck + 1)
                 return false;
 
-            history.Clear();
-            Console.Out.WriteLine("SWIPE LEF");
-            Console.ReadLine();
+            //La distance de référence est ici la distance entre le milieu du dos et le milieu des épaules.
+            refDistance = Math.Abs(localHistory[0][spineID].Position.Y - localHistory[0][shoulderCenterID].Position.Y);
+            //On commence la position pour les indexesToCheck dernières postures (celle à l'index 0 étant la dernière).
+            startPoint = localHistory[localHistory.Count - indexesToCheck][handLeftID].Position;
+
+            //De la position p1 à pn, on suit l'algorithme.
+            for (int i = localHistory.Count - indexesToCheck + 1; i < localHistory.Count; i++)
+            {
+                //Debug temporaire pour vérifier la validité de certaines contraintes durant la gesture.
+                /*if (localHistory[i][handLeftID].Position.Y > localHistory[i][headID].Position.Y)
+                    debug.R1.Fill = System.Windows.Media.Brushes.Cyan;
+                else
+                    debug.R1.Fill = System.Windows.Media.Brushes.DarkGray;
+
+                if (localHistory[i][handLeftID].Position.Y < localHistory[i][hipCenterID].Position.Y)
+                    debug.R2.Fill = System.Windows.Media.Brushes.Cyan;
+                else
+                    debug.R2.Fill = System.Windows.Media.Brushes.DarkGray;
+
+                if (localHistory[i][handLeftID].Position.X > localHistory[i - 1][handLeftID].Position.X)
+                    debug.R3.Fill = System.Windows.Media.Brushes.Cyan;
+                else
+                    debug.R3.Fill = System.Windows.Media.Brushes.DarkGray;
+
+                if (Math.Abs(localHistory[i][handLeftID].Position.Y - startPoint.Y) < refDistance / 2)
+                    debug.R4.Fill = System.Windows.Media.Brushes.Cyan;
+                else
+                    debug.R4.Fill = System.Windows.Media.Brushes.DarkGray;*/
+
+                //Si la position Y de la main est plus haute que la tête
+                //OU si la position Y de la main est plus basse que la hanche
+                //OU si la nouvelle position X de la main est à gauche de la précédente
+                //OU si la nouvelle position Y de la main est plus éloignée de la distance N par rapport à la première position Y
+                //Alors on retourne faux.
+                if (localHistory[i][handLeftID].Position.Y < localHistory[i][headID].Position.Y ||
+                localHistory[i][handLeftID].Position.Y > localHistory[i][hipCenterID].Position.Y ||
+                localHistory[i][handLeftID].Position.X < localHistory[i - 1][handLeftID].Position.X ||
+                Math.Abs(localHistory[i][handLeftID].Position.Y - startPoint.Y) > refDistance / 2)
+                    return false;
+            }
+
+            //Si la distance horizontale du geste a été plus courte que la distance N
+            //Alors on retourne faux.
+            //float dist = (localHistory[localHistory.Count - 1][handLeftID].Position.X - localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.X);
+
+            if (Math.Abs(localHistory[0][handLeftID].Position.X - localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.X) < refDistance / 2)
+                return false;
+
+            //Si la dernière position de la main droite est sur le côté gauche du corps
+            //OU si la première position calculée de la main droite est sur le côté droit du corps
+            //Alors on retourne faux.
+            if (localHistory[localHistory.Count - 1][handLeftID].Position.X < localHistory[localHistory.Count - 1][hipCenterID].Position.X ||
+               localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.X > localHistory[localHistory.Count - 1][hipCenterID].Position.X)
+                return false;
+
+            //System.Console.Out.WriteLine(Math.Abs(localHistory[0][handLeftID].Position.X - localHistory[localHistory.Count - indexesToCheck][handLeftID].Position.X) + " < " + refDistance / 2);
+            //On supprime l'historique local.
+            localHistory.Clear();
+            //Si on est arrivé jusqu'ici, toutes les conditions pour un swipe right ont été remplies.
             return true;
         }
     }
--- a/middleware/src/Tracking/KinectMain.cs	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Tracking/KinectMain.cs	Thu Mar 15 13:33:21 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Projet : KINECT PROJECTS
+ * Projet : TraKERS
  * Module : MIDDLEWARE
  * Sous-Module : Tracking
  * Classe : KinectMain
@@ -40,7 +40,8 @@
 using Trakers.Tracking.Gestures;
 using Trakers.Tracking.Events;
 using System.Configuration;
-using Kinect.Toolbox;
+using System.Resources;
+using System.Reflection;
 
 namespace Trakers.Tracking
 {
@@ -49,11 +50,17 @@
     public delegate void RightHandTrackedHandler(object o, RightHandTrackedEventArgs e);
     public delegate void LeftHandQuitHandler(object o, LeftHandQuitEventArgs e);
     public delegate void RightHandQuitHandler(object o, RightHandQuitEventArgs e);
-    //Il s'agit des fonctions permettant d'appeler les fonctions des événements Swipe left/right/up/down.
+    //Il s'agit de la fonction permettant d'appeler les fonctions des événements Swipe left/right/up/down.
     public delegate void SwipeHandler(object o, SwipeEventArgs e);
+    //Il s'agit de la fonction permettant d'appeler les fonctions des événements Push/Pull.
+    public delegate void PushHandler(object o, PushEventArgs e);
+    //Il s'agit de la fonction permettant d'appeler les fonctions des événements Jump.
+    public delegate void JumpHandler(object o, JumpEventArgs e);
 
     public class KinectMain
     {
+        //Gestionnaire de ressources.
+        private ResourceManager rm;
         //Fenêtre de debug.
         private Debug.DebugWindow debug;
         //Squelettes (Il y en a 6 par défaut).
@@ -61,13 +68,20 @@
         //Caméra infrarouge (sensor) de la Kinect.
         private KinectSensor kinectSensor;
 
-        //Détecteur de gestes.
+        //Détecteur de swipes.
         private SwipeDetector swipeDetector;
+        //Détecteur de pushes.
+        private PushDetector pushDetector;
+        //Détecteur de jumps.
+        private JumpDetector jumpDetector;
 
         //Distances min/max délimitant le champ de recherche.
         private float minDistHands;
         private float maxDistHands;
 
+        //Temps de rafraichissement pour le timer (Détection de gesture dans le serveur TUIO).
+        private int timerElapsing;
+
         //Serveur TUIO pour la connexion du Middleware vers le Front Atelier.
         private Server server;
 
@@ -76,15 +90,22 @@
         public static event RightHandTrackedHandler RightHandTrackedEvent;
         public static event LeftHandQuitHandler LeftHandQuitEvent;
         public static event RightHandQuitHandler RightHandQuitEvent;
-        //Les événements swipe.
+        //L'événement swipe.
         public static event SwipeHandler SwipeEvent;
+        //L'événement push.
+        public static event PushHandler PushEvent;
+        //L'événement jump.
+        public static event JumpHandler JumpEvent;
             
         //Voici les ID des noeuds d'un squelette.
-        private int hipCenterID = 0, spineID = 1, shoulderCenterID = 2, headID = 3;
-        private int shoulderLeftID = 4, elbowLeftID = 5, wristLeftID = 6, handLeftID = 7;
-        private int shoulderRightID = 8, elbowRightID = 9, wristRightID = 10, handRightID = 11;
-        private int hipLeftID = 12, kneeLeftID = 13, ankleLeftID = 14, footLeftID = 15;
-        private int hipRightID = 16, kneeRightID = 17, ankleRightID = 18, footRightID = 19;
+        public int hipCenterID = 0, spineID = 1, shoulderCenterID = 2, headID = 3;
+        public int shoulderLeftID = 4, elbowLeftID = 5, wristLeftID = 6, handLeftID = 7;
+        public int shoulderRightID = 8, elbowRightID = 9, wristRightID = 10, handRightID = 11;
+        public int hipLeftID = 12, kneeLeftID = 13, ankleLeftID = 14, footLeftID = 15;
+        public int hipRightID = 16, kneeRightID = 17, ankleRightID = 18, footRightID = 19;
+        
+        private string connexionHost;
+        private int connexionPort;
 
         /*
         *  Initialisation de la classe principale.
@@ -93,27 +114,28 @@
         */
         public KinectMain()
         {
+            //Si on n'a pas fait appel au gestionnaire de ressources avant, on le fait là.
+            if(rm == null)
+                rm = new ResourceManager("Trakers.Properties.resources", Assembly.GetExecutingAssembly());
             //On crée la fenêtre de debug.
             debug = new Debug.DebugWindow(this);
             
-            //On crée le détecteur de gestes.
-            swipeDetector = new SwipeDetector();
+            //On crée les détecteurs de gestes.
+            swipeDetector = new SwipeDetector(debug);
+            pushDetector = new PushDetector(debug);
+            jumpDetector = new JumpDetector(debug);
 
             //On tente de charger les paramètres du fichier params.ini.
             //Si on n'y arrive pas, on affiche une erreur et on charge les paramètres par défaut.
             if (!loadParameters())
             {
-                debug.ExceptionLbl.Content = "Impossible de charger les paramètres. Paramètres par défaut.";
+                debug.ExceptionLbl.Content = rm.GetString("loadParametersFail");
                 //Distances de détection des mains par défaut pour la recherche (ici de 1m à 2m de la Kinect).
                 minDistHands = (float)1.0;
                 maxDistHands = (float)1.5;
-            }
-            else if (maxDistHands <= 0 || minDistHands <= 0 || maxDistHands > 4 || minDistHands > 4 || minDistHands >= maxDistHands)
-            {
-                debug.ExceptionLbl.Content = "Paramètres incorrects. Paramètres par défaut.";
-                //Distances de détection des mains par défaut pour la recherche (ici de 1m à 2m de la Kinect).
-                minDistHands = (float)1.0;
-                maxDistHands = (float)1.5;
+                connexionHost = "127.0.0.1";
+                connexionPort = 80;
+                timerElapsing = 1000;
             }
 
             //On affiche la fenêtre de debug.
@@ -125,6 +147,14 @@
         }
 
         /*
+        *  Initialisation de la classe principale avec comme argument le gestionnaire de ressources.
+        */
+        public KinectMain(ResourceManager _rm) : this()
+        {
+            rm = _rm;
+        }
+
+        /*
         *  Initialisation du sensor de la Kinect.
         */
         public void KinectInitialization()
@@ -143,13 +173,21 @@
                 //Quand le Middleware reçoit des trames de la Kinect, on va dans cette fonction.
                 kinectSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(AllFramesReady);
 
+                //On applique des paramètres d'ajustement pour le squelette.
+                TransformSmoothParameters parameters = new TransformSmoothParameters();
+                parameters.Smoothing = 0.2f;
+                parameters.Correction = 0.8f;
+                parameters.Prediction = 0.0f;
+                parameters.JitterRadius = 0.5f;
+                parameters.MaxDeviationRadius = 0.5f;
+                kinectSensor.SkeletonStream.Enable(parameters);
                 //On démarre la Kinect.
                 kinectSensor.Start();
                 debug.ExceptionLbl.Content = "";
             }
             catch (System.Exception)
             {
-                debug.ExceptionLbl.Content = "Kinect non connectée.";
+                debug.ExceptionLbl.Content = rm.GetString("KinectNotConnected");
             }
 
             //Pour les événements main gauche/droite entre dans/quitte le champ, on a 4 listeners.
@@ -169,12 +207,20 @@
             RightHandQuitListener rightHandQuitListener = new RightHandQuitListener();
             RightHandQuitEvent += new RightHandQuitHandler(rightHandQuitListener.ShowOnScreen);
 
-            //Fonction appelée lorsque l'utilisateur effectue un swipe right.
-            SwipeEventListener swipeListener = new SwipeEventListener();
+            //Fonction appelée lorsque l'utilisateur effectue un Swipe right/left/up/down.
+            SwipeListener swipeListener = new SwipeListener();
             SwipeEvent += new SwipeHandler(swipeListener.ShowOnScreen);
 
+            //Fonction appelée lorsque l'utilisateur effectue un Push/Pull.
+            PushListener pushListener = new PushListener();
+            PushEvent += new PushHandler(pushListener.ShowOnScreen);
+
+            //Fonction appelée lorsque l'utilisateur effectue un Jump.
+            JumpListener jumpListener = new JumpListener();
+            JumpEvent += new JumpHandler(jumpListener.ShowOnScreen);
+
             //On connecte le serveur à l'adresse locale sur le port 80.
-            server = new Server("127.0.0.1", 80);
+            server = new Server(connexionHost, connexionPort, timerElapsing);
         }
 
         /*
@@ -193,14 +239,14 @@
             }
             catch (System.Exception)
             {
-                debug.ExceptionLbl.Content = "Kinect non connectée.";
+                debug.ExceptionLbl.Content = rm.GetString("KinectNotConnected");
             }
         }
 
         /*
         *  Récupère le premier squelette.
         */
-        Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
+        Skeleton GetFirstSkeleton(object sender, AllFramesReadyEventArgs e)
         {
             using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
             {
@@ -220,7 +266,7 @@
         /*
         *  Récupère le squelette le plus proche.
         */
-        Skeleton GetNearestSkeleton(AllFramesReadyEventArgs e)
+        Skeleton GetNearestSkeleton(object sender, AllFramesReadyEventArgs e)
         {
             using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
             {
@@ -275,11 +321,11 @@
             //On récupère le premier squelette tracké.
             //Skeleton first = GetFirstSkeleton(e);
             //On récupère le plus proche squelette tracké.
-            Skeleton first = GetNearestSkeleton(e);
+            Skeleton first = GetNearestSkeleton(sender, e);
             //Si celui-ci n’est pas nul
             if (first == null)
                 return;
-
+            
             //Si ce squelette est tracké (donc suivi et reconnu par la camera)
             if (first.TrackingState == SkeletonTrackingState.Tracked)
             {
@@ -291,33 +337,30 @@
                 Joint hipRight = getJoint(first, hipRightID), kneeRight = getJoint(first, kneeRightID), ankleRight = getJoint(first, ankleRightID), footRight = getJoint(first, footRightID);
 
                 //On construit l'historique des postures.
-                /*List<Joint> joints = new List<Joint>();
+                List<Joint> joints = new List<Joint>();
                 joints.Clear();
-                joints.Add(footRight);
-                joints.Add(ankleRight);
-                joints.Add(kneeRight);
-                joints.Add(hipRight);
-                joints.Add(footLeft);
-                joints.Add(ankleLeft);
-                joints.Add(kneeLeft);
-                joints.Add(hipLeft);
-                joints.Add(handRight);
-                joints.Add(wristRight);
-                joints.Add(elbowRight);
-                joints.Add(shoulderRight);
-                joints.Add(handLeft);
-                joints.Add(wristLeft);
-                joints.Add(elbowLeft);
-                joints.Add(shoulderLeft);
-                joints.Add(head);
-                joints.Add(shoulderCenter);
-                joints.Add(spine);
-                joints.Add(hipCenter);
-                swipeDetector.UpdateSkeletonHistory(joints);*/
-
-                SkeletonDisplayManager sdm = new SkeletonDisplayManager(kinectSensor, debug.DebugCanvas);
-                //sdm.Draw();
-
+                joints.Insert(hipCenterID, hipCenter);
+                joints.Insert(spineID, spine);
+                joints.Insert(shoulderCenterID, shoulderCenter);
+                joints.Insert(headID, head);
+                joints.Insert(shoulderLeftID, shoulderLeft);
+                joints.Insert(elbowLeftID, elbowLeft);
+                joints.Insert(wristLeftID, wristLeft);
+                joints.Insert(handLeftID, handLeft);
+                joints.Insert(shoulderRightID, shoulderRight);
+                joints.Insert(elbowRightID, elbowRight);
+                joints.Insert(wristRightID, wristRight);
+                joints.Insert(handRightID, handRight);
+                joints.Insert(hipLeftID, hipLeft);
+                joints.Insert(kneeLeftID, kneeLeft);
+                joints.Insert(ankleLeftID, ankleLeft);
+                joints.Insert(footLeftID, footLeft);
+                joints.Insert(hipRightID, hipRight);
+                joints.Insert(kneeRightID, kneeRight);
+                joints.Insert(ankleRightID, ankleRight);
+                joints.Insert(footRightID, footRight);
+                GestureDetector.UpdateSkeletonHistory(joints);
+                
                 //On obtient sa distance à la Kinect.
                 float distance = first.Position.Z;
 
@@ -356,10 +399,38 @@
                     OnSwipeEvent(swipeEvent);
                 }
 
+                //Si l'utilisateur effectue un swipe right.
+                if (swipeDetector.CheckForSwipeRight())
+                {
+                    SwipeEventArgs swipeEvent = new SwipeEventArgs(debug, server, SwipeDetector.Direction.RIGHT);
+                    OnSwipeEvent(swipeEvent);
+                }
+
+                //Enum sur la main qui effectue le geste.
+                PushDetector.Hand handPush;
+                //Si l'utilisateur effectue un push.
+                if ((handPush = pushDetector.CheckForPush()) != PushDetector.Hand.NONE)
+                {
+                    PushEventArgs pushEvent = new PushEventArgs(debug, server, PushDetector.Direction.PUSH, handPush);
+                    OnPushEvent(pushEvent);
+                }
+                //Si l'utilisateur effectue un pull.
+                if ((handPush = pushDetector.CheckForPull()) != PushDetector.Hand.NONE)
+                {
+                    PushEventArgs pushEvent = new PushEventArgs(debug, server, PushDetector.Direction.PULL, handPush);
+                    OnPushEvent(pushEvent);
+                }
+
+                //Si l'utilisateur effectue un saut.
+                /*if (jumpDetector.CheckForJump())
+                {
+                    JumpEventArgs jumpEvent = new JumpEventArgs(debug, server);
+                    OnJumpEvent(jumpEvent);
+                }*/
 
                 //Dessine le squelette dans le debug.
-                //debug.drawJoints(first.Joints, first);
-                //debug.showSkeleton(hipCenter, spine, shoulderCenter, head, shoulderLeft, elbowLeft, wristLeft, handLeft, shoulderRight, elbowRight, wristRight, handRight, hipLeft, kneeLeft, ankleLeft, footLeft, hipRight, kneeRight, ankleRight, footRight);
+                debug.drawJoints(first.Joints, first);
+                debug.showSkeleton(hipCenter, spine, shoulderCenter, head, shoulderLeft, elbowLeft, wristLeft, handLeft, shoulderRight, elbowRight, wristRight, handRight, hipLeft, kneeLeft, ankleLeft, footLeft, hipRight, kneeRight, ankleRight, footRight);
             }
         }
 
@@ -417,22 +488,22 @@
         }
 
         /*
-        *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un swipe up.
+        *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un push.
         */
-        /*public static void OnSwipeUpEvent(SwipeUpEventArgs e)
+        public static void OnPushEvent(PushEventArgs e)
         {
-            if (SwipeUpEvent != null)
-                SwipeUpEvent(new object(), e);
-        }*/
+            if (PushEvent != null)
+                PushEvent(new object(), e);
+        }
 
         /*
-        *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un swipe down.
+        *  Initialise l'événement et fait appel aux fonctions du listener quand l'utilisateur effectue un saut.
         */
-        /*public static void OnSwipeDownEvent(SwipeDownEventArgs e)
+        public static void OnJumpEvent(JumpEventArgs e)
         {
-            if (SwipeDownEvent != null)
-                SwipeDownEvent(new object(), e);
-        }*/
+            if (JumpEvent != null)
+                JumpEvent(new object(), e);
+        }
 
         /*
         *  Méthode de chargement des paramètres (position du champ de recherche...).
@@ -441,14 +512,42 @@
         {
             try
             {
-                minDistHands = float.Parse(ConfigurationManager.AppSettings["searchMinDistance"]);
-                maxDistHands = float.Parse(ConfigurationManager.AppSettings["searchMaxDistance"]);
+                minDistHands = (float)double.Parse(ConfigurationManager.AppSettings["searchMinDistance"]);
+                maxDistHands = (float)double.Parse(ConfigurationManager.AppSettings["searchMaxDistance"]);
+                connexionHost = ConfigurationManager.AppSettings["connexionHost"];
+                connexionPort = int.Parse(ConfigurationManager.AppSettings["connexionPort"]);
+                hipCenterID = int.Parse(ConfigurationManager.AppSettings["hipCenterID"]);
+                spineID = int.Parse(ConfigurationManager.AppSettings["spineID"]);
+                shoulderCenterID = int.Parse(ConfigurationManager.AppSettings["shoulderCenterID"]);
+                headID = int.Parse(ConfigurationManager.AppSettings["headID"]);
+                shoulderLeftID = int.Parse(ConfigurationManager.AppSettings["shoulderLeftID"]);
+                elbowLeftID = int.Parse(ConfigurationManager.AppSettings["elbowLeftID"]);
+                wristLeftID = int.Parse(ConfigurationManager.AppSettings["wristLeftID"]);
+                handLeftID = int.Parse(ConfigurationManager.AppSettings["handLeftID"]);
+                shoulderRightID = int.Parse(ConfigurationManager.AppSettings["shoulderRightID"]);
+                elbowRightID = int.Parse(ConfigurationManager.AppSettings["elbowRightID"]);
+                wristRightID = int.Parse(ConfigurationManager.AppSettings["wristRightID"]);
+                handRightID = int.Parse(ConfigurationManager.AppSettings["handRightID"]);
+                hipLeftID = int.Parse(ConfigurationManager.AppSettings["hipLeftID"]);
+                kneeLeftID = int.Parse(ConfigurationManager.AppSettings["kneeLeftID"]);
+                ankleLeftID = int.Parse(ConfigurationManager.AppSettings["ankleLeftID"]);
+                footLeftID = int.Parse(ConfigurationManager.AppSettings["footLeftID"]);
+                hipRightID = int.Parse(ConfigurationManager.AppSettings["hipRightID"]);
+                kneeRightID = int.Parse(ConfigurationManager.AppSettings["kneeRightID"]);
+                ankleRightID = int.Parse(ConfigurationManager.AppSettings["ankleRightID"]);
+                footRightID = int.Parse(ConfigurationManager.AppSettings["footRightID"]);
+                timerElapsing = int.Parse(ConfigurationManager.AppSettings["timerElapsing"]);
             }
             catch (Exception)
             {
                 return false;
             }
-
+            
+            if (maxDistHands <= 0 || minDistHands <= 0 || maxDistHands > 4 || minDistHands > 4 || minDistHands >= maxDistHands)
+            {
+                debug.ExceptionLbl.Content = rm.GetString("loadParametersIncorrect");
+                return false;
+            }
             return true;
         }
     }
--- a/middleware/src/Trakers.csproj	Fri Mar 09 18:15:12 2012 +0100
+++ b/middleware/src/Trakers.csproj	Thu Mar 15 13:33:21 2012 +0100
@@ -52,9 +52,6 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\lib\Coding4Fun.Kinect.Wpf.dll</HintPath>
     </Reference>
-    <Reference Include="Kinect.Toolbox">
-      <HintPath>..\lib\Kinect.Toolbox.dll</HintPath>
-    </Reference>
     <Reference Include="Microsoft.Kinect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\lib\Microsoft.Kinect.dll</HintPath>
@@ -91,15 +88,22 @@
       <AutoGen>True</AutoGen>
       <DesignTime>True</DesignTime>
       <DependentUpon>Resources.resx</DependentUpon>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Compile>
     <Compile Include="Properties\Settings.Designer.cs">
       <AutoGen>True</AutoGen>
       <DependentUpon>Settings.settings</DependentUpon>
       <DesignTimeSharedInput>True</DesignTimeSharedInput>
     </Compile>
-    <Compile Include="Tracking\Events\SwipeEventListener.cs" />
+    <Compile Include="Tracking\Events\JumpEventArgs.cs" />
+    <Compile Include="Tracking\Events\JumpListener.cs" />
+    <Compile Include="Tracking\Events\PushEventArgs.cs" />
+    <Compile Include="Tracking\Events\PushListener.cs" />
+    <Compile Include="Tracking\Events\SwipeListener.cs" />
     <Compile Include="Tracking\Events\SwipeEventArgs.cs" />
     <Compile Include="Tracking\Gestures\GestureDetector.cs" />
+    <Compile Include="Tracking\Gestures\JumpDetector.cs" />
+    <Compile Include="Tracking\Gestures\PushDetector.cs" />
     <Compile Include="Tracking\Gestures\SwipeDetector.cs" />
     <Compile Include="Tracking\KinectMain.cs" />
     <Compile Include="Tracking\Events\LeftHandQuitEventArgs.cs" />
@@ -121,6 +125,7 @@
     <EmbeddedResource Include="Properties\Resources.resx">
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </EmbeddedResource>
     <None Include="App.config" />
     <None Include="Properties\Settings.settings">