using BBIWARG.Input.InputHandling; using BBIWARG.Recognition.PalmRecognition; using BBIWARG.Recognition.TouchRecognition; using BBIWARG.Utility; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using TUIO; namespace BBIWARG.TUIO { /// /// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a . /// internal 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>(); } /// /// 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 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); } /// /// Closes the server. /// public void close() { server.close(); } /// /// 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++) { /* BEGIN HACK */ int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; if (i == 0) { x0 = (int)corners[0].X; y0 = (int)corners[0].Y; x1 = (int)corners[2].X; y1 = (int)corners[2].Y; } else if (i == 1) { x0 = (int)corners[1].X; y0 = (int)corners[1].Y; x1 = (int)corners[3].X; y1 = (int)corners[3].Y; } else if (i == 2) { x0 = (int)corners[2].X; y0 = (int)corners[2].Y; x1 = (int)corners[0].X; y1 = (int)corners[0].Y; } else if (i == 3) { x0 = (int)corners[3].X; y0 = (int)corners[3].Y; x1 = (int)corners[1].X; y1 = (int)corners[1].Y; } /* END HACK */ server.updateTuioObject( palmTobjs[i], corners[i].X, corners[i].Y, frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1)); //frameData.DepthImage.getDepthAt((int)corners[i].X, (int)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++) { /* BEGIN HACK */ int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; if (i == 0) { x0 = (int)corners[0].X; y0 = (int)corners[0].Y; x1 = (int)corners[2].X; y1 = (int)corners[2].Y; } else if (i == 1) { x0 = (int)corners[1].X; y0 = (int)corners[1].Y; x1 = (int)corners[3].X; y1 = (int)corners[3].Y; } else if (i == 2) { x0 = (int)corners[2].X; y0 = (int)corners[2].Y; x1 = (int)corners[0].X; y1 = (int)corners[0].Y; } else if (i == 3) { x0 = (int)corners[3].X; y0 = (int)corners[3].Y; x1 = (int)corners[1].X; y1 = (int)corners[1].Y; } /* END HACK */ palmTobjs.Add(server.addTuioObject( corners[i].X, corners[i].Y, frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1))); //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(); } /// /// 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(); } } }