using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using bbiwarg.Recognition.TouchRecognition; using bbiwarg.Recognition.PalmRecognition; using bbiwarg.Utility; using bbiwarg.Input.InputHandling; using TUIO; namespace bbiwarg.TUIO { /// /// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a . /// class TuioCommunicator { /// /// the tuio server /// private TuioServer server; /// /// dictionary of lists of tuio cursors indexed by touch id /// private Dictionary tcursors; /// /// dictionary of lists of tuio objects indexed by palm id /// private Dictionary> tobjects; /// /// Constructs a TuioCommunicator. /// /// server ip /// server port public TuioCommunicator(string host, int port) { server = new TuioServer(host, port); tcursors = new Dictionary(); tobjects = new Dictionary>(); } /// /// Handles the event that a new frame is finished processing by updating the cursors and objects and sending them. /// /// event sender /// event arguments public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e) { server.initFrame(); FrameData frameData = e.FrameData; lock (frameData) { if (frameData.ResetFlag) reset(); foreach (TouchEvent te in frameData.TouchEvents) { switch (te.Type) { case TouchEventType.Down: TuioCursor tcur = server.addTuioCursor(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y); tcursors.Add(te.Touch.TrackID, tcur); break; case TouchEventType.Move: server.updateTuioCursor(tcursors[te.Touch.TrackID], te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y); break; case TouchEventType.Up: server.removeTuioCursor(tcursors[te.Touch.TrackID]); tcursors.Remove(te.Touch.TrackID); break; } } List updatedIDs = new List(); foreach (Palm palm in frameData.TrackedPalms) { if (tobjects.Keys.Contains(palm.TrackID)) { // update / move List palmTobjs = tobjects[palm.TrackID]; Vector2D[] corners = palm.Quad.Corners; for (int i = 0; i < 4; i++) server.updateTuioObject(palmTobjs[i], corners[i].X, corners[i].Y); updatedIDs.Add(palm.TrackID); } else { // add / create List palmTobjs = new List(); Vector2D[] corners = palm.Quad.Corners; for (int i = 0; i < 4; i++) palmTobjs.Add(server.addTuioObject(corners[i].X, corners[i].Y, palm.TrackID + 0.1f * i)); tobjects.Add(palm.TrackID, palmTobjs); updatedIDs.Add(palm.TrackID); } } // remove List ids = tobjects.Keys.ToList(); for (int i = ids.Count - 1; i >= 0; i--) { int id = ids[i]; if (!updatedIDs.Contains(id)) { foreach (TuioObject tobj in tobjects[id]) server.removeTuioObject(tobj); tobjects.Remove(id); } } } server.commitFrame(); } /// /// Closes the server. /// public void close() { server.close(); } /// /// Resets the server by removing all cursors and objects. /// public void reset() { foreach (int id in tcursors.Keys) server.removeTuioCursor(tcursors[id]); tcursors.Clear(); foreach (int id in tobjects.Keys) foreach (TuioObject tobj in tobjects[id]) server.removeTuioObject(tobj); tobjects.Clear(); } /// /// Tries to parse an ip address string. /// /// the ip address string to parse /// out parameter for the ip address in *.*.*.* format if ipIn is valid and null otherwise /// true iff ipIn is a valid ip address public static bool tryParseIPAddress(String ipIn, out String ipOut) { IPAddress ipAddress; bool result = (IPAddress.TryParse(ipIn, out ipAddress) && ipAddress.AddressFamily == AddressFamily.InterNetwork); if (result) ipOut = ipAddress.ToString(); else ipOut = null; return result; } /// /// Tries to parse a port string. /// /// the port string to parse /// out parameter for the port as an Int16 if portIn is valid and undefined otherwise /// true iff portIn is a valid port public static bool tryParsePort(String portIn, out Int16 portOut) { return Int16.TryParse(portIn, out portOut); } } }