Example #1
0
        /// <summary>
        /// Handles the control logic for adding a point. This will draw a red line from the mouse position to the closest point along the
        /// curve
        /// </summary>
        /// <param name="spline">spline to handle control point logic for</param>
        protected void PointSelection(ISpline2DEditor spline)
        {
            float2 mouse = EditorInputAbstractions.MousePos2D();
            int    splineIndex;
            float2 createPoint = ClosestPointSelection(mouse, spline, out splineIndex);

            if (splineIndex != m_editNewPointIndex)
            {
                m_editNewPointIndex = splineIndex;
                Repaint(); // force refresh inspector
            }

            Handles.color = Color.red;
            Handles.DrawLine(
                new Vector3(createPoint.x, createPoint.y, 0f),
                new Vector3(mouse.x, mouse.y, 0f));

            if (EditorInputAbstractions.LeftClick() && spline is Object objSpline)
            {
                Undo.RecordObject(objSpline, "Insert Spline Point");
                EditorUtility.SetDirty(objSpline);

                float3 origin = m_sourceTrans.position;
                spline.InsertControlPoint(m_editNewPointIndex, mouse - origin.xy);

                SceneView.RepaintAll();
            }
        }
Example #2
0
        public void UpdateControlPoint(ISpline2D spline, int index, float3 newPoint, SplinePoint pointType)
        {
            ISpline2DEditor spline2D = spline as ISpline2DEditor;

            Assert.NotNull(spline2D);

            spline2D.UpdateControlPointLocal(index, newPoint.xy, pointType);
        }
Example #3
0
        public float3 GetControlPoint(ISpline2D spline, int index, SplinePoint pointType)
        {
            ISpline2DEditor spline2D = spline as ISpline2DEditor;

            Assert.NotNull(spline2D);

            return(new float3(spline2D.GetControlPoint2DLocal(index), 0f));
        }
Example #4
0
        public void InsertControlPointWorldSpace(ISpline2D spline, int index, float3 point)
        {
            ISpline2DEditor spline2D = spline as ISpline2DEditor;

            Assert.NotNull(spline2D);

            spline2D.InsertControlPoint(index, point.xy);
        }
        /// <summary>
        /// Find the closest point to the spline
        /// </summary>
        /// <param name="mouse">mouse position</param>
        /// <param name="spline">spline to check</param>
        /// <param name="index">spline index of the closest point</param>
        /// <returns>closest point on the spline to the mouse</returns>
        protected override float2 ClosestPointSelection(float2 mouse, ISpline2DEditor spline, out int index)
        {
            Assert.AreSame(pointSpline, spline, "Somehow the spline changed from the start point and the point sample point");

            float2 closest = base.ClosestPointSelection(mouse, spline, out index);

            index = pointSpline.Looped ? (index + 1) % spline.ControlPointCount : index;
            return(closest);
        }
        /// <summary>
        /// Find the closest point to the spline
        /// </summary>
        /// <param name="mouse">mouse position</param>
        /// <param name="spline">spline to check</param>
        /// <param name="index">spline index of the closest point</param>
        /// <returns>closest point on the spline to the mouse</returns>
        protected override float2 ClosestPointSelection(float2 mouse, ISpline2DEditor spline, out int index)
        {
            index = 0;

            if (spline.ControlPointCount == 1)
            {
                return(spline.GetControlPoint2DLocal(0));
            }
            else if (spline.ControlPointCount == 0)
            {
                return(mouse);
            }

            float2 bestPoint    = float2.zero;
            float  bestDistance = float.MaxValue;

            for (int i = 1; i < spline.SegmentPointCount; i++)
            {
                for (int s = 0; s <= 64; s++)
                {
                    float  progress = s / 64f;
                    float2 p        = spline.Get2DPointWorld(progress, i - 1);

                    float dist = math.distance(mouse, p);
                    if (bestDistance > dist)
                    {
                        bestPoint    = p;
                        bestDistance = dist;

                        if (progress > 0.5)
                        {
                            index = (i + 1) % spline.ControlPointCount;
                        }
                        else
                        {
                            index = i;
                        }
                    }
                }
            }

            if (!(spline is ILoopingSpline) || !((ILoopingSpline)spline).Looped)
            {
                if (math.distance(bestPoint, spline.GetControlPoint2DWorld(0)) <= 0.00001f)
                {
                    index = 0;
                }
                else if (math.distance(bestPoint, spline.GetControlPoint2DWorld(spline.ControlPointCount - 1)) <= 0.00001f)
                {
                    index = spline.ControlPointCount - 1;
                }
            }

            return(bestPoint);
        }
Example #7
0
        private void MoveWithTransform(ISpline2DEditor spline)
        {
            if (m_editMoveWithTrans)
            {
                return;
            }

            Vector3 currentPosition = m_sourceTrans.position;

            if (currentPosition != m_lastTransPosition)
            {
                Vector3 delta = m_lastTransPosition - currentPosition;
                m_lastTransPosition = currentPosition;

                // move all the points by delta amount
                spline.MoveControlPoints(new float2(delta.x, delta.y));
            }
        }
