TuioCommunicator.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using BBIWARG.Input.InputHandling;
  2. using BBIWARG.Recognition.PalmRecognition;
  3. using BBIWARG.Recognition.TouchRecognition;
  4. using BBIWARG.Utility;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using TUIO;
  11. namespace BBIWARG.TUIO
  12. {
  13. /// <summary>
  14. /// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a <see cref="TuioServer"/>.
  15. /// </summary>
  16. internal class TuioCommunicator
  17. {
  18. /// <summary>
  19. /// the tuio server
  20. /// </summary>
  21. private TuioServer server;
  22. /// <summary>
  23. /// dictionary of lists of tuio cursors indexed by touch id
  24. /// </summary>
  25. private Dictionary<int, TuioCursor> tcursors;
  26. /// <summary>
  27. /// dictionary of lists of tuio objects indexed by palm id
  28. /// </summary>
  29. private Dictionary<int, List<TuioObject>> tobjects;
  30. /// <summary>
  31. /// Constructs a TuioCommunicator.
  32. /// </summary>
  33. /// <param name="host">server ip</param>
  34. /// <param name="port">server port</param>
  35. public TuioCommunicator(string host, int port)
  36. {
  37. server = new TuioServer(host, port);
  38. tcursors = new Dictionary<int, TuioCursor>();
  39. tobjects = new Dictionary<int, List<TuioObject>>();
  40. }
  41. /// <summary>
  42. /// Tries to parse an ip address string.
  43. /// </summary>
  44. /// <param name="ipIn">the ip address string to parse</param>
  45. /// <param name="ipOut">out parameter for the ip address in *.*.*.* format if ipIn is valid and null otherwise</param>
  46. /// <returns>true iff ipIn is a valid ip address</returns>
  47. public static bool tryParseIPAddress(String ipIn, out String ipOut)
  48. {
  49. IPAddress ipAddress;
  50. bool result = IPAddress.TryParse(ipIn, out ipAddress) && ipAddress.AddressFamily == AddressFamily.InterNetwork;
  51. if (result)
  52. ipOut = ipAddress.ToString();
  53. else
  54. ipOut = null;
  55. return result;
  56. }
  57. /// <summary>
  58. /// Tries to parse a port string.
  59. /// </summary>
  60. /// <param name="portIn">the port string to parse</param>
  61. /// <param name="portOut">out parameter for the port if portIn is valid and undefined otherwise</param>
  62. /// <returns>true iff portIn is a valid port</returns>
  63. public static bool tryParsePort(String portIn, out Int16 portOut)
  64. {
  65. return Int16.TryParse(portIn, out portOut);
  66. }
  67. /// <summary>
  68. /// Closes the server.
  69. /// </summary>
  70. public void close()
  71. {
  72. server.close();
  73. }
  74. /// <summary>
  75. /// Handles the event that a new frame is finished processing by updating the cursors and objects and sending them.
  76. /// </summary>
  77. /// <param name="sender">event sender</param>
  78. /// <param name="e">event arguments</param>
  79. public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
  80. {
  81. server.initFrame();
  82. FrameData frameData = e.FrameData;
  83. lock (frameData)
  84. {
  85. if (frameData.ResetFlag)
  86. reset();
  87. foreach (TouchEvent te in frameData.TouchEvents)
  88. {
  89. switch (te.Type)
  90. {
  91. case TouchEventType.Down:
  92. TuioCursor tcur = server.addTuioCursor(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
  93. tcursors.Add(te.Touch.TrackID, tcur);
  94. break;
  95. case TouchEventType.Move:
  96. server.updateTuioCursor(tcursors[te.Touch.TrackID], te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
  97. break;
  98. case TouchEventType.Up:
  99. server.removeTuioCursor(tcursors[te.Touch.TrackID]);
  100. tcursors.Remove(te.Touch.TrackID);
  101. break;
  102. }
  103. }
  104. List<int> updatedIDs = new List<int>();
  105. foreach (Palm palm in frameData.TrackedPalms)
  106. {
  107. if (tobjects.Keys.Contains(palm.TrackID))
  108. {
  109. // update / move
  110. List<TuioObject> palmTobjs = tobjects[palm.TrackID];
  111. Vector2D[] corners = palm.Quad.Corners;
  112. for (int i = 0; i < 4; i++)
  113. server.updateTuioObject(
  114. palmTobjs[i],
  115. corners[i].X,
  116. corners[i].Y,
  117. frameData.DepthImage.getDepthAt((int) corners[i].X, (int) corners[i].Y));
  118. updatedIDs.Add(palm.TrackID);
  119. }
  120. else
  121. {
  122. // add / create
  123. List<TuioObject> palmTobjs = new List<TuioObject>();
  124. Vector2D[] corners = palm.Quad.Corners;
  125. for (int i = 0; i < 4; i++)
  126. {
  127. palmTobjs.Add(server.addTuioObject(
  128. corners[i].X,
  129. corners[i].Y,
  130. frameData.DepthImage.getDepthAt((int) corners[i].X, (int) corners[i].Y))); //palm.TrackID + 0.1f * i));
  131. }
  132. tobjects.Add(palm.TrackID, palmTobjs);
  133. updatedIDs.Add(palm.TrackID);
  134. }
  135. }
  136. // remove
  137. List<int> ids = tobjects.Keys.ToList();
  138. for (int i = ids.Count - 1; i >= 0; i--)
  139. {
  140. int id = ids[i];
  141. if (!updatedIDs.Contains(id))
  142. {
  143. foreach (TuioObject tobj in tobjects[id])
  144. server.removeTuioObject(tobj);
  145. tobjects.Remove(id);
  146. }
  147. }
  148. }
  149. server.commitFrame();
  150. }
  151. /// <summary>
  152. /// Resets the server by removing all cursors and objects.
  153. /// </summary>
  154. public void reset()
  155. {
  156. foreach (int id in tcursors.Keys)
  157. server.removeTuioCursor(tcursors[id]);
  158. tcursors.Clear();
  159. foreach (int id in tobjects.Keys)
  160. foreach (TuioObject tobj in tobjects[id])
  161. server.removeTuioObject(tobj);
  162. tobjects.Clear();
  163. }
  164. }
  165. }