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(); 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)
{ {

View file

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

View file

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

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