mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Added some missing files
Some refactoring regarding visual sloping
This commit is contained in:
parent
5d1492c5c2
commit
5bcb27e51f
7 changed files with 487 additions and 99 deletions
|
@ -482,6 +482,7 @@
|
|||
<Compile Include="VisualModes\BaseVisualGeometrySidedef.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualMode.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualSlope.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualVertex.cs" />
|
||||
<Compile Include="VisualModes\Effect3DFloor.cs" />
|
||||
|
|
|
@ -480,6 +480,7 @@
|
|||
<Compile Include="VisualModes\BaseVisualGeometrySidedef.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualMode.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualSlope.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualVertex.cs" />
|
||||
<Compile Include="VisualModes\Effect3DFloor.cs" />
|
||||
|
@ -517,6 +518,7 @@
|
|||
<Compile Include="VisualModes\VisualSidedefParts.cs" />
|
||||
<Compile Include="VisualModes\VisualSidedefSlope.cs" />
|
||||
<Compile Include="VisualModes\VisualUpper.cs" />
|
||||
<Compile Include="VisualModes\VisualVertexSlope.cs" />
|
||||
<Compile Include="VisualModes\WallPolygon.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -819,7 +819,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if (General.Map.UDMF)
|
||||
{
|
||||
if (mode.AllSlopeHandles.ContainsKey(level.sector))
|
||||
foreach (VisualSidedefSlope handle in mode.AllSlopeHandles[level.sector])
|
||||
foreach (VisualSlope handle in mode.AllSlopeHandles[level.sector])
|
||||
handle.Changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,8 +417,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in allslopehandles)
|
||||
{
|
||||
foreach (VisualSlope handle in kvp.Value)
|
||||
if (handle.Selected) selectedobjects.Add((VisualSidedefSlope)handle);
|
||||
foreach (BaseVisualSlope handle in kvp.Value)
|
||||
if (handle.Selected) selectedobjects.Add(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,7 +540,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
else if(target.picked is VisualSlope)
|
||||
{
|
||||
|
||||
// Clear smart pivot handles, otherwise it will keep being displayed
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in allslopehandles)
|
||||
foreach (VisualSlope checkhandle in kvp.Value)
|
||||
|
@ -1305,10 +1304,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
foreach (VisualSlope handle in kvp.Value)
|
||||
if (handle != null && handle.Selected)
|
||||
if(handle is VisualSidedefSlope)
|
||||
RemoveSelectedObject((VisualSidedefSlope)handle);
|
||||
else
|
||||
RemoveSelectedObject((VisualVertexSlope)handle);
|
||||
if (handle is BaseVisualSlope)
|
||||
RemoveSelectedObject((BaseVisualSlope)handle);
|
||||
|
||||
kvp.Value.Clear();
|
||||
}
|
||||
|
|
125
Source/Plugins/BuilderModes/VisualModes/BaseVisualSlope.cs
Normal file
125
Source/Plugins/BuilderModes/VisualModes/BaseVisualSlope.cs
Normal file
|
@ -0,0 +1,125 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.BuilderModes;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
namespace CodeImp.DoomBuilder.VisualModes
|
||||
{
|
||||
internal abstract class BaseVisualSlope : VisualSlope, IVisualEventReceiver
|
||||
{
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
protected readonly BaseVisualMode mode;
|
||||
protected readonly SectorLevel level;
|
||||
protected Vector3D pickintersect;
|
||||
protected double pickrayu;
|
||||
protected readonly bool up;
|
||||
protected Plane plane;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public SectorLevel Level { get { return level; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
public BaseVisualSlope(BaseVisualMode mode, SectorLevel level, bool up)
|
||||
{
|
||||
this.mode = mode;
|
||||
this.level = level;
|
||||
this.up = up;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Select or deselect
|
||||
public void OnSelectEnd()
|
||||
{
|
||||
if (this.selected)
|
||||
{
|
||||
this.selected = false;
|
||||
mode.RemoveSelectedObject(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.pivot)
|
||||
{
|
||||
General.Interface.DisplayStatus(Windows.StatusType.Warning, "It is not allowed to mark pivot slope handles as selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.selected = true;
|
||||
mode.AddSelectedObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEditEnd()
|
||||
{
|
||||
// We can only have one pivot handle, so remove it from all first
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in mode.AllSlopeHandles)
|
||||
{
|
||||
foreach (VisualSlope handle in kvp.Value)
|
||||
{
|
||||
if (handle == mode.HighlightedTarget)
|
||||
{
|
||||
if (handle.Selected)
|
||||
General.Interface.DisplayStatus(Windows.StatusType.Warning, "It is not allowed to mark selected slope handles as pivot slope handles.");
|
||||
else
|
||||
handle.Pivot = !handle.Pivot;
|
||||
}
|
||||
else
|
||||
handle.Pivot = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void OnChangeTargetHeight(int amount);
|
||||
|
||||
// Return texture name
|
||||
public string GetTextureName() { return ""; }
|
||||
|
||||
// Unused
|
||||
public void OnSelectBegin() { }
|
||||
public void OnEditBegin() { }
|
||||
public void OnChangeTargetBrightness(bool up) { }
|
||||
public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { }
|
||||
public void OnSelectTexture() { }
|
||||
public void OnCopyTexture() { }
|
||||
public void OnPasteTexture() { }
|
||||
public void OnCopyTextureOffsets() { }
|
||||
public void OnPasteTextureOffsets() { }
|
||||
public void OnTextureAlign(bool alignx, bool aligny) { }
|
||||
public void OnToggleUpperUnpegged() { }
|
||||
public void OnToggleLowerUnpegged() { }
|
||||
public void OnProcess(long deltatime) { }
|
||||
public void OnTextureFloodfill() { }
|
||||
public void OnInsert() { }
|
||||
public void OnTextureFit(FitTextureOptions options) { } //mxd
|
||||
public void ApplyTexture(string texture) { }
|
||||
public void ApplyUpperUnpegged(bool set) { }
|
||||
public void ApplyLowerUnpegged(bool set) { }
|
||||
public void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd
|
||||
public virtual void OnPaintSelectEnd() { } // biwa
|
||||
public void OnChangeScale(int x, int y) { }
|
||||
public void OnResetTextureOffset() { }
|
||||
public void OnResetLocalTextureOffset() { }
|
||||
public void OnCopyProperties() { }
|
||||
public void OnPasteProperties(bool usecopysetting) { }
|
||||
public void OnDelete() { }
|
||||
public void OnPaintSelectBegin() { }
|
||||
public void OnMouseMove(MouseEventArgs e) { }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -11,17 +11,11 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
|
||||
namespace CodeImp.DoomBuilder.VisualModes
|
||||
{
|
||||
internal class VisualSidedefSlope : VisualSlope, IVisualEventReceiver
|
||||
internal class VisualSidedefSlope : BaseVisualSlope // VisualSlope, IVisualEventReceiver
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private readonly BaseVisualMode mode;
|
||||
private readonly Sidedef sidedef;
|
||||
private readonly SectorLevel level;
|
||||
private readonly bool up;
|
||||
private Vector3D pickintersect;
|
||||
private double pickrayu;
|
||||
private Plane plane;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -34,24 +28,17 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
#region ================== Properties
|
||||
|
||||
public Sidedef Sidedef { get { return sidedef; } }
|
||||
public SectorLevel Level { get { return level; } }
|
||||
public int NormalizedAngleDeg { get { return (sidedef.Line.AngleDeg >= 180) ? (sidedef.Line.AngleDeg - 180) : sidedef.Line.AngleDeg; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
public VisualSidedefSlope(BaseVisualMode mode, SectorLevel level, Sidedef sidedef, bool up) : base()
|
||||
public VisualSidedefSlope(BaseVisualMode mode, SectorLevel level, Sidedef sidedef, bool up) : base(mode, level, up)
|
||||
{
|
||||
this.mode = mode;
|
||||
this.sidedef = sidedef;
|
||||
this.level = level;
|
||||
this.up = up;
|
||||
|
||||
type = VisualSlopeType.Line;
|
||||
|
||||
// length = sidedef.Line.Length;
|
||||
|
||||
Update();
|
||||
|
||||
// We have no destructor
|
||||
|
@ -315,7 +302,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
#region ================== Events
|
||||
|
||||
public void OnChangeTargetHeight(int amount)
|
||||
public override void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
VisualSlope pivothandle = null;
|
||||
List<IVisualEventReceiver> selectedsectors = mode.GetSelectedObjects(true, false, false, false, false);
|
||||
|
@ -375,81 +362,6 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
mode.SetActionResult("Changed slope.");
|
||||
}
|
||||
|
||||
// Select or deselect
|
||||
public void OnSelectEnd()
|
||||
{
|
||||
if (this.selected)
|
||||
{
|
||||
this.selected = false;
|
||||
mode.RemoveSelectedObject(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.pivot)
|
||||
{
|
||||
General.Interface.DisplayStatus(Windows.StatusType.Warning, "It is not allowed to mark pivot slope handles as selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.selected = true;
|
||||
mode.AddSelectedObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEditEnd()
|
||||
{
|
||||
// We can only have one pivot handle, so remove it from all first
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in mode.AllSlopeHandles)
|
||||
{
|
||||
foreach (VisualSlope handle in kvp.Value)
|
||||
{
|
||||
if (handle == mode.HighlightedTarget)
|
||||
{
|
||||
if (handle.Selected)
|
||||
General.Interface.DisplayStatus(Windows.StatusType.Warning, "It is not allowed to mark selected slope handles as pivot slope handles.");
|
||||
else
|
||||
handle.Pivot = !handle.Pivot;
|
||||
}
|
||||
else
|
||||
handle.Pivot = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public string GetTextureName() { return ""; }
|
||||
|
||||
// Unused
|
||||
public void OnSelectBegin() { }
|
||||
public void OnEditBegin() { }
|
||||
public void OnChangeTargetBrightness(bool up) { }
|
||||
public void OnChangeTextureOffset(int horizontal, int vertical, bool doSurfaceAngleCorrection) { }
|
||||
public void OnSelectTexture() { }
|
||||
public void OnCopyTexture() { }
|
||||
public void OnPasteTexture() { }
|
||||
public void OnCopyTextureOffsets() { }
|
||||
public void OnPasteTextureOffsets() { }
|
||||
public void OnTextureAlign(bool alignx, bool aligny) { }
|
||||
public void OnToggleUpperUnpegged() { }
|
||||
public void OnToggleLowerUnpegged() { }
|
||||
public void OnProcess(long deltatime) { }
|
||||
public void OnTextureFloodfill() { }
|
||||
public void OnInsert() { }
|
||||
public void OnTextureFit(FitTextureOptions options) { } //mxd
|
||||
public void ApplyTexture(string texture) { }
|
||||
public void ApplyUpperUnpegged(bool set) { }
|
||||
public void ApplyLowerUnpegged(bool set) { }
|
||||
public void SelectNeighbours(bool select, bool withSameTexture, bool withSameHeight) { } //mxd
|
||||
public virtual void OnPaintSelectEnd() { } // biwa
|
||||
public void OnChangeScale(int x, int y) { }
|
||||
public void OnResetTextureOffset() { }
|
||||
public void OnResetLocalTextureOffset() { }
|
||||
public void OnCopyProperties() { }
|
||||
public void OnPasteProperties(bool usecopysetting) { }
|
||||
public void OnDelete() { }
|
||||
public void OnPaintSelectBegin() { }
|
||||
public void OnMouseMove(MouseEventArgs e) { }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
351
Source/Plugins/BuilderModes/VisualModes/VisualVertexSlope.cs
Normal file
351
Source/Plugins/BuilderModes/VisualModes/VisualVertexSlope.cs
Normal file
|
@ -0,0 +1,351 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.BuilderModes;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
namespace CodeImp.DoomBuilder.VisualModes
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the normalized angle (clockwise from the vertex) and if the original line's front points in a clockwise or counter clockwise direction
|
||||
/// </summary>
|
||||
internal struct LineAngleInfo
|
||||
{
|
||||
public double angle;
|
||||
public bool clockwise;
|
||||
|
||||
public LineAngleInfo(Linedef ld, Vertex v, Sector s)
|
||||
{
|
||||
Line2D line;
|
||||
|
||||
if (ld.Start == v)
|
||||
{
|
||||
line = ld.Line;
|
||||
clockwise = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = new Line2D(ld.End.Position, ld.Start.Position);
|
||||
clockwise = false;
|
||||
}
|
||||
|
||||
angle = line.GetAngle();
|
||||
|
||||
if (ld.Front.Sector != s)
|
||||
clockwise = !clockwise;
|
||||
}
|
||||
}
|
||||
|
||||
internal class VisualVertexSlope : BaseVisualSlope
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private readonly Vertex vertex;
|
||||
private readonly Sector sector;
|
||||
private double angle;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public Vertex Vertex { get { return vertex; } }
|
||||
public Sector Sector { get { return sector; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
public VisualVertexSlope(BaseVisualMode mode, SectorLevel level, Vertex vertex, Sector sector, bool up) : base(mode, level, up)
|
||||
{
|
||||
this.vertex = vertex;
|
||||
this.sector = sector;
|
||||
|
||||
type = VisualSlopeType.Vertex;
|
||||
|
||||
ComputeAngle();
|
||||
|
||||
Update();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
private void ComputeAngle()
|
||||
{
|
||||
List<LineAngleInfo> lines = new List<LineAngleInfo>();
|
||||
List<double> angles = new List<double>();
|
||||
|
||||
// Special case handling
|
||||
if (vertex.Linedefs.Count == 0) // should never happen
|
||||
{
|
||||
angle = 0.0;
|
||||
return;
|
||||
}
|
||||
else if (vertex.Linedefs.Count == 1)
|
||||
{
|
||||
angle = vertex.Linedefs.First().Angle + Angle2D.PIHALF;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all lines that we have to take into account. Ignore linedefs where both sides
|
||||
// don't belong to the sector or don't belong to the sector
|
||||
foreach (Linedef ld in vertex.Linedefs)
|
||||
{
|
||||
if (ld.IsDisposed)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
bool frontsame = false;
|
||||
bool backsame = false;
|
||||
|
||||
if (ld.Front != null && ld.Front.Sector == sector)
|
||||
frontsame = true;
|
||||
|
||||
if (ld.Back != null && ld.Back.Sector == sector)
|
||||
backsame = true;
|
||||
|
||||
if (frontsame == backsame)
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.Add(new LineAngleInfo(ld, vertex, sector));
|
||||
}
|
||||
|
||||
// Special case handling
|
||||
if(lines.Count == 0)
|
||||
{
|
||||
angle = lines[0].angle;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort lines by their normalized angle
|
||||
lines.Sort((a, b) => a.angle.CompareTo(b.angle));
|
||||
|
||||
// Get the other line we want to compute the angle between
|
||||
int other = 1;
|
||||
if (!lines[0].clockwise)
|
||||
other = lines.Count - 1;
|
||||
|
||||
Vector2D v1 = Vector2D.FromAngle(lines[0].angle);
|
||||
Vector2D v2 = Vector2D.FromAngle(lines[other].angle);
|
||||
|
||||
angle = lines[0].angle + (Math.Atan2(v2.y, v2.x) - Math.Atan2(v1.y, v1.x)) / 2.0;
|
||||
|
||||
// If the first line is going clockwise we have to add 180°
|
||||
if (lines[0].clockwise)
|
||||
angle += Angle2D.PI;
|
||||
|
||||
// Add 90° to get it in line with Doom's angles
|
||||
angle += Angle2D.PIHALF;
|
||||
|
||||
// Also need to modify the angle for ceilings
|
||||
if (level.type == SectorLevelType.Ceiling)
|
||||
angle += Angle2D.PI;
|
||||
|
||||
angle = Angle2D.Normalized(angle);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
plane = new Plane(level.plane.Normal, level.plane.Offset - 0.1f);
|
||||
|
||||
if (!up)
|
||||
plane = plane.GetInverted();
|
||||
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
public void UpdatePosition()
|
||||
{
|
||||
Vector2D av = Vector2D.FromAngle(angle);
|
||||
|
||||
SetPosition(new Line2D(vertex.Position, vertex.Position + av), level.plane);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a slope handle to pivot around. It takes the vertex that's furthest away from the given handle
|
||||
/// </summary>
|
||||
/// <param name="starthandle">The slope handle to start from (the one we need to find a pivot handle for)</param>
|
||||
/// <returns></returns>
|
||||
public static VisualVertexSlope GetSmartPivotHandle(VisualVertexSlope starthandle, BaseVisualMode mode)
|
||||
{
|
||||
VisualVertexSlope handle = starthandle;
|
||||
List<VisualVertexSlope> potentialhandles = new List<VisualVertexSlope>();
|
||||
List<IVisualEventReceiver> selectedsectors = mode.GetSelectedObjects(true, false, false, false, false);
|
||||
|
||||
if (selectedsectors.Count == 0)
|
||||
{
|
||||
// No sectors selected, so find all handles that belong to the same level
|
||||
foreach (VisualVertexSlope checkhandle in mode.VertexSlopeHandles[starthandle.Sector])
|
||||
{
|
||||
if (checkhandle != starthandle && checkhandle.Level == starthandle.Level)
|
||||
potentialhandles.Add(checkhandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sectors are selected, get all handles from those sectors that have the same level
|
||||
HashSet<Sector> sectors = new HashSet<Sector>();
|
||||
|
||||
foreach (BaseVisualGeometrySector bvgs in selectedsectors)
|
||||
sectors.Add(bvgs.Sector.Sector);
|
||||
|
||||
foreach (Sector s in sectors)
|
||||
foreach (VisualVertexSlope checkhandle in mode.VertexSlopeHandles[s])
|
||||
{
|
||||
if (checkhandle != starthandle)
|
||||
foreach (BaseVisualGeometrySector bvgs in selectedsectors)
|
||||
if (bvgs.Level == checkhandle.Level)
|
||||
potentialhandles.Add(checkhandle);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in mode.AllSlopeHandles)
|
||||
foreach (VisualSlope checkhandle in kvp.Value)
|
||||
checkhandle.SmartPivot = false;
|
||||
|
||||
handle = potentialhandles.OrderByDescending(h => Vector2D.Distance(h.Vertex.Position, starthandle.vertex.Position)).First();
|
||||
|
||||
if (handle == starthandle)
|
||||
return null;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the thing must be tested for line intersection. This should reject
|
||||
/// as fast as possible to rule out all geometry that certainly does not touch the line.
|
||||
/// </summary>
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
if (vertex.IsDisposed || sector.IsDisposed)
|
||||
return false;
|
||||
|
||||
RectangleF bbox = sector.BBox;
|
||||
|
||||
if ((up && plane.Distance(from) > 0.0f) || (!up && plane.Distance(from) < 0.0f))
|
||||
{
|
||||
if (plane.GetIntersection(from, to, ref pickrayu))
|
||||
{
|
||||
if (pickrayu > 0.0f)
|
||||
{
|
||||
pickintersect = from + (to - from) * pickrayu;
|
||||
|
||||
return ((pickintersect.x >= bbox.Left) && (pickintersect.x <= bbox.Right) &&
|
||||
(pickintersect.y >= bbox.Top) && (pickintersect.y <= bbox.Bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the thing must be tested for line intersection. This should perform
|
||||
/// accurate hit detection and set u_ray to the position on the ray where this hits the geometry.
|
||||
/// </summary>
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref double u_ray)
|
||||
{
|
||||
u_ray = pickrayu;
|
||||
|
||||
Sidedef sd = MapSet.NearestSidedef(sector.Sidedefs, pickintersect);
|
||||
Vertex v = MapSet.NearestVertex(new Vertex[] { sd.Line.Start, sd.Line.End }, pickintersect);
|
||||
if (v == vertex)
|
||||
{
|
||||
double side = sd.Line.SideOfLine(pickintersect);
|
||||
|
||||
if ((side <= 0.0f && sd.IsFront) || (side > 0.0f && !sd.IsFront))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pivor point for this slope handle
|
||||
/// </summary>
|
||||
/// <returns>The pivot point as Vector3D</returns>
|
||||
public override Vector3D GetPivotPoint()
|
||||
{
|
||||
return new Vector3D(vertex.Position, level.plane.GetZ(vertex.Position));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
public override void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
VisualSlope pivothandle = null;
|
||||
List<IVisualEventReceiver> selectedsectors = mode.GetSelectedObjects(true, false, false, false, false);
|
||||
List<SectorLevel> levels = new List<SectorLevel>();
|
||||
|
||||
if (selectedsectors.Count == 0)
|
||||
levels.Add(level);
|
||||
else
|
||||
{
|
||||
foreach (BaseVisualGeometrySector bvgs in selectedsectors)
|
||||
levels.Add(bvgs.Level);
|
||||
|
||||
if (!levels.Contains(level))
|
||||
levels.Add(level);
|
||||
}
|
||||
|
||||
// Try to find a slope handle the user set to be the pivot handle
|
||||
// TODO: doing this every time is kind of stupid. Maybe store the pivot handle in the mode?
|
||||
foreach (KeyValuePair<Sector, List<VisualSlope>> kvp in mode.AllSlopeHandles)
|
||||
{
|
||||
foreach (VisualSlope handle in kvp.Value)
|
||||
{
|
||||
if (handle.Pivot)
|
||||
{
|
||||
pivothandle = handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User didn't set a pivot handle, try to find the smart pivot handle
|
||||
if (pivothandle == null)
|
||||
pivothandle = GetSmartPivotHandle(this, mode);
|
||||
|
||||
// Still no pivot handle, cancle
|
||||
if (pivothandle == null)
|
||||
return;
|
||||
|
||||
pivothandle.SmartPivot = true;
|
||||
|
||||
mode.CreateUndo("Change slope");
|
||||
|
||||
Plane originalplane = level.plane;
|
||||
|
||||
// Build a new plane. Since we only got 2 points (the pivot point of the pivot handle and the vertex slope vertex) we need
|
||||
// to create a third point. That's done by getting the perpendicular of the line between the aforementioned 2 points, then
|
||||
// add the perpendicular to the vertex position of the vertex slope vertex
|
||||
Vector3D p3 = pivothandle.GetPivotPoint();
|
||||
Vector2D perp = new Line2D(vertex.Position, p3).GetPerpendicular();
|
||||
|
||||
Vector3D p1 = new Vector3D(vertex.Position, originalplane.GetZ(vertex.Position) + amount);
|
||||
Vector3D p2 = new Vector3D(vertex.Position + perp, originalplane.GetZ(vertex.Position + perp) + amount);
|
||||
|
||||
Plane plane = new Plane(p1, p2, p3, true);
|
||||
|
||||
// Apply slope to surfaces
|
||||
foreach (SectorLevel l in levels)
|
||||
VisualSidedefSlope.ApplySlope(l, plane, mode);
|
||||
|
||||
mode.SetActionResult("Changed slope.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue