Exemplo n.º 1
0
        private int SetVectors(RubberBand brush, ref Vector3 skewAxis, ref Vector3 perpAxis, ref Vector3 offset)
        {
            skewAxis = verticalMaskVector;
            perpAxis = horizontalMaskVector;
            offset   = brush.Bounds.Max;
            int sign = 1;

            if (hitStatus == SolidGrabHandles.HitStatus.Top ||
                hitStatus == SolidGrabHandles.HitStatus.Bottom)
            {
                skewAxis = horizontalMaskVector;
                perpAxis = verticalMaskVector;
            }

            // northern and eastern skew handles use the min vector as offset
            if (hitStatus == SolidGrabHandles.HitStatus.Top ||
                hitStatus == SolidGrabHandles.HitStatus.Right)
            {
                offset = brush.Bounds.Min;
            }

            // invert western and southern skewing factor
            if (hitStatus == SolidGrabHandles.HitStatus.Left ||
                hitStatus == SolidGrabHandles.HitStatus.Bottom)
            {
                sign = -1;
            }

            return(sign);
        }
Exemplo n.º 2
0
 public void Visit(RubberBand mapObject)
 {
     if (!SnapAabb(mapObject.Bounds))
     {
         TranslateBounds(mapObject.Bounds);
     }
 }
Exemplo n.º 3
0
        public void Visit(RubberBand mapObject)
        {
            if ((deltaStart - deltaEnd).Length < GeneralUtility.Epsilon)
            {
                return;
            }

            Vector3 planeNormal      = Vector3.UnitZ.TransformL(viewportMatrix);
            Vector3 axisMask         = KeepVectorAbsolute((Vector3.UnitX + Vector3.UnitY).TransformL(viewportMatrix));
            Vector3 axisRotationMask = KeepVectorAbsolute(planeNormal);

            // calculate angle
            Vector3 first  = Vector3.Multiply(deltaStart - mapObject.Bounds.Center, axisMask);
            Vector3 second = Vector3.Multiply(deltaEnd - mapObject.Bounds.Center, axisMask);

            float   angle = (float)first.SignedAngleTo(second, planeNormal);
            Vector3 euler = axisRotationMask * angle;

            euler = KeepEulerSnapped(euler);

            Matrix4 rotationMatrix = Matrix4.CreateRotationX(euler.X) * Matrix4.CreateRotationY(euler.Y) *
                                     Matrix4.CreateRotationZ(euler.Z);

            mapObject.Transformation = Matrix4.CreateTranslation(-mapObject.Bounds.Center) * rotationMatrix *
                                       Matrix4.CreateTranslation(mapObject.Bounds.Center);
        }
Exemplo n.º 4
0
        private float GetSkewFactor(RubberBand brush, Vector3 skewAxis, Vector3 perpAxis)
        {
            float delta = Vector3.Dot(deltaEnd - deltaStart, skewAxis);

            Vector3 brushDelta     = brush.Bounds.Max - brush.Bounds.Min;
            float   axisLength     = Vector3.Dot(brushDelta, skewAxis);
            float   perpAxisLength = Vector3.Dot(brushDelta, perpAxis);

            // we do multiply with the scale factor because we want the skew to be based of the skew axis
            // instead of the perpendicular axis
            float scaleFactor = axisLength / perpAxisLength;

            return(delta / axisLength * scaleFactor);
        }
Exemplo n.º 5
0
        public void Visit(RubberBand mapObject)
        {
            Vector3 skewAxis          = Vector3.Zero;
            Vector3 perpendicularAxis = Vector3.Zero;
            Vector3 offsetVector      = Vector3.Zero;

            // get the correct vectors
            int sign = SetVectors(mapObject, ref skewAxis, ref perpendicularAxis, ref offsetVector);

            // create the skew matrix
            float skewFactor = sign * GetSkewFactor(mapObject, skewAxis, perpendicularAxis);

            mapObject.Transformation = CreateSkewMatrix(skewAxis, skewFactor, perpendicularAxis, offsetVector);
        }
Exemplo n.º 6
0
            public override ToolState StartPointerSequence(PointerEventInfo info, ILevelGeometry viewport)
            {
                Band  = new RubberBand(new Point((int)info.X, (int)info.Y));
                Annot = new SelectionAnnot(new Point((int)info.X, (int)info.Y))
                {
                    Fill    = SelectionAnnotFill,
                    Outline = SelectionAnnotOutline,
                };

                Tool._annots.Add(Annot);
                Tool.StartAutoScroll(info, viewport);

                return(this);
            }
