diff --git a/Source/Plugins/BuilderModes/IO/ImageExporter.cs b/Source/Plugins/BuilderModes/IO/ImageExporter.cs index 71ded00..8e9b601 100644 --- a/Source/Plugins/BuilderModes/IO/ImageExporter.cs +++ b/Source/Plugins/BuilderModes/IO/ImageExporter.cs @@ -34,6 +34,9 @@ using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Map; using System.Diagnostics; +using CodeImp.DoomBuilder.Rendering; +using CodeImp.DoomBuilder.Windows; +using System.Security.Policy; namespace CodeImp.DoomBuilder.BuilderModes.IO { @@ -208,6 +211,36 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO foreach (Sector s in sectors) { float rotation = (float)s.Fields.GetValue("rotationfloor", 0.0); + Vector2D foffset = new Vector2D(0.0f, 0.0f); + + if (General.Map.SRB2) + { + bool sidealignment = false; + foreach (Sidedef side in s.Sidedefs) + { + if (side.Line.IsFlatAlignment && side.Line.Tag == 0 && side.Line.Front.Sector == s && + ((settings.Floor && !side.Line.IsFlagSet("2048")) || (!settings.Floor && !side.Line.IsFlagSet("4096")))) + { + sidealignment = true; + rotation = GetFlatRotation(side.Line, s); + foffset = GetFlatOffset(side.Line, s); + } + } + + if (!sidealignment) + { + if (s.Tag != 0) + { + foreach (Linedef l in General.Map.Map.Linedefs) + if (l.IsFlatAlignment && (l.Tag == s.Tag) && + ((settings.Floor && !l.IsFlagSet("2048")) || (!settings.Floor && !l.IsFlagSet("4096")))) + { + rotation = GetFlatRotation(l, s); + foffset = GetFlatOffset(l, s); + } + } + } + } // If a sector is rotated any offset is on the rotated axes. But we need to offset by // map coordinates. We'll use this vector to compute that offset @@ -263,6 +296,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO textureoffset.x = s.Fields.GetValue("xpanningfloor", 0.0f) * scale; textureoffset.y = s.Fields.GetValue("ypanningfloor", 0.0f) * scale; + if (General.Map.SRB2) + { + textureoffset.x = foffset.x * scale; + textureoffset.y = foffset.y * scale; + } + // GZDoom uses bigger numbers for smaller scales (i.e. a scale of 2 will halve the size), so we need to change the scale texturescale.x = 1.0f / s.Fields.GetValue("xscalefloor", 1.0f); texturescale.y = 1.0f / s.Fields.GetValue("yscalefloor", 1.0f); @@ -279,6 +318,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO textureoffset.x = s.Fields.GetValue("xpanningceiling", 0.0f) * scale; textureoffset.y = s.Fields.GetValue("ypanningceiling", 0.0f) * scale; + if (General.Map.SRB2) + { + textureoffset.x = foffset.x * scale; + textureoffset.y = foffset.y * scale; + } + // GZDoom uses bigger numbers for smaller scales (i.e. a scale of 2 will halve the size), so we need to change the scale texturescale.x = 1.0f / s.Fields.GetValue("xscaleceiling", 1.0f); texturescale.y = 1.0f / s.Fields.GetValue("yscaleceiling", 1.0f); @@ -538,7 +583,46 @@ namespace CodeImp.DoomBuilder.BuilderModes.IO image = destImage; } + private float GetFlatRotation(Linedef l, Sector s) + { + bool useoffsets = l.IsFlagSet("8192"); + float xoffset = useoffsets ? l.Front.OffsetX : -l.Start.Position.x; + float yoffset = useoffsets ? -l.Front.OffsetY : -l.Start.Position.y; + float rotation = General.ClampAngle(90f - l.Angle * Angle2D.PIDEG); + + // Affine offset, this got me a few headaches of why both rotation and offset didn't worked at same time + float rotationrad = rotation / Angle2D.PIDEG; + float cos = (float)Math.Cos(rotationrad); + float sin = (float)Math.Sin(rotationrad); + float rx = cos * xoffset - sin * yoffset; + float ry = sin * xoffset + cos * yoffset; + xoffset = rx; + yoffset = -ry; + Vector2D offset = new Vector2D(xoffset, yoffset); + + return rotation; + } + private Vector2D GetFlatOffset(Linedef l, Sector s) + { + bool useoffsets = l.IsFlagSet("8192"); + + float xoffset = useoffsets ? l.Front.OffsetX : -l.Start.Position.x; + float yoffset = useoffsets ? -l.Front.OffsetY : -l.Start.Position.y; + float rotation = General.ClampAngle(90f - l.Angle * Angle2D.PIDEG); + + // Affine offset, this got me a few headaches of why both rotation and offset didn't worked at same time + float rotationrad = rotation / Angle2D.PIDEG; + float cos = (float)Math.Cos(rotationrad); + float sin = (float)Math.Sin(rotationrad); + float rx = cos * xoffset - sin * yoffset; + float ry = sin * xoffset + cos * yoffset; + xoffset = rx; + yoffset = -ry; + Vector2D offset = new Vector2D(xoffset, yoffset); + + return offset; + } #endregion } }