Exemple #1
0
        public override bool DragUpdated()
        {
            //Debug.Log("DragUpdated");
            //InternalCSGModelManager.skipRefresh = true;
            try
            {
                DisableVisualObjects();
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                var intersection = SceneQueryUtility.FindMeshIntersection(Event.current.mousePosition);
                var normal       = intersection.plane.normal;

                hoverPosition     = intersection.worldIntersection;
                hoverParent       = SelectionUtility.FindParentToAssignTo(intersection);
                hoverBrushSurface = intersection.brush != null ? new SelectedBrushSurface(intersection.brush, intersection.surfaceIndex) : null;
                hoverRotation     = SelectionUtility.FindDragOrientation(normal, sourceSurfaceAlignment, destinationSurfaceAlignment);
                haveNoParent      = (hoverParent == null);
                hoverSiblingIndex = int.MaxValue;

                RealtimeCSG.Grid.SetForcedGrid(intersection.plane);

                var toggleSnapping = (Event.current.modifiers & EventModifiers.Control) == EventModifiers.Control;
                var doSnapping     = RealtimeCSG.CSGSettings.SnapToGrid ^ toggleSnapping;
                if (doSnapping)
                {
                    var localPoints = new Vector3[8];
                    var localPlane  = intersection.plane;
                    for (var i = 0; i < localPoints.Length; i++)
                    {
                        localPoints[i] = GeometryUtility.ProjectPointOnPlane(localPlane, (hoverRotation * projectedBounds[i]) + hoverPosition);
                    }

                    hoverPosition += RealtimeCSG.Grid.SnapDeltaToGrid(MathConstants.zeroVector3, localPoints);
                }
                hoverPosition = GeometryUtility.ProjectPointOnPlane(intersection.plane, hoverPosition) + (normal * 0.01f);

                EnableVisualObjects();
                return(true);
            }
            finally
            {
                if (!SceneViewEventHandler.IsActive())
                {
                    SceneViewEventHandler.ResetUpdateRoutine();
                }
            }
        }
        public bool DragUpdated(SceneView sceneView)
        {
            try
            {
                DisableVisualObjects();
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                var camera       = sceneView.camera;
                var intersection = SceneQueryUtility.FindMeshIntersection(camera, Event.current.mousePosition);
                var normal       = intersection.worldPlane.normal;

                hoverPosition     = intersection.worldIntersection;
                hoverParent       = SelectionUtility.FindParentToAssignTo(intersection);
                hoverBrushSurface = intersection.brush != null ? new SelectedBrushSurface(intersection.brush, intersection.surfaceIndex, intersection.worldPlane) : null;
                hoverRotation     = SelectionUtility.FindDragOrientation(sceneView, normal, sourceSurfaceAlignment, destinationSurfaceAlignment);
                haveNoParent      = (hoverParent == null);
                hoverSiblingIndex = int.MaxValue;

                RealtimeCSG.CSGGrid.SetForcedGrid(camera, intersection.worldPlane);

                // Since we're snapping points to grid and do not have a relative distance, relative snapping makes no sense
                var doGridSnapping = RealtimeCSG.CSGSettings.ActiveSnappingMode != SnapMode.None;
                if (doGridSnapping)
                {
                    var localPoints = new Vector3[8];
                    var localPlane  = intersection.worldPlane;
                    for (var i = 0; i < localPoints.Length; i++)
                    {
                        localPoints[i] = GeometryUtility.ProjectPointOnPlane(localPlane, (hoverRotation * projectedBounds[i]) + hoverPosition);
                    }

                    hoverPosition += RealtimeCSG.CSGGrid.SnapDeltaToGrid(camera, MathConstants.zeroVector3, localPoints);
                }
                hoverPosition = GeometryUtility.ProjectPointOnPlane(intersection.worldPlane, hoverPosition);                  // + (normal * 0.01f);

                EnableVisualObjects();
                return(true);
            }
            finally
            {
                if (!UpdateLoop.IsActive())
                {
                    UpdateLoop.ResetUpdateRoutine();
                }
            }
        }
Exemple #3
0
        void EnableVisualObjects()
        {
            //Debug.Log("EnableVisualObjects");
            if (visualDragGameObject == null ||
                visualDragGameObject.Count != dragGameObjects.Count)
            {
                CreateVisualObjects();
            }
            else
            {
                for (int i = 0; i < dragGameObjects.Count; i++)
                {
                    if (visualDragGameObject[i] == null || !visualDragGameObject[i])
                    {
                        continue;
                    }
                    visualDragGameObject[i].SetActive(dragGameObjects[i].activeSelf);
                }
            }

            int counter = 0;

            foreach (var obj in visualDragGameObject)
            {
                if (obj == null || !obj)
                {
                    continue;
                }
                obj.transform.rotation = hoverRotation;
                obj.transform.position = hoverPosition;
                if (hoverParent != null && !SelectionUtility.IsPrefab(hoverParent.gameObject))
                {
                    obj.transform.SetParent(hoverParent, true);
                }
                obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                counter++;
            }

            /*
             * InternalCSGModelManager.CheckTransformChanged();
             * InternalCSGModelManager.OnHierarchyModified();
             * InternalCSGModelManager.UpdateMeshes(forceUpdate: true);
             * MeshInstanceManager.UpdateHelperSurfaceVisibility();
             */
        }
Exemple #4
0
        public static Transform FindParentToAssignTo(BrushIntersection intersection)
        {
            if (intersection.brush == null ||
                SelectionUtility.IsPrefab(intersection.brush.gameObject))
            {
                var lastModel = SelectionUtility.LastUsedModel;
                if (lastModel == null ||
                    SelectionUtility.IsPrefab(lastModel.gameObject))
                {
                    return(null);
                }

                return(lastModel.transform);
            }

            var hoverParent = intersection.brush.transform.parent;
            var iterator    = hoverParent;

            while (iterator != null)
            {
                var node = iterator.GetComponent <CSGNode>();
                if (node != null)
                {
                    hoverParent = node.transform;
                }
                iterator = iterator.transform.parent;
            }
            if (!hoverParent)
            {
                return(null);
            }
            if (PrefabUtility.GetPrefabParent(hoverParent.gameObject) != null)
            {
                return(null);
            }
            return(hoverParent);
        }
