View Javadoc

1   /**
2    * 
3    */
4   package org.ximtec.igesture.io.tuio;
5   
6   import java.awt.Color;
7   import java.awt.Dimension;
8   import java.util.HashSet;
9   import java.util.Hashtable;
10  import java.util.List;
11  import java.util.Set;
12  
13  import javax.swing.BorderFactory;
14  
15  import org.ximtec.igesture.Recogniser;
16  import org.ximtec.igesture.core.Gesture;
17  import org.ximtec.igesture.core.GestureSample3D;
18  import org.ximtec.igesture.io.AbstractGestureDevice;
19  import org.ximtec.igesture.io.tuio.interfaces.AbstractTuioCursor;
20  import org.ximtec.igesture.io.tuio.interfaces.AbstractTuioObject;
21  import org.ximtec.igesture.io.tuio.tuio3D.TuioCursor3D;
22  import org.ximtec.igesture.io.tuio.tuio3D.TuioObject3D;
23  import org.ximtec.igesture.util.Constant;
24  import org.ximtec.igesture.util.additions3d.AccelerationSample;
25  import org.ximtec.igesture.util.additions3d.Accelerations;
26  import org.ximtec.igesture.util.additions3d.Point3D;
27  import org.ximtec.igesture.util.additions3d.RecordedGesture3D;
28  
29  /**
30   * Reader that initializes the TuioConnection and handles the events caused by the TuioConnection. There are three ways to use the TuioReader.
31   * 1) Manually
32   * After performing the gesture, you can get the gesture with getGesture() and do the recognition.
33   * 2) GestureEventListener interface
34   * Register with the TuioReader as a GestureEventListener, it will notify you when a gesture was performed. The recognition of the performed
35   * gesture can then be done.
36   * 3) Configure the TuioReader with a Recogniser
37   * When a gesture was performed, the recogniser will automatically try to recognise the gesture and notify GestureHandlers.
38   *  
39   * General steps to use:
40   * 	1. create the TuioReader
41   * 	2. connect to a tuio service
42   *  3. In case of GestureEventListener : register as a listener
43   *     In case of Recogniser : set this TuioReaders recogniser
44   *  
45   * @author Bjorn Puype, bpuype@gmail.com
46   * @see TuioConnection
47   */
48  public class TuioReader3D extends AbstractGestureDevice<RecordedGesture3D, Point3D> implements ITuioReader{
49  	
50  	/** List of RecordedGesture3D (3D gestures) */
51  	private Hashtable<Long,RecordedGesture3D> gestures = new Hashtable<Long,RecordedGesture3D>();
52  	
53  	/** List of AbstractTuioObject */
54  	private Hashtable<Long,AbstractTuioObject> objectList = new Hashtable<Long,AbstractTuioObject>();
55  	/** List of AbstractTuioCursor */
56  	private Hashtable<Long,AbstractTuioCursor> cursorList = new Hashtable<Long,AbstractTuioCursor>();
57  	
58  	/** TUIO Connection used */
59  	private TuioConnection connection;
60  	
61  	/** Recogniser to recognise the gestures */
62  	private Recogniser recogniser;
63  	
64  	private boolean debug = false;
65  
66  	private GestureSample3D gesture3D;
67  	private RecordedGesture3D lastRecordedGesture3DAdded;
68  	
69  	/**
70  	 * Default Constructor
71  	 */
72  	public TuioReader3D()
73  	{
74  		this(new Integer(TuioConstants.DEFAULT_PORT));
75  	}
76  	
77  	/**
78  	 * Constructor
79  	 * @param port	Port to listen to.
80  	 */
81  	public TuioReader3D(Integer port)
82  	{
83  		//customize TuioProcessor with portnumber
84  		// 			more than one tuioserver can connect and send information
85  	
86  		connection = new TuioConnection(port.intValue());
87  		
88  		setDeviceID(String.valueOf(port));
89  		setConnectionType(Constant.CONNECTION_TUIO);
90  		setDeviceType(Constant.TYPE_3D);
91  		setName("Tuio Service on Port "+port);
92  		
93  		lastRecordedGesture3DAdded = new RecordedGesture3D();
94  		gesture3D = new GestureSample3D(this,"", lastRecordedGesture3DAdded);
95  	}
96  	
97  	/**
98  	 * Set the recogniser to use.
99  	 * @param recogniser	Recogniser to use.
100 	 */
101 	public void setRecogniser(Recogniser recogniser)
102 	{
103 		this.recogniser = recogniser;
104 	}
105 	
106 	private void debug(String message)
107 	{
108 		if(debug)
109 			System.out.println("[TUIO]: "+message);
110 	}
111 	
112 	/* (non-Javadoc)
113 	 * @see org.ximtec.igesture.io.AbstractGestureDevice#connect()
114 	 */
115 	@Override
116 	public void connect() {
117 		connection.connect();
118 		setIsConnected(connection.isConnected());
119 		
120 		Set<String> list = new HashSet<String>();
121 		list.add(TuioConstants.TUIO_CURSOR_3D);
122 		list.add(TuioConstants.TUIO_OBJECT_3D);
123 		addTuioMessages(list);
124 	}
125 
126 	/* (non-Javadoc)
127 	 * @see org.ximtec.igesture.io.AbstractGestureDevice#disconnect()
128 	 */
129 	@Override
130 	public void disconnect() {
131 		connection.disconnect();
132 		setIsConnected(connection.isConnected());
133 	}
134 
135 	/* (non-Javadoc)
136 	 * @see org.ximtec.igesture.io.GestureDevice#clear()
137 	 */
138 	@Override
139 	public void clear() {
140 		lastRecordedGesture3DAdded = new RecordedGesture3D();
141 		gesture3D = new GestureSample3D(this,"",lastRecordedGesture3DAdded);
142 		fireGestureEvent(gesture3D);
143 	}
144 
145 	/* (non-Javadoc)
146 	 * @see org.ximtec.igesture.io.GestureDevice#dispose()
147 	 */
148 	@Override
149 	public void dispose() {
150 		removeAllListener();
151 		lastRecordedGesture3DAdded = new RecordedGesture3D();
152 		gesture3D = new GestureSample3D(this,"",lastRecordedGesture3DAdded);
153 	}
154 
155 	/* (non-Javadoc)
156 	 * @see org.ximtec.igesture.io.GestureDevice#getChunks()
157 	 */
158 	@Override
159 	public List<Point3D> getChunks() {
160 		return null;
161 	}
162 
163 	/* (non-Javadoc)
164 	 * @see org.ximtec.igesture.io.GestureDevice#getGesture()
165 	 */
166 	@Override
167 	public Gesture<RecordedGesture3D> getGesture() {
168 		return new GestureSample3D(this,gesture3D.getName(),lastRecordedGesture3DAdded);
169 	}
170 
171 	/* (non-Javadoc)
172 	 * @see org.ximtec.igesture.io.GestureDevice#init()
173 	 */
174 	@Override
175 	public void init() {
176 	}
177 
178 	/**
179 	 * Set-up the processor to listen for and act on messages of the desired profiles.
180 	 * @param	modifiers	the desired TUIO profiles	
181 	 */
182 	private void addTuioMessages(Set<String> modifiers) {
183 		connection.addTuioListener(this, modifiers);
184 	}
185 	
186 	/**
187 	 * Stop the processor of listening for and act on messages of the desired profiles.
188 	 * @param	modifiers	the desired TUIO profiles
189 	 */
190 	private void removeTuioMessages(Set<String> modifiers) {
191 		connection.removeTuioListener(this, modifiers);
192 	}
193 	
194 	/**
195 	 * Create a AccelerationSample
196 	 * @param xs	X speed
197 	 * @param ys	Y speed
198 	 * @param zs	Z speed
199 	 * @param ms	motion speed
200 	 * @param macc	motion acceleration
201 	 * @param time	timestamp
202 	 * @return
203 	 */
204 	private AccelerationSample createAccelerationSample(double xs, double ys, double zs, double ms, double macc, long time)
205 	{
206 		double dt = ms/macc;
207 		AccelerationSample sample = new AccelerationSample(xs/dt,ys/dt,zs/dt,time);
208 		return sample;
209 	}
210 	
211 	/* (non-Javadoc)
212 	 * @see org.ximtec.igesture.io.tuio.TuioListener#addTuioCursor(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioCursor)
213 	 */
214 	@Override
215 	public void addTuioCursor(AbstractTuioCursor atcur) {
216 		TuioCursor3D tcur = (TuioCursor3D)atcur;
217 		if (!cursorList.containsKey(tcur.getSessionID())) 
218 		{
219 			cursorList.put(tcur.getSessionID(), tcur);
220 			
221 			//TODO
222 			//calculate timestamp
223 			long time = tcur.getTuioTime().add(tcur.getStartTime()).getTotalMilliseconds();
224 			//OR
225 			//long time = tcur.getTuioTime().getTotalMilliseconds();
226 			
227 			//create new recordedgesture3D and add first point to it
228 			RecordedGesture3D gesture = new RecordedGesture3D();
229 			Point3D point = new Point3D(tcur.getX(),tcur.getY(),tcur.getZ(),time);
230 			gesture.add(point);
231 			
232 			//create accelerations and an acceleration sample
233 			Accelerations accelerations = new Accelerations();
234 			AccelerationSample sample = createAccelerationSample(tcur.getXSpeed(),tcur.getYSpeed(),tcur.getZSpeed(),tcur.getMotionSpeed(),tcur.getMotionSpeed(),time);
235 			//add sample to accelerations
236 			accelerations.addSample(sample);
237 			//set the gesture accelerations
238 			gesture.setAccelerations(accelerations);
239 			//save recordedgesture3D
240 			gestures.put(tcur.getSessionID(), gesture);
241 		}	 
242 		debug("add cur "+tcur.getCursorID()+" ("+tcur.getSessionID()+") "+tcur.getX()+" "+tcur.getY()+" "+tcur.getZ());
243 	}
244 
245 	/* (non-Javadoc)
246 	 * @see org.ximtec.igesture.io.tuio.TuioListener#addTuioObject(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioObject)
247 	 */
248 	@Override
249 	public void addTuioObject(AbstractTuioObject atobj) {
250 		TuioObject3D tobj = (TuioObject3D)atobj;
251 		if(!objectList.containsKey(tobj.getSessionID()))
252 		{
253 			objectList.put(tobj.getSessionID(),tobj);
254 			
255 			//TODO
256 			//calculate timestamp
257 			long time = tobj.getTuioTime().add(tobj.getStartTime()).getTotalMilliseconds();
258 			
259 			//create new recordedgesture3D and add first point to it
260 			RecordedGesture3D gesture = new RecordedGesture3D();
261 			Point3D point = new Point3D(tobj.getX(),tobj.getY(),tobj.getZ(),time);
262 			gesture.add(point);
263 			//create accelerations and an acceleration sample
264 			Accelerations accelerations = new Accelerations();
265 			AccelerationSample sample = createAccelerationSample(tobj.getXSpeed(),tobj.getYSpeed(),tobj.getZSpeed(),tobj.getMotionSpeed(),tobj.getMotionAccel(),time);
266 			//add sample to accelerations
267 			accelerations.addSample(sample);
268 			//set the gesture accelerations
269 			gesture.setAccelerations(accelerations);
270 			//save recordedgesture3D
271 			gestures.put(tobj.getSessionID(), gesture);
272 
273 		}
274 		debug("add obj "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getZ());
275 	}
276 
277 	/* (non-Javadoc)
278 	 * @see org.ximtec.igesture.io.tuio.TuioListener#refresh(org.ximtec.igesture.io.tuio.TuioTime)
279 	 */
280 	@Override
281 	public void refresh(TuioTime ftime) {
282 	}
283 
284 	/* (non-Javadoc)
285 	 * @see org.ximtec.igesture.io.tuio.TuioListener#removeTuioCursor(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioCursor)
286 	 */
287 	@Override
288 	public void removeTuioCursor(AbstractTuioCursor atcur) {
289 		TuioCursor3D tcur = (TuioCursor3D)atcur;
290 		cursorList.remove(tcur.getSessionID());	
291 		
292 		lastRecordedGesture3DAdded = gestures.get(tcur.getSessionID());
293 		fireGestureEvent(gesture3D);
294 		if(recogniser != null)
295 		{
296 			//process recordedGesture3D by recognizing it and notifying listeners
297 			recogniser.recognise(new GestureSample3D(this,org.sigtec.util.Constant.EMPTY_STRING, lastRecordedGesture3DAdded),false);
298 					//recogniser automatically performs fireEvent which warns 
299 					//gestureHandlers of new performed gestures
300 		}
301 		
302 		//remove note from the list
303 		gestures.remove(tcur.getSessionID());
304 
305 		debug("del cur "+tcur.getCursorID()+" ("+tcur.getSessionID()+")");
306 	}
307 
308 	/* (non-Javadoc)
309 	 * @see org.ximtec.igesture.io.tuio.TuioListener#removeTuioObject(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioObject)
310 	 */
311 	@Override
312 	public void removeTuioObject(AbstractTuioObject atobj) {
313 		TuioObject3D tobj = (TuioObject3D)atobj;
314 		objectList.remove(tobj.getSessionID());	
315 		
316 		RecordedGesture3D record = gestures.get(tobj.getSessionID());
317 		//if the recorded gesture contains more than one point3D, then the object was used to perform a gesture
318 		//otherwise not, so no recognition is TuioCursor tcur = (TuioCursor)atcur;needed.
319 		if(record.size() > 1)
320 		{
321 			lastRecordedGesture3DAdded = record;
322 			fireGestureEvent(getGesture());
323 			if(recogniser != null)
324 			{
325 				//process recordedGesture3D by recognizing it and notifying listeners
326 				recogniser.recognise(new GestureSample3D(this,org.sigtec.util.Constant.EMPTY_STRING, gestures.get(tobj.getSessionID())),false);
327 						//recogniser automatically performs fireEvent which warns 
328 						//gestureHandlers of new performed gestures
329 			}
330 		}
331 		//remove note from the list
332 		gestures.remove(tobj.getSessionID());
333 		
334 		debug("del obj "+tobj.getSymbolID()+" ("+tobj.getSessionID()+")");
335 	}
336 
337 	/* (non-Javadoc)
338 	 * @see org.ximtec.igesture.io.tuio.TuioListener#updateTuioCursor(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioCursor)
339 	 */
340 	@Override
341 	public void updateTuioCursor(AbstractTuioCursor atcur) {
342 		TuioCursor3D tcur = (TuioCursor3D)atcur;
343 		if(gestures.containsKey(tcur.getSessionID()))
344 		{
345 			//TODO
346 			//calculate timestamp
347 			long time = tcur.getTuioTime().add(tcur.getStartTime()).getTotalMilliseconds();
348 			
349 			//add new point to the corresponding recordedgesture3D
350 			Point3D p = new Point3D(tcur.getX(),tcur.getY(),tcur.getZ(),time);
351 			RecordedGesture3D gesture = gestures.get(tcur.getSessionID());
352 			gesture.add(p);
353 			//add new acceleration sample to the recordedgesture3D's accelerations
354 			AccelerationSample sample = createAccelerationSample(tcur.getXSpeed(),tcur.getYSpeed(),tcur.getZSpeed(),tcur.getMotionSpeed(),tcur.getMotionAccel(),time);
355 			//add sample to accelerations
356 			Accelerations accelerations = gesture.getAccelerations(); 
357 			accelerations.addSample(sample);
358 			
359 			//DEBUG
360 			TuioCursor3D demo = (TuioCursor3D)cursorList.get(tcur.getSessionID());
361 			demo.update(tcur);
362 		}	
363 		debug("set cur "+tcur.getCursorID()+" ("+tcur.getSessionID()+") "+tcur.getX()+" "+tcur.getY()+" "+tcur.getMotionSpeed()+" "+tcur.getMotionAccel());
364 	}
365 
366 	/* (non-Javadoc)
367 	 * @see org.ximtec.igesture.io.tuio.TuioListener#updateTuioObject(org.ximtec.igesture.io.tuio.interfaces.AbstractTuioObject)
368 	 */
369 	@Override
370 	public void updateTuioObject(AbstractTuioObject atobj) {
371 		TuioObject3D tobj = (TuioObject3D)atobj;
372 		if(gestures.containsKey(tobj.getSessionID()))
373 		{
374 			//TODO
375 			//calculate timestamp
376 			long time = tobj.getTuioTime().add(tobj.getStartTime()).getTotalMilliseconds();
377 			
378 			//add new point to the corresponding recordedgesture3D
379 			Point3D p = new Point3D(tobj.getX(),tobj.getY(),tobj.getZ(),time);
380 			RecordedGesture3D gesture = gestures.get(tobj.getSessionID());
381 			gesture.add(p);
382 			//add new acceleration sample to the recordedgesture3D's accelerations
383 			AccelerationSample sample = createAccelerationSample(tobj.getXSpeed(),tobj.getYSpeed(),tobj.getZSpeed(),tobj.getMotionSpeed(),tobj.getMotionAccel(),time);
384 			//add sample to accelerations
385 			Accelerations accelerations = gesture.getAccelerations(); 
386 			accelerations.addSample(sample);
387 			
388 			//DEBUG
389 			TuioObject3D demo = (TuioObject3D)objectList.get(tobj.getSessionID());
390 			demo.update(tobj);
391 		}
392 		debug("set obj "+tobj.getSymbolID()+" ("+tobj.getSessionID()+") "+tobj.getX()+" "+tobj.getY()+" "+tobj.getZ());
393 	}
394 	
395 	@Override
396 	public TuioReaderPanel getPanel()
397 	{
398 		return getPanel(new Dimension(200,200));
399 	}
400 	
401 	@Override
402 	public TuioReaderPanel getPanel(Dimension dimension)
403 	{
404 		TuioReaderPanel panel = new TuioReaderPanel(this,TuioReaderPanel.TYPE_3D);
405 		panel.setSize(dimension);
406 		panel.setPreferredSize(dimension);
407 		panel.setOpaque(true);
408 		panel.setBackground(Color.WHITE);
409 		panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
410 		return panel;
411 	}
412 
413 }