void OnSceneGUI(SceneView sceneView)
        {
            SceneStyles.Init();

            m_CurrentEvent = Event.current;

            EditorHandleDrawing.DrawSceneHandles(SceneDragAndDropListener.isDragging ? SelectMode.None : selectMode);

            DrawHandleGUI(sceneView);

            if (m_CurrentEvent.type == EventType.KeyDown)
            {
                // Escape isn't assignable as a shortcut
                if (m_CurrentEvent.keyCode == KeyCode.Escape && selectMode != SelectMode.Object)
                {
                    selectMode = SelectMode.Object;

                    m_IsDragging          = false;
                    m_IsReadyForMouseDrag = false;

                    m_CurrentEvent.Use();
                }
            }

            if (selectMode == SelectMode.Object)
            {
                return;
            }

            bool pathSelectionModifier = EditorHandleUtility.IsSelectionPathModifier(m_CurrentEvent.modifiers);

            // Check mouse position in scene and determine if we should highlight something
            if (s_ShowHoverHighlight &&
                selectMode.IsMeshElementMode() &&
                (m_CurrentEvent.type == EventType.MouseMove ||
                 (m_wasSelectingPath != pathSelectionModifier && m_CurrentEvent.isKey)))
            {
                m_Hovering.CopyTo(m_HoveringPrevious);
                if (GUIUtility.hotControl != 0 ||
                    EditorSceneViewPicker.MouseRayHitTest(m_CurrentEvent.mousePosition, selectMode, m_ScenePickerPreferences, m_Hovering) > ScenePickerPreferences.maxPointerDistance)
                {
                    m_Hovering.Clear();
                }

                if (!m_Hovering.Equals(m_HoveringPrevious))
                {
                    if (pathSelectionModifier)
                    {
                        EditorSceneViewPicker.DoMouseHover(m_Hovering);
                    }

                    SceneView.RepaintAll();
                }
            }

            m_wasSelectingPath = pathSelectionModifier;

            if (Tools.current == Tool.View)
            {
                return;
            }

            switch (m_CurrentEvent.type)
            {
            case EventType.ValidateCommand:
            case EventType.ExecuteCommand:
                bool execute = m_CurrentEvent.type == EventType.ExecuteCommand;
                switch (m_CurrentEvent.commandName)
                {
                case "SelectAll":
                    if (execute)
                    {
                        SelectAll();
                    }
                    m_CurrentEvent.Use();
                    break;

                case "DeselectAll":
                    if (execute)
                    {
                        DeselectAll();
                    }
                    m_CurrentEvent.Use();
                    break;

                case "InvertSelection":
                    if (execute)
                    {
                        InvertSelection();
                    }
                    m_CurrentEvent.Use();
                    break;
                }
                break;
            }

            if (EditorHandleUtility.SceneViewInUse(m_CurrentEvent))
            {
                if (m_IsDragging)
                {
                    m_IsDragging = false;
                }

                if (GUIUtility.hotControl == m_DefaultControl)
                {
                    GUIUtility.hotControl = 0;
                }

                return;
            }

            // This prevents us from selecting other objects in the scene,
            // and allows for the selection of faces / vertices.
            m_DefaultControl = GUIUtility.GetControlID(FocusType.Passive);
            if (Event.current.type == EventType.Layout)
            {
                HandleUtility.AddDefaultControl(m_DefaultControl);
            }

            if (m_CurrentEvent.type == EventType.MouseDown && HandleUtility.nearestControl == m_DefaultControl)
            {
                // double clicking object
                if (m_CurrentEvent.clickCount > 1)
                {
                    DoubleClick(m_CurrentEvent);
                }

                m_InitialMousePosition = m_CurrentEvent.mousePosition;
                // readyForMouseDrag prevents a bug wherein after ending a drag an errant
                // MouseDrag event is sent with no corresponding MouseDown/MouseUp event.
                m_IsReadyForMouseDrag = true;

                GUIUtility.hotControl = m_DefaultControl;
            }

            if (m_CurrentEvent.type == EventType.MouseDrag && m_IsReadyForMouseDrag && GUIUtility.hotControl == m_DefaultControl)
            {
                if (!m_IsDragging && Vector2.Distance(m_CurrentEvent.mousePosition, m_InitialMousePosition) > k_MouseDragThreshold)
                {
                    sceneView.Repaint();
                    m_IsDragging = true;
                }
            }

            if (m_CurrentEvent.type == EventType.Ignore)
            {
                if (m_IsDragging)
                {
                    m_IsReadyForMouseDrag = false;
                    m_IsDragging          = false;
                    EditorSceneViewPicker.DoMouseDrag(m_MouseDragRect, selectMode, m_ScenePickerPreferences);
                }

                if (m_WasDoubleClick)
                {
                    m_WasDoubleClick = false;
                }

                if (GUIUtility.hotControl == m_DefaultControl)
                {
                    GUIUtility.hotControl = 0;
                }
            }

            if (m_CurrentEvent.type == EventType.MouseUp && GUIUtility.hotControl == m_DefaultControl)
            {
                GUIUtility.hotControl = 0;

                if (m_WasDoubleClick)
                {
                    m_WasDoubleClick = false;
                }
                else
                {
                    if (!m_IsDragging)
                    {
                        if (UVEditor.instance)
                        {
                            UVEditor.instance.ResetUserPivot();
                        }

                        EditorSceneViewPicker.DoMouseClick(m_CurrentEvent, selectMode, m_ScenePickerPreferences);
                        UpdateSelection();
                    }
                    else
                    {
                        m_IsDragging          = false;
                        m_IsReadyForMouseDrag = false;

                        if (UVEditor.instance)
                        {
                            UVEditor.instance.ResetUserPivot();
                        }

                        EditorSceneViewPicker.DoMouseDrag(m_MouseDragRect, selectMode, m_ScenePickerPreferences);

                        if (GUIUtility.hotControl == m_DefaultControl)
                        {
                            GUIUtility.hotControl = 0;
                        }
                    }
                }
            }
        }
        public static ProBuilderMesh DoMouseClick(Event evt, SelectMode selectionMode, ScenePickerPreferences pickerPreferences)
        {
            bool appendModifier         = EditorHandleUtility.IsAppendModifier(evt.modifiers);
            bool addToSelectionModifier = EditorHandleUtility.IsSelectionAddModifier(evt.modifiers);
            bool addOrRemoveIfPresentFromSelectionModifier = EditorHandleUtility.IsSelectionAppendOrRemoveIfPresentModifier(evt.modifiers);
            bool pathSelectionModifier = EditorHandleUtility.IsSelectionPathModifier(evt.modifiers);

            float pickedElementDistance;

            if (selectionMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
            {
                pickedElementDistance = EdgeRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection);
            }
            else if (selectionMode.ContainsFlag(SelectMode.Vertex | SelectMode.TextureVertex))
            {
                pickedElementDistance = VertexRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection);
            }
            else
            {
                pickedElementDistance = FaceRaycast(evt.mousePosition, pickerPreferences, k_AllowUnselected, s_Selection, evt.clickCount > 1 ? -1 : 0, false);
            }

            evt.Use();

            if (!appendModifier)
            {
                if (s_Selection.mesh != null)
                {
                    s_Selection.mesh.ClearSelection();
                }
                MeshSelection.SetSelection((GameObject)null);
            }

            if (pickedElementDistance > ScenePickerPreferences.maxPointerDistance)
            {
                if (appendModifier && Selection.gameObjects.Contains(s_Selection.gameObject))
                {
                    MeshSelection.RemoveFromSelection(s_Selection.gameObject);
                }
                else
                {
                    MeshSelection.AddToSelection(s_Selection.gameObject);
                }

                return(null);
            }

            GameObject candidateNewActiveObject     = s_Selection.gameObject;
            bool       activeObjectSelectionChanged = Selection.gameObjects.Contains(s_Selection.gameObject) && s_Selection.gameObject != Selection.activeGameObject;

            if (s_Selection.mesh != null)
            {
                var mesh = s_Selection.mesh;

                foreach (var face in s_Selection.faces)
                {
                    // Check for other editor mouse shortcuts first (todo proper event handling for mouse shortcuts)
                    MaterialEditor matEditor = MaterialEditor.instance;

                    if (matEditor != null && matEditor.ClickShortcutCheck(Event.current.modifiers, mesh, face))
                    {
                        return(null);
                    }

                    UVEditor uvEditor = UVEditor.instance;

                    if (uvEditor != null && uvEditor.ClickShortcutCheck(mesh, face))
                    {
                        return(null);
                    }

                    var faces = mesh.faces as Face[] ?? mesh.faces.ToArray();
                    var ind   = Array.IndexOf <Face>(faces, face);
                    var sel   = mesh.selectedFaceIndexes.IndexOf(ind);

                    UndoUtility.RecordSelection(mesh, "Select Face");

                    if (sel > -1)
                    {
                        if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier ||
                            (addToSelectionModifier && face == mesh.GetActiveFace() && !activeObjectSelectionChanged))
                        {
                            mesh.RemoveFromFaceSelectionAtIndex(sel);

                            if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged)
                            {
                                candidateNewActiveObject = Selection.activeGameObject;
                            }
                            else if (mesh.selectedFaceCount == 0)
                            {
                                for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--)
                                {
                                    if (MeshSelection.topInternal[i].selectedFaceCount > 0)
                                    {
                                        candidateNewActiveObject     = MeshSelection.topInternal[i].gameObject;
                                        activeObjectSelectionChanged = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            mesh.selectedFaceIndicesInternal = mesh.selectedFaceIndicesInternal.Remove(ind);
                            mesh.SetSelectedFaces(mesh.selectedFaceIndicesInternal.Add(ind));
                        }
                    }
                    else if (pathSelectionModifier && mesh.GetActiveFace() != null)
                    {
                        var pathFaces = SelectPathFaces.GetPath(mesh, Array.IndexOf <Face>(faces, mesh.GetActiveFace()),
                                                                Array.IndexOf <Face>(faces, face));
                        foreach (var pathFace in pathFaces)
                        {
                            mesh.AddToFaceSelection(pathFace);
                        }
                    }
                    else
                    {
                        mesh.AddToFaceSelection(ind);
                    }
                }

                foreach (var edge in s_Selection.edges)
                {
                    int ind = mesh.IndexOf(mesh.selectedEdges, edge);

                    UndoUtility.RecordSelection(mesh, "Select Edge");

                    if (ind > -1)
                    {
                        if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier ||
                            (addToSelectionModifier && edge == mesh.GetActiveEdge() && !activeObjectSelectionChanged))
                        {
                            mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().RemoveAt(ind));

                            if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged)
                            {
                                candidateNewActiveObject = Selection.activeGameObject;
                            }
                            else if (mesh.selectedEdgeCount == 0)
                            {
                                for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--)
                                {
                                    if (MeshSelection.topInternal[i].selectedEdgeCount > 0)
                                    {
                                        candidateNewActiveObject     = MeshSelection.topInternal[i].gameObject;
                                        activeObjectSelectionChanged = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            mesh.selectedEdgesInternal = mesh.selectedEdgesInternal.Remove(edge);
                            mesh.SetSelectedEdges(mesh.selectedEdgesInternal.Add(edge));
                        }
                    }
                    else
                    {
                        mesh.SetSelectedEdges(mesh.selectedEdges.ToArray().Add(edge));
                    }
                }
                foreach (var vertex in s_Selection.vertexes)
                {
                    int ind = Array.IndexOf(mesh.selectedIndexesInternal, vertex);

                    UndoUtility.RecordSelection(mesh, "Select Vertex");

                    if (ind > -1)
                    {
                        var sharedIndex  = mesh.sharedVertexLookup[vertex];
                        var sharedVertex = mesh.sharedVerticesInternal[sharedIndex];
                        s_IndexBuffer.Clear();
                        foreach (var sVertex in sharedVertex)
                        {
                            var index = Array.IndexOf(mesh.selectedIndexesInternal, sVertex);
                            if (index < 0)
                            {
                                continue;
                            }

                            s_IndexBuffer.Add(index);
                        }
                        s_IndexBuffer.Sort();

                        if (!appendModifier || addOrRemoveIfPresentFromSelectionModifier ||
                            (addToSelectionModifier && vertex == mesh.GetActiveVertex() && !activeObjectSelectionChanged))
                        {
                            mesh.selectedIndexesInternal = mesh.selectedIndexesInternal.SortedRemoveAt(s_IndexBuffer);
                            mesh.SetSelectedVertices(mesh.selectedIndexesInternal);

                            if (addOrRemoveIfPresentFromSelectionModifier && activeObjectSelectionChanged)
                            {
                                candidateNewActiveObject = Selection.activeGameObject;
                            }
                            else if (mesh.selectedIndexesInternal.Length == 0)
                            {
                                for (var i = MeshSelection.topInternal.Count - 1; i >= 0; i--)
                                {
                                    if (MeshSelection.topInternal[i].selectedIndexesInternal.Length > 0)
                                    {
                                        candidateNewActiveObject     = MeshSelection.topInternal[i].gameObject;
                                        activeObjectSelectionChanged = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            mesh.selectedIndexesInternal = mesh.selectedIndexesInternal.SortedRemoveAt(s_IndexBuffer);
                            mesh.SetSelectedVertices(mesh.selectedIndexesInternal.Add(vertex));
                        }
                    }
                    else
                    {
                        mesh.SetSelectedVertices(mesh.selectedIndexesInternal.Add(vertex));
                    }
                }

                if (activeObjectSelectionChanged)
                {
                    MeshSelection.MakeActiveObject(candidateNewActiveObject);
                }
                else
                {
                    MeshSelection.AddToSelection(candidateNewActiveObject);
                }

                return(mesh);
            }

            return(null);
        }
        void OnSceneGUI(SceneView sceneView)
        {
            SceneStyles.Init();

            m_CurrentEvent = Event.current;

            EditorHandleDrawing.DrawSceneHandles(SceneDragAndDropListener.isDragging ? SelectMode.None : selectMode);

            DrawHandleGUI(sceneView);

            if (m_CurrentEvent.type == EventType.KeyDown)
            {
                // Escape isn't assignable as a shortcut
                if (m_CurrentEvent.keyCode == KeyCode.Escape && selectMode != SelectMode.Object)
                {
                    selectMode = SelectMode.Object;

                    m_IsDragging          = false;
                    m_IsReadyForMouseDrag = false;

                    m_CurrentEvent.Use();
                }
            }

            if (selectMode == SelectMode.Object)
            {
                return;
            }

            bool pathSelectionModifier = EditorHandleUtility.IsSelectionPathModifier(m_CurrentEvent.modifiers);

            // Check mouse position in scene and determine if we should highlight something
            if (s_ShowHoverHighlight &&
                selectMode.IsMeshElementMode() &&
                (m_CurrentEvent.type == EventType.MouseMove ||
                 (m_wasSelectingPath != pathSelectionModifier && m_CurrentEvent.isKey)))
            {
                m_Hovering.CopyTo(m_HoveringPrevious);
                if (GUIUtility.hotControl != 0 ||
                    EditorSceneViewPicker.MouseRayHitTest(m_CurrentEvent.mousePosition, selectMode, m_ScenePickerPreferences, m_Hovering) > ScenePickerPreferences.maxPointerDistance)
                {
                    m_Hovering.Clear();
                }

                if (!m_Hovering.Equals(m_HoveringPrevious))
                {
                    if (pathSelectionModifier)
                    {
                        EditorSceneViewPicker.DoMouseHover(m_Hovering);
                    }

                    SceneView.RepaintAll();
                }
            }

            m_wasSelectingPath = pathSelectionModifier;

            if (Tools.current == Tool.View)
            {
                return;
            }

            switch (m_CurrentEvent.type)
            {
            case EventType.ValidateCommand:
            case EventType.ExecuteCommand:
                bool execute = m_CurrentEvent.type == EventType.ExecuteCommand;
                switch (m_CurrentEvent.commandName)
                {
                case "SelectAll":
                    if (execute)
                    {
                        SelectAll();
                    }
                    m_CurrentEvent.Use();
                    break;

                case "DeselectAll":
                    if (execute)
                    {
                        DeselectAll();
                    }
                    m_CurrentEvent.Use();
                    break;

                case "InvertSelection":
                    if (execute)
                    {
                        InvertSelection();
                    }
                    m_CurrentEvent.Use();
                    break;
                }
                break;
            }

            if (EditorHandleUtility.SceneViewInUse(m_CurrentEvent))
            {
                if (m_IsDragging)
                {
                    m_IsDragging = false;
                }

                if (GUIUtility.hotControl == m_DefaultControl)
                {
                    GUIUtility.hotControl = 0;
                }

                return;
            }

            // This prevents us from selecting other objects in the scene,
            // and allows for the selection of faces / vertices.
            m_DefaultControl = GUIUtility.GetControlID(FocusType.Passive);
            if (Event.current.type == EventType.Layout)
            {
                HandleUtility.AddDefaultControl(m_DefaultControl);
            }

            HandleMouseEvent(sceneView, m_DefaultControl);
        }