mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 04:12:12 +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();
|
||||
}
|
||||
|
||||
//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
|
||||
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 System.Drawing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Tools;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -239,6 +239,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
General.Interface.RefreshInfo();
|
||||
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
|
||||
|
||||
|
@ -623,51 +641,30 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
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
|
||||
if(marqueSelectionMode == MarqueSelectionMode.SELECT) {
|
||||
// Go for all lines
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
l.Selected = isInSelectionRect(l, selectionOutline);
|
||||
} else if(marqueSelectionMode == MarqueSelectionMode.ADD) {
|
||||
// Go for all lines
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
l.Selected |= isInSelectionRect(l, selectionOutline);
|
||||
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
||||
// Go for all lines
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
foreach (Linedef l in General.Map.Map.Linedefs)
|
||||
if(isInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||
} else { //should be Intersect
|
||||
// Go for all lines
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
// Go for the eyes, Boo! Go for the eyes!
|
||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
||||
if(!isInSelectionRect(l, selectionOutline)) l.Selected = false;
|
||||
}
|
||||
|
||||
//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
|
||||
|
||||
#region ================== Events
|
||||
|
@ -943,140 +976,38 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
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
|
||||
if(marqueSelectionMode == MarqueSelectionMode.SELECT){
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
//select sectors fully and partially inside selection, deselect all other sectors
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
bool select = false;
|
||||
bool select;
|
||||
foreach (Sector s in General.Map.Map.Sectors) {
|
||||
select = isInSelectionRect(s, selectionOutline);
|
||||
|
||||
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 && !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);
|
||||
}
|
||||
if(select && !s.Selected) SelectSector(s, true, false);
|
||||
else if(!select && s.Selected) SelectSector(s, false, false);
|
||||
}
|
||||
}else if(marqueSelectionMode == MarqueSelectionMode.ADD) { //additive selection
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
//select sectors fully and partially inside selection, leave others untouched
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
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);
|
||||
}
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
if(!s.Selected && isInSelectionRect(s, selectionOutline))
|
||||
SelectSector(s, true, false);
|
||||
}
|
||||
|
||||
} else if(marqueSelectionMode == MarqueSelectionMode.SUBTRACT) {
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
//deselect sectors fully and partially inside selection, leave others untouched
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
if(!s.Selected) continue;
|
||||
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);
|
||||
}
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
if(!s.Selected) continue;
|
||||
if(isInSelectionRect(s, selectionOutline))
|
||||
SelectSector(s, false, false);
|
||||
}
|
||||
|
||||
} else { //should be Intersect
|
||||
if(BuilderPlug.Me.MarqueSelectTouching) {
|
||||
//deselect sectors which are fully outside selection
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
if(!s.Selected) continue;
|
||||
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);
|
||||
}
|
||||
foreach(Sector s in General.Map.Map.Sectors) {
|
||||
if(!s.Selected) continue;
|
||||
if(!isInSelectionRect(s, selectionOutline))
|
||||
SelectSector(s, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue