From 560d4a5828c657280a067f65d4bd2acab85d27c4 Mon Sep 17 00:00:00 2001 From: biwa <6475593+biwa@users.noreply.github.com> Date: Sat, 4 Apr 2020 18:03:40 +0200 Subject: [PATCH] When auto-aligning textures on floors/ceilings they can be scaled independently on slope type Added option to select behavior (Tools -> Preferences -> Editing) of scaling when auto-aligning textures on floors/ceilings (use base scale of 1 (default), use current scale as base, never scale) --- .../BuilderModes/General/BuilderPlug.cs | 3 + .../Interface/PreferencesForm.Designer.cs | 57 ++++++--- .../BuilderModes/Interface/PreferencesForm.cs | 3 + .../VisualModes/BaseVisualGeometrySector.cs | 116 ++++-------------- .../BuilderModes/VisualModes/VisualCeiling.cs | 37 +----- .../BuilderModes/VisualModes/VisualFloor.cs | 37 +----- 6 files changed, 77 insertions(+), 176 deletions(-) diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs index 75d8f0b7..2b3c5df2 100755 --- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs +++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs @@ -136,6 +136,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private bool alphabasedtexturehighlighting; //mxd private bool showlightradii; //mxd private bool showsoundradii; //mxd + private int scaletexturesonslopes; // 0 = base scale of 1, 1 = use current scale as base, 2 = don't scale #endregion @@ -189,6 +190,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public bool AlphaBasedTextureHighlighting { get { return alphabasedtexturehighlighting; } internal set { alphabasedtexturehighlighting = value; } } //mxd public bool ShowLightRadii { get { return showlightradii; } internal set { showlightradii = value; } } //mxd public bool ShowSoundRadii { get { return showsoundradii; } internal set { showsoundradii = value; } } //mxd + public int ScaleTexturesOnSlopes { get { return scaletexturesonslopes; } internal set { scaletexturesonslopes = value; } } //mxd. "Make Door" action persistent settings internal MakeDoorSettings MakeDoor; @@ -291,6 +293,7 @@ namespace CodeImp.DoomBuilder.BuilderModes autoAlignTextureOffsetsOnCreate = General.Settings.ReadPluginSetting("autoaligntextureoffsetsoncreate", false); //mxd dontMoveGeometryOutsideMapBoundary = General.Settings.ReadPluginSetting("dontmovegeometryoutsidemapboundary", false); //mxd syncSelection = General.Settings.ReadPluginSetting("syncselection", false); //mxd + scaletexturesonslopes = General.Settings.ReadPluginSetting("scaletexturesonslopes", 0); } //mxd. Load settings, which can be changed via UI diff --git a/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs index d284d309..1db5dac6 100755 --- a/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs @@ -40,6 +40,7 @@ namespace CodeImp.DoomBuilder.BuilderModes this.defaultbrightness = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox(); this.label11 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.additivepaintselect = new System.Windows.Forms.CheckBox(); this.switchviewmodes = new System.Windows.Forms.CheckBox(); this.autodrawonedit = new System.Windows.Forms.CheckBox(); this.syncSelection = new System.Windows.Forms.CheckBox(); @@ -72,7 +73,8 @@ namespace CodeImp.DoomBuilder.BuilderModes this.label10 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.heightbysidedef = new System.Windows.Forms.ComboBox(); - this.additivepaintselect = new System.Windows.Forms.CheckBox(); + this.label18 = new System.Windows.Forms.Label(); + this.scaletexturesonslopes = new System.Windows.Forms.ComboBox(); this.tabs.SuspendLayout(); this.taboptions.SuspendLayout(); this.groupBox4.SuspendLayout(); @@ -120,7 +122,7 @@ namespace CodeImp.DoomBuilder.BuilderModes this.groupBox4.Controls.Add(this.label12); this.groupBox4.Controls.Add(this.defaultbrightness); this.groupBox4.Controls.Add(this.label11); - this.groupBox4.Location = new System.Drawing.Point(6, 300); + this.groupBox4.Location = new System.Drawing.Point(6, 335); this.groupBox4.Name = "groupBox4"; this.groupBox4.Size = new System.Drawing.Size(272, 136); this.groupBox4.TabIndex = 2; @@ -240,13 +242,23 @@ namespace CodeImp.DoomBuilder.BuilderModes this.groupBox3.Controls.Add(this.editnewthing); this.groupBox3.Controls.Add(this.editnewsector); this.groupBox3.Controls.Add(this.additiveselect); - this.groupBox3.Location = new System.Drawing.Point(284, 104); + this.groupBox3.Location = new System.Drawing.Point(284, 139); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(379, 332); this.groupBox3.TabIndex = 3; this.groupBox3.TabStop = false; this.groupBox3.Text = " Options "; // + // additivepaintselect + // + this.additivepaintselect.AutoSize = true; + this.additivepaintselect.Location = new System.Drawing.Point(13, 135); + this.additivepaintselect.Name = "additivepaintselect"; + this.additivepaintselect.Size = new System.Drawing.Size(233, 17); + this.additivepaintselect.TabIndex = 11; + this.additivepaintselect.Text = "Additive paint selecting without holding Shift"; + this.additivepaintselect.UseVisualStyleBackColor = true; + // // switchviewmodes // this.switchviewmodes.AutoSize = true; @@ -375,7 +387,7 @@ namespace CodeImp.DoomBuilder.BuilderModes this.groupBox2.Controls.Add(this.label6); this.groupBox2.Controls.Add(this.label4); this.groupBox2.Controls.Add(this.label7); - this.groupBox2.Location = new System.Drawing.Point(6, 104); + this.groupBox2.Location = new System.Drawing.Point(6, 139); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(272, 190); this.groupBox2.TabIndex = 1; @@ -569,13 +581,15 @@ namespace CodeImp.DoomBuilder.BuilderModes // // groupBox1 // + this.groupBox1.Controls.Add(this.scaletexturesonslopes); + this.groupBox1.Controls.Add(this.label18); this.groupBox1.Controls.Add(this.splitbehavior); this.groupBox1.Controls.Add(this.label10); this.groupBox1.Controls.Add(this.label1); this.groupBox1.Controls.Add(this.heightbysidedef); this.groupBox1.Location = new System.Drawing.Point(6, 6); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(657, 92); + this.groupBox1.Size = new System.Drawing.Size(657, 127); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = " Behavior "; @@ -607,7 +621,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(9, 22); + this.label1.Location = new System.Drawing.Point(15, 22); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(308, 13); this.label1.TabIndex = 0; @@ -628,15 +642,28 @@ namespace CodeImp.DoomBuilder.BuilderModes this.heightbysidedef.Size = new System.Drawing.Size(309, 21); this.heightbysidedef.TabIndex = 0; // - // additivepaintselect + // label18 // - this.additivepaintselect.AutoSize = true; - this.additivepaintselect.Location = new System.Drawing.Point(13, 135); - this.additivepaintselect.Name = "additivepaintselect"; - this.additivepaintselect.Size = new System.Drawing.Size(233, 17); - this.additivepaintselect.TabIndex = 11; - this.additivepaintselect.Text = "Additive paint selecting without holding Shift"; - this.additivepaintselect.UseVisualStyleBackColor = true; + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(133, 94); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(190, 13); + this.label18.TabIndex = 2; + this.label18.Text = "When auto-aligning textures on slopes:"; + this.label18.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // scaletexturesonslopes + // + this.scaletexturesonslopes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.scaletexturesonslopes.FormattingEnabled = true; + this.scaletexturesonslopes.Items.AddRange(new object[] { + "Use a scale of 1 as base", + "Use current scale as base", + "Don\'t scale"}); + this.scaletexturesonslopes.Location = new System.Drawing.Point(342, 91); + this.scaletexturesonslopes.Name = "scaletexturesonslopes"; + this.scaletexturesonslopes.Size = new System.Drawing.Size(309, 21); + this.scaletexturesonslopes.TabIndex = 3; // // PreferencesForm // @@ -710,5 +737,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private System.Windows.Forms.Label label16; private System.Windows.Forms.Label label17; private System.Windows.Forms.CheckBox additivepaintselect; + private System.Windows.Forms.ComboBox scaletexturesonslopes; + private System.Windows.Forms.Label label18; } } \ No newline at end of file diff --git a/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs b/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs index 762a6a76..38ff83de 100755 --- a/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs +++ b/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs @@ -64,6 +64,7 @@ namespace CodeImp.DoomBuilder.BuilderModes defaultbrightness.Text = General.Settings.DefaultBrightness.ToString(); //mxd defaultceilheight.Text = General.Settings.DefaultCeilingHeight.ToString();//mxd defaultfloorheight.Text = General.Settings.DefaultFloorHeight.ToString(); //mxd + scaletexturesonslopes.SelectedIndex = General.Settings.ReadPluginSetting("scaletexturesonslopes", 0); } #endregion @@ -91,8 +92,10 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Settings.WritePluginSetting("autoaligntextureoffsetsoncreate", autoaligntexturesoncreate.Checked);//mxd General.Settings.WritePluginSetting("dontmovegeometryoutsidemapboundary", dontMoveGeometryOutsideBounds.Checked);//mxd General.Settings.WritePluginSetting("syncselection", syncSelection.Checked);//mxd + General.Settings.WritePluginSetting("scaletexturesonslopes", scaletexturesonslopes.SelectedIndex); General.Settings.SwitchViewModes = switchviewmodes.Checked; //mxd General.Settings.SplitLineBehavior = (SplitLineBehavior)splitbehavior.SelectedIndex;//mxd + //default sector values General.Settings.DefaultBrightness = General.Clamp(defaultbrightness.GetResult(192), 0, 255); diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs index f667dc84..c4647c12 100755 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs @@ -298,6 +298,32 @@ namespace CodeImp.DoomBuilder.BuilderModes //update angle UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f); + // Scale texture if it's a slope and the appropriate option is set + if (level.plane.Normal.z != 1.0f && BuilderPlug.Me.ScaleTexturesOnSlopes != 2) + { + Vector2D basescale = new Vector2D(1.0f, 1.0f); + + // User wants to use the current scale as a base? + if(BuilderPlug.Me.ScaleTexturesOnSlopes == 1) + { + basescale.x = scaleX; + basescale.y = scaleY; + } + + // Create a unit vector of the direction of the target line in 3D space + Vector3D targetlinevector = new Line3D(new Vector3D(targetLine.Start.Position, level.plane.GetZ(targetLine.Start.Position)), new Vector3D(targetLine.End.Position, level.plane.GetZ(targetLine.End.Position))).GetDelta().GetNormal(); + + // Get a perpendicular vector of the target line in 3D space. This is used to get the slope angle relative to the target line + Vector3D targetlineperpendicular = Vector3D.CrossProduct(targetlinevector, level.plane.Normal); + + if (alignx) + scaleX = Math.Abs(basescale.x * (1.0f / (float)Math.Cos(targetlinevector.GetAngleZ()))); + + if (aligny) + scaleY = Math.Abs(basescale.y * (1.0f / (float)Math.Cos(targetlineperpendicular.GetAngleZ()))); + + } + //set scale UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f); UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f); @@ -323,96 +349,6 @@ namespace CodeImp.DoomBuilder.BuilderModes Sector.UpdateSectorGeometry(false); } - //mxd - protected void AlignTextureToSlopeLine(Linedef slopeSource, float slopeAngle, bool isFront, bool alignx, bool aligny) - { - bool isFloor = (geometrytype == VisualGeometryType.FLOOR); - Sector.Sector.Fields.BeforeFieldsChange(); - float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(slopeSource.Angle) + 90 : -Angle2D.RadToDeg(slopeSource.Angle) - 90), 1); - - if(isFloor) - { - if((isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight) || - (!isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight)) - { - sourceAngle = General.ClampAngle(sourceAngle + 180); - } - } - else - { - if((isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight) || - (!isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight)) - { - sourceAngle = General.ClampAngle(sourceAngle + 180); - } - } - - //update angle - UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f); - - //update scaleY - string xScaleKey = (isFloor ? "xscalefloor" : "xscaleceiling"); - string yScaleKey = (isFloor ? "yscalefloor" : "yscaleceiling"); - - float scaleX = Sector.Sector.Fields.GetValue(xScaleKey, 1.0f); - float scaleY; - - //set scale - if(aligny) - { - scaleY = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2); - UniFields.SetFloat(Sector.Sector.Fields, yScaleKey, scaleY, 1.0f); - } - else - { - scaleY = Sector.Sector.Fields.GetValue(yScaleKey, 1.0f); - } - - //update texture offsets - Vector2D offset; - if(isFloor) - { - if((isFront && slopeSource.Front.Sector.FloorHeight < slopeSource.Back.Sector.FloorHeight) || - (!isFront && slopeSource.Front.Sector.FloorHeight > slopeSource.Back.Sector.FloorHeight)) - { - offset = slopeSource.End.Position; - } - else - { - offset = slopeSource.Start.Position; - } - } - else - { - if((isFront && slopeSource.Front.Sector.CeilHeight > slopeSource.Back.Sector.CeilHeight) || - (!isFront && slopeSource.Front.Sector.CeilHeight < slopeSource.Back.Sector.CeilHeight)) - { - offset = slopeSource.End.Position; - } - else - { - offset = slopeSource.Start.Position; - } - } - - offset = offset.GetRotated(Angle2D.DegToRad(sourceAngle)); - - if(alignx) - { - if(Texture != null && Texture.IsImageLoaded) offset.x %= Texture.Width / scaleX; - UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f); - } - - if(aligny) - { - if(Texture != null && Texture.IsImageLoaded) offset.y %= Texture.Height / scaleY; - UniFields.SetFloat(Sector.Sector.Fields, (isFloor ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f); - } - - //update geometry - Sector.UpdateSectorGeometry(false); - } - //mxd protected void ClearFields(IEnumerable keys, string undodescription, string resultdescription) { diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs index 5598eb68..c9ca4fa0 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualCeiling.cs @@ -654,42 +654,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(!General.Map.UDMF) return; - //is is a surface with line slope? - float slopeAngle = level.plane.Normal.GetAngleZ() - Angle2D.PIHALF; - - if(slopeAngle == 0) //it's a horizontal plane - { - AlignTextureToClosestLine(alignx, aligny); - } - else //it can be a surface with line slope - { - Linedef slopeSource = null; - bool isFront = false; - - foreach(Sidedef side in Sector.Sector.Sidedefs) - { - if(side.Line.Action == 181) - { - if(side.Line.Args[1] == 1 && side.Line.Front != null && side.Line.Front == side) - { - slopeSource = side.Line; - isFront = true; - break; - } - - if(side.Line.Args[1] == 2 && side.Line.Back != null && side.Line.Back == side) - { - slopeSource = side.Line; - break; - } - } - } - - if(slopeSource != null && slopeSource.Front != null && slopeSource.Front.Sector != null && slopeSource.Back != null && slopeSource.Back.Sector != null) - AlignTextureToSlopeLine(slopeSource, slopeAngle, isFront, alignx, aligny); - else - AlignTextureToClosestLine(alignx, aligny); - } + AlignTextureToClosestLine(alignx, aligny); } #endregion diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs index a8a4f285..8b28ce1e 100755 --- a/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs +++ b/Source/Plugins/BuilderModes/VisualModes/VisualFloor.cs @@ -586,42 +586,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(!General.Map.UDMF) return; - //is is a surface with line slope? - float slopeAngle = level.plane.Normal.GetAngleZ() - Angle2D.PIHALF; - - if(slopeAngle == 0) //it's a horizontal plane - { - AlignTextureToClosestLine(alignx, aligny); - } - else //it can be a surface with line slope - { - Linedef slopeSource = null; - bool isFront = false; - - foreach(Sidedef side in Sector.Sector.Sidedefs) - { - if(side.Line.Action == 181) - { - if(side.Line.Args[0] == 1 && side.Line.Front != null && side.Line.Front == side) - { - slopeSource = side.Line; - isFront = true; - break; - } - - if(side.Line.Args[0] == 2 && side.Line.Back != null && side.Line.Back == side) - { - slopeSource = side.Line; - break; - } - } - } - - if(slopeSource != null && slopeSource.Front != null && slopeSource.Front.Sector != null && slopeSource.Back != null && slopeSource.Back.Sector != null) - AlignTextureToSlopeLine(slopeSource, slopeAngle, isFront, alignx, aligny); - else - AlignTextureToClosestLine(alignx, aligny); - } + AlignTextureToClosestLine(alignx, aligny); } #endregion