Exemple #1
0
        public List <BrushBase> ExtractBrushBases(List <Brush> sourceBrushes)
        {
            // Generate a list of editable brushes (in the case of compound brush's child brushes this would be the root controller)
            List <BrushBase> brushBases = new List <BrushBase>();

            for (int i = 0; i < sourceBrushes.Count; i++)
            {
                if (sourceBrushes[i].GetType() == typeof(PrimitiveBrush))
                {
                    // Get any controller (e.g. compound brush) that is driving the selected brush
                    BrushBase controller = ((PrimitiveBrush)sourceBrushes[i]).BrushController;
                    if (controller != null)
                    {
                        // Controller found, add it instead if it's not already in the list
                        if (!brushBases.Contains(controller))
                        {
                            brushBases.Add(controller);
                        }
                    }
                    else
                    {
                        // No controller found just add the brush
                        brushBases.Add(sourceBrushes[i]);
                    }
                }
                else
                {
                    // Not a primitive brush, so just add it
                    brushBases.Add(sourceBrushes[i]);
                }
            }
            return(brushBases);
        }
Exemple #2
0
        /// <summary>
        /// Overrides the built in selection duplication to maintain sibling order of the selection. But only if at least one of the selection is under a CSG Model.
        /// </summary>
        /// <returns><c>true</c>, if our custom duplication took place (and one of the selection was under a CSG Model), <c>false</c> otherwise in which case the duplication event should not be consumed so that Unity will duplicate for us.</returns>
        public static bool DuplicateSelection()
        {
            List <Transform> selectedTransforms = Selection.transforms.ToList();

            // Whether any of the selection objects are under a CSG Model
            bool shouldCustomDuplicationOccur = false;

            for (int i = 0; i < selectedTransforms.Count; i++)
            {
                if (selectedTransforms[i].GetComponentInParent <CSGModel>() != null)
                {
                    shouldCustomDuplicationOccur = true;
                }
            }

            if (shouldCustomDuplicationOccur)            // Some of the objects are under a CSG Model, so peform our special duplication override
            {
                // Sort the selected transforms in order of sibling index
                selectedTransforms.Sort((x, y) => x.GetSiblingIndex().CompareTo(y.GetSiblingIndex()));
                GameObject[] newObjects = new GameObject[Selection.gameObjects.Length];

                // Walk through each selected object in the correct order, duplicating them one by one
                for (int i = 0; i < selectedTransforms.Count; i++)
                {
                    // Temporarily set the selection to the single entry
                    Selection.activeGameObject = selectedTransforms[i].gameObject;
                    // Seems to be a bug in Unity where we need to set the objects array too otherwise it won't be set straight away
                    Selection.objects = new Object[] { selectedTransforms[i].gameObject };

                    // Duplicate the single entry
                    Unsupported.DuplicateGameObjectsUsingPasteboard();
                    // Cache the new entry, so when we're done we reselect all new objects
                    newObjects[i] = Selection.activeGameObject;
                    // Remove the 'Brush (1)', 'Brush (2)', etc. from the name.
                    newObjects[i].name = Regex.Replace(newObjects[i].name, " \\(\\d+\\)$", "");

                    // If we are dealing with a brush, properly duplicate the volume type.
                    BrushBase brush = newObjects[i].GetComponent <BrushBase>();
                    if (brush != null && brush.Volume != null)
                    {
                        brush.Volume = ScriptableObject.Instantiate(brush.Volume);
                        brush.RebuildVolume();
                    }
                }
                // Finished duplicating, select all new objects
                Selection.objects = newObjects;
            }

            // Whether custom duplication took place and whether the Duplicate event should be consumed
            return(shouldCustomDuplicationOccur);
        }
Exemple #3
0
        protected override void Update()
        {
            base.Update();
            // encapsulate all of the child objects in our bounds.
            Bounds csgBounds = new Bounds();

            foreach (Transform childTransform in transform)
            {
                BrushBase child = childTransform.GetComponent <BrushBase>();
                if (child == null)
                {
                    continue;
                }
                csgBounds.Encapsulate(child.GetBoundsLocalTo(transform));
            }
            // apply the generated csg bounds.
            localBounds = csgBounds;
            // update the generated name in the hierarchy.
            UpdateGeneratedHierarchyName();
        }
