Kaynağa Gözat

Add OSC and TUIO including TuioServer

jost_vincent.schultz 10 yıl önce
ebeveyn
işleme
306e6450b3

+ 92 - 0
bbiwarg/Server/OSC.NET/OSCBundle.cs

@@ -0,0 +1,92 @@
+using System;
+using System.Collections;
+
+namespace OSC.NET
+{
+	/// <summary>
+	/// OSCBundle
+	/// </summary>
+	public class OSCBundle : OSCPacket
+	{
+		protected const string BUNDLE = "#bundle";
+		private long timestamp = 0;
+		
+		public OSCBundle(long ts)
+		{
+			this.address = BUNDLE;
+			this.timestamp = ts;
+		}
+
+		public OSCBundle()
+		{
+			this.address = BUNDLE;
+			this.timestamp = 0;
+		}
+
+		override protected void pack()
+		{
+			ArrayList data = new ArrayList();
+
+			addBytes(data, packString(this.Address));
+			padNull(data);
+			addBytes(data, packLong(0)); // TODO
+			
+			foreach(object value in this.Values)
+			{
+				if(value is OSCPacket)
+				{
+					byte[] bs = ((OSCPacket)value).BinaryData;
+					addBytes(data, packInt(bs.Length));
+					addBytes(data, bs);
+				}
+				else 
+				{
+					// TODO
+				}
+			}
+			
+			this.binaryData = (byte[])data.ToArray(typeof(byte));
+		}
+
+		public static new OSCBundle Unpack(byte[] bytes, ref int start, int end)
+		{
+
+			string address = unpackString(bytes, ref start);
+			//Console.WriteLine("bundle: " + address);
+			if(!address.Equals(BUNDLE)) return null; // TODO
+
+			long timestamp = unpackLong(bytes, ref start);
+			OSCBundle bundle = new OSCBundle(timestamp);
+			
+			while(start < end)
+			{
+				int length = unpackInt(bytes, ref start);
+				int sub_end = start + length;
+				//Console.WriteLine(bytes.Length +" "+ start+" "+length+" "+sub_end);
+				bundle.Append(OSCPacket.Unpack(bytes, ref start, sub_end));
+
+			}
+
+			return bundle;
+		}
+
+		public long getTimeStamp() {
+			return timestamp;
+		}
+
+		override public void Append(object value)
+		{
+			if( value is OSCPacket) 
+			{
+				values.Add(value);
+			}
+			else 
+			{
+				// TODO: exception
+			}
+		}
+
+		override public bool IsBundle() { return true; }
+	}
+}
+

+ 124 - 0
bbiwarg/Server/OSC.NET/OSCMessage.cs

@@ -0,0 +1,124 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace OSC.NET
+{
+	/// <summary>
+	/// OSCMessage
+	/// </summary>
+	public class OSCMessage : OSCPacket
+	{
+		protected const char INTEGER = 'i';
+		protected const char FLOAT	  = 'f';
+		protected const char LONG	  = 'h';
+		protected const char DOUBLE  = 'd';
+		protected const char STRING  = 's';
+		protected const char SYMBOL  = 'S';
+		//protected const char BLOB	  = 'b';
+		//protected const char ALL     = '*';
+
+		public OSCMessage(string address)
+		{
+			this.typeTag = ",";
+			this.Address = address;
+		}
+		public OSCMessage(string address, object value)
+		{
+			this.typeTag = ",";
+			this.Address = address;
+			Append(value);
+		}
+
+		override protected void pack()
+		{
+			ArrayList data = new ArrayList();
+
+			addBytes(data, packString(this.address));
+			padNull(data);
+			addBytes(data, packString(this.typeTag));
+			padNull(data);
+			
+			foreach(object value in this.Values)
+			{
+				if(value is int) addBytes(data, packInt((int)value));
+				else if(value is long) addBytes(data, packLong((long)value));
+				else if(value is float) addBytes(data, packFloat((float)value));
+				else if(value is double) addBytes(data, packDouble((double)value));
+				else if(value is string)
+				{
+					addBytes(data, packString((string)value));
+					padNull(data);
+				}
+				else 
+				{
+					// TODO
+				}
+			}
+			
+			this.binaryData = (byte[])data.ToArray(typeof(byte));
+		}
+
+
+		public static OSCMessage Unpack(byte[] bytes, ref int start)
+		{
+			string address = unpackString(bytes, ref start);
+			//Console.WriteLine("address: " + address);
+			OSCMessage msg = new OSCMessage(address);
+
+			char[] tags = unpackString(bytes, ref start).ToCharArray();
+			//Console.WriteLine("tags: " + new string(tags));
+			foreach(char tag in tags)
+			{
+				//Console.WriteLine("tag: " + tag + " @ "+start);
+				if(tag == ',') continue;
+				else if(tag == INTEGER) msg.Append(unpackInt(bytes, ref start));
+				else if(tag == LONG) msg.Append(unpackLong(bytes, ref start));
+				else if(tag == DOUBLE) msg.Append(unpackDouble(bytes, ref start));
+				else if(tag == FLOAT) msg.Append(unpackFloat(bytes, ref start));
+				else if(tag == STRING || tag == SYMBOL) msg.Append(unpackString(bytes, ref start));
+				else Console.WriteLine("unknown tag: "+tag);
+			}
+
+			return msg;
+		}
+
+		override public void Append(object value)
+		{
+			if(value is int)
+			{
+				AppendTag(INTEGER);
+			}
+			else if(value is long)
+			{
+				AppendTag(LONG);
+			}
+			else if(value is float)
+			{
+				AppendTag(FLOAT);
+			}
+			else if(value is double)
+			{
+				AppendTag(DOUBLE);
+			}
+			else if(value is string)
+			{
+				AppendTag(STRING);
+			}
+			else 
+			{
+				// TODO: exception
+			}
+			values.Add(value);
+		}
+
+		protected string typeTag;
+		protected void AppendTag(char type)
+		{
+			typeTag += type;
+		}
+
+
+		override public bool IsBundle() { return false; }
+	}
+}