Exemplo n.º 7
0
        /// <summary>
        /// Resets editor tool state
        /// </summary>
        private void ResetEditorState()
        {
            editorViewport.ResetViewports();
            RubberBand.SetToZeroVolume();
            Selection.Clear();
            CopyBoard.Clear();
            ResetRenderModeToolbarAndMenu();
            creationButtonsPanel.UpdatePrimitiveToolbar("box");
            SetSolidManipulationMode("solid");
            UpdateSolidManipulationToolbar(SolidManipulationMode.Solid);
            UpdateGroupToolbar();

            CurrentTool = new SolidManipulationTool();
            CurrentTool.Initialize(this);
        }
Exemplo n.º 8
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            var mouse = MouseZoom(e.Location);

            if (draggedShape != null)
            {
                DragShape(e);

                if (dragStarted)
                {
                    view.Model.ReRouteTask(draggedShape.Task);
                }

                Invalidate();
                draggedShape = null;
            }
            if (draggedSegment != null)
            {
                draggedSegment.Connector.Normalise();
                draggedSegment = null;
            }
            if (rubberBand != null)
            {
                rubberBand.MouseUp(mouse);
                rubberBand = null;
                Invalidate();
            }
            if (panning)
            {
                Cursor  = Cursors.Default;
                panning = false;
                Invalidate();
            }
            if (selectionFrame != null)
            {
                var frame   = selectionFrame.Frame;
                var topLeft = PointToClient(frame.Location);
                var rect    = new Rectangle(
                    (int)Math.Floor(topLeft.X / zoom),
                    (int)Math.Floor(topLeft.Y / zoom),
                    (int)Math.Ceiling(frame.Width / zoom),
                    (int)Math.Ceiling(frame.Height / zoom));
                View.Selection.SelectInRectangle(rect);
                selectionFrame = null;
                Invalidate();
            }
            UpdateSize();
        }
Exemplo n.º 9
0
        public override bool OnMouseDown(Point mouseCurPos, MouseButtons button, BaseViewport viewport)
        {
            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE &&
                button == MouseButtons.Left)
            {
                RubberBand rubberBand = controller.RubberBand;

                bool controlPressed     = Control.ModifierKeys == Keys.Control;
                bool isSelectedSolidHit = IsSelectedSolidAabbHit(mouseCurPos.X, mouseCurPos.Y, viewport);
                bool isGrabHandleHit    = GetGrableHandleHit(mouseCurPos.X, mouseCurPos.Y, viewport) != (int)SolidGrabHandles.HitStatus.None;

                // check if we want to do something with the selected solids
                if ((isSelectedSolidHit || isGrabHandleHit) && !controlPressed)
                {
                    currentAction     = isSelectedSolidHit ? SolidToolActionType.Drag : SolidToolActionType.Transform;
                    rubberBand.Color  = Color.Red;
                    rubberBand.Bounds = (AABB)controller.Selection.Bounds.Clone();
                }
                else
                {
                    // default is solid creation
                    rubberBand.Color = Color.Yellow;
                    currentAction    = SolidToolActionType.Create;

                    MapObject hitMapObject = controller.GetMapObjectIfHit(mouseCurPos.X, mouseCurPos.Y, viewport);
                    SelectMapObject(hitMapObject);
                    controller.UpdateUserInterface();
                    if (hitMapObject != null)
                    {
                        currentAction = SolidToolActionType.Select;
                    }
                }
            }
            else if (button == MouseButtons.Left)
            {
                MapObject hitMapObject = controller.GetMapObjectIfHit(mouseCurPos.X, mouseCurPos.Y, viewport);
                SelectMapObject(hitMapObject);
                controller.UpdateUserInterface();
            }

            mouseDownPos = mouseCurPos;

            return(true);
        }
Exemplo n.º 10
0
        private void StartDrag(PointerEventInfo info, ILevelGeometry viewport, MergeAction action)
        {
            TileCoord location = TileLocation(info);

            int x = (int)(location.X * Layer.TileWidth);
            int y = (int)(location.Y * Layer.TileHeight);

            _band           = new RubberBand(new Point(location.X, location.Y));
            _selectionAnnot = new SelectionAnnot(new Point((int)info.X, (int)info.Y))
            {
                Fill = new SolidColorBrush(new Color(76, 178, 255, 128)),
            };

            _annots.Add(_selectionAnnot);
            _action      = UpdateAction.Box;
            _mergeAction = action;

            StartAutoScroll(info, viewport);
        }