Exemple #4
0
        public override void Invalidate(bool polygonsChanged)
        {
            ////////////////////////////////////////////////////////////////////
            // a little hack to detect the user manually resizing the bounds. //
            // we use this to automatically add steps for barnaby.            //
            // it's probably good to build a more 'official' way to detect    //
            // user scaling events in compound brushes sometime.              //
            if (m_LastKnownExtents != localBounds.extents)                    //
            {                                                                 //
                // undo any position movement.                                //
                transform.localPosition = m_LastKnownPosition;                //
            }                                                                 //
            ////////////////////////////////////////////////////////////////////
            Bounds csgBounds = new Bounds();

            // nothing to do except copy csg information to our child brushes.
            foreach (Transform childTransform in transform)
            {
                BrushBase child = childTransform.GetComponent <BrushBase>();
                if (child == null)
                {
                    continue;
                }

                // we do not override these properties in a group.
                // it wouldn't make much sense and break whatever the user grouped.
                //child.Mode = this.Mode;
                //child.IsNoCSG = this.IsNoCSG;
                //child.IsVisible = this.IsVisible;
                //child.HasCollision = this.HasCollision;
                child.Invalidate(polygonsChanged);
                csgBounds.Encapsulate(child.GetBoundsLocalTo(transform));
            }
            // apply the generated csg bounds.
            localBounds         = csgBounds;
            m_LastKnownExtents  = localBounds.extents;
            m_LastKnownPosition = transform.localPosition;
            // update name in hierarchy.
            base.Invalidate(polygonsChanged);
        }
Exemple #5
0
 public void SetBrushController(BrushBase brushController)
 {
     this.brushController = brushController;
 }