Exemple #5
0
        void EnableVisualObjects()
        {
            if (visualDragGameObject == null ||
                visualDragGameObject.Count != dragGameObjects.Count)
            {
                CreateVisualObjects();
            }
            else
            {
                for (int i = 0; i < dragGameObjects.Count; i++)
                {
                    if (visualDragGameObject[i] == null || !visualDragGameObject[i])
                    {
                        continue;
                    }
                    visualDragGameObject[i].SetActive(dragGameObjects[i].activeSelf);
                }
            }

            int counter = 0;

            foreach (var obj in visualDragGameObject)
            {
                if (obj == null || !obj)
                {
                    continue;
                }
                obj.transform.rotation = hoverRotation;
                obj.transform.position = hoverPosition;
                if (hoverParent != null && !SelectionUtility.IsPrefab(hoverParent.gameObject))
                {
                    obj.transform.SetParent(hoverParent, true);
                }
                obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                counter++;
            }
        }
        // Update rectangle selection using reflection
        // This is hacky & dangerous
        // LOOK AWAY NOW!
        internal static void Update(SceneView sceneView)
        {
            InitReflectedData();
            if (!reflectionSucceeded)
            {
                prevStartGUIPoint    = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
                prevMouseGUIPoint    = prevStartGUIPoint;
                prevStartScreenPoint = MathConstants.zeroVector2;
                prevMouseScreenPoint = MathConstants.zeroVector2;
                rectFoundGameObjects.Clear();
                return;
            }

            var s_RectSelectionID_instance = (int)s_RectSelectionID_field.GetValue(null);

            // check if we're rect-selecting
            if (GUIUtility.hotControl == s_RectSelectionID_instance)
            {
                var typeForControl = Event.current.GetTypeForControl(s_RectSelectionID_instance);
                if (typeForControl == EventType.Used ||
                    Event.current.commandName == "ModifierKeysChanged")
                {
                    // m_RectSelection field of SceneView
                    var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView);

                    // m_RectSelecting field of RectSelection instance
                    var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance);
                    if (m_RectSelecting_instance)
                    {
                        // m_SelectStartPoint of RectSelection instance
                        var m_SelectStartPoint_instance = (Vector2)m_SelectStartPoint_field.GetValue(m_RectSelection_instance);

                        // m_SelectMousePoint of RectSelection instance
                        var m_SelectMousePoint_instance = (Vector2)m_SelectMousePoint_field.GetValue(m_RectSelection_instance);

                        // determine if our frustum changed since the last time
                        bool modified   = false;
                        bool needUpdate = false;
                        if (prevStartGUIPoint != m_SelectStartPoint_instance)
                        {
                            prevStartGUIPoint    = m_SelectStartPoint_instance;
                            prevStartScreenPoint = Event.current.mousePosition;
                            needUpdate           = true;
                        }
                        if (prevMouseGUIPoint != m_SelectMousePoint_instance)
                        {
                            prevMouseGUIPoint    = m_SelectMousePoint_instance;
                            prevMouseScreenPoint = Event.current.mousePosition;
                            needUpdate           = true;
                        }
                        if (needUpdate)
                        {
                            var rect = CameraUtility.PointsToRect(prevStartScreenPoint, prevMouseScreenPoint);
                            if (rect.width > 3 && rect.height > 3)
                            {
                                var frustum = CameraUtility.GetCameraSubFrustumGUI(sceneView.camera, rect);

                                // Find all the brushes (and it's gameObjects) that are in the frustum
                                if (SceneQueryUtility.GetItemsInFrustum(frustum.Planes,
                                                                        rectFoundGameObjects))
                                {
                                    modified = true;
                                }
                                else
                                {
                                    if (rectFoundGameObjects != null &&
                                        rectFoundGameObjects.Count > 0)
                                    {
                                        rectFoundGameObjects.Clear();
                                        modified = true;
                                    }
                                }
                            }
                        }

                        GameObject[] currentSelection          = null;
                        var          m_LastSelection_instance  = (Dictionary <GameObject, bool>)m_LastSelection_field.GetValue(m_RectSelection_instance);
                        var          m_SelectionStart_instance = (UnityEngine.Object[])m_SelectionStart_field.GetValue(m_RectSelection_instance);
                        if (modified &&
                            rectFoundGameObjects != null &&
                            rectFoundGameObjects.Count > 0)
                        {
                            if (EditModeManager.ActiveTool == null)
                            {
                                if (EditModeManager.EditMode != ToolEditMode.Place ||
                                    EditModeManager.EditMode != ToolEditMode.Edit)
                                {
                                    EditModeManager.EditMode = ToolEditMode.Place;
                                }
                            }

                            foreach (var obj in rectFoundGameObjects)
                            {
                                // if it hasn't already been added, add the obj
                                if (!m_LastSelection_instance.ContainsKey(obj))
                                {
                                    m_LastSelection_instance.Add(obj, false);
                                }


                                // Remove models that we may have selected when we should be selecting it's brushes
                                var models = obj.GetComponentsInParent <CSGModel>(includeInactive: true);
                                var model  = models.Length == 0 ? null : models[0];
                                if (model != null)
                                {
                                    var modelObj = model.gameObject;
                                    if (model != null &&
                                        modelObj != obj &&
                                        m_LastSelection_instance.ContainsKey(modelObj) &&
                                        !ArrayUtility.Contains(m_SelectionStart_instance, modelObj))
                                    {
                                        m_LastSelection_instance.Remove(modelObj);
                                        modified = true;
                                    }
                                }
                            }

                            currentSelection = m_LastSelection_instance.Keys.ToArray();
                            m_CurrentSelection_field.SetValue(m_RectSelection_instance, currentSelection);
                        }
                        for (int j = m_SelectionStart_instance.Length - 1; j >= 0; j--)
                        {
                            var obj = m_SelectionStart_instance[j] as GameObject;
                            if (obj == null)
                            {
                                continue;
                            }

                            if (obj.GetComponent <GeneratedMeshInstance>() != null)
                            {
                                ArrayUtility.RemoveAt(ref m_SelectionStart_instance, j);
                                m_LastSelection_instance.Remove(obj);
                                m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance);
                                modified = true;
                            }
                        }

                        if ((Event.current.commandName == "ModifierKeysChanged" || modified))
                        {
                            if (currentSelection == null || modified)
                            {
                                currentSelection = m_LastSelection_instance.Keys.ToArray();
                            }
                            var foundObjects = currentSelection;

                            for (int j = foundObjects.Length - 1; j >= 0; j--)
                            {
                                var obj = foundObjects[j];
                                if (obj == null || obj.GetComponent <GeneratedMeshInstance>() != null)
                                {
                                    ArrayUtility.RemoveAt(ref foundObjects, j);
                                    m_LastSelection_instance.Remove(obj);
                                    m_SelectionStart_field.SetValue(m_RectSelection_instance, m_SelectionStart_instance);
                                }
                            }


                            var selectionTypeNormal = SelectionType_Normal;
                            if (Event.current.shift)
                            {
                                selectionTypeNormal = SelectionType_Additive;
                            }
                            else
                            if (EditorGUI.actionKey)
                            {
                                selectionTypeNormal = SelectionType_Subtractive;
                            }

                            // calling static method UpdateSelection of RectSelection
                            UpdateSelection_method.Invoke(null,
                                                          new object[] {
                                m_SelectionStart_instance,
                                foundObjects,
                                selectionTypeNormal,
                                m_RectSelecting_instance
                            });
                        }
                    }
                }
            }
            if (GUIUtility.hotControl != s_RectSelectionID_instance)
            {
                prevStartGUIPoint = MathConstants.zeroVector2;
                prevMouseGUIPoint = MathConstants.zeroVector2;
                rectFoundGameObjects.Clear();
            }


            var eventType = Event.current.GetTypeForControl(s_RectSelectionID_instance);

            var hotControl = GUIUtility.hotControl;

            if (hotControl == s_RectSelectionID_instance &&
                EditModeManager.ActiveTool.IgnoreUnityRect)
            {
                hotControl            = 0;
                GUIUtility.hotControl = 0;
            }

            switch (eventType)
            {
            case EventType.MouseDown:
            {
                rectClickDown      = (Event.current.button == 0 && hotControl == s_RectSelectionID_instance);
                clickMousePosition = Event.current.mousePosition;
                mouseDragged       = false;
                break;
            }

            case EventType.MouseUp:
            {
                rectClickDown = false;
                break;
            }

            case EventType.MouseMove:
            {
                rectClickDown = false;
                break;
            }

            case EventType.Used:
            {
                if (clickMousePosition != Event.current.mousePosition)
                {
                    mouseDragged = true;
                }
                if (!mouseDragged && rectClickDown &&
                    Event.current.button == 0)
                {
                    // m_RectSelection field of SceneView
                    var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView);

                    var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance);
                    if (!m_RectSelecting_instance)
                    {
                        // make sure GeneratedMeshes are not part of our selection
                        if (Selection.gameObjects != null)
                        {
                            var selectedObjects = Selection.objects;
                            var foundObjects    = new List <UnityEngine.Object>();
                            foreach (var obj in selectedObjects)
                            {
                                var component  = obj as Component;
                                var gameObject = obj as GameObject;
                                var transform  = obj as Transform;
                                if (!(component && component.GetComponent <GeneratedMeshes>()) &&
                                    !(gameObject && gameObject.GetComponent <GeneratedMeshes>()) &&
                                    !(transform && transform.GetComponent <Transform>()))
                                {
                                    foundObjects.Add(obj);
                                }
                            }
                            if (foundObjects.Count != selectedObjects.Length)
                            {
                                Selection.objects = foundObjects.ToArray();
                            }
                        }

                        SelectionUtility.DoSelectionClick(sceneView);
                        Event.current.Use();
                    }
                }
                rectClickDown = false;
                break;
            }


            case EventType.ValidateCommand:
            {
                if (Event.current.commandName == "SelectAll")
                {
                    Event.current.Use();
                    break;
                }
                if (Keys.HandleSceneValidate(EditModeManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }

            case EventType.ExecuteCommand:
            {
                if (Event.current.commandName == "SelectAll")
                {
                    var transforms = new List <UnityEngine.Object>();
                    for (int sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++)
                    {
                        var scene = SceneManager.GetSceneAt(sceneIndex);
                        foreach (var gameObject in scene.GetRootGameObjects())
                        {
                            foreach (var transform in gameObject.GetComponentsInChildren <Transform>())
                            {
                                if ((transform.hideFlags & (HideFlags.NotEditable | HideFlags.HideInHierarchy)) == (HideFlags.NotEditable | HideFlags.HideInHierarchy))
                                {
                                    continue;
                                }
                                transforms.Add(transform.gameObject);
                            }
                        }
                    }
                    Selection.objects = transforms.ToArray();

                    Event.current.Use();
                    break;
                }
                break;
            }

            case EventType.KeyDown:
            {
                if (Keys.HandleSceneKeyDown(EditModeManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }

            case EventType.KeyUp:
            {
                if (Keys.HandleSceneKeyUp(EditModeManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }
            }
        }
        public bool UpdateSelection(HashSet <CSGNode> newTargetNodes, HashSet <Transform> newTargetOthers)
        {
            if (newTargetNodes == null)
            {
                newTargetNodes = new HashSet <CSGNode>();
            }
            if (newTargetOthers == null)
            {
                newTargetOthers = new HashSet <Transform>();
            }

            this.RemovedNodes  = null;
            this.RemovedOthers = null;

            this.AddedNodes  = null;
            this.AddedOthers = null;

            var foundRemovedNodes = new List <CSGNode>();

            if (this.NodeTargets != null &&
                this.NodeTargets.Length > 0)
            {
                if (newTargetNodes.Count == 0)
                {
                    foundRemovedNodes.AddRange(this.NodeTargets);
                }
                else
                {
                    for (int i = 0; i < this.NodeTargets.Length; i++)
                    {
                        if (!this.NodeTargets[i] ||
                            !newTargetNodes.Contains(this.NodeTargets[i]))
                        {
                            foundRemovedNodes.Add(this.NodeTargets[i]);
                        }
                    }
                }
            }

            var foundRemovedOthers = new List <Transform>();

            if (this.OtherTargets != null &&
                this.OtherTargets.Length > 0)
            {
                if (newTargetOthers.Count == 0)
                {
                    foundRemovedOthers.AddRange(this.OtherTargets);
                }
                else
                {
                    for (int i = 0; i < this.OtherTargets.Length; i++)
                    {
                        if (!this.OtherTargets[i] ||
                            !newTargetOthers.Contains(this.OtherTargets[i]))
                        {
                            foundRemovedOthers.Add(this.OtherTargets[i]);
                        }
                    }
                }
            }

            var originalTargetNodeCount  = (this.NodeTargets == null) ? 0 : this.NodeTargets.Length;
            var originalTargetOtherCount = (this.OtherTargets == null) ? 0 : this.OtherTargets.Length;

            // If our counts are the same and nothing is removed (and nothing could've been added), nothing has changed.
            if (newTargetNodes.Count == originalTargetNodeCount &&
                newTargetOthers.Count == originalTargetOtherCount &&
                foundRemovedNodes.Count == 0 &&
                foundRemovedOthers.Count == 0)
            {
                //Debug.Log(originalTargetNodeCount + " " + originalTargetOtherCount + " " + newTargetNodes .Count + " " + newTargetOthers .Count);
                return(false);
            }

            Validate();

            foreach (var node in foundRemovedNodes)
            {
                ArrayUtility.Remove(ref this.NodeTargets, node);

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    ArrayUtility.Remove(ref this.BrushTargets, brush);
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    ArrayUtility.Remove(ref this.OperationTargets, operation);
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    ArrayUtility.Remove(ref this.ModelTargets, model);
                    continue;
                }
            }

            foreach (var other in foundRemovedOthers)
            {
                ArrayUtility.Remove(ref this.OtherTargets, other);
            }

            var foundAddedNodes = new List <CSGNode>();

            foreach (var node in newTargetNodes)
            {
                if (this.NodeTargets != null &&
                    ArrayUtility.Contains(this.NodeTargets, node))
                {
                    continue;
                }

                if (this.NodeTargets == null)
                {
                    this.NodeTargets = new CSGNode[] { node };
                }
                else
                {
                    ArrayUtility.Add(ref this.NodeTargets, node);
                }

                foundAddedNodes.Add(node);

                if (SelectionUtility.IsPrefab(node.gameObject))
                {
                    continue;
                }

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    if (this.BrushTargets == null)
                    {
                        this.BrushTargets = new CSGBrush[] { brush }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.BrushTargets, brush);
                    }
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    if (this.OperationTargets == null)
                    {
                        this.OperationTargets = new CSGOperation[] { operation }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.OperationTargets, operation);
                    }
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    if (this.ModelTargets == null)
                    {
                        this.ModelTargets = new CSGModel[] { model }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.ModelTargets, model);
                    }
                    continue;
                }
            }

            var foundAddedOthers = new List <Transform>();

            foreach (var other in newTargetOthers)
            {
                if (this.OtherTargets != null &&
                    ArrayUtility.Contains(this.OtherTargets, other))
                {
                    continue;
                }

                if (this.OtherTargets == null)
                {
                    this.OtherTargets = new Transform[] { other }
                }
                ;
                else
                {
                    ArrayUtility.Add(ref this.OtherTargets, other);
                }
                foundAddedOthers.Add(other);
            }

            for (int i = foundAddedNodes.Count - 1; i >= 0; i--)
            {
                var node  = foundAddedNodes[i];
                var brush = node as CSGBrush;
                if (brush != null)
                {
                    var brush_cache = InternalCSGModelManager.GetBrushCache(brush);
                    if (brush_cache == null ||
                        brush_cache.childData == null ||
                        brush_cache.childData.Model == null)
                    {
                        continue;
                    }

                    var childModel = brush_cache.childData.Model;
                    if (childModel &&
                        childModel.isActiveAndEnabled)
                    {
                        SelectionUtility.LastUsedModel = childModel;
                    }
                    break;
                }
                var operation = node as CSGOperation;
                if (operation != null)
                {
                    var operation_cache = InternalCSGModelManager.GetOperationCache(operation);
                    if (operation_cache == null ||
                        operation_cache.ChildData == null ||
                        operation_cache.ChildData.Model == null)
                    {
                        continue;
                    }

                    SelectionUtility.LastUsedModel = operation_cache.ChildData.Model;
                    break;
                }
                var model = node as CSGModel;
                if (model &&
                    model.isActiveAndEnabled)
                {
                    SelectionUtility.LastUsedModel = model;
                    break;
                }
            }

            this.RemovedNodes  = foundRemovedNodes.ToArray();
            this.RemovedOthers = foundRemovedOthers.ToArray();

            this.AddedNodes  = foundAddedNodes.ToArray();
            this.AddedOthers = foundAddedOthers.ToArray();

            return(foundAddedNodes.Count > 0 || foundRemovedNodes.Count > 0 || foundAddedOthers.Count > 0 || foundRemovedOthers.Count > 0);
        }
        public static void OnSceneGUI(SceneView sceneView)
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            CameraUtility.InitDistanceChecks(sceneView);
            SelectionUtility.HandleEvents();
            InitTools();

            HandleBuilderEvents();
            {
                UpdateTool();

                if (instance.activeTool != null)
                {
                    if (RealtimeCSG.CSGSettings.EnableRealtimeCSG)
                    {
                        // handle the tool
                        var sceneSize = sceneView.position.size;
                        var sceneRect = new Rect(0, 0, sceneSize.x, sceneSize.y - ((CSG_GUIStyleUtility.BottomToolBarHeight + 4) + 17));

                        instance.activeTool.HandleEvents(sceneRect);
                    }
                    else
                    {
                        if (Event.current.type == EventType.Repaint)
                        {
                            var brushes         = instance.filteredSelection.BrushTargets;
                            var wireframes      = new List <GeometryWireframe>(brushes.Length);
                            var transformations = new List <Matrix4x4>(brushes.Length);
                            for (int i = 0; i < brushes.Length; i++)
                            {
                                var brush = brushes[i];
                                if (!brush)
                                {
                                    continue;
                                }

                                if (brush.ChildData == null ||
                                    !brush.ChildData.Model)
                                {
                                    continue;
                                }

                                var brushTransformation = brush.compareTransformation.localToWorldMatrix;

                                wireframes.Add(BrushOutlineManager.GetBrushOutline(brushes[i].brushNodeID));
                                transformations.Add(brushTransformation);
                            }
                            if (wireframes.Count > 0)
                            {
                                CSGRenderer.DrawSelectedBrushes(instance.zTestLineMeshManager, instance.noZTestLineMeshManager,
                                                                wireframes.ToArray(), transformations.ToArray(),
                                                                ColorSettings.SelectedOutlines, GUIConstants.thickLineScale);
                            }
                            MaterialUtility.LineDashMultiplier      = 1.0f;
                            MaterialUtility.LineThicknessMultiplier = 1.0f;
                            MaterialUtility.LineAlphaMultiplier     = 1.0f;
                            instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine);
                            instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine);
                        }
                    }
                }
            }

            int sceneWindowId   = GUIUtility.GetControlID(SceneWindowHash, FocusType.Passive);
            var sceneWindowType = Event.current.GetTypeForControl(sceneWindowId);

            if (sceneWindowType == EventType.Repaint)
            {
                if (currentEditorWindows.Count > 0)
                {
                    for (int i = 0; i < currentEditorWindows.Count; i++)
                    {
                        currentEditorWindows[i].Repaint();
                    }
                    return;
                }
            }

            if (sceneWindowType == EventType.MouseMove)
            {
                SceneDragToolManager.IsDraggingObjectInScene = false;
            }

            if (RealtimeCSG.CSGSettings.EnableRealtimeCSG)
            {
                if (sceneView && sceneWindowType != EventType.Used && !SceneDragToolManager.IsDraggingObjectInScene)
                {
                    if (currentEditorWindows.Count == 0)
                    {
                        try
                        {
                            Handles.BeginGUI();
                            Rect windowRect = new Rect(Vector2.zero, sceneView.position.size);
                            EditModeSelectionGUI.HandleWindowGUI(windowRect);
                        }
                        finally
                        {
                            Handles.EndGUI();
                        }
                    }
                }
            }
        }
