mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 12:22:35 +00:00
Sectors and Linedefs modes: rectangular selection now checks for intersections between linedefs and itself when "select touching" is enabled.
This commit is contained in:
parent
c4130499fc
commit
e4a924eb14
4 changed files with 95 additions and 165 deletions
|
@ -90,6 +90,11 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
return new Vector2D(dx, dy).GetNormal();
|
return new Vector2D(dx, dy).GetNormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. This tests if given lines intersects
|
||||||
|
public static bool GetIntersection(Line2D line1, Line2D line2) {
|
||||||
|
return GetIntersection(line1.v1, line1.v2, line2.v1.x, line2.v1.y, line2.v2.x, line2.v2.y);
|
||||||
|
}
|
||||||
|
|
||||||
// This tests if the line intersects with the given line coordinates
|
// This tests if the line intersects with the given line coordinates
|
||||||
public static bool GetIntersection(Vector2D v1, Vector2D v2, float x3, float y3, float x4, float y4)
|
public static bool GetIntersection(Vector2D v1, Vector2D v2, float x3, float y3, float x4, float y4)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,9 +22,6 @@ using CodeImp.DoomBuilder.Config;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using CodeImp.DoomBuilder.IO;
|
using CodeImp.DoomBuilder.IO;
|
||||||
using CodeImp.DoomBuilder.Types;
|
|
||||||
using CodeImp.DoomBuilder.Data;
|
|
||||||
using CodeImp.DoomBuilder.GZBuilder.Tools;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
General.Interface.RefreshInfo();
|
General.Interface.RefreshInfo();
|
||||||
General.Map.IsChanged = true;
|
General.Map.IsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd
|
||||||
|
private bool isInSelectionRect(Linedef l, List<Line2D> selectionOutline) {
|
||||||
|
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||||
|
bool selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
||||||
|
|
||||||
|
//check intersections with outline
|
||||||
|
if(!selected) {
|
||||||
|
foreach(Line2D line in selectionOutline) {
|
||||||
|
if(Line2D.GetIntersection(l.Line, line))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -623,51 +641,30 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
if(selectionvolume)
|
if(selectionvolume)
|
||||||
{
|
{
|
||||||
|
List<Line2D> selectionOutline = new List<Line2D>() {
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top),
|
||||||
|
new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom),
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Right, selectionrect.Bottom),
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Left, selectionrect.Top)
|
||||||
|
};
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
|
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
|
||||||
// Go for all lines
|
// Go for all lines
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
l.Selected = isInSelectionRect(l, selectionOutline);
|
||||||
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
|
||||||
} else {
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
|
||||||
l.Selected = selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
|
||||||
}
|
|
||||||
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
|
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
|
||||||
// Go for all lines
|
// Go for all lines
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
l.Selected |= isInSelectionRect(l, selectionOutline);
|
||||||
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
|
||||||
} else {
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
|
||||||
l.Selected |= selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y);
|
|
||||||
}
|
|
||||||
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
||||||
// Go for all lines
|
// Go for all lines
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach (Linedef l in General.Map.Map.Linedefs)
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs) {
|
if(isInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||||
if(selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || selectionrect.Contains(l.End.Position.x, l.End.Position.y))
|
|
||||||
l.Selected = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs) {
|
|
||||||
if(selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && selectionrect.Contains(l.End.Position.x, l.End.Position.y))
|
|
||||||
l.Selected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { //should be Intersect
|
} else { //should be Intersect
|
||||||
// Go for all lines
|
// Go for the eyes, Boo! Go for the eyes!
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs) {
|
if(!isInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||||
if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) && !selectionrect.Contains(l.End.Position.x, l.End.Position.y))
|
|
||||||
l.Selected = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs) {
|
|
||||||
if(!selectionrect.Contains(l.Start.Position.x, l.Start.Position.y) || !selectionrect.Contains(l.End.Position.x, l.End.Position.y))
|
|
||||||
l.Selected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
|
|
|
@ -468,6 +468,39 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd
|
||||||
|
private bool isInSelectionRect(Sector s, List<Line2D> selectionOutline) {
|
||||||
|
bool selected = false;
|
||||||
|
|
||||||
|
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||||
|
//check endpoints
|
||||||
|
foreach (Sidedef side in s.Sidedefs) {
|
||||||
|
selected = (selectionrect.Contains(side.Line.Start.Position.x, side.Line.Start.Position.y)
|
||||||
|
|| selectionrect.Contains(side.Line.End.Position.x, side.Line.End.Position.y));
|
||||||
|
if (selected) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check line intersections
|
||||||
|
foreach (Sidedef side in s.Sidedefs) {
|
||||||
|
foreach (Line2D line in selectionOutline) {
|
||||||
|
if(Line2D.GetIntersection(side.Line.Line, line))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check endpoints
|
||||||
|
foreach(Sidedef side in s.Sidedefs) {
|
||||||
|
selected = (selectionrect.Contains(side.Line.Start.Position.x, side.Line.Start.Position.y)
|
||||||
|
&& selectionrect.Contains(side.Line.End.Position.x, side.Line.End.Position.y));
|
||||||
|
if(!selected) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Events
|
#region ================== Events
|
||||||
|
@ -943,140 +976,38 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
if(selectionvolume)
|
if(selectionvolume)
|
||||||
{
|
{
|
||||||
|
List<Line2D> selectionOutline = new List<Line2D>() {
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Top, selectionrect.Right, selectionrect.Top),
|
||||||
|
new Line2D(selectionrect.Right, selectionrect.Top, selectionrect.Right, selectionrect.Bottom),
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Right, selectionrect.Bottom),
|
||||||
|
new Line2D(selectionrect.Left, selectionrect.Bottom, selectionrect.Left, selectionrect.Top)
|
||||||
|
};
|
||||||
|
|
||||||
//mxd. collect changed sectors
|
//mxd. collect changed sectors
|
||||||
if(marqueSelectionMode == MarqueSelectionMode.SELECT){
|
if(marqueSelectionMode == MarqueSelectionMode.SELECT){
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
bool select;
|
||||||
//select sectors fully and partially inside selection, deselect all other sectors
|
foreach (Sector s in General.Map.Map.Sectors) {
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
select = isInSelectionRect(s, selectionOutline);
|
||||||
bool select = false;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
if(select && !s.Selected) SelectSector(s, true, false);
|
||||||
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
else if(!select && s.Selected) SelectSector(s, false, false);
|
||||||
select = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(select && !s.Selected)
|
|
||||||
SelectSector(s, true, false);
|
|
||||||
else if(!select && s.Selected)
|
|
||||||
SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//select sectors fully inside selection, deselect all other sectors
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
|
||||||
bool select = true;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
select = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(select && !s.Selected)
|
|
||||||
SelectSector(s, true, false);
|
|
||||||
else if(!select && s.Selected)
|
|
||||||
SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
|
}else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Sector s in General.Map.Map.Sectors) {
|
||||||
//select sectors fully and partially inside selection, leave others untouched
|
if(!s.Selected && isInSelectionRect(s, selectionOutline))
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
SelectSector(s, true, false);
|
||||||
if(s.Selected) continue;
|
|
||||||
bool select = false;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
select = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(select) SelectSector(s, true, false);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//select sectors fully inside selection, leave others untouched
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
|
||||||
if(s.Selected) continue;
|
|
||||||
bool select = true;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
select = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(select) SelectSector(s, true, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Sector s in General.Map.Map.Sectors) {
|
||||||
//deselect sectors fully and partially inside selection, leave others untouched
|
if(!s.Selected) continue;
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
if(isInSelectionRect(s, selectionOutline))
|
||||||
if(!s.Selected) continue;
|
SelectSector(s, false, false);
|
||||||
bool deselect = false;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
deselect = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deselect) SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//deselect sectors fully inside selection, leave others untouched
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
|
||||||
if(!s.Selected) continue;
|
|
||||||
bool deselect = true;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
deselect = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deselect) SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { //should be Intersect
|
} else { //should be Intersect
|
||||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
foreach(Sector s in General.Map.Map.Sectors) {
|
||||||
//deselect sectors which are fully outside selection
|
if(!s.Selected) continue;
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
if(!isInSelectionRect(s, selectionOutline))
|
||||||
if(!s.Selected) continue;
|
SelectSector(s, false, false);
|
||||||
bool keep = false;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
keep = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!keep) SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//deselect sectors which are fully and partially outside selection
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors) {
|
|
||||||
if(!s.Selected) continue;
|
|
||||||
bool keep = true;
|
|
||||||
|
|
||||||
foreach(Sidedef sd in s.Sidedefs) {
|
|
||||||
if(!selectionrect.Contains(sd.Line.Start.Position.x, sd.Line.Start.Position.y) || !selectionrect.Contains(sd.Line.End.Position.x, sd.Line.End.Position.y)) {
|
|
||||||
keep = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!keep) SelectSector(s, false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue