TuioCommunicator.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. {
  114. /* BEGIN HACK */
  115. int x0 = 0;
  116. int y0 = 0;
  117. int x1 = 0;
  118. int y1 = 0;
  119. if (i == 0)
  120. {
  121. x0 = (int)corners[0].X;
  122. y0 = (int)corners[0].Y;
  123. x1 = (int)corners[2].X;
  124. y1 = (int)corners[2].Y;
  125. }
  126. else if (i == 1)
  127. {
  128. x0 = (int)corners[1].X;
  129. y0 = (int)corners[1].Y;
  130. x1 = (int)corners[3].X;
  131. y1 = (int)corners[3].Y;
  132. }
  133. else if (i == 2)
  134. {
  135. x0 = (int)corners[2].X;
  136. y0 = (int)corners[2].Y;
  137. x1 = (int)corners[0].X;
  138. y1 = (int)corners[0].Y;
  139. }
  140. else if (i == 3)
  141. {
  142. x0 = (int)corners[3].X;
  143. y0 = (int)corners[3].Y;
  144. x1 = (int)corners[1].X;
  145. y1 = (int)corners[1].Y;
  146. }
  147. /* END HACK */
  148. server.updateTuioObject(
  149. palmTobjs[i],
  150. corners[i].X,
  151. corners[i].Y,
  152. frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1));
  153. //frameData.DepthImage.getDepthAt((int)corners[i].X, (int)corners[i].Y));
  154. }
  155. updatedIDs.Add(palm.TrackID);
  156. }
  157. else
  158. {
  159. // add / create
  160. List<TuioObject> palmTobjs = new List<TuioObject>();
  161. Vector2D[] corners = palm.Quad.Corners;
  162. for (int i = 0; i < 4; i++)
  163. {
  164. /* BEGIN HACK */
  165. int x0 = 0;
  166. int y0 = 0;
  167. int x1 = 0;
  168. int y1 = 0;
  169. if (i == 0)
  170. {
  171. x0 = (int)corners[0].X;
  172. y0 = (int)corners[0].Y;
  173. x1 = (int)corners[2].X;
  174. y1 = (int)corners[2].Y;
  175. }
  176. else if (i == 1)
  177. {
  178. x0 = (int)corners[1].X;
  179. y0 = (int)corners[1].Y;
  180. x1 = (int)corners[3].X;
  181. y1 = (int)corners[3].Y;
  182. }
  183. else if (i == 2)
  184. {
  185. x0 = (int)corners[2].X;
  186. y0 = (int)corners[2].Y;
  187. x1 = (int)corners[0].X;
  188. y1 = (int)corners[0].Y;
  189. }
  190. else if (i == 3)
  191. {
  192. x0 = (int)corners[3].X;
  193. y0 = (int)corners[3].Y;
  194. x1 = (int)corners[1].X;
  195. y1 = (int)corners[1].Y;
  196. }
  197. /* END HACK */
  198. palmTobjs.Add(server.addTuioObject(
  199. corners[i].X,
  200. corners[i].Y,
  201. frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1))); //palm.TrackID + 0.1f * i));
  202. }
  203. tobjects.Add(palm.TrackID, palmTobjs);
  204. updatedIDs.Add(palm.TrackID);
  205. }
  206. }
  207. // remove
  208. List<int> ids = tobjects.Keys.ToList();
  209. for (int i = ids.Count - 1; i >= 0; i--)
  210. {
  211. int id = ids[i];
  212. if (!updatedIDs.Contains(id))
  213. {
  214. foreach (TuioObject tobj in tobjects[id])
  215. server.removeTuioObject(tobj);
  216. tobjects.Remove(id);
  217. }
  218. }
  219. }
  220. server.commitFrame();
  221. }
  222. /// <summary>
  223. /// Resets the server by removing all cursors and objects.
  224. /// </summary>
  225. public void reset()
  226. {
  227. foreach (int id in tcursors.Keys)
  228. server.removeTuioCursor(tcursors[id]);
  229. tcursors.Clear();
  230. foreach (int id in tobjects.Keys)
  231. foreach (TuioObject tobj in tobjects[id])
  232. server.removeTuioObject(tobj);
  233. tobjects.Clear();
  234. }
  235. }
  236. }