Exemple #6
0
        private static void OnBottomToolbarGUI(int windowID)
        {
            GUILayout.BeginHorizontal();

            GUIStyle createBrushStyle = new GUIStyle(EditorStyles.toolbarButton);

            createBrushStyle.fixedHeight = 20;
            if (GUI.Button(new Rect(0, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCubeTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cube);
            }

            if (GUI.Button(new Rect(30, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonPrismTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Prism);
            }

            //if(GUI.Button(new Rect(60,0, 30, createBrushStyle.fixedHeight), "", createBrushStyle))
            //{
            //}

            if (GUI.Button(new Rect(60, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonStairsTexture, createBrushStyle))
            {
                CreateCompoundBrush <StairBrush>();
            }

            if (GUI.Button(new Rect(90, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCurvedStairsTexture, createBrushStyle))
            {
                CreateCompoundBrush <CurvedStairBrush>();
            }

            GUILayout.Space(92 + 30);
#if DEBUG_SABRECSG_PERF
            // For debugging frame rate
            GUILayout.Label(((int)(1 / csgModel.CurrentFrameDelta)).ToString(), SabreGUILayout.GetLabelStyle());
#endif

            if (SabreGUILayout.Button("Rebuild"))
            {
                csgModel.Build(false, false);
            }

            if (SabreGUILayout.Button("Force Rebuild"))
            {
                csgModel.Build(true, false);
            }

            GUI.color = Color.white;

            if (csgModel.AutoRebuild)
            {
                GUI.color = Color.green;
            }
            csgModel.AutoRebuild = SabreGUILayout.Toggle(csgModel.AutoRebuild, "Auto Rebuild");
            GUI.color            = Color.white;

            GUILayout.Label(csgModel.BuildMetrics.BuildMetaData.ToString(), SabreGUILayout.GetForeStyle(), GUILayout.Width(140));

            bool lastBrushesHidden = CurrentSettings.BrushesHidden;
            if (lastBrushesHidden)
            {
                GUI.color = Color.red;
            }
            CurrentSettings.BrushesHidden = SabreGUILayout.Toggle(CurrentSettings.BrushesHidden, "Brushes Hidden");
            if (CurrentSettings.BrushesHidden != lastBrushesHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }
            GUI.color = Color.white;


            bool lastMeshHidden = CurrentSettings.MeshHidden;
            if (lastMeshHidden)
            {
                GUI.color = Color.red;
            }
            CurrentSettings.MeshHidden = SabreGUILayout.Toggle(CurrentSettings.MeshHidden, "Mesh Hidden");
            if (CurrentSettings.MeshHidden != lastMeshHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }

            GUI.color = Color.white;


            if (GUILayout.Button("Grid " + CurrentSettings.GridMode.ToString(), EditorStyles.toolbarDropDown, GUILayout.Width(90)))
            {
                GenericMenu menu = new GenericMenu();

                string[] names = Enum.GetNames(typeof(GridMode));

                for (int i = 0; i < names.Length; i++)
                {
                    GridMode value    = (GridMode)Enum.Parse(typeof(GridMode), names[i]);
                    bool     selected = false;
                    if (CurrentSettings.GridMode == value)
                    {
                        selected = true;
                    }
                    menu.AddItem(new GUIContent(names[i]), selected, OnSelectedGridOption, value);
                }

                menu.DropDown(gridRect);
            }

            if (Event.current.type == EventType.Repaint)
            {
                gridRect       = GUILayoutUtility.GetLastRect();
                gridRect.width = 100;
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            // Line Two
            GUILayout.BeginHorizontal();

            if (GUI.Button(new Rect(0, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCylinderTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cylinder);
            }

            if (GUI.Button(new Rect(30, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonSphereTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Sphere);
            }

            if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonConeTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cone);
            }

            //if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "", createBrushStyle))
            //{
            //}

            if (GUI.Button(new Rect(90, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "...", createBrushStyle))
            {
                GenericMenu menu = new GenericMenu();

                List <Type> compoundBrushTypes = CompoundBrush.FindAllInAssembly();
                for (int i = 0; i < compoundBrushTypes.Count; i++)
                {
                    menu.AddItem(new GUIContent(compoundBrushTypes[i].Name), false, CreateCompoundBrush, compoundBrushTypes[i]);
                }

                menu.DropDown(new Rect(60, createBrushStyle.fixedHeight, 100, createBrushStyle.fixedHeight));
            }

            GUILayout.Space(92 + 30);

            // Display brush count
            GUILayout.Label(csgModel.BrushCount.ToStringWithSuffix(" brush", " brushes"), SabreGUILayout.GetLabelStyle());
//			CurrentSettings.GridMode = (GridMode)EditorGUILayout.EnumPopup(CurrentSettings.GridMode, EditorStyles.toolbarPopup, GUILayout.Width(80));

            if (Selection.activeGameObject != null)
            {
                BrushBase        primaryBrush = Selection.activeGameObject.GetComponent <BrushBase>();
                List <BrushBase> brushes      = new List <BrushBase>();
                for (int i = 0; i < Selection.gameObjects.Length; i++)
                {
                    BrushBase brush = Selection.gameObjects[i].GetComponent <BrushBase>();
                    if (brush != null)
                    {
                        brushes.Add(brush);
                    }
                }
                if (primaryBrush != null)
                {
                    CSGMode brushMode = (CSGMode)EditorGUILayout.EnumPopup(primaryBrush.Mode, EditorStyles.toolbarPopup, GUILayout.Width(80));
                    if (brushMode != primaryBrush.Mode)
                    {
                        bool anyChanged = false;

                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush To " + brushMode);
                            brush.Mode = brushMode;
                            anyChanged = true;
                        }
                        if (anyChanged)
                        {
                            // Need to update the icon for the csg mode in the hierarchy
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }


                    bool[] noCSGStates = brushes.Select(brush => brush.IsNoCSG).Distinct().ToArray();
                    bool   isNoCSG     = (noCSGStates.Length == 1) ? noCSGStates[0] : false;

                    bool newIsNoCSG = SabreGUILayout.ToggleMixed(noCSGStates, "NoCSG", GUILayout.Width(53));


                    bool[] collisionStates = brushes.Select(item => item.HasCollision).Distinct().ToArray();
                    bool   hasCollision    = (collisionStates.Length == 1) ? collisionStates[0] : false;

                    bool newHasCollision = SabreGUILayout.ToggleMixed(collisionStates, "Collision", GUILayout.Width(53));


                    bool[] visibleStates = brushes.Select(item => item.IsVisible).Distinct().ToArray();
                    bool   isVisible     = (visibleStates.Length == 1) ? visibleStates[0] : false;

                    bool newIsVisible = SabreGUILayout.ToggleMixed(visibleStates, "Visible", GUILayout.Width(53));

                    if (newIsNoCSG != isNoCSG)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush NoCSG Mode");
                            brush.IsNoCSG = newIsNoCSG;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }

                        EditorApplication.RepaintHierarchyWindow();
                    }
                    if (newHasCollision != hasCollision)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush Collision Mode");
                            brush.HasCollision = newHasCollision;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }
                    }
                    if (newIsVisible != isVisible)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush Visible Mode");
                            brush.IsVisible = newIsVisible;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }
                        if (newIsVisible == false)
                        {
                            csgModel.NotifyPolygonsRemoved();
                        }
                    }
                }
            }

            GUILayout.Space(10);

            // Position snapping UI
            CurrentSettings.PositionSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.PositionSnappingEnabled, "Pos Snapping");
            CurrentSettings.PositionSnapDistance    = EditorGUILayout.FloatField(CurrentSettings.PositionSnapDistance, GUILayout.Width(50));

            if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft))
            {
                CurrentSettings.ChangePosSnapDistance(.5f);
            }
            if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight))
            {
                CurrentSettings.ChangePosSnapDistance(2f);
            }

            // Rotation snapping UI
            CurrentSettings.AngleSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.AngleSnappingEnabled, "Ang Snapping");
            CurrentSettings.AngleSnapDistance    = EditorGUILayout.FloatField(CurrentSettings.AngleSnapDistance, GUILayout.Width(50));

            if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft))
            {
                if (CurrentSettings.AngleSnapDistance > 15)
                {
                    CurrentSettings.AngleSnapDistance -= 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance -= 5;
                }
            }
            if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight))
            {
                if (CurrentSettings.AngleSnapDistance >= 15)
                {
                    CurrentSettings.AngleSnapDistance += 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance += 5;
                }
            }

            GUILayout.FlexibleSpace();

            if (SabreGUILayout.Button("Prefs"))
            {
                SabreCSGPreferences.CreateAndShow();
            }

            if (SabreGUILayout.Button("Disable"))
            {
                Selection.activeGameObject = null;
                csgModel.EditMode          = false;
            }

            GUILayout.EndHorizontal();
        }
