package org.squidy.nodes.reactivision;
/*
TUIO Java backend - part of the reacTIVision project
http://reactivision.sourceforge.net/
Copyright (c) 2005-2008 Martin Kaltenbrunner <mkalten@iua.upf.edu>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import com.illposed.osc.*;
import java.util.*;
public class TuioClient implements OSCListener {
private int port = 3333;
private OSCPortIn oscPort;
private Hashtable<Long, TuioObject> objectList = new Hashtable<Long, TuioObject>();
private Vector<Long> aliveObjectList = new Vector<Long>();
private Vector<Long> newObjectList = new Vector<Long>();
private Hashtable<Long, TuioCursor> cursorList = new Hashtable<Long, TuioCursor>();
private Vector<Long> aliveCursorList = new Vector<Long>();
private Vector<Long> newCursorList = new Vector<Long>();
private Vector<TuioCursor> freeCursorList = new Vector<TuioCursor>();
private int maxFingerID = -1;
private long currentFrame = 0;
private long lastFrame = 0;
private long startTime = 0;
private long lastTime = 0;
private final int UNDEFINED = -1;
private Vector<TuioListener> listenerList = new Vector<TuioListener>();
public TuioClient(int port) {
this.port = port;
}
public TuioClient() {
}
public void connect() {
try {
oscPort = new OSCPortIn(port, Endian.LITTLE_ENDIAN);
oscPort.addListener("/tuio/2Dobj", this);
oscPort.addListener("/tuio/2Dcur", this);
oscPort.startListening();
startTime = System.currentTimeMillis();
}
catch (Exception e) {
System.out.println("failed to connect to port " + port);
}
}
public void disconnect() {
oscPort.stopListening();
try {
Thread.sleep(100);
}
catch (Exception e) {
}
;
oscPort.close();
}
public void addTuioListener(TuioListener listener) {
listenerList.addElement(listener);
}
public void removeTuioListener(TuioListener listener) {
listenerList.removeElement(listener);
}
public Vector<TuioObject> getTuioObjects() {
return new Vector<TuioObject>(objectList.values());
}
public Vector<TuioCursor> getTuioCursors() {
return new Vector<TuioCursor>(cursorList.values());
}
public TuioObject getTuioObject(long s_id) {
return (TuioObject) objectList.get(new Long(s_id));
}
public TuioCursor getTuioCursor(long s_id) {
return (TuioCursor) cursorList.get(new Long(s_id));
}
public void acceptMessages(Date date, OSCMessage[] messages) {
for (OSCMessage message : messages) {
Object[] args = message.getArguments();
String command = (String) args[0];
String address = message.getAddress();
if (address.equals("/tuio/2Dobj")) {
if (command.equals("set")) {
if ((currentFrame < lastFrame) && (currentFrame > 0))
return;
long s_id = ((Integer) args[1]).longValue();
int f_id = ((Integer) args[2]).intValue();
float xpos = ((Float) args[3]).floatValue();
float ypos = ((Float) args[4]).floatValue();
float angle = ((Float) args[5]).floatValue();
float xspeed = ((Float) args[6]).floatValue();
float yspeed = ((Float) args[7]).floatValue();
float rspeed = ((Float) args[8]).floatValue();
float maccel = ((Float) args[9]).floatValue();
float raccel = ((Float) args[10]).floatValue();
if (objectList.get(s_id) == null) {
TuioObject addObject = new TuioObject(s_id, f_id, xpos, ypos, angle);
objectList.put(s_id, addObject);
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.addTuioObject(addObject);
}
}
else {
TuioObject updateObject = (TuioObject) objectList.get(s_id);
if ((updateObject.xpos != xpos) || (updateObject.ypos != ypos) || (updateObject.angle != angle)
|| (updateObject.x_speed != xspeed) || (updateObject.y_speed != yspeed)
|| (updateObject.rotationSpeed != rspeed) || (updateObject.motion_accel != maccel)
|| (updateObject.rotationAcceleration != raccel)) {
updateObject.update(xpos, ypos, angle, xspeed, yspeed, rspeed, maccel, raccel);
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.updateTuioObject(updateObject);
}
}
}
// System.out.println("set obj "
// +s_id+" "+f_id+" "+xpos+" "+ypos+" "+angle+" "+xspeed+" "+yspeed+" "+rspeed+" "+maccel+" "+raccel);
}
else if (command.equals("alive")) {
if ((currentFrame < lastFrame) && (currentFrame > 0))
return;
for (int i = 1; i < args.length; i++) {
// get the message content
long s_id = ((Integer) args[i]).longValue();
newObjectList.addElement(s_id);
// reduce the object list to the lost objects
if (aliveObjectList.contains(s_id))
aliveObjectList.removeElement(s_id);
}
// remove the remaining objects
for (int i = 0; i < aliveObjectList.size(); i++) {
TuioObject removeObject = (TuioObject) objectList.remove(aliveObjectList.elementAt(i));
if (removeObject == null)
continue;
removeObject.remove();
// System.out.println("remove "+id);
for (int j = 0; j < listenerList.size(); j++) {
TuioListener listener = (TuioListener) listenerList.elementAt(j);
if (listener != null)
listener.removeTuioObject(removeObject);
}
}
Vector<Long> buffer = aliveObjectList;
aliveObjectList = newObjectList;
// recycling of the vector
newObjectList = buffer;
newObjectList.clear();
}
else if (command.equals("fseq")) {
if (currentFrame >= 0)
lastFrame = currentFrame;
currentFrame = ((Integer) args[1]).intValue();
if ((currentFrame >= lastFrame) || (currentFrame < 0)) {
long currentTime = lastTime;
if (currentFrame > lastFrame) {
currentTime = System.currentTimeMillis() - startTime;
lastTime = currentTime;
}
Enumeration<TuioObject> refreshList = objectList.elements();
while (refreshList.hasMoreElements()) {
TuioObject refreshObject = refreshList.nextElement();
if (refreshObject.getUpdateTime() == UNDEFINED)
refreshObject.setUpdateTime(currentTime);
}
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.refresh(currentTime);
}
}
}
}
else if (address.equals("/tuio/2Dcur")) {
if (command.equals("set")) {
if ((currentFrame < lastFrame) && (currentFrame > 0))
return;
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();
if (cursorList.get(s_id) == null) {
int f_id = cursorList.size();
if (cursorList.size() <= maxFingerID) {
TuioCursor closestCursor = freeCursorList.firstElement();
Enumeration<TuioCursor> testList = freeCursorList.elements();
while (testList.hasMoreElements()) {
TuioCursor testCursor = testList.nextElement();
if (testCursor.getDistance(xpos, ypos) < closestCursor.getDistance(xpos, ypos))
closestCursor = testCursor;
}
f_id = closestCursor.getFingerID();
freeCursorList.removeElement(closestCursor);
}
else
maxFingerID = f_id;
TuioCursor addCursor = new TuioCursor(s_id, f_id, xpos, ypos);
cursorList.put(s_id, addCursor);
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.addTuioCursor(addCursor);
}
}
else {
TuioCursor updateCursor = (TuioCursor) cursorList.get(s_id);
if ((updateCursor.xpos != xpos) || (updateCursor.ypos != ypos)
|| (updateCursor.x_speed != xspeed) || (updateCursor.y_speed != yspeed)
|| (updateCursor.motion_accel != maccel)) {
updateCursor.update(xpos, ypos, xspeed, yspeed, maccel);
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.updateTuioCursor(updateCursor);
}
}
}
// System.out.println("set cur " +
// s_id+" "+xpos+" "+ypos+" "+xspeed+" "+yspeed+" "+maccel);
}
else if (command.equals("alive")) {
if ((currentFrame < lastFrame) && (currentFrame > 0))
return;
for (int i = 1; i < args.length; i++) {
// get the message content
long s_id = ((Integer) args[i]).longValue();
newCursorList.addElement(s_id);
// reduce the cursor list to the lost cursors
if (aliveCursorList.contains(s_id))
aliveCursorList.removeElement(s_id);
}
// remove the remaining cursors
for (int i = 0; i < aliveCursorList.size(); i++) {
TuioCursor removeCursor = (TuioCursor) cursorList.remove(aliveCursorList.elementAt(i));
if (removeCursor == null)
continue;
removeCursor.remove();
if (removeCursor.finger_id == maxFingerID) {
maxFingerID = -1;
if (cursorList.size() > 0) {
Enumeration<TuioCursor> clist = cursorList.elements();
while (clist.hasMoreElements()) {
int f_id = clist.nextElement().finger_id;
if (f_id > maxFingerID)
maxFingerID = f_id;
}
Enumeration<TuioCursor> flist = freeCursorList.elements();
while (flist.hasMoreElements()) {
int c_id = flist.nextElement().getFingerID();
if (c_id >= maxFingerID)
freeCursorList.removeElement(c_id);
}
}
}
else if (removeCursor.finger_id < maxFingerID)
freeCursorList.addElement(removeCursor);
// System.out.println("remove "+id);
for (int j = 0; j < listenerList.size(); j++) {
TuioListener listener = (TuioListener) listenerList.elementAt(j);
if (listener != null)
listener.removeTuioCursor(removeCursor);
}
}
Vector<Long> buffer = aliveCursorList;
aliveCursorList = newCursorList;
// recycling of the vector
newCursorList = buffer;
newCursorList.clear();
}
else if (command.equals("fseq")) {
if (currentFrame >= 0)
lastFrame = currentFrame;
currentFrame = ((Integer) args[1]).intValue();
if ((currentFrame >= lastFrame) || (currentFrame < 0)) {
long currentTime = lastTime;
if (currentFrame > lastFrame) {
currentTime = System.currentTimeMillis() - startTime;
lastTime = currentTime;
}
Enumeration<TuioCursor> refreshList = cursorList.elements();
while (refreshList.hasMoreElements()) {
TuioCursor refreshCursor = refreshList.nextElement();
if (refreshCursor.getUpdateTime() == UNDEFINED)
refreshCursor.setUpdateTime(currentTime);
}
for (int i = 0; i < listenerList.size(); i++) {
TuioListener listener = (TuioListener) listenerList.elementAt(i);
if (listener != null)
listener.refresh(currentTime);
}
}
}
}
}
}
}