+ 164 - 0
bbiwarg/Server/OSC.NET/OSCPacket.cs

@@ -0,0 +1,164 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace OSC.NET
+{
+	/// <summary>
+	/// OSCPacket
+	/// </summary>
+	abstract public class OSCPacket
+	{
+		public OSCPacket()
+		{
+			this.values = new ArrayList();
+		}
+
+		protected static void addBytes(ArrayList data, byte[] bytes)
+		{
+			foreach(byte b in bytes)
+			{
+				data.Add(b);
+			}
+		}
+
+		protected static void padNull(ArrayList data)
+		{
+			byte zero = 0;
+			int pad = 4 - (data.Count % 4);
+			for (int i = 0; i < pad; i++)
+			{
+				data.Add(zero);
+			}
+		}
+
+		protected static byte[] swapEndian(byte[] data)
+		{
+			byte[] swapped = new byte[data.Length];
+			for(int i = data.Length - 1, j = 0 ; i >= 0 ; i--, j++)
+			{
+				swapped[j] = data[i];
+			}
+			return swapped;
+		}
+
+		protected static byte[] packInt(int value)
+		{
+			byte[] data = BitConverter.GetBytes(value);
+			if(BitConverter.IsLittleEndian)	data = swapEndian(data);
+			return data;
+		}
+
+		protected static byte[] packLong(long value)
+		{
+			byte[] data = BitConverter.GetBytes(value);
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return data;
+		}
+
+		protected static byte[] packFloat(float value)
+		{
+			byte[] data = BitConverter.GetBytes(value);
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return data;
+		}
+
+		protected static byte[] packDouble(double value)
+		{
+			byte[] data = BitConverter.GetBytes(value);
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return data;
+		}
+
+		protected static byte[] packString(string value)
+		{
+			return System.Text.Encoding.ASCII.GetBytes(value);
+		}
+
+		abstract protected void pack();
+		protected byte[] binaryData;
+		public byte[] BinaryData
+		{
+			get
+			{
+				pack();
+				return binaryData;
+			}
+		}
+
+		protected static int unpackInt(byte[] bytes, ref int start)
+		{
+			byte[] data = new byte[4];
+			for(int i = 0 ; i < 4 ; i++, start++) data[i] = bytes[start];
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return BitConverter.ToInt32(data, 0);
+		}
+
+		protected static long unpackLong(byte[] bytes, ref int start)
+		{
+			byte[] data = new byte[8];
+			for(int i = 0 ; i < 8 ; i++, start++) data[i] = bytes[start];
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return BitConverter.ToInt64(data, 0);
+		}
+
+		protected static float unpackFloat(byte[] bytes, ref int start)
+		{
+			byte[] data = new byte[4];
+			for(int i = 0 ; i < 4 ; i++, start++) data[i] = bytes[start];
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return BitConverter.ToSingle(data, 0);
+		}
+
+		protected static double unpackDouble(byte[] bytes, ref int start)
+		{
+			byte[] data = new byte[8];
+			for(int i = 0 ; i < 8 ; i++, start++) data[i] = bytes[start];
+			if(BitConverter.IsLittleEndian) data = swapEndian(data);
+			return BitConverter.ToDouble(data, 0);
+		}
+
+		protected static string unpackString(byte[] bytes, ref int start)
+		{
+			int count= 0;
+			for(int index = start ; bytes[index] != 0 ; index++, count++) ;
+			string s = Encoding.ASCII.GetString(bytes, start, count);
+			start += count+1;
+			start = (start + 3) / 4 * 4;
+			return s;
+		}
+
+		public static OSCPacket Unpack(byte[] bytes)
+		{
+			int start = 0;
+			return Unpack(bytes, ref start, bytes.Length);
+		}
+
+		public static OSCPacket Unpack(byte[] bytes, ref int start, int end)
+		{
+			if(bytes[start] == '#') return OSCBundle.Unpack(bytes, ref start, end);
+			else return OSCMessage.Unpack(bytes, ref start);
+		}
+
+
+		protected string address;
+		public string Address
+		{
+			get { return address; }
+			set 
+			{
+				// TODO: validate
+				address = value;
+			}
+		}
+
+		protected ArrayList values;
+		public ArrayList Values
+		{
+			get { return (ArrayList)values.Clone(); }
+		}
+		abstract public void Append(object value);
+
+		abstract public bool IsBundle();
+	}
+}

