public static void DrawLength(UnityEngine.Vector3 from, UnityEngine.Vector3 to, float forceValue) { var prevColor = SceneHandles.color; SceneHandles.color = SceneHandles.StateColor(SceneHandles.measureColor); var invMatrix = SceneHandles.inverseMatrix; var camera = UnityEngine.Camera.current; var camPos = invMatrix.MultiplyPoint(camera.transform.position); var camDir = (SceneHandleUtility.ProjectPointLine(camPos, from, to) - camPos).normalized; var delta = (to - from); var length = delta.magnitude; var forward = delta / length; var right = Vector3.Cross(forward, camDir); var fromSize = UnityEditor.HandleUtility.GetHandleSize(from); var toSize = UnityEditor.HandleUtility.GetHandleSize(to); var center = (to + from) * 0.5f; SceneHandles.DrawLine(from, to); DrawFlatArrow(from, forward, camDir, fromSize * 0.2f); DrawFlatArrow(to, -forward, camDir, toSize * 0.2f); // SceneHandles.DrawLine(from - right, from + right); // SceneHandles.DrawLine(to - right, to + right); DrawUnitLabel(center, right, 2, forceValue); SceneHandles.color = prevColor; }
public static Vector3 Edge2DHandleOffset(int id, Vector3 from, Vector3 to, Vector3 slideDir1, Vector3 slideDir2, CapFunction capFunction = null, Axes axes = Axes.None, Vector3?snappingSteps = null, bool setCursor = true, bool renderEdge = true) { var midPoint = (from + to) * 0.5f; var handleDir = Vector3.Cross(slideDir1, slideDir2); return(SceneHandles.Edge2DHandleOffset(id, from, to, midPoint, handleDir, slideDir1, slideDir2, 0, capFunction, axes, snappingSteps, setCursor: setCursor, renderEdge: renderEdge)); }
public static void RenderShape(Matrix4x4 transformation, Curve2D shape, float height) { if (Event.current.type != EventType.Repaint) { return; } if (shape == null || shape.controlPoints == null || shape.controlPoints.Length == 1) { return; } using (new SceneHandles.DrawingScope(transformation)) { for (int j = shape.controlPoints.Length - 1, i = 0; i < shape.controlPoints.Length; j = i, i++) { var controlPointJ = shape.controlPoints[j].position; var controlPointI = shape.controlPoints[i].position; var pointJ0 = new Vector3(controlPointJ.x, 0, controlPointJ.y); var pointI0 = new Vector3(controlPointI.x, 0, controlPointI.y); var pointJ1 = new Vector3(controlPointJ.x, height, controlPointJ.y); var pointI1 = new Vector3(controlPointI.x, height, controlPointI.y); SceneHandles.DrawDottedLine(pointJ0, pointI0, 1.0f); SceneHandles.DrawDottedLine(pointJ1, pointI1, 1.0f); SceneHandles.DrawDottedLine(pointI0, pointI1, 1.0f); } } }
public static Rect DrawLabel(UnityEngine.Vector3 position, UnityEngine.Vector3 alignmentDirection, GUIContent content, GUIStyle style) { if (Event.current.type == EventType.Repaint) { var matrix = SceneHandles.matrix; var pt = UnityEngine.Camera.current.WorldToViewportPoint(matrix.MultiplyPoint(position)); // cull if behind camera if (pt.z < 0) { return(emptyRect); } var rect = GetLabelRect(position, alignmentDirection, content, style); SceneHandles.BeginGUI(); { GUI.Label(rect, content, style); } SceneHandles.EndGUI(); return(rect); } else if (Event.current.type == EventType.Layout) { return(GetLabelRect(position, alignmentDirection, content, style)); } return(emptyRect); }
public static void DrawIntersectionPoint(Vector3 position) { var rotation = Quaternion.LookRotation(Camera.current.transform.forward); var size = UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f; SceneHandles.DotHandleCap(-1, position, rotation, size, Event.current.type); }
public static void RenderBox(Matrix4x4 transformation, Bounds bounds) { if (Event.current.type != EventType.Repaint) { return; } using (new SceneHandles.DrawingScope(transformation * Matrix4x4.TRS(bounds.center, Quaternion.identity, bounds.extents))) { SceneHandles.DrawDottedLine(boxVertices[0], boxVertices[1], 1.0f); SceneHandles.DrawDottedLine(boxVertices[1], boxVertices[2], 1.0f); SceneHandles.DrawDottedLine(boxVertices[2], boxVertices[3], 1.0f); SceneHandles.DrawDottedLine(boxVertices[3], boxVertices[0], 1.0f); SceneHandles.DrawDottedLine(boxVertices[4], boxVertices[5], 1.0f); SceneHandles.DrawDottedLine(boxVertices[5], boxVertices[6], 1.0f); SceneHandles.DrawDottedLine(boxVertices[6], boxVertices[7], 1.0f); SceneHandles.DrawDottedLine(boxVertices[7], boxVertices[4], 1.0f); SceneHandles.DrawDottedLine(boxVertices[0], boxVertices[4], 1.0f); SceneHandles.DrawDottedLine(boxVertices[1], boxVertices[5], 1.0f); SceneHandles.DrawDottedLine(boxVertices[2], boxVertices[6], 1.0f); SceneHandles.DrawDottedLine(boxVertices[3], boxVertices[7], 1.0f); } }
public static Vector3 Edge2DHandleTangentOffset(int id, Vector3 from, Vector3 to, CapFunction capFunction = null, Vector3?snappingSteps = null, bool setCursor = true, bool renderEdge = true) { var edgeDelta = from - to; var grid = Grid.ActiveGrid; var edgeAxis = grid.GetClosestAxis(edgeDelta); var axes = grid.GetTangentAxesForAxis(edgeAxis, out Vector3 slideDir1, out Vector3 slideDir2); var midPoint = (from + to) * 0.5f; var handleDir = Vector3.Cross(slideDir1, slideDir2); return(SceneHandles.Edge2DHandleOffset(id, from, to, midPoint, handleDir, slideDir1, slideDir2, 0, capFunction, axes, snappingSteps, setCursor: setCursor, renderEdge: renderEdge)); }
public static void RenderSquareXZ(Extents3D extents, float y) { var v0 = new Vector3(extents.min.x, y, extents.min.z); var v1 = new Vector3(extents.min.x, y, extents.max.z); var v2 = new Vector3(extents.max.x, y, extents.max.z); var v3 = new Vector3(extents.max.x, y, extents.min.z); SceneHandles.DrawDottedLine(v0, v1, 1.0f); SceneHandles.DrawDottedLine(v1, v2, 1.0f); SceneHandles.DrawDottedLine(v2, v3, 1.0f); SceneHandles.DrawDottedLine(v3, v0, 1.0f); }
public static Rect DrawLabel(UnityEngine.Vector3 position, UnityEngine.Vector3 alignmentDirection, int padding, string text) { var matrix = SceneHandles.matrix; var pt = UnityEngine.Camera.current.WorldToViewportPoint(matrix.MultiplyPoint(position)); // cull if behind camera if (pt.z < 0) { return(new Rect()); } var labelStyle = new LabelStyle(SceneHandles.color, padding); if (!labelStyles.TryGetValue(labelStyle, out GUIStyle style)) { style = new UnityEngine.GUIStyle(); style.normal.textColor = SceneHandles.color; style.alignment = UnityEngine.TextAnchor.UpperLeft; // some eyeballed offsets because CalcSize returns a non-centered rect style.padding.left = 4 + padding; style.padding.right = padding; style.padding.top = 1 + padding; style.padding.bottom = 4 + padding; labelStyles[labelStyle] = style; } //SceneHandles.Label(position, text, style); = alignment is broken, positioning of text on coordinate is *weird* tempContent.text = text; var size = style.CalcSize(tempContent); var halfSize = size * 0.5f; var screenpos = UnityEditor.HandleUtility.WorldToGUIPoint(position); var screendir = (UnityEditor.HandleUtility.WorldToGUIPoint(position + alignmentDirection) - screenpos).normalized; // align on the rect around the text in the direction of alignmentDirection screenpos.x += (screendir.x - 1) * halfSize.x; screenpos.y += (screendir.y - 1) * halfSize.y; var rect = new Rect(screenpos.x, screenpos.y, size.x, size.y); if (Event.current.type == EventType.Repaint) { SceneHandles.BeginGUI(); { GUI.Label(rect, tempContent, style); } SceneHandles.EndGUI(); } return(rect); }
public static void DrawSelectionRectangle(Rect rect) { var origMatrix = SceneHandles.matrix; SceneHandles.matrix = Matrix4x4.identity; if (rect.width >= 0 || rect.height >= 0) { SceneHandles.BeginGUI(); selectionRect.Draw(rect, GUIContent.none, false, false, false, false); SceneHandles.EndGUI(); } SceneHandles.matrix = origMatrix; }
public static float RadiusHandle(Quaternion rotation, Vector3 position, float radius, bool renderDisc = true) { var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; // Radius handle in zenith bool temp = GUI.changed; // Radius handles at disc temp = GUI.changed; GUI.changed = false; var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = SizeSlider(position, up, forward, up, right, radius); radius = SizeSlider(position, -up, forward, up, right, radius); isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = SizeSlider(position, right, forward, up, right, radius); radius = SizeSlider(position, -right, forward, up, right, radius); if (GUI.changed) { radius = Mathf.Max(0.0f, radius); } GUI.changed |= temp; isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); // Draw gizmo if (radius > 0 && renderDisc) { SceneHandles.DrawWireDisc(position, forward, radius); } SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; return(radius); }
public static void DrawEdgeHandle(int id, Vector3 from, Vector3 to, bool setCursor, bool renderEdge = true, bool setControl = true, MouseCursor?cursor = null) { var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.Layout: { if (setCursor && setControl) { if (InCameraOrbitMode) { break; } UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToLine(from, to) * 0.5f); } break; } case EventType.Repaint: { if (setCursor && !InCameraOrbitMode) { if (!cursor.HasValue) { SetCursor(id, from, to); } else { SetCursor(id, cursor.Value); } } if (renderEdge) { linePoints[0] = from; linePoints[1] = to; if (EditorGUIUtility.keyboardControl == id) { SceneHandles.DrawAAPolyLine(3.5f, linePoints); } else { SceneHandles.DrawAAPolyLine(2.5f, linePoints); } } break; } } }
public static Vector3 Edge2DHandleOffset(int id, Vector3 from, Vector3 to, Vector3 position, Vector3 handleDir, Vector3 slideDir1, Vector3 slideDir2, float handleSize, CapFunction capFunction, Axes axes = Axes.None, Vector3?snappingSteps = null) { var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.Layout: { if (Tools.current == Tool.View || Tools.current == Tool.None || evt.alt) { break; } UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToLine(from, to) * 0.5f); break; } case EventType.Repaint: { var sceneView = SceneView.currentDrawingSceneView; if (sceneView && Tools.current != Tool.View && Tools.current != Tool.None && !evt.alt) { if (UnityEditor.HandleUtility.nearestControl == id || EditorGUIUtility.hotControl == id) { var rect = sceneView.position; rect.min = Vector2.zero; EditorGUIUtility.AddCursorRect(rect, SceneHandleUtility.GetCursorForEdge(from, to)); } } if (EditorGUIUtility.keyboardControl == id) { SceneHandles.DrawAAPolyLine(3.0f, from, to); } else { SceneHandles.DrawAAPolyLine(2.5f, from, to); } break; } } var points = new Vector3[] { from, to }; var result = Slider2D.Do(id, points, position, Vector3.zero, handleDir, slideDir1, slideDir2, handleSize, capFunction, axes, snappingSteps: snappingSteps); return(result[0] - from); }
public static float Radius2DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity, bool renderDisc = true) { minRadius = Mathf.Abs(minRadius); maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius) { maxRadius = minRadius; } var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var prevDisabled = SceneHandles.disabled; var prevColor = SceneHandles.color; var forward = rotation * Vector3.forward; var up = rotation * Vector3.up; var right = rotation * Vector3.right; bool temp = GUI.changed; GUI.changed = false; var isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = Size2DSlider(position, up, forward, up, right, radius); radius = Size2DSlider(position, -up, forward, up, right, radius); isDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0]; SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); radius = Size2DSlider(position, right, forward, up, right, radius); radius = Size2DSlider(position, -right, forward, up, right, radius); radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius)); GUI.changed |= temp; if (radius > 0 && renderDisc) { isDisabled = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]); SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false); SceneHandles.DrawWireDisc(position, forward, radius); SceneHandles.disabled = prevDisabled; SceneHandles.color = prevColor; } return(radius); }
public static void RenderDistance(Matrix4x4 transformation, Vector3 from, Vector3 to) { var distance = from - to; if (distance.sqrMagnitude == 0) { return; } using (new SceneHandles.DrawingScope(transformation)) { SceneHandles.DrawLine(from, to); SceneHandles.RenderBorderedDot(from, UnityEditor.HandleUtility.GetHandleSize(from) * HandleRendering.kPointScale); SceneHandles.RenderBorderedDot(to, UnityEditor.HandleUtility.GetHandleSize(to) * HandleRendering.kPointScale); } }
public static Vector3 Edge1DHandleOffset(int id, Axis axis, Vector3 from, Vector3 to, Vector3 position, Vector3 direction, float snappingStep, float handleSize, CapFunction capFunction) { var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.Layout: { if (Tools.current == Tool.View || Tools.current == Tool.None || evt.alt) { break; } UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToLine(from, to)); break; } case EventType.Repaint: { var sceneView = SceneView.currentDrawingSceneView; if (sceneView && Tools.current != Tool.View && Tools.current != Tool.None && !evt.alt) { var rect = sceneView.position; rect.min = Vector2.zero; var hovering = UnityEditor.HandleUtility.nearestControl == id && UnityEditor.HandleUtility.DistanceToLine(from, to) < 10; // in case multiple edges share the same id, we want to ignore those that aren't even close if (EditorGUIUtility.hotControl == id || hovering) { EditorGUIUtility.AddCursorRect(rect, SceneHandleUtility.GetCursorForEdge(from, to)); } } SceneHandles.DrawAAPolyLine(3.0f, from, to); break; } } var points = new Vector3[] { from, to }; var result = Slider1DHandle(id, axis, points, position, direction, snappingStep, handleSize, capFunction); return(result[0] - from); }
public static void RenderCylinder(Matrix4x4 transformation, Bounds bounds, int segments) { if (Event.current.type != EventType.Repaint || segments < 3) { return; } if (cylinderVertices == null || cylinderVertices.Length < segments * 2) { cylinderVertices = new Vector3[segments * 2]; } RenderSquareXZ(transformation, bounds); if (prevCylinderSegments != segments) { prevCylinderSegments = segments; float angleOffset = ((segments & 1) == 1) ? 0.0f : ((360.0f / segments) * 0.5f); var xVector = Vector3.right; var zVector = Vector3.forward; for (int v = 0; v < segments; v++) { var r = (((v * 360.0f) / (float)segments) + angleOffset) * Mathf.Deg2Rad; var s = Mathf.Sin(r); var c = Mathf.Cos(r); var bottomVertex = (xVector * c) + (zVector * s); var topVertex = bottomVertex; bottomVertex.y -= 1.0f; topVertex.y += 1.0f; cylinderVertices[v] = bottomVertex; cylinderVertices[v + segments] = topVertex; } } using (new SceneHandles.DrawingScope(transformation * Matrix4x4.TRS(bounds.center, Quaternion.identity, bounds.extents))) { for (int n0 = segments - 1, n1 = 0; n1 < segments; n0 = n1, n1++) { SceneHandles.DrawDottedLine(cylinderVertices[n0], cylinderVertices[n1], 1.0f); SceneHandles.DrawDottedLine(cylinderVertices[segments + n0], cylinderVertices[segments + n1], 1.0f); SceneHandles.DrawDottedLine(cylinderVertices[n1], cylinderVertices[segments + n1], 1.0f); } } }
public static void RenderSnapping1D(Vector3 min, Vector3 max, Vector3 pivot, Vector3 slideDirection, SnapResult1D snapResult, Axis axis) { if (Event.current.type != EventType.Repaint) { return; } using (new SceneHandles.DrawingScope(Matrix4x4.identity)) { if (max == min && (snapResult & SnapResult1D.Min) != 0) { snapResult &= ~SnapResult1D.Max; } if (pivot == min && (snapResult & SnapResult1D.Min) != 0) { snapResult &= ~SnapResult1D.Pivot; } if (pivot == max && (snapResult & SnapResult1D.Max) != 0) { snapResult &= ~SnapResult1D.Pivot; } var grid = Grid.ActiveGrid; var dotX = Mathf.Abs(Vector3.Dot(grid.Forward.normalized, slideDirection)); var dotZ = Mathf.Abs(Vector3.Dot(grid.Right.normalized, slideDirection)); var dotY = Mathf.Abs(Vector3.Dot(grid.Up.normalized, slideDirection)); if ((dotY - dotX) < 0.00001f && (dotY - dotZ) < 0.00001f && ((1.0f - dotX) < 0.00001f || (1.0f - dotZ) < 0.00001f)) { var direction = (dotX < dotZ) ? grid.Forward : grid.Right; if ((snapResult & SnapResult1D.Pivot) != 0) { SceneHandles.DrawDottedLine(pivot + (direction * -1000), pivot + (direction * 1000), 4.0f); } if ((snapResult & SnapResult1D.Min) != 0) { SceneHandles.DrawDottedLine(min + (direction * -1000), min + (direction * 1000), 4.0f); } if ((snapResult & SnapResult1D.Max) != 0) { SceneHandles.DrawDottedLine(max + (direction * -1000), max + (direction * 1000), 4.0f); } } } }
static void InfiniteLine(float x, float y, float z, Axis axis) { const float kLineSize = 1000; const int kLineParts = 10; const float kLineMultiply = kLineSize / kLineParts; switch (axis) { case Axis.X: { for (int i = 1; i < kLineParts; i++) { var n0 = (i - 1) * kLineMultiply; var n1 = i * kLineMultiply; SceneHandles.DrawDottedLine(new Vector3(x - n1, y, z), new Vector3(x - n0, y, z), 4.0f); SceneHandles.DrawDottedLine(new Vector3(x + n0, y, z), new Vector3(x + n1, y, z), 4.0f); } break; } case Axis.Y: { for (int i = 1; i < kLineParts; i++) { var n0 = (i - 1) * kLineMultiply; var n1 = i * kLineMultiply; SceneHandles.DrawDottedLine(new Vector3(x, y - n1, z), new Vector3(x, y - n0, z), 4.0f); SceneHandles.DrawDottedLine(new Vector3(x, y + n0, z), new Vector3(x, y + n1, z), 4.0f); } break; } case Axis.Z: { for (int i = 1; i < kLineParts; i++) { var n0 = (i - 1) * kLineMultiply; var n1 = i * kLineMultiply; SceneHandles.DrawDottedLine(new Vector3(x, y, z - n1), new Vector3(x, y, z - n0), 4.0f); SceneHandles.DrawDottedLine(new Vector3(x, y, z + n0), new Vector3(x, y, z + n1), 4.0f); } break; } } }
public static void RenderSquareXZ(Matrix4x4 transformation, Bounds bounds) { using (new SceneHandles.DrawingScope(transformation)) { var min = bounds.min; var max = bounds.max; float minX = min.x, minY = min.y, minZ = min.z; float maxX = max.x, maxZ = max.z; var v0 = new Vector3(minX, minY, minZ); var v1 = new Vector3(minX, minY, maxZ); var v2 = new Vector3(maxX, minY, maxZ); var v3 = new Vector3(maxX, minY, minZ); SceneHandles.DrawDottedLine(v0, v1, 1.0f); SceneHandles.DrawDottedLine(v1, v2, 1.0f); SceneHandles.DrawDottedLine(v2, v3, 1.0f); SceneHandles.DrawDottedLine(v3, v0, 1.0f); } }
public static void NormalHandleCap(int controlID, Vector3 position, Quaternion rotation, float size, EventType eventType) { switch (eventType) { case EventType.Layout: { if (SceneHandles.InCameraOrbitMode) { break; } if (controlID == -1) { break; } UnityEditor.HandleUtility.AddControl(controlID, UnityEditor.HandleUtility.DistanceToCircle(position, size)); UnityEditor.HandleUtility.AddControl(controlID, UnityEditor.HandleUtility.DistanceToLine(position, position + (rotation * Vector3.forward * size * 10))); break; } case EventType.Repaint: { RenderBorderedCircle(position, size); var prevColor = SceneHandles.color; var color = prevColor; color.a = 1.0f; var normal = rotation * Vector3.forward; SceneHandles.color = color; var currentFocusControl = SceneHandleUtility.focusControl; if (currentFocusControl == controlID) { SceneHandles.ArrowHandleCap(controlID, position, Quaternion.LookRotation(normal), size * 20, Event.current.type); } else { DrawAAPolyLine(3.5f, position, position + (normal * size * 10)); } SceneHandles.color = prevColor; break; } } }
public static void DrawFlatArrow(UnityEngine.Vector3 center, UnityEngine.Vector3 direction, UnityEngine.Vector3 forward, float handleSize) { var matrix = SceneHandles.matrix; SceneHandles.matrix = UnityEngine.Matrix4x4.identity; center = matrix.MultiplyPoint(center); var xdir = matrix.MultiplyVector(direction).normalized; var ydir = Vector3.Cross(xdir, matrix.MultiplyVector(forward)).normalized; ydir *= 0.3f * handleSize; xdir *= handleSize; arrowPoints[0] = center; arrowPoints[1] = center + (xdir - ydir); arrowPoints[2] = center + (xdir + ydir); SceneHandles.DrawAAConvexPolygon(arrowPoints); SceneHandles.matrix = matrix; }
public static Vector3 Edge1DHandleOffset(int id, Axis axis, Vector3 from, Vector3 to, Vector3 position, Vector3 direction, float snappingStep, float handleSize, CapFunction capFunction) { if (snappingStep == 0) { snappingStep = Snapping.MoveSnappingSteps[(int)axis]; } if (handleSize == 0) { handleSize = UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f; } var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.Layout: { if (SceneHandles.InCameraOrbitMode) { break; } UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToLine(from, to)); break; } case EventType.Repaint: { SetCursor(id, from, to); linePoints[0] = from; linePoints[1] = to; SceneHandles.DrawAAPolyLine(3.0f, linePoints); break; } } var points = new Vector3[] { from, to }; var result = Slider1DHandle(id, axis, points, position, direction, snappingStep, handleSize, capFunction); return(result[0] - from); }
public static void RenderSquareXZ(Matrix4x4 transformation, Vector3 start, Vector3 end) { var right = Vector3.right; var forward = Vector3.forward; var delta = (end - start); var width = Vector3.Dot(right, delta) * (Vector3)right; var length = Vector3.Dot(forward, delta) * (Vector3)forward; var v0 = start; var v1 = start + width; var v2 = start + width + length; var v3 = start + length; using (new SceneHandles.DrawingScope(transformation)) { SceneHandles.DrawDottedLine(v0, v1, 1.0f); SceneHandles.DrawDottedLine(v1, v2, 1.0f); SceneHandles.DrawDottedLine(v2, v3, 1.0f); SceneHandles.DrawDottedLine(v3, v0, 1.0f); } }
internal static Vector3[] Do(int id, Axis axis, Vector3[] points, Vector3 handleOrigin, Vector3 handleDirection, Vector3 slideDirection, float snappingStep = 0, float handleSize = 0, SceneHandles.CapFunction capFunction = null, bool selectLockingAxisOnClick = false) { if (snappingStep == 0) { snappingStep = Snapping.MoveSnappingSteps[(int)axis]; } if (handleSize == 0) { handleSize = UnityEditor.HandleUtility.GetHandleSize(handleOrigin) * 0.05f; } if (handleDirection.sqrMagnitude == 0) { return(points); } var evt = Event.current; var type = evt.GetTypeForControl(id); switch (type) { case EventType.MouseDown: { if (SceneHandles.InCameraOrbitMode) { break; } if (GUIUtility.hotControl != 0) { break; } if ((UnityEditor.HandleUtility.nearestControl != id || evt.button != 0) && (GUIUtility.keyboardControl != id || evt.button != 2)) { break; } GUIUtility.hotControl = GUIUtility.keyboardControl = id; evt.Use(); EditorGUIUtility.SetWantsMouseJumping(1); s_CurrentMousePosition = evt.mousePosition; s_StartPoints = points.ToArray(); var handleMatrix = SceneHandles.matrix; s_Snapping1D.Initialize(s_CurrentMousePosition, handleMatrix.MultiplyPoint(handleOrigin), handleMatrix.MultiplyVector(slideDirection), snappingStep, axis); s_Snapping1D.CalculateExtents(SceneHandles.inverseMatrix, s_StartPoints); s_MovedMouse = false; break; } case EventType.MouseDrag: { if (GUIUtility.hotControl != id) { break; } s_MovedMouse = true; if (SceneHandles.disabled || Snapping.IsAxisLocked(axis)) { break; } s_CurrentMousePosition += evt.delta; evt.Use(); if (!s_Snapping1D.Move(s_CurrentMousePosition)) { break; } var handleInverseMatrix = SceneHandles.inverseMatrix; var pointDelta = handleInverseMatrix.MultiplyVector(s_Snapping1D.WorldSnappedOffset); if (s_StartPoints != null) { points = new Vector3[points.Length]; // if we don't, it's hard to do Undo properly for (int i = 0; i < points.Length; i++) { points[i] = SnappingUtility.Quantize(s_StartPoints[i] + pointDelta); } } //SceneView.RepaintAll(); GUI.changed = true; break; } case EventType.MouseUp: { if (GUIUtility.hotControl == id && (evt.button == 0 || evt.button == 2)) { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; //Grid.currentGrid = s_PrevGrid; s_StartPoints = null; evt.Use(); EditorGUIUtility.SetWantsMouseJumping(0); if (!s_MovedMouse && selectLockingAxisOnClick) { switch (axis) { case Axis.X: { Snapping.ActiveAxes = Axes.X; break; } case Axis.Y: { Snapping.ActiveAxes = Axes.Y; break; } case Axis.Z: { Snapping.ActiveAxes = Axes.Z; break; } } } SceneView.RepaintAll(); } break; } #if UNITY_2020_1_OR_NEWER case EventType.MouseMove: { if (SceneHandles.InCameraOrbitMode) { break; } var position = handleOrigin; var rotation = Quaternion.LookRotation(handleDirection); if (handleSize > 0) { if (capFunction != null) { capFunction(id, position, rotation, handleSize, type); } } int currentFocusControl = SceneHandleUtility.focusControl; if ((currentFocusControl == id && s_PrevFocusControl != id) || (currentFocusControl != id && s_PrevFocusControl == id)) { s_PrevFocusControl = currentFocusControl; SceneView.RepaintAll(); } break; } #endif case EventType.Layout: { if (SceneHandles.InCameraOrbitMode) { break; } var position = handleOrigin; var rotation = Quaternion.LookRotation(handleDirection); if (handleSize > 0) { if (capFunction != null) { capFunction(id, position, rotation, handleSize, type); } else { UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToCircle(position, handleSize * .2f)); } } int currentFocusControl = SceneHandleUtility.focusControl; if ((currentFocusControl == id && s_PrevFocusControl != id) || (currentFocusControl != id && s_PrevFocusControl == id)) { s_PrevFocusControl = currentFocusControl; SceneView.RepaintAll(); } break; } case EventType.Repaint: { if (axis != Axis.None) { if (GUIUtility.hotControl == id) { var selectedColor = SceneHandles.StateColor(SceneHandles.MultiplyTransparency(SceneHandles.selectedColor, 0.5f)); using (new SceneHandles.DrawingScope(selectedColor)) HandleRendering.RenderSnapping1D(s_Snapping1D.Min, s_Snapping1D.Max, s_Snapping1D.WorldSnappedPosition, s_Snapping1D.SlideDirection, s_Snapping1D.SnapResult, axis); } } if (capFunction == null) { break; } var position = handleOrigin; var rotation = Quaternion.LookRotation(handleDirection); var color = SceneHandles.StateColor(SceneHandles.color, isSelected: (id == s_PrevFocusControl)); using (new SceneHandles.DrawingScope(color)) { capFunction(id, position, rotation, handleSize, EventType.Repaint); } break; } } return(points); }
public static Bounds BoundsHandle(Bounds bounds, Quaternion rotation, CapFunction sideCapFunction, CapFunction pointCapFunction, Vector3?snappingSteps = null) { var hotControl = GUIUtility.hotControl; bool isControlHot = false; for (int i = 0; i < s_BoundsControlIds.Length; i++) { s_BoundsControlIds[i] = GUIUtility.GetControlID(s_BoundsHash, FocusType.Keyboard); s_BoundsAxisHot[i] = s_BoundsControlIds[i] == hotControl; isControlHot = isControlHot || s_BoundsAxisHot[i]; } s_BoundsSlideDirs[0] = rotation * Vector3.right; s_BoundsSlideDirs[1] = rotation * Vector3.up; s_BoundsSlideDirs[2] = rotation * Vector3.forward; var min = bounds.min; var max = bounds.max; var center = bounds.center; s_BoundsValues[0] = min.x; s_BoundsValues[1] = min.y; s_BoundsValues[2] = min.z; s_BoundsValues[3] = max.x; s_BoundsValues[4] = max.y; s_BoundsValues[5] = max.z; s_BoundsVertices[0] = rotation * new Vector3(s_BoundsValues[0], s_BoundsValues[1], s_BoundsValues[2]); s_BoundsVertices[1] = rotation * new Vector3(s_BoundsValues[3], s_BoundsValues[1], s_BoundsValues[2]); s_BoundsVertices[2] = rotation * new Vector3(s_BoundsValues[3], s_BoundsValues[4], s_BoundsValues[2]); s_BoundsVertices[3] = rotation * new Vector3(s_BoundsValues[0], s_BoundsValues[4], s_BoundsValues[2]); s_BoundsVertices[4] = rotation * new Vector3(s_BoundsValues[0], s_BoundsValues[1], s_BoundsValues[5]); s_BoundsVertices[5] = rotation * new Vector3(s_BoundsValues[3], s_BoundsValues[1], s_BoundsValues[5]); s_BoundsVertices[6] = rotation * new Vector3(s_BoundsValues[3], s_BoundsValues[4], s_BoundsValues[5]); s_BoundsVertices[7] = rotation * new Vector3(s_BoundsValues[0], s_BoundsValues[4], s_BoundsValues[5]); s_BoundsSidePoint[0] = rotation * new Vector3(s_BoundsValues[0], center.y, center.z); s_BoundsSidePoint[1] = rotation * new Vector3(center.x, s_BoundsValues[1], center.z); s_BoundsSidePoint[2] = rotation * new Vector3(center.x, center.y, s_BoundsValues[2]); s_BoundsSidePoint[3] = rotation * new Vector3(s_BoundsValues[3], center.y, center.z); s_BoundsSidePoint[4] = rotation * new Vector3(center.x, s_BoundsValues[4], center.z); s_BoundsSidePoint[5] = rotation * new Vector3(center.x, center.y, s_BoundsValues[5]); // TODO: add handles in the corners of each quad on the bounds, with an offset from the vertex, to drag from there using (new SceneHandles.DrawingScope()) { var prevDisabled = SceneHandles.disabled; var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); for (int i = 0; i < s_BoundsAxisDisabled.Length; i++) { s_BoundsAxisDisabled[i] = isStatic || prevDisabled || Snapping.AxisLocking[i % 3] || (isControlHot && !s_BoundsAxisHot[i]); } var camera = Camera.current; var cameraLocalPos = SceneHandles.inverseMatrix.MultiplyPoint(camera.transform.position); var cameraLocalForward = SceneHandles.inverseMatrix.MultiplyVector(camera.transform.forward); var isCameraInsideBox = bounds.Contains(cameraLocalPos); var isCameraOrthographic = camera.orthographic; var boundsColor = SceneHandles.yAxisColor; var backfacedColor = new Color(boundsColor.r, boundsColor.g, boundsColor.b, boundsColor.a * SceneHandles.backfaceAlphaMultiplier); var prevGUIchanged = GUI.changed; bool haveChanged = false; var selectedAxes = Axes.None; // all sides of bounds int currentFocusControl = SceneHandleUtility.focusControl; for (int i = 0; i < s_BoundsValues.Length; i++) { var id = s_BoundsControlIds[i]; GUI.changed = false; var localPoint = s_BoundsSidePoint[i]; var handleSize = UnityEditor.HandleUtility.GetHandleSize(localPoint); var pointSize = handleSize * kPointScale; var direction = s_BoundsSlideDirs[i % 3]; var normal = (i < 3) ? -direction : direction; normal.x *= (bounds.size.x < 0) ? -1 : 1; normal.y *= (bounds.size.y < 0) ? -1 : 1; normal.z *= (bounds.size.z < 0) ? -1 : 1; if (Event.current.type == EventType.Repaint) { s_BoundsBackfaced[i] = false; if (!isCameraInsideBox) { var cosV = isCameraOrthographic ? Vector3.Dot(normal, -cameraLocalForward) : Vector3.Dot(normal, (cameraLocalPos - localPoint)); if (cosV < -0.0001f) { // TODO: do not set backfaced to true when side is infinitely thin s_BoundsBackfaced[i] = !(isControlHot && !s_BoundsAxisHot[i % 3]); } } var sideColor = (s_BoundsBackfaced[i] ? backfacedColor: boundsColor); SceneHandles.color = SceneHandles.StateColor(sideColor, s_BoundsAxisDisabled[i], (currentFocusControl == id)); if (currentFocusControl == id) { var sceneView = SceneView.currentDrawingSceneView; if (sceneView) { var rect = sceneView.position; rect.min = Vector2.zero; EditorGUIUtility.AddCursorRect(rect, SceneHandleUtility.GetCursorForDirection(localPoint, normal)); } selectedAxes = s_BoundsAxes[i]; } if (s_BoundsBackfaced[i]) { pointSize *= backfaceSizeMultiplier; } } var steps = snappingSteps ?? Snapping.MoveSnappingSteps; var newPoint = Slider1DHandle(id, (Axis)(i % 3), localPoint, normal, steps[i % 3], pointSize, sideCapFunction); if (GUI.changed) { s_BoundsValues[i] += Vector3.Dot(direction, newPoint - localPoint); haveChanged = true; } } // all edges of bounds for (int i = 0; i < s_BoundsEdgeIndices.GetLength(0); i++) { var id = GUIUtility.GetControlID(s_BoundsHash, FocusType.Keyboard); GUI.changed = false; var index1 = s_BoundsEdgeIndices[i, 0]; var index2 = s_BoundsEdgeIndices[i, 1]; var point1 = s_BoundsVertices[index1]; var point2 = s_BoundsVertices[index2]; var midPoint = (point1 + point2) * 0.5f; var offset1 = s_EdgeDirectionOffsets[i, 0]; var offset2 = s_EdgeDirectionOffsets[i, 1]; var offset3 = s_EdgeDirectionOffsets[i, 2]; var offset1_dir = offset1 % 3; var offset2_dir = offset2 % 3; if (Event.current.type == EventType.Repaint) { var highlight = (currentFocusControl == id) || (currentFocusControl == s_BoundsControlIds[offset1]) || (currentFocusControl == s_BoundsControlIds[offset2]); var edgeColor = (s_BoundsBackfaced[offset1] && s_BoundsBackfaced[offset2]) ? backfacedColor : boundsColor; var edgeDisabled = (s_BoundsAxisDisabled[offset1] && s_BoundsAxisDisabled[offset2]); SceneHandles.color = SceneHandles.StateColor(edgeColor, edgeDisabled, highlight); if (currentFocusControl == id) { selectedAxes = s_EdgeAxes[i]; } } // only use capFunction (render point) when in ortho mode & aligned with box or when side size is 0 bool isSideAlignedWithCamera = false; // TODO: determine if aligned with camera direction & in ortho mode bool showSidePoint = !isSideAlignedWithCamera && ((point2 - point1).sqrMagnitude < kShowPointThreshold); float pointSize; Vector3 offset; if (showSidePoint) { pointSize = UnityEditor.HandleUtility.GetHandleSize(midPoint) * kPointScale; offset = Edge2DHandleOffset(id, point1, point2, midPoint, s_BoundsSlideDirs[offset3], s_BoundsSlideDirs[offset1_dir], s_BoundsSlideDirs[offset2_dir], pointSize, pointCapFunction, s_EdgeAxes[i], snappingSteps: snappingSteps); } else { offset = Edge2DHandleOffset(id, point1, point2, midPoint, s_BoundsSlideDirs[offset3], s_BoundsSlideDirs[offset1_dir], s_BoundsSlideDirs[offset2_dir], 0, null, s_EdgeAxes[i], snappingSteps: snappingSteps); } if (GUI.changed) { offset = Quaternion.Inverse(rotation) * offset; if (Mathf.Abs(offset[offset1_dir]) > 0.000001f || Mathf.Abs(offset[offset2_dir]) > 0.000001f) { s_BoundsValues[offset1] += offset[offset1_dir]; s_BoundsValues[offset2] += offset[offset2_dir]; haveChanged = true; } else { GUI.changed = false; } } } GUI.changed = prevGUIchanged || haveChanged; if (haveChanged) { var size = bounds.size; center.x = (s_BoundsValues[3] + s_BoundsValues[0]) * 0.5f; size.x = (s_BoundsValues[3] - s_BoundsValues[0]); center.y = (s_BoundsValues[4] + s_BoundsValues[1]) * 0.5f; size.y = (s_BoundsValues[4] - s_BoundsValues[1]); center.z = (s_BoundsValues[5] + s_BoundsValues[2]) * 0.5f; size.z = (s_BoundsValues[5] - s_BoundsValues[2]); bounds.center = center; bounds.size = size; } // TODO: paint XZ intersection with grid plane + 'shadow' SceneHandles.disabled = prevDisabled; } return(bounds); }
public static void RenderSnapping3D(Grid grid, Extents3D extents, Vector3 pivotPosition, SnapResult3D snapResult, bool ignorePivot = false) { if (Event.current.type != EventType.Repaint) { return; } using (new SceneHandles.DrawingScope(grid.GridToWorldSpace)) { if (extents.min.x == extents.max.x && (snapResult & SnapResult3D.MinX) != 0) { snapResult &= ~SnapResult3D.MaxX; } if (extents.min.y == extents.max.y && (snapResult & SnapResult3D.MinY) != 0) { snapResult &= ~SnapResult3D.MaxY; } if (extents.min.z == extents.max.z && (snapResult & SnapResult3D.MinZ) != 0) { snapResult &= ~SnapResult3D.MaxZ; } if (ignorePivot) { snapResult &= ~SnapResult3D.PivotX; snapResult &= ~SnapResult3D.PivotY; snapResult &= ~SnapResult3D.PivotZ; } else { if (extents.min.x == pivotPosition.x && (snapResult & SnapResult3D.MinX) != 0) { snapResult &= ~SnapResult3D.PivotX; } if (extents.min.y == pivotPosition.y && (snapResult & SnapResult3D.MinY) != 0) { snapResult &= ~SnapResult3D.PivotY; } if (extents.min.z == pivotPosition.z && (snapResult & SnapResult3D.MinZ) != 0) { snapResult &= ~SnapResult3D.PivotZ; } if (extents.max.x == pivotPosition.x && (snapResult & SnapResult3D.MaxX) != 0) { snapResult &= ~SnapResult3D.PivotX; } if (extents.max.y == pivotPosition.y && (snapResult & SnapResult3D.MaxY) != 0) { snapResult &= ~SnapResult3D.PivotY; } if (extents.max.z == pivotPosition.z && (snapResult & SnapResult3D.MaxZ) != 0) { snapResult &= ~SnapResult3D.PivotZ; } } float y = 0; if (extents.min.y > 0) { y = extents.min.y; } else if (extents.max.y < 0) { y = extents.max.y; } RenderCrossXZ(extents, y, pivotPosition, snapResult); RenderBox(extents); var color = SceneHandles.color; color.a *= 0.5f; SceneHandles.color = color; if (y != 0) { RenderSquareXZ(extents, 0); if ((snapResult & SnapResult3D.MinX) != 0) { var center = new Vector3(extents.min.x, y, pivotPosition.z); if ((snapResult & SnapResult3D.MinZ) != 0) { SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.min.z), new Vector3(center.x, center.y, extents.min.z), 4.0f); } if ((snapResult & SnapResult3D.MaxZ) != 0) { SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.max.z), new Vector3(center.x, center.y, extents.max.z), 4.0f); } } if ((snapResult & SnapResult3D.MinZ) != 0) { var center = new Vector3(pivotPosition.x, y, extents.min.z); if ((snapResult & SnapResult3D.MinX) != 0) { SceneHandles.DrawDottedLine(new Vector3(extents.min.x, 0, center.z), new Vector3(extents.min.x, center.y, center.z), 4.0f); } if ((snapResult & SnapResult3D.MaxX) != 0) { SceneHandles.DrawDottedLine(new Vector3(extents.max.x, 0, center.z), new Vector3(extents.max.x, center.y, center.z), 4.0f); } } if ((snapResult & SnapResult3D.MaxX) != 0) { var center = new Vector3(extents.max.x, y, pivotPosition.z); if ((snapResult & SnapResult3D.MinZ) != 0) { SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.min.z), new Vector3(center.x, center.y, extents.min.z), 4.0f); } if ((snapResult & SnapResult3D.MaxZ) != 0) { SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.max.z), new Vector3(center.x, center.y, extents.max.z), 4.0f); } } if ((snapResult & SnapResult3D.MaxZ) != 0) { var center = new Vector3(pivotPosition.x, y, extents.max.z); if ((snapResult & SnapResult3D.MinX) != 0) { SceneHandles.DrawDottedLine(new Vector3(extents.min.x, 0, center.z), new Vector3(extents.min.x, center.y, center.z), 4.0f); } if ((snapResult & SnapResult3D.MaxX) != 0) { SceneHandles.DrawDottedLine(new Vector3(extents.max.x, 0, center.z), new Vector3(extents.max.x, center.y, center.z), 4.0f); } } } } }
public static Vector3[] Do(int id, Vector3[] points, Vector3 handleOrigin, Vector3 handleCursorOffset, Vector3 handleNormal, Vector3 slideDir1, Vector3 slideDir2, float handleSize, SceneHandles.CapFunction capFunction, Axes axes = Axes.None, bool selectLockingAxisOnClick = false, bool noSnapping = false, Vector3?snappingSteps = null) { var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.MouseDown: { if (Tools.current == Tool.View || Tools.current == Tool.None || evt.alt) { break; } if (GUIUtility.hotControl != 0) { break; } if ((UnityEditor.HandleUtility.nearestControl != id || evt.button != 0) && (GUIUtility.keyboardControl != id || evt.button != 2)) { break; } GUIUtility.hotControl = GUIUtility.keyboardControl = id; evt.Use(); EditorGUIUtility.SetWantsMouseJumping(1); s_CurrentMousePosition = evt.mousePosition; s_StartPoints = points.ToArray(); var localToWorldMatrix = UnityEditor.Handles.matrix; var center = Grid.ActiveGrid.Center; Matrix4x4 gridSpace = Matrix4x4.identity; gridSpace.SetColumn(0, localToWorldMatrix.MultiplyVector(slideDir1).normalized); gridSpace.SetColumn(1, localToWorldMatrix.MultiplyVector(handleNormal).normalized); gridSpace.SetColumn(2, localToWorldMatrix.MultiplyVector(slideDir2).normalized); gridSpace.SetColumn(3, new Vector4(center.x, center.y, center.z, 1.0f)); var workGrid = new Grid(gridSpace, snappingSteps.HasValue ? snappingSteps.Value : Snapping.MoveSnappingSteps); s_Snapping2D.Initialize(workGrid, s_CurrentMousePosition, handleOrigin, localToWorldMatrix); s_Snapping2D.CalculateExtents(s_StartPoints); s_MovedMouse = false; break; } case EventType.MouseDrag: { if (GUIUtility.hotControl != id) { break; } s_MovedMouse = true; if (SceneHandles.disabled || Snapping.AreAxisLocked(axes)) { break; } s_CurrentMousePosition += evt.delta; evt.Use(); if (!s_Snapping2D.DragTo(s_CurrentMousePosition, noSnapping ? SnappingMode.Never: SnappingMode.Default)) { break; } var handleInverseMatrix = UnityEditor.Handles.inverseMatrix; var pointDelta = handleInverseMatrix.MultiplyVector(s_Snapping2D.WorldSnappedDelta); if (s_StartPoints != null) { points = new Vector3[points.Length]; // if we don't, it's hard to do Undo properly for (int i = 0; i < points.Length; i++) { points[i] = SnappingUtility.Quantize(s_StartPoints[i] + pointDelta); } } //SceneView.RepaintAll(); GUI.changed = true; break; } case EventType.MouseUp: { if (GUIUtility.hotControl == id && (evt.button == 0 || evt.button == 2)) { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; s_StartPoints = null; evt.Use(); EditorGUIUtility.SetWantsMouseJumping(0); SceneView.RepaintAll(); if (!s_MovedMouse && selectLockingAxisOnClick) { Snapping.ActiveAxes = axes; } } break; } case EventType.Layout: { if (Tools.current == Tool.View || Tools.current == Tool.None || evt.alt) { break; } var position = handleOrigin + handleCursorOffset; var rotation = Quaternion.LookRotation(handleNormal, slideDir1); if (capFunction != null) { capFunction(id, position, rotation, handleSize, EventType.Layout); } else { UnityEditor.HandleUtility.AddControl(id, UnityEditor.HandleUtility.DistanceToCircle(position, handleSize * .5f)); } int currentFocusControl = SceneHandleUtility.focusControl; if ((currentFocusControl == id && s_PrevFocusControl != id) || (currentFocusControl != id && s_PrevFocusControl == id)) { s_PrevFocusControl = currentFocusControl; SceneView.RepaintAll(); } break; } case EventType.Repaint: { if (axes != Axes.None) { if (GUIUtility.hotControl == id) { var selectedColor = UnityEditor.Handles.selectedColor; selectedColor.a = 0.5f; using (new SceneHandles.DrawingScope(selectedColor)) HandleRendering.RenderSnapping3D(s_Snapping2D.WorldSlideGrid, s_Snapping2D.WorldSnappedExtents, s_Snapping2D.GridSnappedPosition, s_Snapping2D.SnapResult); } } if (capFunction == null) { break; } var position = handleOrigin + handleCursorOffset; var rotation = Quaternion.LookRotation(handleNormal, slideDir1); var color = SceneHandles.StateColor(SceneHandles.color, isSelected: (id == s_PrevFocusControl)); using (new SceneHandles.DrawingScope(color)) { capFunction(id, position, rotation, handleSize, EventType.Repaint); } break; } } return(points); }
static Vector3[] PlanarHandle(int id, PlaneAxes planarAxes, Vector3[] points, Vector3 position, Quaternion rotation, float handleSize, bool selectLockingAxisOnClick = false) { int axis1index = 0; int axis2index = 0; var isStatic = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects)); var axes = Axes.None; switch (planarAxes) { case PlaneAxes.XZ: { axis1index = 0; axis2index = 2; axes = Axes.XZ; break; } case PlaneAxes.XY: { axis1index = 0; axis2index = 1; axes = Axes.XY; break; } case PlaneAxes.YZ: { axis1index = 1; axis2index = 2; axes = Axes.YZ; break; } } int axisNormalIndex = 3 - axis2index - axis1index; var prevColor = SceneHandles.color; var handleTransform = Matrix4x4.TRS(position, rotation, Vector3.one); var sceneView = SceneView.currentDrawingSceneView; var cameraToTransformToolVector = handleTransform.inverse.MultiplyPoint(sceneView.camera.transform.position).normalized; /* * if (Mathf.Abs (cameraToTransformToolVector[axisNormalIndex]) < 0.05f && GUIUtility.hotControl != id) * { * Handles.color = prevColor; * return points; * }*/ if (EditorGUIUtility.hotControl == 0) { s_PlanarHandlesOctant[axis1index] = (cameraToTransformToolVector[axis1index] < -0.01f ? -1 : 1); s_PlanarHandlesOctant[axis2index] = (cameraToTransformToolVector[axis2index] < -0.01f ? -1 : 1); } var handleOffset = s_PlanarHandlesOctant; handleOffset[axisNormalIndex] = 0; handleOffset = rotation * (handleOffset * handleSize * 0.5f); var axis1 = Vector3.zero; var axis2 = Vector3.zero; var axisNormal = Vector3.zero; axis1[axis1index] = 1; axis2[axis2index] = 1; axisNormal[axisNormalIndex] = 1; axis1 = rotation * axis1; axis2 = rotation * axis2; axisNormal = rotation * axisNormal; s_Vertices[0] = position + handleOffset + (axis1 + axis2) * handleSize * 0.5f; s_Vertices[1] = position + handleOffset + (-axis1 + axis2) * handleSize * 0.5f; s_Vertices[2] = position + handleOffset + (-axis1 - axis2) * handleSize * 0.5f; s_Vertices[3] = position + handleOffset + (axis1 - axis2) * handleSize * 0.5f; var innerColor = SceneHandles.color; var outerColor = Color.black; innerColor = new Color(innerColor.r, innerColor.g, innerColor.b, 0.1f); if (!isStatic && !SceneHandles.disabled) { SceneHandles.DrawSolidRectangleWithOutline(s_Vertices, innerColor, outerColor); } points = Slider2DHandle(id, points, position, handleOffset, axisNormal, axis1, axis2, handleSize * 0.5f, RectangleHandleCap, axes, selectLockingAxisOnClick); SceneHandles.color = prevColor; return(points); }
public static Vector3[] PositionHandle(ref PositionHandleIDs handleIDs, Vector3[] points, Vector3 position, Quaternion rotation, Axes enabledAxes = Axes.XYZ) { var xAxisId = handleIDs.xAxisId; var yAxisId = handleIDs.yAxisId; var zAxisId = handleIDs.zAxisId; var xzPlaneId = handleIDs.xzPlaneId; var xyPlaneId = handleIDs.xyPlaneId; var yzPlaneId = handleIDs.yzPlaneId; var centerId = handleIDs.centerId; var originalColor = SceneHandles.color; var handleSize = UnityEditor.HandleUtility.GetHandleSize(position); UnityEditor.HandleUtility.AddControl(centerId, UnityEditor.HandleUtility.DistanceToCircle(position, handleSize * 0.055f)); var evt = Event.current; var type = evt.GetTypeForControl(centerId); switch (type) { case EventType.MouseDown: { if (GUIUtility.hotControl != 0) { break; } if ((UnityEditor.HandleUtility.nearestControl != centerId || evt.button != 0) && (GUIUtility.keyboardControl != centerId || evt.button != 2)) { break; } handleIDs.originalPosition = position; GUIUtility.hotControl = GUIUtility.keyboardControl = centerId; evt.Use(); EditorGUIUtility.SetWantsMouseJumping(1); break; } case EventType.MouseMove: { handleIDs.originalPosition = position; break; } case EventType.MouseDrag: { if (GUIUtility.hotControl != centerId) { break; } break; } case EventType.MouseUp: { if (GUIUtility.hotControl == centerId && (evt.button == 0 || evt.button == 2)) { GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; evt.Use(); Snapping.ActiveAxes = Axes.XYZ; EditorGUIUtility.SetWantsMouseJumping(0); SceneView.RepaintAll(); handleIDs.originalPosition = position; } break; } } //,.,.., look at 2018.1 how the position handle works w/ colors var xAxisLocked = (handleIDs.xAxisState & ControlState.Locked) == ControlState.Locked; var yAxisLocked = (handleIDs.yAxisState & ControlState.Locked) == ControlState.Locked; var zAxisLocked = (handleIDs.zAxisState & ControlState.Locked) == ControlState.Locked; var xzPlaneLocked = (handleIDs.xzPlaneState & ControlState.Locked) == ControlState.Locked; var xyPlaneLocked = (handleIDs.xyPlaneState & ControlState.Locked) == ControlState.Locked; var yzPlaneLocked = (handleIDs.yzPlaneState & ControlState.Locked) == ControlState.Locked; var xAxisDisabled = ((enabledAxes & Axes.X) != Axes.X) || (handleIDs.xAxisState & ControlState.Disabled) == ControlState.Disabled; var yAxisDisabled = ((enabledAxes & Axes.Y) != Axes.Y) || (handleIDs.yAxisState & ControlState.Disabled) == ControlState.Disabled; var zAxisDisabled = ((enabledAxes & Axes.Z) != Axes.Z) || (handleIDs.zAxisState & ControlState.Disabled) == ControlState.Disabled; var xyPlaneDisabled = ((enabledAxes & Axes.XY) != Axes.XY) || (handleIDs.xyPlaneState & ControlState.Disabled) == ControlState.Disabled; var yzPlaneDisabled = ((enabledAxes & Axes.YZ) != Axes.YZ) || (handleIDs.yzPlaneState & ControlState.Disabled) == ControlState.Disabled; var xzPlaneDisabled = ((enabledAxes & Axes.XZ) != Axes.XZ) || (handleIDs.xzPlaneState & ControlState.Disabled) == ControlState.Disabled; var xAxisSelected = (handleIDs.xAxisIndirectState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var yAxisSelected = (handleIDs.yAxisIndirectState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var zAxisSelected = (handleIDs.zAxisIndirectState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var xzPlaneSelected = (handleIDs.xzPlaneState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var xyPlaneSelected = (handleIDs.xyPlaneState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var yzPlaneSelected = (handleIDs.yzPlaneState & (ControlState.Focused | ControlState.Active)) != ControlState.None; var xAxisColor = SceneHandles.StateColor(SceneHandles.xAxisColor, xAxisDisabled, xAxisSelected); var yAxisColor = SceneHandles.StateColor(SceneHandles.yAxisColor, yAxisDisabled, yAxisSelected); var zAxisColor = SceneHandles.StateColor(SceneHandles.zAxisColor, zAxisDisabled, zAxisSelected); var xzPlaneColor = SceneHandles.StateColor(SceneHandles.yAxisColor, xzPlaneDisabled, xzPlaneSelected); var xyPlaneColor = SceneHandles.StateColor(SceneHandles.zAxisColor, xyPlaneDisabled, xyPlaneSelected); var yzPlaneColor = SceneHandles.StateColor(SceneHandles.xAxisColor, yzPlaneDisabled, yzPlaneSelected); var prevDisabled = SceneHandles.disabled; if (!xAxisLocked) { SceneHandles.disabled = xAxisDisabled; SceneHandles.color = xAxisColor; points = Slider1DHandle(xAxisId, Axis.X, points, position, rotation * Vector3.right, Snapping.MoveSnappingSteps.x, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true); } if (!yAxisLocked) { SceneHandles.disabled = yAxisDisabled; SceneHandles.color = yAxisColor; points = Slider1DHandle(yAxisId, Axis.Y, points, position, rotation * Vector3.up, Snapping.MoveSnappingSteps.y, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true); } if (!zAxisLocked) { SceneHandles.disabled = zAxisDisabled; SceneHandles.color = zAxisColor; points = Slider1DHandle(zAxisId, Axis.Z, points, position, rotation * Vector3.forward, Snapping.MoveSnappingSteps.z, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true); } if (!xzPlaneLocked) { SceneHandles.disabled = xzPlaneDisabled; SceneHandles.color = xzPlaneColor; points = PlanarHandle(xzPlaneId, PlaneAxes.XZ, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true); } if (!xyPlaneLocked) { SceneHandles.disabled = xyPlaneDisabled; SceneHandles.color = xyPlaneColor; points = PlanarHandle(xyPlaneId, PlaneAxes.XY, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true); } if (!yzPlaneLocked) { SceneHandles.disabled = yzPlaneDisabled; SceneHandles.color = yzPlaneColor; points = PlanarHandle(yzPlaneId, PlaneAxes.YZ, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true); } if ((handleIDs.centerState & ControlState.Disabled) != ControlState.Disabled) { switch (type) { case EventType.Repaint: { var focused = (handleIDs.centerState & ControlState.Focused) == ControlState.Focused; SceneHandles.color = SceneHandles.StateColor(SceneHandles.centerColor, false, focused); SceneHandles.RenderBorderedCircle(position, handleSize * 0.05f); break; } } } SceneHandles.disabled = prevDisabled; SceneHandles.color = originalColor; return(points); }