Fit Textures action: texture repeats can now be negative.

Fixed, Fit Textures action: vertical texture offset of a middle part of double-sided linedef with "Lower unpegged" flag was calculated incorrectly.
Fixed, Fit Textures action: texture offsets were calculated incorrectly when using the action on several groups of connected walls at once with "Fit across connected surfaces" enabled.
Fixed, Visual mode: middle parts of double-sided linedefs were not rendered when ScaleY was negative.
Updated ZDoom_DECORATE.cfg.
This commit is contained in:
MaxED 2014-12-23 12:32:08 +00:00
parent deb43343bb
commit 4a1f8319c9
7 changed files with 192 additions and 135 deletions

View file

@ -56,6 +56,7 @@ keywords
A_Remove = "A_Remove(int pointer, int flags)\nflags: RMVF flags.";
A_SentinelBob = "A_SentinelBob";
A_SetTeleFog = "A_SetTeleFog(string telefogsourceclass, string telefogdestclass)";
A_Srcr2Decide = "A_Srcr2Decide";
A_SwapTeleFog = "A_SwapTeleFog";
A_TurretLook = "A_TurretLook";
A_Teleport = "A_Teleport[(string teleportstate = \"Teleport\"[, string targettype = \"BossSpot\"[, string fogtype = \"TeleportFog\"[, int flags = 0[, float mindist = 0[, float maxdist = 0]]]]])]";
@ -862,9 +863,16 @@ constants
SMF_PRECISE;
SPF_FORCECLAMP;
SPF_INTERPOLATE;
TF_FORCED;
TF_RANDOMDECIDE;
TF_TELEFRAG;
TF_RANDOMDECIDE;
TF_FORCED;
TF_KEEPVELOCITY;
TF_KEEPANGLE;
TF_USESPOTZ;
TF_NOSRCFOG;
TF_NODESTFOG;
TF_USEACTORFOG;
TF_NOJUMP;
TIF_NOTAKEINFINITE;
VAF_DMGTYPEAPPLYTODIRECT;
WARPF_ABSOLUTEANGLE;

View file

