public static MeshAndFace PickFace(Camera camera, Vector3 mousePosition)
        {
            MeshAndFace res = new MeshAndFace();
            GameObject  go  = PickObject(camera, mousePosition);

            if (go == null || !(res.mesh = go.GetComponent <ProBuilderMesh>()))
            {
                return(res);
            }

            res.face = SelectionPicker.PickFace(camera, mousePosition, res.mesh);
            return(res);
        }
 public static Dictionary <ProBuilderMesh, HashSet <Face> > PickFaces(Camera camera, Rect rect, GameObject[] gameObjects)
 {
     try
     {
         return(SelectionPicker.PickFacesInRect(camera, rect, gameObjects.Select(g => g.GetComponent <ProBuilderMesh>()).Where(pbm => pbm != null).ToArray(), new PickerOptions {
             rectSelectMode = RectSelectMode.Partial, depthTest = false
         }));
     }
     catch (System.Exception e)
     {
         Debug.LogError(e);
         return(new Dictionary <ProBuilderMesh, HashSet <Face> >());
     }
 }
        public static Dictionary <ProBuilderMesh, HashSet <Face> > PickFaces(Camera camera, Rect rect, Rect uiRect, GameObject[] gameObjects, bool depthTest)
        {
            try
            {
                if (depthTest)
                {
                    return(PBSelectionPicker.Renderer.PickFacesInRect(camera, rect, gameObjects.Select(g => g.GetComponent <ProBuilderMesh>()).Where(pbm => pbm != null).ToArray(), Mathf.RoundToInt(uiRect.width), Mathf.RoundToInt(uiRect.height)));
                }

                return(SelectionPicker.PickFacesInRect(camera, rect, gameObjects.Select(g => g.GetComponent <ProBuilderMesh>()).Where(pbm => pbm != null).ToArray(), new PickerOptions {
                    rectSelectMode = RectSelectMode.Partial, depthTest = false
                }, 1));
            }
            catch (System.Exception e)
            {
                Debug.LogError(e);
                return(new Dictionary <ProBuilderMesh, HashSet <Face> >());
            }
        }
        public static void DoMouseDrag(Rect mouseDragRect, SelectMode selectionMode, ScenePickerPreferences scenePickerPreferences)
        {
            var pickingOptions = new PickerOptions()
            {
                depthTest      = scenePickerPreferences.cullMode == CullingMode.Back,
                rectSelectMode = scenePickerPreferences.rectSelectMode
            };

            UndoUtility.RecordSelection("Drag Select");
            bool isAppendModifier = EditorHandleUtility.IsAppendModifier(Event.current.modifiers);

            if (!isAppendModifier)
            {
                MeshSelection.ClearElementSelection();
            }

            bool elementsInDragRect = false;

            switch (selectionMode)
            {
            case SelectMode.Vertex:
            case SelectMode.TextureVertex:
            {
                Dictionary <ProBuilderMesh, HashSet <int> > selected = SelectionPicker.PickVerticesInRect(
                    SceneView.lastActiveSceneView.camera,
                    mouseDragRect,
                    MeshSelection.topInternal,
                    pickingOptions,
                    EditorGUIUtility.pixelsPerPoint);

                foreach (var kvp in selected)
                {
                    var            mesh          = kvp.Key;
                    SharedVertex[] sharedIndexes = mesh.sharedVerticesInternal;
                    HashSet <int>  common;

                    if (isAppendModifier)
                    {
                        common = mesh.GetSharedVertexHandles(mesh.selectedIndexesInternal);

                        if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add)
                        {
                            common.UnionWith(kvp.Value);
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract)
                        {
                            common.RemoveWhere(x => kvp.Value.Contains(x));
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference)
                        {
                            common.SymmetricExceptWith(kvp.Value);
                        }
                    }
                    else
                    {
                        common = kvp.Value;
                    }

                    elementsInDragRect |= kvp.Value.Any();
                    mesh.SetSelectedVertices(common.SelectMany(x => sharedIndexes[x]));
                }

                break;
            }

            case SelectMode.Face:
            case SelectMode.TextureFace:
            {
                Dictionary <ProBuilderMesh, HashSet <Face> > selected = SelectionPicker.PickFacesInRect(
                    SceneView.lastActiveSceneView.camera,
                    mouseDragRect,
                    MeshSelection.topInternal,
                    pickingOptions,
                    EditorGUIUtility.pixelsPerPoint);

                foreach (var kvp in selected)
                {
                    HashSet <Face> current;

                    if (isAppendModifier)
                    {
                        current = new HashSet <Face>(kvp.Key.selectedFacesInternal);

                        if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add)
                        {
                            current.UnionWith(kvp.Value);
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract)
                        {
                            current.RemoveWhere(x => kvp.Value.Contains(x));
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference)
                        {
                            current.SymmetricExceptWith(kvp.Value);
                        }
                    }
                    else
                    {
                        current = kvp.Value;
                    }

                    elementsInDragRect |= kvp.Value.Any();
                    kvp.Key.SetSelectedFaces(current);
                }

                break;
            }

            case SelectMode.Edge:
            case SelectMode.TextureEdge:
            {
                var selected = SelectionPicker.PickEdgesInRect(
                    SceneView.lastActiveSceneView.camera,
                    mouseDragRect,
                    MeshSelection.topInternal,
                    pickingOptions,
                    EditorGUIUtility.pixelsPerPoint);

                foreach (var kvp in selected)
                {
                    ProBuilderMesh        mesh          = kvp.Key;
                    Dictionary <int, int> common        = mesh.sharedVertexLookup;
                    HashSet <EdgeLookup>  selectedEdges = EdgeLookup.GetEdgeLookupHashSet(kvp.Value, common);
                    HashSet <EdgeLookup>  current;

                    if (isAppendModifier)
                    {
                        current = EdgeLookup.GetEdgeLookupHashSet(mesh.selectedEdges, common);

                        if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Add)
                        {
                            current.UnionWith(selectedEdges);
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Subtract)
                        {
                            current.RemoveWhere(x => selectedEdges.Contains(x));
                        }
                        else if (scenePickerPreferences.selectionModifierBehavior == SelectionModifierBehavior.Difference)
                        {
                            current.SymmetricExceptWith(selectedEdges);
                        }
                    }
                    else
                    {
                        current = selectedEdges;
                    }

                    elementsInDragRect |= kvp.Value.Any();
                    mesh.SetSelectedEdges(current.Select(x => x.local));
                }

                break;
            }
            }

            // if nothing was selected in the drag rect, clear the object selection too
            if (!elementsInDragRect && !isAppendModifier)
            {
                MeshSelection.ClearElementAndObjectSelection();
            }

            ProBuilderEditor.Refresh();
            SceneView.RepaintAll();
        }
