RotateHandle.cs 7.3 KB

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