SceneAxesHandle.cs 11 KB

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