@ -19,6 +19,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
internal readonly Vector2D Start;
internal readonly Vector2D End;
internal Rectangle Bounds;
internal Rectangle GlobalBounds;
internal readonly Dictionary<SortedVisualSide, bool> NextSides;
internal readonly Dictionary<SortedVisualSide, bool> PreviousSides;
internal readonly int Index;
@ -86,6 +87,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
internal void OnTextureFit(FitTextureOptions options)
{
options.Bounds = Bounds;
options.GlobalBounds = GlobalBounds;
options.InitialOffsetX = OffsetX;
options.InitialOffsetY = OffsetY;
options.InitialScaleX = ScaleX;
@ -195,7 +197,37 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Connect sides
foreach (KeyValuePair<long, List<BaseVisualGeometrySidedef>> pair in sidesbytexture)
{
// Create strips
IEnumerable<SortedVisualSide> group = ConnectSides(pair.Value);
// Calculate global bounds...
int minx = int.MaxValue;
int maxx = int.MinValue;
int miny = int.MaxValue;
int maxy = int.MinValue;
foreach(SortedVisualSide side in group)
{
if(side.Bounds.X < minx) minx = side.Bounds.X;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width;
if(side.Bounds.Y < miny) miny = side.Bounds.Y;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height;
}
Rectangle bounds = new Rectangle(minx, miny, maxx - minx, maxy - miny);
// Normalize Y-offset
int offsety = bounds.Y;
bounds.Y = 0;
// Apply changes
foreach(SortedVisualSide side in group)
{
side.Bounds.Y -= offsety;
side.GlobalBounds = bounds;
}
// Add to result
result.AddRange(group);
}

View file

@ -27,11 +27,11 @@
private void InitializeComponent() {
this.labelhorizrepeat = new System.Windows.Forms.Label();
this.repeatgroup = new System.Windows.Forms.GroupBox();
this.labelvertrepeat = new System.Windows.Forms.Label();
this.horizrepeat = new System.Windows.Forms.NumericUpDown();
this.vertrepeat = new System.Windows.Forms.NumericUpDown();
this.resethoriz = new System.Windows.Forms.Button();
this.resetvert = new System.Windows.Forms.Button();
this.resethoriz = new System.Windows.Forms.Button();
this.vertrepeat = new System.Windows.Forms.NumericUpDown();
this.horizrepeat = new System.Windows.Forms.NumericUpDown();
this.labelvertrepeat = new System.Windows.Forms.Label();
this.cbfitwidth = new System.Windows.Forms.CheckBox();
this.accept = new System.Windows.Forms.Button();
this.cancel = new System.Windows.Forms.Button();
@ -39,8 +39,8 @@
this.cbfitconnected = new System.Windows.Forms.CheckBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.repeatgroup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.horizrepeat)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.vertrepeat)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.horizrepeat)).BeginInit();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
@ -68,60 +68,15 @@
this.repeatgroup.TabStop = false;
this.repeatgroup.Text = " Texture Repeating ";
//
// labelvertrepeat
// resetvert
//
this.labelvertrepeat.AutoSize = true;
this.labelvertrepeat.Location = new System.Drawing.Point(33, 52);
this.labelvertrepeat.Name = "labelvertrepeat";
this.labelvertrepeat.Size = new System.Drawing.Size(45, 13);
this.labelvertrepeat.TabIndex = 1;
this.labelvertrepeat.Text = "Vertical:";
//
// horizrepeat
//
this.horizrepeat.Location = new System.Drawing.Point(84, 22);
this.horizrepeat.Maximum = new decimal(new int[] {
512,
0,
0,
0});
this.horizrepeat.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.horizrepeat.Name = "horizrepeat";
this.horizrepeat.Size = new System.Drawing.Size(60, 20);
this.horizrepeat.TabIndex = 2;
this.horizrepeat.Value = new decimal(new int[] {
1,
0,
0,
0});
this.horizrepeat.ValueChanged += new System.EventHandler(this.repeat_ValueChanged);
//
// vertrepeat
//
this.vertrepeat.Location = new System.Drawing.Point(84, 48);
this.vertrepeat.Maximum = new decimal(new int[] {
512,
0,
0,
0});
this.vertrepeat.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.vertrepeat.Name = "vertrepeat";
this.vertrepeat.Size = new System.Drawing.Size(60, 20);
this.vertrepeat.TabIndex = 3;
this.vertrepeat.Value = new decimal(new int[] {
1,
0,
0,
0});
this.vertrepeat.ValueChanged += new System.EventHandler(this.repeat_ValueChanged);
this.resetvert.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset;
this.resetvert.Location = new System.Drawing.Point(150, 46);
this.resetvert.Name = "resetvert";
this.resetvert.Size = new System.Drawing.Size(24, 24);
this.resetvert.TabIndex = 5;
this.resetvert.UseVisualStyleBackColor = true;
this.resetvert.Click += new System.EventHandler(this.resetvert_Click);
//
// resethoriz
//
@ -133,15 +88,60 @@
this.resethoriz.UseVisualStyleBackColor = true;
this.resethoriz.Click += new System.EventHandler(this.resethoriz_Click);
//
// resetvert
// vertrepeat
//
this.resetvert.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset;
this.resetvert.Location = new System.Drawing.Point(150, 46);
this.resetvert.Name = "resetvert";
this.resetvert.Size = new System.Drawing.Size(24, 24);
this.resetvert.TabIndex = 5;
this.resetvert.UseVisualStyleBackColor = true;
this.resetvert.Click += new System.EventHandler(this.resetvert_Click);
this.vertrepeat.Location = new System.Drawing.Point(84, 48);
this.vertrepeat.Maximum = new decimal(new int[] {
512,
0,
0,
0});
this.vertrepeat.Minimum = new decimal(new int[] {
512,
0,
0,
-2147483648});
this.vertrepeat.Name = "vertrepeat";
this.vertrepeat.Size = new System.Drawing.Size(60, 20);
this.vertrepeat.TabIndex = 3;
this.vertrepeat.Value = new decimal(new int[] {
1,
0,
0,
0});
this.vertrepeat.ValueChanged += new System.EventHandler(this.vertrepeat_ValueChanged);
//
// horizrepeat
//
this.horizrepeat.Location = new System.Drawing.Point(84, 22);
this.horizrepeat.Maximum = new decimal(new int[] {
512,
0,
0,
0});
this.horizrepeat.Minimum = new decimal(new int[] {
512,
0,
0,
-2147483648});
this.horizrepeat.Name = "horizrepeat";
this.horizrepeat.Size = new System.Drawing.Size(60, 20);
this.horizrepeat.TabIndex = 2;
this.horizrepeat.Value = new decimal(new int[] {
1,
0,
0,
0});
this.horizrepeat.ValueChanged += new System.EventHandler(this.horizrepeat_ValueChanged);
//
// labelvertrepeat
//
this.labelvertrepeat.AutoSize = true;
this.labelvertrepeat.Location = new System.Drawing.Point(33, 52);
this.labelvertrepeat.Name = "labelvertrepeat";
this.labelvertrepeat.Size = new System.Drawing.Size(45, 13);
this.labelvertrepeat.TabIndex = 1;
this.labelvertrepeat.Text = "Vertical:";
//
// cbfitwidth
//
@ -196,7 +196,6 @@
this.cbfitconnected.TabIndex = 9;
this.cbfitconnected.Text = "Fit across connected surfaces";
this.cbfitconnected.UseVisualStyleBackColor = true;
this.cbfitconnected.CheckedChanged += new System.EventHandler(this.repeat_ValueChanged);
//
// groupBox2
//
@ -223,6 +222,7 @@
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FitTexturesForm";
this.Opacity = 1;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
@ -230,8 +230,8 @@
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FitTexturesForm_FormClosing);
this.repeatgroup.ResumeLayout(false);
this.repeatgroup.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.horizrepeat)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.vertrepeat)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.horizrepeat)).EndInit();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);

