public JitterVerticesForm(string editingModeName)
        {
            this.editingModeName = editingModeName;
            this.HelpRequested  += JitterVerticesForm_HelpRequested;

            InitializeComponent();

            //get selection
            selection = new List <Vertex>();

            if (editingModeName == "BaseVisualMode")
            {
                VisualMode            vm = (VisualMode)General.Editing.Mode;
                List <VisualGeometry> visualSelection = vm.GetSelectedSurfaces();
                visualSectors = new List <VisualSector>();
                int linesCount = 0;

                foreach (VisualGeometry vg in visualSelection)
                {
                    if (vg.Sidedef != null && vm.VisualSectorExists(vg.Sidedef.Sector))
                    {
                        if (!selection.Contains(vg.Sidedef.Line.Start))
                        {
                            selection.Add(vg.Sidedef.Line.Start);
                        }
                        if (!selection.Contains(vg.Sidedef.Line.End))
                        {
                            selection.Add(vg.Sidedef.Line.End);
                        }
                        linesCount++;

                        visualSectors.Add(vm.GetVisualSector(vg.Sidedef.Sector));

                        if (vg.Sidedef.Other != null && vg.Sidedef.Other.Sector != null && vm.VisualSectorExists(vg.Sidedef.Other.Sector))
                        {
                            visualSectors.Add(vm.GetVisualSector(vg.Sidedef.Other.Sector));
                        }
                    }
                }

                visualVerts = new List <VisualVertexPair>();
                foreach (Vertex vert in selection)
                {
                    if (vm.VisualVertices.ContainsKey(vert))
                    {
                        visualVerts.Add(vm.VisualVertices[vert]);
                    }
                }

                //update window header
                this.Text = "Randomize " + linesCount + (linesCount > 1 ? " linedefs" : " linedef");
            }
            else if (editingModeName == "LinedefsMode")
            {
                ICollection <Linedef> list = General.Map.Map.GetSelectedLinedefs(true);
                int linesCount             = 0;

                foreach (Linedef l in list)
                {
                    if (!selection.Contains(l.Start))
                    {
                        selection.Add(l.Start);
                    }
                    if (!selection.Contains(l.End))
                    {
                        selection.Add(l.End);
                    }
                    linesCount++;
                }

                //update window header
                this.Text = "Randomize " + linesCount + (linesCount > 1 ? " linedefs" : " linedef");
            }
            else
            {
                ICollection <Vertex> list = General.Map.Map.GetSelectedVertices(true);
                foreach (Vertex v in list)
                {
                    selection.Add(v);
                }

                //update window header
                this.Text = "Randomize " + selection.Count + (selection.Count > 1 ? " vertices" : " vertex");
            }

            if (selection.Count == 0)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Unable to get vertices from selection!");
                return;
            }

            //create undo
            General.Map.UndoRedo.ClearAllRedos();
            General.Map.UndoRedo.CreateUndo("Randomize " + selection.Count + (selection.Count > 1 ? " vertices" : " vertex"));

            Dictionary <Vertex, VertexData> data = new Dictionary <Vertex, VertexData>();

            foreach (Vertex v in selection)
            {
                VertexData vd = new VertexData {
                    Position = v.Position
                };
                data.Add(v, vd);
            }

            foreach (Vertex v in selection)
            {
                if (v.Linedefs == null)
                {
                    continue;
                }

                //get nearest linedef
                Linedef closestLine = null;
                float   distance    = float.MaxValue;

                // Go for all linedefs in selection
                foreach (Linedef l in General.Map.Map.Linedefs)
                {
                    if (v.Linedefs.Contains(l))
                    {
                        continue;
                    }

                    // Calculate distance and check if closer than previous find
                    float d = l.SafeDistanceToSq(v.Position, true);
                    if (d < distance)
                    {
                        // This one is closer
                        closestLine = l;
                        distance    = d;
                    }
                }

                if (closestLine == null)
                {
                    continue;
                }

                float closestLineDistance = Vector2D.Distance(v.Position, closestLine.NearestOnLine(v.Position));

                //check SafeDistance of closest line
                if (data.ContainsKey(closestLine.Start) &&
                    data[closestLine.Start].SafeDistance > closestLineDistance)
                {
                    VertexData vd = data[closestLine.Start];
                    vd.SafeDistance         = (int)Math.Floor(closestLineDistance);
                    data[closestLine.Start] = vd;
                }
                if (data.ContainsKey(closestLine.End) &&
                    data[closestLine.End].SafeDistance > closestLineDistance)
                {
                    VertexData vd = data[closestLine.End];
                    vd.SafeDistance       = (int)Math.Floor(closestLineDistance);
                    data[closestLine.End] = vd;
                }

                //save SafeDistance
                int dist = (int)Math.Floor(closestLineDistance);
                if (data[v].SafeDistance == 0 || data[v].SafeDistance > dist)
                {
                    VertexData vd = data[v];
                    vd.SafeDistance = dist;
                    data[v]         = vd;
                }
            }

            //store properties
            vertexData = new VertexData[data.Values.Count];
            data.Values.CopyTo(vertexData, 0);

            for (int i = 0; i < vertexData.Length; i++)
            {
                if (vertexData[i].SafeDistance > 0)
                {
                    vertexData[i].SafeDistance /= 2;
                }
                if (MaxSafeDistance < vertexData[i].SafeDistance)
                {
                    MaxSafeDistance = vertexData[i].SafeDistance;
                }
            }

            positionJitterAmmount.Maximum = MaxSafeDistance;

            UpdateAngles();
        }
        public JitterSectorsForm(string editingModeName)
        {
            this.editingModeName = editingModeName;

            InitializeComponent();

            //get selection
            List <Vertex> verts   = new List <Vertex>();
            List <Sector> sectors = new List <Sector>();

            if (editingModeName == "BaseVisualMode")
            {
                VisualMode            vm             = (VisualMode)General.Editing.Mode;
                List <VisualGeometry> visualGeometry = vm.GetSelectedSurfaces();
                visualSectors = new List <VisualSector>();

                //get selected visual and regular sectors
                foreach (VisualGeometry vg in visualGeometry)
                {
                    if (vg.GeometryType != VisualGeometryType.CEILING && vg.GeometryType != VisualGeometryType.FLOOR)
                    {
                        continue;
                    }

                    if (vg.Sector != null && vg.Sector.Sector != null)
                    {
                        foreach (Sidedef sd in vg.Sector.Sector.Sidedefs)
                        {
                            if (!verts.Contains(sd.Line.Start))
                            {
                                verts.Add(sd.Line.Start);
                            }
                            if (!verts.Contains(sd.Line.End))
                            {
                                verts.Add(sd.Line.End);
                            }
                        }

                        sectors.Add(vg.Sector.Sector);
                        visualSectors.Add(vg.Sector);
                    }
                }

                //also get visual sectors around selected ones (because they also may be affected)
                List <Vertex> affectedVerts = new List <Vertex>();

                foreach (Sector s in sectors)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        if (!affectedVerts.Contains(sd.Line.Start))
                        {
                            affectedVerts.Add(sd.Line.Start);
                        }
                        if (!affectedVerts.Contains(sd.Line.End))
                        {
                            affectedVerts.Add(sd.Line.End);
                        }
                    }
                }

                List <Sector> affectedSectors = new List <Sector>();
                foreach (Vertex v in affectedVerts)
                {
                    foreach (Linedef l in v.Linedefs)
                    {
                        if (l.Front != null && !sectors.Contains(l.Front.Sector) &&
                            !affectedSectors.Contains(l.Front.Sector) &&
                            vm.VisualSectorExists(l.Front.Sector))
                        {
                            visualSectors.Add(vm.GetVisualSector(l.Front.Sector));
                            affectedSectors.Add(l.Front.Sector);
                        }
                        if (l.Back != null && !sectors.Contains(l.Back.Sector) &&
                            !affectedSectors.Contains(l.Back.Sector) &&
                            vm.VisualSectorExists(l.Back.Sector))
                        {
                            visualSectors.Add(vm.GetVisualSector(l.Back.Sector));
                            affectedSectors.Add(l.Back.Sector);
                        }
                    }
                }

                visualVerts = new List <VisualVertexPair>();
                foreach (Vertex vert in affectedVerts)
                {
                    if (vm.VisualVertices.ContainsKey(vert))
                    {
                        visualVerts.Add(vm.VisualVertices[vert]);
                    }
                }
            }
            else if (editingModeName == "SectorsMode")
            {
                ICollection <Sector> list = General.Map.Map.GetSelectedSectors(true);

                foreach (Sector s in list)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        if (!verts.Contains(sd.Line.Start))
                        {
                            verts.Add(sd.Line.Start);
                        }
                        if (!verts.Contains(sd.Line.End))
                        {
                            verts.Add(sd.Line.End);
                        }
                    }
                    sectors.Add(s);
                }
            }

            if (verts.Count == 0 || sectors.Count == 0)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Unable to get sectors from selection!");
                return;
            }

            //create undo
            General.Map.UndoRedo.ClearAllRedos();
            General.Map.UndoRedo.CreateUndo("Randomize " + sectors.Count + (sectors.Count > 1 ? " sectors" : " sector"));

            //update window header
            this.Text = "Randomize " + sectors.Count + (sectors.Count > 1 ? " sectors" : " sector");

            //store intial properties
