RotateHandle.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using BansheeEngine;
  2. namespace BansheeEditor
  3. {
  4. public sealed class RotateHandle : DefaultHandle
  5. {
  6. private Quaternion delta;
  7. private HandleSliderDisc xAxis;
  8. private HandleSliderDisc yAxis;
  9. private HandleSliderDisc zAxis;
  10. public Quaternion Delta
  11. {
  12. get { return delta; }
  13. }
  14. internal override bool IsDragged()
  15. {
  16. return xAxis.State == HandleSlider.StateType.Active ||
  17. yAxis.State == HandleSlider.StateType.Active ||
  18. zAxis.State == HandleSlider.StateType.Active;
  19. }
  20. public RotateHandle()
  21. {
  22. xAxis = new HandleSliderDisc(this, Vector3.xAxis, 1.0f);
  23. yAxis = new HandleSliderDisc(this, Vector3.yAxis, 1.0f);
  24. zAxis = new HandleSliderDisc(this, Vector3.zAxis, 1.0f);
  25. }
  26. protected override void PreInput()
  27. {
  28. xAxis.Position = position;
  29. yAxis.Position = position;
  30. zAxis.Position = position;
  31. xAxis.SetCutoffPlane(GetXStartAngle(), true);
  32. yAxis.SetCutoffPlane(GetYStartAngle(), true);
  33. zAxis.SetCutoffPlane(GetZStartAngle(), true);
  34. }
  35. protected override void PostInput()
  36. {
  37. delta = Quaternion.identity;
  38. Degree xValue = 0.0f;
  39. Degree yValue = 0.0f;
  40. Degree zValue = 0.0f;
  41. if (Handles.RotateHandleSnapActive)
  42. {
  43. xValue = Handles.SnapValue(xAxis.Delta, Handles.RotateSnapAmount);
  44. yValue = Handles.SnapValue(yAxis.Delta, Handles.RotateSnapAmount);
  45. zValue = Handles.SnapValue(zAxis.Delta, Handles.RotateSnapAmount);
  46. }
  47. else
  48. {
  49. xValue = xAxis.Delta;
  50. yValue = yAxis.Delta;
  51. zValue = zAxis.Delta;
  52. }
  53. delta = Quaternion.FromAxisAngle(GetXDir(), xValue) * delta;
  54. delta = Quaternion.FromAxisAngle(GetYDir(), yValue) * delta;
  55. delta = Quaternion.FromAxisAngle(GetZDir(), zValue) * delta;
  56. }
  57. protected override void Draw()
  58. {
  59. HandleDrawing.SetTransform(Matrix4.TRS(Position, Quaternion.identity, Vector3.one));
  60. float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);
  61. // Draw arcs
  62. if (xAxis.State == HandleSlider.StateType.Active)
  63. HandleDrawing.SetColor(Color.White);
  64. else if(xAxis.State == HandleSlider.StateType.Hover)
  65. HandleDrawing.SetColor(Color.BansheeOrange);
  66. else
  67. HandleDrawing.SetColor(Color.Red);
  68. HandleDrawing.DrawWireArc(Vector3.zero, GetXDir(), 1.0f, GetXStartAngle(), 180.0f, handleSize);
  69. if (yAxis.State == HandleSlider.StateType.Active)
  70. HandleDrawing.SetColor(Color.White);
  71. else if (yAxis.State == HandleSlider.StateType.Hover)
  72. HandleDrawing.SetColor(Color.BansheeOrange);
  73. else
  74. HandleDrawing.SetColor(Color.Green);
  75. HandleDrawing.DrawWireArc(Vector3.zero, GetYDir(), 1.0f, GetYStartAngle(), 180.0f, handleSize);
  76. if (zAxis.State == HandleSlider.StateType.Active)
  77. HandleDrawing.SetColor(Color.White);
  78. else if (zAxis.State == HandleSlider.StateType.Hover)
  79. HandleDrawing.SetColor(Color.BansheeOrange);
  80. else
  81. HandleDrawing.SetColor(Color.Blue);
  82. HandleDrawing.DrawWireArc(Vector3.zero, GetZDir(), 1.0f, GetZStartAngle(), 180.0f, handleSize);
  83. // Draw active rotation pie
  84. Color gray = new Color(1.0f, 1.0f, 1.0f, 0.3f);
  85. HandleDrawing.SetColor(gray);
  86. if (xAxis.State == HandleSlider.StateType.Active)
  87. HandleDrawing.DrawArc(Vector3.zero, GetXDir(), 1.0f, xAxis.StartAngle, xAxis.Delta, handleSize);
  88. else if (yAxis.State == HandleSlider.StateType.Active)
  89. HandleDrawing.DrawArc(Vector3.zero, GetYDir(), 1.0f, yAxis.StartAngle, yAxis.Delta, handleSize);
  90. else if (zAxis.State == HandleSlider.StateType.Active)
  91. HandleDrawing.DrawArc(Vector3.zero, GetZDir(), 1.0f, zAxis.StartAngle, zAxis.Delta, handleSize);
  92. // Draw free rotate handle
  93. //// Rotate it so it always faces the camera, and move it forward a bit to always render in front
  94. Vector3 freeHandleNormal = EditorApplication.SceneViewCamera.sceneObject.Rotation.Rotate(GetZDir());
  95. Vector3 offset = freeHandleNormal*0.1f;
  96. HandleDrawing.DrawWireDisc(offset, freeHandleNormal, 1.0f, handleSize);
  97. }
  98. private Degree GetXStartAngle()
  99. {
  100. Vector3 xStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetXDir());
  101. return PointOnCircleToAngle(GetXDir(), xStartDir);
  102. }
  103. private Degree GetYStartAngle()
  104. {
  105. Vector3 yStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetYDir());
  106. return PointOnCircleToAngle(GetYDir(), yStartDir);
  107. }
  108. private Degree GetZStartAngle()
  109. {
  110. Vector3 zStartDir = Vector3.Cross(EditorApplication.SceneViewCamera.sceneObject.Forward, GetZDir());
  111. return PointOnCircleToAngle(GetZDir(), zStartDir);
  112. }
  113. private Vector3 GetXDir()
  114. {
  115. return Vector3.xAxis;
  116. }
  117. private Vector3 GetYDir()
  118. {
  119. return Vector3.yAxis;
  120. }
  121. private Vector3 GetZDir()
  122. {
  123. return Vector3.zAxis;
  124. }
  125. private Degree PointOnCircleToAngle(Vector3 up, Vector3 point)
  126. {
  127. Quaternion rot = Quaternion.FromToRotation(up, Vector3.yAxis);
  128. Matrix4 worldToPlane = Matrix4.TRS(Vector3.zero, rot, Vector3.one);
  129. point = worldToPlane.MultiplyAffine(point);
  130. return (MathEx.Atan2(-point.z, -point.x) + MathEx.Pi) * MathEx.Rad2Deg;
  131. }
  132. }
  133. }