static void UndoRedoPerformed()
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (instance.activeTool != null)
            {
                instance.activeTool.UndoRedoPerformed();
            }

            EditModeManager.UpdateSelection(forceUpdate: true);
        }
Example #2
0
 static void OnSelectionChanged()
 {
     EditModeManager.UpdateSelection();
 }
        protected void HandleHeightHandles(SceneView sceneView, Rect sceneRect, bool showHeightValue)
        {
            var camera = sceneView.camera;

            for (int p = 0; p < extrusionPoints.Length; p++)
            {
                var type = Event.current.GetTypeForControl(extrusionPoints[p].ID);
                switch (type)
                {
                case EventType.Repaint:
                {
                    if (SceneDragToolManager.IsDraggingObjectInScene)
                    {
                        break;
                    }

                    bool isSelected = extrusionPoints[p].ID == GUIUtility.keyboardControl;
                    var  temp       = Handles.color;
                    var  origMatrix = Handles.matrix;

                    Handles.matrix = MathConstants.identityMatrix;
                    var rotation = camera.transform.rotation;


                    var state = SelectState.None;
                    if (isSelected)
                    {
                        state |= SelectState.Selected;
                        state |= SelectState.Hovering;
                    }
                    else
                    if (HandleUtility.nearestControl == extrusionPoints[p].ID)
                    {
                        state |= SelectState.Hovering;
                    }


                    if (polygons != null && outlineVertices.Length >= 3)
                    {
                        var wireframeColor    = ColorSettings.WireframeOutline;
                        var topWireframeColor = ColorSettings.WireframeOutline;

                        if (!shapeIsValid)
                        {
                            wireframeColor = Color.red;
                        }

                        var surfaceColor = ColorSettings.ShapeDrawingFill;
                        if (GUIUtility.hotControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected | SelectState.Hovering)];
                            surfaceColor.a   *= 0.5f;
                        }
                        else
                        if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected)];
                            surfaceColor.a   *= 0.5f;
                        }


                        var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                        for (int i = 0; i < polygons.Length; i++)
                        {
                            PaintUtility.DrawPolygon(poly2dToWorldMatrix, polygons[i].Vertices, surfaceColor);
                        }

                        poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.identity, MathConstants.oneVector3);
                        for (int i = 1; i < outlineVertices.Length; i++)
                        {
                            PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], GUIConstants.oldLineScale, topWireframeColor);
                            PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], topWireframeColor, 4.0f);
                        }
                        PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], GUIConstants.oldLineScale, topWireframeColor);
                        PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], topWireframeColor, 4.0f);

                        if (p > 0)
                        {
                            var prevOffset = extrusionPoints[p - 1].Position;
                            var prevPoly2dToWorldMatrix = Matrix4x4.TRS(prevOffset, Quaternion.identity, MathConstants.oneVector3);
                            for (int i = 0; i < outlineVertices.Length; i++)
                            {
                                var from = prevPoly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                var to   = poly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                PaintUtility.DrawLine(from, to, GUIConstants.oldLineScale, wireframeColor);
                                PaintUtility.DrawDottedLine(from, to, wireframeColor, 4.0f);
                            }
                        }
                    }

                    var color = ColorSettings.PolygonInnerStateColor[(int)state];
                    if (!shapeIsValid)
                    {
                        color = Color.red;
                    }

                    var handleSize       = CSG_HandleUtility.GetHandleSize(extrusionPoints[p].Position);
                    var scaledHandleSize = handleSize * GUIConstants.handleScale;
                    if (p > 0)
                    {
                        PaintUtility.DrawDottedLine(extrusionPoints[p - 1].Position, extrusionPoints[p].Position, color, 4.0f);
                    }

                    Handles.color = color;
                    PaintUtility.SquareDotCap(extrusionPoints[p].ID, extrusionPoints[p].Position, rotation, scaledHandleSize);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    Handles.matrix = origMatrix;
                    Handles.color  = temp;

                    if (p > 0 && showHeightValue)
                    {
                        var length = GetSegmentLength(extrusionPoints[p].Position, extrusionPoints[p - 1].Position, direction);
                        PaintHeightMessage(camera, extrusionPoints[p - 1].Position, extrusionPoints[p].Position, gridTangent, length);
                    }
                    break;
                }

                case EventType.Layout:
                {
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan))
                    {
                        break;
                    }

                    var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                    var forceOverHandle     = IsMouseOverShapePolygons(poly2dToWorldMatrix);
                    HandleUtility.AddControl(extrusionPoints[p].ID, forceOverHandle ? 3.0f : float.PositiveInfinity);

                    var origMatrix = Handles.matrix;
                    Handles.matrix = MathConstants.identityMatrix;
                    float handleSize       = CSG_HandleUtility.GetHandleSize(extrusionPoints[p].Position);
                    float scaledHandleSize = handleSize * GUIConstants.handleScale * handle_extension;
                    float distanceToCircle = HandleUtility.DistanceToCircle(extrusionPoints[p].Position, scaledHandleSize);

                    HandleUtility.AddControl(extrusionPoints[p].ID, distanceToCircle);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                    {
                        for (int g = generatedGameObjects.Length - 1; g >= 0; g--)
                        {
                            if (generatedGameObjects[g])
                            {
                                continue;
                            }
                            ArrayUtility.RemoveAt(ref generatedGameObjects, g);
                        }

                        if (generatedGameObjects == null || generatedGameObjects.Length == 0)
                        {
                            Cancel();
                        }
                    }

                    Handles.matrix = origMatrix;
                    break;
                }

                case EventType.MouseDown:
                {
                    if (!sceneRect.Contains(Event.current.mousePosition))
                    {
                        break;
                    }
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan) ||
                        Event.current.modifiers != EventModifiers.None)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == 0 &&
                        HandleUtility.nearestControl == extrusionPoints[p].ID && Event.current.button == 0)
                    {
                        if (editMode != EditMode.ExtrudeShape &&
                            !StartExtrudeMode(camera))
                        {
                            Cancel();
                        }
                        else
                        {
                            UpdateBaseShape(registerUndo: false);
                            dragPositionStart = extrusionPoints[p].Position;
                            GrabHeightHandle(sceneView, p);
                            BeginExtrusion();
                            Event.current.Use();
                        }
                    }
                    break;
                }

                case EventType.MouseDrag:
                case EventType.MouseMove:
                {
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == extrusionPoints[p].ID)                            // && Event.current.button == 0)
                    {
                        Undo.RecordObject(this, "Extrude shape");
                        heightPosition += Event.current.delta;
                        Vector3 worldPosition = GetHeightHandlePosition(sceneView, extrusionPoints[p].Position) - heightHandleOffset;
                        if (float.IsInfinity(worldPosition.x) || float.IsNaN(worldPosition.x) ||
                            float.IsInfinity(worldPosition.y) || float.IsNaN(worldPosition.y) ||
                            float.IsInfinity(worldPosition.z) || float.IsNaN(worldPosition.z))
                        {
                            worldPosition = extrusionPoints[p].Position;
                        }

                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            CSGBrush snappedOnBrush = null;
                            worldPosition      = raySnapFunction(camera, worldPosition, new Ray(brushPosition, movePolygonDirection), ref visualSnappedEdges, out snappedOnBrush);
                            visualSnappedBrush = snappedOnBrush;
                        }

                        visualSnappedGrid = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(camera, worldPosition);

                        extrusionPoints[p].Position = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, brushPosition, movePolygonDirection);

                        if (p == 0)
                        {
                            MoveShape(extrusionPoints[0].Position - dragPositionStart);
                            UpdateBaseShape();
                        }

                        UpdateBrushPosition();
                        UpdateExtrudedShape();

                        GUI.changed = true;
                        Event.current.Use();
                        break;
                    }
                    break;
                }

                case EventType.MouseUp:
                {
                    forceDragHandle = false;
                    //forceDragSource = null;
                    if (GUIUtility.hotControl == extrusionPoints[p].ID &&
                        Event.current.button == 0 &&
                        (Tools.viewTool == ViewTool.None || Tools.viewTool == ViewTool.Pan))
                    {
                        EndExtrusion();
                        if (firstClick)
                        {
                            firstClick = false;
                            break;
                        }

                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;
                        Event.current.Use();

                        ResetVisuals();
                        CleanupGrid();

                        if (!HaveExtrusion)
                        {
                            RevertToEditVertices();
                        }

                        if (commitExtrusionAfterRelease)
                        {
                            var prevGeneratedBrushes = generatedBrushes;
                            Commit(camera);
                            // did we switch to edit mode?
                            if (EditModeManager.EditMode == ToolEditMode.Edit &&
                                prevGeneratedBrushes != null)
                            {
                                EditModeManager.UpdateTool();
                                EditModeManager.UpdateSelection(true);
                                var tool = EditModeManager.ActiveTool as EditModeMeshEdit;
                                if (tool)
                                {
                                    var brush        = prevGeneratedBrushes[0];
                                    var polygonCount = brush.ControlMesh.Polygons.Length;
                                    tool.SelectPolygon(brush, polygonCount - 2);                                             // select front most polygon
                                }
                            }
                        }
                        break;
                    }
                    break;
                }
                }
            }

            var shapeType = Event.current.GetTypeForControl(shapeId);

            HandleKeyboard(shapeType);
        }
        static void InitTools()
        {
            if (instance)
            {
                return;
            }


            var values = Enum.GetValues(typeof(ToolEditMode)).Cast <ToolEditMode>().ToList();

            values.Sort();
            firstEditMode = values[0];
            lastEditModes = values[values.Count - 1];

            Undo.undoRedoPerformed -= UndoRedoPerformed;
            Undo.undoRedoPerformed += UndoRedoPerformed;

            EditorApplication.modifierKeysChanged -= OnModifierKeysChanged;
            EditorApplication.modifierKeysChanged += OnModifierKeysChanged;


            var managers = Resources.FindObjectsOfTypeAll <EditModeManager>().ToArray();

            for (int i = 0; i < managers.Length; i++)
            {
                DestroyImmediate(managers[i]);
            }
            instance           = ScriptableObject.CreateInstance <EditModeManager>();
            instance.hideFlags = scriptableObjectHideflags;

            var types = new Type[]
            {
                typeof(EditModePlace),
                typeof(EditModeGenerate),
                typeof(EditModeMeshEdit),
                typeof(EditModeClip),
                typeof(EditModeSurface)
            };

            if (types.Length != values.Count)
            {
                Debug.LogWarning("types.Length != values.Count");
            }

            brushTools = new IEditMode[values.Count];
            for (int j = 0; j < types.Length; j++)
            {
                var objects = Resources.FindObjectsOfTypeAll(types[j]).ToArray();
                for (int i = 0; i < objects.Length; i++)
                {
                    DestroyImmediate(objects[i]);
                }

                var obj = ScriptableObject.CreateInstance(types[j]);
                brushTools[j] = obj as IEditMode;
                if (brushTools[j] == null)
                {
                    Debug.LogWarning("brushTools[j] == null");
                    continue;
                }
                if (!(brushTools[j] is ScriptableObject))
                {
                    Debug.LogWarning("!(brushTools[j] is ScriptableObject)");
                    continue;
                }
                obj.hideFlags = scriptableObjectHideflags;
            }

            EditModeGenerate.ShapeCommitted -= OnShapeCommittedEvent;
            EditModeGenerate.ShapeCommitted += OnShapeCommittedEvent;
            EditModeGenerate.ShapeCancelled -= OnShapeCancelledEvent;
            EditModeGenerate.ShapeCancelled += OnShapeCancelledEvent;

            RealtimeCSG.CSGSettings.Reload();
            instance.editMode = RealtimeCSG.CSGSettings.EditMode;

            EditModeManager.UpdateSelection(true);
            InitTargets();
        }