//process verts...
            Dictionary <Vertex, TranslationOffsetVertexData> data = new Dictionary <Vertex, TranslationOffsetVertexData>();

            foreach (Vertex v in verts)
            {
                TranslationOffsetVertexData vd = new TranslationOffsetVertexData();
                vd.Vertex          = v;
                vd.InitialPosition = v.Position;
                data.Add(v, vd);
            }

            foreach (Vertex v in verts)
            {
                if (v.Linedefs == null)
                {
                    continue;
                }

                //get nearest linedef
                Linedef closestLine = null;
                double  distance    = double.MaxValue;

                // Go for all linedefs in selection
                foreach (Linedef l in General.Map.Map.Linedefs)
                {
                    if (v.Linedefs.Contains(l))
                    {
                        continue;
                    }

                    // Calculate distance and check if closer than previous find
                    double d = l.SafeDistanceToSq(v.Position, true);
                    if (d < distance)
                    {
                        // This one is closer
                        closestLine = l;
                        distance    = d;
                    }
                }

                if (closestLine == null)
                {
                    continue;
                }

                double closestLineDistance = Vector2D.Distance(v.Position, closestLine.NearestOnLine(v.Position));

                //check SafeDistance of closest line
                if (data.ContainsKey(closestLine.Start) &&
                    data[closestLine.Start].SafeDistance > closestLineDistance)
                {
                    TranslationOffsetVertexData vd = data[closestLine.Start];
                    vd.SafeDistance         = (int)Math.Floor(closestLineDistance);
                    data[closestLine.Start] = vd;
                }
                if (data.ContainsKey(closestLine.End) &&
                    data[closestLine.End].SafeDistance > closestLineDistance)
                {
                    TranslationOffsetVertexData vd = data[closestLine.End];
                    vd.SafeDistance       = (int)Math.Floor(closestLineDistance);
                    data[closestLine.End] = vd;
                }

                //save SafeDistance
                int dist = (int)Math.Floor(closestLineDistance);
                if (data[v].SafeDistance == 0 || data[v].SafeDistance > dist)
                {
                    TranslationOffsetVertexData vd = data[v];
                    vd.SafeDistance = dist;
                    data[v]         = vd;
                }
            }

            //store properties
            vertexData = new TranslationOffsetVertexData[data.Values.Count];
            data.Values.CopyTo(vertexData, 0);

            for (int i = 0; i < data.Count; i++)
            {
                if (vertexData[i].SafeDistance > 0)
                {
                    vertexData[i].SafeDistance /= 2;
                }
                if (MaxSafeDistance < vertexData[i].SafeDistance)
                {
                    MaxSafeDistance = vertexData[i].SafeDistance;
                }
            }

