Example #1
0
    private void DrawSceneAnchorPointHandle(BezierPoint bezierPoint, BezierPoint nearBezierPoint, Vector2 mousePosition, float handleSize)
    {
        if (selectedPoints.Contains(bezierPoint))
        {
            Vector3 p = bezierPoint.GetPosition() - new Vector3(1, 1, 0) * handleSize;
            Handles.DrawSolidRectangleWithOutline(new Rect(p, Vector3.one * handleSize * 2.0f), Color.yellow, Color.white);
        }

        if (bezierPoint == nearBezierPoint)
        {
            Handles.color = Color.yellow;
        }

        Vector3 position = Handles.FreeMoveHandle(bezierPoint.GetPosition(), Quaternion.identity, handleSize, Vector3.zero, Handles.RectangleCap);

        Handles.color = Color.white;
        Handles.Label(bezierPoint.GetPosition() + Vector3.right * 0.5f, bezierPoint.name);

        if (bezierPoint.GetLocalPosition() != position)
        {
            if (Event.current.control && grabbedBezierPoint == bezierPoint)
            {
                position.x = Mathf.Round(mousePosition.x / bezierCurve.snapSize) * bezierCurve.snapSize;
                position.y = Mathf.Round(mousePosition.y / bezierCurve.snapSize) * bezierCurve.snapSize;
            }

            Undo.RecordObject(target, "Move Point");
            bezierPoint.SetPosition(position);
        }
    }
Example #2
0
    private void DrawInspectorBezierPointControls()
    {
        List <BezierPoint> points = bezierCurve.GetAnchorPoints();

        string[] bezierPointTypes = System.Enum.GetNames(typeof(BezierPointType));

        if (points == null)
        {
            return;
        }

        for (int i = 0; i < points.Count; i++)
        {
            BezierPoint bezierPoint = points [i];

            GUILayout.BeginHorizontal();
            GUILayout.Label(bezierPoint.name);
            EditorGUI.BeginChangeCheck();
            BezierPointType pointType = (BezierPointType)EditorGUILayout.Popup((int)bezierPoint.pointType, bezierPointTypes);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(bezierCurve, "Change Point Type");

                bezierPoint.pointType = pointType;
                SceneView.RepaintAll();
            }
            if (GUILayout.Button("X", GUILayout.Width(15), GUILayout.Height(15)))
            {
                RemovePoint(bezierPoint);
            }
            GUILayout.EndHorizontal();

            Vector3 position = EditorGUILayout.Vector3Field("    Position: ", bezierPoint.position);

            if (bezierPoint.pointType != BezierPointType.None)
            {
                Vector3 handle1 = EditorGUILayout.Vector3Field("    Handle 1: ", bezierPoint.handle1);
                Vector3 handle2 = EditorGUILayout.Vector3Field("    Handle 2: ", bezierPoint.handle2);

                if (bezierPoint.GetHandle1LocalPosition() != handle1)
                {
                    Undo.RecordObject(target, "Move Handle Point 1");
                    bezierPoint.handle1 = handle1;
                }
                if (bezierPoint.GetHandle2LocalPosition() != handle2)
                {
                    Undo.RecordObject(target, "Move Handle Point 2");
                    bezierPoint.handle2 = handle2;
                }
            }

            if (bezierPoint.GetLocalPosition() != position)
            {
                Undo.RecordObject(target, "Move Point");
                bezierPoint.SetPosition(position);
            }
        }
    }
