SceneAxesHandle.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. Vector3 xOffset = rotation.Rotate(new Vector3(BOX_EXTENT, 0.0f, 0.0f));
  49. Vector3 yOffset = rotation.Rotate(new Vector3(0.0f, BOX_EXTENT, 0.0f));
  50. Vector3 zOffset = rotation.Rotate(new Vector3(0.0f, 0.0f, BOX_EXTENT));
  51. xAxis.Position = position + xOffset;
  52. yAxis.Position = position + yOffset;
  53. zAxis.Position = position + zOffset;
  54. xAxis.Rotation = rotation;
  55. yAxis.Rotation = rotation;
  56. zAxis.Rotation = rotation;
  57. xNegAxis.Position = position - xOffset;
  58. yNegAxis.Position = position - yOffset;
  59. zNegAxis.Position = position - zOffset;
  60. xNegAxis.Rotation = rotation;
  61. yNegAxis.Rotation = rotation;
  62. zNegAxis.Rotation = rotation;
  63. Vector3 cameraForward = cam.SceneObject.Forward;
  64. xAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)) < DISABLE_THRESHOLD;
  65. yAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)) < DISABLE_THRESHOLD;
  66. zAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)) < DISABLE_THRESHOLD;
  67. xNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)) < DISABLE_THRESHOLD;
  68. yNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)) < DISABLE_THRESHOLD;
  69. zNegAxis.Enabled = MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)) < DISABLE_THRESHOLD;
  70. Vector3 freeAxisOffset = new Vector3(-BOX_EXTENT, -BOX_EXTENT, 0.2f);
  71. projTypePlane.Rotation = Quaternion.Identity;
  72. projTypePlane.Position = position + freeAxisOffset;
  73. }
  74. /// <inheritdoc/>
  75. protected internal override void PostInput()
  76. {
  77. var axes = new []
  78. {
  79. new Tuple<HandleSlider, Action>(xAxis, () => RotateCameraTo(Vector3.XAxis)),
  80. new Tuple<HandleSlider, Action>(yAxis, () => RotateCameraTo(Vector3.YAxis)),
  81. new Tuple<HandleSlider, Action>(zAxis, () => RotateCameraTo(Vector3.ZAxis)),
  82. new Tuple<HandleSlider, Action>(xNegAxis, () => RotateCameraTo(-Vector3.XAxis)),
  83. new Tuple<HandleSlider, Action>(yNegAxis, () => RotateCameraTo(-Vector3.YAxis)),
  84. new Tuple<HandleSlider, Action>(zNegAxis, () => RotateCameraTo(-Vector3.ZAxis)),
  85. new Tuple<HandleSlider, Action>(projTypePlane, ToggleProjectionType)
  86. };
  87. for (int i = 0; i < axes.Length; i++)
  88. {
  89. if (axes[i].Item1.State == HandleSlider.StateType.Active)
  90. {
  91. if (!clickStates[i])
  92. {
  93. axes[i].Item2();
  94. clickStates[i] = true;
  95. }
  96. }
  97. else
  98. {
  99. clickStates[i] = false;
  100. }
  101. }
  102. }
  103. /// <inheritdoc/>
  104. protected internal override void Draw()
  105. {
  106. HandleDrawing.Layer = LAYER;
  107. HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
  108. Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
  109. // Draw 1D arrows
  110. Color xColor = Color.Red;
  111. if (xAxis.State == HandleSlider.StateType.Active)
  112. xColor = Color.White;
  113. else if (xAxis.State == HandleSlider.StateType.Hover)
  114. xColor = Color.BansheeOrange;
  115. xColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)), 0.8f, 1.0f);
  116. HandleDrawing.Color = xColor;
  117. Vector3 xLineStart = Vector3.XAxis* BOX_EXTENT;
  118. Vector3 xConeStart = Vector3.XAxis * (1.0f - CONE_HEIGHT);
  119. HandleDrawing.DrawLine(xLineStart, xConeStart);
  120. HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS);
  121. Color yColor = Color.Green;
  122. if (yAxis.State == HandleSlider.StateType.Active)
  123. yColor = Color.White;
  124. else if (yAxis.State == HandleSlider.StateType.Hover)
  125. yColor = Color.BansheeOrange;
  126. yColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)), 0.8f, 1.0f);
  127. HandleDrawing.Color = yColor;
  128. Vector3 yLineStart = Vector3.YAxis * BOX_EXTENT;
  129. Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
  130. HandleDrawing.DrawLine(yLineStart, yConeStart);
  131. HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS);
  132. Color zColor = Color.Blue;
  133. if (zAxis.State == HandleSlider.StateType.Active)
  134. zColor = Color.White;
  135. else if (zAxis.State == HandleSlider.StateType.Hover)
  136. zColor = Color.BansheeOrange;
  137. zColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)), 0.8f, 1.0f);
  138. HandleDrawing.Color = zColor;
  139. Vector3 zLineStart = Vector3.ZAxis * BOX_EXTENT;
  140. Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
  141. HandleDrawing.DrawLine(zLineStart, zConeStart);
  142. HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS);
  143. // Draw negative 1D arrows
  144. Color xNegColor = Color.LightGray;
  145. if (xNegAxis.State == HandleSlider.StateType.Active)
  146. xNegColor = Color.White;
  147. else if (xNegAxis.State == HandleSlider.StateType.Hover)
  148. xNegColor = Color.BansheeOrange;
  149. xNegColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)), 0.8f, 1.0f);
  150. HandleDrawing.Color = xNegColor;
  151. Vector3 xNegLineStart = -Vector3.XAxis * BOX_EXTENT;
  152. Vector3 xNegConeStart = -Vector3.XAxis * (1.0f - CONE_HEIGHT);
  153. HandleDrawing.DrawLine(xNegLineStart, xNegConeStart);
  154. HandleDrawing.DrawCone(xNegConeStart, -Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS);
  155. Color yNegColor = Color.LightGray;
  156. if (yNegAxis.State == HandleSlider.StateType.Active)
  157. yNegColor = Color.White;
  158. else if (yNegAxis.State == HandleSlider.StateType.Hover)
  159. yNegColor = Color.BansheeOrange;
  160. yNegColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)), 0.8f, 1.0f);
  161. HandleDrawing.Color = yNegColor;
  162. Vector3 yNegLineStart = -Vector3.YAxis * BOX_EXTENT;
  163. Vector3 yNegConeStart = -Vector3.YAxis * (1.0f - CONE_HEIGHT);
  164. HandleDrawing.DrawLine(yNegLineStart, yNegConeStart);
  165. HandleDrawing.DrawCone(yNegConeStart, -Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS);
  166. Color zNegcolor = Color.LightGray;
  167. if (zNegAxis.State == HandleSlider.StateType.Active)
  168. zNegcolor = Color.White;
  169. else if (zNegAxis.State == HandleSlider.StateType.Hover)
  170. zNegcolor = Color.BansheeOrange;
  171. zNegcolor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)), 0.8f, 1.0f);
  172. HandleDrawing.Color = zNegcolor;
  173. Vector3 zNegLineStart = -Vector3.ZAxis * BOX_EXTENT;
  174. Vector3 zNegConeStart = -Vector3.ZAxis * (1.0f - CONE_HEIGHT);
  175. HandleDrawing.DrawLine(zNegLineStart, zNegConeStart);
  176. HandleDrawing.DrawCone(zNegConeStart, -Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS);
  177. // Draw projection type handle
  178. if (projTypePlane.State == HandleSlider.StateType.Active)
  179. HandleDrawing.Color = Color.White;
  180. else if (projTypePlane.State == HandleSlider.StateType.Hover)
  181. HandleDrawing.Color = Color.BansheeOrange;
  182. else
  183. HandleDrawing.Color = Color.White;
  184. HandleDrawing.DrawCube(Vector3.Zero, new Vector3(BOX_EXTENT, BOX_EXTENT, BOX_EXTENT));
  185. }
  186. private void RotateCameraTo(Vector3 axis)
  187. {
  188. SceneWindow sceneWindow = EditorWindow.GetWindow<SceneWindow>();
  189. if (sceneWindow != null)
  190. sceneWindow.LookAlong(axis);
  191. }
  192. private void ToggleProjectionType()
  193. {
  194. SceneWindow sceneWindow = EditorWindow.GetWindow<SceneWindow>();
  195. if (sceneWindow != null)
  196. {
  197. if (sceneWindow.ProjectionType == ProjectionType.Orthographic)
  198. sceneWindow.ProjectionType = ProjectionType.Perspective;
  199. else
  200. sceneWindow.ProjectionType = ProjectionType.Orthographic;
  201. }
  202. }
  203. }
  204. }