//process sectors and linedes
            sectorData  = new List <SectorData>();
            sidedefData = new List <SidedefData>();

            foreach (Sector s in sectors)
            {
                SectorData sd = new SectorData();

                sd.Sector = s;
                sd.InitialCeilingHeight = s.CeilHeight;
                sd.InitialFloorHeight   = s.FloorHeight;
                sd.Triangular           = General.Map.UDMF && s.Sidedefs.Count == 3;
                if (sd.Triangular)
                {
                    Vertex[] sectorverts = GetSectorVerts(s);
                    sd.Verts = new HeightOffsetVertexData[sectorverts.Length];
                    for (int i = 0; i < sectorverts.Length; i++)
                    {
                        HeightOffsetVertexData vd = new HeightOffsetVertexData();
                        vd.Vertex               = sectorverts[i];
                        vd.ZFloor               = sectorverts[i].ZFloor;
                        vd.ZCeiling             = sectorverts[i].ZCeiling;
                        vd.InitialFloorHeight   = double.IsNaN(vd.ZFloor) ? GetHighestFloor(sectorverts[i]) : sectorverts[i].ZFloor;
                        vd.InitialCeilingHeight = double.IsNaN(vd.ZCeiling) ? GetLowestCeiling(sectorverts[i]) : sectorverts[i].ZCeiling;

                        sd.Verts[i] = vd;
                    }
                }
                sd.SafeDistance = (s.CeilHeight - s.FloorHeight) / 2;
                if (sd.SafeDistance > MaxSafeHeightDistance)
                {
                    MaxSafeHeightDistance = sd.SafeDistance;
                }
                sectorData.Add(sd);

                foreach (Sidedef side in s.Sidedefs)
                {
                    //store initial sidedef properties
                    SidedefData sdd = new SidedefData();

                    sdd.Side        = side;
                    sdd.LowTexture  = side.LowTexture;
                    sdd.HighTexture = side.HighTexture;
                    sdd.PegBottom   = side.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag);
                    sdd.PegTop      = side.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag);

                    if (side.Other != null && !sectors.Contains(side.Other.Sector))
                    {
                        sdd.UpdateTextureOnOtherSide = true;
                        sdd.OtherHighTexture         = side.Other.HighTexture;
                        sdd.OtherLowTexture          = side.Other.LowTexture;
                    }

                    sidedefData.Add(sdd);
                }
            }

            positionJitterAmmount.Maximum = MaxSafeDistance;
            floorHeightAmmount.Maximum    = MaxSafeHeightDistance;
            ceilingHeightAmmount.Maximum  = MaxSafeHeightDistance;

            //set editing settings
            cbKeepExistingTextures.Checked = keepExistingSideTextures;
            ceiloffsetmode.SelectedIndex   = storedceiloffsetmode;
            flooroffsetmode.SelectedIndex  = storedflooroffsetmode;

            //vertex heights can not be set in non-UDMF maps
            if (General.Map.UDMF)
            {
                cbUseFloorVertexHeights.Checked   = useFloorVertexHeights;
                cbUseCeilingVertexHeights.Checked = useCeilingVertexHeights;
            }
            else
            {
                useFloorVertexHeights           = false;
                cbUseFloorVertexHeights.Checked = false;
                cbUseFloorVertexHeights.Enabled = false;

                useCeilingVertexHeights           = false;
                cbUseCeilingVertexHeights.Checked = false;
                cbUseCeilingVertexHeights.Enabled = false;
            }

            //texture pickers
            textureLower.Initialize();
            textureUpper.Initialize();

            //We can't use floor/ceiling textures when MixTexturesFlats is disabled
            if (General.Map.Config.MixTexturesFlats)
            {
                textureLower.TextureName = General.Settings.DefaultFloorTexture;
                textureUpper.TextureName = General.Settings.DefaultCeilingTexture;
            }
            else
            {
                textureLower.TextureName = General.Settings.DefaultTexture;
                textureUpper.TextureName = General.Settings.DefaultTexture;
                cbUpperTexStyle.Items[1] = "Use default texture";
                cbLowerTexStyle.Items[1] = "Use default texture";
            }

            cbUpperTexStyle.SelectedIndex = 0;
            cbLowerTexStyle.SelectedIndex = 0;
            UpdateTextureSelectors();             //update interface

            //create random values
            UpdateAngles();
            UpdateFloorHeights();
            UpdateCeilingHeights();
        }
