GUIAnimEvents.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using BansheeEngine;
  5. namespace BansheeEditor
  6. {
  7. /** @addtogroup AnimationEditor
  8. * @{
  9. */
  10. public class GUIAnimEvents
  11. {
  12. private const int EVENT_HALF_WIDTH = 2;
  13. private float rangeLength = 60.0f;
  14. private float rangeOffset = 0.0f;
  15. private int fps = 1;
  16. private GUICanvas canvas;
  17. private int width;
  18. private int height;
  19. private int drawableWidth;
  20. private AnimationEvent[] events = new AnimationEvent[0];
  21. private bool[] selectedEvents = new bool[0];
  22. public GUIAnimEvents(GUILayout layout, int width, int height)
  23. {
  24. canvas = new GUICanvas();
  25. layout.AddElement(canvas);
  26. SetSize(width, height);
  27. }
  28. public bool FindEvent(Vector2I windowCoords, out int eventIdx)
  29. {
  30. Rect2I bounds = canvas.Bounds;
  31. if (windowCoords.x < (bounds.x + GUIGraphTime.PADDING) || windowCoords.x >= (bounds.x + bounds.width - GUIGraphTime.PADDING) ||
  32. windowCoords.y < bounds.y || windowCoords.y >= (bounds.y + bounds.height))
  33. {
  34. eventIdx = -1;
  35. return false;
  36. }
  37. Vector2I relativeCoords = windowCoords - new Vector2I(bounds.x + GUIGraphTime.PADDING, bounds.y);
  38. for (int i = 0; i < events.Length; i++)
  39. {
  40. AnimationEvent evnt = events[i];
  41. int xPos = (int)(((evnt.Time - rangeOffset) / GetRange()) * drawableWidth) + GUIGraphTime.PADDING;
  42. if (relativeCoords.x >= (xPos - EVENT_HALF_WIDTH) || relativeCoords.y >= (xPos + EVENT_HALF_WIDTH))
  43. {
  44. eventIdx = i;
  45. return true;
  46. }
  47. }
  48. eventIdx = -1;
  49. return false;
  50. }
  51. public void SetSize(int width, int height)
  52. {
  53. this.width = width;
  54. this.height = height;
  55. canvas.SetWidth(width);
  56. canvas.SetHeight(height);
  57. drawableWidth = Math.Max(0, width - GUIGraphTime.PADDING * 2);
  58. }
  59. public void SetRange(float length)
  60. {
  61. rangeLength = Math.Max(0.0f, length);
  62. }
  63. public void SetOffset(float offset)
  64. {
  65. rangeOffset = offset;
  66. }
  67. public void SetFPS(int fps)
  68. {
  69. this.fps = Math.Max(1, fps);
  70. }
  71. public void SetEvents(AnimationEvent[] events, bool[] selected)
  72. {
  73. int numEvents;
  74. if (events != null)
  75. numEvents = events.Length;
  76. else
  77. numEvents = 0;
  78. this.events = new AnimationEvent[numEvents];
  79. if(events != null)
  80. Array.Copy(events, this.events, numEvents);
  81. selectedEvents = new bool[numEvents];
  82. if(selected != null)
  83. Array.Copy(selected, selectedEvents, MathEx.Min(numEvents, selected.Length));
  84. }
  85. private void DrawEventMarker(float t, bool selected)
  86. {
  87. int xPos = (int)(((t - rangeOffset) / GetRange()) * drawableWidth) + GUIGraphTime.PADDING;
  88. Vector2I a = new Vector2I(xPos - EVENT_HALF_WIDTH, height - 1);
  89. Vector2I b = new Vector2I(xPos, 0);
  90. Vector2I c = new Vector2I(xPos + EVENT_HALF_WIDTH, height - 1);
  91. Vector2I d = new Vector2I(xPos, 0);
  92. // Draw square shape
  93. Vector2I[] linePoints = { a, b, c, d, a };
  94. Vector2I[] trianglePoints = { b, c, a, d };
  95. Color outerColor = selected ? Color.BansheeOrange : Color.Black;
  96. canvas.DrawTriangleStrip(trianglePoints, Color.White, 101);
  97. canvas.DrawPolyLine(linePoints, outerColor, 100);
  98. }
  99. private float GetRange(bool padding = false)
  100. {
  101. float spf = 1.0f / fps;
  102. float range = rangeLength;
  103. if (padding)
  104. {
  105. float lengthPerPixel = rangeLength / drawableWidth;
  106. range += lengthPerPixel * GUIGraphTime.PADDING;
  107. }
  108. return ((int)range / spf) * spf;
  109. }
  110. /// <summary>
  111. /// Rebuilds the internal GUI elements. Should be called whenever timeline properties change.
  112. /// </summary>
  113. public void Rebuild()
  114. {
  115. canvas.Clear();
  116. float range = GetRange();
  117. float lengthPerPixel = rangeLength / drawableWidth;
  118. float eventHalfWidth = lengthPerPixel * EVENT_HALF_WIDTH;
  119. for (int i = 0; i < events.Length; i++)
  120. {
  121. float t = events[i].Time;
  122. float min = t - eventHalfWidth;
  123. float max = t + eventHalfWidth;
  124. if (max < rangeOffset || min > (rangeOffset + range))
  125. continue;
  126. DrawEventMarker(t, selectedEvents[i]);
  127. }
  128. }
  129. }
  130. /** @} */
  131. }