Пример #1
0
        void ApplyClipPlane(bool keepBothSides)
        {
            List <Object> newObjects = new List <Object>();

            foreach (PrimitiveBrush brush in targetBrushes)
            {
                if (brush != null)
                {
                    // Recalculate the clip plane from the world points, converting to local space for this transform
                    Plane localClipPlane;

                    // If the user has specified to flip the plane, flip the plane we just calculated
                    if (isFlipped)
                    {
                        localClipPlane = new Plane(brush.transform.InverseTransformPoint(points[0]),
                                                   brush.transform.InverseTransformPoint(points[1]),
                                                   brush.transform.InverseTransformPoint(points[2]));
                    }
                    else
                    {
                        localClipPlane = new Plane(brush.transform.InverseTransformPoint(points[2]),
                                                   brush.transform.InverseTransformPoint(points[1]),
                                                   brush.transform.InverseTransformPoint(points[0]));
                    }

                    if (keepBothSides)
                    {
                        Undo.RecordObject(brush, "Split Brush");
                        Undo.RecordObject(brush.transform, "Split Brush");
                    }
                    else
                    {
                        Undo.RecordObject(brush, "Clipped Brush");
                        Undo.RecordObject(brush.transform, "Clipped Brush");
                    }

                    GameObject newObject = ClipUtility.ApplyClipPlane(brush, localClipPlane, keepBothSides);

                    if (keepBothSides && newObject != null)
                    {
                        Undo.RegisterCreatedObjectUndo(newObject, "Split Brush");
                        newObjects.Add(newObject);
                    }
                }
            }

            // Add any new objects to the selection
            if (newObjects.Count > 0)
            {
                // First of all add the existing selection to the start of the new objects list
                newObjects.InsertRange(0, Selection.objects);
                // Then replace the selected objects with the new objects list in array form
                Selection.objects = newObjects.ToArray();
            }
        }
Пример #2
0
        public static void SplitIntersecting(PrimitiveBrush[] brushes)
        {
            List <Brush> intersections = new List <Brush>();

            foreach (PrimitiveBrush brush in brushes)
            {
                intersections.AddRange(brush.BrushCache.IntersectingVisualBrushes);
            }

            foreach (PrimitiveBrush brush in brushes)
            {
                List <PrimitiveBrush> newBrushes = new List <PrimitiveBrush>();

                foreach (Brush intersectingBrush in intersections)
                {
                    PrimitiveBrush brushToClip = (PrimitiveBrush)intersectingBrush;

                    Polygon[] polygons = brush.GetPolygons();

                    // A brush may have several polygons that share a plane, find all the distinct polygon planes
                    List <Plane> distinctPlanes = new List <Plane>();

                    for (int polygonIndex = 0; polygonIndex < polygons.Length; polygonIndex++)
                    {
                        Polygon polygon = polygons[polygonIndex];
                        Vertex  vertex1, vertex2, vertex3;
                        SurfaceUtility.GetPrimaryPolygonDescribers(polygon, out vertex1, out vertex2, out vertex3);

                        Vector3 position1 = vertex1.Position;
                        Vector3 position2 = vertex2.Position;
                        Vector3 position3 = vertex3.Position;

                        // Transform from local to brush to local to intersectingBrush
                        position1 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position1));
                        position2 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position2));
                        position3 = intersectingBrush.transform.InverseTransformPoint(brush.transform.TransformPoint(position3));

                        // Calculate plane in intersectingBrush's local space
                        Plane polygonPlane = new Plane(position1, position2, position3);

                        bool found = false;
                        // See if it already exists
                        for (int i = 0; i < distinctPlanes.Count; i++)
                        {
                            if (MathHelper.PlaneEqualsLooser(distinctPlanes[i], polygonPlane))
                            {
                                found = true;
                                break;
                            }
                        }

                        // Not added to an existing group, so add new
                        if (!found)
                        {
                            // Add a new group for the polygon
                            distinctPlanes.Add(polygonPlane);
                        }
                    }

                    foreach (Plane clipPlane in distinctPlanes)
                    {
#if UNITY_EDITOR
                        UnityEditor.Undo.RecordObject(brushToClip, "Split Intersecting Brushes");
                        UnityEditor.Undo.RecordObject(brushToClip.transform, "Split Intersecting Brushes");
#endif

                        GameObject newObject = ClipUtility.ApplyClipPlane(brushToClip, clipPlane, true, false);

                        if (newObject != null)
                        {
#if UNITY_EDITOR
                            UnityEditor.Undo.RegisterCreatedObjectUndo(newObject, "Split Intersecting Brushes");
#endif
                            newBrushes.Add(newObject.GetComponent <PrimitiveBrush>());
                        }
                    }

                    brushToClip.ResetPivot();
                }

                foreach (PrimitiveBrush newBrush in newBrushes)
                {
                    newBrush.ResetPivot();
                }

                intersections.AddRange(newBrushes.ConvertAll <Brush>(item => (Brush)item));
            }
        }