No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProjectedTransform.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Reflection;
  4. using UnityEditor;
  5. namespace UnityEngine.Rendering.Universal
  6. {
  7. // Copy of UnityEditor.Rendering.HighDefinition.DisplacableRectHandles
  8. class ProjectedTransform
  9. {
  10. struct PositionHandleIds
  11. {
  12. static int s_xAxisMoveHandleHash = "xAxisDecalPivot".GetHashCode();
  13. static int s_yAxisMoveHandleHash = "yAxisDecalPivot".GetHashCode();
  14. static int s_zAxisMoveHandleHash = "zAxisDecalPivot".GetHashCode();
  15. static int s_xyAxisMoveHandleHash = "xyAxisDecalPivot".GetHashCode();
  16. public static PositionHandleIds @default
  17. {
  18. get
  19. {
  20. return new PositionHandleIds(
  21. GUIUtility.GetControlID(s_xAxisMoveHandleHash, FocusType.Passive),
  22. GUIUtility.GetControlID(s_yAxisMoveHandleHash, FocusType.Passive),
  23. GUIUtility.GetControlID(s_zAxisMoveHandleHash, FocusType.Passive),
  24. GUIUtility.GetControlID(s_xyAxisMoveHandleHash, FocusType.Passive)
  25. );
  26. }
  27. }
  28. public readonly int x, y, z, xy;
  29. public int this[int index]
  30. {
  31. get
  32. {
  33. switch (index)
  34. {
  35. case 0: return x;
  36. case 1: return y;
  37. case 2: return z;
  38. case 3: return xy;
  39. }
  40. return -1;
  41. }
  42. }
  43. public bool Has(int id)
  44. {
  45. return x == id
  46. || y == id
  47. || z == id
  48. || xy == id;
  49. }
  50. public PositionHandleIds(int x, int y, int z, int xy)
  51. {
  52. this.x = x;
  53. this.y = y;
  54. this.z = z;
  55. this.xy = xy;
  56. }
  57. public override int GetHashCode()
  58. {
  59. return x ^ y ^ z ^ xy;
  60. }
  61. public override bool Equals(object obj)
  62. {
  63. if (!(obj is PositionHandleIds o))
  64. return false;
  65. return o.x == x && o.y == y && o.z == z && o.xy == xy;
  66. }
  67. }
  68. struct PositionHandleParam
  69. {
  70. public static PositionHandleParam defaultHandleXY = new PositionHandleParam(
  71. Handle.X | Handle.Y | Handle.XY,
  72. Vector3.zero, Vector3.one, Vector3.zero, Vector3.one * .25f,
  73. Orientation.Signed, Orientation.Camera);
  74. public static PositionHandleParam defaultHandleZ = new PositionHandleParam(
  75. Handle.Z,
  76. Vector3.zero, Vector3.one, Vector3.zero, Vector3.one * .25f,
  77. Orientation.Signed, Orientation.Camera);
  78. [Flags]
  79. public enum Handle
  80. {
  81. None = 0,
  82. X = 1 << 0,
  83. Y = 1 << 1,
  84. Z = 1 << 2,
  85. XY = 1 << 3,
  86. All = ~None
  87. }
  88. public enum Orientation
  89. {
  90. Signed,
  91. Camera
  92. }
  93. public readonly Vector3 axisOffset;
  94. public readonly Vector3 axisSize;
  95. public readonly Vector3 planeOffset;
  96. public readonly Vector3 planeSize;
  97. public readonly Handle handles;
  98. public readonly Orientation axesOrientation;
  99. public readonly Orientation planeOrientation;
  100. public bool ShouldShow(int axis)
  101. {
  102. return (handles & (Handle)(1 << axis)) != 0;
  103. }
  104. public bool ShouldShow(Handle handle)
  105. {
  106. return (handles & handle) != 0;
  107. }
  108. public PositionHandleParam(
  109. Handle handles,
  110. Vector3 axisOffset,
  111. Vector3 axisSize,
  112. Vector3 planeOffset,
  113. Vector3 planeSize,
  114. Orientation axesOrientation,
  115. Orientation planeOrientation)
  116. {
  117. this.axisOffset = axisOffset;
  118. this.axisSize = axisSize;
  119. this.planeOffset = planeOffset;
  120. this.planeSize = planeSize;
  121. this.handles = handles;
  122. this.axesOrientation = axesOrientation;
  123. this.planeOrientation = planeOrientation;
  124. }
  125. }
  126. static PositionHandleParam paramXY = PositionHandleParam.defaultHandleXY;
  127. static PositionHandleParam paramZ = PositionHandleParam.defaultHandleZ;
  128. static PositionHandleIds ids = PositionHandleIds.@default;
  129. static int[] s_DoPositionHandle_Internal_NextIndex = { 1, 2, 0 };
  130. static int[] s_DoPositionHandle_Internal_PrevIndex = { 2, 0, 1 };
  131. static Vector3[] verts = { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero };
  132. static Func<bool> s_IsGridSnappingActive;
  133. static ProjectedTransform()
  134. {
  135. //We need to know if grid snaping is active or not in Editor. Sadly this is internal so we must grab it by reflection.
  136. Type gridSnappingType = typeof(Handles).Assembly.GetType("UnityEditor.GridSnapping");
  137. PropertyInfo activePropertyInfo = gridSnappingType.GetProperty("active", BindingFlags.Public | BindingFlags.Static);
  138. MethodCallExpression activePropertyGetCall = Expression.Call(null, activePropertyInfo.GetGetMethod());
  139. var activeGetLambda = Expression.Lambda<Func<bool>>(activePropertyGetCall);
  140. s_IsGridSnappingActive = activeGetLambda.Compile();
  141. }
  142. static bool IsHovering(int controlID, Event evt)
  143. {
  144. return controlID == HandleUtility.nearestControl && GUIUtility.hotControl == 0 && !Tools.viewToolActive;
  145. }
  146. public static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Quaternion rotation)
  147. {
  148. var isHot = ids.Has(GUIUtility.hotControl);
  149. var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize;
  150. var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]);
  151. Vector3 sliderRotatedWorldPos = Quaternion.Inverse(rotation) * position;
  152. var size1D = HandleUtility.GetHandleSize(sliderRotatedWorldPos);
  153. var size2D = HandleUtility.GetHandleSize(sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance)) * planarSize * .5f;
  154. Vector3 depthSlider = sliderRotatedWorldPos;
  155. EditorGUI.BeginChangeCheck();
  156. {
  157. // dot offset = transform position seen as a sphere
  158. EditorGUI.BeginChangeCheck();
  159. depthSlider = Handles.Slider(depthSlider, Vector3.forward, size1D * .1f, Handles.SphereHandleCap, -1);
  160. if (EditorGUI.EndChangeCheck())
  161. sliderRotatedWorldPos.z = depthSlider.z;
  162. // 2D slider: square xy-axis
  163. Vector3 sliderFaceProjected = sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance);
  164. sliderFaceProjected.x += size2D;
  165. sliderFaceProjected.y += size2D;
  166. using (new Handles.DrawingScope(Handles.zAxisColor))
  167. {
  168. verts[0] = sliderFaceProjected + (Vector3.right + Vector3.up) * size2D;
  169. verts[1] = sliderFaceProjected + (-Vector3.right + Vector3.up) * size2D;
  170. verts[2] = sliderFaceProjected + (-Vector3.right - Vector3.up) * size2D;
  171. verts[3] = sliderFaceProjected + (Vector3.right - Vector3.up) * size2D;
  172. int id = GUIUtility.GetControlID(ids.xy, FocusType.Passive);
  173. float faceOpacity = 0.8f;
  174. if (GUIUtility.hotControl == id)
  175. Handles.color = Handles.selectedColor;
  176. else if (IsHovering(id, Event.current))
  177. faceOpacity = 0.4f;
  178. else
  179. faceOpacity = 0.1f;
  180. Color faceColor = new Color(Handles.zAxisColor.r, Handles.zAxisColor.g, Handles.zAxisColor.b, Handles.zAxisColor.a * faceOpacity);
  181. Handles.DrawSolidRectangleWithOutline(verts, faceColor, Color.clear);
  182. EditorGUI.BeginChangeCheck();
  183. sliderFaceProjected = Handles.Slider2D(id, sliderFaceProjected, Vector3.forward, Vector3.right, Vector3.up, size2D, Handles.RectangleHandleCap, s_IsGridSnappingActive() ? Vector2.zero : new Vector2(EditorSnapSettings.move[0], EditorSnapSettings.move[1]), false);
  184. if (EditorGUI.EndChangeCheck())
  185. {
  186. sliderRotatedWorldPos.x = sliderFaceProjected.x;
  187. sliderRotatedWorldPos.y = sliderFaceProjected.y;
  188. }
  189. }
  190. sliderFaceProjected.x -= size2D;
  191. sliderFaceProjected.y -= size2D;
  192. // 2D slider: x-axis
  193. EditorGUI.BeginChangeCheck();
  194. using (new Handles.DrawingScope(Handles.xAxisColor))
  195. sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.right);
  196. if (EditorGUI.EndChangeCheck())
  197. sliderRotatedWorldPos.x = sliderFaceProjected.x;
  198. // 2D slider: y-axis
  199. EditorGUI.BeginChangeCheck();
  200. using (new Handles.DrawingScope(Handles.yAxisColor))
  201. sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.up);
  202. if (EditorGUI.EndChangeCheck())
  203. sliderRotatedWorldPos.y = sliderFaceProjected.y;
  204. // depth: z-axis
  205. EditorGUI.BeginChangeCheck();
  206. using (new Handles.DrawingScope(Handles.zAxisColor))
  207. depthSlider = Handles.Slider(depthSlider, Vector3.forward);
  208. if (EditorGUI.EndChangeCheck())
  209. sliderRotatedWorldPos.z = depthSlider.z;
  210. }
  211. if (EditorGUI.EndChangeCheck())
  212. {
  213. position = rotation * sliderRotatedWorldPos;
  214. }
  215. return position;
  216. }
  217. }
  218. }