SceneAxesHandle.cs 11 KB

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