Beispiel #1
0
        public override void OnSceneGUI(SceneView sceneView, Event e)
        {
            base.OnSceneGUI(sceneView, e);             // Allow the base logic to calculate first

            // If any points are selected let the handles move them
            if (pointSelected > -1)
            {
                EditorGUI.BeginChangeCheck();
                // Display a handle and allow the user to determine a new position in world space
                Vector3 newWorldPosition = Handles.PositionHandle(points[pointSelected], Quaternion.identity);

                if (EditorGUI.EndChangeCheck())
                {
                    Vector3 newPosition = newWorldPosition;

                    Vector3 accumulatedDelta = newPosition - startPosition;

                    if (CurrentSettings.PositionSnappingEnabled)
                    {
                        float snapDistance = CurrentSettings.PositionSnapDistance;
                        accumulatedDelta = MathHelper.RoundVector3(accumulatedDelta, snapDistance);
                    }

                    newPosition = startPosition + accumulatedDelta;

                    points[pointSelected] = newPosition;

                    e.Use();
                }
            }



            // First let's see if we can select any existing points
            if (e.type == EventType.MouseDown || e.type == EventType.MouseUp)
            {
                if (!EditorHelper.IsMousePositionNearSceneGizmo(e.mousePosition))
                {
                    OnMouseSelection(sceneView, e);
                }
            }

            if (e.button == 0 && e.type == EventType.MouseDrag && !CameraPanInProgress)
            {
                planeEstablished = false;
            }

            // Forward specific events on to handlers
            if (e.type == EventType.MouseDown || e.type == EventType.MouseUp || e.type == EventType.MouseDrag || e.type == EventType.MouseMove)
            {
                if (sceneView.camera.orthographic && EditorHelper.GetSceneViewCamera(sceneView) != EditorHelper.SceneViewCamera.Other)
                {
                    OnMouseActionOrthographic(sceneView, e);
                }
                else
                {
                    OnMouseAction3D(sceneView, e);
                }
            }
            else if (e.type == EventType.Repaint || e.type == EventType.Layout)
            {
                OnRepaint(sceneView, e);
            }
            else if (e.type == EventType.KeyDown || e.type == EventType.KeyUp)
            {
                OnKeyAction(sceneView, e);
            }
        }
        // Select any vertices
        void OnMouseUp(SceneView sceneView, Event e)
        {
            if (e.button == 0 && !CameraPanInProgress)
            {
                Transform sceneViewTransform = sceneView.camera.transform;
                Vector3   sceneViewPosition  = sceneViewTransform.position;
                if (moveInProgress)
                {
                }
                else
                {
                    if (isMarqueeSelection)                    // Marquee vertex selection
                    {
                        selectedEdges.Clear();

                        isMarqueeSelection = false;

                        marqueeEnd = e.mousePosition;

                        foreach (PrimitiveBrush brush in targetBrushes)
                        {
                            Polygon[] polygons = brush.GetPolygons();

                            for (int i = 0; i < polygons.Length; i++)
                            {
                                Polygon polygon = polygons[i];

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

                                    Vector3 worldPosition = brush.transform.TransformPoint(vertex.Position);
                                    Vector3 screenPoint   = sceneView.camera.WorldToScreenPoint(worldPosition);

                                    // Point is contained within marquee box
                                    if (SabreMouse.MarqueeContainsPoint(marqueeStart, marqueeEnd, screenPoint))
                                    {
                                        if (EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Control))
                                        {
                                            // Only when holding control should a deselection occur from a valid point
                                            selectedVertices.Remove(vertex);
                                        }
                                        else
                                        {
                                            // Point was in marquee (and ctrl wasn't held) so select it!
                                            if (!selectedVertices.ContainsKey(vertex))
                                            {
                                                selectedVertices.Add(vertex, brush);
                                            }
                                        }
                                    }
                                    else if (!EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Control) &&
                                             !EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Shift))
                                    {
                                        selectedVertices.Remove(vertex);
                                    }
                                }
                            }
                        }
                        SceneView.RepaintAll();
                    }
                    else if (!EditorHelper.IsMousePositionInInvalidRects(e.mousePosition) && !marqueeCancelled)                     // Clicking style vertex selection
                    {
                        Vector2 mousePosition = e.mousePosition;

                        bool clickedAnyPoints = false;
//						Vertex closestVertexFound = null;
                        Vector3 closestVertexWorldPosition = Vector3.zero;
                        float   closestDistanceSquare      = float.PositiveInfinity;

                        foreach (PrimitiveBrush brush in targetBrushes)
                        {
                            Polygon[] polygons = brush.GetPolygons();
                            for (int i = 0; i < polygons.Length; i++)
                            {
                                Polygon polygon = polygons[i];

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

                                    Vector3 worldPosition = brush.transform.TransformPoint(vertex.Position);

                                    float vertexDistanceSquare = (sceneViewPosition - worldPosition).sqrMagnitude;

                                    if (EditorHelper.InClickZone(mousePosition, worldPosition) && vertexDistanceSquare < closestDistanceSquare)
                                    {
//										closestVertexFound = vertex;
                                        closestVertexWorldPosition = worldPosition;
                                        clickedAnyPoints           = true;
                                        closestDistanceSquare      = vertexDistanceSquare;
                                    }
                                }
                            }
                        }

                        if (!EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Control) && !EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Shift))
                        {
                            ClearSelection();
                        }

                        foreach (PrimitiveBrush brush in targetBrushes)
                        {
                            Polygon[] polygons = brush.GetPolygons();
                            for (int i = 0; i < polygons.Length; i++)
                            {
                                Polygon polygon = polygons[i];

                                for (int j = 0; j < polygon.Vertices.Length; j++)
                                {
                                    Vertex  vertex        = polygon.Vertices[j];
                                    Vector3 worldPosition = brush.transform.TransformPoint(vertex.Position);
                                    if (clickedAnyPoints && worldPosition == closestVertexWorldPosition)
                                    {
                                        if (EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Control))
                                        {
                                            if (!selectedVertices.ContainsKey(vertex))
                                            {
                                                selectedVertices.Add(vertex, brush);
                                            }
                                            else
                                            {
                                                selectedVertices.Remove(vertex);
                                            }
                                        }
                                        else
                                        {
                                            if (!selectedVertices.ContainsKey(vertex))
                                            {
                                                selectedVertices.Add(vertex, brush);
                                            }
                                        }
                                    }
                                    else if (!EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Control) &&
                                             !EnumHelper.IsFlagSet(e.modifiers, EventModifiers.Shift))
                                    {
                                        selectedVertices.Remove(vertex);
                                    }
                                }
                            }
                        }


                        if (!clickedAnyPoints)                        // Couldn't click any directly, next try to click an edge
                        {
                            Edge    selectedEdge = null;
                            Vector3 selectedEdgeWorldPosition1 = Vector3.zero;
                            Vector3 selectedEdgeWorldPosition2 = Vector3.zero;
                            // Used to track the closest edge clicked, so if we could click through several edges with
                            // one click, then we only count the closest
                            float closestFound = float.PositiveInfinity;

                            foreach (PrimitiveBrush brush in targetBrushes)
                            {
                                Polygon[] polygons = brush.GetPolygons();
                                for (int i = 0; i < polygons.Length; i++)
                                {
                                    Polygon polygon = polygons[i];
                                    for (int j = 0; j < polygon.Vertices.Length; j++)
                                    {
                                        Vector3 worldPoint1 = brush.transform.TransformPoint(polygon.Vertices[j].Position);
                                        Vector3 worldPoint2 = brush.transform.TransformPoint(polygon.Vertices[(j + 1) % polygon.Vertices.Length].Position);

                                        // Distance from the mid point of the edge to the camera
                                        float squareDistance = (Vector3.Lerp(worldPoint1, worldPoint2, 0.5f) - Camera.current.transform.position).sqrMagnitude;

                                        float screenDistance = HandleUtility.DistanceToLine(worldPoint1, worldPoint2);
                                        if (screenDistance < EDGE_SCREEN_TOLERANCE && squareDistance < closestFound)
                                        {
                                            selectedEdgeWorldPosition1 = worldPoint1;
                                            selectedEdgeWorldPosition2 = worldPoint2;
                                            selectedEdge = new Edge(polygon.Vertices[j], polygon.Vertices[(j + 1) % polygon.Vertices.Length]);

                                            closestFound = squareDistance;
                                        }
                                    }
                                }
                            }

                            List <Vertex> newSelectedVertices = new List <Vertex>();

                            if (selectedEdge != null)
                            {
                                newSelectedVertices.Add(selectedEdge.Vertex1);
                                newSelectedVertices.Add(selectedEdge.Vertex2);

                                selectedEdges.Add(selectedEdge);

                                foreach (PrimitiveBrush brush in targetBrushes)
                                {
                                    Polygon[] polygons = brush.GetPolygons();

                                    for (int i = 0; i < polygons.Length; i++)
                                    {
                                        Polygon polygon = polygons[i];

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

                                            Vector3 worldPosition = brush.transform.TransformPoint(vertex.Position);
                                            if (worldPosition == selectedEdgeWorldPosition1 ||
                                                worldPosition == selectedEdgeWorldPosition2)
                                            {
                                                if (!selectedVertices.ContainsKey(vertex))
                                                {
                                                    selectedVertices.Add(vertex, brush);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    moveInProgress = false;


                    // Repaint all scene views to show the selection change
                    SceneView.RepaintAll();
                }

                if (selectedVertices.Count > 0)
                {
                    e.Use();
                }
            }
        }
Beispiel #3
0
        void OnRepaint(SceneView sceneView, Event e)
        {
            if (primaryTargetBrush != null)
            {
                // Use a helper method to draw a visualisation of the clipping plane
                float largestExtent = GetBounds().GetLargestExtent();
                float planeSize     = largestExtent * 4f;
//				clipPlane.
                SabreGraphics.DrawPlane(displayPlane, planePosition, new Color(0f, 1f, 0f, .3f), new Color(1f, 0f, 0f, .3f), planeSize);

                // Selected brush green outline
                SabreCSGResources.GetSelectedBrushMaterial().SetPass(0);

                // Draw black lines where the clip plane intersects the brushes
                if (!sceneView.camera.orthographic || EditorHelper.GetSceneViewCamera(sceneView) == EditorHelper.SceneViewCamera.Other)
                {
                    GL.Begin(GL.LINES);
                    GL.Color(Color.black);

                    foreach (PrimitiveBrush brush in targetBrushes)
                    {
                        Polygon[] polygons = brush.GenerateTransformedPolygons();
                        foreach (Polygon polygon in polygons)
                        {
                            Vector3 position1;
                            Vector3 position2;
                            if (Polygon.PlanePolygonIntersection(polygon, out position1, out position2, displayPlane))
                            {
                                GL.Vertex(position1);
                                GL.Vertex(position2);
                            }
                        }
                    }

                    GL.End();
                }

                if (displayPoint)
                {
                    Camera sceneViewCamera = sceneView.camera;

                    SabreCSGResources.GetVertexMaterial().SetPass(0);
                    GL.PushMatrix();
                    GL.LoadPixelMatrix();

                    GL.Begin(GL.QUADS);


                    // Draw points in reverse order because we want the precedence to be Red, Green, Blue

                    GL.Color(Color.blue);

                    Vector3 target = sceneViewCamera.WorldToScreenPoint(points[2]);

                    if (target.z > 0)
                    {
                        // Make it pixel perfect
                        target = MathHelper.RoundVector3(target);
                        SabreGraphics.DrawBillboardQuad(target, 8, 8);
                    }

                    GL.Color(Color.green);

                    target = sceneViewCamera.WorldToScreenPoint(points[1]);

                    if (target.z > 0)
                    {
                        // Make it pixel perfect
                        target = MathHelper.RoundVector3(target);
                        SabreGraphics.DrawBillboardQuad(target, 8, 8);
                    }

                    GL.Color(Color.red);

                    target = sceneViewCamera.WorldToScreenPoint(points[0]);

                    if (target.z > 0)
                    {
                        // Make it pixel perfect
                        target = MathHelper.RoundVector3(target);
                        SabreGraphics.DrawBillboardQuad(target, 8, 8);
                    }

                    GL.End();
                    GL.PopMatrix();
                }
            }

            // Draw UI specific to this editor
//			GUI.backgroundColor = Color.red;
            Rect     rectangle = new Rect(0, 50, 210, 130);
            GUIStyle toolbar   = new GUIStyle(EditorStyles.toolbar);

            toolbar.normal.background = SabreCSGResources.ClearTexture;
            toolbar.fixedHeight       = rectangle.height;
            GUILayout.Window(140006, rectangle, OnToolbarGUI, "", toolbar);
        }
Beispiel #4
0
        void OnMouseAction3D(SceneView sceneView, Event e)
        {
            if (primaryTargetBrush == null || CameraPanInProgress || e.button != 0)
            {
                return;
            }

            Vector2 mousePosition = e.mousePosition;

            mousePosition = EditorHelper.ConvertMousePointPosition(mousePosition);

            Ray   ray          = Camera.current.ScreenPointToRay(mousePosition);
            float bestDistance = float.PositiveInfinity;

            Polygon bestPolygon = null;

            float testDistance;

            foreach (Brush brush in targetBrushes)
            {
                List <Polygon> polygons    = brush.GenerateTransformedPolygons().ToList();
                Polygon        testPolygon = GeometryHelper.RaycastPolygons(polygons, ray, out testDistance, 0.1f);
                if (testPolygon != null && testDistance < bestDistance)
                {
                    bestDistance = testDistance;
                    bestPolygon  = testPolygon;
                }
            }

            if (bestPolygon != null)
            {
//				VisualDebug.ClearAll();
//				VisualDebug.AddPolygon(hitPolygon, Color.red);
                Vector3 hitPoint = ray.GetPoint(bestDistance);

                if (e.type == EventType.MouseDown || e.type == EventType.MouseMove)
                {
                    if (e.type == EventType.MouseMove && planeEstablished)
                    {
                        return;
                    }

                    points[0]    = hitPoint;
                    displayPoint = true;

                    if (CurrentSettings.PositionSnappingEnabled)
                    {
                        float snapDistance = CurrentSettings.PositionSnapDistance;
                        points[0] = MathHelper.RoundVector3(points[0], snapDistance);
                    }

                    points[1] = points[0];
                    points[2] = points[0];

                    isFlipped = false;
                }
                else
                {
                    points[1] = hitPoint;

                    if (CurrentSettings.PositionSnappingEnabled)
                    {
                        float snapDistance = CurrentSettings.PositionSnapDistance;
                        points[1] = MathHelper.RoundVector3(points[1], snapDistance);
                    }
                    points[2] = points[0] - bestPolygon.Plane.normal;

                    if (e.type == EventType.MouseUp)
                    {
                        planeEstablished = true;

                        if (points[1] == points[0])
                        {
                            ResetTool();
                        }
                    }
                }
                SceneView.RepaintAll();
            }
        }
Beispiel #5
0
        void OnMouseActionOrthographic(SceneView sceneView, Event e)
        {
            if (primaryTargetBrush == null || CameraPanInProgress || e.button != 0)
            {
                return;
            }


            if (EditorHelper.IsMousePositionNearSceneGizmo(e.mousePosition))
            {
                return;
            }

            Vector2 mousePosition = e.mousePosition;

            mousePosition = EditorHelper.ConvertMousePointPosition(mousePosition);

            Ray ray = Camera.current.ScreenPointToRay(mousePosition);

            Plane   plane = new Plane(sceneView.camera.transform.forward, primaryTargetBrushTransform.position);
            Vector3 worldPoint;             // This is the point on the plane that is perpendicular to the camera
            float   distance = 0;

            if (plane.Raycast(ray, out distance))
            {
                worldPoint = ray.GetPoint(distance);
            }
            else
            {
                return;
            }

            if (e.type == EventType.MouseDown || e.type == EventType.MouseMove)
            {
                if (e.type == EventType.MouseMove && planeEstablished)
                {
                    return;
                }

                points[0]    = worldPoint;
                displayPoint = true;

                if (CurrentSettings.PositionSnappingEnabled)
                {
                    float snapDistance = CurrentSettings.PositionSnapDistance;
                    points[0] = MathHelper.RoundVector3(points[0], snapDistance);
                }

                points[1] = points[0];
                points[2] = points[0];

                isFlipped = false;
            }
            else
            {
                points[1] = worldPoint;

                if (CurrentSettings.PositionSnappingEnabled)
                {
                    float snapDistance = CurrentSettings.PositionSnapDistance;
                    points[1] = MathHelper.RoundVector3(points[1], snapDistance);
                }
                points[2] = points[0] + sceneView.camera.transform.forward;

                if (e.type == EventType.MouseUp)
                {
                    planeEstablished = true;

                    if (points[1] == points[0])
                    {
                        ResetTool();
                    }
                }
            }
            SceneView.RepaintAll();
        }
Beispiel #6
0
        public override void OnSceneGUI(UnityEditor.SceneView sceneView, Event e)
        {
            base.OnSceneGUI(sceneView, e);             // Allow the base logic to calculate first

            if (primaryTargetBrush != null && AnySelected)
            {
                if (startPositions.Count == 0)
                {
                    foreach (KeyValuePair <Vertex, Brush> selectedVertex in selectedVertices)
                    {
                        startPositions.Add(selectedVertex.Key, selectedVertex.Key.Position);
                    }
                }

                // Make the handle respect the Unity Editor's Local/World orientation mode
                Quaternion handleDirection = Quaternion.identity;
                if (Tools.pivotRotation == PivotRotation.Local)
                {
                    handleDirection = primaryTargetBrush.transform.rotation;
                }

                // Grab a source point and convert from local space to world
                Vector3 sourceWorldPosition = GetSelectedCenter();


                if (e.type == EventType.MouseUp)
                {
                    Undo.RecordObjects(targetBrushTransforms, "Moved Vertices");
                    Undo.RecordObjects(targetBrushes, "Moved Vertices");

                    AutoWeld();

                    foreach (PrimitiveBrush brush in targetBrushes)
                    {
                        brush.Invalidate(true);

                        brush.BreakTypeRelation();
                    }
                }

                EditorGUI.BeginChangeCheck();
                // Display a handle and allow the user to determine a new position in world space
                Vector3 newWorldPosition = Handles.PositionHandle(sourceWorldPosition, handleDirection);


                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObjects(targetBrushTransforms, "Moved Vertices");
                    Undo.RecordObjects(targetBrushes, "Moved Vertices");

                    Vector3 deltaWorld = newWorldPosition - sourceWorldPosition;

                    //				if(deltaLocal.sqrMagnitude > 0)
                    //				{
                    TranslateSelectedVertices(deltaWorld);
                    isMarqueeSelection = false;
                    moveInProgress     = true;
                    foreach (PrimitiveBrush brush in targetBrushes)
                    {
                        EditorUtility.SetDirty(brush);
                    }
                    e.Use();
                    // Shouldn't reset the pivot while the vertices are being manipulated, so make sure the pivot
                    // is set to get reset at next opportunity
                    pivotNeedsReset = true;
                }
                else
                {
                    // The user is no longer moving a handle
                    if (pivotNeedsReset)
                    {
                        // Pivot needs to be reset, so reset it!
                        foreach (PrimitiveBrush brush in targetBrushes)
                        {
                            brush.ResetPivot();
                        }

                        pivotNeedsReset = false;
                    }

                    startPositions.Clear();
                }
            }

            if (primaryTargetBrush != null)
            {
                if (!EditorHelper.IsMousePositionNearSceneGizmo(e.mousePosition))
                {
                    if (e.type == EventType.MouseDown)
                    {
                        OnMouseDown(sceneView, e);
                    }
                    else if (e.type == EventType.MouseDrag)
                    {
                        OnMouseDrag(sceneView, e);
                    }
                    // If you mouse up on a different scene view to the one you started on it's surpressed as Ignore, when
                    // doing marquee selection make sure to check the real type
                    else if (e.type == EventType.MouseUp || (isMarqueeSelection && e.rawType == EventType.MouseUp))
                    {
                        OnMouseUp(sceneView, e);
                    }
                }
            }

//			if(e.type == EventType.Repaint)
            {
                OnRepaint(sceneView, e);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Called whenever the editor updates and there was an event on the scene GUI.
        /// </summary>
        /// <param name="sceneView">The scene view.</param>
        /// <param name="e">The event information.</param>
        public override void OnSceneGUI(SceneView sceneView, Event e)
        {
            // allow the base logic to calculate first.
            base.OnSceneGUI(sceneView, e);

            // we adjust the toolbar size depending on the drawing mode.
            switch (drawingMode)
            {
            case DrawingMode.Color:
#if UNITY_2019_3_OR_NEWER
                toolbarHeight = 230;
#else
                toolbarHeight = 217;
#endif
                break;

            case DrawingMode.R:
            case DrawingMode.G:
            case DrawingMode.B:
            case DrawingMode.Alpha:
#if UNITY_2019_3_OR_NEWER
                toolbarHeight = 138;
#else
                toolbarHeight = 126;
#endif
                break;
            }

            if (e.button == 0 &&
                !EditorHelper.IsMousePositionInInvalidRects(e.mousePosition) &&
                !EditorHelper.IsMousePositionInIMGUIRect(e.mousePosition, actualToolbarRect) &&
                !CameraPanInProgress)
            {
                if (e.type == EventType.MouseDown)
                {
                    OnMouseDown(sceneView, e);
                }
                else if (e.type == EventType.MouseDrag)
                {
                    OnMouseDrag(sceneView, e);
                }
                else if (e.type == EventType.MouseMove)
                {
                    OnMouseMove(sceneView, e);
                }
                // If you mouse up on a different scene view to the one you started on it's surpressed as Ignore, so
                // make sure to check the real type
                else if (e.type == EventType.MouseUp || e.rawType == EventType.MouseUp)
                {
                    OnMouseUp(sceneView, e);
                }
            }

            if (e.type == EventType.KeyDown || e.type == EventType.KeyUp)
            {
                OnKeyAction(sceneView, e);
            }

            if (e.type == EventType.Layout || e.type == EventType.Repaint)
            {
                OnRepaint(sceneView, e);
            }
        }