Пример #1
0
        // TODO: make selecting variants work when selecting in hierarchy/rect-select too
        public static void DoSelectionClick(SceneView sceneView, Vector2 mousePosition)
        {
            CSGTreeBrushIntersection intersection;
            var gameobject = CSGClickSelectionManager.PickClosestGameObject(Event.current.mousePosition, out intersection);

            // If we're a child of an operation that has a "handle as one" flag set, return that instead
            gameobject = CSGSceneQuery.GetContainerGameObject(gameobject);

            var selectionType = GetCurrentSelectionType();

            var selectedObjectsOnClick = new List <int>(Selection.instanceIDs);

            switch (selectionType)
            {
            case SelectionType.Additive:
            {
                if (!gameobject)
                {
                    break;
                }

                CSGSyncSelection.SelectBrushVariant(intersection.brush, uniqueSelection: false);
                var instanceID = gameobject.GetInstanceID();
                selectedObjectsOnClick.Add(instanceID);
                Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                break;
            }

            case SelectionType.Subtractive:
            {
                if (!gameobject)
                {
                    break;
                }

                Undo.RecordObject(CSGSyncSelection.Instance, "Deselected brush variant");
                CSGSyncSelection.DeselectBrushVariant(intersection.brush);
                // Can only deselect brush if all it's synchronized brushes have also been deselected
                if (!CSGSyncSelection.IsAnyBrushVariantSelected(intersection.brush))
                {
                    var instanceID = gameobject.GetInstanceID();
                    selectedObjectsOnClick.Remove(instanceID);
                }
                Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                return;
            }

            default:
            {
                Undo.RecordObject(CSGSyncSelection.Instance, "Selected brush variant");
                CSGSyncSelection.SelectBrushVariant(intersection.brush, uniqueSelection: true);
                Selection.activeGameObject = gameobject;
                break;
            }
            }
        }
Пример #2
0
        static void OnMoveTool()
        {
            var position = Tools.handlePosition;
            var rotation = Tools.handleRotation;

#if SYNC_SUPPORT // TODO: finish and fix this
            var selectedNodes = Selection.GetFiltered <CSGNode>(SelectionMode.Editable | SelectionMode.TopLevel);
            if (selectedNodes.Length == 0)
            {
                // TODO: probably need to use our own PositionHandle on non CSG objects, to be able to snap to grid
                return;
            }


            var transformation    = Matrix4x4.identity;
            var invTransformation = Matrix4x4.identity;

            // TODO: figure out how to handle this with selecting multiple variants of the same brush (synchronized brushes)
            if (selectedNodes.Length == 1)
            {
                foundTreeBrushes.Clear();
                selectedNodes[0].GetAllTreeBrushes(foundTreeBrushes, ignoreSynchronizedBrushes: true);
                if (foundTreeBrushes.Count == 1)
                {
                    var transform  = CSGNodeHierarchyManager.FindModelTransformOfTransform(selectedNodes[0].hierarchyItem.Transform);
                    var firstBrush = foundTreeBrushes.First();
                    var brush      = firstBrush;
                    if (!CSGSyncSelection.IsBrushVariantSelected(brush))
                    {
                        List <CSGTreeBrush> selectedVariants = new List <CSGTreeBrush>();
                        if (CSGSyncSelection.GetSelectedVariantsOfBrush(brush, selectedVariants))
                        {
                            brush = selectedVariants[0];
                        }
                    }
                    if (transform)
                    {
                        transformation = transform.localToWorldMatrix * brush.NodeToTreeSpaceMatrix;
                    }
                    else
                    {
                        transformation = brush.NodeToTreeSpaceMatrix;
                    }
                    rotation          = Quaternion.LookRotation(transformation.GetColumn(2), transformation.GetColumn(1));
                    invTransformation = selectedNodes[0].transform.localToWorldMatrix * transformation.inverse;
                    if (Tools.pivotRotation == PivotRotation.Global)
                    {
                        rotation = Quaternion.identity;
                    }
                    position = transformation.GetColumn(3);
                }
            }
#endif

            EditorGUI.BeginChangeCheck();
            // TODO: make this work with bounds!
            var newPosition = UnitySceneExtensions.SceneHandles.PositionHandle(position, rotation);
            if (EditorGUI.EndChangeCheck())
            {
                var delta      = newPosition - position;
                var transforms = Selection.transforms;
                if (transforms != null && transforms.Length > 0)
                {
                    MoveTransformsTo(transforms, delta);
                }
            }
        }
