2
0

DefaultHandleManager.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using System.Collections.Generic;
  2. using BansheeEngine;
  3. namespace BansheeEditor
  4. {
  5. /// <summary>
  6. /// Manages the default set of built-in handles like move, rotate and scale. Handles switching between the three handle
  7. /// types, as well as switching between coordinate and pivot modes, while tracking and updating active scene object
  8. /// selection. Essentially it detects which handles need to be displayed and where, and then forwards the data
  9. /// to the specific handle for processing.
  10. /// </summary>
  11. internal sealed class DefaultHandleManager : Handle
  12. {
  13. /// <summary>
  14. /// Representation of a scene object currently being modified by a handle.
  15. /// </summary>
  16. private struct HandledObject
  17. {
  18. /// <summary>
  19. /// Creates a new scene object representation by recording the current object transform.
  20. /// </summary>
  21. /// <param name="so">Scene object that is being modified by a handle.</param>
  22. public HandledObject(SceneObject so)
  23. {
  24. this.so = so;
  25. initialPosition = so.LocalPosition;
  26. initialRotation = so.LocalRotation;
  27. initialScale = so.LocalScale;
  28. }
  29. public SceneObject so;
  30. public Vector3 initialPosition;
  31. public Quaternion initialRotation;
  32. public Vector3 initialScale;
  33. }
  34. private SceneViewTool activeHandleType = SceneViewTool.View;
  35. private DefaultHandle activeHandle;
  36. private HandledObject[] activeSelection;
  37. private bool isDragged;
  38. private Vector3 initialHandlePosition;
  39. private Quaternion initialHandleRotation;
  40. private Vector3 initialHandleScale;
  41. /// <inheritdoc/>
  42. protected internal override void PreInput()
  43. {
  44. SceneObject[] selectedSceneObjects = Selection.SceneObjects;
  45. if (selectedSceneObjects.Length == 0)
  46. {
  47. if (activeHandle != null)
  48. {
  49. activeHandle.Destroy();
  50. activeHandle = null;
  51. }
  52. }
  53. else
  54. {
  55. if (activeHandleType != EditorApplication.ActiveSceneTool || activeHandle == null)
  56. {
  57. if (activeHandle != null)
  58. {
  59. activeHandle.Destroy();
  60. activeHandle = null;
  61. }
  62. switch (EditorApplication.ActiveSceneTool)
  63. {
  64. case SceneViewTool.Move:
  65. activeHandle = new MoveHandle();
  66. break;
  67. case SceneViewTool.Rotate:
  68. activeHandle = new RotateHandle();
  69. break;
  70. case SceneViewTool.Scale:
  71. activeHandle = new ScaleHandle();
  72. break;
  73. }
  74. activeHandleType = EditorApplication.ActiveSceneTool;
  75. }
  76. }
  77. if (activeHandle != null)
  78. {
  79. Quaternion rotation;
  80. if (EditorApplication.ActiveCoordinateMode == HandleCoordinateMode.World)
  81. rotation = Quaternion.Identity;
  82. else
  83. rotation = selectedSceneObjects[0].Rotation; // We don't average rotation in case of multi-selection
  84. Vector3 position;
  85. if (EditorApplication.ActivePivotMode == HandlePivotMode.Pivot)
  86. position = selectedSceneObjects[0].Position; // Just take pivot from the first one, no averaging
  87. else
  88. {
  89. List<SceneObject> flatenedHierarchy = new List<SceneObject>();
  90. foreach (var so in selectedSceneObjects)
  91. flatenedHierarchy.AddRange(EditorUtility.FlattenHierarchy(so));
  92. AABox selectionBounds = EditorUtility.CalculateBounds(flatenedHierarchy.ToArray());
  93. position = selectionBounds.Center;
  94. }
  95. activeHandle.Position = position;
  96. activeHandle.Rotation = rotation;
  97. if (!isDragged)
  98. initialHandleScale = selectedSceneObjects[0].Scale;
  99. activeHandle.PreInput();
  100. }
  101. }
  102. /// <inheritdoc/>
  103. protected internal override void PostInput()
  104. {
  105. if (activeHandle != null)
  106. {
  107. if (activeHandle.IsDragged())
  108. {
  109. if (!isDragged)
  110. {
  111. isDragged = true;
  112. SceneObject[] selectedSceneObjects = Selection.SceneObjects;
  113. activeSelection = new HandledObject[selectedSceneObjects.Length];
  114. for (int i = 0; i < selectedSceneObjects.Length; i++)
  115. activeSelection[i] = new HandledObject(selectedSceneObjects[0]);
  116. initialHandlePosition = activeHandle.Position;
  117. initialHandleRotation = activeHandle.Rotation;
  118. }
  119. }
  120. else
  121. {
  122. isDragged = false;
  123. activeSelection = null;
  124. }
  125. activeHandle.PostInput();
  126. if (activeHandle.IsDragged())
  127. {
  128. switch (activeHandleType)
  129. {
  130. case SceneViewTool.Move:
  131. MoveHandle moveHandle = (MoveHandle) activeHandle;
  132. foreach (var selectedObj in activeSelection)
  133. selectedObj.so.LocalPosition = selectedObj.initialPosition + moveHandle.Delta;
  134. break;
  135. case SceneViewTool.Rotate:
  136. {
  137. RotateHandle rotateHandle = (RotateHandle) activeHandle;
  138. // Make sure we transform relative to the handle position
  139. SceneObject temporarySO = new SceneObject("Temp");
  140. temporarySO.Position = initialHandlePosition;
  141. temporarySO.LocalRotation = initialHandleRotation;
  142. SceneObject[] originalParents = new SceneObject[activeSelection.Length];
  143. for (int i = 0; i < activeSelection.Length; i++)
  144. {
  145. originalParents[i] = activeSelection[i].so.Parent;
  146. activeSelection[i].so.LocalPosition = activeSelection[i].initialPosition;
  147. activeSelection[i].so.LocalRotation = activeSelection[i].initialRotation;
  148. activeSelection[i].so.Parent = temporarySO;
  149. }
  150. temporarySO.LocalRotation *= rotateHandle.Delta;
  151. for (int i = 0; i < activeSelection.Length; i++)
  152. activeSelection[i].so.Parent = originalParents[i];
  153. temporarySO.Destroy();
  154. }
  155. break;
  156. case SceneViewTool.Scale:
  157. {
  158. ScaleHandle scaleHandle = (ScaleHandle) activeHandle;
  159. // Make sure we transform relative to the handle position
  160. SceneObject temporarySO = new SceneObject("Temp");
  161. temporarySO.Position = activeHandle.Position;
  162. temporarySO.LocalScale = initialHandleScale;
  163. SceneObject[] originalParents = new SceneObject[activeSelection.Length];
  164. for (int i = 0; i < activeSelection.Length; i++)
  165. {
  166. originalParents[i] = activeSelection[i].so.Parent;
  167. activeSelection[i].so.LocalPosition = activeSelection[i].initialPosition;
  168. activeSelection[i].so.LocalRotation = activeSelection[i].initialRotation;
  169. activeSelection[i].so.LocalScale = activeSelection[i].initialScale;
  170. activeSelection[i].so.Parent = temporarySO;
  171. }
  172. temporarySO.LocalScale += scaleHandle.Delta;
  173. for (int i = 0; i < activeSelection.Length; i++)
  174. activeSelection[i].so.Parent = originalParents[i];
  175. temporarySO.Destroy();
  176. }
  177. break;
  178. }
  179. EditorApplication.SetSceneDirty();
  180. }
  181. }
  182. else
  183. {
  184. isDragged = false;
  185. activeSelection = null;
  186. }
  187. }
  188. /// <inheritdoc/>
  189. protected internal override void Draw()
  190. {
  191. if (activeHandle != null)
  192. activeHandle.Draw();
  193. }
  194. }
  195. }