using OSC.NET; using System; using System.Collections.Generic; // using System.Runtime.InteropServices; namespace TUIO { /// /// Tuio server class to send tuio cursors and objects to tuio clients. /// internal class TuioServer { /// /// the maximum packet size /// private const int MAX_PACKET_SIZE = 65535 - 8; /// /// current tuio time /// private TuioTime currentFrameTime; /// /// list of generated cursors /// private List cursorList; /// /// server ip address /// private String host = "127.0.0.1"; /// /// list of all generated objects /// private List objectList; /// /// server port /// private int port = 3333; /// /// tuio session id /// private long sessionID = 0; /// /// transmitter to send packages over udp /// private OSCTransmitter transmitter = null; /// /// list of cursors updated in the current frame /// private List updatedCursorList; /// /// list of objects updated in the current frame /// private List updatedObjectList; /// /// Creates a tuio server with default ip and port. /// public TuioServer() { init(); } /// /// Creates a tuio server with default ip. /// /// server port public TuioServer(int port) { this.port = port; init(); } /// /// Creates a tuio server. /// /// server ip /// server port public TuioServer(String host, int port) { this.host = host; this.port = port; init(); } /// /// Adds and returns a tuio cursor. /// /// x position of the cursor /// y position of the cursor /// the added cursor public TuioCursor addTuioCursor(float xp, float yp) { TuioCursor tcur = new TuioCursor(sessionID, cursorList.Count, xp, yp); cursorList.Add(tcur); updatedCursorList.Add(tcur); sessionID++; return tcur; } /// /// Adds and returns tuio object. /// /// x position of the object /// y position of the object /// angle of the object /// the added object public TuioObject addTuioObject(float xp, float yp, float angle) { TuioObject tobj = new TuioObject(sessionID, objectList.Count, xp, yp, angle); objectList.Add(tobj); updatedObjectList.Add(tobj); sessionID++; return tobj; } /// /// Closes the transmission. /// public void close() { transmitter.Close(); } /// /// Sends cursors and objects which were updated in the current frame. /// public void commitFrame() { sendMessage(updatedCursorList, updatedObjectList); } /// /// Initializes cursor and object lists for sending information for a new frame. /// public void initFrame() { currentFrameTime = TuioTime.getSessionTime(); updatedCursorList = new List(); updatedObjectList = new List(); } /// /// Removes a tuio cursor. /// /// the cursor to remove public void removeTuioCursor(TuioCursor tcur) { cursorList.Remove(tcur); } /// /// Removes a tuio object. /// /// the object to remove public void removeTuioObject(TuioObject tobj) { objectList.Remove(tobj); } /// /// Sends all cursors and objects. /// public void sendFullMessages() { sendMessage(cursorList, objectList); } /// /// Updates a tui cursor. /// /// the cursor to update /// new x position /// new y position public void updateTuioCursor(TuioCursor tcur, float xp, float yp) { tcur.update(currentFrameTime, xp, yp); if (!updatedCursorList.Contains(tcur)) updatedCursorList.Add(tcur); } /// /// Updates a tuio object. /// /// the object to update /// new x position /// new y position public void updateTuioObject(TuioObject tobj, float xp, float yp) { tobj.update(currentFrameTime, xp, yp); if (!updatedObjectList.Contains(tobj)) updatedObjectList.Add(tobj); } /// /// Updates a tuio object. /// /// the object to update /// new x position /// new y position public void updateTuioObject(TuioObject tobj, float xp, float yp, float angle) { tobj.update(currentFrameTime, xp, yp, angle); if (!updatedObjectList.Contains(tobj)) updatedObjectList.Add(tobj); } /// /// Adds a tuio cursor alive message to a packet. /// /// packet to add the message to private void addAliveCursorMessagesToBundle(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); } /// /// Adds a tuio object alive message to a packet. /// /// packet to add the message to private void addAliveObjectMessagesToBundle(OSCBundle packet) { OSCMessage mssg = new OSCMessage("/tuio/2Dobj"); mssg.Append("alive"); for (int i = 0; i < objectList.Count; i++) { mssg.Append((Int32)objectList[i].getSessionID()); } packet.Append(mssg); } /// /// Initializes the server, cursors and objects. /// private void init() { TuioTime.initSession(); cursorList = new List(); objectList = new List(); transmitter = new OSCTransmitter(host, port); } /// /// Sends cursors and objects. /// /// list of cursors to send /// list of objects to send private void sendMessage(List cursorList, List objectList) { OSCBundle packet = new OSCBundle(); OSCMessage currentMessage; // cursors addAliveCursorMessagesToBundle(packet); TuioCursor tcur; for (int i = 0; i < cursorList.Count; i++) { tcur = cursorList[i]; currentMessage = new OSCMessage("/tuio/2Dcur"); currentMessage.Append("set"); currentMessage.Append((Int32)tcur.getSessionID()); currentMessage.Append(tcur.getX()); currentMessage.Append(tcur.getY()); currentMessage.Append(tcur.getXSpeed()); currentMessage.Append(tcur.getYSpeed()); currentMessage.Append(tcur.getMotionAccel()); packet.Append(currentMessage); } currentMessage = new OSCMessage("/tuio/2Dcur"); currentMessage.Append("fseq"); currentMessage.Append(-1); //sequence_id; actually -1 stands for redundant bundle packet.Append(currentMessage); transmitter.Send(packet); // objects packet = new OSCBundle(); addAliveObjectMessagesToBundle(packet); TuioObject tobj; for (int i = 0; i < objectList.Count; i++) { tobj = objectList[i]; currentMessage = new OSCMessage("/tuio/2Dobj"); currentMessage.Append("set"); currentMessage.Append((Int32)tobj.getSessionID()); currentMessage.Append(tobj.getSymbolID()); currentMessage.Append(tobj.getX()); currentMessage.Append(tobj.getY()); currentMessage.Append(tobj.getAngle()); currentMessage.Append(tobj.getXSpeed()); currentMessage.Append(tobj.getYSpeed()); currentMessage.Append(tobj.getRotationSpeed()); currentMessage.Append(tobj.getMotionAccel()); currentMessage.Append(tobj.getRotationAccel()); packet.Append(currentMessage); } currentMessage = new OSCMessage("/tuio/2Dobj"); currentMessage.Append("fseq"); currentMessage.Append(-1); //sequence_id; actually -1 stands for redundant bundle packet.Append(currentMessage); transmitter.Send(packet); } } }