Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
            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);
            }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
            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 Vector3[] PositionHandle(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 isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevDisabled = SceneHandles.disabled;

            var hotControl = GUIUtility.hotControl;

            var xAxisIsHot  = (xAxisId == hotControl);
            var yAxisIsHot  = (yAxisId == hotControl);
            var zAxisIsHot  = (zAxisId == hotControl);
            var xzAxisIsHot = (xzPlaneId == hotControl);
            var xyAxisIsHot = (xyPlaneId == hotControl);
            var yzAxisIsHot = (yzPlaneId == hotControl);
            var centerIsHot = (centerId == hotControl);

            var isControlHot = xAxisIsHot || yAxisIsHot || zAxisIsHot || xzAxisIsHot || xyAxisIsHot || yzAxisIsHot || centerIsHot;

            var handleSize    = UnityEditor.HandleUtility.GetHandleSize(position);
            var originalColor = SceneHandles.color;

            var activeAxes = Snapping.ActiveAxes;

            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;
                }

                GUIUtility.hotControl = GUIUtility.keyboardControl = centerId;
                evt.Use();
                EditorGUIUtility.SetWantsMouseJumping(1);
                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();
                }
                break;
            }
            }

            //,.,.., look at 2018.1 how the position handle works w/ colors

            var xAxisActive = !Snapping.AxisLocking[0];
            var yAxisActive = !Snapping.AxisLocking[1];
            var zAxisActive = !Snapping.AxisLocking[2];

            var xzPlaneActive = xAxisActive && zAxisActive;
            var xyPlaneActive = xAxisActive && yAxisActive;
            var yzPlaneActive = yAxisActive && zAxisActive;

            var xAxisDisabled   = isStatic || prevDisabled || ((enabledAxes & Axes.X) == 0) || !xAxisActive || (isControlHot && !xAxisIsHot && !xzAxisIsHot && !xyAxisIsHot);
            var yAxisDisabled   = isStatic || prevDisabled || ((enabledAxes & Axes.Y) == 0) || !yAxisActive || (isControlHot && !yAxisIsHot && !xyAxisIsHot && !yzAxisIsHot);
            var zAxisDisabled   = isStatic || prevDisabled || ((enabledAxes & Axes.Z) == 0) || !zAxisActive || (isControlHot && !zAxisIsHot && !xzAxisIsHot && !yzAxisIsHot);
            var xzPlaneDisabled = isStatic || prevDisabled || ((enabledAxes & Axes.XZ) != Axes.XZ) || !xzPlaneActive || (isControlHot && !xzAxisIsHot);
            var xyPlaneDisabled = isStatic || prevDisabled || ((enabledAxes & Axes.XY) != Axes.XY) || !xyPlaneActive || (isControlHot && !xyAxisIsHot);
            var yzPlaneDisabled = isStatic || prevDisabled || ((enabledAxes & Axes.YZ) != Axes.YZ) || !yzPlaneActive || (isControlHot && !yzAxisIsHot);

            var currentFocusControl = SceneHandleUtility.focusControl;

            var xAxisIndirectlyFocused = (currentFocusControl == xyPlaneId || currentFocusControl == xzPlaneId);
            var yAxisIndirectlyFocused = (currentFocusControl == xyPlaneId || currentFocusControl == yzPlaneId);
            var zAxisIndirectlyFocused = (currentFocusControl == xzPlaneId || currentFocusControl == yzPlaneId);

            var xAxisIndirectlyActive = activeAxes == Axes.XY || activeAxes == Axes.XZ;
            var yAxisIndirectlyActive = activeAxes == Axes.XY || activeAxes == Axes.YZ;
            var zAxisIndirectlyActive = activeAxes == Axes.XZ || activeAxes == Axes.YZ;

            var xAxisSelected = xAxisIndirectlyFocused || xAxisIndirectlyActive || activeAxes == Axes.X;
            var yAxisSelected = yAxisIndirectlyFocused || yAxisIndirectlyActive || activeAxes == Axes.Y;
            var zAxisSelected = zAxisIndirectlyFocused || zAxisIndirectlyActive || activeAxes == Axes.Z;
            var xzAxiSelected = activeAxes == Axes.XZ;
            var xyAxiSelected = activeAxes == Axes.XZ;
            var yzAxiSelected = activeAxes == Axes.YZ;

            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, xzAxiSelected);
            var xyPlaneColor = SceneHandles.StateColor(SceneHandles.zAxisColor, xyPlaneDisabled, xyAxiSelected);
            var yzPlaneColor = SceneHandles.StateColor(SceneHandles.xAxisColor, yzPlaneDisabled, yzAxiSelected);


            if (xAxisActive)
            {
                SceneHandles.disabled = xAxisDisabled;
                SceneHandles.color    = xAxisColor;
                points = Slider1DHandle(xAxisId, Axis.X, points, position, rotation * Vector3.right, Snapping.MoveSnappingSteps.x, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true);
            }

            if (yAxisActive)
            {
                SceneHandles.disabled = yAxisDisabled;
                SceneHandles.color    = yAxisColor;
                points = Slider1DHandle(yAxisId, Axis.Y, points, position, rotation * Vector3.up, Snapping.MoveSnappingSteps.y, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true);
            }

            if (zAxisActive)
            {
                SceneHandles.disabled = zAxisDisabled;
                SceneHandles.color    = zAxisColor;
                points = Slider1DHandle(zAxisId, Axis.Z, points, position, rotation * Vector3.forward, Snapping.MoveSnappingSteps.z, handleSize, ArrowHandleCap, selectLockingAxisOnClick: true);
            }

            if (xzPlaneActive)
            {
                SceneHandles.disabled = xzPlaneDisabled;
                SceneHandles.color    = xzPlaneColor;
                points = PlanarHandle(xzPlaneId, PlaneAxes.XZ, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true);
            }

            if (xyPlaneActive)
            {
                SceneHandles.disabled = xyPlaneDisabled;
                SceneHandles.color    = xyPlaneColor;
                points = PlanarHandle(xyPlaneId, PlaneAxes.XY, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true);
            }

            if (yzPlaneActive)
            {
                SceneHandles.disabled = yzPlaneDisabled;
                SceneHandles.color    = yzPlaneColor;
                points = PlanarHandle(yzPlaneId, PlaneAxes.YZ, points, position, rotation, handleSize * 0.3f, selectLockingAxisOnClick: true);
            }


            switch (type)
            {
            case EventType.Repaint:
            {
                SceneHandles.color = SceneHandles.StateColor(SceneHandles.centerColor, false, centerId == SceneHandleUtility.focusControl);
                SceneHandles.RenderBorderedCircle(position, handleSize * 0.05f);
                break;
            }
            }



            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = originalColor;

            return(points);
        }
