Beispiel #1
0
        public static void DrawSelectedKnot(
            Bezier3DSplineData splineData,
            Action <IReadOnly3DSplineData> onUpdateSpline,
            UnityEditor.Editor editorWindow,
            Transform transform = null)
        {
            var knot = splineData.GetKnot(CurveEditorState.SelectedKnotIndex);

            Handles.color = Color.green;

            var knotWorldPos = transform == null
                                ? knot.position
                                : transform.TransformPoint(knot.position);

            if (knot.rotation.HasValue)
            {
                Handles.color = Handles.yAxisColor;
                var rot = knot.rotation.Value;
                Handles.ArrowHandleCap(
                    0,
                    knotWorldPos,
                    rot * Quaternion.AngleAxis(90, Vector3.left),
                    0.15f,
                    EventType.Repaint);
            }

            if (Tools.current == Tool.Move)
            {
                //Position handle
                using (var changeCheck = new EditorGUI.ChangeCheckScope())
                {
                    knotWorldPos = Handles.PositionHandle(knotWorldPos, Tools.handleRotation);

                    if (changeCheck.changed)
                    {
                        Undo.RecordObject(splineData, "Edit Bezier Point");
                        knot.position = transform == null ? knotWorldPos : transform.InverseTransformPoint(knotWorldPos);
                        splineData.SetKnot(CurveEditorState.SelectedKnotIndex, knot);
                        onUpdateSpline?.Invoke(splineData);
                        editorWindow.Repaint();
                    }
                }

                Handles.color = Color.white;

                //In Handle
                if (knot.handleIn != Vector3.zero)
                {
                    using (var changeCheck = new EditorGUI.ChangeCheckScope())
                    {
                        var inHandleWorldPos = transform == null
                                                        ? knot.position + knot.handleIn
                                                        : transform.TransformPoint(knot.position + knot.handleIn);

                        inHandleWorldPos = Handles.PositionHandle(inHandleWorldPos, Tools.handleRotation);

                        if (changeCheck.changed)
                        {
                            Undo.RecordObject(splineData, "Edit Bezier Handle");
                            knot.handleIn = transform == null
                                                                ? inHandleWorldPos - knot.position
                                                                : transform.InverseTransformPoint(inHandleWorldPos) - knot.position;
                            knot.auto = 0;
                            if (CurvePreferences.ShouldMirrorHandleMovement)
                            {
                                knot.handleOut = -knot.handleIn;
                            }

                            splineData.SetKnot(CurveEditorState.SelectedKnotIndex, knot);
                            onUpdateSpline?.Invoke(splineData);
                            editorWindow.Repaint();
                        }

                        Handles.DrawLine(knotWorldPos, inHandleWorldPos);
                    }
                }

                //outHandle
                if (knot.handleOut != Vector3.zero)
                {
                    using (var changeCheck = new EditorGUI.ChangeCheckScope())
                    {
                        var outHandleWorldPos = transform == null
                                                        ? knot.position + knot.handleOut
                                                        : transform.TransformPoint(knot.position + knot.handleOut);

                        outHandleWorldPos = Handles.PositionHandle(outHandleWorldPos, Tools.handleRotation);

                        if (changeCheck.changed)
                        {
                            Undo.RecordObject(splineData, "Edit Bezier Handle");
                            knot.handleOut = transform == null
                                                                ? outHandleWorldPos - knot.position
                                                                : transform.InverseTransformPoint(outHandleWorldPos) - knot.position;
                            knot.auto = 0;
                            if (CurvePreferences.ShouldMirrorHandleMovement)
                            {
                                knot.handleIn = -knot.handleOut;
                            }

                            splineData.SetKnot(CurveEditorState.SelectedKnotIndex, knot);
                            onUpdateSpline?.Invoke(splineData);
                            editorWindow.Repaint();
                        }

                        Handles.DrawLine(knotWorldPos, outHandleWorldPos);
                    }
                }
            }
            else if (Tools.current == Tool.Rotate)
            {
                //Rotation handle
                using (var changeCheck = new EditorGUI.ChangeCheckScope())
                {
                    var rot = (knot.rotation.HasValue ? knot.rotation.Value : Quaternion.identity).normalized;
                    rot = Handles.RotationHandle(rot, knotWorldPos);
                    if (changeCheck.changed)
                    {
                        Undo.RecordObject(splineData, "Edit Bezier Point");
                        knot.rotation = rot;
                        splineData.SetKnot(CurveEditorState.SelectedKnotIndex, knot);
                        onUpdateSpline?.Invoke(splineData);
                        editorWindow.Repaint();
                    }
                }
            }
        }
        public override void OnInspectorGUI()
        {
            ValidateSelected();

            // Spline Properties
            EditorGUI.indentLevel = 0;
            GUILayout.BeginVertical(GUI.skin.box);
            EditorGUILayout.LabelField("Spline Settings", EditorStyles.boldLabel);
            EditorGUILayout.Space(5);
            DrawInterpolationSteps();
            DrawClosedToggle();

            // Spline Actions
            GUILayout.BeginVertical(GUI.skin.box);
            EditorGUILayout.LabelField("Actions", EditorStyles.boldLabel);
            EditorGUILayout.Space(5);
            DrawSplineFlipAction();
            DrawCopySplineDataToClipboard();
            DrawPasteSplineDataToClipboard();
            DrawResetSplineData();
            GUILayout.EndVertical();

            GUILayout.EndVertical();

            // Selected Point Properties
            EditorGUILayout.Space();
            if (CurveEditorState.HasKnotSelected)
            {
                // Header information for selected knot.
                GUILayout.BeginVertical(GUI.skin.box);
                EditorGUILayout.LabelField(
                    $"Selected Knot (index = {CurveEditorState.SelectedKnotIndex})",
                    EditorStyles.boldLabel);
                EditorGUILayout.Space(2);

                var knot = _spline.GetKnot(CurveEditorState.SelectedKnotIndex);

                // Draw Position
                DrawKnotPosition(knot);
                EditorGUILayout.Space(2);

                // Draw Orientation
                DrawKnotOrientationToggle(knot);
                DrawKnotOrientationValue(knot);

                EditorGUILayout.Space(2);

                // Draw Auto-Handle
                DrawKnotAutoHandleToggle(knot);
                if (knot.IsUsingAutoHandles)
                {
                    DrawKnotAutoHandleValue(knot);
                }
                else
                {
                    DrawKnotHandleValues(knot);
                }

                GUILayout.EndVertical();
            }
        }
