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)
This commit is contained in:
biwa 2020-04-04 18:03:40 +02:00
parent a3ce81dc2b
commit 560d4a5828
6 changed files with 77 additions and 176 deletions

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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<string> keys, string undodescription, string resultdescription)
{

View file

@ -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

View file

@ -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