Example #5
0
        private static void PickProBuilderElementsNonAlloc(List <ProbeHit> hits, List <ProBuilderMesh> meshes, SceneView sceneView, Vector2 guiPosition)
        {
            var screenPosition = HandleUtility.GUIPointToScreenPixelCoordinate(guiPosition);
            var worldPosition  = sceneView.camera.ScreenToWorldPoint(screenPosition);

            var pickRadius = PeekPlugin.Configuration.probeProBuilderRadius;

            var pickerOptions = PickerOptions.Default;

            pickerOptions.depthTest = PeekPlugin.Configuration.probeProBuilderDepthTest;

            var pickRect = new Rect
                           (
                guiPosition.x - pickRadius,
                guiPosition.y - pickRadius,
                2 * pickRadius,
                2 * pickRadius
                           );

            var verticesByMeshes = SelectionPicker.PickVerticesInRect(sceneView.camera, pickRect, meshes, pickerOptions, EditorGUIUtility.pixelsPerPoint);

            var edgesByMeshes = SelectionPicker.PickEdgesInRect(sceneView.camera, pickRect, meshes, pickerOptions, EditorGUIUtility.pixelsPerPoint);

            var facesByMeshes = SelectionPicker.PickFacesInRect(sceneView.camera, pickRect, meshes, pickerOptions, EditorGUIUtility.pixelsPerPoint);

            foreach (var verticesByMesh in verticesByMeshes)
            {
                var mesh           = verticesByMesh.Key;
                var gameObject     = mesh.gameObject;
                var vertices       = verticesByMesh.Value;
                var meshVertices   = mesh.GetVertices();
                var sharedVertices = mesh.sharedVertices;

                foreach (var vertexIndex in vertices)
                {
                    var hit = new ProbeHit(gameObject);

                    var vertex            = meshVertices[vertexIndex];
                    var sharedVertex      = sharedVertices[vertexIndex];
                    var sharedVertexIndex = sharedVertex[0];
                    hit.point    = vertex.position;
                    hit.distance = Vector3.Distance(vertex.position, worldPosition);

                    hit.label      = $"{mesh.name}: Vertex {vertexIndex}";
                    hit.icon       = PeekProBuilderIntegration.Icons.vertex;
                    hit.groupOrder = 1;

                    hit.selectHandler = (add) =>
                    {
                        Selection.activeGameObject = gameObject;

                        ProBuilderEditor.selectMode = SelectMode.Vertex;

                        Undo.RecordObject(mesh, "Selection Change");

                        if (add)
                        {
                            mesh.SetSelectedVertices(mesh.selectedVertices.Concat(sharedVertex));
                        }
                        else
                        {
                            mesh.SetSelectedVertices(sharedVertex);
                        }

                        PeekProBuilderIntegration.UpdateSelection();
                    };

                    hit.focusHandler     = () => ProBuilderHighlight(new SceneSelection(mesh, sharedVertexIndex));
                    hit.lostFocusHandler = ClearProBuilderHighlight;

                    hits.Add(hit);
                }
            }

            foreach (var edgesByMesh in edgesByMeshes)
            {
                var mesh           = edgesByMesh.Key;
                var gameObject     = mesh.gameObject;
                var edges          = edgesByMesh.Value;
                var meshVertices   = mesh.GetVertices();
                var sharedVertices = mesh.sharedVertices;

                var visited = HashSetPool <(int, int)> .New();

                foreach (var edge in edges)
                {
                    var hit = new ProbeHit(gameObject);

                    var vertexA = meshVertices[edge.a];
                    var vertexB = meshVertices[edge.b];
                    var center  = (vertexA.position + vertexB.position) / 2;

                    var sharedVertexIndexA = -1;
                    var sharedVertexIndexB = -1;

                    for (var currentSharedIndex = 0; currentSharedIndex < sharedVertices.Count; currentSharedIndex++)
                    {
                        var sharedVertex = sharedVertices[currentSharedIndex];

                        if (sharedVertex.Contains(edge.a))
                        {
                            sharedVertexIndexA = currentSharedIndex;
                        }

                        if (sharedVertex.Contains(edge.b))
                        {
                            sharedVertexIndexB = currentSharedIndex;
                        }
                    }

                    var sharedVertexIndexMin = Mathf.Min(sharedVertexIndexA, sharedVertexIndexB);
                    var sharedVertexIndexMax = Mathf.Max(sharedVertexIndexA, sharedVertexIndexB);

                    if (visited.Contains((sharedVertexIndexMin, sharedVertexIndexMax)))
                    {
                        continue;
                    }

                    hit.point      = center;
                    hit.distance   = Vector3.Distance(center, worldPosition);
                    hit.label      = $"{mesh.name}: Edge [{sharedVertexIndexMin}, {sharedVertexIndexMax}]";
                    hit.icon       = PeekProBuilderIntegration.Icons.edge;
                    hit.groupOrder = 2;

                    hit.selectHandler = (add) =>
                    {
                        Selection.activeGameObject = gameObject;

                        ProBuilderEditor.selectMode = SelectMode.Edge;

                        Undo.RecordObject(mesh, "Selection Change");

                        if (add)
                        {
                            mesh.SetSelectedEdges(mesh.selectedEdges.Append(edge));
                        }
                        else
                        {
                            mesh.SetSelectedEdges(edge.Yield());
                        }

                        PeekProBuilderIntegration.UpdateSelection();
                    };

                    hit.focusHandler     = () => ProBuilderHighlight(new SceneSelection(mesh, edge));
                    hit.lostFocusHandler = ClearProBuilderHighlight;

                    hits.Add(hit);

                    visited.Add((sharedVertexIndexMin, sharedVertexIndexMax));
                }

                visited.Free();
            }

            foreach (var facesByMesh in facesByMeshes)
            {
                var mesh         = facesByMesh.Key;
                var gameObject   = mesh.gameObject;
                var faces        = facesByMesh.Value;
                var meshVertices = mesh.GetVertices();
                var meshFaces    = mesh.faces;

                foreach (var face in faces)
                {
                    var faceIndex = meshFaces.IndexOf(face);

                    var hit = new ProbeHit(gameObject);

                    var center = Vector3.zero;

                    foreach (var vertexIndex in face.distinctIndexes)
                    {
                        var vertex = meshVertices[vertexIndex];
                        center += vertex.position;
                    }

                    center /= face.distinctIndexes.Count;

                    hit.point    = center;
                    hit.distance = Vector3.Distance(center, worldPosition);

                    hit.label      = $"{mesh.name}: Face {faceIndex}";
                    hit.icon       = PeekProBuilderIntegration.Icons.face;
                    hit.groupOrder = 3;

                    hit.selectHandler = (add) =>
                    {
                        Selection.activeGameObject = gameObject;

                        ProBuilderEditor.selectMode = SelectMode.Face;

                        Undo.RecordObject(mesh, "Selection Change");

                        if (add)
                        {
                            mesh.SetSelectedFaces(mesh.GetSelectedFaces().Append(face));
                        }
                        else
                        {
                            mesh.SetSelectedFaces(null);
                            mesh.SetSelectedFaces(face.Yield());
                        }

                        PeekProBuilderIntegration.UpdateSelection();
                    };

                    hit.focusHandler     = () => ProBuilderHighlight(new SceneSelection(mesh, face));
                    hit.lostFocusHandler = ClearProBuilderHighlight;

                    hits.Add(hit);
                }
            }
        }
 public static Dictionary <ProBuilderMesh, HashSet <Edge> > PickEdges(Camera camera, Rect rect, GameObject[] gameObjects)
 {
     return(SelectionPicker.PickEdgesInRect(camera, rect, gameObjects.Select(g => g.GetComponent <ProBuilderMesh>()).Where(pbm => pbm != null).ToArray(), new PickerOptions {
         rectSelectMode = RectSelectMode.Partial, depthTest = false
     }));
 }