Ejemplo n.º 9
0
        public static Vector3 RadiusHandle(Vector3 center, Vector3 up, Vector3 radius)
        {
            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevDisabled = SceneHandles.disabled;
            var prevColor    = SceneHandles.color;
            var prevChanged  = GUI.changed;


            var delta1 = radius - center;
            var delta2 = Quaternion.AngleAxis(90, up) * delta1;

            var position0 = center + delta1;
            var position1 = center - delta1;
            var position2 = center + delta2;
            var position3 = center - delta2;


            float   size;
            Vector3 forward;
            Vector3 right;

            GeometryUtility.CalculateTangents(up, out right, out forward);



            var isDisabled = isStatic || prevDisabled;

            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position0);
            position0   = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = position0; prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position1);
            position1   = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = center - (position1 - center); prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position2);
            position2   = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = center + (Quaternion.AngleAxis(-90, up) * (position2 - center)); prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position3);
            position3   = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = center - (Quaternion.AngleAxis(-90, up) * (position3 - center)); prevChanged = true;
            }



            GUI.changed |= prevChanged;

            isDisabled         = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


            float radiusMagnitude = delta1.magnitude;

            if (radiusMagnitude > 0)
            {
                SceneHandles.DrawWireDisc(center, up, radiusMagnitude);
            }


            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = prevColor;
            return(radius);
        }
Ejemplo n.º 10
0
        public static void RadiusHandle(Vector3 center, Vector3 up, ref Vector3 radius1, ref Vector3 radius2)
        {
            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevColor    = SceneHandles.color;
            var prevMatrix   = SceneHandles.matrix;
            var prevDisabled = SceneHandles.disabled;
            var prevChanged  = GUI.changed;


            var delta1 = radius1 - center;
            var delta2 = radius2 - center;

            var position0 = center + delta1;
            var position1 = center - delta1;
            var position2 = center + delta2;
            var position3 = center - delta2;


            float   size;
            Vector3 forward;
            Vector3 right;

            GeometryUtility.CalculateTangents(up, out right, out forward);



            var isDisabled = isStatic || prevDisabled;

            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position0);
            position0   = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius1     = position0;
                radius2     = center + (Quaternion.AngleAxis(-90, up) * ((radius1 - center).normalized * (radius2 - center).magnitude));
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position1);
            position1   = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius1     = center - (position1 - center);
                radius2     = center + (Quaternion.AngleAxis(-90, up) * ((radius1 - center).normalized * (radius2 - center).magnitude));
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position2);
            position2   = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius2     = center + (position2 - center);
                radius1     = center + (Quaternion.AngleAxis(-90, up) * ((radius2 - center).normalized * (radius1 - center).magnitude));
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position3);
            position3   = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius2     = center - (position3 - center);
                radius1     = center + (Quaternion.AngleAxis(-90, up) * ((radius2 - center).normalized * (radius1 - center).magnitude));
                prevChanged = true;
            }



            GUI.changed |= prevChanged;

            isDisabled         = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


            float radiusMagnitude1 = delta1.magnitude;
            float radiusMagnitude2 = delta2.magnitude;

            if (radiusMagnitude1 > 0 && radiusMagnitude2 > 0)
            {
                var ellipsis = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);

                ellipsis.m00 = delta1.x;
                ellipsis.m10 = delta1.y;
                ellipsis.m20 = delta1.z;

                ellipsis.m01 = delta2.x;
                ellipsis.m11 = delta2.y;
                ellipsis.m21 = delta2.z;

                ellipsis.m02 = up.x;
                ellipsis.m12 = up.y;
                ellipsis.m22 = up.z;

                ellipsis *= Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one);

                var newMatrix = prevMatrix * ellipsis;

                SceneHandles.matrix = newMatrix;
                SceneHandles.DrawWireDisc(center, up, 1.0f);
            }


            SceneHandles.disabled = prevDisabled;
            SceneHandles.matrix   = prevMatrix;
            SceneHandles.color    = prevColor;
        }
