Example #1
0
        private Coordinate GetResizeDistance(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document document)
        {
            var origin = GetResizeOrigin(viewport, state, document);

            if (origin == null)
            {
                return(null);
            }
            var before = state.MoveStart;
            var after  = viewport.ScreenToWorld(e.X, viewport.Height - e.Y);

            return(SnapIfNeeded(origin + after - before, document) - origin);
        }
Example #2
0
        private Coordinate GetResizeOrigin(Viewport2D viewport, BaseBoxTool.BoxState state, Document document)
        {
            if (state.Action != BaseBoxTool.BoxAction.Resizing || state.Handle != BaseBoxTool.ResizeHandle.Center)
            {
                return(null);
            }
            var sel = document.Selection.GetSelectedParents().ToList();

            if (sel.Count == 1 && sel[0] is Entity && !sel[0].HasChildren)
            {
                return(viewport.Flatten(((Entity)sel[0]).Origin));
            }
            var st     = viewport.Flatten(state.PreTransformBoxStart);
            var ed     = viewport.Flatten(state.PreTransformBoxEnd);
            var points = new[] { st, ed, new Coordinate(st.X, ed.Y, 0), new Coordinate(ed.X, st.Y, 0) };

            return(points.OrderBy(x => (state.MoveStart - x).LengthSquared()).First());
        }
Example #3
0
        private static Coordinate GetOriginForTransform(Viewport2D viewport, BaseBoxTool.BoxState state)
        {
            decimal x      = 0;
            decimal y      = 0;
            var     cstart = viewport.Flatten(state.PreTransformBoxStart);
            var     cend   = viewport.Flatten(state.PreTransformBoxEnd);

            switch (state.Handle)
            {
            case BaseBoxTool.ResizeHandle.TopLeft:
            case BaseBoxTool.ResizeHandle.Top:
            case BaseBoxTool.ResizeHandle.TopRight:
            case BaseBoxTool.ResizeHandle.Left:
            case BaseBoxTool.ResizeHandle.Right:
                y = cstart.Y;
                break;

            case BaseBoxTool.ResizeHandle.BottomLeft:
            case BaseBoxTool.ResizeHandle.Bottom:
            case BaseBoxTool.ResizeHandle.BottomRight:
                y = cend.Y;
                break;
            }
            switch (state.Handle)
            {
            case BaseBoxTool.ResizeHandle.Top:
            case BaseBoxTool.ResizeHandle.TopRight:
            case BaseBoxTool.ResizeHandle.Right:
            case BaseBoxTool.ResizeHandle.BottomRight:
            case BaseBoxTool.ResizeHandle.Bottom:
                x = cstart.X;
                break;

            case BaseBoxTool.ResizeHandle.TopLeft:
            case BaseBoxTool.ResizeHandle.Left:
            case BaseBoxTool.ResizeHandle.BottomLeft:
                x = cend.X;
                break;
            }
            return(viewport.Expand(new Coordinate(x, y, 0)));
        }
Example #4
0
        public override Matrix4?GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc, IEnumerable <Widget> activeWidgets)
        {
            var origin = viewport.ZeroUnusedCoordinate((state.PreTransformBoxStart + state.PreTransformBoxEnd) / 2);
            var rw     = activeWidgets.OfType <RotationWidget>().FirstOrDefault();

            if (rw != null)
            {
                origin = rw.GetPivotPoint();
            }

            var forigin = viewport.Flatten(origin);

            var origv = (state.MoveStart - forigin).Normalise();
            var newv  = (viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - forigin).Normalise();

            var angle = DMath.Acos(Math.Max(-1, Math.Min(1, origv.Dot(newv))));

            if ((origv.Cross(newv).Z < 0))
            {
                angle = 2 * DMath.PI - angle;
            }

            var shf  = KeyboardState.Shift;
            var def  = Select.RotationStyle;
            var snap = (def == RotationStyle.SnapOnShift && shf) || (def == RotationStyle.SnapOffShift && !shf);

            if (snap)
            {
                var deg = angle * (180 / DMath.PI);
                var rnd = Math.Round(deg / 15) * 15;
                angle = rnd * (DMath.PI / 180);
            }

            Matrix4 rotm;

            if (viewport.Direction == Viewport2D.ViewDirection.Top)
            {
                rotm = Matrix4.CreateRotationZ((float)angle);
            }
            else if (viewport.Direction == Viewport2D.ViewDirection.Front)
            {
                rotm = Matrix4.CreateRotationX((float)angle);
            }
            else
            {
                rotm = Matrix4.CreateRotationY((float)-angle);  // The Y axis rotation goes in the reverse direction for whatever reason
            }
            var mov = Matrix4.CreateTranslation((float)-origin.X, (float)-origin.Y, (float)-origin.Z);
            var rot = Matrix4.Mult(mov, rotm);

            return(Matrix4.Mult(rot, Matrix4.Invert(mov)));
        }
