// Mouse input
        internal void ProcessMouseInput(Vector2D delta)
        {
            // Change camera angles with the mouse changes
            anglexy -= delta.x * ANGLE_FROM_MOUSE;
            if (General.Settings.InvertYAxis)
            {
                anglez -= delta.y * ANGLE_FROM_MOUSE;
            }
            else
            {
                anglez += delta.y * ANGLE_FROM_MOUSE;
            }

            // Normalize angles
            anglexy = Angle2D.Normalized(anglexy);
            anglez  = Angle2D.Normalized(anglez);

            // Limit vertical angle
            if (anglez < MAX_ANGLEZ_LOW)
            {
                anglez = MAX_ANGLEZ_LOW;
            }
            if (anglez > MAX_ANGLEZ_HIGH)
            {
                anglez = MAX_ANGLEZ_HIGH;
            }
        }
Example #2
0
        // This updates the selection
        private void Update()
        {
            // Not in any modifying mode?
            if (mode == ModifyMode.None)
            {
                Vector2D prevdragoffset = alignoffset;
                alignoffset     = new Vector2D(float.MinValue, float.MinValue);
                showalignoffset = false;

                // Check what grip the mouse is over
                // and change cursor accordingly
                Grip mousegrip = CheckMouseGrip();
                switch (mousegrip)
                {
                case Grip.Main:
                    int   closestcorner = -1;
                    float cornerdist    = float.MaxValue;
                    for (int i = 0; i < 4; i++)
                    {
                        Vector2D delta = corners[i] - mousemappos;
                        float    d     = delta.GetLengthSq();
                        if (d < cornerdist)
                        {
                            closestcorner = i;
                            cornerdist    = d;
                        }
                    }
                    switch (closestcorner)
                    {
                    // TODO:
                    case 0: alignoffset = new Vector2D(0f, 0f); break;

                    case 1: alignoffset = new Vector2D(texture.ScaledWidth, 0f); break;

                    case 2: alignoffset = new Vector2D(texture.ScaledWidth, -texture.ScaledHeight); break;

                    case 3: alignoffset = new Vector2D(0f, -texture.ScaledHeight); break;
                    }
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Hand);
                    break;

                case Grip.RotateLB:
                case Grip.RotateRT:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    General.Interface.SetCursor(Cursors.Cross);
                    break;

                case Grip.SizeH:
                case Grip.SizeV:
                    alignoffset     = new Vector2D(0f, 0f);
                    showalignoffset = true;
                    // Pick the best matching cursor depending on rotation and side
                    float resizeangle = -(rotation + sectorinfo[0].rotation);
                    if (mousegrip == Grip.SizeH)
                    {
                        resizeangle += Angle2D.PIHALF;
                    }
                    resizeangle = Angle2D.Normalized(resizeangle);
                    if (resizeangle > Angle2D.PI)
                    {
                        resizeangle -= Angle2D.PI;
                    }
                    resizeangle = Math.Abs(resizeangle + Angle2D.PI / 8.000001f);
                    int cursorindex = (int)Math.Floor((resizeangle / Angle2D.PI) * 4.0f) % 4;
                    General.Interface.SetCursor(RESIZE_CURSORS[cursorindex]);
                    break;

                default:
                    General.Interface.SetCursor(Cursors.Default);
                    break;
                }

                if (prevdragoffset != alignoffset)
                {
                    General.Interface.RedrawDisplay();
                }
            }
            else
            {
                Vector2D snappedmappos = mousemappos;
                bool     dosnaptogrid  = snaptogrid;

                // Options
                snaptogrid    = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
                snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;

                // Change to crosshair cursor so we can clearly see around the mouse cursor
                General.Interface.SetCursor(Cursors.Cross);

                // Check what modifying mode we are in
                switch (mode)
                {
                case ModifyMode.Dragging:

                    offset = -mousemappos - dragoffset;
                    Vector2D transformedpos = TexToWorld(alignoffset);

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, transformedpos, vrange);
                        if (nv != null)
                        {
                            // Change offset to snap to target
                            offset      -= nv.Position - transformedpos;
                            dosnaptogrid = false;
                        }
                        else
                        {
                            // Find the nearest line within range
                            Linedef nl = MapSet.NearestLinedefRange(General.Map.Map.Linedefs, transformedpos, vrange);
                            if (nl != null)
                            {
                                // Snap to grid?
                                if (dosnaptogrid)
                                {
                                    // Get grid intersection coordinates
                                    List <Vector2D> coords = nl.GetGridIntersections();

                                    // Find nearest grid intersection
                                    float    found_distance = float.MaxValue;
                                    Vector2D found_pos      = new Vector2D(float.NaN, float.NaN);
                                    foreach (Vector2D v in coords)
                                    {
                                        Vector2D dist = transformedpos - v;
                                        if (dist.GetLengthSq() < found_distance)
                                        {
                                            // Found a better match
                                            found_distance = dist.GetLengthSq();
                                            found_pos      = v;

                                            // Do not snap to grid anymore
                                            dosnaptogrid = false;
                                        }
                                    }

                                    // Found something?
                                    if (!float.IsNaN(found_pos.x))
                                    {
                                        // Change offset to snap to target
                                        offset -= found_pos - transformedpos;
                                    }
                                }
                                else
                                {
                                    // Change offset to snap onto the line
                                    offset -= nl.NearestOnLine(transformedpos) - transformedpos;
                                }
                            }
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Change offset to align to grid
                        offset -= General.Map.Grid.SnappedToGrid(transformedpos) - transformedpos;
                    }

                    break;

                case ModifyMode.Resizing:

                    // Snap to nearest vertex?
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;
                        }
                    }

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // Aligned to grid
                        snappedmappos = General.Map.Grid.SnappedToGrid(snappedmappos);
                    }

                    float newscale = 1f / resizeaxis.GetNearestOnLine(snappedmappos);
                    if (float.IsInfinity(newscale) || float.IsNaN(newscale))
                    {
                        newscale = 99999f;
                    }
                    scale = (newscale * resizefilter) + scale * (1.0f - resizefilter);
                    if (float.IsInfinity(scale.x) || float.IsNaN(scale.x))
                    {
                        scale.x = 99999f;
                    }
                    if (float.IsInfinity(scale.y) || float.IsNaN(scale.y))
                    {
                        scale.y = 99999f;
                    }

                    // Show the extension line so that the user knows what it is aligning to
                    UpdateRectangleComponents();
                    Line2D edgeline;
                    if (resizefilter.x > resizefilter.y)
                    {
                        edgeline = new Line2D(corners[1], corners[2]);
                    }
                    else
                    {
                        edgeline = new Line2D(corners[3], corners[2]);
                    }
                    float nearestonedge = edgeline.GetNearestOnLine(snappedmappos);
                    if (nearestonedge > 0.5f)
                    {
                        extensionline = new Line2D(edgeline.v1, snappedmappos);
                    }
                    else
                    {
                        extensionline = new Line2D(edgeline.v2, snappedmappos);
                    }

                    break;

                case ModifyMode.Rotating:

                    // Snap to nearest vertex?
                    extensionline = new Line2D();
                    if (snaptonearest)
                    {
                        float vrange = BuilderPlug.Me.StitchRange / renderer.Scale;

                        // Try the nearest vertex
                        Vertex nv = MapSet.NearestVertexSquareRange(General.Map.Map.Vertices, snappedmappos, vrange);
                        if (nv != null)
                        {
                            snappedmappos = nv.Position;
                            dosnaptogrid  = false;

                            // Show the extension line so that the user knows what it is aligning to
                            extensionline = new Line2D(corners[0], snappedmappos);
                        }
                    }

                    Vector2D delta      = snappedmappos - rotationcenter;
                    float    deltaangle = -delta.GetAngle();

                    // Snap to grid?
                    if (dosnaptogrid)
                    {
                        // We make 8 vectors that the rotation can snap to
                        float founddistance = float.MaxValue;
                        float foundrotation = rotation;
                        for (int i = 0; i < 8; i++)
                        {
                            // Make the vectors
                            float    angle   = (float)i * Angle2D.PI * 0.25f;
                            Vector2D gridvec = Vector2D.FromAngle(angle);
                            Vector3D rotvec  = Vector2D.FromAngle(deltaangle + rotationoffset);

                            // Check distance
                            float dist = 2.0f - Vector2D.DotProduct(gridvec, rotvec);
                            if (dist < founddistance)
                            {
                                foundrotation = angle;
                                founddistance = dist;
                            }
                        }

                        // Keep rotation
                        rotation = foundrotation - sectorinfo[0].rotation;
                    }
                    else
                    {
                        rotation = deltaangle + rotationoffset - sectorinfo[0].rotation;
                    }
                    break;
                }

                UpdateSectors();
                General.Interface.RedrawDisplay();
            }
        }