+ 53 - 0
bbiwarg/Server/OSC.NET/OSCTransmitter.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+
+namespace OSC.NET
+{
+	/// <summary>
+	/// OSCTransmitter
+	/// </summary>
+	public class OSCTransmitter
+	{
+		protected UdpClient udpClient;
+		protected string remoteHost;
+		protected int remotePort;
+
+		public OSCTransmitter(string remoteHost, int remotePort)
+		{
+			this.remoteHost = remoteHost;
+			this.remotePort = remotePort;
+			Connect();
+		}
+
+		public void Connect()
+		{
+			if(this.udpClient != null) Close();
+			this.udpClient = new UdpClient(this.remoteHost, this.remotePort);
+		}
+
+		public void Close()
+		{
+			this.udpClient.Close();
+			this.udpClient = null;
+		}
+
+		public int Send(OSCPacket packet)
+		{
+			int byteNum = 0;
+			byte[] data = packet.BinaryData;
+			try 
+			{
+				byteNum = this.udpClient.Send(data, data.Length);
+			}
+			catch (Exception e)
+			{
+				Console.Error.WriteLine(e.Message);
+				Console.Error.WriteLine(e.StackTrace);
+			}
+
+			return byteNum;
+		}
+
+	}
+}

+ 333 - 0
bbiwarg/Server/TUIO/TuioContainer.cs

