TouchEventVisualizer.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using bbiwarg.Recognition.TouchRecognition;
  9. using bbiwarg.Utility;
  10. using bbiwarg.Input.InputHandling;
  11. namespace bbiwarg.Output.DebugOutput
  12. {
  13. class TouchEventVisualizer
  14. {
  15. private Object sync;
  16. private Stopwatch timer;
  17. private Dictionary<int, List<Vector2D>> activeTouches;
  18. private Dictionary<int, List<Vector2D>> oldTouches;
  19. private Dictionary<int, long> lastUpdates;
  20. private int nextFreeID;
  21. public TouchEventVisualizer()
  22. {
  23. sync = new object();
  24. reset();
  25. }
  26. public void reset()
  27. {
  28. timer = new Stopwatch();
  29. timer.Start();
  30. nextFreeID = 1;
  31. activeTouches = new Dictionary<int, List<Vector2D>>();
  32. oldTouches = new Dictionary<int, List<Vector2D>>();
  33. lastUpdates = new Dictionary<int, long>();
  34. }
  35. public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
  36. {
  37. FrameData frameData = e.FrameData;
  38. lock (frameData) lock (sync)
  39. {
  40. if (frameData.ResetFlag)
  41. reset();
  42. foreach (TouchEvent te in frameData.TouchEvents)
  43. {
  44. switch (te.Type)
  45. {
  46. case TouchEventType.Down:
  47. activeTouches.Add(te.Touch.TrackID, new List<Vector2D>());
  48. activeTouches[te.Touch.TrackID].Add(te.Touch.RelativePosition);
  49. break;
  50. case TouchEventType.Move:
  51. activeTouches[te.Touch.TrackID].Add(te.Touch.RelativePosition);
  52. break;
  53. case TouchEventType.Up:
  54. activeTouches[te.Touch.TrackID].Add(te.Touch.RelativePosition);
  55. oldTouches.Add(nextFreeID, activeTouches[te.Touch.TrackID]);
  56. lastUpdates.Add(nextFreeID, timer.ElapsedMilliseconds);
  57. activeTouches.Remove(te.Touch.TrackID);
  58. nextFreeID++;
  59. break;
  60. }
  61. }
  62. }
  63. }
  64. public OutputImage getOutputImage(ImageSize imageSize, int numRows, int numColumns)
  65. {
  66. lock (sync)
  67. {
  68. long currentTime = timer.ElapsedMilliseconds;
  69. removeOldPositions(currentTime - Parameters.TouchEventVisualizerFadeOutTime);
  70. OutputImage outputImage = new OutputImage(imageSize);
  71. int imageWidth = imageSize.Width;
  72. int imageHeight = imageSize.Height;
  73. // border
  74. outputImage.drawBorder(Parameters.TouchEventVisualizerGridColor);
  75. // draw grid
  76. int widthPerColumn = imageWidth / numColumns;
  77. int heightPerRow = imageHeight / numRows;
  78. // find active blocks
  79. bool[,] activeBlocks = new bool[numRows, numColumns];
  80. if (numRows * numColumns > 1)
  81. {
  82. foreach (List<Vector2D> positions in activeTouches.Values)
  83. {
  84. Vector2D lastPosition = positions.Last();
  85. int activeRow = (int)Math.Min(lastPosition.Y * numRows, numRows - 1);
  86. int activeCol = (int)Math.Min(lastPosition.X * numColumns, numColumns - 1);
  87. activeBlocks[activeRow, activeCol] = true;
  88. }
  89. }
  90. // draw blocks
  91. int index = 1;
  92. for (int row = 0; row < numRows; row++)
  93. {
  94. for (int col = 0; col < numColumns; col++)
  95. {
  96. if (activeBlocks[row, col])
  97. outputImage.fillRectangle(new Rectangle(col * widthPerColumn, row * heightPerRow, widthPerColumn, heightPerRow), Parameters.TouchEventVisualizerActiveBlockColor);
  98. int x = (int)((col + 0.5f) * widthPerColumn) - 5;
  99. int y = (int)((row + 0.5f) * heightPerRow) + 5;
  100. outputImage.drawText(new Point(x,y), index.ToString(), Parameters.TouchEventVisualizerTextColor);
  101. index++;
  102. }
  103. }
  104. // draw grid
  105. for (int i = 0; i <= numColumns; i++)
  106. outputImage.drawLineSegment(new LineSegment2D(new Vector2D(i * widthPerColumn, 0), new Vector2D(i * widthPerColumn, imageHeight - 1)), Parameters.TouchEventVisualizerGridColor);
  107. for (int i = 0; i <= numRows; i++)
  108. outputImage.drawLineSegment(new LineSegment2D(new Vector2D(0, i * heightPerRow), new Vector2D(imageWidth - 1, i * heightPerRow)), Parameters.TouchEventVisualizerGridColor);
  109. // draw active touches
  110. foreach (List<Vector2D> positions in activeTouches.Values)
  111. outputImage.drawTouchGesture(positions, imageSize.MaxPixel);
  112. // draw old touches (fade out)
  113. foreach (int id in oldTouches.Keys)
  114. {
  115. List<Vector2D> positions = oldTouches[id];
  116. long lastUpdate = lastUpdates[id];
  117. float opacity = 1 - ((currentTime - lastUpdate) / (float)Parameters.TouchEventVisualizerFadeOutTime);
  118. outputImage.drawTouchGesture(positions, imageSize.MaxPixel, opacity);
  119. }
  120. return outputImage;
  121. }
  122. }
  123. private void removeOldPositions(long breakTime)
  124. {
  125. long currentTime = timer.ElapsedMilliseconds;
  126. List<int> ids = new List<int>(lastUpdates.Keys);
  127. for (int i = ids.Count - 1; i >= 0; i--)
  128. {
  129. int id = ids[i];
  130. if (breakTime > lastUpdates[id])
  131. {
  132. oldTouches.Remove(id);
  133. lastUpdates.Remove(id);
  134. }
  135. }
  136. }
  137. }
  138. }