Exemple #1
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));
        }
        /// <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);
        }
Exemple #3
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();
                        }
                    }
                }
            }
        }