Exemple #9
0
        public static bool HandleSceneKeyUp(IEditMode tool, bool checkForTextEditing = true)
        {
            if (EditorGUIUtility.editingTextField && checkForTextEditing)
            {
                return(false);
            }

            if (Keys.MakeSelectedPassThroughKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                OperationsUtility.SetPassThroughOnSelected(); return(true);
            }
            if (Keys.MakeSelectedAdditiveKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                OperationsUtility.ModifyOperationsOnSelected(CSGOperationType.Additive); return(true);
            }
            if (Keys.MakeSelectedSubtractiveKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                OperationsUtility.ModifyOperationsOnSelected(CSGOperationType.Subtractive); return(true);
            }
            if (Keys.MakeSelectedIntersectingKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                OperationsUtility.ModifyOperationsOnSelected(CSGOperationType.Intersecting); return(true);
            }

            if (Keys.ToggleSelectedObjectVisibilityKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                SelectionUtility.ToggleSelectedObjectVisibility(); return(true);
            }
            if (Keys.QuickHideSelectedObjectsKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                SelectionUtility.HideSelectedObjects(); return(true);
            }
            if (Keys.QuickHideUnselectedObjectsKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                SelectionUtility.HideUnselectedObjects(); return(true);
            }
            if (Keys.UnHideAllObjectsKey.IsKeyPressed() && tool.UsesUnitySelection)
            {
                SelectionUtility.UnHideAll(); return(true);
            }
            if (Keys.CancelActionKey.IsKeyPressed())
            {
                SelectionUtility.DeselectAll(); return(true);
            }

            if (Keys.HalfGridSizeKey.IsKeyPressed())
            {
                GridUtility.HalfGridSize(); return(true);
            }
            if (Keys.DoubleGridSizeKey.IsKeyPressed())
            {
                GridUtility.DoubleGridSize(); return(true);
            }
            if (Keys.ToggleShowGridKey.IsKeyPressed())
            {
                GridUtility.ToggleShowGrid(); return(true);
            }
            if (Keys.ToggleSnappingKey.IsKeyPressed())
            {
                GridUtility.ToggleSnapToGrid(); return(true);
            }
            return(false);
        }