View file

@ -38,6 +38,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
private static Point location = Point.Empty;
private bool blockupdate;
private int prevhorizrepeat;
private int prevvertrepeat;
// Settings
private static int horizontalrepeat = 1;
@ -48,7 +50,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
//Surface stuff
private List<SortedVisualSide> strips;
private Rectangle bounds;
#endregion
@ -83,26 +84,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
return;
}
// Create bounds
int minx = int.MaxValue;
int maxx = int.MinValue;
int miny = int.MaxValue;
int maxy = int.MinValue;
foreach(SortedVisualSide side in strips)
{
if(side.Bounds.X < minx) minx = side.Bounds.X;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width;
if(side.Bounds.Y < miny) miny = side.Bounds.Y;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height;
}
bounds = new Rectangle(minx, miny, maxx-minx, maxy-miny);
// Normalize Y-offset
foreach (SortedVisualSide side in strips) side.Bounds.Y -= bounds.Y;
bounds.Y = 0;
#if DEBUG
//debug
DrawDebugUV();
@ -113,6 +94,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
horizrepeat.Value = horizontalrepeat;
vertrepeat.Value = verticalrepeat;
prevhorizrepeat = horizontalrepeat;
prevvertrepeat = verticalrepeat;
cbfitconnected.Checked = fitacrosssurfaces;
cbfitwidth.Checked = fitwidth;
cbfitheight.Checked = fitheight;
@ -129,7 +112,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Apply changes
FitTextureOptions options = new FitTextureOptions
{
GlobalBounds = bounds,
FitAcrossSurfaces = cbfitconnected.Checked,
FitWidth = cbfitwidth.Checked,
FitHeight = cbfitheight.Checked,
@ -177,17 +159,41 @@ namespace CodeImp.DoomBuilder.BuilderModes
private void resethoriz_Click(object sender, EventArgs e)
{
prevhorizrepeat = 1;
horizrepeat.Value = 1;
}
private void resetvert_Click(object sender, EventArgs e)
{
prevvertrepeat = 1;
vertrepeat.Value = 1;
}
private void repeat_ValueChanged(object sender, EventArgs e)
private void horizrepeat_ValueChanged(object sender, EventArgs e)
{
if(blockupdate) return;
if (horizrepeat.Value == 0)
{
horizrepeat.Value = prevhorizrepeat > 0 ? -1 : 1;
return;
}
prevhorizrepeat = (int)horizrepeat.Value;
UpdateChanges();
}
private void vertrepeat_ValueChanged(object sender, EventArgs e)
{
if(blockupdate) return;
if(vertrepeat.Value == 0)
{
vertrepeat.Value = prevvertrepeat > 0 ? -1 : 1;
return;
}
prevvertrepeat = (int)vertrepeat.Value;
UpdateChanges();
}
@ -225,42 +231,55 @@ namespace CodeImp.DoomBuilder.BuilderModes
private void DrawDebugUV()
{
const int margin = 20;
//find bounds
int minx = int.MaxValue;
int maxx = int.MinValue;
int miny = int.MaxValue;
int maxy = int.MinValue;
foreach(SortedVisualSide side in strips)
//sort by texture...
Dictionary<long, List<SortedVisualSide>> sortedstrips = new Dictionary<long, List<SortedVisualSide>>();
foreach(SortedVisualSide side in strips)
{
if(side.Bounds.X < minx) minx = side.Bounds.X;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width;
if(side.Bounds.Y < miny) miny = side.Bounds.Y;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height;
if(!sortedstrips.ContainsKey(side.Side.Texture.LongName))
sortedstrips.Add(side.Side.Texture.LongName, new List<SortedVisualSide>());
sortedstrips[side.Side.Texture.LongName].Add(side);
}
Bitmap bmp = new Bitmap(maxx - minx + margin * 2, maxy - miny + margin * 2);
using(Graphics g = Graphics.FromImage(bmp))
foreach (KeyValuePair<long, List<SortedVisualSide>> pair in sortedstrips)
{
int i = 0;
foreach(SortedVisualSide side in strips)
//find bounds
int minx = int.MaxValue;
int maxx = int.MinValue;
int miny = int.MaxValue;
int maxy = int.MinValue;
foreach(SortedVisualSide side in pair.Value)
{
Color c = General.Colors.BrightColors[General.Random(0, General.Colors.BrightColors.Length - 1)].ToColor();
Pen p = new Pen(c);
Brush b = new SolidBrush(c);
int x = side.Bounds.X - minx + margin;
int y = side.Bounds.Y - miny + margin;
g.DrawRectangle(p, x, y, side.Bounds.Width, side.Bounds.Height);
g.DrawString(i++ + ": line " + side.Side.Sidedef.Line.Index + "; x:" + side.Bounds.X + " y:" + side.Bounds.Y, this.Font, b, x + 2, y + 2);
if(side.Bounds.X < minx) minx = side.Bounds.X;
if(side.Bounds.X + side.Bounds.Width > maxx) maxx = side.Bounds.X + side.Bounds.Width;
if(side.Bounds.Y < miny) miny = side.Bounds.Y;
if(side.Bounds.Y + side.Bounds.Height > maxy) maxy = side.Bounds.Y + side.Bounds.Height;
}
}
bmp.Save("testuv.png", ImageFormat.Png);
Bitmap bmp = new Bitmap(maxx - minx + margin * 2, maxy - miny + margin * 2);
using(Graphics g = Graphics.FromImage(bmp))
{
int i = 0;
foreach(SortedVisualSide side in pair.Value)
{
Color c = General.Colors.BrightColors[General.Random(0, General.Colors.BrightColors.Length - 1)].ToColor();
Pen p = new Pen(c);
Brush b = new SolidBrush(c);
int x = side.Bounds.X - minx + margin;
int y = side.Bounds.Y - miny + margin;
g.DrawRectangle(p, x, y, side.Bounds.Width, side.Bounds.Height);
g.DrawString(i++ + ": line " + side.Side.Sidedef.Line.Index + "; x:" + side.Bounds.X + " y:" + side.Bounds.Y, this.Font, b, x + 2, y + 2);
}
}
bmp.Save("testuv_" + pair.Value[0].Side.Texture.ShortName + ".png", ImageFormat.Png);
}
General.Interface.DisplayStatus(StatusType.Info, "Saved test image!");
}