Ejemplo n.º 11
0
        public static Vector3 Radius2DHandle(Vector3 center, Vector3 up, Vector3 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 prevChanged  = GUI.changed;
            var hasChanged   = false;


            var plane = new Plane(up, Vector3.zero);

            var delta1 = GeometryUtility.ProjectPointPlane(radius - center, plane);
            var delta2 = Quaternion.AngleAxis(90, up) * delta1;

            var position0 = center + delta1;
            var position1 = center - delta1;
            var position2 = center + delta2;
            var position3 = center - delta2;


            float   size;
            Vector3 forward;
            Vector3 right;

            GeometryUtility.CalculateTangents(up, out right, out forward);



            bool noRotation = Event.current.shift;

            var isDisabled = isStatic || prevDisabled;

            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);

            Vector3 moveDelta = Vector3.zero;

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position0);
            position0   = Slider2DHandle(position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                moveDelta = position0 - center; hasChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position1);
            position1   = Slider2DHandle(position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                moveDelta = -(position1 - center); hasChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position2);
            position2   = Slider2DHandle(position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                moveDelta = (Quaternion.AngleAxis(-90, up) * (position2 - center)); hasChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position3);
            position3   = Slider2DHandle(position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                moveDelta = -(Quaternion.AngleAxis(-90, up) * (position3 - center)); hasChanged = true;
            }

            if (hasChanged)
            {
                Vector3 prevRadius = radius;
                var     newRadius  = center + moveDelta;

                var newDelta = GeometryUtility.ProjectPointPlane((newRadius - center), plane);
                var length   = newDelta.magnitude;
                if (length < minRadius || length > maxRadius)
                {
                    var direction = (length > Vector3.kEpsilon) ? newDelta.normalized : ((delta1.magnitude > Vector3.kEpsilon) ? delta1.normalized : Vector3.up);
                    length = Mathf.Max(minRadius, Mathf.Min(length, maxRadius));
                    radius = center + (length * direction);
                }
                else
                {
                    radius = newRadius;
                }

                if (noRotation)
                {
                    var magnitude = newRadius.magnitude;
                    radius = prevRadius.normalized * magnitude;
                }
            }


            GUI.changed |= prevChanged | hasChanged;

            isDisabled         = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


            float radiusMagnitude = delta1.magnitude;

            if (radiusMagnitude > 0 && renderDisc)
            {
                SceneHandles.DrawWireDisc(center, up, radiusMagnitude);
            }


            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = prevColor;
            return(radius);
        }
Ejemplo n.º 12
0
        public static bool Radius2DHandle(Vector3 center, Vector3 up, ref Vector3 radius1, ref Vector3 radius2, float minRadius1 = 0, float minRadius2 = 0, float maxRadius1 = float.PositiveInfinity, float maxRadius2 = float.PositiveInfinity, bool renderDisc = true)
        {
            var positionId0 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId1 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId2 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId3 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);

            minRadius1 = Mathf.Abs(minRadius1);
            minRadius2 = Mathf.Abs(minRadius2);
            maxRadius1 = Mathf.Abs(maxRadius1); if (maxRadius1 < minRadius1)
            {
                maxRadius1 = minRadius1;
            }
            maxRadius2 = Mathf.Abs(maxRadius2); if (maxRadius2 < minRadius2)
            {
                maxRadius2 = minRadius2;
            }

            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevColor    = SceneHandles.color;
            var prevMatrix   = SceneHandles.matrix;
            var prevDisabled = SceneHandles.disabled;
            var prevChanged  = GUI.changed;

            float   size;
            Vector3 forward;
            Vector3 right;

            GeometryUtility.CalculateTangents(up, out right, out forward);

            var plane = new Plane(up, Vector3.zero);

            var delta1 = GeometryUtility.ProjectPointPlane(radius1 - center, plane);
            var delta2 = GeometryUtility.ProjectPointPlane(radius2 - center, plane);

            var delta1Magnitude = delta1.magnitude;
            var delta2Magnitude = delta2.magnitude;

            var delta1Normalized = (delta1Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta1 / delta1Magnitude);
            var delta2Normalized = (delta2Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta2 / delta2Magnitude);

            // useful to have when modifying the 'other' one
            var rotatedDelta1 = Quaternion.AngleAxis(-90, up) * delta1Normalized;
            var rotatedDelta2 = Quaternion.AngleAxis(90, up) * delta2Normalized;


            var position0 = center + delta1;
            var position1 = center - delta1;
            var position2 = center + delta2;
            var position3 = center - delta2;

            var isDisabled = isStatic || prevDisabled;

            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);

            bool noRotation = Event.current.shift;

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position0);
            position0   = Slider2DHandle(positionId0, position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position0 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta2);
                }
                else
                {
                    newRadius = center + moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta1Magnitude = newDelta.magnitude;

                if (!noRotation && delta1Magnitude > Vector3.kEpsilon)
                {
                    radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude);
                }

                // set this after setting radius2 since both may lead to same variable
                delta1      = newDelta;
                radius1     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position1);
            position1   = Slider2DHandle(positionId1, position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position1 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta2);
                }
                else
                {
                    newRadius = center - moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta1Magnitude = newDelta.magnitude;

                if (!noRotation && delta1Magnitude > Vector3.kEpsilon)
                {
                    radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude);
                }

                // set this after setting radius2 since both may lead to same variable
                delta1      = newDelta;
                radius1     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position2);
            position2   = Slider2DHandle(positionId2, position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position2 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta1);
                }
                else
                {
                    newRadius = center + moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta2Magnitude = newDelta.magnitude;

                if (!noRotation && delta2Magnitude > Vector3.kEpsilon)
                {
                    radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude);
                }

                // set this after setting radius1 since both may lead to same variable
                delta2      = newDelta;
                radius2     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position3);
            position3   = Slider2DHandle(positionId3, position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position3 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta1);
                }
                else
                {
                    newRadius = center - moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta2Magnitude = newDelta.magnitude;

                if (!noRotation && delta2Magnitude > Vector3.kEpsilon)
                {
                    radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude);
                }

                // set this after setting radius1 since both may lead to same variable
                delta2      = newDelta;
                radius2     = newRadius;
                prevChanged = true;
            }

            GUI.changed |= prevChanged;

            if (delta1Magnitude < minRadius1 || delta1Magnitude > maxRadius1)
            {
                if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2)
                {
                    delta1Magnitude = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1));
                    delta2Magnitude = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2));

                    delta1Normalized = right;
                    delta2Normalized = up;

                    delta1 = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane);
                    delta2 = GeometryUtility.ProjectPointPlane(delta2Normalized * delta2Magnitude, plane);

                    rotatedDelta2 = delta2Normalized;
                    rotatedDelta1 = delta1Normalized;

                    radius1     = center + delta1;
                    radius2     = center + delta2;
                    GUI.changed = true;
                }
                else
                {
                    delta1Magnitude  = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1));
                    delta1Normalized = rotatedDelta2;
                    delta1           = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane);
                    radius1          = center + delta1;
                    GUI.changed      = true;
                }
            }
            else
            if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2)
            {
                delta2Magnitude  = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2));
                delta2Normalized = rotatedDelta1;
                delta2           = delta2Normalized * delta2Magnitude;
                radius2          = center + delta2;
                GUI.changed      = true;
            }


            if (Event.current.type == EventType.Repaint)
            {
                isDisabled         = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
                SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


                if (delta1Magnitude > Vector3.kEpsilon && delta2Magnitude > Vector3.kEpsilon)
                {
                    var ellipsis = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);

                    ellipsis.m00 = delta1.x;
                    ellipsis.m10 = delta1.y;
                    ellipsis.m20 = delta1.z;

                    ellipsis.m01 = delta2.x;
                    ellipsis.m11 = delta2.y;
                    ellipsis.m21 = delta2.z;

                    ellipsis.m02 = up.x;
                    ellipsis.m12 = up.y;
                    ellipsis.m22 = up.z;

                    ellipsis *= Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one);

                    var newMatrix = prevMatrix * ellipsis;

                    SceneHandles.matrix = newMatrix;
                    if (renderDisc)
                    {
                        SceneHandles.DrawWireDisc(center, Vector3.forward, 1.0f);
                    }
                }
                else
                if (delta1Magnitude > Vector3.kEpsilon)
                {
                    SceneHandles.DrawLine(position0, position1);
                }
                else
                if (delta2Magnitude > Vector3.kEpsilon)
                {
                    SceneHandles.DrawLine(position2, position3);
                }
            }

            SceneHandles.disabled = prevDisabled;
            SceneHandles.matrix   = prevMatrix;
            SceneHandles.color    = prevColor;

            var focus = SceneHandleUtility.focusControl;

            return((focus == positionId0) ||
                   (focus == positionId1) ||
                   (focus == positionId2) ||
                   (focus == positionId3));
        }
