SceneAxesHandle.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using System;
  2. using BansheeEngine;
  3. namespace BansheeEditor
  4. {
  5. /// <summary>
  6. /// Draws axes that display the orientation of the scene camera. Also allows you to change camera orientation along
  7. /// one of the axes, or change projection modes.
  8. /// </summary>
  9. [CustomHandle(null)]
  10. internal class SceneAxesHandle : Handle
  11. {
  12. public const UInt64 LAYER = 0x7000000000000000;
  13. private const float CONE_HEIGHT = 0.25f;
  14. private const float CONE_RADIUS = 0.175f;
  15. private const float BOX_EXTENT = 0.2f;
  16. private const float DISABLE_THRESHOLD = 0.9f;
  17. private HandleSliderLine xAxis;
  18. private HandleSliderLine yAxis;
  19. private HandleSliderLine zAxis;
  20. private HandleSliderLine xNegAxis;
  21. private HandleSliderLine yNegAxis;
  22. private HandleSliderLine zNegAxis;
  23. private HandleSliderPlane projTypePlane;
  24. private bool[] clickStates = new bool[7];
  25. private Vector3 position = Vector3.Zero;
  26. private Quaternion rotation = Quaternion.Identity;
  27. /// <summary>
  28. /// Creates a new scene axes handle.
  29. /// </summary>
  30. public SceneAxesHandle()
  31. {
  32. xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f - BOX_EXTENT, false, LAYER);
  33. yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f - BOX_EXTENT, false, LAYER);
  34. zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f - BOX_EXTENT, false, LAYER);
  35. xNegAxis = new HandleSliderLine(this, -Vector3.XAxis, 1.0f - BOX_EXTENT, false, LAYER);
  36. yNegAxis = new HandleSliderLine(this, -Vector3.YAxis, 1.0f - BOX_EXTENT, false, LAYER);
  37. zNegAxis = new HandleSliderLine(this, -Vector3.ZAxis, 1.0f - BOX_EXTENT, false, LAYER);
  38. projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, BOX_EXTENT * 2.0f, false, LAYER);
  39. }
  40. /// <inheritdoc/>
  41. protected internal override void PreInput()
  42. {
  43. Camera cam = EditorApplication.SceneViewCamera;
  44. if (cam == null)
  45. return;
  46. position = new Vector3(0, 0, -5.0f);
  47. rotation = cam.SceneObject.Rotation.Inverse;
  48. xAxis.Position = position + new Vector3(BOX_EXTENT, 0.0f, 0.0f);
  49. yAxis.Position = position + new Vector3(0.0f, BOX_EXTENT, 0.0f);
  50. zAxis.Position = position + new Vector3(0.0f, 0.0f, BOX_EXTENT);
  51. xAxis.Rotation = rotation;
  52. yAxis.Rotation = rotation;
  53. zAxis.Rotation = rotation;
  54. xNegAxis.Position = position - new Vector3(BOX_EXTENT, 0.0f, 0.0f);
  55. yNegAxis.Position = position - new Vector3(0.0f, BOX_EXTENT, 0.0f);
  56. zNegAxis.Position = position - new Vector3(0.0f, 0.0f, BOX_EXTENT);
  57. xNegAxis.Rotation = rotation;
  58. yNegAxis.Rotation = rotation;
  59. zNegAxis.Rotation = rotation;
  60. Vector3 cameraForward = cam.SceneObject.Forward;
  61. xAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)) < DISABLE_THRESHOLD;
  62. yAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)) < DISABLE_THRESHOLD;
  63. zAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)) < DISABLE_THRESHOLD;
  64. xNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)) < DISABLE_THRESHOLD;
  65. xNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)) < DISABLE_THRESHOLD;
  66. xNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)) < DISABLE_THRESHOLD;
  67. Vector3 freeAxisOffset = new Vector3(-BOX_EXTENT, -BOX_EXTENT, 0.2f);
  68. projTypePlane.Rotation = Quaternion.Identity;
  69. projTypePlane.Position = position + freeAxisOffset;
  70. }
  71. /// <inheritdoc/>
  72. protected internal override void PostInput()
  73. {
  74. var axes = new []
  75. {
  76. new Tuple<HandleSlider, Action>(xAxis, () => RotateCameraTo(Vector3.XAxis)),
  77. new Tuple<HandleSlider, Action>(yAxis, () => RotateCameraTo(Vector3.YAxis)),
  78. new Tuple<HandleSlider, Action>(zAxis, () => RotateCameraTo(Vector3.ZAxis)),
  79. new Tuple<HandleSlider, Action>(xNegAxis, () => RotateCameraTo(-Vector3.XAxis)),
  80. new Tuple<HandleSlider, Action>(yNegAxis, () => RotateCameraTo(-Vector3.YAxis)),
  81. new Tuple<HandleSlider, Action>(zNegAxis, () => RotateCameraTo(-Vector3.ZAxis)),
  82. new Tuple<HandleSlider, Action>(projTypePlane, ToggleProjectionType)
  83. };
  84. for (int i = 0; i < axes.Length; i++)
  85. {
  86. if (axes[i].Item1.State == HandleSlider.StateType.Active)
  87. {
  88. if (!clickStates[i])
  89. {
  90. axes[i].Item2();
  91. clickStates[i] = true;
  92. }
  93. }
  94. else
  95. {
  96. clickStates[i] = false;
  97. }
  98. }
  99. }
  100. /// <inheritdoc/>
  101. protected internal override void Draw()
  102. {
  103. HandleDrawing.Layer = LAYER;
  104. HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
  105. Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
  106. // Draw 1D arrows
  107. Color xColor = Color.Red;
  108. if (xAxis.State == HandleSlider.StateType.Active)
  109. xColor = Color.White;
  110. else if (xAxis.State == HandleSlider.StateType.Hover)
  111. xColor = Color.BansheeOrange;
  112. xColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)), 0.8f, 1.0f);
  113. HandleDrawing.Color = xColor;
  114. Vector3 xLineStart = Vector3.XAxis* BOX_EXTENT;
  115. Vector3 xConeStart = Vector3.XAxis * (1.0f - CONE_HEIGHT);
  116. HandleDrawing.DrawLine(xLineStart, xConeStart);
  117. HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS);
  118. Color yColor = Color.Green;
  119. if (yAxis.State == HandleSlider.StateType.Active)
  120. yColor = Color.White;
  121. else if (yAxis.State == HandleSlider.StateType.Hover)
  122. yColor = Color.BansheeOrange;
  123. yColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)), 0.8f, 1.0f);
  124. HandleDrawing.Color = yColor;
  125. Vector3 yLineStart = Vector3.YAxis * BOX_EXTENT;
  126. Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
  127. HandleDrawing.DrawLine(yLineStart, yConeStart);
  128. HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS);
  129. Color zColor = Color.Blue;
  130. if (zAxis.State == HandleSlider.StateType.Active)
  131. zColor = Color.White;
  132. else if (zAxis.State == HandleSlider.StateType.Hover)
  133. zColor = Color.BansheeOrange;
  134. zColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)), 0.8f, 1.0f);
  135. HandleDrawing.Color = zColor;
  136. Vector3 zLineStart = Vector3.ZAxis * BOX_EXTENT;
  137. Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
  138. HandleDrawing.DrawLine(zLineStart, zConeStart);
  139. HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS);
  140. // Draw negative 1D arrows
  141. Color xNegColor = Color.LightGray;
  142. if (xNegAxis.State == HandleSlider.StateType.Active)
  143. xNegColor = Color.White;
  144. else if (xNegAxis.State == HandleSlider.StateType.Hover)
  145. xNegColor = Color.BansheeOrange;
  146. xNegColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)), 0.8f, 1.0f);
  147. HandleDrawing.Color = xNegColor;
  148. Vector3 xNegLineStart = -Vector3.XAxis * BOX_EXTENT;
  149. Vector3 xNegConeStart = -Vector3.XAxis * (1.0f - CONE_HEIGHT);
  150. HandleDrawing.DrawLine(xNegLineStart, xNegConeStart);
  151. HandleDrawing.DrawCone(xNegConeStart, -Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS);
  152. Color yNegColor = Color.LightGray;
  153. if (yNegAxis.State == HandleSlider.StateType.Active)
  154. yNegColor = Color.White;
  155. else if (yNegAxis.State == HandleSlider.StateType.Hover)
  156. yNegColor = Color.BansheeOrange;
  157. yNegColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)), 0.8f, 1.0f);
  158. HandleDrawing.Color = yNegColor;
  159. Vector3 yNegLineStart = -Vector3.YAxis * BOX_EXTENT;
  160. Vector3 yNegConeStart = -Vector3.YAxis * (1.0f - CONE_HEIGHT);
  161. HandleDrawing.DrawLine(yNegLineStart, yNegConeStart);
  162. HandleDrawing.DrawCone(yNegConeStart, -Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS);
  163. Color zNegcolor = Color.LightGray;
  164. if (zNegAxis.State == HandleSlider.StateType.Active)
  165. zNegcolor = Color.White;
  166. else if (zNegAxis.State == HandleSlider.StateType.Hover)
  167. zNegcolor = Color.BansheeOrange;
  168. zNegcolor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)), 0.8f, 1.0f);
  169. HandleDrawing.Color = zNegcolor;
  170. Vector3 zNegLineStart = -Vector3.ZAxis * BOX_EXTENT;
  171. Vector3 zNegConeStart = -Vector3.ZAxis * (1.0f - CONE_HEIGHT);
  172. HandleDrawing.DrawLine(zNegLineStart, zNegConeStart);
  173. HandleDrawing.DrawCone(zNegConeStart, -Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS);
  174. // Draw projection type handle
  175. if (projTypePlane.State == HandleSlider.StateType.Active)
  176. HandleDrawing.Color = Color.White;
  177. else if (projTypePlane.State == HandleSlider.StateType.Hover)
  178. HandleDrawing.Color = Color.BansheeOrange;
  179. else
  180. HandleDrawing.Color = Color.White;
  181. HandleDrawing.DrawCube(Vector3.Zero, new Vector3(BOX_EXTENT, BOX_EXTENT, BOX_EXTENT));
  182. // TODO - Add a text notifying the user whether ortho/proj is active
  183. }
  184. private void RotateCameraTo(Vector3 axis)
  185. {
  186. // TODO - Rotate to the provided axis. If already looking at that axis, rotate in the opposite direction (-axis)
  187. }
  188. private void ToggleProjectionType()
  189. {
  190. // TODO - Switch between ortographic and perspective
  191. }
  192. }
  193. }