Sectors and Linedefs modes: rectangular selection now checks for intersections between linedefs and itself when "select touching" is enabled.

This commit is contained in:
MaxED 2013-11-29 14:45:29 +00:00
parent c4130499fc
commit e4a924eb14
4 changed files with 95 additions and 165 deletions

View file

@ -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)
{

View file

@ -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

View file

@ -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

View file

@ -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);
}
}