SceneAxesHandle.cs 6.9 KB

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