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); }
public void Visit(RubberBand mapObject) { if (!SnapAabb(mapObject.Bounds)) { TranslateBounds(mapObject.Bounds); } }
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); }
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); }
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); }
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); }
/// <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); }
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(); }
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); }
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); }
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); }
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); }
/// <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(); } }
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); }
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; } }
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); } } }
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); }
public void Visit(RubberBand mapObject) { }
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); } }