RotateHandle.cs 8.1 KB

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