Example #3
0
        private void ComputeAngle()
        {
            List <LineAngleInfo> lines  = new List <LineAngleInfo>();
            List <double>        angles = new List <double>();

            // Get all lines that we have to take into account. Ignore linedefs where both sides
            // don't belong to the sector or don't belong to the sector
            foreach (Linedef ld in vertex.Linedefs)
            {
                if (ld.IsDisposed)
                {
                    continue;
                }
                else
                {
                    bool frontsame = false;
                    bool backsame  = false;

                    if (ld.Front != null && ld.Front.Sector == sector)
                    {
                        frontsame = true;
                    }

                    if (ld.Back != null && ld.Back.Sector == sector)
                    {
                        backsame = true;
                    }

                    if (frontsame == backsame)
                    {
                        continue;
                    }
                }

                lines.Add(new LineAngleInfo(ld, vertex, sector));
            }

            // Special case handling
            if (lines.Count < 2)
            {
                if (vertex.Linedefs.Count == 1)
                {
                    angle = vertex.Linedefs.First().Angle + Angle2D.PIHALF;
                    return;
                }

                angle = 0.0;
                return;
            }

            // Sort lines by their normalized angle
            lines.Sort((a, b) => a.angle.CompareTo(b.angle));

            // Get the other line we want to compute the angle between
            int other = 1;

            if (!lines[0].clockwise)
            {
                other = lines.Count - 1;
            }

            Vector2D v1 = Vector2D.FromAngle(lines[0].angle);
            Vector2D v2 = Vector2D.FromAngle(lines[other].angle);

            angle = lines[0].angle + (Math.Atan2(v2.y, v2.x) - Math.Atan2(v1.y, v1.x)) / 2.0;

            // If the first line is going clockwise we have to add 180°
            if (lines[0].clockwise)
            {
                angle += Angle2D.PI;
            }

            // Add 90° to get it in line with Doom's angles
            angle += Angle2D.PIHALF;

            // Also need to modify the angle for ceilings
            if (level.type == SectorLevelType.Ceiling)
            {
                angle += Angle2D.PI;
            }

            angle = Angle2D.Normalized(angle);
        }