Example #5
0
        public override Matrix4?GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc, IEnumerable <Widget> activeWidgets)
        {
            var shearUpDown   = state.Handle == BaseBoxTool.ResizeHandle.Left || state.Handle == BaseBoxTool.ResizeHandle.Right;
            var shearTopRight = state.Handle == BaseBoxTool.ResizeHandle.Top || state.Handle == BaseBoxTool.ResizeHandle.Right;

            var nsmd      = viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - state.MoveStart;
            var mouseDiff = SnapIfNeeded(nsmd, doc);

            if (KeyboardState.Shift)
            {
                mouseDiff = doc.Snap(nsmd, doc.Map.GridSpacing / 2);
            }

            var relative    = viewport.Flatten(state.PreTransformBoxEnd - state.PreTransformBoxStart);
            var shearOrigin = (shearTopRight) ? state.PreTransformBoxStart : state.PreTransformBoxEnd;

            var shearAmount = new Coordinate(mouseDiff.X / relative.Y, mouseDiff.Y / relative.X, 0);

            if (!shearTopRight)
            {
                shearAmount *= -1;
            }

            var shearMatrix = Matrix4.Identity;
            var sax         = (float)shearAmount.X;
            var say         = (float)shearAmount.Y;

            switch (viewport.Direction)
            {
            case Viewport2D.ViewDirection.Top:
                if (shearUpDown)
                {
                    shearMatrix.M12 = say;
                }
                else
                {
                    shearMatrix.M21 = sax;
                }
                break;

            case Viewport2D.ViewDirection.Front:
                if (shearUpDown)
                {
                    shearMatrix.M23 = say;
                }
                else
                {
                    shearMatrix.M32 = sax;
                }
                break;

            case Viewport2D.ViewDirection.Side:
                if (shearUpDown)
                {
                    shearMatrix.M13 = say;
                }
                else
                {
                    shearMatrix.M31 = sax;
                }
                break;
            }


            var stran = Matrix4.CreateTranslation((float)-shearOrigin.X, (float)-shearOrigin.Y, (float)-shearOrigin.Z);
            var shear = Matrix4.Mult(stran, shearMatrix);

            return(Matrix4.Mult(shear, Matrix4.Invert(stran)));
        }
Example #6
0
 public abstract Matrix4?GetTransformationMatrix(Viewport2D viewport, ViewportEvent mouseEventArgs, BaseBoxTool.BoxState state, Document doc, IEnumerable <Widget> activeWidgets);