Example #8
0
        /// <summary>
        /// Renders a blue dot at each control point of the spline
        /// </summary>
        /// <param name="spline">spline to render control points for</param>
        protected void RenderControlPoints(ISpline2DEditor spline)
        {
            for (int i = 0; i < spline.ControlPointCount; i++)
            {
                bool selected = m_editControlPoint == i;

                Handles.color = selected ? Color.blue : new Color(0f, 1f, 1f, 0.73f);

                float2 point          = spline.GetControlPoint2DWorld(i);
                float3 editorPosition = new float3(point, 0f);

                // draw handles
                if (selected)
                {
                    // main point
                    EditorGUI.BeginChangeCheck();
                    Vector3 pos = Handles.DoPositionHandle(editorPosition, Quaternion.identity);

                    if (EditorGUI.EndChangeCheck() && spline is Object objSpline)
                    {
                        Undo.RecordObject(objSpline, "Move Point");
                        EditorUtility.SetDirty(objSpline);

                        float3 origin   = ((MonoBehaviour)spline).transform.position;
                        float2 newPoint = new float2(pos.x, pos.y) - origin.xy;
                        spline.UpdateControlPointLocal(i, newPoint, SplinePoint.Point);

                        SceneView.RepaintAll();
                    }
                }
                else
                {
                    float size = HandleUtility.GetHandleSize(editorPosition) / 12f;
                    if (Handles.Button(editorPosition, Quaternion.identity, size, size, Handles.DotHandleCap))
                    {
                        m_editControlPoint = i;
                        Repaint();
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Shared Inspector logic
        /// </summary>
        /// <param name="spline">spline to show inspector for</param>
        protected void OnInspectorGUI(ISpline2DEditor spline)
        {
            if (GUILayout.Button("Edit Points"))
            {
                m_editing           = !m_editing;
                m_editControlPoint  = null;
                m_editNewPointIndex = -1;
                m_lastTransPosition = m_sourceTrans?.position ?? Vector3.zero;

                SceneView.RepaintAll();
            }

            if (!m_editing)
            {
                GUILayout.Space(5);
                EditorGUILayout.HelpBox(
                    $"Points: {spline.ControlPointCount}\n" +
                    $"Length: {spline.Length():N3}", MessageType.None);

                if (spline is ILoopingSpline loop)
                {
                    EditorGUI.BeginChangeCheck();
                    loop.Looped = EditorGUILayout.Toggle("Loop", loop.Looped);
                    if (EditorGUI.EndChangeCheck())
                    {
                        SceneView.RepaintAll();
                    }
                }

                if (spline is IArkableSpline arked)
                {
                    EditorGUI.BeginChangeCheck();
                    arked.ArkParameterization = EditorGUILayout.Toggle("Ark Parametrization", arked.ArkParameterization);
                    if (EditorGUI.EndChangeCheck() && spline is Object objSpline)
                    {
                        EditorUtility.SetDirty(objSpline);
                    }

                    if (arked.ArkParameterization)
                    {
                        EditorGUI.BeginChangeCheck();
                        arked.ArkLength = EditorGUILayout.FloatField("Ark Length", arked.ArkLength);
                        if (EditorGUI.EndChangeCheck() && spline is Object objSpline2)
                        {
                            EditorUtility.SetDirty(objSpline2);
                        }
                    }
                }

                GUILayout.Space(5);

                // Draw spline points - Draw a point every set interval to illustrate where bezier points will be
                EditorGUI.BeginChangeCheck();
                m_debugPointQty = (int)EditorGUILayout.Slider("Draw points", m_debugPointQty, 0, 200);
                if (EditorGUI.EndChangeCheck())
                {
                    SceneView.RepaintAll();
                }
            }
            else
            {
                if (m_sourceTrans != null)
                {
                    bool value = EditorGUILayout.Toggle("Move Points with Transform", m_editMoveWithTrans);
                    if (value != m_editMoveWithTrans)
                    {
                        m_editMoveWithTrans = value;
                        m_lastTransPosition = m_sourceTrans.position;
                    }

                    MoveWithTransform(spline);
                }

                if (m_editNewPointIndex >= 0)
                {
                    EditorGUILayout.LabelField($"New At Index: {m_editNewPointIndex}");
                }

                if (m_editControlPoint == null)
                {
                    EditorGUILayout.HelpBox($"No Control Point Selected!", MessageType.None);
                }
                else
                {
                    m_editNewPointIndex = -1;
                    EditorGUILayout.LabelField($"Control Point: {m_editControlPoint}");

                    // show the current control point location
                    EditorGUI.BeginChangeCheck();
                    float2 currentPoint = spline.GetControlPoint2DLocal(m_editControlPoint.Value);
                    currentPoint = EditorGUILayout.Vector2Field("Point", currentPoint);
                    if (EditorGUI.EndChangeCheck())
                    {
                        spline.UpdateControlPointLocal(m_editControlPoint.Value, currentPoint, SplinePoint.Point);
                        SceneView.RepaintAll();
                    }

                    SplineEditMode existingValue = spline.GetEditMode(m_editControlPoint.Value);
                    SplineEditMode editMode      = (SplineEditMode)EditorGUILayout.EnumPopup("Edit Mode", existingValue);
                    if (editMode != existingValue && spline is Object objSpline)
                    {
                        Undo.RecordObject(objSpline, $"Change EditMode of Point {m_editControlPoint}");
                        EditorUtility.SetDirty(objSpline);
                        spline.ChangeEditMode(m_editControlPoint.Value, editMode);

                        SceneView.RepaintAll();
                    }

                    GUILayout.Space(10);
                    if (GUILayout.Button("Remove Point") ||
                        Event.current.isKey && Event.current.type == EventType.KeyDown &&
                        Event.current.keyCode == KeyCode.Delete)
                    {
                        spline.RemoveControlPoint(m_editControlPoint.Value);
                        m_editControlPoint = null;

                        SceneView.RepaintAll();

                        if (Event.current.keyCode == KeyCode.Delete)
                        {
                            // Sadly this doesn't actually work :( dammit Unity
                            GUIUtility.hotControl = 0;
                            Event.current.Use();
                        }
                    }
                }
            }
        }