Exemplo n.º 11
0
        private void StartDrag(PointerEventInfo info, ILevelGeometry viewport)
        {
            ClearPreviewMarker();
            _activeBrush = null;

            TileCoord location = TileLocation(info);

            int x = (int)(location.X * Layer.TileWidth);
            int y = (int)(location.Y * Layer.TileHeight);

            _band           = new RubberBand(new Point(location.X, location.Y));
            _selectionAnnot = new SelectionAnnot(new Point((int)info.X, (int)info.Y))
            {
                Fill = new SolidColorBrush(new Color(76, 178, 255, 128)),
            };

            _annots.Add(_selectionAnnot);

            //StartAutoScroll(info, viewport);
        }
Exemplo n.º 12
0
        private void StartEraseAreaSequence(PointerEventInfo info, ILevelGeometry viewport)
        {
            HidePreviewMarker();

            TileCoord location = TileLocation(info);

            int x = (int)(location.X * Layer.TileWidth);
            int y = (int)(location.Y * Layer.TileHeight);

            _band      = new RubberBand(new Point(location.X, location.Y));
            _selection = new SelectionAnnot(new Point(x, y))
            {
                Fill = new SolidColorBrush(new Color(192, 0, 0, 128)),
                //Outline = new Pen(new SolidColorBrush(new Color(192, 0, 0, 200))),
            };

            _annots.Add(_selection);
            _inAreaSequence = true;

            StartAutoScroll(info, viewport);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Initializes the editor
        /// </summary>
        private void InitializeEditor()
        {
            // events
            Move       += editorViewport.OnEditorMoves;
            Activated  += editorViewport.OnEditorGotFocus;
            Deactivate += editorViewport.OnEditorLostFocus;
            Disposed   += EditorForm_Dispose;

            editorViewport.OnViewportFocus      += OnViewportFocus;
            textureSelector.ApplyButton.Click   += OnApplySelectedTexture;
            textureSelector.ReplaceButton.Click += OnReplaceSelectedTexture;

            creationButtonsPanel.OnCreationButtonPressed = HandleGeometryBarItems;
            solidProperties.OnPropertiesChanged          = OnSolidPropertiesChanged;
            textureProperties.OnPropertiesChanged        = OnTexturePropertiesChanged;
            textureProperties.OnJustify = OnTexturePropertiesJustifyClicked;

            // initialization
            EditorSettings    = new EditorSettings();
            RubberBand        = new RubberBand();
            Selection         = new MapObjectGroup();
            CopyBoard         = new MapObjectGroup();
            CurrentTool       = new SolidManipulationTool();
            defaultMapSaver   = new RuneMapExporter();
            defaultMapLoader  = new RuneMapImporter();
            TextureCollection = new TextureCollection(EditorSettings.TextureFolder);

            if (!DesignMode)
            {
                EditorSettings.Load();
                SetupSolidFactory();
                solidProperties.UpdateProperties(Selection);
                editorViewport.SetController(this);
                textureSelector.TextureCollection = TextureCollection;
                CurrentTool.Initialize(this);

                Rotate = GeneralUtility.CreateCursor(Resources.rotate, 16, 16);
                NewDocument();
            }
        }
Exemplo n.º 14
0
        public override bool OnMouseUp(Point mouseCurPos, MouseButtons button, BaseViewport viewport)
        {
            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE &&
                button == MouseButtons.Left)
            {
                RubberBand       rubberBand          = controller.RubberBand;
                MapObject        selectionGroup      = controller.Selection;
                SolidGrabHandles handles             = rubberBand.Handles;
                Matrix4          fromGridSpaceMatrix = viewport.Camera.GetViewMatrix().ClearTranslation();

                // check for the program to decide if it needs to go the next grab handle mode
                bool isHoveringSelectedSolid = IsSelectedSolidAabbHit(mouseCurPos.X, mouseCurPos.Y, viewport);
                bool hasNoNewSelection       = currentAction != SolidToolActionType.Select;

                Vector3 snappedDownMousePosition = GeneralUtility.SnapToGrid(
                    new Vector3(mouseDownPos.X, mouseDownPos.Y, 0), viewport.GridSize);
                Vector3 snappedCurMousePosition = GeneralUtility.SnapToGrid(new Vector3(mouseCurPos.X, mouseCurPos.Y, 0),
                                                                            viewport.GridSize);
                bool mouseHasNotMoved = snappedDownMousePosition == snappedCurMousePosition;

                if (isHoveringSelectedSolid && mouseHasNotMoved && hasNoNewSelection)
                {
                    handles.NextMode();
                }
                else
                {
                    switch (currentAction)
                    {
                    case SolidToolActionType.Create:
                        controller.CreateSolid(fromGridSpaceMatrix);
                        break;

                    case SolidToolActionType.Drag:
                        // set new position
                        Vector3 displacement = rubberBand.Bounds.Center - selectionGroup.Bounds.Center;
                        controller.Selection.PerformOperation(new TranslateOperation(displacement));
                        break;

                    case SolidToolActionType.Transform:
                        Vector3             oldBoundVector = selectionGroup.Bounds.Max - selectionGroup.Bounds.Min;
                        Vector3             newBoundVector = rubberBand.Bounds.Max - rubberBand.Bounds.Min;
                        IMapObjectOperation operation      = null;

                        switch (handles.Mode)
                        {
                        case SolidGrabHandles.HandleMode.Resize:
                            operation = new ResizeTransformation(fromGridSpaceMatrix, oldBoundVector,
                                                                 newBoundVector,
                                                                 handles.LastHitStatus, viewport.GridSize);
                            break;

                        case SolidGrabHandles.HandleMode.Rotate:
                            operation = new RotateTransformation(fromGridSpaceMatrix, Vector3.Zero, Vector3.Zero,
                                                                 rubberBand.Transformation);
                            break;

                        case SolidGrabHandles.HandleMode.Skew:
                            operation = new SkewTransformation(fromGridSpaceMatrix, Vector3.Zero, Vector3.Zero,
                                                               rubberBand.Transformation,
                                                               handles.LastHitStatus);
                            break;
                        }

                        if (operation != null)
                        {
                            controller.Selection.PerformOperation(operation);
                        }
                        break;
                    }

                    controller.UpdateUserInterface();
                }

                rubberBand.SetToZeroVolume();
                rubberBand.ShowGrabhandles = true;
                currentAction = SolidToolActionType.None;
            }

            return(true);
        }