Ejemplo n.º 13
0
        public static Rect RectHandle(Rect rect, CapFunction capFunction)
        {
            var handlesMatrix = SceneHandles.matrix;

            var direction = Vector3.forward;
            var slideDirX = Vector3.right;
            var slideDirY = Vector3.up;

            var point1Id = GUIUtility.GetControlID(s_RectHash0, FocusType.Keyboard);
            var point2Id = GUIUtility.GetControlID(s_RectHash1, FocusType.Keyboard);
            var point3Id = GUIUtility.GetControlID(s_RectHash2, FocusType.Keyboard);
            var point4Id = GUIUtility.GetControlID(s_RectHash3, FocusType.Keyboard);

            var edge1Id = GUIUtility.GetControlID(s_RectHash4, FocusType.Keyboard);
            var edge2Id = GUIUtility.GetControlID(s_RectHash5, FocusType.Keyboard);
            var edge3Id = GUIUtility.GetControlID(s_RectHash6, FocusType.Keyboard);
            var edge4Id = GUIUtility.GetControlID(s_RectHash7, FocusType.Keyboard);

            int currentFocusControl = SceneHandleUtility.focusControl;

            bool highlightEdge1 = (currentFocusControl == edge1Id) || (currentFocusControl == point1Id) || (currentFocusControl == point2Id);
            bool highlightEdge2 = (currentFocusControl == edge2Id) || (currentFocusControl == point3Id) || (currentFocusControl == point4Id);
            bool highlightEdge3 = (currentFocusControl == edge3Id) || (currentFocusControl == point2Id) || (currentFocusControl == point3Id);
            bool highlightEdge4 = (currentFocusControl == edge4Id) || (currentFocusControl == point4Id) || (currentFocusControl == point1Id);

            var selectedAxes = ((highlightEdge3 || highlightEdge4) ? Axes.X : Axes.None) |
                               ((highlightEdge1 || highlightEdge2) ? Axes.Y : Axes.None);

            var xMin = rect.xMin;
            var xMax = rect.xMax;
            var yMin = rect.yMin;
            var yMax = rect.yMax;

            var point1 = new Vector3(xMin, yMin, 0);
            var point2 = new Vector3(xMax, yMin, 0);
            var point3 = new Vector3(xMax, yMax, 0);
            var point4 = new Vector3(xMin, yMax, 0);

            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevDisabled = SceneHandles.disabled;
            var prevColor    = SceneHandles.color;

            var xAxisDisabled = isStatic || prevDisabled || Snapping.AxisLocking[0];
            var yAxisDisabled = isStatic || prevDisabled || Snapping.AxisLocking[1];
            var xyAxiDisabled = xAxisDisabled && yAxisDisabled;

            Vector3 position, offset;
            var     prevGUIchanged = GUI.changed;


            SceneHandles.disabled = yAxisDisabled;
            {
                GUI.changed        = false;
                position           = (point1 + point2) * 0.5f;
                SceneHandles.color = SceneHandles.StateColor(SceneHandles.yAxisColor, xAxisDisabled, highlightEdge1);
                offset             = Edge1DHandleOffset(edge1Id, Axis.Y, point1, point2, position, slideDirY, Snapping.MoveSnappingSteps.y, UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f, null);
                if (GUI.changed)
                {
                    yMin += offset.y; prevGUIchanged = true;
                }

                GUI.changed        = false;
                position           = (point3 + point4) * 0.5f;
                SceneHandles.color = SceneHandles.StateColor(SceneHandles.yAxisColor, xAxisDisabled, highlightEdge2);
                offset             = Edge1DHandleOffset(edge2Id, Axis.Y, point3, point4, position, slideDirY, Snapping.MoveSnappingSteps.y, UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f, null);
                if (GUI.changed)
                {
                    yMax += offset.y; prevGUIchanged = true;
                }
            }


            SceneHandles.disabled = xAxisDisabled;
            {
                GUI.changed        = false;
                position           = (point2 + point3) * 0.5f;
                SceneHandles.color = SceneHandles.StateColor(SceneHandles.yAxisColor, xAxisDisabled, highlightEdge3);
                offset             = Edge1DHandleOffset(edge3Id, Axis.X, point2, point3, position, slideDirX, Snapping.MoveSnappingSteps.x, UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f, null);
                if (GUI.changed)
                {
                    xMax += offset.x; prevGUIchanged = true;
                }

                GUI.changed        = false;
                position           = (point4 + point1) * 0.5f;
                SceneHandles.color = SceneHandles.StateColor(SceneHandles.yAxisColor, xAxisDisabled, highlightEdge4);
                offset             = Edge1DHandleOffset(edge4Id, Axis.X, point4, point1, position, slideDirX, Snapping.MoveSnappingSteps.x, UnityEditor.HandleUtility.GetHandleSize(position) * 0.05f, null);
                if (GUI.changed)
                {
                    xMin += offset.x; prevGUIchanged = true;
                }
            }


            SceneHandles.disabled = xyAxiDisabled;
            SceneHandles.color    = SceneHandles.StateColor(SceneHandles.yAxisColor, xyAxiDisabled, false);
            {
                GUI.changed = false;
                point1      = Slider2DHandle(point1Id, point1, Vector3.zero, direction, slideDirX, slideDirY, UnityEditor.HandleUtility.GetHandleSize(point1) * 0.05f, capFunction, Axes.XZ);
                if (GUI.changed)
                {
                    xMin = point1.x; yMin = point1.y; prevGUIchanged = true;
                }

                GUI.changed = false;
                point2      = Slider2DHandle(point2Id, point2, Vector3.zero, direction, slideDirX, slideDirY, UnityEditor.HandleUtility.GetHandleSize(point2) * 0.05f, capFunction, Axes.XZ);
                if (GUI.changed)
                {
                    xMax = point2.x; yMin = point2.y; prevGUIchanged = true;
                }

                GUI.changed = false;
                point3      = Slider2DHandle(point3Id, point3, Vector3.zero, direction, slideDirX, slideDirY, UnityEditor.HandleUtility.GetHandleSize(point3) * 0.05f, capFunction, Axes.XZ);
                if (GUI.changed)
                {
                    xMax = point3.x; yMax = point3.y; prevGUIchanged = true;
                }

                GUI.changed = false;
                point4      = Slider2DHandle(point4Id, point4, Vector3.zero, direction, slideDirX, slideDirY, UnityEditor.HandleUtility.GetHandleSize(point4) * 0.05f, capFunction, Axes.XZ);
                if (GUI.changed)
                {
                    xMin = point4.x; yMax = point4.y; prevGUIchanged = true;
                }
            }
            GUI.changed = prevGUIchanged;

            rect.x = xMin; rect.width = xMax - xMin;
            rect.y = yMin; rect.height = yMax - yMin;

            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = prevColor;

            return(rect);
        }