@@ -0,0 +1,333 @@
+/*
+	TUIO C# Library - part of the reacTIVision project
+	http://reactivision.sourceforge.net/
+
+	Copyright (c) 2005-2009 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
+*/
+
+using System;
+using System.Collections.Generic;
+
+namespace TUIO
+{
+
+/**
+ * The abstract TuioContainer class defines common attributes that apply to both subclasses {@link TuioObject} and {@link TuioCursor}.
+ *
+ * @author Martin Kaltenbrunner
+ * @version 1.4
+ */
+public abstract class TuioContainer:TuioPoint {
+
+	/**
+	 * The unique session ID number that is assigned to each TUIO object or cursor.
+	 */
+	protected long session_id;
+	/**
+	 * The X-axis velocity value.
+	 */
+	protected float x_speed;
+	/**
+	 * The Y-axis velocity value.
+	 */
+	protected float y_speed;
+	/**
+	 * The motion speed value.
+	 */
+	protected float motion_speed;
+	/**
+	 * The motion acceleration value.
+	 */
+	protected float motion_accel;
+	/**
+	 * A Vector of TuioPoints containing all the previous positions of the TUIO component.
+	 */
+	protected List<TuioPoint> path;
+	/**
+	 * Defines the ADDED state.
+	 */
+	public const int TUIO_ADDED = 0;
+	/**
+	 * Defines the ACCELERATING state.
+	 */
+	public const int TUIO_ACCELERATING = 1;
+	/**
+	 * Defines the DECELERATING state.
+	 */
+	public const int TUIO_DECELERATING = 2;
+	/**
+	 * Defines the STOPPED state.
+	 */
+	public const int TUIO_STOPPED = 3;
+	/**
+	 * Defines the REMOVED state.
+	 */
+	public const int TUIO_REMOVED = 4;
+	/**
+	 * Reflects the current state of the TuioComponent
+	 */
+	protected int state;
+
+	/**
+	 * This constructor takes a TuioTime argument and assigns it along with the provided
+	 * Session ID, X and Y 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
+	 */
+	public TuioContainer(TuioTime ttime, long si, float xp, float yp):base(ttime,xp,yp) {
+		session_id = si;
+		x_speed = 0.0f;
+		y_speed = 0.0f;
+		motion_speed = 0.0f;
+		motion_accel = 0.0f;
+
+		path = new List<TuioPoint>();
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		state = TUIO_ADDED;
+	}
+
+	/**
+	 * This constructor takes the provided Session ID, X and Y 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
+	 */
+	public TuioContainer (long si, float xp, float yp):base(xp,yp) {
+		session_id = si;
+		x_speed = 0.0f;
+		y_speed = 0.0f;
+		motion_speed = 0.0f;
+		motion_accel = 0.0f;
+		path = new List<TuioPoint>();
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		state = TUIO_ADDED;
+	}
+
+	/**
+	 * This constructor takes the atttibutes of the provided TuioContainer
+	 * and assigs these values to the newly created TuioContainer.
+	 *
+	 * @param	tcon	the TuioContainer to assign
+	 */
+	public TuioContainer (TuioContainer tcon):base(tcon) {
+		session_id = tcon.getSessionID();
+		x_speed = 0.0f;
+		y_speed = 0.0f;
+		motion_speed = 0.0f;
+		motion_accel = 0.0f;
+		path = new List<TuioPoint>();
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		state = TUIO_ADDED;
+	}
+
+	/**
+	 * Takes a TuioTime argument and assigns it along with the provided
+	 * X and Y 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
+	 */
+	public new void update(TuioTime ttime, float xp, float yp) {
+		TuioPoint lastPoint = path[path.Count-1];
+		base.update(ttime,xp,yp);
+
+		TuioTime diffTime = currentTime - lastPoint.getTuioTime();
+		float dt = diffTime.getTotalMilliseconds()/1000.0f;
+		float dx = this.xpos - lastPoint.getX();
+		float dy = this.ypos - lastPoint.getY();
+		float dist = (float)Math.Sqrt(dx*dx+dy*dy);
+		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.Add(new TuioPoint(currentTime,xpos,ypos));
+		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,this.xpos,this.ypos);
+	}
+
+	/**
+	 * Takes a TuioTime argument and assigns it along with the provided
+	 * X and Y 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	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 xs,float ys,float ma) {
+		base.update(ttime,xp,yp);
+		x_speed = xs;
+		y_speed = ys;
+		motion_speed = (float)Math.Sqrt(x_speed*x_speed+y_speed*y_speed);
+		motion_accel = ma;
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		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.
+	 *
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y 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 xs,float ys,float ma) {
+		base.update(xp,yp);
+
+		x_speed = xs;
+		y_speed = ys;
+		motion_speed = (float)Math.Sqrt(x_speed*x_speed+y_speed*y_speed);
+		motion_accel = ma;
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		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.
+	 *
+	 * @param	tcon	the TuioContainer to assign
+	 */
+	public void update (TuioContainer tcon) {
+		base.update(tcon.getX(),tcon.getY());
+
+		x_speed = tcon.getXSpeed();
+		y_speed = tcon.getYSpeed();
+		motion_speed = (float)Math.Sqrt(x_speed*x_speed+y_speed*y_speed);
+		motion_accel = tcon.getMotionAccel();
+		path.Add(new TuioPoint(currentTime,xpos,ypos));
+		if (motion_accel>0) state = TUIO_ACCELERATING;
+		else if (motion_accel<0) state = TUIO_DECELERATING;
+		else state = TUIO_STOPPED;
+	}
+
+	/**
+	 * Assigns the REMOVE state to this TuioContainer and sets
+	 * its TuioTime time stamp to the provided TuioTime argument.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 */
+	public void remove(TuioTime ttime) {
+			currentTime = ttime;
+			state = TUIO_REMOVED;
+	}
+
+	/**
+	 * Returns the Session ID of this TuioContainer.
+	 * @return	the Session ID of this TuioContainer
+	 */
+	public long getSessionID() {
+		return session_id;
+	}
+
+	/**
+	 * Returns the X velocity of this TuioContainer.
+	 * @return	the X velocity of this TuioContainer
+	 */
+	public float getXSpeed() {
+		return x_speed;
+	}
+
+	/**
+	 * Returns the Y velocity of this TuioContainer.
+	 * @return	the Y velocity of this TuioContainer
+	 */
+	public float getYSpeed() {
+		return y_speed;
+	}
+
+	/**
+	 * Returns the position of this TuioContainer.
+	 * @return	the position of this TuioContainer
+	 */
+	public TuioPoint getPosition() {
+		return new TuioPoint(xpos,ypos);
+	}
+
+	/**
+	 * Returns the path of this TuioContainer.
+	 * @return	the path of this TuioContainer
+	 */
+	public List<TuioPoint> getPath() {
+		return path;
+	}
+
+	/**
+	 * Returns the motion speed of this TuioContainer.
+	 * @return	the motion speed of this TuioContainer
+	 */
+	public float getMotionSpeed() {
+		return motion_speed;
+	}
+
+	/**
+	 * Returns the motion acceleration of this TuioContainer.
+	 * @return	the motion acceleration of this TuioContainer
+	 */
+	public float getMotionAccel() {
+		return motion_accel;
+	}
+
+	/**
+	 * Returns the TUIO state of this TuioContainer.
+	 * @return	the TUIO state of this TuioContainer
+	 */
+	public int getTuioState() {
+		return state;
+	}
+
+	/**
+	 * Returns true of this TuioContainer is moving.
+	 * @return	true of this TuioContainer is moving
+	 */
+	public bool isMoving() {
+		if ((state==TUIO_ACCELERATING) || (state==TUIO_DECELERATING)) return true;
+		else return false;
+	}
+
+	}
+}

+ 86 - 0
bbiwarg/Server/TUIO/TuioCursor.cs

