TuioCommunicatorHack.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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.Drawing;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. using TUIO;
  12. namespace BBIWARG.TUIO
  13. {
  14. /// <summary>
  15. /// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a <see cref="TuioServer"/>.
  16. /// </summary>
  17. internal class TuioCommunicatorHack
  18. {
  19. /// <summary>
  20. /// the tuio server
  21. /// </summary>
  22. private TuioServer server;
  23. /// <summary>
  24. /// dictionary of lists of tuio cursors indexed by touch id
  25. /// </summary>
  26. private Dictionary<int, TuioCursor> tcursors;
  27. /// <summary>
  28. /// dictionary of lists of tuio objects indexed by palm id
  29. /// </summary>
  30. private Dictionary<int, List<TuioObject>> tobjects;
  31. /// <summary>
  32. /// Constructs a TuioCommunicator.
  33. /// </summary>
  34. /// <param name="host">server ip</param>
  35. /// <param name="port">server port</param>
  36. public TuioCommunicatorHack(string host, int port)
  37. {
  38. server = new TuioServer(host, port);
  39. tcursors = new Dictionary<int, TuioCursor>();
  40. tobjects = new Dictionary<int, List<TuioObject>>();
  41. }
  42. /// <summary>
  43. /// Tries to parse an ip address string.
  44. /// </summary>
  45. /// <param name="ipIn">the ip address string to parse</param>
  46. /// <param name="ipOut">out parameter for the ip address in *.*.*.* format if ipIn is valid and null otherwise</param>
  47. /// <returns>true iff ipIn is a valid ip address</returns>
  48. public static bool tryParseIPAddress(String ipIn, out String ipOut)
  49. {
  50. IPAddress ipAddress;
  51. bool result = IPAddress.TryParse(ipIn, out ipAddress) && ipAddress.AddressFamily == AddressFamily.InterNetwork;
  52. if (result)
  53. ipOut = ipAddress.ToString();
  54. else
  55. ipOut = null;
  56. return result;
  57. }
  58. /// <summary>
  59. /// Tries to parse a port string.
  60. /// </summary>
  61. /// <param name="portIn">the port string to parse</param>
  62. /// <param name="portOut">out parameter for the port if portIn is valid and undefined otherwise</param>
  63. /// <returns>true iff portIn is a valid port</returns>
  64. public static bool tryParsePort(String portIn, out Int16 portOut)
  65. {
  66. return Int16.TryParse(portIn, out portOut);
  67. }
  68. /// <summary>
  69. /// Closes the server.
  70. /// </summary>
  71. public void close()
  72. {
  73. server.close();
  74. }
  75. /// <summary>
  76. /// Handles the event that a new frame is finished processing by updating the cursors and objects and sending them.
  77. /// </summary>
  78. /// <param name="sender">event sender</param>
  79. /// <param name="e">event arguments</param>
  80. public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
  81. {
  82. server.initFrame();
  83. FrameData frameData = e.FrameData;
  84. lock (frameData)
  85. {
  86. if (frameData.ResetFlag)
  87. reset();
  88. foreach (TouchEvent te in frameData.TouchEvents)
  89. {
  90. Point p = getButton(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
  91. switch (te.Type)
  92. {
  93. case TouchEventType.Down:
  94. TuioCursor tcur = server.addTuioCursor(p.X, p.Y);
  95. tcursors.Add(te.Touch.TrackID, tcur);
  96. break;
  97. case TouchEventType.Move:
  98. server.updateTuioCursor(tcursors[te.Touch.TrackID], p.X, p.Y);
  99. break;
  100. case TouchEventType.Up:
  101. server.removeTuioCursor(tcursors[te.Touch.TrackID]);
  102. tcursors.Remove(te.Touch.TrackID);
  103. break;
  104. }
  105. }
  106. List<int> updatedIDs = new List<int>();
  107. foreach (Palm palm in frameData.TrackedPalms)
  108. {
  109. if (tobjects.Keys.Contains(palm.TrackID))
  110. {
  111. // update / move
  112. List<TuioObject> palmTobjs = tobjects[palm.TrackID];
  113. Vector2D[] corners = palm.Quad.Corners;
  114. for (int i = 0; i < 4; i++)
  115. {
  116. /* BEGIN HACK */
  117. int x0 = 0;
  118. int y0 = 0;
  119. int x1 = 0;
  120. int y1 = 0;
  121. if (i == 0)
  122. {
  123. x0 = (int)corners[0].X;
  124. y0 = (int)corners[0].Y;
  125. x1 = (int)corners[2].X;
  126. y1 = (int)corners[2].Y;
  127. }
  128. else if (i == 1)
  129. {
  130. x0 = (int)corners[1].X;
  131. y0 = (int)corners[1].Y;
  132. x1 = (int)corners[3].X;
  133. y1 = (int)corners[3].Y;
  134. }
  135. else if (i == 2)
  136. {
  137. x0 = (int)corners[2].X;
  138. y0 = (int)corners[2].Y;
  139. x1 = (int)corners[0].X;
  140. y1 = (int)corners[0].Y;
  141. }
  142. else if (i == 3)
  143. {
  144. x0 = (int)corners[3].X;
  145. y0 = (int)corners[3].Y;
  146. x1 = (int)corners[1].X;
  147. y1 = (int)corners[1].Y;
  148. }
  149. /* END HACK */
  150. server.updateTuioObject(
  151. palmTobjs[i],
  152. corners[i].X,
  153. corners[i].Y,
  154. frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1));
  155. //frameData.DepthImage.getDepthAt((int)corners[i].X, (int)corners[i].Y));
  156. }
  157. updatedIDs.Add(palm.TrackID);
  158. }
  159. else
  160. {
  161. // add / create
  162. List<TuioObject> palmTobjs = new List<TuioObject>();
  163. Vector2D[] corners = palm.Quad.Corners;
  164. for (int i = 0; i < 4; i++)
  165. {
  166. /* BEGIN HACK */
  167. int x0 = 0;
  168. int y0 = 0;
  169. int x1 = 0;
  170. int y1 = 0;
  171. if (i == 0)
  172. {
  173. x0 = (int)corners[0].X;
  174. y0 = (int)corners[0].Y;
  175. x1 = (int)corners[2].X;
  176. y1 = (int)corners[2].Y;
  177. }
  178. else if (i == 1)
  179. {
  180. x0 = (int)corners[1].X;
  181. y0 = (int)corners[1].Y;
  182. x1 = (int)corners[3].X;
  183. y1 = (int)corners[3].Y;
  184. }
  185. else if (i == 2)
  186. {
  187. x0 = (int)corners[2].X;
  188. y0 = (int)corners[2].Y;
  189. x1 = (int)corners[0].X;
  190. y1 = (int)corners[0].Y;
  191. }
  192. else if (i == 3)
  193. {
  194. x0 = (int)corners[3].X;
  195. y0 = (int)corners[3].Y;
  196. x1 = (int)corners[1].X;
  197. y1 = (int)corners[1].Y;
  198. }
  199. /* END HACK */
  200. palmTobjs.Add(server.addTuioObject(
  201. corners[i].X,
  202. corners[i].Y,
  203. frameData.DepthImage.getDepthAtFixed(x0, y0, x1, y1))); //palm.TrackID + 0.1f * i));
  204. }
  205. tobjects.Add(palm.TrackID, palmTobjs);
  206. updatedIDs.Add(palm.TrackID);
  207. }
  208. }
  209. // remove
  210. List<int> ids = tobjects.Keys.ToList();
  211. for (int i = ids.Count - 1; i >= 0; i--)
  212. {
  213. int id = ids[i];
  214. if (!updatedIDs.Contains(id))
  215. {
  216. foreach (TuioObject tobj in tobjects[id])
  217. server.removeTuioObject(tobj);
  218. tobjects.Remove(id);
  219. }
  220. }
  221. }
  222. server.commitFrame();
  223. }
  224. private Point getButton(float rX , float rY)
  225. {
  226. int activeRow = (int)Math.Min(rY * Parameters.ActiveTouches.Count,
  227. Parameters.PalmGridDefaultNumRows - 1);
  228. int activeCol = (int)Math.Min(rX * Parameters.ActiveTouches.ElementAt(activeRow).Count,
  229. Parameters.ActiveTouches.ElementAt(activeRow).Count - 1);
  230. if (activeRow != Parameters.PalmSliderPos)
  231. return new Point(activeRow, activeCol);
  232. else
  233. return new Point(activeRow, Parameters.PalmSliderCurr);
  234. }
  235. /// <summary>
  236. /// Resets the server by removing all cursors and objects.
  237. /// </summary>
  238. public void reset()
  239. {
  240. foreach (int id in tcursors.Keys)
  241. server.removeTuioCursor(tcursors[id]);
  242. tcursors.Clear();
  243. foreach (int id in tobjects.Keys)
  244. foreach (TuioObject tobj in tobjects[id])
  245. server.removeTuioObject(tobj);
  246. tobjects.Clear();
  247. }
  248. }
  249. }