Ejemplo n.º 14
0
        public static void DrawAngle(UnityEngine.Vector3 center, UnityEngine.Vector3 direction, UnityEngine.Vector3 axis, float angle)
        {
            var rotation   = UnityEngine.Quaternion.AngleAxis(angle, axis);
            var centerSize = UnityEditor.HandleUtility.GetHandleSize(center);
            var maxSize    = direction.magnitude;
            var xdir       = direction / maxSize;
            //var ydir		= UnityEngine.Vector3.Cross(xdir, axis);
            var handleSize = Mathf.Min(centerSize, maxSize);
            var drawAngle  = UnityEngine.Mathf.Clamp(angle, -360, 360);
            var realLength = Mathf.Max(1, Mathf.CeilToInt((anglePoints.Length / 360.0f) * Mathf.Abs(drawAngle)));

            var pointSize = centerSize * 0.04f;

            SceneHandles.color = SceneHandles.StateColor(SceneHandles.measureColor);
            SceneHandles.DrawAAPolyLine(center + (xdir * pointSize), center + direction);
            SceneHandles.DrawAAPolyLine(center + (rotation * (xdir * pointSize)), center + (rotation * direction));

            SceneHandles.DrawWireDisc(center, Vector3.forward, pointSize);

            direction = xdir * handleSize;
            if (UnityEngine.Mathf.Abs(angle) > 0.0f)
            {
                var angleStep = drawAngle / realLength;
                var curAngle  = 0.0f;
                for (int i = 0; i < realLength; i++)
                {
                    anglePoints[i] = center + (UnityEngine.Quaternion.AngleAxis(curAngle, axis) * direction);
                    curAngle      += angleStep;
                }
                SceneHandles.DrawDottedLines(anglePoints.Take(realLength).ToArray(), 4.0f);

                rotation = UnityEngine.Quaternion.AngleAxis(angle, axis);
                var right     = rotation * Vector3.right;
                var endPoint  = center + (rotation * direction);
                var arrowSize = handleSize * 0.2f;                  // UnityEditor.HandleUtility.GetHandleSize(endPoint) * 0.2f;

                if (angle < 0.0f)
                {
                    DrawFlatArrow(endPoint, -right, arrowSize);
                }
                else
                {
                    DrawFlatArrow(endPoint, right, arrowSize);
                }
            }

            Vector3 facing;
            Vector3 position;

            if (handleSize == maxSize)
            {
                facing   = rotation * xdir;
                position = center + (facing * handleSize);
            }
            else
            {
                var halfRotation = UnityEngine.Quaternion.AngleAxis(drawAngle / 2.0f, axis);
                facing   = halfRotation * xdir;
                position = center;
            }

            DrawLabel(position, facing, 5, angle + "°");
        }
