/// <summary>
        /// Draw Scene GUI handles, circles and outlines for submesh vertices.
        /// <summary>
        public void OnSceneGUI()
        {
            //get world positions of vertices
            allPoints = ConvertAllPoints();

            //create a ray to get where we clicked in the scene view and pass in mouse position
            Ray        worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            RaycastHit hitInfo;
            Event      e = Event.current;

            //this prevents selecting other objects in the scene
            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            HandleUtility.AddDefaultControl(controlID);
            //find index of closest vertex, if any
            dragIndex = FindClosest();

            if (!placing && e.type == EventType.keyDown && e.keyCode == KeyCode.Backspace)
            {
                e.Use();
                Undo.RegisterCompleteObjectUndo(script, "Delete Vertex");
                Undo.RecordObject(script.GetComponent <MeshFilter>().sharedMesh, "Delete Vertex");
                DeleteSelected();
                return;
            }

            //in the edit mode, ray hit something
            if (placing)
            {
                Tools.current = Tool.None;
                Handles.BeginGUI();
                GUILayout.Window(2, new Rect(Screen.width - 157, Screen.height - 100, 100, 50), (id) =>
                {
                    GUILayout.Label(editOnText);
                }, "Control Info Box");
                Handles.EndGUI();

                if (Physics.Raycast(worldRay, out hitInfo))
                {
                    //the actual hit position
                    mousePosition = hitInfo.point;

                    //place new point if the left mouse button was clicked
                    if (e.type == EventType.mouseUp && e.button == 0 && !e.alt)
                    {
                        Undo.RegisterCompleteObjectUndo(script, "Add Vertex");

                        //get current submesh vertex count
                        int currentCount = script.current.Count;
                        //create a new submesh, if control was hold in addition to the mouse click
                        //or if autoSplit is true and the current count exceeds splitAt
                        if ((e.control && currentCount >= 3) ||
                            (script.autoSplit && currentCount >= script.splitAt))
                        {
                            GameObject newObj = script.CreateSubMesh();
                            Undo.RegisterCreatedObjectUndo(newObj, "Add Vertex");
                        }

                        //call this method when you've used an event.
                        //the event's type will be set to EventType.Used,
                        //causing other GUI elements to ignore it
                        e.Use();

                        //add point to existing vertex, if near any
                        //but don't add it to the same submesh (closed mesh)
                        //otherwise just add a new vertex position
                        if (script.current.Contains(dragIndex))
                        {
                            script.AddPoint(script.transform.TransformPoint(script.list[dragIndex]));
                        }
                        else if (dragIndex >= 0)
                        {
                            script.AddPoint(dragIndex);
                        }
                        else
                        {
                            script.AddPoint(mousePosition);
                        }

                        //invoke new mesh calculation
                        Undo.RegisterCompleteObjectUndo(script.subMesh, "Add Vertex");
                        script.CreateMesh();
                        return;
                    }
                }
            }

            //not in edit mode
            if (!placing)
            {
                Handles.BeginGUI();
                GUILayout.Window(2, new Rect(Screen.width - 200, Screen.height - 100, 100, 50), (id) =>
                {
                    GUILayout.Label(editOffText);
                }, "Control Info Box");
                Handles.EndGUI();

                //clicking near vertices will select them and show handles
                if (e.type == EventType.mouseUp && e.button == 0 && !e.alt)
                {
                    //select/unselect vertex point
                    if (dragIndex >= 0)
                    {
                        if (!selected.Contains(dragIndex))
                        {
                            selected.Add(dragIndex);
                        }
                        else
                        {
                            selected.Remove(dragIndex);
                        }

                        SceneView.RepaintAll();
                    }
                    else if (selected.Count == 0)
                    {
                        Selection.activeObject = null;
                    }
                }
                //unselect all vertices
                else if (e.type == EventType.mouseUp && e.button == 1 && !e.alt)
                {
                    selected.Clear();
                }
            }

            //draw scene gizmos
            DrawSelectedHandles();
            DrawPolygonOutline();

            //handle undo of vertex modifications (redraw mesh)
            if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed")
            {
                undoRedo = true;
            }

            HandleUtility.AddDefaultControl(-1);
            HandleUtility.Repaint();
        }
Exemple #2
0
        /// <summary>
        /// Draw Scene GUI handles, circles and outlines for submesh vertices.
        /// <summary>
        public void OnSceneGUI()
        {
            //get world positions of vertices
            allPoints = ConvertAllPoints();

            //create a ray to get where we clicked in the scene view and pass in mouse position
            Ray        worldRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            RaycastHit hitInfo;

            //this prevents selecting other objects in the scene
            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            HandleUtility.AddDefaultControl(controlID);
            //find index of closest vertex, if any
            dragIndex = FindClosest();

            //in the edit mode, ray hit something
            if (placing && Physics.Raycast(worldRay, out hitInfo))
            {
                //the actual hit position
                mousePosition = hitInfo.point;
                Event e = Event.current;

                //place new point if the left mouse button was clicked
                if (e.type == EventType.mouseUp && e.button == 0)
                {
                    Undo.RegisterCompleteObjectUndo(script, "Split Mesh");

                    //get current submesh vertex count
                    int currentCount = script.current.Count;
                    //create a new submesh, if control was hold in addition to the mouse click
                    //or if autoSplit is true and the current count exceeds splitAt
                    if ((e.control && currentCount >= 3) ||
                        (script.autoSplit && currentCount >= script.splitAt))
                    {
                        GameObject newObj = script.CreateSubMesh();
                        Undo.RegisterCreatedObjectUndo(newObj, "Split Mesh");
                    }

                    //call this method when you've used an event.
                    //the event's type will be set to EventType.Used,
                    //causing other GUI elements to ignore it
                    Event.current.Use();

                    //add point to existing vertex, if near any
                    //otherwise just add a new vertex position
                    if (dragIndex >= 0)
                    {
                        script.AddPoint(dragIndex);
                    }
                    else
                    {
                        script.AddPoint(mousePosition);
                    }

                    //invoke new mesh calculation
                    Undo.RecordObject(script.subMesh, "Split Mesh");
                    script.CreateMesh();
                    return;
                }
            }

            //not in edit mode, clicking near vertices will select them and show handles
            if (!placing && Event.current.type == EventType.mouseUp && Event.current.button == 0)
            {
                //select/unselect vertex point
                if (dragIndex >= 0)
                {
                    if (!selected.Contains(dragIndex))
                    {
                        selected.Add(dragIndex);
                    }
                    else
                    {
                        selected.Remove(dragIndex);
                    }

                    SceneView.RepaintAll();
                }
            }

            //right-clicking anywhere will unselect all vertices
            if (!placing && Event.current.type == EventType.mouseUp && Event.current.button == 1)
            {
                selected.Clear();
            }

            //draw scene gizmos
            DrawSelectedHandles();
            DrawPolygonOutline();

            //handle undo of vertex modifications (redraw mesh)
            if (Event.current.commandName == "UndoRedoPerformed")
            {
                if (!script.GetComponent <MeshFilter>().sharedMesh)
                {
                    return;
                }

                script.UpdateMesh(ConvertAllPoints());
                return;
            }
        }