Пример #3
0
        internal static void Update(SceneView sceneView)
        {
            if (!CSGRectSelection.Valid)
            {
                prevStartGUIPoint    = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
                prevMouseGUIPoint    = prevStartGUIPoint;
                prevStartScreenPoint = Vector2.zero;
                prevMouseScreenPoint = Vector2.zero;
                rectFoundGameObjects.Clear();
                rectFoundTreeNodes.Clear();
                return;
            }

            CSGRectSelection.SceneView = sceneView;

            var rectSelectionID  = CSGRectSelection.RectSelectionID;
            var hotControl       = GUIUtility.hotControl;
            var areRectSelecting = hotControl == rectSelectionID;
            var typeForControl   = Event.current.GetTypeForControl(rectSelectionID);

            // check if we're rect-selecting
            if (areRectSelecting)
            {
                if ((typeForControl == EventType.Used || Event.current.commandName == "ModifierKeysChanged") &&
                    CSGRectSelection.RectSelecting)
                {
                    var selectStartPoint = CSGRectSelection.SelectStartPoint;
                    var selectMousePoint = CSGRectSelection.SelectMousePoint;

                    // determine if our frustum changed since the last time
                    bool modified   = false;
                    bool needUpdate = false;
                    if (prevStartGUIPoint != selectStartPoint)
                    {
                        prevStartGUIPoint    = selectStartPoint;
                        prevStartScreenPoint = Event.current.mousePosition;
                        needUpdate           = true;
                    }
                    if (prevMouseGUIPoint != selectMousePoint)
                    {
                        prevMouseGUIPoint    = selectMousePoint;
                        prevMouseScreenPoint = Event.current.mousePosition;
                        needUpdate           = true;
                    }
                    if (needUpdate)
                    {
                        var rect = CSGCameraUtility.PointsToRect(prevStartScreenPoint, prevMouseScreenPoint);
                        if (rect.width > 3 &&
                            rect.height > 3)
                        {
                            var frustum = CSGCameraUtility.GetCameraSubFrustum(Camera.current, rect);

                            // Find all the brushes (and it's gameObjects) that are inside the frustum
                            if (!CSGSceneQuery.GetNodesInFrustum(frustum, UnityEditor.Tools.visibleLayers, ref rectFoundTreeNodes))
                            {
                                if (rectFoundGameObjects != null &&
                                    rectFoundGameObjects.Count > 0)
                                {
                                    rectFoundTreeNodes.Clear();
                                    rectFoundGameObjects.Clear();
                                    modified = true;
                                }
                            }
                            else
                            {
                                modified = true;
                            }

                            var selectionType = GetCurrentSelectionType();
                            foreach (var treeNode in rectFoundTreeNodes)
                            {
                                var brush = (CSGTreeBrush)treeNode;
                                if (brush.Valid)
                                {
                                    switch (selectionType)
                                    {
                                    case SelectionType.Additive:
                                    {
                                        CSGSyncSelection.SelectBrushVariant(brush, uniqueSelection: false);
                                        break;
                                    }

                                    case SelectionType.Subtractive:
                                    {
                                        CSGSyncSelection.DeselectBrushVariant(brush);
                                        break;
                                    }

                                    default:
                                    {
                                        CSGSyncSelection.SelectBrushVariant(brush, uniqueSelection: true);
                                        break;
                                    }
                                    }
                                }
                                var nodeComponent = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(treeNode);
                                if (!nodeComponent)
                                {
                                    continue;
                                }
                                var gameObject = nodeComponent.gameObject;
                                rectFoundGameObjects.Add(gameObject);
                            }
                        }
                    }

                    UnityEngine.Object[] currentSelection = null;
                    var originalLastSelection             = CSGRectSelection.LastSelection;
                    var originalSelectionStart            = CSGRectSelection.SelectionStart;

                    if (modified &&
                        rectFoundGameObjects != null &&
                        rectFoundGameObjects.Count > 0)
                    {
                        foreach (var obj in rectFoundGameObjects)
                        {
                            // if it hasn't already been added, add the obj
                            if (!originalLastSelection.ContainsKey(obj))
                            {
                                originalLastSelection.Add(obj, false);
                            }
                        }

                        currentSelection = originalLastSelection.Keys.ToArray();
                        CSGRectSelection.CurrentSelection = currentSelection;
                    }
                    else
                    {
                        if (currentSelection == null || modified)
                        {
                            currentSelection = originalLastSelection.Keys.ToArray();
                        }
                    }

                    if (RemoveGeneratedMeshesFromArray(ref originalSelectionStart))
                    {
                        modified = true;
                    }

                    if (currentSelection != null && RemoveGeneratedMeshesFromArray(ref currentSelection))
                    {
                        modified = true;
                    }

                    if ((Event.current.commandName == "ModifierKeysChanged" || modified))
                    {
                        var foundObjects = currentSelection;

                        RemoveGeneratedMeshesFromArray(ref foundObjects);

                        // calling static method UpdateSelection of RectSelection
                        CSGRectSelection.UpdateSelection(originalSelectionStart, foundObjects, GetCurrentSelectionType());
                    }
                }
                hotControl = GUIUtility.hotControl;
            }

            if (hotControl != rectSelectionID)
            {
                prevStartGUIPoint = Vector2.zero;
                prevMouseGUIPoint = Vector2.zero;
                rectFoundGameObjects.Clear();
                rectFoundTreeNodes.Clear();
            } /*else
               * if (ignoreRect)
               * {
               * hotControl = 0;
               * GUIUtility.hotControl = 0;
               * }
               */

            bool click = false;
            var  evt   = Event.current;

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

            case EventType.MouseUp:
            {
                if (!mouseDragged)
                {
                    if ((UnityEditor.HandleUtility.nearestControl != 0 || evt.button != 0) &&
                        (GUIUtility.keyboardControl != 0 || evt.button != 2))
                    {
                        break;
                    }
                    click = true;
                    Event.current.Use();
                }
                rectClickDown = false;
                break;
            }

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

            case EventType.MouseDrag:
            {
                mouseDragged = true;
                break;
            }

            case EventType.Used:
            {
                if (!mouseDragged)
                {
                    var delta = Event.current.mousePosition - clickMousePosition;
                    if (Mathf.Abs(delta.x) > 4 || Mathf.Abs(delta.y) > 4)
                    {
                        mouseDragged = true;
                    }
                }
                if (mouseDragged || !rectClickDown || Event.current.button != 0 || CSGRectSelection.RectSelecting)
                {
                    rectClickDown = false; break;
                }

                click = true;
                Event.current.Use();
                break;
            }

            case EventType.KeyUp:
            {
                if (hotControl == 0 &&
                    Event.current.keyCode == UnityEngine.KeyCode.Escape)
                {
                    Selection.activeTransform = null;
                }
                break;
            }

            case EventType.ValidateCommand:
            {
                if (Event.current.commandName != "SelectAll")
                {
                    break;
                }

                Event.current.Use();
                break;
            }

            case EventType.ExecuteCommand:
            {
                if (Event.current.commandName != "SelectAll")
                {
                    break;
                }

                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);
                        }
                    }
                }

                var foundObjects = transforms.ToArray();

                RemoveGeneratedMeshesFromArray(ref foundObjects);

                Selection.objects = foundObjects;

                Event.current.Use();
                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;
                 * }
                 */
            }

            if (click)
            {
                // make sure GeneratedMeshes are not part of our selection
                RemoveGeneratedMeshesFromSelection();

                DoSelectionClick(sceneView, Event.current.mousePosition);
            }
        }