Ejemplo n.º 15
0
        public static void DrawLengths(Bounds bounds, Axes activeAxes = Axes.XYZ, Axes visibleAxes = Axes.XYZ, Axes selectedAxes = Axes.None)
        {
            // TODO: what if camera is inside of bounds?
            // TODO: what if length is outside of camera, but other option is inside of camera view?
            // TODO: don't make the side lines move around when resizing, be smarter about handlesize
            //			-> maybe limit the projected line to the screen?

            var invMatrix = SceneHandles.inverseMatrix;
            var prevColor = SceneHandles.color;
            var color     = prevColor;
            var color2    = color;

            color2.a *= 0.5f;

            var camera = UnityEngine.Camera.current;
            var camPos = invMatrix.MultiplyPoint(camera.transform.position);

            var lengthX = bounds.size.x;
            var lengthY = bounds.size.y;
            var lengthZ = bounds.size.z;

            var absLengthX = Mathf.Abs(lengthX);
            var absLengthY = Mathf.Abs(lengthY);
            var absLengthZ = Mathf.Abs(lengthZ);

            var delta = (bounds.center - camPos) * 2;
            var dotX  = delta.x < 0 ? -1 : 1;
            var dotY  = delta.y < 0 ? -1 : 1;
            var dotZ  = delta.z < 0 ? -1 : 1;

            var insideX = (delta.x >= -absLengthX && delta.x <= absLengthX);
            var insideY = (delta.y >= -absLengthY && delta.y <= absLengthY);
            var insideZ = (delta.z >= -absLengthZ && delta.z <= absLengthZ);

            bool showX = !(insideY && insideZ);
            bool showY = !(insideX && insideZ);
            bool showZ = !(insideX && insideY);


            Vector3 fromX, toX;
            Vector3 fromY, toY;
            Vector3 fromZ, toZ;

            var min = bounds.min;
            var max = bounds.max;

            // min/max of bounds can potentially be inverted
            min.x = Mathf.Min(min.x, max.x);
            min.y = Mathf.Min(min.y, max.y);
            min.z = Mathf.Min(min.z, max.z);

            fromX = min; toX = fromX + new Vector3(absLengthX, 0, 0);
            fromY = min; toY = fromY + new Vector3(0, absLengthY, 0);
            fromZ = min; toZ = fromZ + new Vector3(0, 0, absLengthZ);

            var signZ = Vector3.one;

            if (showZ)
            {
                bool swapX = (dotX > 0) ^ insideY;
                bool swapY = (dotY < 0) ^ insideY;

                signZ.x = swapX ? 1 : -1; signZ.y = swapY ? 1 : -1;
                var ofsX = swapX ? absLengthX : 0; fromZ.x += ofsX; toZ.x += ofsX;
                var ofsY = swapY ? absLengthY : 0; fromZ.y += ofsY; toZ.y += ofsY;
            }

            var signY = Vector3.one;

            if (showY)
            {
                bool swapX = (dotX > 0) ^ insideZ;
                bool swapZ = (dotZ < 0);

                signY.x = swapX ? 1 : -1; signY.z = swapZ ? 1 : -1;
                var ofsX = swapX ? absLengthX : 0; fromY.x += ofsX; toY.x += ofsX;
                var ofsZ = swapZ ? absLengthZ : 0; fromY.z += ofsZ; toY.z += ofsZ;
            }

            var signX = Vector3.one;

            if (showX)
            {
                bool swapY = (dotY > 0) ^ insideZ;
                bool swapZ = (dotZ < 0);

                signX.y = swapY ? 1 : -1; signX.z = swapZ ? 1 : -1;
                var ofsY = swapY ? absLengthY : 0; fromX.y += ofsY; toX.y += ofsY;
                var ofsZ = swapZ ? absLengthZ : 0; fromX.z += ofsZ; toX.z += ofsZ;
            }

            var lineHandleX = SceneHandleUtility.ProjectPointLine(camPos, fromX, toX);
            var lineHandleY = SceneHandleUtility.ProjectPointLine(camPos, fromY, toY);
            var lineHandleZ = SceneHandleUtility.ProjectPointLine(camPos, fromZ, toZ);
            var lineOfsX    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleX) * 0.25f);
            var lineOfsY    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleY) * 0.25f);
            var lineOfsZ    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleZ) * 0.25f);

            var angleX     = lineHandleX - camPos;
            var angleY     = lineHandleY - camPos;
            var angleZ     = lineHandleZ - camPos;
            var directionX = Mathf.Abs(angleX.y) <= Mathf.Abs(angleX.z);
            var directionY = Mathf.Abs(angleY.x) <= Mathf.Abs(angleY.z);
            var directionZ = Mathf.Abs(angleZ.y) <= Mathf.Abs(angleZ.x);

            var disabled = SceneHandles.disabled;

            const int labelPadding = 2;

            if (showX && ((visibleAxes & Axes.X) == Axes.X))
            {
                var axisDisabled = ((activeAxes & Axes.X) != Axes.X) || disabled;
                var selected     = ((selectedAxes & Axes.X) == Axes.X) && !axisDisabled;

                var offsetY = new Vector3(0, (lineOfsY * signX.y), 0);
                var offsetZ = new Vector3(0, 0, (lineOfsZ * signX.z));

                var offset  = directionX ? offsetY : offsetZ;
                var fromOfs = fromX + offset;
                var toOfs   = toX + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthX / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthX / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromX, fromOfs);
                SceneHandles.DrawLine(toX, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.right, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.right, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthX, "X");
            }

            if (showY && ((visibleAxes & Axes.Y) == Axes.Y))
            {
                var axisDisabled = ((activeAxes & Axes.Y) != Axes.Y) || disabled;
                var selected     = ((selectedAxes & Axes.Y) == Axes.Y) && !axisDisabled;

                var offsetX = new Vector3((lineOfsX * signY.x), 0, 0);
                var offsetZ = new Vector3(0, 0, (lineOfsZ * signY.z));

                var offset  = directionY ? offsetX : offsetZ;
                var fromOfs = fromY + offset;
                var toOfs   = toY + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthY / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthY / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromY, fromOfs);
                SceneHandles.DrawLine(toY, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.up, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.up, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthY, "Y");
            }

            if (showZ && ((visibleAxes & Axes.Z) == Axes.Z))
            {
                var axisDisabled = ((activeAxes & Axes.Z) != Axes.Z) || disabled;
                var selected     = ((selectedAxes & Axes.Z) == Axes.Z) && !axisDisabled;

                var offsetX = new Vector3((lineOfsX * signZ.x), 0, 0);
                var offsetY = new Vector3(0, (lineOfsY * signZ.y), 0);

                var offset  = directionZ ? offsetY : offsetX;
                var fromOfs = fromZ + offset;
                var toOfs   = toZ + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthZ / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthZ / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromZ, fromOfs);
                SceneHandles.DrawLine(toZ, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.forward, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.forward, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthZ, "Z");
            }
            SceneHandles.color = prevColor;
        }