View file

@ -658,9 +658,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if (Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
{
//offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, options.Bounds.Y * scaley - Sidedef.OffsetY, scaley, true) - (options.Bounds.Height + Sidedef.GetHighHeight()) * scaley;
offsety = (options.Bounds.Y - /*options.Bounds.Height -*/ Sidedef.GetHighHeight()) * scaley - Sidedef.OffsetY;
//offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, offsety, scaley, true);
offsety = (options.Bounds.Y - Sidedef.GetHighHeight() - Sidedef.GetLowHeight()) * scaley - Sidedef.OffsetY;
}
else
{

View file

@ -74,35 +74,35 @@ namespace CodeImp.DoomBuilder.BuilderModes {
SectorData sd = mode.GetSectorData(Sidedef.Other.Sector);
//mxd. which texture we must use?
long textureLong = 0;
long longtexture = 0;
if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
{
if (Sidedef.Other.LongHighTexture != MapSet.EmptyLongName)
textureLong = Sidedef.Other.LongHighTexture;
longtexture = Sidedef.Other.LongHighTexture;
}
else if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
{
if(Sidedef.Other.LongLowTexture != MapSet.EmptyLongName)
textureLong = Sidedef.Other.LongLowTexture;
longtexture = Sidedef.Other.LongLowTexture;
}
else if ((sourceside.LongMiddleTexture != MapSet.EmptyLongName))
{
textureLong = sourceside.LongMiddleTexture;
longtexture = sourceside.LongMiddleTexture;
}
// Texture given?
if (textureLong != 0)
if (longtexture != 0)
{
// Load texture
base.Texture = General.Map.Data.GetTextureImage(textureLong);
base.Texture = General.Map.Data.GetTextureImage(longtexture);
if(base.Texture == null || base.Texture is UnknownImage)
{
base.Texture = General.Map.Data.UnknownTexture3D;
setuponloadedtexture = textureLong;
setuponloadedtexture = longtexture;
}
else if (!base.Texture.IsImageLoaded)
{
setuponloadedtexture = textureLong;
setuponloadedtexture = longtexture;
}
}
else

View file

@ -196,16 +196,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(!repeatmidtex)
{
// First determine the visible portion of the texture
float textop, texbottom;
float textop;
// Determine top portion height
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
textop = geobottom + tof.y + tsz.y;
textop = geobottom + tof.y + Math.Abs(tsz.y);
else
textop = geotop + tof.y;
// Calculate bottom portion height
texbottom = textop - tsz.y;
float texbottom = textop - Math.Abs(tsz.y);
// Create crop planes (we also need these for intersection testing)
topclipplane = new Plane(new Vector3D(0, 0, -1), textop);