Exemple #7
0
        public void SetSelection(GameObject selectedGameObject, GameObject[] selectedGameObjects)
        {
            // Find the selected brush bases
            List <BrushBase> brushBases = new List <BrushBase>();

            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                BrushBase matchedBrushBase = Selection.gameObjects[i].GetComponent <BrushBase>();

                // If we've selected a brush base that isn't a prefab in the project
                if (matchedBrushBase != null
#if UNITY_2018_2_OR_NEWER
                    && !(PrefabUtility.GetCorrespondingObjectFromSource(matchedBrushBase.gameObject) == null
#else
                    && !(PrefabUtility.GetPrefabParent(matchedBrushBase.gameObject) == null
#endif
#if !UNITY_2018_3_OR_NEWER
                         && PrefabUtility.GetPrefabObject(matchedBrushBase.transform) != null))
#else
                         && PrefabUtility.GetPrefabInstanceHandle(selectedGameObject.transform) != null))
#endif
                {
                    brushBases.Add(matchedBrushBase);
                }
            }

            // Also find an array of brushes (brush bases that aren't primitive brushes will have a null entry)
            PrimitiveBrush[] primitiveBrushes = brushBases.Select(item => item.GetComponent <PrimitiveBrush>()).ToArray();

            // Pick out the first brush base and primitive brush (or null if none)
            BrushBase      newPrimaryBrushBase = null;
            PrimitiveBrush newPrimaryBrush     = null;

            // Make sure it's not null and that it isn't a prefab in the project
            if (selectedGameObject != null
#if UNITY_2018_2_OR_NEWER
                && !(PrefabUtility.GetCorrespondingObjectFromSource(selectedGameObject) == null
#else
                && !(PrefabUtility.GetPrefabParent(selectedGameObject) == null
#endif
#if !UNITY_2018_3_OR_NEWER
                     && PrefabUtility.GetPrefabObject(selectedGameObject.transform) != null))
#else
                     && PrefabUtility.GetPrefabInstanceHandle(selectedGameObject.transform) != null))