Ejemplo n.º 3
0
        private void ApplyDirectionalShading()
        {
            // Boilerplate
            if (General.Editing.Mode == null)
            {
                return;
            }
            if (!General.Map.UDMF)
            {
                General.Interface.DisplayStatus(StatusType.Warning, "This action is available only in UDMF map format!");
                return;
            }

            DirectionalShadingForm form;
            string currentmodename = General.Editing.Mode.GetType().Name;

            // Create the form or tell the user why we can't do that
            if (currentmodename == "SectorsMode")
            {
                if (General.Map.Map.SelectedSectorsCount == 0)
                {
                    General.Interface.DisplayStatus(StatusType.Warning, "Select some sectors first!");
                    return;
                }

                // Collect sectors
                ICollection <Sector> sectors = General.Map.Map.GetSelectedSectors(true);

                // Collect sidedefs
                HashSet <Sidedef> sides = new HashSet <Sidedef>();
                foreach (Sector s in sectors)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        sides.Add(sd);
                        if (sd.Other != null)
                        {
                            sides.Add(sd.Other);
                        }
                    }
                }

                // Create the form
                form = new DirectionalShadingForm(sectors, sides, null);
            }
            else if (currentmodename == "LinedefsMode")
            {
                if (General.Map.Map.SelectedLinedefsCount == 0)
                {
                    General.Interface.DisplayStatus(StatusType.Warning, "Select some linedefs first!");
                    return;
                }

                // Collect linedefs
                ICollection <Linedef> linedefs = General.Map.Map.GetSelectedLinedefs(true);

                // Collect sectors
                ICollection <Sector> sectors = General.Map.Map.GetSectorsFromLinedefs(linedefs);

                // Collect sidedefs from linedefs
                HashSet <Sidedef> sides = new HashSet <Sidedef>();
                foreach (Linedef l in linedefs)
                {
                    if (l.Front != null)
                    {
                        sides.Add(l.Front);
                    }
                    if (l.Back != null)
                    {
                        sides.Add(l.Back);
                    }
                }

                // Collect sidedefs from sectors
                foreach (Sector s in sectors)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        sides.Add(sd);
                        if (sd.Other != null)
                        {
                            sides.Add(sd.Other);
                        }
                    }
                }

                // Create the form
                form = new DirectionalShadingForm(sectors, sides, null);
            }
            else if (currentmodename == "BaseVisualMode")
            {
                // Check selected geometry
                VisualMode             mode        = (VisualMode)General.Editing.Mode;
                List <VisualGeometry>  list        = mode.GetSelectedSurfaces();
                HashSet <VisualSector> selectedgeo = new HashSet <VisualSector>();
                List <Sector>          sectors     = new List <Sector>();
                HashSet <Sidedef>      sides       = new HashSet <Sidedef>();

                // Collect sectors and sides
                if (list.Count > 0)
                {
                    foreach (VisualGeometry vg in list)
                    {
                        switch (vg.GeometryType)
                        {
                        case VisualGeometryType.FLOOR:
                            selectedgeo.Add(vg.Sector);
                            sectors.Add(vg.Sector.Sector);
                            break;

                        case VisualGeometryType.WALL_UPPER:
                        case VisualGeometryType.WALL_MIDDLE:
                        case VisualGeometryType.WALL_LOWER:
                            sides.Add(vg.Sidedef);
                            selectedgeo.Add(mode.GetVisualSector(vg.Sidedef.Sector));
                            break;
                        }
                    }
                }

                // Add sides from selected sectors
                foreach (Sector s in sectors)
                {
                    foreach (Sidedef sd in s.Sidedefs)
                    {
                        sides.Add(sd);
                        if (sd.Other != null)
                        {
                            sides.Add(sd.Other);
                        }
                    }
                }

                // Create the form?
                if (sectors.Count > 0 || sides.Count > 0)
                {
                    form = new DirectionalShadingForm(sectors, sides, selectedgeo);
                }
                else
                {
                    General.Interface.DisplayStatus(StatusType.Warning, "Select some floor or wall surfaces first!");
                    return;
                }
            }
            else             // Wrong mode
            {
                General.Interface.DisplayStatus(StatusType.Warning, "Switch to Sectors, Linedefs or Visual mode first!");
                return;
            }

            // Show the form
            form.ShowDialog(General.Interface);
        }