@@ -0,0 +1,86 @@
+/*
+	TUIO C# Library - part of the reacTIVision project
+	http://reactivision.sourceforge.net/
+
+	Copyright (c) 2005-2009 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
+*/
+
+using System;
+
+namespace TUIO
+{
+
+/**
+ * The TuioCursor class encapsulates /tuio/2Dcur TUIO cursors.
+ *
+ * @author Martin Kaltenbrunner
+ * @version 1.4
+ */
+public class TuioCursor:TuioContainer {
+
+	/**
+	 * The individual cursor ID number that is assigned to each TuioCursor.
+	 */
+	protected int cursor_id;
+
+	/**
+	 * This constructor takes a TuioTime argument and assigns it along with the provided
+	 * Session ID, Cursor ID, X and Y 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
+	 */
+	public TuioCursor (TuioTime ttime, long si, int ci, float xp, float yp):base(ttime, si,xp,yp) {
+		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.
+	 *
+	 * @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
+	 */
+	public TuioCursor (long si, int ci, float xp, float yp):base(si,xp,yp) {
+		cursor_id = ci;
+	}
+
+	/**
+	 * 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 TuioCursor (TuioCursor tcur):base(tcur) {
+		cursor_id = tcur.getCursorID();
+	}
+
+	/**
+	 * Returns the Cursor ID of this TuioCursor.
+	 * @return	the Cursor ID of this TuioCursor
+	 */
+	public int getCursorID() {
+		return cursor_id;
+	}
+
+	}
+}

+ 271 - 0
bbiwarg/Server/TUIO/TuioPoint.cs

@@ -0,0 +1,271 @@
+/*
+	TUIO C# Library - part of the reacTIVision project
+	http://reactivision.sourceforge.net/
+
+	Copyright (c) 2005-2009 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
+*/
+
+using System;
+
+namespace TUIO
+{
+
+/**
+ * The TuioPoint class on the one hand is a simple container and utility class to handle TUIO positions in general,
+ * on the other hand the TuioPoint is the base class for the TuioCursor and TuioObject classes.
+ *
+ * @author Martin Kaltenbrunner
+ * @version 1.4
+ */
+public class TuioPoint {
+
+	/**
+	 * X coordinate, representated as a floating point value in a range of 0..1
+	 */
+	protected float xpos;
+	/**
+	 * Y coordinate, representated as a floating point value in a range of 0..1
+	 */
+	protected float ypos;
+	/**
+	 * The time stamp of the last update represented as TuioTime (time since session start)
+	 */
+	protected TuioTime currentTime;
+	/**
+	 * The creation time of this TuioPoint represented as TuioTime (time since session start)
+	 */
+	protected TuioTime startTime;
+
+	/**
+	 * The default constructor takes no arguments and sets
+	 * its coordinate attributes to zero and its time stamp to the current session time.
+	 */
+	public TuioPoint () {
+		xpos = 0.0f;
+		ypos = 0.0f;
+		currentTime = TuioTime.getSessionTime();
+		startTime = new TuioTime(currentTime);
+	}
+
+	/**
+	 * This constructor takes two 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
+	 */
+	public TuioPoint (float xp, float yp) {
+		xpos = xp;
+		ypos = yp;
+		currentTime = TuioTime.getSessionTime();
+		startTime = new TuioTime(currentTime);
+	}
+
+	/**
+	 * This constructor takes a TuioPoint argument and sets its coordinate attributes
+	 * to the coordinates of the provided TuioPoint and its time stamp to the current session time.
+	 *
+	 * @param	tpoint	the TuioPoint to assign
+	 */
+	public TuioPoint(TuioPoint tpoint) {
+		xpos = tpoint.getX();
+		ypos = tpoint.getY();
+		currentTime = TuioTime.getSessionTime();
+		startTime = new TuioTime(currentTime);
+	}
+
+	/**
+	 * This constructor takes a TuioTime object and two 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
+	 */
+	public TuioPoint(TuioTime ttime, float xp, float yp) {
+		xpos = xp;
+		ypos = yp;
+		currentTime = new TuioTime(ttime);
+		startTime = new TuioTime(currentTime);
+	}
+
+	/**
+	 * Takes a TuioPoint argument and updates its coordinate attributes
+	 * to the coordinates of the provided TuioPoint and leaves its time stamp unchanged.
+	 *
+	 * @param	tpoint	the TuioPoint to assign
+	 */
+	public void update(TuioPoint tpoint) {
+		xpos = tpoint.getX();
+		ypos = tpoint.getY();
+	}
+
+	/**
+	 * Takes two 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
+	 */
+	public void update(float xp, float yp) {
+		xpos = xp;
+		ypos = yp;
+	}
+
+	/**
+	 * 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.
+	 *
+	 * @param	ttime	the TuioTime to assign
+	 * @param	xp	the X coordinate to assign
+	 * @param	yp	the Y coordinate to assign
+	 */
+	public void update(TuioTime ttime, float xp, float yp) {
+		xpos = xp;
+		ypos = yp;
+		currentTime = new TuioTime(ttime);
+	}
+
+	/**
+	 * Returns the X coordinate of this TuioPoint.
+	 * @return	the X coordinate of this TuioPoint
+	 */
+	public float getX() {
+		return xpos;
+	}
+
+	/**
+	 * Returns the Y coordinate of this TuioPoint.
+	 * @return	the Y coordinate of this TuioPoint
+	 */
+	public float getY() {
+		return ypos;
+	}
+
+	/**
+	 * 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
+	 * @return	the distance to the provided coordinates
+	 */
+	public float getDistance(float x, float y) {
+		float dx = xpos-x;
+		float dy = ypos-y;
+		return (float)Math.Sqrt(dx*dx+dy*dy);
+	}
+
+	/**
+	 * Returns the distance to the provided TuioPoint
+	 *
+	 * @param	tpoint	the distant TuioPoint
+	 * @return	the distance to the provided TuioPoint
+	 */
+	public float getDistance(TuioPoint tpoint) {
+		return getDistance(tpoint.getX(),tpoint.getY());
+	}
+
+	/**
+	 * Returns the angle to the provided coordinates
+	 *
+	 * @param	xp	the X coordinate of the distant point
+	 * @param	yp	the Y coordinate of the distant point
+	 * @return	the angle to the provided coordinates
+	 */
+	public float getAngle(float xp, float yp) {
+
+		float side = xp-xpos;
+		float height = yp- ypos;
+		float distance = getDistance(xp,yp);
+
+		float angle = (float)(Math.Asin(side/distance)+Math.PI/2);
+		if (height<0) angle = 2.0f*(float)Math.PI-angle;
+
+		return angle;
+	}
+
+	/**
+	 * Returns the angle to the provided TuioPoint
+	 *
+	 * @param	tpoint	the distant TuioPoint
+	 * @return	the angle to the provided TuioPoint
+	 */
+	public float getAngle(TuioPoint tpoint) {
+		return getAngle(tpoint.getX(),tpoint.getY());
+	}
+
+	/**
+	 * Returns the angle in degrees to the provided coordinates
+	 *
+	 * @param	xp	the X coordinate of the distant point
+	 * @param	yp	the Y coordinate of the distant point
+	 * @return	the angle in degrees to the provided TuioPoint
+	 */
+	public float getAngleDegrees(float xp, float yp) {
+		return (getAngle(xp,yp)/(float)Math.PI)*180.0f;
+	}
+
+	/**
+	 * Returns the angle in degrees to the provided TuioPoint
+	 *
+	 * @param	tpoint	the distant TuioPoint
+	 * @return	the angle in degrees to the provided TuioPoint
+	 */
+	public float getAngleDegrees(TuioPoint tpoint) {
+		return (getAngle(tpoint)/(float)Math.PI)*180.0f;
+	}
+
+	/**
+	 * Returns the X coordinate in pixels relative to the provided screen width.
+	 *
+	 * @param	width	the screen width
+	 * @return	the X coordinate of this TuioPoint in pixels relative to the provided screen width
+	 */
+	public int getScreenX(int width) {
+		return (int)Math.Round(xpos*width);
+	}
+
+	/**
+	 * Returns the Y coordinate in pixels relative to the provided screen height.
+	 *
+	 * @param	height	the screen height
+	 * @return	the Y coordinate of this TuioPoint in pixels relative to the provided screen height
+	 */
+	public int getScreenY(int height) {
+		return (int)Math.Round(ypos*height);
+	}
+
+	/**
+	 * Returns the time stamp of this TuioPoint as TuioTime.
+	 *
+	 * @return	the time stamp of this TuioPoint as TuioTime
+	 */
+	public TuioTime getTuioTime() {
+		return new TuioTime(currentTime);
+	}
+
+	/**
+	 * Returns the start time of this TuioPoint as TuioTime.
+	 *
+	 * @return	the start time of this TuioPoint as TuioTime
+	 */
+	public TuioTime getStartTime() {
+		return new TuioTime(startTime);
+	}
+
+	}
+}

+ 142 - 0
bbiwarg/Server/TUIO/TuioServer.cs

@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+//using Ventuz.OSC;
+using OSC.NET;
+//using System.Runtime.InteropServices;
+
+namespace TUIO
+{
+    class TuioServer
+    {
+        const int MAX_PACKET_SIZE = 65535 - 8;
+
+        OSCTransmitter transmitter = null;
+        String host = "127.0.0.1";
+        int port = 3333;
+
+        List<TuioCursor> cursorList = new List<TuioCursor>();
+        List<TuioCursor> updatedCursorList;
+
+        public TuioServer() { transmitter = new OSCTransmitter(host, port); }
+
+        public TuioServer(int port)
+        {
+            this.port = port;
+            transmitter = new OSCTransmitter(host, port);
+        }
+
+        public TuioServer(String host, int port)
+        {
+            this.host = host;
+            this.port = port;
+            transmitter = new OSCTransmitter(host, port);
+        }
+
+
+        public void close()
+        {
+            transmitter.Close();
+        }
+
+        public TuioCursor addTuioCursor(float x, float y)
+        {
+            TuioCursor tcur = new TuioCursor(cursorList.Count, cursorList.Count, x, y);
+            cursorList.Add(tcur);
+            updatedCursorList.Add(tcur);
+            return tcur;
+        }
+
+        public void updateTuioCursor(TuioCursor tcur, float xp, float yp)
+        {
+            tcur.update(new TuioTime(0, 0), xp, yp);
+            if (!updatedCursorList.Contains(tcur))
+                updatedCursorList.Add(tcur);
+        }
+
+        public void removeTuioCursor(TuioCursor tcur)
+        {
+            cursorList.Remove(tcur);
+        }
+
+
+        public void initFrame()
+        {
+            updatedCursorList = new List<TuioCursor>();
+        }
+
+        public void commitFrame()
+        {
+            sendMessage(updatedCursorList);
+        }
+
+        public void sendFullMessages()
+        {
+            sendMessage(cursorList);
+        }
+
+        private void sendMessage(List<TuioCursor> list)
+        {
+            OSCBundle packet = new OSCBundle();
+            addAliveMessagesToBundle(packet);
+
+            OSCMessage currentMessage;
+            TuioCursor cursor;
+            for (int i = 0; i < list.Count; i++)
+            {
+                cursor = cursorList[i];
+                currentMessage = new OSCMessage("/tuio/2Dcur");
+                currentMessage.Append("set");
+                currentMessage.Append((int)cursor.getSessionID());
+                currentMessage.Append((float)cursor.getX());
+                currentMessage.Append((float)cursor.getY()); 
+                currentMessage.Append((float)cursor.getXSpeed());
+                currentMessage.Append((float)cursor.getYSpeed());
+                currentMessage.Append((float)cursor.getMotionAccel());
+
+                /*if (Marshal.SizeOf(packet) + Marshal.SizeOf(currentOscElement) >= MAX_PACKET_SIZE)
+                {
+                    packet.AddElement(new OscElement("/tuio/2Dcur", new Object[] { "fseq", -1 }));
+                    udpwriter.Send(packet);
+
+                    packet = new OscBundle();
+                    addAliveMessagesToBundle(packet);
+                }*/
+                packet.Append(currentMessage);
+            }
+            currentMessage = new OSCMessage("/tuio/2Dcur");
+            currentMessage.Append("fseq");
+            currentMessage.Append(-1);
+            packet.Append(currentMessage);
+            transmitter.Send(packet);
+        }
+
+        private void addAliveMessagesToBundle(OSCBundle packet)
+        {
+            OSCMessage mssg = new OSCMessage("/tuio/2Dcur");
+            mssg.Append("alive");
+            for (int i = 0; i < cursorList.Count; i++)
+            {
+                mssg.Append((Int32)cursorList[i].getSessionID());
+            }
+            packet.Append(mssg);
+        }
+
+        public List<TuioCursor> getTuioCursor()
+        {
+            return cursorList;
+        }
+
+        public TuioCursor getTuioCursor(long s_id)
+        {
+            for (int i = 0; i < cursorList.Count; i++)
+            {
+                if (cursorList[i].getSessionID() == s_id)
+                    return cursorList[i];
+            }
+            return null;
+        }
+    }
+}

+ 242 - 0
bbiwarg/Server/TUIO/TuioTime.cs

@@ -0,0 +1,242 @@
+/*
+	TUIO C# Library - part of the reacTIVision project
+	http://reactivision.sourceforge.net/
+
+	Copyright (c) 2005-2009 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
+*/
+
+using System;
+
+namespace TUIO
+{
+
+/**
+ * The TuioTime class is a simple structure that is used to reprent the time that has elapsed since the session start.
+ * The time is internally represented as seconds and fractions of microseconds which should be more than sufficient for gesture related timing requirements.
+ * Therefore at the beginning of a typical TUIO session the static method initSession() will set the reference time for the session.
+ * Another important static method getSessionTime will return a TuioTime object representing the time elapsed since the session start.
+ * The class also provides various addtional convience method, which allow some simple time arithmetics.
+ *
+ * @author Martin Kaltenbrunner
+ * @version 1.4
+ */
+public class TuioTime {
+
+	/**
+	 * the time since session start in seconds
+	 */
+	private long seconds = 0;
+	/**
+	 * time fraction in microseconds
+	 */
+	private long micro_seconds = 0;
+	/**
+	 * the session start time in seconds
+	 */
+	private static long start_seconds = 0;
+	/**
+	 * start time fraction in microseconds
+	 */
+	private static long start_micro_seconds = 0;
+
+	/**
+	 * The default constructor takes no arguments and sets
+	 * the Seconds and Microseconds attributes of the newly created TuioTime both to zero.
+	 */
+	public TuioTime () {
+		this.seconds = 0;
+		this.micro_seconds = 0;
+	}
+
+	/**
+	 * This constructor takes the provided time represented in total Milliseconds
+	 * and assigs this value to the newly created TuioTime.
+	 *
+	 * @param msec the total time in Millseconds
+	 */
+	public TuioTime (long msec) {
+		this.seconds = msec/1000;
+		this.micro_seconds = 1000*(msec%1000);
+	}
+
+	/**
+	 * This constructor takes the provided time represented in Seconds and Microseconds
+	 * and assigs these value to the newly created TuioTime.
+	 *
+	 * @param sec the total time in seconds
+	 * @param usec	the microseconds time component
+	 */
+	public TuioTime (long sec, long usec) {
+		this.seconds = sec;
+		this.micro_seconds = usec;
+	}
+
+	/**
+	 * This constructor takes the provided TuioTime
+	 * and assigs its Seconds and Microseconds values to the newly created TuioTime.
+	 *
+	 * @param ttime the TuioTime used to copy
+	 */
+	public TuioTime (TuioTime ttime) {
+		this.seconds = ttime.getSeconds();
+		this.micro_seconds = ttime.getMicroseconds();
+	}
+
+	/**
+	 * Sums the provided time value represented in total Microseconds to the base TuioTime.
+	 *
+	 * @param btime	the base TuioTime
+	 * @param us	the total time to add in Microseconds
+	 * @return the sum of this TuioTime with the provided argument in microseconds
+	*/
+	public static TuioTime operator + (TuioTime atime, long us) {
+		long sec = atime.getSeconds() + us/1000000;
+		long usec = atime.getMicroseconds() + us%1000000;
+		return new TuioTime(sec,usec);
+	}
+
+	/**
+	 * Sums the provided TuioTime to the base TuioTime.
+	 *
+	 * @param btime	the base TuioTime
+	 * @param ttime	the TuioTime to add
+	 * @return the sum of this TuioTime with the provided TuioTime argument
+	 */
+	public static TuioTime operator + (TuioTime btime, TuioTime ttime) {
+		long sec = btime.getSeconds() + ttime.getSeconds();
+		long usec = btime.getMicroseconds() + ttime.getMicroseconds();
+		sec += usec/1000000;
+		usec = usec%1000000;
+		return new TuioTime(sec,usec);
+	}
+
+	/**
+	 * Subtracts the provided time represented in Microseconds from the base TuioTime.
+	 *
+	 * @param btime	the base TuioTime
+	 * @param us	the total time to subtract in Microseconds
+	 * @return the subtraction result of this TuioTime minus the provided time in Microseconds
+	 */
+	public static TuioTime operator - (TuioTime btime, long us) {
+		long sec = btime.getSeconds() - us/1000000;
+		long usec = btime.getMicroseconds() - us%1000000;
+
+		if (usec<0) {
+			usec += 1000000;
+			sec--;
+		}
+
+		return new TuioTime(sec,usec);
+	}
+
+	/**
+	 * Subtracts the provided TuioTime from the private Seconds and Microseconds attributes.
+	 *
+	 * @param btime	the base TuioTime
+	 * @param ttime	the TuioTime to subtract
+	 * @return the subtraction result of this TuioTime minus the provided TuioTime
+	 */
+	public static TuioTime operator - (TuioTime btime, TuioTime ttime) {
+		long sec = btime.getSeconds() - ttime.getSeconds();
+		long usec = btime.getMicroseconds() - ttime.getMicroseconds();
+
+		if (usec<0) {
+			usec += 1000000;
+			sec--;
+		}
+
+		return new TuioTime(sec,usec);
+	}
+
+	/**
+	 * Takes a TuioTime argument and compares the provided TuioTime to the private Seconds and Microseconds attributes.
+	 *
+	 * @param ttime	the TuioTime to compare
+	 * @return true if the two TuioTime have equal Seconds and Microseconds attributes
+	 */
+	public bool Equals(TuioTime ttime) {
+		if ((seconds==ttime.getSeconds()) && (micro_seconds==ttime.getMicroseconds())) return true;
+		else return false;
+	}
+
+	/**
+	 * Resets the seconds and micro_seconds attributes to zero.
+	 */
+	public void reset() {
+		seconds = 0;
+		micro_seconds = 0;
+	}
+
+	/**
+	 * Returns the TuioTime Seconds component.
+	 * @return the TuioTime Seconds component
+	 */
+	public long getSeconds() {
+		return seconds;
+	}
+
+	/**
+	 * Returns the TuioTime Microseconds component.
+	 * @return the TuioTime Microseconds component
+	 */
+	public long getMicroseconds() {
+		return micro_seconds;
+	}
+
+	/**
+	 * Returns the total TuioTime in Milliseconds.
+	 * @return the total TuioTime in Milliseconds
+	 */
+	public long getTotalMilliseconds() {
+		return seconds*1000+micro_seconds/1000;
+	}
+
+	/**
+	 * This static method globally resets the TUIO session time.
+	 */
+	public static void initSession() {
+		TuioTime startTime = getSystemTime();
+		start_seconds = startTime.getSeconds();
+		start_micro_seconds = startTime.getMicroseconds();
+	}
+
+	/**
+	 * Returns the present TuioTime representing the time since session start.
+	 * @return the present TuioTime representing the time since session start
+	 */
+	public static TuioTime getSessionTime() {
+		return getSystemTime()-getStartTime();
+	}
+
+	/**
+	 * Returns the absolut TuioTime representing the session start.
+	 * @return the absolut TuioTime representing the session start
+	 */
+	public static TuioTime getStartTime() {
+		return new TuioTime(start_seconds,start_micro_seconds);
+	}
+
+	/**
+	 * Returns the absolut TuioTime representing the current system time.
+	 * @return the absolut TuioTime representing the current system time
+	 */
+	public static TuioTime getSystemTime() {
+		long usec = DateTime.Now.Ticks/10;
+		return new TuioTime(usec/1000000,usec%1000000);
+	}
+}
+}

+ 9 - 0
bbiwarg/bbiwarg.csproj

@@ -91,6 +91,15 @@
     <Compile Include="InputProvider\IisuInputProvider.cs" />
     <Compile Include="MainBBWIWARG.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Server\OSC.NET\OSCBundle.cs" />
+    <Compile Include="Server\OSC.NET\OSCMessage.cs" />
+    <Compile Include="Server\OSC.NET\OSCPacket.cs" />
+    <Compile Include="Server\OSC.NET\OSCTransmitter.cs" />
+    <Compile Include="Server\TUIO\TuioContainer.cs" />
+    <Compile Include="Server\TUIO\TuioCursor.cs" />
+    <Compile Include="Server\TUIO\TuioPoint.cs" />
+    <Compile Include="Server\TUIO\TuioServer.cs" />
+    <Compile Include="Server\TUIO\TuioTime.cs" />
     <Compile Include="Utility\Kalman2DPositionFilter.cs" />
     <Compile Include="Utility\Line2D.cs" />
     <Compile Include="Utility\LineSegment2D.cs" />