예제 #1
0
        // TODO: make selecting variants work when selecting in hierarchy/rect-select too
        public static void DoSelectionClick(SceneView sceneView, Vector2 mousePosition)
        {
            ChiselIntersection intersection;
            var gameobject = ChiselClickSelectionManager.PickClosestGameObject(mousePosition, out intersection);

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

            var selectionType = GetCurrentSelectionType();

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

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

                ChiselSyncSelection.SelectBrushVariant(intersection.brushIntersection.brush, uniqueSelection: false);
                var instanceID = gameobject.GetInstanceID();
                selectedObjectsOnClick.Add(instanceID);
                ChiselClickSelectionManager.ignoreSelectionChanged = true;
                Selection.instanceIDs = selectedObjectsOnClick.ToArray();
                break;
            }

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

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

            default:
            {
                Undo.RecordObject(ChiselSyncSelection.Instance, "Selected brush variant");
                ChiselSyncSelection.SelectBrushVariant(intersection.brushIntersection.brush, uniqueSelection: true);
                ChiselClickSelectionManager.ignoreSelectionChanged = true;
                Selection.activeGameObject = gameobject;
                break;
            }
            }
        }
예제 #2
0
        void UpdateBrushState()
        {
            if (updateBrushSelection)
            {
                updateBrushSelection = false;
                UpdateBrushSelection();
                updateBrushWireframe = true;
            }
            if (updateBrushWireframe)
            {
                updateBrushWireframe = false;
                UpdateBrushWireframe();
                updateBrushLineCache = true;
            }
            if (updateBrushLineCache)
            {
                updateBrushLineCache = false;
                brushOutlineRenderer.Begin();

                foreach (var pair in brushOutlines)
                {
                    var wireframe = pair.Value;
                    if (wireframe == null)
                    {
                        continue;
                    }

                    var outline = pair.Key;
                    if (!outline.brush.Valid)
                    {
                        continue;
                    }

                    // TODO: simplify this
                    var wireframeValue = pair.Value;
                    var modelTransform = outline.transform;
                    //var brushes		= outline.brush.AllSynchronizedVariants;
                    //var anySelected	= ChiselSyncSelection.IsAnyBrushVariantSelected(brushes);

                    //foreach (var brush in brushes)
                    var brush       = outline.brush;
                    var anySelected = ChiselSyncSelection.IsBrushVariantSelected(brush);
                    {
                        Matrix4x4 transformation;
                        if (modelTransform)
                        {
                            transformation = modelTransform.localToWorldMatrix * brush.NodeToTreeSpaceMatrix;
                        }
                        else
                        {
                            transformation = brush.NodeToTreeSpaceMatrix;
                        }

                        if ((VisualizationMode & VisualizationMode.Outline) == VisualizationMode.Outline)
                        {
                            var directSelect = !ChiselEditModeManager.EditMode.ShowCompleteOutline &&
                                               ((brush == outline.brush && !anySelected) || (anySelected && ChiselSyncSelection.IsBrushVariantSelected(brush)));

                            // TODO: tweak look of selection, figure out how to do backfaced lighting of edges, for clarity
                            // TODO: support selecting surfaces/edges/points (without showing the entire object selection)
                            if (directSelect)
                            {
                                brushOutlineRenderer.DrawOutlines(transformation, wireframeValue, ColorManager.kSelectedOutlineColor, thickness: 3.0f, onlyInnerLines: false);
                            }
                            else
                            {
                                brushOutlineRenderer.DrawOutlines(transformation, wireframeValue, ColorManager.kUnselectedOutlineColor, thickness: 1.0f, onlyInnerLines: false);// (ChiselEditModeManager.EditMode == CSGEditMode.ShapeEdit));
                            }
                        }

                        if ((VisualizationMode & VisualizationMode.SimpleOutline) == VisualizationMode.SimpleOutline)
                        {
                            brushOutlineRenderer.DrawSimpleOutlines(transformation, wireframeValue, ColorManager.kUnselectedOutlineColor);
                        }
                    }
                }
                brushOutlineRenderer.End();
            }
        }
예제 #3
0
        internal static void Update(SceneView sceneView)
        {
            if (!ChiselRectSelection.Valid)
            {
                prevStartGUIPoint    = new Vector2(float.PositiveInfinity, float.PositiveInfinity);
                prevMouseGUIPoint    = prevStartGUIPoint;
                prevStartScreenPoint = Vector2.zero;
                prevMouseScreenPoint = Vector2.zero;
                rectFoundGameObjects.Clear();
                rectFoundTreeNodes.Clear();
                return;
            }

            ChiselRectSelection.SceneView = sceneView;

            var rectSelectionID  = ChiselRectSelection.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") &&
                    ChiselRectSelection.RectSelecting)
                {
                    var selectStartPoint = ChiselRectSelection.SelectStartPoint;
                    var selectMousePoint = ChiselRectSelection.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 = ChiselCameraUtility.PointsToRect(prevStartScreenPoint, prevMouseScreenPoint);
                        if (rect.width > 3 &&
                            rect.height > 3)
                        {
                            var frustum       = ChiselCameraUtility.GetCameraSubFrustum(Camera.current, rect);
                            var selectionType = GetCurrentSelectionType();

                            if (selectionType == SelectionType.Replace)
                            {
                                rectFoundTreeNodes.Clear();
                                rectFoundGameObjects.Clear();
                            }


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

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

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

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

                    UnityEngine.Object[] currentSelection = null;
                    var originalLastSelection             = ChiselRectSelection.LastSelection;
                    var originalSelectionStart            = ChiselRectSelection.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();
                        ChiselRectSelection.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
                        ChiselRectSelection.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 || ChiselRectSelection.RectSelecting)
                {
                    rectClickDown = false; break;
                }

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

            case EventType.KeyUp:
            {
                if (hotControl == 0 &&
                    Event.current.keyCode == UnityEngine.KeyCode.Escape)
                {
                    if (GUIUtility.hotControl == 0 &&     // make sure we're not actively doing anything
                        Tools.current != Tool.Custom)
                    {
                        // This deselects everything and disables all tool modes
                        Selection.activeTransform = null;
                        Event.current.Use();
                    }
                }
                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);
            }
        }
예제 #4
0
        static void OnMoveTool()
        {
            var position = Tools.handlePosition;
            var rotation = Tools.handleRotation;

#if SYNC_SUPPORT // TODO: finish and fix this
            var selectedNodes = Selection.GetFiltered <ChiselNode>(SelectionMode.Editable | SelectionMode.TopLevel);
            if (selectedNodes.Length == 0)
            {
                // TODO: probably need to use our own PositionHandle on non Chisel 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  = ChiselNodeHierarchyManager.FindModelTransformOfTransform(selectedNodes[0].hierarchyItem.Transform);
                    var firstBrush = foundTreeBrushes.First();
                    var brush      = firstBrush;
                    if (!ChiselSyncSelection.IsBrushVariantSelected(brush))
                    {
                        List <CSGTreeBrush> selectedVariants = new List <CSGTreeBrush>();
                        if (ChiselSyncSelection.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);
                }
            }
        }