#endif
            {
                newPrimaryBrushBase = selectedGameObject.GetComponent <BrushBase>();               // brushBases.FirstOrDefault();
                newPrimaryBrush     = selectedGameObject.GetComponent <PrimitiveBrush>();          // primitiveBrushes.Where(item => item != null).FirstOrDefault();
            }

            // If the primary brush base has changed
            if (primaryTargetBrushBase != newPrimaryBrushBase ||
                (primaryTargetBrushBase == null && newPrimaryBrushBase != null))                    // Special case for undo where references are equal but one is null
            {
                primaryTargetBrushBase = newPrimaryBrushBase;

                if (newPrimaryBrushBase != null)
                {
                    primaryTargetBrushTransform = newPrimaryBrushBase.transform;
                }
                else
                {
                    primaryTargetBrushTransform = null;
                }

                ResetTool();
            }

            BrushBase[] brushBasesArray = brushBases.ToArray();
            primaryTargetBrush = newPrimaryBrush;

            if (!targetBrushBases.ContentsEquals(brushBasesArray))
            {
                OnSelectionChanged();
                targetBrushBases      = brushBasesArray;
                targetBrushes         = primitiveBrushes;
                targetBrushTransforms = new Transform[brushBasesArray.Length];
                for (int i = 0; i < brushBasesArray.Length; i++)
                {
                    if (brushBasesArray[i] != null)
                    {
                        targetBrushTransforms[i] = brushBasesArray[i].transform;
                    }
                    else
                    {
                        targetBrushTransforms[i] = null;
                    }
                }
            }
        }
        /// <summary>
        /// Flips brushes along the provided axis
        /// </summary>
        /// <param name="primaryTargetBrush">The brush considered to be the pivot brush, for use when localToPrimaryBrush is true</param>
        /// <param name="targetBrushes">All brushes to be flipped</param>
        /// <param name="axisIndex">Index of the axis component to flip along, 0 = X, 1 = Y, 2 = Z</param>
        /// <param name="localToPrimaryBrush">Whether the axis to flip in is local to the primary brush's rotation, if false global orientation is used</param>
        /// <param name="flipCenter">The point in world space at which to flip the geometry around</param>
        public static void Flip(BrushBase primaryTargetBrush, BrushBase[] targetBrushes, int axisIndex, bool localToPrimaryBrush, Vector3 flipCenter)
        {
            foreach (Brush brush in targetBrushes)
            {
                Polygon[] polygons = brush.GetPolygons();

                for (int i = 0; i < polygons.Length; i++)
                {
                    for (int j = 0; j < polygons[i].Vertices.Length; j++)
                    {
                        Vertex vertex = polygons[i].Vertices[j];

                        Vector3 position = vertex.Position;
                        Vector3 normal   = vertex.Normal;

                        if (localToPrimaryBrush)
                        {
                            // Rotate the position and normal to be relative to the primary brush's local space
                            position = primaryTargetBrush.transform.InverseTransformDirection(brush.transform.TransformDirection(position));
                            normal   = primaryTargetBrush.transform.InverseTransformDirection(brush.transform.TransformDirection(normal));
                        }
                        else
                        {
                            // Rotate the position and normal to be relative to the global axis orientation
                            position = brush.transform.TransformDirection(position);
                            normal   = brush.transform.TransformDirection(normal);
                        }

                        // Flip in relevant axis
                        position[axisIndex] = -position[axisIndex];
                        normal[axisIndex]   = -normal[axisIndex];

                        if (localToPrimaryBrush)
                        {
                            // Rotate the position and normal from the primary brush's local space back to the brush's local space
                            position = brush.transform.InverseTransformDirection(primaryTargetBrush.transform.TransformDirection(position));
                            normal   = brush.transform.InverseTransformDirection(primaryTargetBrush.transform.TransformDirection(normal));
                        }
                        else
                        {
                            // Rotate the position and normal from the global axis orientation back to the brush's original local space
                            position = brush.transform.InverseTransformDirection(position);
                            normal   = brush.transform.InverseTransformDirection(normal);
                        }

                        // Set the vertex position and normal to their new values
                        vertex.Position = position;
                        vertex.Normal   = normal;
                    }
                    // Because a flip has occurred we need to reverse the winding order
                    Array.Reverse(polygons[i].Vertices);
                    // Polygon plane has probably changed so it should now be recalculated
                    polygons[i].CalculatePlane();
                }

                if (targetBrushes.Length > 0) // Only need to move brushes if there's more than one
                {
                    // Calculate the difference between the brush position and the center of flipping
                    Vector3 deltaFromCenter = brush.transform.position - flipCenter;
                    if (localToPrimaryBrush)
                    {
                        // Rotate the delta so that it's in the primary brush's local space
                        deltaFromCenter = primaryTargetBrush.transform.InverseTransformDirection(deltaFromCenter);
                    }

                    // Negate the delta, so that the brush position will be flipped to the other side
                    deltaFromCenter[axisIndex] = -deltaFromCenter[axisIndex];

                    if (localToPrimaryBrush)
                    {
                        // Rotate the delta back to its original space
                        deltaFromCenter = primaryTargetBrush.transform.TransformDirection(deltaFromCenter);
                    }
                    // Set the brush's new position
                    brush.transform.position = flipCenter + deltaFromCenter;
                }
                // Notify the brush that it has changed
                brush.Invalidate(true);
            }
        }
        public sealed override void OnInspectorGUI()
        {
            // group editing:
            if (ShowGroupInspector)
            {
                using (new NamedVerticalScope("Group"))
                {
                    GUILayout.BeginHorizontal();

                    // find whether we are currently inside of a group:
                    GroupBrush group = null;
                    if (BrushTarget.transform.parent)
                    {
                        group = BrushTarget.transform.parent.GetComponent <GroupBrush>();
                    }

                    // we are in a group:
                    if (group != null)
                    {
                        if (GUILayout.Button("Select Group"))
                        {
                            // select the group.
                            Selection.objects = new Object[] { BrushTarget.transform.parent.gameObject };
                        }
                    }

                    if (GUILayout.Button("Create Group"))
                    {
                        // create a group.
                        TransformHelper.GroupSelection();
                    }

                    GUILayout.EndHorizontal();
                }
            }

            // volume editing:
            if (BrushTargets.Any(b => b.Mode == CSGMode.Volume))
            {
                using (new NamedVerticalScope("Volume"))
                {
                    // find all of the volume types in the project:
                    List <System.Type> volumeTypes = Volume.FindAllInAssembly();
                    if (volumeTypes.Count == 0)
                    {
                        EditorGUILayout.LabelField("No volume types could be found!");
                    }
                    else
                    {
                        // find all of the volume brushes that are currently selected.
                        BrushBase[] volumeBrushes = BrushTargets.Where(b => b.Mode == CSGMode.Volume).ToArray();
                        BrushBase   volumeTarget  = volumeBrushes.Contains(BrushTarget) ? BrushTarget : volumeBrushes.Last();

                        // make sure all volume brushes are of the same type (for multi-editing).
                        object brushTargetVolumeType = volumeTarget.Volume ? volumeTarget.Volume.GetType() : null;
                        if (volumeBrushes.Length > 1 && !volumeBrushes.All(b => b.Volume.GetType() == brushTargetVolumeType))
                        {
                            EditorGUILayout.LabelField("Cannot multi-edit volumes of different types!");
                        }
                        else
                        {
                            // let the user pick a volume type:
                            int selected = 0;
                            if (volumeTarget.Volume != null)
                            {
                                for (int i = 0; i < volumeTypes.Count; i++)
                                {
                                    selected = i;
                                    if (volumeTarget.Volume.GetType() == volumeTypes[i])
                                    {
                                        break;
                                    }
                                }
                            }
                            selected = EditorGUILayout.Popup("Volume Type", selected, volumeTypes.Select(v => v.Name + " (" + v.Namespace + ")").ToArray());

                            // set the brush volume type:
                            for (int i = 0; i < volumeBrushes.Length; i++)
                            {
                                BrushBase target = volumeBrushes[i];

                                // if the brush does not have a volume yet or the wrong one, create the selected type now:
                                if (target.Volume == null || target.Volume.GetType() != volumeTypes[selected])
                                {
                                    target.Volume = (Volume)ScriptableObject.CreateInstance(volumeTypes[selected]);
                                    if (serializedObject.targetObject != null)
                                    {
                                        serializedObject.ApplyModifiedProperties();
                                        System.Array.ForEach(volumeBrushes, item => item.Invalidate(true));
                                    }
                                }
                            }

                            // custom volume inspector:
                            if (volumeTarget.Volume.OnInspectorGUI(volumeBrushes.Select(b => b.Volume).ToArray()))
                            {
                                if (serializedObject.targetObject != null)
                                {
                                    serializedObject.ApplyModifiedProperties();
                                    System.Array.ForEach(volumeBrushes, item => item.Invalidate(true));
                                }
                            }
                        }
                    }
                }
            }

            // custom inspector:
            DoInspectorGUI();

            // generic brush editing:
            using (new NamedVerticalScope("Order"))
            {
                List <BrushBase> orderedTargets = BrushTargets.ToList();
                orderedTargets.RemoveAll(item => (item == null));
                orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex()));

                if (GUILayout.Button("Set As First"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsFirstSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Earlier"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        if (siblingIndex > 0)
                        {
                            Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                            siblingIndex--;
                            thisBrush.transform.SetSiblingIndex(siblingIndex);
                        }
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Later"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        siblingIndex++;
                        thisBrush.transform.SetSiblingIndex(siblingIndex);
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Set As Last"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsLastSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (serializedObject.targetObject != null)
                {
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }
Exemple #10
0
        public sealed override void OnInspectorGUI()
        {
            // group editing:
            if (ShowGroupInspector)
            {
                using (new NamedVerticalScope("Group"))
                {
                    GUILayout.BeginHorizontal();

                    // find whether we are currently inside of a group:
                    GroupBrush group = null;
                    if (BrushTarget.transform.parent)
                    {
                        group = BrushTarget.transform.parent.GetComponent <GroupBrush>();
                    }

                    // we are in a group:
                    if (group != null)
                    {
                        if (GUILayout.Button("Select Group"))
                        {
                            // select the group.
                            Selection.objects = new Object[] { BrushTarget.transform.parent.gameObject };
                        }
                    }

                    if (GUILayout.Button("Create Group"))
                    {
                        // create a group.
                        TransformHelper.GroupSelection();
                    }

                    GUILayout.EndHorizontal();
                }
            }

            // custom inspector:
            DoInspectorGUI();


            // generic brush editing:
            using (new NamedVerticalScope("Order"))
            {
                List <BrushBase> orderedTargets = BrushTargets.ToList();
                orderedTargets.RemoveAll(item => (item == null));
                orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex()));

                if (GUILayout.Button("Set As First"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsFirstSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Earlier"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        if (siblingIndex > 0)
                        {
                            Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                            siblingIndex--;
                            thisBrush.transform.SetSiblingIndex(siblingIndex);
                        }
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Later"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        siblingIndex++;
                        thisBrush.transform.SetSiblingIndex(siblingIndex);
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Set As Last"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsLastSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (serializedObject.targetObject != null)
                {
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }
        public override void OnInspectorGUI()
        {
            using (new NamedVerticalScope("Order"))
            {
                List <BrushBase> orderedTargets = BrushTargets.ToList();
                orderedTargets.RemoveAll(item => (item == null));
                orderedTargets.Sort((x, y) => x.transform.GetSiblingIndex().CompareTo(y.transform.GetSiblingIndex()));

                if (GUILayout.Button("Set As First"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsFirstSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Earlier"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        if (siblingIndex > 0)
                        {
                            Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                            siblingIndex--;
                            thisBrush.transform.SetSiblingIndex(siblingIndex);
                        }
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Send Later"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        // REVERSED
                        BrushBase thisBrush = orderedTargets[orderedTargets.Count - 1 - i];

                        int siblingIndex = thisBrush.transform.GetSiblingIndex();
                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        siblingIndex++;
                        thisBrush.transform.SetSiblingIndex(siblingIndex);
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (GUILayout.Button("Set As Last"))
                {
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        BrushBase thisBrush = orderedTargets[i];

                        Undo.SetTransformParent(thisBrush.transform, thisBrush.transform.parent, "Change Order");
                        thisBrush.transform.SetAsLastSibling();
                    }

                    // Force all the brushes to recalculate their intersections and get ready for rebuilding
                    for (int i = 0; i < orderedTargets.Count; i++)
                    {
                        if (orderedTargets[i] is PrimitiveBrush)
                        {
                            ((PrimitiveBrush)orderedTargets[i]).RecalculateIntersections();
                            ((PrimitiveBrush)orderedTargets[i]).BrushCache.SetUnbuilt();
                        }
                    }
                }

                if (serializedObject.targetObject != null)
                {
                    serializedObject.ApplyModifiedProperties();
                }
            }
        }