diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj
index 5bbde87c..74e7ffa7 100755
--- a/Source/Plugins/BuilderModes/BuilderModes.csproj
+++ b/Source/Plugins/BuilderModes/BuilderModes.csproj
@@ -181,6 +181,12 @@
PreferencesForm.cs
+
+ Form
+
+
+ SlopeArchForm.cs
+
True
True
@@ -196,6 +202,9 @@
+
+ SlopeArchForm.cs
+
diff --git a/Source/Plugins/BuilderModes/Interface/SlopeArchForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.Designer.cs
new file mode 100644
index 00000000..719fa5bd
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.Designer.cs
@@ -0,0 +1,177 @@
+namespace CodeImp.DoomBuilder.BuilderModes.Interface
+{
+ partial class SlopeArchForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.theta = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.offset = new CodeImp.DoomBuilder.Controls.ButtonsNumericTextbox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.cancel = new System.Windows.Forms.Button();
+ this.accept = new System.Windows.Forms.Button();
+ this.up = new System.Windows.Forms.RadioButton();
+ this.down = new System.Windows.Forms.RadioButton();
+ this.SuspendLayout();
+ //
+ // theta
+ //
+ this.theta.AllowDecimal = true;
+ this.theta.AllowExpressions = false;
+ this.theta.AllowNegative = false;
+ this.theta.AllowRelative = false;
+ this.theta.ButtonStep = 5;
+ this.theta.ButtonStepBig = 15F;
+ this.theta.ButtonStepFloat = 5F;
+ this.theta.ButtonStepSmall = 15F;
+ this.theta.ButtonStepsUseModifierKeys = true;
+ this.theta.ButtonStepsWrapAround = false;
+ this.theta.Location = new System.Drawing.Point(104, 7);
+ this.theta.Name = "theta";
+ this.theta.Size = new System.Drawing.Size(63, 24);
+ this.theta.StepValues = null;
+ this.theta.TabIndex = 18;
+ this.theta.WhenTextChanged += new System.EventHandler(this.UpdateArch);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(19, 17);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(31, 13);
+ this.label1.TabIndex = 19;
+ this.label1.Text = "theta";
+ //
+ // offset
+ //
+ this.offset.AllowDecimal = true;
+ this.offset.AllowExpressions = false;
+ this.offset.AllowNegative = false;
+ this.offset.AllowRelative = false;
+ this.offset.ButtonStep = 5;
+ this.offset.ButtonStepBig = 15F;
+ this.offset.ButtonStepFloat = 5F;
+ this.offset.ButtonStepSmall = 15F;
+ this.offset.ButtonStepsUseModifierKeys = true;
+ this.offset.ButtonStepsWrapAround = false;
+ this.offset.Location = new System.Drawing.Point(104, 37);
+ this.offset.Name = "offset";
+ this.offset.Size = new System.Drawing.Size(63, 24);
+ this.offset.StepValues = null;
+ this.offset.TabIndex = 20;
+ this.offset.WhenTextChanged += new System.EventHandler(this.UpdateArch);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(22, 47);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(33, 13);
+ this.label2.TabIndex = 21;
+ this.label2.Text = "offset";
+ //
+ // cancel
+ //
+ this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancel.Location = new System.Drawing.Point(104, 197);
+ this.cancel.Name = "cancel";
+ this.cancel.Size = new System.Drawing.Size(88, 24);
+ this.cancel.TabIndex = 22;
+ this.cancel.Text = "Cancel";
+ this.cancel.UseVisualStyleBackColor = true;
+ //
+ // accept
+ //
+ this.accept.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.accept.Location = new System.Drawing.Point(10, 197);
+ this.accept.Name = "accept";
+ this.accept.Size = new System.Drawing.Size(88, 24);
+ this.accept.TabIndex = 23;
+ this.accept.Text = "Apply";
+ this.accept.UseVisualStyleBackColor = true;
+ //
+ // up
+ //
+ this.up.AutoSize = true;
+ this.up.Checked = true;
+ this.up.Location = new System.Drawing.Point(22, 96);
+ this.up.Name = "up";
+ this.up.Size = new System.Drawing.Size(39, 17);
+ this.up.TabIndex = 24;
+ this.up.TabStop = true;
+ this.up.Text = "Up";
+ this.up.UseVisualStyleBackColor = true;
+ this.up.CheckedChanged += new System.EventHandler(this.UpdateArch);
+ //
+ // down
+ //
+ this.down.AutoSize = true;
+ this.down.Location = new System.Drawing.Point(22, 119);
+ this.down.Name = "down";
+ this.down.Size = new System.Drawing.Size(53, 17);
+ this.down.TabIndex = 25;
+ this.down.Text = "Down";
+ this.down.UseVisualStyleBackColor = true;
+ this.down.CheckedChanged += new System.EventHandler(this.UpdateArch);
+ //
+ // SlopeArchForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.cancel;
+ this.ClientSize = new System.Drawing.Size(205, 251);
+ this.Controls.Add(this.down);
+ this.Controls.Add(this.up);
+ this.Controls.Add(this.accept);
+ this.Controls.Add(this.cancel);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.offset);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.theta);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "SlopeArchForm";
+ this.ShowIcon = false;
+ this.Text = "SlopeArchForm";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private Controls.ButtonsNumericTextbox theta;
+ private System.Windows.Forms.Label label1;
+ private Controls.ButtonsNumericTextbox offset;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button cancel;
+ private System.Windows.Forms.Button accept;
+ private System.Windows.Forms.RadioButton up;
+ private System.Windows.Forms.RadioButton down;
+ }
+}
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Interface/SlopeArchForm.cs b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.cs
new file mode 100644
index 00000000..c7892ded
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using CodeImp.DoomBuilder.Windows;
+using CodeImp.DoomBuilder.Controls;
+using CodeImp.DoomBuilder.Editing;
+using CodeImp.DoomBuilder.Geometry;
+
+namespace CodeImp.DoomBuilder.BuilderModes.Interface
+{
+ public partial class SlopeArchForm : DelayedForm
+ {
+ private EditMode mode;
+ private double originaltheta;
+ private double originaloffset;
+ private Vector2D p1;
+ private Vector2D p2;
+
+ public SlopeArchForm(EditMode mode, Vector2D p1, Vector2D p2)
+ {
+ InitializeComponent();
+
+ this.mode = mode;
+ this.p1 = p1;
+ this.p2 = p2;
+
+ originaltheta = 90.0;
+ originaloffset = 45.0;
+
+ theta.Text = originaltheta.ToString();
+ offset.Text = originaloffset.ToString();
+ }
+
+ private void UpdateArch(object sender, EventArgs e)
+ {
+ double t = theta.GetResultFloat(originaltheta);
+ double o = offset.GetResultFloat(originaloffset);
+
+ if (t > 180.0)
+ theta.Text = "180";
+
+ if (t + o > 180.0 || t + o < 0.0)
+ return;
+
+ double s = up.Checked ? 1.0 : -1.0;
+
+ ((BaseVisualMode)mode).DoArchBetweenHandles(p1, p2, t, o, s);
+ }
+ }
+}
diff --git a/Source/Plugins/BuilderModes/Interface/SlopeArchForm.resx b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/Source/Plugins/BuilderModes/Interface/SlopeArchForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
index 10586ac5..bbd17afa 100755
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
@@ -4254,6 +4254,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public void ArchBetweenHandles()
{
List selectedsectors = GetSelectedObjects(true, false, false, false, false);
+
if (selectedsectors.Count < 2)
{
General.Interface.DisplayStatus(StatusType.Warning, "You need to select at least two floors and ceilings to slope arch between slope handles.");
@@ -4270,9 +4271,28 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.UndoRedo.CreateUndo("Arch between slope handles");
- Line2D handleline = new Line2D(handles[0].GetCenterPoint(), handles[1].GetCenterPoint());
- double offsetangle = Angle2D.DegToRad(0.0);
- double theta = Angle2D.DegToRad(180.0);
+ Vector2D p1 = handles[0].GetCenterPoint();
+ Vector2D p2 = handles[1].GetCenterPoint();
+
+ SlopeArchForm saf = new SlopeArchForm(this, p1, p2);
+ DialogResult result = saf.ShowDialog();
+
+ if (result == DialogResult.Cancel)
+ General.Map.UndoRedo.WithdrawUndo();
+
+
+ UpdateChangedObjects();
+
+ General.Interface.DisplayStatus(StatusType.Action, "Arched between slope handles.");
+ }
+
+ public void DoArchBetweenHandles(Vector2D p1, Vector2D p2, double _theta, double _offsetangle, double scale)
+ {
+ List selectedsectors = GetSelectedObjects(true, false, false, false, false);
+
+ Line2D handleline = new Line2D(p1, p2);
+ double offsetangle = Angle2D.DegToRad(_offsetangle);
+ double theta = Angle2D.DegToRad(_theta);
double length = handleline.GetLength();
double right = Math.Cos(0.0);
@@ -4287,32 +4307,48 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach (BaseVisualGeometrySector bvgs in selectedsectors)
{
- double u1 = double.MaxValue;
- double u2 = double.MinValue;
+ double u1 = 1.0;
+ double u2 = 0.0;
+
-
foreach (Sidedef sd in bvgs.Sector.Sides.Keys)
{
double intersection;
double bla;
- if (!Line2D.GetIntersection(handleline.v1, handleline.v2, sd.Line.Line.v1.x, sd.Line.Line.v1.y, sd.Line.Line.v2.x, sd.Line.Line.v2.y, out bla, out intersection, true))
+ if (!Line2D.GetIntersection(handleline.v1, handleline.v2, sd.Line.Line.v1.x, sd.Line.Line.v1.y, sd.Line.Line.v2.x, sd.Line.Line.v2.y, out bla, out intersection, false))
continue;
if (intersection < u1)
u1 = intersection;
-
if (intersection > u2)
u2 = intersection;
}
if (u1 == u2)
- continue;
+ {
+ if(u1 >= 0.5)
+ {
+ u1 = 1.0;
+ }
+ else
+ {
+ u2 = 0.0;
+ }
+
+ }
double xpos1 = sectionstart + (u1 * length);
double xpos2 = sectionstart + (u2 * length);
- double height1 = Math.Sqrt(radius * radius - xpos1 * xpos1);
- double height2 = Math.Sqrt(radius * radius - xpos2 * xpos2);
+ double height1 = Math.Sqrt(radius * radius - xpos1 * xpos1) * scale;
+ double height2 = Math.Sqrt(radius * radius - xpos2 * xpos2) * scale;
+
+ if (double.IsNaN(height1))
+ height1 = 0.0;
+
+ if (double.IsNaN(height2))
+ height2 = 0.0;
+
double slopeangle = Vector2D.GetAngle(new Vector2D(xpos1, height1), new Vector2D(xpos2, height2));
Plane plane = new Plane(new Vector3D(handleline.GetCoordinatesAt(u1), height1), handleline.GetAngle() + Angle2D.PIHALF, slopeangle, true);
@@ -4324,8 +4360,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
UpdateChangedObjects();
-
- General.Interface.DisplayStatus(StatusType.Action, "Arched between slope handles.");
}
#endregion