Ejemplo n.º 16
0
        public static float Radius3DHandle(Quaternion rotation, Vector3 position, float radius, float minRadius = 0, float maxRadius = float.PositiveInfinity)
        {
            minRadius = Mathf.Abs(minRadius);
            maxRadius = Mathf.Abs(maxRadius); if (maxRadius < minRadius)
            {
                maxRadius = minRadius;
            }

            const float kEpsilon = 0.000001F;

            var camera               = Camera.current;
            var cameraLocalPos       = SceneHandles.inverseMatrix.MultiplyPoint(camera.transform.position);
            var cameraLocalForward   = SceneHandles.inverseMatrix.MultiplyVector(camera.transform.forward);
            var isCameraInsideSphere = (cameraLocalPos - position).magnitude < radius;
            var isCameraOrthographic = camera.orthographic;

            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 guiHasChanged = GUI.changed;

            GUI.changed = false;

            Vector3 positiveXDir = right;
            Vector3 negativeXDir = -right;
            Vector3 positiveYDir = up;
            Vector3 negativeYDir = -up;
            Vector3 positiveZDir = forward;
            Vector3 negativeZDir = -forward;

            Vector3 positiveXHandle = position + positiveXDir * radius;
            Vector3 negativeXHandle = position + negativeXDir * radius;
            Vector3 positiveYHandle = position + positiveYDir * radius;
            Vector3 negativeYHandle = position + negativeYDir * radius;
            Vector3 positiveZHandle = position + positiveZDir * radius;
            Vector3 negativeZHandle = position + negativeZDir * radius;

            bool positiveXBackfaced = false;
            bool negativeXBackfaced = false;
            bool positiveYBackfaced = false;
            bool negativeYBackfaced = false;
            bool positiveZBackfaced = false;
            bool negativeZBackfaced = false;

            if (!isCameraInsideSphere)
            {
                float cosV;

                cosV = isCameraOrthographic ? Vector3.Dot(positiveXDir, -cameraLocalForward) :
                       Vector3.Dot(positiveXDir, (cameraLocalPos - positiveXHandle));
                positiveXBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeXDir, -cameraLocalForward) :
                       Vector3.Dot(negativeXDir, (cameraLocalPos - negativeXHandle));
                negativeXBackfaced = (cosV < -0.0001f);


                cosV = isCameraOrthographic ? Vector3.Dot(positiveYDir, -cameraLocalForward) :
                       Vector3.Dot(positiveYDir, (cameraLocalPos - positiveYHandle));
                positiveYBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeYDir, -cameraLocalForward) :
                       Vector3.Dot(negativeYDir, (cameraLocalPos - negativeYHandle));
                negativeYBackfaced = (cosV < -0.0001f);


                cosV = isCameraOrthographic ? Vector3.Dot(positiveZDir, -cameraLocalForward) :
                       Vector3.Dot(positiveZDir, (cameraLocalPos - positiveZHandle));
                positiveZBackfaced = (cosV < -0.0001f);

                cosV = isCameraOrthographic ? Vector3.Dot(negativeZDir, -cameraLocalForward) :
                       Vector3.Dot(negativeZDir, (cameraLocalPos - negativeZHandle));
                negativeZBackfaced = (cosV < -0.0001f);
            }

            float positiveXSize = UnityEditor.HandleUtility.GetHandleSize(positiveXHandle) * 0.05f * (positiveXBackfaced ? backfaceSizeMultiplier : 1);
            float negativeXSize = UnityEditor.HandleUtility.GetHandleSize(negativeXHandle) * 0.05f * (negativeXBackfaced ? backfaceSizeMultiplier : 1);
            float positiveYSize = UnityEditor.HandleUtility.GetHandleSize(positiveYHandle) * 0.05f * (positiveYBackfaced ? backfaceSizeMultiplier : 1);
            float negativeYSize = UnityEditor.HandleUtility.GetHandleSize(negativeYHandle) * 0.05f * (negativeYBackfaced ? backfaceSizeMultiplier : 1);
            float positiveZSize = UnityEditor.HandleUtility.GetHandleSize(positiveZHandle) * 0.05f * (positiveZBackfaced ? backfaceSizeMultiplier : 1);
            float negativeZSize = UnityEditor.HandleUtility.GetHandleSize(negativeZHandle) * 0.05f * (negativeZBackfaced ? backfaceSizeMultiplier : 1);



            var isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[0];
            var color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            var backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveXBackfaced ? backfacedColor : color;
            positiveXHandle    = Slider2DHandle(positiveXHandle, Vector3.zero, forward, up, right, positiveXSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveXHandle - position, positiveXDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeXBackfaced ? backfacedColor : color;
            negativeXHandle    = Slider2DHandle(negativeXHandle, Vector3.zero, forward, up, right, negativeXSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeXHandle - position, negativeXDir); guiHasChanged = true;
            }



            isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[1];
            color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveYBackfaced ? backfacedColor : color;
            positiveYHandle    = Slider2DHandle(positiveYHandle, Vector3.zero, forward, up, right, positiveYSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveYHandle - position, positiveYDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeYBackfaced ? backfacedColor : color;
            negativeYHandle    = Slider2DHandle(negativeYHandle, Vector3.zero, forward, up, right, negativeYSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeYHandle - position, negativeYDir); guiHasChanged = true;
            }



            isDisabled     = isStatic || prevDisabled || Snapping.AxisLocking[2];
            color          = SceneHandles.StateColor(prevColor, isDisabled, false);
            backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);

            GUI.changed        = false;
            SceneHandles.color = positiveZBackfaced ? backfacedColor : color;
            positiveZHandle    = Slider2DHandle(positiveZHandle, Vector3.zero, up, forward, right, positiveZSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(positiveZHandle - position, positiveZDir); guiHasChanged = true;
            }

            GUI.changed        = false;
            SceneHandles.color = negativeZBackfaced ? backfacedColor : color;
            negativeZHandle    = Slider2DHandle(negativeZHandle, Vector3.zero, up, forward, right, negativeZSize, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                radius = Vector3.Dot(negativeZHandle - position, negativeZDir); guiHasChanged = true;
            }


            radius = Mathf.Max(minRadius, Mathf.Min(Mathf.Abs(radius), maxRadius));


            GUI.changed |= guiHasChanged;

            if (radius > 0)
            {
                isDisabled     = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
                color          = SceneHandles.StateColor(prevColor, isDisabled, false);
                backfacedColor = SceneHandles.MultiplyTransparency(color, SceneHandles.backfaceAlphaMultiplier);
                var discOrientations = new Vector3[]
                {
                    rotation *Vector3.right,
                    rotation *Vector3.up,
                    rotation *Vector3.forward
                };

                var currentCamera   = Camera.current;
                var cameraTransform = currentCamera.transform;
                if (currentCamera.orthographic)
                {
                    var planeNormal = cameraTransform.forward;
                    SceneHandles.DrawWireDisc(position, planeNormal, radius);
                    planeNormal.Normalize();
                    for (int i = 0; i < 3; i++)
                    {
                        var discOrientation = discOrientations[i];
                        var discTangent     = Vector3.Cross(discOrientation, planeNormal);

                        // we may have view dir locked to one axis
                        if (discTangent.sqrMagnitude > kEpsilon)
                        {
                            SceneHandles.color = color;
                            SceneHandles.DrawWireArc(position, discOrientation, discTangent, 180, radius);
                            SceneHandles.color = backfacedColor;
                            SceneHandles.DrawWireArc(position, discOrientation, discTangent, -180, radius);
                        }
                    }
                }
                else
                {
                    // Since the geometry is transformed by Handles.matrix during rendering, we transform the camera position
                    // by the inverse matrix so that the two-shaded wireframe will have the proper orientation.
                    var invMatrix = SceneHandles.inverseMatrix;

                    var cameraCenter          = cameraTransform.position;
                    var cameraToCenter        = position - invMatrix.MultiplyPoint(cameraCenter);           // vector from camera to center
                    var sqrDistCameraToCenter = cameraToCenter.sqrMagnitude;
                    var sqrRadius             = radius * radius;                                            // squared radius
                    var sqrOffset             = sqrRadius * sqrRadius / sqrDistCameraToCenter;              // squared distance from actual center to drawn disc center
                    var insideAmount          = sqrOffset / sqrRadius;
                    if (insideAmount < 1)
                    {
                        if (Mathf.Abs(sqrDistCameraToCenter) < kEpsilon)
                        {
                            return(radius);
                        }

                        var horizonRadius = Mathf.Sqrt(sqrRadius - sqrOffset);
                        var horizonCenter = position - sqrRadius * cameraToCenter / sqrDistCameraToCenter;
                        SceneHandles.color = color;
                        SceneHandles.DrawWireDisc(horizonCenter, cameraToCenter, horizonRadius);

                        var planeNormal = cameraToCenter.normalized;
                        for (int i = 0; i < 3; i++)
                        {
                            var discOrientation = discOrientations[i];

                            var angleBetweenDiscAndNormal = Mathf.Acos(Vector3.Dot(discOrientation, planeNormal));
                            angleBetweenDiscAndNormal = (Mathf.PI * 0.5f) - Mathf.Min(angleBetweenDiscAndNormal, Mathf.PI - angleBetweenDiscAndNormal);

                            float f = Mathf.Tan(angleBetweenDiscAndNormal);
                            float g = Mathf.Sqrt(sqrOffset + f * f * sqrOffset) / radius;
                            if (g < 1)
                            {
                                var angleToHorizon         = Mathf.Asin(g) * Mathf.Rad2Deg;
                                var discTangent            = Vector3.Cross(discOrientation, planeNormal);
                                var vectorToPointOnHorizon = Quaternion.AngleAxis(angleToHorizon, discOrientation) * discTangent;
                                var horizonArcLength       = (90 - angleToHorizon) * 2.0f;

                                SceneHandles.color = color;
                                SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength, radius);
                                SceneHandles.color = backfacedColor;
                                SceneHandles.DrawWireArc(position, discOrientation, vectorToPointOnHorizon, horizonArcLength - 360, radius);
                            }
                            else
                            {
                                SceneHandles.color = backfacedColor;
                                SceneHandles.DrawWireDisc(position, discOrientation, radius);
                            }
                        }
                    }
                    else
                    {
                        SceneHandles.color = backfacedColor;
                        for (int i = 0; i < 3; i++)
                        {
                            var discOrientation = discOrientations[i];
                            SceneHandles.DrawWireDisc(position, discOrientation, radius);
                        }
                    }
                }
            }

            SceneHandles.disabled = prevDisabled;
            SceneHandles.color    = prevColor;

            return(radius);
        }