Пример #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();
            }
        }
        private void OnSceneGUI()
        {
            if (!m_editing)
            {
                if (m_debugPointQty > 0)
                {
                    RenderIntermediateSplinePoints(m_debugPointQty, pointSpline);
                }

                return;
            }

            if (m_editControlPoint.HasValue && EditorInputAbstractions.AddPointMode())
            {
                m_editControlPoint = null;
            }

            CheckActiveCamera();
            RenderControlPoints(pointSpline);

            if (EditorInputAbstractions.AddPointMode() &&
                SceneView.currentDrawingSceneView == SceneView.lastActiveSceneView)
            {
                PointSelection(pointSpline);

                if (Event.current.type == EventType.MouseMove)
                {
                    SceneView.RepaintAll();
                }
            }
        }
Пример #3
0
        private void OnSceneGUI()
        {
            if (!m_editing)
            {
                if (m_debugPointQty > 0)
                {
                    RenderIntermediateSplinePoints(m_debugPointQty, cubic2DSpline);
                }

                return;
            }

            if (m_editControlPoint.HasValue && EditorInputAbstractions.AddPointMode())
            {
                m_editControlPoint = null;
            }

            RenderControlPoints(cubic2DSpline);

            if (EditorInputAbstractions.AddPointMode())
            {
                PointSelection(cubic2DSpline);

                if (Event.current.type == EventType.MouseMove)
                {
                    SceneView.RepaintAll();
                }
            }
        }
Пример #4
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(ISpline3DEditor spline)
        {
            int    splineIndex;
            float3 splinePoint, splineMousePoint;

            ClosestPointSelection(Event.current.mousePosition, spline, out splineIndex, out splinePoint, out splineMousePoint);

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

            Handles.color = Color.red;
            Handles.DrawLine(splinePoint, splineMousePoint);

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

                if ((m_editNewPointIndex == spline.ControlPointCount - 1 || spline.ControlPointCount == 1) &&
                    splinePoint.Equals(spline.GetControlPoint3DLocal(m_editNewPointIndex)))
                {
                    spline.AddControlPoint(splineMousePoint);
                }
                else
                {
                    spline.InsertControlPointWorldSpace(m_editNewPointIndex, splineMousePoint);
                }

                SceneView.RepaintAll();
            }
        }
Пример #5
0
        /// <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>
        /// <param name="splinePoint">Point on spline that is closest</param>
        /// <param name="creationPoint">point that aligned to the mouse point relative to the camera</param>
        /// <returns>true is point could be found</returns>
        protected virtual bool ClosestPointSelection(float2 mouse, ISpline3DEditor spline, out int index, out float3 splinePoint,
                                                     out float3 creationPoint)
        {
            index = 0;
            float2 mouseComparison = new float2(mouse.x, LastSceneCamera.pixelHeight - mouse.y);

            if (spline.ControlPointCount == 0)
            {
                splinePoint = EditorInputAbstractions.MousePos3D();
            }
            if (spline.ControlPointCount == 1)
            {
                splinePoint = spline.GetControlPoint3DLocal(0);
            }
            else
            {
                splinePoint = float3.zero;
                float bestDistance = float.MaxValue;

                const int   segmentSampleAmount  = 64;
                const float segmentSampleAmountF = segmentSampleAmount;

                // this could potentially be cached as long as the spline doesn't change and the camera is at the same position
                for (int i = 1; i < spline.SegmentPointCount; i++)
                {
                    for (int s = 0; s <= segmentSampleAmount; s++)
                    {
                        float   progress       = s / segmentSampleAmountF;
                        float3  p              = spline.Get3DPoint(progress, i - 1);
                        Vector3 screenPosition = LastSceneCamera.WorldToScreenPoint(p);

                        float dist = math.distance(mouseComparison, new float2(screenPosition.x, screenPosition.y));
                        if (bestDistance > dist)
                        {
                            splinePoint  = p;
                            index        = i;
                            bestDistance = dist;
                        }
                    }
                }

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

            // convert the spline point and mouse position into the new point position
            if (!splinePoint.Equals(float3.zero))
            {
                Vector3 camPosition = LastSceneCameraTrans.position;

                float worldDistance = math.distance(splinePoint, camPosition);
                Ray   cameraRay     = LastSceneCamera.ScreenPointToRay(new Vector3(mouseComparison.x, mouseComparison.y, 0f));

                creationPoint = cameraRay.GetPoint(worldDistance);
                return(true);
            }

            creationPoint = default;
            return(false);
        }