Example #3
0
    private void AddPoint(Vector3 position, Vector3 handle1, Vector3 handle2, int curveIndex = 0)
    {
        Undo.RecordObject(bezierCurve, "Add Point");

        BezierPoint bezierPoint = new BezierPoint(position, handle1, handle2);

        bezierCurve.AddAnchorPoint(bezierPoint, curveIndex);
        bezierPoint.SetPosition(position);          // wierd code :(

        SceneView.RepaintAll();
    }
        BezierPoint DoBezierPointGUI(BezierPoint point)
        {
            Vector3 pos = point.position, tin = point.tangentIn, tout = point.tangentOut;

            bool  wasInWideMode = EditorGUIUtility.wideMode;
            float labelWidth    = EditorGUIUtility.labelWidth;

            EditorGUIUtility.wideMode   = true;
            EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth / 3f;

            EditorGUI.BeginChangeCheck();
            pos = EditorGUILayout.Vector3Field("Position", pos);
            if (EditorGUI.EndChangeCheck())
            {
                point.SetPosition(pos);
            }

            EditorGUI.BeginChangeCheck();
            tin = EditorGUILayout.Vector3Field("Tan. In", tin);
            if (EditorGUI.EndChangeCheck())
            {
                point.SetTangentIn(tin, m_TangentMode);
            }
            Rect r = GUILayoutUtility.GetLastRect();

            r.x      += EditorGUIUtility.labelWidth - 12;
            GUI.color = Color.blue;
            GUI.Label(r, "\u2022");
            GUI.color = Color.white;

            EditorGUI.BeginChangeCheck();
            tout = EditorGUILayout.Vector3Field("Tan. Out", tout);
            if (EditorGUI.EndChangeCheck())
            {
                point.SetTangentOut(tout, m_TangentMode);
            }
            r         = GUILayoutUtility.GetLastRect();
            r.x      += EditorGUIUtility.labelWidth - 12;
            GUI.color = Color.red;
            GUI.Label(r, "\u2022");
            GUI.color = Color.white;

            Vector3 euler = point.rotation.eulerAngles;

            euler          = EditorGUILayout.Vector3Field("Rotation", euler);
            point.rotation = Quaternion.Euler(euler);

            EditorGUIUtility.labelWidth = labelWidth;
            EditorGUIUtility.wideMode   = wasInWideMode;

            return(point);
        }
        void OnSceneGUI()
        {
            Event e = Event.current;

            bool eventHasBeenUsed = false;

            if (m_IsMoving)
            {
                if (e.type == EventType.Ignore ||
                    e.type == EventType.MouseUp)
                {
                    eventHasBeenUsed = true;
                    OnFinishVertexModification();
                }
            }

            bool sceneViewInUse = EditorHandleUtility.SceneViewInUse(e);

            if (e.type == EventType.KeyDown)
            {
                if (e.keyCode == KeyCode.Backspace && m_currentHandle > -1 && m_currentHandle < m_Points.Count)
                {
                    UndoUtility.RecordObject(m_Target, "Delete Bezier Point");
                    m_Points.RemoveAt(m_currentHandle);
                    UpdateMesh(true);
                }
                else if (e.keyCode == KeyCode.Escape)
                {
                    SetIsEditing(false);
                }
            }

            int count = m_Points.Count;

            Matrix4x4 handleMatrix = Handles.matrix;

            Handles.matrix = m_Target.transform.localToWorldMatrix;

            EditorGUI.BeginChangeCheck();

            for (int index = 0; index < count; index++)
            {
                if (index < count - 1 || m_CloseLoop)
                {
                    Handles.DrawBezier(m_Points[index].position,
                                       m_Points[(index + 1) % count].position,
                                       m_Points[index].tangentOut,
                                       m_Points[(index + 1) % count].tangentIn,
                                       Color.green,
                                       EditorGUIUtility.whiteTexture,
                                       1f);
                }

                if (!m_IsEditing)
                {
                    continue;
                }

                // If the index is selected show the full transform gizmo, otherwise use free move handles
                if (m_currentHandle == index)
                {
                    BezierPoint point = m_Points[index];

                    if (!m_currentHandle.isTangent)
                    {
                        Vector3 prev = point.position;

                        prev = Handles.PositionHandle(prev, Quaternion.identity);

                        if (!Math.Approx3(prev, point.position))
                        {
                            if (!m_IsMoving)
                            {
                                OnBeginVertexModification();
                            }

                            prev = EditorSnapping.MoveSnap(prev);

                            Vector3 dir = prev - point.position;
                            point.position    = prev;
                            point.tangentIn  += dir;
                            point.tangentOut += dir;
                        }

                        // rotation
                        int     prev_index = index > 0 ? index - 1 : (m_CloseLoop ? count - 1 : -1);
                        int     next_index = index < count - 1 ? index + 1 : (m_CloseLoop ? 0 : -1);
                        Vector3 rd         = BezierPoint.GetLookDirection(m_Points, index, prev_index, next_index);

                        Quaternion look = Quaternion.LookRotation(rd);
                        float      size = HandleUtility.GetHandleSize(point.position);
                        Matrix4x4  pm   = Handles.matrix;
                        Handles.matrix = pm * Matrix4x4.TRS(point.position, look, Vector3.one);
                        point.rotation = Handles.Disc(point.rotation, Vector3.zero, Vector3.forward, size, false, 0f);
                        Handles.matrix = pm;
                    }
                    else
                    {
                        Handles.color = bezierTangentHandleColor;

                        if (m_currentHandle.tangent == BezierTangentDirection.In && (m_CloseLoop || index > 0))
                        {
                            EditorGUI.BeginChangeCheck();
                            point.tangentIn = Handles.PositionHandle(point.tangentIn, Quaternion.identity);
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (!m_IsMoving)
                                {
                                    OnBeginVertexModification();
                                }

                                point.tangentIn = EditorSnapping.MoveSnap(point.tangentIn);
                                point.EnforceTangentMode(BezierTangentDirection.In, m_TangentMode);
                            }
                            Handles.color = Color.blue;
                            Handles.DrawLine(m_Points[index].position, m_Points[index].tangentIn);
                        }

                        if (m_currentHandle.tangent == BezierTangentDirection.Out && (m_CloseLoop || index < count - 1))
                        {
                            EditorGUI.BeginChangeCheck();
                            point.tangentOut = Handles.PositionHandle(point.tangentOut, Quaternion.identity);
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (!m_IsMoving)
                                {
                                    OnBeginVertexModification();
                                }

                                point.tangentOut = EditorSnapping.MoveSnap(point.tangentOut);
                                point.EnforceTangentMode(BezierTangentDirection.Out, m_TangentMode);
                            }
                            Handles.color = Color.red;
                            Handles.DrawLine(m_Points[index].position, m_Points[index].tangentOut);
                        }
                    }

                    m_Points[index] = point;
                }
            }

            if (!m_IsEditing)
            {
                return;
            }

            EventType eventType = e.type;

            if (!eventHasBeenUsed)
            {
                eventHasBeenUsed = eventType == EventType.Used;
            }

            for (int index = 0; index < count; index++)
            {
                Vector3     prev;
                BezierPoint point = m_Points[index];

                // Position Handle
                float size = HandleUtility.GetHandleSize(point.position) * k_HandleSize;
                Handles.color = bezierPositionHandleColor;

                if (m_currentHandle == index && !m_currentHandle.isTangent)
                {
                    Handles.DotHandleCap(0, point.position, Quaternion.identity, size, e.type);
                }
                else
                {
                    prev = point.position;
                    prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap);
                    if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used)
                    {
                        eventHasBeenUsed = true;
                        m_currentHandle  = (BezierHandle)index;
                        Repaint();
                        SceneView.RepaintAll();
                    }
                    else if (!Math.Approx3(prev, point.position))
                    {
                        if (!m_IsMoving)
                        {
                            OnBeginVertexModification();
                        }

                        point.SetPosition(EditorSnapping.MoveSnap(prev));
                    }
                }

                // Tangent handles
                Handles.color = bezierTangentHandleColor;

                // Tangent In Handle
                if (m_CloseLoop || index > 0)
                {
                    size = HandleUtility.GetHandleSize(point.tangentIn) * k_HandleSize;
                    Handles.DrawLine(point.position, point.tangentIn);

                    if (index == m_currentHandle && m_currentHandle.isTangent && m_currentHandle.tangent == BezierTangentDirection.In)
                    {
                        Handles.DotHandleCap(0, point.tangentIn, Quaternion.identity, size, e.type);
                    }
                    else
                    {
                        prev = point.tangentIn;
                        prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap);

                        if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used)
                        {
                            eventHasBeenUsed = true;
                            m_currentHandle.SetIndexAndTangent(index, BezierTangentDirection.In);
                            Repaint();
                            SceneView.RepaintAll();
                        }
                        else if (!Math.Approx3(prev, point.tangentIn))
                        {
                            if (!m_IsMoving)
                            {
                                OnBeginVertexModification();
                            }
                            point.tangentIn = EditorSnapping.MoveSnap(prev);
                            point.EnforceTangentMode(BezierTangentDirection.In, m_TangentMode);
                        }
                    }
                }

                // Tangent Out
                if (m_CloseLoop || index < count - 1)
                {
                    size = HandleUtility.GetHandleSize(point.tangentOut) * k_HandleSize;
                    Handles.DrawLine(point.position, point.tangentOut);

                    if (index == m_currentHandle && m_currentHandle.isTangent && m_currentHandle.tangent == BezierTangentDirection.Out)
                    {
                        Handles.DotHandleCap(0, point.tangentOut, Quaternion.identity, size, e.type);
                    }
                    else
                    {
                        prev = point.tangentOut;
                        prev = Handles.FreeMoveHandle(prev, Quaternion.identity, size, Vector3.zero, Handles.DotHandleCap);

                        if (!eventHasBeenUsed && eventType == EventType.MouseUp && e.type == EventType.Used)
                        {
                            eventHasBeenUsed = true;
                            m_currentHandle.SetIndexAndTangent(index, BezierTangentDirection.Out);
                            Repaint();
                            SceneView.RepaintAll();
                        }
                        else if (!Math.Approx3(prev, point.tangentOut))
                        {
                            if (!m_IsMoving)
                            {
                                OnBeginVertexModification();
                            }
                            point.tangentOut = EditorSnapping.MoveSnap(prev);
                            point.EnforceTangentMode(BezierTangentDirection.Out, m_TangentMode);
                        }
                    }
                }

                m_Points[index] = point;
            }

            // Do control point insertion
            if (!eventHasBeenUsed && m_ControlPoints != null && m_ControlPoints.Count > 1)
            {
                int   index = -1;
                float distanceToLine;

                Vector3 p = EditorHandleUtility.ClosestPointToPolyLine(m_ControlPoints, out index, out distanceToLine, false, null);

                if (!IsHoveringHandlePoint(e.mousePosition) && distanceToLine < PreferenceKeys.k_MaxPointDistanceFromControl)
                {
                    Handles.color = Color.green;
                    Handles.DotHandleCap(-1, p, Quaternion.identity, HandleUtility.GetHandleSize(p) * .05f, e.type);
                    Handles.color = Color.white;

                    if (!eventHasBeenUsed && eventType == EventType.MouseDown && e.button == 0)
                    {
                        UndoUtility.RecordObject(m_Target, "Add Point");
                        Vector3 dir = m_ControlPoints[(index + 1) % m_ControlPoints.Count] - m_ControlPoints[index];
                        m_Points.Insert((index / m_Columns) + 1, new BezierPoint(p, p - dir, p + dir, Quaternion.identity));
                        UpdateMesh(true);
                        e.Use();
                    }

                    SceneView.RepaintAll();
                }
            }

            if (e.type == EventType.MouseUp && !sceneViewInUse)
            {
                m_currentHandle.SetIndex(-1);
            }

            Handles.matrix = handleMatrix;

            if (EditorGUI.EndChangeCheck())
            {
                UpdateMesh(false);
            }
        }