public static Dictionary <ProBuilderMesh, HashSet <int> > PickVerticesInRect(
            Camera cam,
            Rect rect,
            Rect uiRootRect,
            IList <ProBuilderMesh> selectable,
            PickerOptions options,
            float pixelsPerPoint = 1f)
        {
            if (options.depthTest)
            {
                return(PBSelectionPickerRenderer.PickVerticesInRect(
                           cam,
                           rect,
                           selectable,
                           true,
                           (int)(uiRootRect.width / pixelsPerPoint),
                           (int)(uiRootRect.height / pixelsPerPoint)));
            }

            // while the selectionpicker render path supports no depth test picking, it's usually faster to skip
            // the render. also avoids issues with vertex billboards obscuring one another.
            var selected = new Dictionary <ProBuilderMesh, HashSet <int> >();

            foreach (var pb in selectable)
            {
                if (!pb.selectable)
                {
                    continue;
                }

                IList <SharedVertex> sharedIndexes = pb.sharedVertices;
                HashSet <int>        inRect        = new HashSet <int>();
                IList <Vector3>      positions     = pb.positions;
                var   trs         = pb.transform;
                float pixelHeight = uiRootRect.height;

                for (int n = 0; n < sharedIndexes.Count; n++)
                {
                    Vector3 v = trs.TransformPoint(positions[sharedIndexes[n][0]]);
                    Vector3 p = cam.WorldToScreenPoint(v);

                    if (p.z < cam.nearClipPlane)
                    {
                        continue;
                    }

                    p.x /= pixelsPerPoint;
                    p.y  = (pixelHeight - p.y) / pixelsPerPoint;

                    if (rect.Contains(p))
                    {
                        inRect.Add(n);
                    }
                }

                selected.Add(pb, inRect);
            }

            return(selected);
        }
Example #2
0
        public static Dictionary <ProBuilderMesh, HashSet <Face> > PickFaces(Camera camera, Rect rect, Rect uiRect, GameObject[] gameObjects, bool depthTest)
        {
            try
            {
                if (depthTest)
                {
                    return(PBSelectionPickerRenderer.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 Dictionary <ProBuilderMesh, HashSet <Edge> > PickEdgesInRect(
            Camera cam,
            Rect rect,
            Rect uiRootRect,
            IList <ProBuilderMesh> selectable,
            PickerOptions options,
            float pixelsPerPoint = 1f)
        {
            if (options.depthTest && options.rectSelectMode == RectSelectMode.Partial)
            {
                return(PBSelectionPickerRenderer.PickEdgesInRect(
                           cam,
                           rect,
                           selectable,
                           true,
                           (int)(uiRootRect.width / pixelsPerPoint),
                           (int)(uiRootRect.height / pixelsPerPoint)));
            }

            var selected = new Dictionary <ProBuilderMesh, HashSet <Edge> >();

            foreach (var pb in selectable)
            {
                if (!pb.selectable)
                {
                    continue;
                }

                Transform trs           = pb.transform;
                var       selectedEdges = new HashSet <Edge>();

                IList <Face>    faces     = pb.faces;
                IList <Vector3> positions = pb.positions;
                for (int i = 0, fc = pb.faceCount; i < fc; i++)
                {
                    var edges = faces[i].edges;

                    for (int n = 0, ec = edges.Count; n < ec; n++)
                    {
                        var edge = edges[n];

                        var posA = trs.TransformPoint(positions[edge.a]);
                        var posB = trs.TransformPoint(positions[edge.b]);

                        Vector3 a = ScreenToGuiPoint(uiRootRect, cam.WorldToScreenPoint(posA), pixelsPerPoint);
                        Vector3 b = ScreenToGuiPoint(uiRootRect, cam.WorldToScreenPoint(posB), pixelsPerPoint);

                        switch (options.rectSelectMode)
                        {
                        case RectSelectMode.Complete:
                        {
                            // if either of the positions are clipped by the camera we cannot possibly select both, skip it
                            if ((a.z < cam.nearClipPlane || b.z < cam.nearClipPlane))
                            {
                                continue;
                            }

                            if (rect.Contains(a) && rect.Contains(b))
                            {
                                if (!options.depthTest || !PBUtility.PointIsOccluded(cam, pb, (posA + posB) * .5f))
                                {
                                    selectedEdges.Add(edge);
                                }
                            }

                            break;
                        }

                        case RectSelectMode.Partial:
                        {
                            // partial + depth test is covered earlier
                            if (RectIntersectsLineSegment(rect, a, b))
                            {
                                selectedEdges.Add(edge);
                            }

                            break;
                        }
                        }
                    }
                }

                selected.Add(pb, selectedEdges);
            }

            return(selected);
        }