SceneAxesHandle.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 HandleSliderLine xAxis;
  16. private HandleSliderLine yAxis;
  17. private HandleSliderLine zAxis;
  18. private HandleSliderPlane projTypePlane;
  19. private bool[] clickStates = new bool[4];
  20. private Vector3 position = Vector3.Zero;
  21. private Quaternion rotation = Quaternion.Identity;
  22. /// <summary>
  23. /// Creates a new scene axes handle.
  24. /// </summary>
  25. public SceneAxesHandle()
  26. {
  27. xAxis = new HandleSliderLine(this, Vector3.XAxis, 1.0f, true, LAYER);
  28. yAxis = new HandleSliderLine(this, Vector3.YAxis, 1.0f, true, LAYER);
  29. zAxis = new HandleSliderLine(this, Vector3.ZAxis, 1.0f, true, LAYER);
  30. projTypePlane = new HandleSliderPlane(this, Vector3.XAxis, Vector3.YAxis, 0.4f);
  31. }
  32. /// <inheritdoc/>
  33. protected internal override void PreInput()
  34. {
  35. Camera cam = EditorApplication.SceneViewCamera;
  36. if (cam == null)
  37. return;
  38. float distFromCamera = 500.0f;
  39. float x = cam.GetFrustumWidth(distFromCamera) * 0.5f;
  40. float y = x / cam.AspectRatio;
  41. Vector3 localPosition = new Vector3(0, 0, -distFromCamera);
  42. float appoxHandleSize = EditorSettings.DefaultHandleSize * distFromCamera;
  43. localPosition.x = x - appoxHandleSize * 1.2f;
  44. localPosition.y = y - appoxHandleSize * 1.2f;
  45. position = cam.SceneObject.WorldTransform.MultiplyAffine(localPosition);
  46. rotation = Quaternion.Identity;
  47. xAxis.Position = position;
  48. yAxis.Position = position;
  49. zAxis.Position = position;
  50. xAxis.Rotation = rotation;
  51. yAxis.Rotation = rotation;
  52. zAxis.Rotation = rotation;
  53. float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
  54. Vector3 freeAxisOffset = (Vector3.XAxis * -0.2f + Vector3.YAxis * -0.2f) * handleSize;
  55. projTypePlane.Rotation = EditorApplication.SceneViewCamera.SceneObject.Rotation;
  56. projTypePlane.Position = position + projTypePlane.Rotation.Rotate(freeAxisOffset);
  57. }
  58. /// <inheritdoc/>
  59. protected internal override void PostInput()
  60. {
  61. var axes = new []
  62. {
  63. new Tuple<HandleSlider, Action>(xAxis, () => RotateCameraTo(Vector3.XAxis)),
  64. new Tuple<HandleSlider, Action>(yAxis, () => RotateCameraTo(Vector3.YAxis)),
  65. new Tuple<HandleSlider, Action>(zAxis, () => RotateCameraTo(Vector3.ZAxis)),
  66. new Tuple<HandleSlider, Action>(projTypePlane, ToggleProjectionType)
  67. };
  68. for (int i = 0; i < axes.Length; i++)
  69. {
  70. if (axes[i].Item1.State == HandleSlider.StateType.Active)
  71. {
  72. if (!clickStates[i])
  73. {
  74. axes[i].Item2();
  75. clickStates[i] = true;
  76. }
  77. }
  78. else
  79. {
  80. clickStates[i] = false;
  81. }
  82. }
  83. }
  84. /// <inheritdoc/>
  85. protected internal override void Draw()
  86. {
  87. HandleDrawing.Layer = LAYER;
  88. HandleDrawing.Transform = Matrix4.TRS(position, rotation, Vector3.One);
  89. Vector3 cameraForward = EditorApplication.SceneViewCamera.SceneObject.Forward;
  90. float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
  91. // Draw 1D arrows
  92. Color xColor = Color.Red;
  93. if (xAxis.State == HandleSlider.StateType.Active)
  94. xColor = Color.White;
  95. else if (xAxis.State == HandleSlider.StateType.Hover)
  96. xColor = Color.BansheeOrange;
  97. xColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.XAxis)), 0.8f, 1.0f);
  98. HandleDrawing.Color = xColor;
  99. Vector3 xConeStart = Vector3.XAxis * (1.0f - CONE_HEIGHT);
  100. HandleDrawing.DrawLine(Vector3.Zero, xConeStart, handleSize);
  101. HandleDrawing.DrawCone(xConeStart, Vector3.XAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
  102. Color yColor = Color.Green;
  103. if (yAxis.State == HandleSlider.StateType.Active)
  104. yColor = Color.White;
  105. else if (yAxis.State == HandleSlider.StateType.Hover)
  106. yColor = Color.BansheeOrange;
  107. yColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.YAxis)), 0.8f, 1.0f);
  108. HandleDrawing.Color = yColor;
  109. Vector3 yConeStart = Vector3.YAxis * (1.0f - CONE_HEIGHT);
  110. HandleDrawing.DrawLine(Vector3.Zero, yConeStart, handleSize);
  111. HandleDrawing.DrawCone(yConeStart, Vector3.YAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
  112. Color zColor = Color.Blue;
  113. if (zAxis.State == HandleSlider.StateType.Active)
  114. zColor = Color.White;
  115. else if (zAxis.State == HandleSlider.StateType.Hover)
  116. zColor = Color.BansheeOrange;
  117. zColor.a = MathEx.Lerp(1.0f, 0.0f, MathEx.Abs(Vector3.Dot(cameraForward, Vector3.ZAxis)), 0.8f, 1.0f);
  118. HandleDrawing.Color = zColor;
  119. Vector3 zConeStart = Vector3.ZAxis * (1.0f - CONE_HEIGHT);
  120. HandleDrawing.DrawLine(Vector3.Zero, zConeStart, handleSize);
  121. HandleDrawing.DrawCone(zConeStart, Vector3.ZAxis, CONE_HEIGHT, CONE_RADIUS, handleSize);
  122. // Draw projection type handle
  123. if (projTypePlane.State == HandleSlider.StateType.Active)
  124. HandleDrawing.Color = Color.White;
  125. else if (projTypePlane.State == HandleSlider.StateType.Hover)
  126. HandleDrawing.Color = Color.BansheeOrange;
  127. else
  128. HandleDrawing.Color = Color.White;
  129. HandleDrawing.DrawCube(Vector3.Zero, new Vector3(0.2f, 0.2f, 0.2f), handleSize);
  130. // TODO - Add a text notifying the user whether ortho/proj is active
  131. }
  132. private void RotateCameraTo(Vector3 axis)
  133. {
  134. // TODO - Rotate to the provided axis. If already looking at that axis, rotate in the opposite direction (-axis)
  135. }
  136. private void ToggleProjectionType()
  137. {
  138. // TODO - Switch between ortographic and perspective
  139. }
  140. }
  141. }