Exemplo n.º 15
0
        public void Visit(RubberBand mapObject)
        {
            AABB bounds = mapObject.Bounds;

            // resize bounding box
            switch (hitStatus)
            {
            case SolidGrabHandles.HitStatus.Top:
                bounds.Max = ResizeRubberbandBounds(bounds.Max, verticalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.TopRight:
                bounds.Max = ResizeRubberbandBounds(bounds.Max, horizontalMaskVector);
                bounds.Max = ResizeRubberbandBounds(bounds.Max, verticalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.Right:
                bounds.Max = ResizeRubberbandBounds(bounds.Max, horizontalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.Left:
                bounds.Min = ResizeRubberbandBounds(bounds.Min, horizontalMaskVector);
                KeepVolumeInMinArea(bounds);
                break;

            case SolidGrabHandles.HitStatus.BottomLeft:
                bounds.Min = ResizeRubberbandBounds(bounds.Min, horizontalMaskVector);
                bounds.Min = ResizeRubberbandBounds(bounds.Min, verticalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.Bottom:
                bounds.Min = ResizeRubberbandBounds(bounds.Min, verticalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.TopLeft:
                bounds.Min = ResizeRubberbandBounds(bounds.Min, horizontalMaskVector);
                bounds.Max = ResizeRubberbandBounds(bounds.Max, verticalMaskVector);
                break;

            case SolidGrabHandles.HitStatus.BottomRight:
                bounds.Min = ResizeRubberbandBounds(bounds.Min, verticalMaskVector);
                bounds.Max = ResizeRubberbandBounds(bounds.Max, horizontalMaskVector);

                break;
            }

            //do not allow negative resizing and keep volume
            switch (hitStatus)
            {
            case SolidGrabHandles.HitStatus.Top:
            case SolidGrabHandles.HitStatus.TopRight:
            case SolidGrabHandles.HitStatus.Right:
                KeepVolumeInMaxArea(bounds);
                break;

            case SolidGrabHandles.HitStatus.Left:
            case SolidGrabHandles.HitStatus.BottomLeft:
            case SolidGrabHandles.HitStatus.Bottom:
                KeepVolumeInMinArea(bounds);
                break;

            case SolidGrabHandles.HitStatus.TopLeft:
                KeepVolumeTopLeft(bounds);
                break;

            case SolidGrabHandles.HitStatus.BottomRight:
                KeepVolumeBottomRight(bounds);
                break;
            }
        }
Exemplo n.º 16
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            var mouse = MouseZoom(e.Location);
            var obj   = view.HitTest(mouse);

            if (obj is Shape)
            {
                if (ModifierKeys == Keys.Control)
                {
                    Debug.WriteLine("toggling object");
                    View.Selection.Toggle(obj);
                    Invalidate();
                }
                else if (ModifierKeys == Keys.None)
                {
                    View.Selection.Select(obj);
                    if (!ReadOnly)
                    {
                        StartShapeDrag((Shape)obj, mouse);
                    }
                    Invalidate();
                }
            }
            else if (obj is Pin && !ReadOnly && ModifierKeys == Keys.None)
            {
                rubberBand = new RubberBand(this, view, obj as Pin);
            }
            else if (obj is Segment && !ReadOnly)
            {
                var connector = (obj as Segment).Connector;
                if (ModifierKeys == Keys.Control)
                {
                    View.Selection.Toggle(connector);
                    Invalidate();
                }
                else if (ModifierKeys == Keys.None)
                {
                    View.Selection.Select(connector);
                    StartSegmentDrag(mouse, (obj as Segment));
                    Invalidate();
                }
            }
            else
            {
                // User clicked on background
                if (ModifierKeys == Keys.Control)
                {
                    selectionFrame = new SelectionFrame(PointToScreen(e.Location), BackColor);
                }
                else if (ModifierKeys == Keys.None)
                {
                    if (View.Selection.Count != 0)
                    {
                        Invalidate();
                        View.Selection.Clear();
                    }
                    panning  = true;
                    panClick = mouse;
                    minLeft  = Math.Min(0, Parent.Width - Width);
                    minTop   = Math.Min(0, Parent.Height - Height);
                }
            }
        }
Exemplo n.º 17
0
        public override bool OnMouseMove(Point mouseCurPos, Point mousePrevPos, BaseViewport viewport)
        {
            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                UpdateCursor(mouseCurPos, viewport);

                if (viewport.IsButtonHeld(BaseViewport.ViewportButtons.LEFT))
                {
                    // set standard values
                    Vector3 mouseDownPosition    = new Vector3(mouseDownPos.X, mouseDownPos.Y, 0);
                    Vector3 prevMousePosition    = new Vector3(mousePrevPos.X, mousePrevPos.Y, 0);
                    Vector3 currentMousePosition = new Vector3(mouseCurPos.X, mouseCurPos.Y, 0);
                    Matrix4 fromGridSpaceMatrix  = viewport.Camera.GetViewMatrix().ClearTranslation();

                    // we only give the rubberband volume if the mouse has moved in creation mode
                    bool mouseHasMoved = (currentMousePosition - mouseDownPosition).Length > GeneralUtility.Epsilon;
                    if (currentAction == SolidToolActionType.Create && mouseHasMoved)
                    {
                        mouseDownPosition.Z    = -viewport.GridSize * 4;
                        currentMousePosition.Z = viewport.GridSize * 4;
                    }

                    // convert to world
                    mouseDownPosition    = viewport.ViewportToWorld(mouseDownPosition);
                    prevMousePosition    = viewport.ViewportToWorld(prevMousePosition);
                    currentMousePosition = viewport.ViewportToWorld(currentMousePosition);

                    // snap
                    Vector3 snappedDownMousePosition    = GeneralUtility.SnapToGrid(mouseDownPosition, viewport.GridSize);
                    Vector3 snappedPrevMousePosition    = GeneralUtility.SnapToGrid(prevMousePosition, viewport.GridSize);
                    Vector3 snappedCurrentMousePosition = GeneralUtility.SnapToGrid(currentMousePosition, viewport.GridSize);

                    RubberBand rubberband = controller.RubberBand;

                    switch (currentAction)
                    {
                    case SolidToolActionType.Create:
                        rubberband.Bounds.Reset();
                        rubberband.Bounds.Grow(snappedDownMousePosition);
                        rubberband.Bounds.Grow(snappedCurrentMousePosition);
                        break;

                    case SolidToolActionType.Drag:
                    {
                        Vector3 delta = snappedCurrentMousePosition - snappedPrevMousePosition;
                        if (delta != Vector3.Zero)
                        {
                            TranslateOperation translate = new TranslateOperation(delta)
                            {
                                GridSize  = viewport.GridSize,
                                Transform = fromGridSpaceMatrix
                            };
                            rubberband.PerformOperation(translate);
                            rubberband.ShowGrabhandles = false;
                        }
                    }
                    break;

                    case SolidToolActionType.Transform:
                    {
                        SolidGrabHandles    handles   = rubberband.Handles;
                        IMapObjectOperation operation = null;

                        Vector3 delta = currentMousePosition - prevMousePosition;
                        if (delta != Vector3.Zero)
                        {
                            rubberband.ShowGrabhandles = false;
                        }

                        switch (handles.Mode)
                        {
                        case SolidGrabHandles.HandleMode.Resize:
                            operation = new ResizeTransformation(fromGridSpaceMatrix, snappedPrevMousePosition,
                                                                 snappedCurrentMousePosition,
                                                                 handles.LastHitStatus, viewport.GridSize);
                            break;

                        case SolidGrabHandles.HandleMode.Rotate:
                            operation = new RotateTransformation(fromGridSpaceMatrix, mouseDownPosition,
                                                                 currentMousePosition, Matrix4.Identity);
                            break;

                        case SolidGrabHandles.HandleMode.Skew:
                            operation = new SkewTransformation(fromGridSpaceMatrix, snappedDownMousePosition,
                                                               snappedCurrentMousePosition, Matrix4.Identity,
                                                               handles.LastHitStatus);
                            break;
                        }

                        if (operation != null)
                        {
                            controller.RubberBand.PerformOperation(operation);
                        }
                    }

                    break;
                    }
                }
            }
            else
            {
                controller.SetCursor(Cursors.Default);
            }

            return(true);
        }
Exemplo n.º 18
0
 public void Visit(RubberBand mapObject)
 {
 }
Exemplo n.º 19
0
        public override void OnRender(Graphics.Graphics graphics, BaseViewport viewport)
        {
            BaseViewportCamera   camera     = viewport.Camera;
            RubberBand           rubberband = controller.RubberBand;
            SolidRenderOperation render     = new SolidRenderOperation
            {
                Viewport = viewport,
                Graphics = graphics
            };

            // Draw all solids
            if (viewport.ViewportType == BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                GL.Enable(EnableCap.DepthTest);
            }

            graphics.BeginDraw(camera.GetViewMatrix() * camera.GetProjMatrix());

            foreach (MapObject mapObject in controller.SceneDocument)
            {
                if (mapObject.Selected)
                {
                    continue;
                }

                mapObject.PerformOperation(render);
            }

            controller.Selection?.PerformOperation(render);

            // only in orthographic viewport
            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                // draw rubberband
                if (rubberband.Bounds.HasVolume2D)
                {
                    graphics.DrawWireframeAabb(rubberband.Bounds, Graphics.Graphics.LineType.LineDashed, rubberband.Color, rubberband.Transformation, viewport.Zoom);
                }
                else
                {
                    // draw "rubberband" for the selection
                    graphics.DrawWireframeAabb(controller.Selection?.Bounds, Graphics.Graphics.LineType.LineDashed,
                                               viewport.RenderMode == BaseViewport.RenderModes.SOLID ? Color.Yellow : Color.Red,
                                               Matrix4.Identity, viewport.Zoom);
                }

                // draw grabhandles for selection
                if (controller.RubberBand.ShowGrabhandles)
                {
                    SolidGrabHandles handles        = controller.RubberBand.Handles;
                    Matrix4          viewportMatrix = viewport.Camera.GetWorldMatrix().ClearTranslation();
                    handles.CreateHandles(controller.Selection, viewportMatrix, viewport.Zoom);
                    handles.Render(graphics);
                }
            }

            graphics.EndDraw();

            if (viewport.ViewportType == BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                GL.Disable(EnableCap.DepthTest);
            }
        }