RotateHandle.cs 7.0 KB

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