Example #7
0
        private Tuple <Coordinate, Coordinate> GetBoxCoordinatesForSelectionResize(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document document)
        {
            if (state.Action != BaseBoxTool.BoxAction.Resizing)
            {
                return(Tuple.Create(state.BoxStart, state.BoxEnd));
            }
            var now    = SnapIfNeeded(viewport.ScreenToWorld(e.X, viewport.Height - e.Y), document);
            var cstart = viewport.Flatten(state.BoxStart);
            var cend   = viewport.Flatten(state.BoxEnd);

            // Proportional scaling
            var ostart       = viewport.Flatten(state.PreTransformBoxStart ?? Coordinate.Zero);
            var oend         = viewport.Flatten(state.PreTransformBoxEnd ?? Coordinate.Zero);
            var owidth       = oend.X - ostart.X;
            var oheight      = oend.Y - ostart.Y;
            var proportional = KeyboardState.Ctrl && state.Action == BaseBoxTool.BoxAction.Resizing && owidth != 0 && oheight != 0;

            switch (state.Handle)
            {
            case BaseBoxTool.ResizeHandle.TopLeft:
                cstart.X = Math.Min(now.X, cend.X - 1);
                cend.Y   = Math.Max(now.Y, cstart.Y + 1);
                break;

            case BaseBoxTool.ResizeHandle.Top:
                cend.Y = Math.Max(now.Y, cstart.Y + 1);
                break;

            case BaseBoxTool.ResizeHandle.TopRight:
                cend.X = Math.Max(now.X, cstart.X + 1);
                cend.Y = Math.Max(now.Y, cstart.Y + 1);
                break;

            case BaseBoxTool.ResizeHandle.Left:
                cstart.X = Math.Min(now.X, cend.X - 1);
                break;

            case BaseBoxTool.ResizeHandle.Center:
                var cdiff = cend - cstart;
                cstart = viewport.Flatten(state.PreTransformBoxStart) + now - SnapIfNeeded(state.MoveStart, document);
                cend   = cstart + cdiff;
                break;

            case BaseBoxTool.ResizeHandle.Right:
                cend.X = Math.Max(now.X, cstart.X + 1);
                break;

            case BaseBoxTool.ResizeHandle.BottomLeft:
                cstart.X = Math.Min(now.X, cend.X - 1);
                cstart.Y = Math.Min(now.Y, cend.Y - 1);
                break;

            case BaseBoxTool.ResizeHandle.Bottom:
                cstart.Y = Math.Min(now.Y, cend.Y - 1);
                break;

            case BaseBoxTool.ResizeHandle.BottomRight:
                cend.X   = Math.Max(now.X, cstart.X + 1);
                cstart.Y = Math.Min(now.Y, cend.Y - 1);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            if (proportional)
            {
                var nwidth  = cend.X - cstart.X;
                var nheight = cend.Y - cstart.Y;
                var mult    = Math.Max(nwidth / owidth, nheight / oheight);
                var pwidth  = owidth * mult;
                var pheight = oheight * mult;
                var wdiff   = pwidth - nwidth;
                var hdiff   = pheight - nheight;
                switch (state.Handle)
                {
                case BaseBoxTool.ResizeHandle.TopLeft:
                    cstart.X -= wdiff;
                    cend.Y   += hdiff;
                    break;

                case BaseBoxTool.ResizeHandle.TopRight:
                    cend.X += wdiff;
                    cend.Y += hdiff;
                    break;

                case BaseBoxTool.ResizeHandle.BottomLeft:
                    cstart.X -= wdiff;
                    cstart.Y -= hdiff;
                    break;

                case BaseBoxTool.ResizeHandle.BottomRight:
                    cend.X   += wdiff;
                    cstart.Y -= hdiff;
                    break;
                }
            }
            return(SnapBoxCoordinatesIfNeeded(viewport, state, document, cstart, cend));
        }
Example #8
0
        public override Matrix4?GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc, IEnumerable <Widget> activeWidgets)
        {
            var coords = GetBoxCoordinatesForSelectionResize(viewport, e, state, doc);

            state.BoxStart = coords.Item1;
            state.BoxEnd   = coords.Item2;
            Matrix4 resizeMatrix;

            if (state.Handle == BaseBoxTool.ResizeHandle.Center)
            {
                var movement = state.BoxStart - state.PreTransformBoxStart;
                resizeMatrix = Matrix4.CreateTranslation((float)movement.X, (float)movement.Y, (float)movement.Z);
            }
            else
            {
                var resize = (state.PreTransformBoxStart - state.BoxStart) +
                             (state.BoxEnd - state.PreTransformBoxEnd);
                resize  = resize.ComponentDivide(state.PreTransformBoxEnd - state.PreTransformBoxStart);
                resize += new Coordinate(1, 1, 1);
                var offset = -GetOriginForTransform(viewport, state);
                var trans  = Matrix4.CreateTranslation((float)offset.X, (float)offset.Y, (float)offset.Z);
                var scale  = Matrix4.Mult(trans, Matrix4.Scale((float)resize.X, (float)resize.Y, (float)resize.Z));
                resizeMatrix = Matrix4.Mult(scale, Matrix4.Invert(trans));
            }
            return(resizeMatrix);
        }
Example #9
0
        private Tuple <Coordinate, Coordinate> SnapBoxCoordinatesIfNeeded(Viewport2D viewport, BaseBoxTool.BoxState state, Document document, Coordinate start, Coordinate end)
        {
            if (state.Action == BaseBoxTool.BoxAction.Resizing && state.Handle == BaseBoxTool.ResizeHandle.Center)
            {
                // Pick the corner to snap
                var ms     = state.MoveStart;
                var pts    = viewport.Flatten(state.PreTransformBoxStart);
                var pte    = viewport.Flatten(state.PreTransformBoxEnd);
                var ss     = SnapIfNeeded(start, document);
                var se     = SnapIfNeeded(end, document);
                var middle = (pts + pte) / 2;
                var delta  = ss - start;
                if (ms.Y > middle.Y)
                {
                    // Top
                    delta.Y = se.Y - end.Y;
                }
                if (ms.X > middle.X)
                {
                    // Right
                    delta.X = se.X - end.X;
                }
                start += delta;
                end   += delta;
            }

            var cstart = viewport.Expand(start) + viewport.GetUnusedCoordinate(state.BoxStart);
            var cend   = viewport.Expand(end) + viewport.GetUnusedCoordinate(state.BoxEnd);

            return(Tuple.Create(cstart, cend));
        }