front_processing/extern/TUIO_JAVA/src/TUIO/TuioClient.java
changeset 0 6fefd4afe506
child 3 92f19af39024
equal deleted inserted replaced
-1:000000000000 0:6fefd4afe506
       
     1 /*
       
     2 	TUIO Java backend - part of the reacTIVision project
       
     3 	http://reactivision.sourceforge.net/
       
     4 
       
     5 	Copyright (c) 2005-2009 Martin Kaltenbrunner <mkalten@iua.upf.edu>
       
     6 
       
     7     This program is free software; you can redistribute it and/or modify
       
     8     it under the terms of the GNU General Public License as published by
       
     9     the Free Software Foundation; either version 2 of the License, or
       
    10     (at your option) any later version.
       
    11 
       
    12     This program is distributed in the hope that it will be useful,
       
    13     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15     GNU General Public License for more details.
       
    16 
       
    17     You should have received a copy of the GNU General Public License
       
    18     along with this program; if not, write to the Free Software
       
    19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    20 */
       
    21 package TUIO;
       
    22 
       
    23 import com.illposed.osc.*;
       
    24 import java.util.*;
       
    25 
       
    26 /**
       
    27  * The TuioClient class is the central TUIO protocol decoder component. It provides a simple callback infrastructure using the {@link TuioListener} interface.
       
    28  * In order to receive and decode TUIO messages an instance of TuioClient needs to be created. The TuioClient instance then generates TUIO events
       
    29  * which are broadcasted to all registered classes that implement the {@link TuioListener} interface.<P> 
       
    30  * <code>
       
    31  * TuioClient client = new TuioClient();<br/>
       
    32  * client.addTuioListener(myTuioListener);<br/>
       
    33  * client.connect();<br/>
       
    34  * </code>
       
    35  *
       
    36  * @author Martin Kaltenbrunner
       
    37  * @version 1.4
       
    38  */ 
       
    39 public class TuioClient implements OSCListener {
       
    40 	
       
    41 	private int port = 3333;
       
    42 	private OSCPortIn oscPort;
       
    43 	private boolean connected = false;
       
    44 	private Hashtable<Long,TuioObject> objectList = new Hashtable<Long,TuioObject>();
       
    45 	private Vector<Long> aliveObjectList = new Vector<Long>();
       
    46 	private Vector<Long> newObjectList = new Vector<Long>();
       
    47 	private Hashtable<Long,TuioCursor> cursorList = new Hashtable<Long,TuioCursor>();
       
    48 	private Vector<Long> aliveCursorList = new Vector<Long>();
       
    49 	private Vector<Long> newCursorList = new Vector<Long>();
       
    50 
       
    51 	private Vector<TuioObject> frameObjects = new Vector<TuioObject>();
       
    52 	private Vector<TuioCursor> frameCursors = new Vector<TuioCursor>();
       
    53 
       
    54 	private Vector<TuioCursor> freeCursorList = new Vector<TuioCursor>();
       
    55 	private int maxCursorID = -1;
       
    56 	
       
    57 	private long currentFrame = 0;
       
    58 	private TuioTime currentTime;
       
    59 
       
    60 	private Vector<TuioListener> listenerList = new Vector<TuioListener>();
       
    61 	
       
    62 	/**
       
    63 	 * The default constructor creates a client that listens to the default TUIO port 3333
       
    64 	 */
       
    65 	public TuioClient() {}
       
    66 
       
    67 	/**
       
    68 	 * This constructor creates a client that listens to the provided port
       
    69 	 *
       
    70 	 * @param  port  the listening port number
       
    71 	 */
       
    72 	public TuioClient(int port) {
       
    73 		this.port = port;
       
    74 	}
       
    75 		
       
    76 	/**
       
    77 	 * The TuioClient starts listening to TUIO messages on the configured UDP port
       
    78 	 * All reveived TUIO messages are decoded and the resulting TUIO events are broadcasted to all registered TuioListeners
       
    79 	 */
       
    80 	public void connect() {
       
    81 
       
    82 		TuioTime.initSession();
       
    83 		currentTime = new TuioTime();
       
    84 		currentTime.reset();
       
    85 		
       
    86 		try {
       
    87 			oscPort = new OSCPortIn(port);
       
    88 			oscPort.addListener("/tuio/2Dobj",this);
       
    89 			oscPort.addListener("/tuio/2Dcur",this);
       
    90 			oscPort.startListening();
       
    91 			connected = true;
       
    92 		} catch (Exception e) {
       
    93 			System.out.println("TuioClient: failed to connect to port "+port);
       
    94 			connected = false;
       
    95 		}		
       
    96 	}
       
    97 	
       
    98 	/**
       
    99 	 * The TuioClient stops listening to TUIO messages on the configured UDP port
       
   100 	 */
       
   101 	public void disconnect() {
       
   102 		oscPort.stopListening();
       
   103 		try { Thread.sleep(100); }
       
   104 		catch (Exception e) {};
       
   105 		oscPort.close();
       
   106 		connected = false;
       
   107 	}
       
   108 
       
   109 	/**
       
   110 	 * Returns true if this TuioClient is currently connected.
       
   111 	 * @return	true if this TuioClient is currently connected
       
   112 	 */
       
   113 	public boolean isConnected() { return connected; }
       
   114 
       
   115 	/**
       
   116 	 * Adds the provided TuioListener to the list of registered TUIO event listeners
       
   117 	 *
       
   118 	 * @param  listener  the TuioListener to add
       
   119 	 */
       
   120 	public void addTuioListener(TuioListener listener) {
       
   121 		listenerList.addElement(listener);
       
   122 	}
       
   123 	
       
   124 	/**
       
   125 	 * Removes the provided TuioListener from the list of registered TUIO event listeners
       
   126 	 *
       
   127 	 * @param  listener  the TuioListener to remove
       
   128 	 */
       
   129 	public void removeTuioListener(TuioListener listener) {	
       
   130 		listenerList.removeElement(listener);
       
   131 	}
       
   132 
       
   133 	/**
       
   134 	 * Removes all TuioListener from the list of registered TUIO event listeners
       
   135 	 */
       
   136 	public void removeAllTuioListeners() {	
       
   137 		listenerList.clear();
       
   138 	}
       
   139 	
       
   140 	/**
       
   141 	 * Returns a Vector of all currently active TuioObjects
       
   142 	 *
       
   143 	 * @return  a Vector of all currently active TuioObjects
       
   144 	 */
       
   145 	public Vector<TuioObject> getTuioObjects() {
       
   146 		return new Vector<TuioObject>(objectList.values());
       
   147 	}
       
   148 	
       
   149 	/**
       
   150 	 * Returns a Vector of all currently active TuioCursors
       
   151 	 *
       
   152 	 * @return  a Vector of all currently active TuioCursors
       
   153 	 */
       
   154 	public Vector<TuioCursor> getTuioCursors() {
       
   155 		return new Vector<TuioCursor>(cursorList.values());
       
   156 	}	
       
   157 
       
   158 	/**
       
   159 	 * Returns the TuioObject corresponding to the provided Session ID
       
   160 	 * or NULL if the Session ID does not refer to an active TuioObject
       
   161 	 *
       
   162 	 * @return  an active TuioObject corresponding to the provided Session ID or NULL
       
   163 	 */
       
   164 	public TuioObject getTuioObject(long s_id) {
       
   165 		return objectList.get(s_id);
       
   166 	}
       
   167 	
       
   168 	/**
       
   169 	 * Returns the TuioCursor corresponding to the provided Session ID
       
   170 	 * or NULL if the Session ID does not refer to an active TuioCursor
       
   171 	 *
       
   172 	 * @return  an active TuioCursor corresponding to the provided Session ID or NULL
       
   173 	 */
       
   174 	public TuioCursor getTuioCursor(long s_id) {
       
   175 		return cursorList.get(s_id);
       
   176 	}	
       
   177 
       
   178 	/**
       
   179 	 * The OSC callback method where all TUIO messages are received and decoded
       
   180 	 * and where the TUIO event callbacks are dispatched
       
   181 	 *
       
   182 	 * @param  date	the time stamp of the OSC bundle
       
   183 	 * @param  message	the received OSC message
       
   184 	 */
       
   185 	public void acceptMessage(Date date, OSCMessage message) {
       
   186 	
       
   187 		Object[] args = message.getArguments();
       
   188 		String command = (String)args[0];
       
   189 		String address = message.getAddress();
       
   190 
       
   191 		if (address.equals("/tuio/2Dobj")) {
       
   192 
       
   193 			if (command.equals("set")) {
       
   194 				
       
   195 				long s_id  = ((Integer)args[1]).longValue();
       
   196 				int c_id  = ((Integer)args[2]).intValue();
       
   197 				float xpos = ((Float)args[3]).floatValue();
       
   198 				float ypos = ((Float)args[4]).floatValue();
       
   199 				float angle = ((Float)args[5]).floatValue();
       
   200 				float xspeed = ((Float)args[6]).floatValue();
       
   201 				float yspeed = ((Float)args[7]).floatValue();
       
   202 				float rspeed = ((Float)args[8]).floatValue();
       
   203 				float maccel = ((Float)args[9]).floatValue();
       
   204 				float raccel = ((Float)args[10]).floatValue();
       
   205 				
       
   206 				if (objectList.get(s_id) == null) {
       
   207 				
       
   208 					TuioObject addObject = new TuioObject(s_id,c_id,xpos,ypos,angle);
       
   209 					frameObjects.addElement(addObject);
       
   210 					
       
   211 				} else {
       
   212 				
       
   213 					TuioObject tobj = objectList.get(s_id);
       
   214 					if (tobj==null) return;
       
   215 					if ((tobj.xpos!=xpos) || (tobj.ypos!=ypos) || (tobj.angle!=angle) || (tobj.x_speed!=xspeed) || (tobj.y_speed!=yspeed) || (tobj.rotation_speed!=rspeed) || (tobj.motion_accel!=maccel) || (tobj.rotation_accel!=raccel)) {
       
   216 						
       
   217 						TuioObject updateObject = new TuioObject(s_id,c_id,xpos,ypos,angle);
       
   218 						updateObject.update(xpos,ypos,angle,xspeed,yspeed,rspeed,maccel,raccel);
       
   219 						frameObjects.addElement(updateObject);
       
   220 					}
       
   221 				
       
   222 				}
       
   223 				
       
   224 			} else if (command.equals("alive")) {
       
   225 	
       
   226 				newObjectList.clear();
       
   227 				for (int i=1;i<args.length;i++) {
       
   228 					// get the message content
       
   229 					long s_id = ((Integer)args[i]).longValue();
       
   230 					newObjectList.addElement(s_id);
       
   231 					// reduce the object list to the lost objects
       
   232 					if (aliveObjectList.contains(s_id))
       
   233 						 aliveObjectList.removeElement(s_id);
       
   234 				}
       
   235 				
       
   236 				// remove the remaining objects
       
   237 				for (int i=0;i<aliveObjectList.size();i++) {
       
   238 					TuioObject removeObject = objectList.get(aliveObjectList.elementAt(i));
       
   239 					if (removeObject==null) continue;
       
   240 					removeObject.remove(currentTime);
       
   241 					frameObjects.addElement(removeObject);
       
   242 				}
       
   243 					
       
   244 			} else if (command.equals("fseq")) {
       
   245 				
       
   246 				long fseq = ((Integer)args[1]).longValue();
       
   247 				boolean lateFrame = false;
       
   248 				
       
   249 				if (fseq>0) {
       
   250 					if (fseq>currentFrame) currentTime = TuioTime.getSessionTime();
       
   251 					if ((fseq>=currentFrame) || ((currentFrame-fseq)>100)) currentFrame=fseq;
       
   252 					else lateFrame = true;
       
   253 				} else if (TuioTime.getSessionTime().subtract(currentTime).getTotalMilliseconds()>100) {
       
   254 					currentTime = TuioTime.getSessionTime();
       
   255 				}
       
   256 				
       
   257 				if (!lateFrame) {
       
   258 					Enumeration<TuioObject> frameEnum = frameObjects.elements();
       
   259 					while(frameEnum.hasMoreElements()) {
       
   260 						TuioObject tobj = frameEnum.nextElement();
       
   261 						
       
   262 						switch (tobj.getTuioState()) {
       
   263 							case TuioObject.TUIO_REMOVED:
       
   264 								TuioObject removeObject = tobj;
       
   265 								removeObject.remove(currentTime);
       
   266 								for (int i=0;i<listenerList.size();i++) {
       
   267 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   268 									if (listener!=null) listener.removeTuioObject(removeObject);
       
   269 								}								
       
   270 								objectList.remove(removeObject.getSessionID());
       
   271 								break;
       
   272 
       
   273 							case TuioObject.TUIO_ADDED:
       
   274 								TuioObject addObject = new TuioObject(currentTime,tobj.getSessionID(),tobj.getSymbolID(),tobj.getX(),tobj.getY(),tobj.getAngle());
       
   275 								objectList.put(addObject.getSessionID(),addObject);
       
   276 								for (int i=0;i<listenerList.size();i++) {
       
   277 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   278 									if (listener!=null) listener.addTuioObject(addObject);
       
   279 								}
       
   280 								break;
       
   281 																
       
   282 							default:
       
   283 								TuioObject updateObject = objectList.get(tobj.getSessionID());
       
   284 								if ( (tobj.getX()!=updateObject.getX() && tobj.getXSpeed()==0) || (tobj.getY()!=updateObject.getY() && tobj.getYSpeed()==0) )
       
   285 									updateObject.update(currentTime,tobj.getX(),tobj.getY(),tobj.getAngle());
       
   286 								else
       
   287 									updateObject.update(currentTime,tobj.getX(),tobj.getY(),tobj.getAngle(),tobj.getXSpeed(),tobj.getYSpeed(),tobj.getRotationSpeed(),tobj.getMotionAccel(),tobj.getRotationAccel());
       
   288 
       
   289 								for (int i=0;i<listenerList.size();i++) {
       
   290 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   291 									if (listener!=null) listener.updateTuioObject(updateObject);
       
   292 								}
       
   293 						}
       
   294 					}
       
   295 					
       
   296 					for (int i=0;i<listenerList.size();i++) {
       
   297 						TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   298 						if (listener!=null) listener.refresh(new TuioTime(currentTime));
       
   299 					}
       
   300 					
       
   301 					Vector<Long> buffer = aliveObjectList;
       
   302 					aliveObjectList = newObjectList;
       
   303 					// recycling the vector
       
   304 					newObjectList = buffer;					
       
   305 				}
       
   306 				frameObjects.clear();
       
   307 			}
       
   308 		} else if (address.equals("/tuio/2Dcur")) {
       
   309 
       
   310 			if (command.equals("set")) {
       
   311 
       
   312 				long s_id  = ((Integer)args[1]).longValue();
       
   313 				float xpos = ((Float)args[2]).floatValue();
       
   314 				float ypos = ((Float)args[3]).floatValue();
       
   315 				float xspeed = ((Float)args[4]).floatValue();
       
   316 				float yspeed = ((Float)args[5]).floatValue();
       
   317 				float maccel = ((Float)args[6]).floatValue();
       
   318 				
       
   319 				if (cursorList.get(s_id) == null) {
       
   320 									
       
   321 					TuioCursor addCursor = new TuioCursor(s_id, -1 ,xpos,ypos);
       
   322 					frameCursors.addElement(addCursor);
       
   323 					
       
   324 				} else {
       
   325 				
       
   326 					TuioCursor tcur = cursorList.get(s_id);
       
   327 					if (tcur==null) return;
       
   328 					if ((tcur.xpos!=xpos) || (tcur.ypos!=ypos) || (tcur.x_speed!=xspeed) || (tcur.y_speed!=yspeed) || (tcur.motion_accel!=maccel)) {
       
   329 
       
   330 						TuioCursor updateCursor = new TuioCursor(s_id,tcur.getCursorID(),xpos,ypos);
       
   331 						updateCursor.update(xpos,ypos,xspeed,yspeed,maccel);
       
   332 						frameCursors.addElement(updateCursor);
       
   333 					}
       
   334 				}
       
   335 				
       
   336 				//System.out.println("set cur " + s_id+" "+xpos+" "+ypos+" "+xspeed+" "+yspeed+" "+maccel);
       
   337 				
       
   338 			} else if (command.equals("alive")) {
       
   339 	
       
   340 				newCursorList.clear();
       
   341 				for (int i=1;i<args.length;i++) {
       
   342 					// get the message content
       
   343 					long s_id = ((Integer)args[i]).longValue();
       
   344 					newCursorList.addElement(s_id);
       
   345 					// reduce the cursor list to the lost cursors
       
   346 					if (aliveCursorList.contains(s_id)) 
       
   347 						aliveCursorList.removeElement(s_id);
       
   348 				}
       
   349 				
       
   350 				// remove the remaining cursors
       
   351 				for (int i=0;i<aliveCursorList.size();i++) {
       
   352 					TuioCursor removeCursor = cursorList.get(aliveCursorList.elementAt(i));
       
   353 					if (removeCursor==null) continue;
       
   354 					removeCursor.remove(currentTime);
       
   355 					frameCursors.addElement(removeCursor);
       
   356 				}
       
   357 								
       
   358 			} else if (command.equals("fseq")) {
       
   359 				long fseq = ((Integer)args[1]).longValue();
       
   360 				boolean lateFrame = false;
       
   361 				
       
   362 				if (fseq>0) {
       
   363 					if (fseq>currentFrame) currentTime = TuioTime.getSessionTime();
       
   364 					if ((fseq>=currentFrame) || ((currentFrame-fseq)>100)) currentFrame = fseq;
       
   365 					else lateFrame = true;
       
   366 				} else if (TuioTime.getSessionTime().subtract(currentTime).getTotalMilliseconds()>100) {
       
   367 					currentTime = TuioTime.getSessionTime();
       
   368 				}
       
   369 				if (!lateFrame) {
       
   370 
       
   371 					Enumeration<TuioCursor> frameEnum = frameCursors.elements();
       
   372 					while(frameEnum.hasMoreElements()) {
       
   373 						TuioCursor tcur = frameEnum.nextElement();
       
   374 						
       
   375 						switch (tcur.getTuioState()) {
       
   376 							case TuioCursor.TUIO_REMOVED:
       
   377 							
       
   378 								TuioCursor removeCursor = tcur;
       
   379 								removeCursor.remove(currentTime);
       
   380 								
       
   381 								for (int i=0;i<listenerList.size();i++) {
       
   382 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   383 									if (listener!=null) listener.removeTuioCursor(removeCursor);
       
   384 								}
       
   385 
       
   386 								cursorList.remove(removeCursor.getSessionID());
       
   387 
       
   388 								if (removeCursor.getCursorID()==maxCursorID) {
       
   389 									maxCursorID = -1;
       
   390 									if (cursorList.size()>0) {
       
   391 										Enumeration<TuioCursor> clist = cursorList.elements();
       
   392 										while (clist.hasMoreElements()) {
       
   393 											int c_id = clist.nextElement().getCursorID();
       
   394 											if (c_id>maxCursorID) maxCursorID=c_id;
       
   395 										}
       
   396 										
       
   397 										Enumeration<TuioCursor> flist = freeCursorList.elements();
       
   398 										while (flist.hasMoreElements()) {
       
   399 											int c_id = flist.nextElement().getCursorID();
       
   400 											if (c_id>=maxCursorID) freeCursorList.removeElement(c_id);
       
   401 										}
       
   402 									} else freeCursorList.clear();
       
   403 								} else if (removeCursor.getCursorID()<maxCursorID) {
       
   404 									freeCursorList.addElement(removeCursor);
       
   405 								}
       
   406 								
       
   407 								break;
       
   408 
       
   409 							case TuioCursor.TUIO_ADDED:
       
   410 
       
   411 								int c_id = cursorList.size();
       
   412 								if ((cursorList.size()<=maxCursorID) && (freeCursorList.size()>0)) {
       
   413 									TuioCursor closestCursor = freeCursorList.firstElement();
       
   414 									Enumeration<TuioCursor> testList = freeCursorList.elements();
       
   415 									while (testList.hasMoreElements()) {
       
   416 										TuioCursor testCursor = testList.nextElement();
       
   417 										if (testCursor.getDistance(tcur)<closestCursor.getDistance(tcur)) closestCursor = testCursor;
       
   418 									}
       
   419 									c_id = closestCursor.getCursorID();
       
   420 									freeCursorList.removeElement(closestCursor);
       
   421 								} else maxCursorID = c_id;		
       
   422 								
       
   423 								TuioCursor addCursor = new TuioCursor(currentTime,tcur.getSessionID(),c_id,tcur.getX(),tcur.getY());
       
   424 								cursorList.put(addCursor.getSessionID(),addCursor);
       
   425 								
       
   426 								for (int i=0;i<listenerList.size();i++) {
       
   427 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   428 									if (listener!=null) listener.addTuioCursor(addCursor);
       
   429 								}
       
   430 								break;
       
   431 								
       
   432 							default:
       
   433 								
       
   434 								TuioCursor updateCursor = cursorList.get(tcur.getSessionID());
       
   435 								if ( (tcur.getX()!=updateCursor.getX() && tcur.getXSpeed()==0) || (tcur.getY()!=updateCursor.getY() && tcur.getYSpeed()==0) )
       
   436 									updateCursor.update(currentTime,tcur.getX(),tcur.getY());
       
   437 								else 
       
   438 									updateCursor.update(currentTime,tcur.getX(),tcur.getY(),tcur.getXSpeed(),tcur.getYSpeed(),tcur.getMotionAccel());
       
   439 									
       
   440 								for (int i=0;i<listenerList.size();i++) {
       
   441 									TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   442 									if (listener!=null) listener.updateTuioCursor(updateCursor);
       
   443 								}
       
   444 						}
       
   445 					}
       
   446 					
       
   447 					for (int i=0;i<listenerList.size();i++) {
       
   448 						TuioListener listener = (TuioListener)listenerList.elementAt(i);
       
   449 						if (listener!=null) listener.refresh(new TuioTime(currentTime));
       
   450 					}
       
   451 					
       
   452 					Vector<Long> buffer = aliveCursorList;
       
   453 					aliveCursorList = newCursorList;
       
   454 					// recycling the vector
       
   455 					newCursorList = buffer;				
       
   456 				}
       
   457 				
       
   458 				frameCursors.clear();
       
   459 			} 
       
   460 
       
   461 		}
       
   462 	}
       
   463 }