TuioCommunicator.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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(palmTobjs[i], corners[i].X, corners[i].Y);
  114. updatedIDs.Add(palm.TrackID);
  115. }
  116. else
  117. {
  118. // add / create
  119. List<TuioObject> palmTobjs = new List<TuioObject>();
  120. Vector2D[] corners = palm.Quad.Corners;
  121. for (int i = 0; i < 4; i++)
  122. palmTobjs.Add(server.addTuioObject(corners[i].X, corners[i].Y, palm.TrackID + 0.1f * i));
  123. tobjects.Add(palm.TrackID, palmTobjs);
  124. updatedIDs.Add(palm.TrackID);
  125. }
  126. }
  127. // remove
  128. List<int> ids = tobjects.Keys.ToList();
  129. for (int i = ids.Count - 1; i >= 0; i--)
  130. {
  131. int id = ids[i];
  132. if (!updatedIDs.Contains(id))
  133. {
  134. foreach (TuioObject tobj in tobjects[id])
  135. server.removeTuioObject(tobj);
  136. tobjects.Remove(id);
  137. }
  138. }
  139. }
  140. server.commitFrame();
  141. }
  142. /// <summary>
  143. /// Resets the server by removing all cursors and objects.
  144. /// </summary>
  145. public void reset()
  146. {
  147. foreach (int id in tcursors.Keys)
  148. server.removeTuioCursor(tcursors[id]);
  149. tcursors.Clear();
  150. foreach (int id in tobjects.Keys)
  151. foreach (TuioObject tobj in tobjects[id])
  152. server.removeTuioObject(tobj);
  153. tobjects.Clear();
  154. }
  155. }
  156. }