Exemple #10
0
        static void OnScene(SceneView sceneView)
        {
            if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG)
            {
                return;
            }
            UpdateOnSceneChange();
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (Event.current.type == EventType.Repaint &&
                !ColorSettings.isInitialized)
            {
                ColorSettings.Update();
            }

            if (!IsActive())
            {
                ResetUpdateRoutine();
            }

            if (Event.current.type == EventType.MouseDown ||
                Event.current.type == EventType.MouseDrag)
            {
                mousePressed = true;
            }
            else if (Event.current.type == EventType.MouseUp ||
                     Event.current.type == EventType.MouseMove)
            {
                mousePressed = false;
            }

            var s_RectSelectionID_instance = (int)s_RectSelectionID_field.GetValue(null);

            UpdateRectSelection(sceneView, s_RectSelectionID_instance);
            OnHandleDragAndDrop(inSceneView: true);

            var eventType = Event.current.GetTypeForControl(s_RectSelectionID_instance);

            var hotControl = GUIUtility.hotControl;

            if (hotControl == s_RectSelectionID_instance &&
                CSGBrushEditorManager.ActiveTool.IgnoreUnityRect)
            {
                hotControl            = 0;
                GUIUtility.hotControl = 0;
            }

            switch (eventType)
            {
            case EventType.MouseDown:
            {
                rectClickDown      = (Event.current.button == 0 && hotControl == s_RectSelectionID_instance);
                clickMousePosition = Event.current.mousePosition;
                mouseDragged       = false;
                break;
            }

            case EventType.MouseUp:
            {
                rectClickDown = false;
                break;
            }

            case EventType.MouseMove:
            {
                rectClickDown = false;
                break;
            }

            case EventType.Used:
            {
                if (clickMousePosition != Event.current.mousePosition)
                {
                    mouseDragged = true;
                }
                if (!mouseDragged && rectClickDown &&
                    Event.current.button == 0)
                {
                    // m_RectSelection field of SceneView
                    var m_RectSelection_instance = m_RectSelection_field.GetValue(sceneView);

                    var m_RectSelecting_instance = (bool)m_RectSelecting_field.GetValue(m_RectSelection_instance);
                    if (!m_RectSelecting_instance)
                    {
                        // make sure GeneratedMeshes are not part of our selection
                        if (Selection.gameObjects != null)
                        {
                            var selectedObjects = Selection.objects;
                            var foundObjects    = new List <UnityEngine.Object>();
                            foreach (var obj in selectedObjects)
                            {
                                var component  = obj as Component;
                                var gameObject = obj as GameObject;
                                var transform  = obj as Transform;
                                if (!(component && component.GetComponent <GeneratedMeshes>()) &&
                                    !(gameObject && gameObject.GetComponent <GeneratedMeshes>()) &&
                                    !(transform && transform.GetComponent <Transform>()))
                                {
                                    foundObjects.Add(obj);
                                }
                            }
                            if (foundObjects.Count != selectedObjects.Length)
                            {
                                Selection.objects = foundObjects.ToArray();
                            }
                        }

                        SelectionUtility.DoSelectionClick();
                        Event.current.Use();
                    }
                }
                rectClickDown = false;
                break;
            }


            case EventType.ValidateCommand:
            {
                if (Event.current.commandName == "SelectAll")
                {
                    Event.current.Use();
                    break;
                }
                if (Keys.HandleSceneValidate(CSGBrushEditorManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }

            case EventType.ExecuteCommand:
            {
                if (Event.current.commandName == "SelectAll")
                {
                    var transforms = new List <UnityEngine.Object>();
                    for (int sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++)
                    {
                        var scene = SceneManager.GetSceneAt(sceneIndex);
                        foreach (var gameObject in scene.GetRootGameObjects())
                        {
                            foreach (var transform in gameObject.GetComponentsInChildren <Transform>())
                            {
                                if ((transform.hideFlags & (HideFlags.NotEditable | HideFlags.HideInHierarchy)) == (HideFlags.NotEditable | HideFlags.HideInHierarchy))
                                {
                                    continue;
                                }
                                transforms.Add(transform.gameObject);
                            }
                        }
                    }
                    Selection.objects = transforms.ToArray();

                    Event.current.Use();
                    break;
                }
                break;
            }

            case EventType.KeyDown:
            {
                if (Keys.HandleSceneKeyDown(CSGBrushEditorManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }

            case EventType.KeyUp:
            {
                if (Keys.HandleSceneKeyUp(CSGBrushEditorManager.CurrentTool, true))
                {
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                break;
            }

            case EventType.Layout:
            {
                if (currentDragTool != null)
                {
                    currentDragTool.Layout();
                }
                break;
            }

            case EventType.Repaint:
            {
                break;
            }
            }

            //bool fallbackGUI = EditorWindow.focusedWindow != sceneView;
            //fallbackGUI =
            CSGBrushEditorManager.InitSceneGUI(sceneView);                    // || fallbackGUI;
            //fallbackGUI = true;

            /*
             * if (SceneQueryUtility._deepClickIntersections != null &&
             *      SceneQueryUtility._deepClickIntersections.Length > 0)
             * {
             *      foreach (var intersection in SceneQueryUtility._deepClickIntersections)
             *      {
             *              var triangle = intersection.triangle;
             *              Debug.DrawLine(triangle[0], triangle[1]);
             *              Debug.DrawLine(triangle[1], triangle[2]);
             *              Debug.DrawLine(triangle[2], triangle[0]);
             *      }
             * }
             */

            if (Event.current.type == EventType.Repaint)
            {
                MeshInstanceManager.RenderHelperSurfaces(sceneView);
            }

            if (Event.current.type == EventType.Repaint)
            {
                if (currentDragTool != null)
                {
                    currentDragTool.OnPaint();
                }

                SceneTools.OnPaint(sceneView);
            }
            else
            //if (fallbackGUI)
            {
                BottomBarGUI.ShowGUI(sceneView);
            }


            CSGBrushEditorManager.OnSceneGUI(sceneView);

            //if (fallbackGUI)
            {
                TooltipUtility.InitToolTip(sceneView);
                if (Event.current.type == EventType.Repaint)
                {
                    BottomBarGUI.ShowGUI(sceneView);
                }
                if (!mousePressed)
                {
                    Handles.BeginGUI();
                    TooltipUtility.DrawToolTip(getLastRect: false);
                    Handles.EndGUI();
                }
            }
        }
        //void OnSceneGUI() <- paints -everything- again for every selected brush
        public static void OnSceneGUI(SceneView sceneView)
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }


            /*
             * int prevHotControl		= GUIUtility.hotControl;
             * int prevKeyboardControl = GUIUtility.keyboardControl;
             *
             * // make it impossible for the tool to click in the bottom bar area
             * int bottomBarId	 = GUIUtility.GetControlID (BottomBarInputHash, FocusType.Passive);
             * bool forceRevert = false;
             * //if (GUIUtility.hotControl == 0)
             * {
             *      var bottomBarRect = sceneView.position;
             *      var min = bottomBarRect.min;
             *      var max = bottomBarRect.max;
             *
             *      min.y = max.y - (GUIStyleUtility.BottomToolBarHeight + 18);
             *
             *      bottomBarRect.min = min;
             *      bottomBarRect.max = max;
             *
             *      if (bottomBarRect.Contains(Event.current.mousePosition))
             *      {
             *              GUIUtility.hotControl	   = bottomBarId;
             *              GUIUtility.keyboardControl = bottomBarId;
             *              forceRevert = true;
             *      }
             * }
             */
            SelectionUtility.HandleEvents();
            InitTools();

            HandleBuilderEvents();
            //HandleYMode();
            {
                UpdateTool();

                if (instance.activeTool != null)
                {
                    if (RealtimeCSG.CSGSettings.EnableRealtimeCSG)
                    {
                        // handle the tool
                        var sceneSize = sceneView.position.size;
                        var sceneRect = new Rect(0, 0, sceneSize.x, sceneSize.y - ((GUIStyleUtility.BottomToolBarHeight + 4) + 17));
                        //var originalEventType = Event.current.type;
                        //if (originalEventType == EventType.MouseMove ||
                        //	originalEventType == EventType.MouseUp)
                        //	holdingDownMouse = false;

                        //var mousePos = Event.current.mousePosition;
                        //if (originalEventType == EventType.Layout ||
                        //	originalEventType == EventType.Repaint ||
                        //	sceneRect.Contains(mousePos) ||
                        //	holdingDownMouse)
                        instance.activeTool.HandleEvents(sceneRect);

                        //if (originalEventType == EventType.MouseDown ||
                        //	originalEventType == EventType.MouseDrag)
                        //	holdingDownMouse = true;
                    }
                    else
                    {
                        if (Event.current.type == EventType.Repaint)
                        {
                            var brushes      = instance.filteredSelection.BrushTargets;
                            var wireframes   = new List <GeometryWireframe>(brushes.Length);
                            var translations = new List <Vector3>(brushes.Length);
                            for (int i = 0; i < brushes.Length; i++)
                            {
                                var brush = brushes[i];
                                if (!brush)
                                {
                                    continue;
                                }

                                var brushCache = InternalCSGModelManager.GetBrushCache(brush);
                                if (brushCache == null ||
                                    brushCache.childData == null ||
                                    !brushCache.childData.Model)
                                {
                                    continue;
                                }

                                var brushTranslation = brushCache.compareTransformation.modelLocalPosition + brushCache.childData.ModelTransform.position;

                                wireframes.Add(BrushOutlineManager.GetBrushOutline(brushes[i].brushID));
                                translations.Add(brushTranslation);
                            }
                            if (wireframes.Count > 0)
                            {
                                CSGRenderer.DrawSelectedBrushes(instance.zTestLineMeshManager, instance.noZTestLineMeshManager,
                                                                wireframes.ToArray(), translations.ToArray(),
                                                                ColorSettings.SelectedOutlines, ToolConstants.thickLineScale);
                            }
                            MaterialUtility.LineDashMultiplier      = 1.0f;
                            MaterialUtility.LineThicknessMultiplier = 1.0f;
                            MaterialUtility.LineAlphaMultiplier     = 1.0f;
                            instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine);
                            instance.zTestLineMeshManager.Render(MaterialUtility.ZTestGenericLine);
                        }
                    }
                }
            }

            /*
             * // reset the control so the bottom bar can take over
             * if (forceRevert)
             * {
             *      GUIUtility.hotControl		= prevHotControl;
             *      GUIUtility.keyboardControl	= prevKeyboardControl;
             * }
             */

            int sceneWindowId   = GUIUtility.GetControlID(SceneWindowHash, FocusType.Passive);
            var sceneWindowType = Event.current.GetTypeForControl(sceneWindowId);

            if (sceneWindowType == EventType.Repaint)
            {
                if (currentEditorWindows.Count > 0)
                {
                    for (int i = 0; i < currentEditorWindows.Count; i++)
                    {
                        currentEditorWindows[i].Repaint();
                    }
                    return;
                }
            }

            if (sceneWindowType == EventType.MouseMove)
            {
                SceneTools.IsDraggingObjectInScene = false;
            }

            if (RealtimeCSG.CSGSettings.EnableRealtimeCSG)
            {
                if (sceneView != null && sceneWindowType != EventType.Used && !SceneTools.IsDraggingObjectInScene)
                {
                    if (currentEditorWindows.Count == 0)
                    {
                        try
                        {
                            Handles.BeginGUI();
                            Rect windowRect = new Rect(Vector2.zero, sceneView.position.size);
                            CSGBrushEditorGUI.HandleWindowGUI(windowRect);
                        }
                        finally
                        {
                            Handles.EndGUI();
                        }
                    }
                }
            }
        }
        static public void OnInspectorGUI(Editor editor, UnityEngine.Object[] targets)
        {
            TooltipUtility.InitToolTip(editor);
            try
            {
                var models = new CSGModel[targets.Length];

                for (int i = targets.Length - 1; i >= 0; i--)
                {
                    models[i] = targets[i] as CSGModel;
                    if (!models[i])
                    {
                        ArrayUtility.RemoveAt(ref models, i);
                    }
                }

                CSG_GUIStyleUtility.InitStyles();
                ShowRealtimeCSGDisabledMessage();

                if (models.Length > 0 && models.Length == targets.Length)
                {
                    CSGModelComponentInspectorGUI.OnInspectorGUI(targets);
                    return;
                }

                var filteredSelection = EditModeManager.FilteredSelection;
                var targetNodes       = filteredSelection.NodeTargets;
                var targetModels      = filteredSelection.ModelTargets;
                var targetBrushes     = filteredSelection.BrushTargets;
                var targetOperations  = filteredSelection.OperationTargets;
                if (targetNodes == null)
                {
                    return;
                }



                bool?isPrefab = false;
                PrefabInstantiateBehaviour?prefabBehaviour            = PrefabInstantiateBehaviour.Reference;
                PrefabSourceAlignment?     prefabSourceAlignment      = PrefabSourceAlignment.AlignedTop;
                PrefabDestinationAlignment?prefabDestinationAlignment = PrefabDestinationAlignment.AlignToSurface;

                if (targetNodes.Length > 0)
                {
                    var gameObject = targetNodes[0].gameObject;
                    isPrefab                   = SelectionUtility.IsPrefab(gameObject);
                    prefabBehaviour            = targetNodes[0].PrefabBehaviour;
                    prefabSourceAlignment      = targetNodes[0].PrefabSourceAlignment;
                    prefabDestinationAlignment = targetNodes[0].PrefabDestinationAlignment;
                    for (int i = 1; i < targetNodes.Length; i++)
                    {
                        gameObject = targetNodes[i].gameObject;
                        var currentIsPrefab                   = PrefabUtility.GetPrefabParent(gameObject) == null && PrefabUtility.GetPrefabObject(gameObject) != null && gameObject.transform.parent == null;
                        var currentPrefabBehaviour            = targetNodes[i].PrefabBehaviour;
                        var currentPrefabSourceAlignment      = targetNodes[i].PrefabSourceAlignment;
                        var currentPrefabDestinationAlignment = targetNodes[i].PrefabDestinationAlignment;
                        if (isPrefab.HasValue && isPrefab.Value != currentIsPrefab)
                        {
                            isPrefab = null;
                        }
                        if (prefabBehaviour.HasValue && prefabBehaviour.Value != currentPrefabBehaviour)
                        {
                            prefabBehaviour = null;
                        }
                        if (prefabSourceAlignment.HasValue && prefabSourceAlignment.Value != currentPrefabSourceAlignment)
                        {
                            prefabSourceAlignment = null;
                        }
                        if (prefabDestinationAlignment.HasValue && prefabDestinationAlignment.Value != currentPrefabDestinationAlignment)
                        {
                            prefabDestinationAlignment = null;
                        }
                    }
                }

                GUILayout.BeginVertical(GUI.skin.box);
                {
                    if (isPrefab.HasValue && isPrefab.Value)
                    {
                        EditorGUILayout.LabelField(PrefabLabelContent);
                    }
                    else
                    {
                        EditorGUILayout.LabelField(RaySnappingLabelContent);
                        TooltipUtility.SetToolTip(RaySnappingBehaviourTooltip);
                    }

                    EditorGUI.indentLevel++;
                    {
                        if (isPrefab.HasValue && isPrefab.Value)
                        {
                            EditorGUI.showMixedValue = !prefabBehaviour.HasValue;
                            var prefabBehavour = prefabBehaviour.HasValue ? prefabBehaviour.Value : PrefabInstantiateBehaviour.Reference;
                            EditorGUI.BeginChangeCheck();
                            {
                                prefabBehavour = (PrefabInstantiateBehaviour)EditorGUILayout.EnumPopup(PrefabInstantiateBehaviourContent, prefabBehavour);
                                TooltipUtility.SetToolTip(PrefabInstantiateBehaviourTooltip);
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                for (int i = 0; i < targetNodes.Length; i++)
                                {
                                    targetNodes[i].PrefabBehaviour = prefabBehavour;
                                }
                            }
                            EditorGUI.showMixedValue = false;
                        }


                        EditorGUI.showMixedValue = !prefabDestinationAlignment.HasValue;
                        var destinationAlignment = prefabDestinationAlignment.HasValue ? prefabDestinationAlignment.Value : PrefabDestinationAlignment.AlignToSurface;
                        EditorGUI.BeginChangeCheck();
                        {
                            destinationAlignment = (PrefabDestinationAlignment)EditorGUILayout.EnumPopup(DestinationAlignmentContent, destinationAlignment);
                            TooltipUtility.SetToolTip(DestinationAlignmentTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            for (int i = 0; i < targetNodes.Length; i++)
                            {
                                targetNodes[i].PrefabDestinationAlignment = destinationAlignment;
                            }
                        }
                        EditorGUI.showMixedValue = false;


                        EditorGUI.showMixedValue = !prefabSourceAlignment.HasValue;
                        var sourceAlignment = prefabSourceAlignment.HasValue ? prefabSourceAlignment.Value : PrefabSourceAlignment.AlignedFront;
                        EditorGUI.BeginChangeCheck();
                        {
                            sourceAlignment = (PrefabSourceAlignment)EditorGUILayout.EnumPopup(SourceAlignmentContent, sourceAlignment);
                            TooltipUtility.SetToolTip(SourceAlignmentTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            for (int i = 0; i < targetNodes.Length; i++)
                            {
                                targetNodes[i].PrefabSourceAlignment = sourceAlignment;
                            }
                        }
                        EditorGUI.showMixedValue = false;
                    }
                    EditorGUI.indentLevel--;
                }
                GUILayout.EndVertical();
                GUILayout.Space(10);


                if (targetModels.Length == 0)
                {
                    int              invalidOperationType = 999;
                    bool?            handleAsOne          = null;
                    bool             selMixedValues       = false;
                    CSGOperationType operationType        = (CSGOperationType)invalidOperationType;
                    bool             opMixedValues        = false;
                    uint?            targetContentLayer   = null;
                    if (targetBrushes.Length > 0)
                    {
                        operationType      = targetBrushes[0].OperationType;
                        targetContentLayer = targetBrushes[0].ContentLayer;
                    }
                    for (int b = 1; b < targetBrushes.Length; b++)
                    {
                        var brush = targetBrushes[b];
                        if (operationType != brush.OperationType)
                        {
                            opMixedValues = true;
                        }
                        if (targetContentLayer.HasValue && targetContentLayer.Value != brush.ContentLayer)
                        {
                            targetContentLayer = null;
                        }
                    }
                    foreach (var operation in targetOperations)
                    {
                        if (operationType == (CSGOperationType)invalidOperationType)
                        {
                            operationType = operation.OperationType;
                        }
                        else
                        if (operationType != operation.OperationType)
                        {
                            opMixedValues = true;
                        }

                        if (!handleAsOne.HasValue)
                        {
                            handleAsOne = operation.HandleAsOne;
                        }
                        else
                        if (handleAsOne.Value != operation.HandleAsOne)
                        {
                            selMixedValues = true;
                        }
                    }
                    GUILayout.BeginVertical(GUI.skin.box);
                    {
                        bool passThroughValue = false;
                        if (targetBrushes.Length == 0 && targetOperations.Length > 0)                         // only operations
                        {
                            bool?passThrough = targetOperations[0].PassThrough;
                            for (int i = 1; i < targetOperations.Length; i++)
                            {
                                if (passThrough.HasValue && passThrough.Value != targetOperations[i].PassThrough)
                                {
                                    passThrough = null;
                                    break;
                                }
                            }

                            opMixedValues = !passThrough.HasValue || passThrough.Value;

                            var ptMixedValues = !passThrough.HasValue;
                            passThroughValue = passThrough.HasValue ? passThrough.Value : false;
                            if (CSG_EditorGUIUtility.PassThroughButton(passThroughValue, ptMixedValues))
                            {
                                Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                                foreach (var operation in targetOperations)
                                {
                                    operation.PassThrough = true;
                                }
                                InternalCSGModelManager.Refresh();
                                EditorApplication.RepaintHierarchyWindow();
                            }

                            if (passThroughValue)
                            {
                                operationType = (CSGOperationType)255;
                            }
                        }
                        EditorGUI.BeginChangeCheck();
                        {
                            operationType = CSG_EditorGUIUtility.ChooseOperation(operationType, opMixedValues);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                            foreach (var brush in targetBrushes)
                            {
                                brush.OperationType = operationType;
                            }
                            foreach (var operation in targetOperations)
                            {
                                operation.PassThrough   = false;
                                operation.OperationType = operationType;
                            }
                            InternalCSGModelManager.Refresh();
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }
                    GUILayout.EndVertical();

                    if (targetOperations.Length == 0 && targetModels.Length == 0)
                    {
                        GUILayout.Space(10);

                        /*
                         * GUILayout.BeginVertical(GUI.skin.box);
                         * {
                         *      GUILayout.Label("Experimental");
                         *      EditorGUI.indentLevel++;
                         *      {
                         *              EditorGUI.showMixedValue = !targetContentLayer.HasValue;
                         *              var contentLayer = targetContentLayer.HasValue ? targetContentLayer.Value : 0;
                         *              EditorGUI.BeginChangeCheck();
                         *              {
                         *                      contentLayer = (uint)EditorGUILayout.Popup(ContentLayerContent, (int)contentLayer, ContentLayerTexts);
                         *                      TooltipUtility.SetToolTip(ContentLayerTooltip);
                         *              }
                         *              if (EditorGUI.EndChangeCheck())
                         *              {
                         *                      for (int i = 0; i < targetBrushes.Length; i++)
                         *                      {
                         *                              targetBrushes[i].ContentLayer = contentLayer;
                         *                      }
                         *              }
                         *      }
                         *      EditorGUI.indentLevel--;
                         * }
                         * GUILayout.EndVertical();
                         *
                         * GUILayout.Space(10);
                         * //*/
                        if (targetBrushes.Length == 1)
                        {
                            GUILayout.BeginVertical(GUI.skin.box);
                            {
                                EditorGUI.indentLevel++;
                                OpenSurfaces = EditorGUILayout.Foldout(OpenSurfaces, SurfacesContent);
                                EditorGUI.indentLevel--;
                                if (OpenSurfaces)
                                {
                                    var targetShape     = targetBrushes[0].Shape;
                                    var texGens         = targetShape.TexGens;
                                    var texGenFlagArray = targetShape.TexGenFlags;
                                    for (int t = 0; t < texGens.Length; t++)
                                    {
                                        GUILayout.Space(2);

                                        var texGenFlags = texGenFlagArray[t];
                                        var material    = targetShape.TexGens[t].RenderMaterial;
                                        EditorGUI.BeginChangeCheck();
                                        {
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Space(4);
                                                material = CSG_EditorGUIUtility.MaterialImage(material);
                                                GUILayout.Space(2);
                                                GUILayout.BeginVertical();
                                                {
                                                    EditorGUI.BeginDisabledGroup(texGenFlags != TexGenFlags.None);
                                                    {
                                                        material = EditorGUILayout.ObjectField(material, typeof(Material), true) as Material;
                                                    }
                                                    EditorGUI.EndDisabledGroup();

                                                    texGenFlags = EditModeCommonGUI.OnSurfaceFlagButtons(texGenFlags);
                                                }
                                                GUILayout.EndVertical();
                                                GUILayout.Space(4);
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        if (EditorGUI.EndChangeCheck())
                                        {
                                            var selectedBrushSurfaces = new []
                                            {
                                                new SelectedBrushSurface(targetBrushes[0], t)
                                            };
                                            using (new UndoGroup(selectedBrushSurfaces, "discarding surface"))
                                            {
                                                texGenFlagArray[t] = texGenFlags;
                                                targetShape.TexGens[t].RenderMaterial = material;
                                            }
                                        }
                                        GUILayout.Space(4);
                                    }
                                }
                            }
                            GUILayout.EndVertical();
                        }
                    }

                    if (handleAsOne.HasValue)
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            EditorGUI.showMixedValue = selMixedValues;
                            handleAsOne = EditorGUILayout.Toggle(HandleAsOneLabel, handleAsOne.Value);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation 'Handle as one object'");
                            foreach (var operation in targetOperations)
                            {
                                operation.HandleAsOne = handleAsOne.Value;
                            }
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }
                }

        #if false
                if (targetNodes.Length == 1)
                {
                    var node  = targetNodes[0];
                    var brush = node as CSGBrush;
                    if (brush != null)
                    {
                        var brush_cache = CSGSceneManager.GetBrushCache(brush);
                        if (brush_cache == null ||
                            brush_cache.childData == null ||
                            brush_cache.childData.modelTransform == null)
                        {
                            EditorGUILayout.LabelField("brush-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("node-id: " + brush.nodeID + " brush-id: " + brush.brushID);
                        }
                    }
                    var operation = node as CSGOperation;
                    if (operation != null)
                    {
                        var operation_cache = CSGSceneManager.GetOperationCache(operation);
                        if (operation_cache == null ||
                            operation_cache.childData == null ||
                            operation_cache.childData.modelTransform == null)
                        {
                            EditorGUILayout.LabelField("operation-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("operation-id: " + operation.nodeID + " operation-id: " + operation.operationID);
                        }
                    }
                    var model = node as CSGModel;
                    if (model != null)
                    {
                        var model_cache = CSGSceneManager.GetModelCache(model);
                        if (model_cache == null ||
                            model_cache.meshContainer == null)
                        {
                            EditorGUILayout.LabelField("model-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("model-id: " + model.nodeID + " model-id: " + model.modelID);
                        }
                    }
                }
        #endif
            }
            finally
            {
                TooltipUtility.DrawToolTip(getLastRect: true, goUp: true);
            }
        }