Beispiel #3
0
        public static void DrawSelectedSplitters(
            Bezier3DSplineData splineData,
            Action <IReadOnly3DSplineData> onUpdateSpline,
            Transform transform = null)
        {
            Handles.color = Color.white;

            //Start add
            if (!splineData.IsClosed && CurveEditorState.SelectedKnotIndex == 0)
            {
                var curve = splineData.GetCurve(0);
                var a     = transform == null
                                                ? curve.StartPoint
                                                : transform.TransformPoint(curve.StartPoint);
                var b = transform == null
                                                ? curve.FirstHandle.normalized * 2f
                                                : transform.TransformDirection(curve.FirstHandle).normalized * 2f;

                var handleScale = HandleUtility.GetHandleSize(a);
                b *= handleScale;
                Handles.DrawDottedLine(a, a - b, 3f);
                if (Handles.Button(
                        a - b,
                        Camera.current.transform.rotation,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        Handles.DotHandleCap))
                {
                    Undo.RecordObject(splineData, "Add Bezier Point");
                    var knot = splineData.GetKnot(CurveEditorState.SelectedKnotIndex);
                    splineData.InsertKnot(
                        0,
                        new Knot(
                            curve.StartPoint - curve.FirstHandle.normalized * handleScale * 2,
                            Vector3.zero,
                            curve.FirstHandle.normalized * 0.5f,
                            knot.auto,
                            knot.rotation));
                    onUpdateSpline?.Invoke(splineData);
                }
            }

            //End add
            if (!splineData.IsClosed && CurveEditorState.SelectedKnotIndex == splineData.CurveCount)
            {
                var curve = splineData.GetCurve(splineData.CurveCount - 1);
                var c     = transform == null
                                                ? curve.SecondHandle.normalized * 2f
                                                : transform.TransformDirection(curve.SecondHandle).normalized * 2f;
                var d = transform == null
                                                ? curve.EndPoint
                                                : transform.TransformPoint(curve.EndPoint);
                var handleScale = HandleUtility.GetHandleSize(d);
                c *= handleScale;
                Handles.DrawDottedLine(d, d - c, 3f);

                if (Handles.Button(
                        d - c,
                        Camera.current.transform.rotation,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        Handles.DotHandleCap))
                {
                    Undo.RecordObject(splineData, "Add Bezier Point");

                    var knot = splineData.GetKnot(CurveEditorState.SelectedKnotIndex);
                    splineData.AddKnot(
                        new Knot(
                            curve.EndPoint - curve.SecondHandle.normalized * handleScale * 2,
                            curve.SecondHandle.normalized * 0.5f,
                            Vector3.zero,
                            knot.auto,
                            knot.rotation));

                    CurveEditorState.SelectKnot(splineData.CurveCount, false);

                    onUpdateSpline?.Invoke(splineData);
                }
            }

            // Prev split
            if (splineData.IsClosed || CurveEditorState.SelectedKnotIndex != 0)
            {
                var curve       = splineData.GetCurve(CurveEditorState.SelectedKnotIndex == 0 ? splineData.CurveCount - 1 : CurveEditorState.SelectedKnotIndex - 1);
                var centerLocal = curve.GetPoint(curve.ConvertDistanceToTime(curve.Length * 0.5f));
                var center      = transform == null ? centerLocal : transform.TransformPoint(centerLocal);

                var a           = curve.StartPoint + curve.FirstHandle;
                var b           = curve.SecondHandle + curve.EndPoint;
                var ab          = (b - a) * 0.3f;
                var handleScale = HandleUtility.GetHandleSize(center);

                if (Handles.Button(
                        center,
                        Camera.current.transform.rotation,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        Handles.DotHandleCap))
                {
                    Undo.RecordObject(splineData, "Add Bezier Point");
                    var knot = splineData.GetKnot(CurveEditorState.SelectedKnotIndex);
                    splineData.InsertKnot(
                        CurveEditorState.SelectedKnotIndex == 0 ? splineData.CurveCount : CurveEditorState.SelectedKnotIndex,
                        new Knot(
                            centerLocal,
                            -ab,
                            ab,
                            knot.auto,
                            knot.rotation));

                    if (CurveEditorState.SelectedKnotIndex == 0)
                    {
                        CurveEditorState.SelectKnot(splineData.CurveCount - 1, false);
                    }

                    onUpdateSpline?.Invoke(splineData);
                }
            }

            // Next split
            if (CurveEditorState.SelectedKnotIndex != splineData.CurveCount)
            {
                var curve       = splineData.GetCurve(CurveEditorState.SelectedKnotIndex);
                var centerLocal = curve.GetPoint(curve.ConvertDistanceToTime(curve.Length * 0.5f));
                var center      = transform == null ? centerLocal : transform.TransformPoint(centerLocal);

                var a           = curve.StartPoint + curve.FirstHandle;
                var b           = curve.SecondHandle + curve.EndPoint;
                var ab          = (b - a) * 0.3f;
                var handleScale = HandleUtility.GetHandleSize(center);
                if (Handles.Button(
                        center,
                        Camera.current.transform.rotation,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        handleScale * SceneGUIConstants.HandleSize * 0.4f,
                        Handles.DotHandleCap))
                {
                    Undo.RecordObject(splineData, "Add Bezier Point");
                    splineData.InsertKnot(CurveEditorState.SelectedKnotIndex + 1, new Knot(centerLocal, -ab, ab));
                    CurveEditorState.SelectKnot(CurveEditorState.SelectedKnotIndex + 1, false);
                    onUpdateSpline?.Invoke(splineData);
                }
            }
        }