SceneAxesHandle.cs 9.9 KB

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