This commit is contained in:
codeimp 2007-12-01 18:29:58 +00:00
parent 4f8cfec1c1
commit 467a2776c3
12 changed files with 251 additions and 281 deletions

View file

@ -219,7 +219,6 @@
</Compile>
<Compile Include="Map\Linedef.cs" />
<Compile Include="Map\MapOptions.cs" />
<Compile Include="Map\MapSelection.cs" />
<Compile Include="Map\MapSet.cs" />
<Compile Include="Data\DataLocation.cs" />
<Compile Include="Map\Sector.cs" />

View file

@ -56,6 +56,9 @@ namespace CodeImp.DoomBuilder.Editing
// List of old vertex positions
private List<Vector2D> oldpositions;
// List of selected items
private ICollection<Vertex> selectedverts;
// List of non-selected items
private ICollection<Vertex> unselectedverts;
@ -83,21 +86,24 @@ namespace CodeImp.DoomBuilder.Editing
Cursor.Current = Cursors.AppStarting;
// Make list of selected vertices
selectedverts = General.Map.Map.GetVerticesSelection(true);
// Make list of non-selected vertices
// This will be used for snapping to nearest items
unselectedverts = General.Map.Map.GetVerticesSelection(false);
// Make old positions list
// We will use this as reference to move the vertices, or to move them back on cancel
oldpositions = new List<Vector2D>(General.Map.Selection.Vertices.Count);
foreach(Vertex v in General.Map.Selection.Vertices) oldpositions.Add(v.Position);
oldpositions = new List<Vector2D>(selectedverts.Count);
foreach(Vertex v in selectedverts) oldpositions.Add(v.Position);
// Also keep old position of the dragged item
dragitemposition = dragitem.Position;
// Make list of non-selected vertices
// This will be used for snapping to nearest items
unselectedverts = General.Map.Map.InvertedCollection(General.Map.Selection.Vertices);
// Make list of unstable lines only
// These will have their length displayed during the drag
unstablelines = General.Map.Map.LinedefsFromSelectedVertices(false, true);
unstablelines = General.Map.Map.LinedefsFromSelectedVertices(false, false, true);
Cursor.Current = Cursors.Default;
@ -165,7 +171,7 @@ namespace CodeImp.DoomBuilder.Editing
if(!snapgrid || (dragitem.Position != oldpos))
{
// Move selected geometry
foreach(Vertex v in General.Map.Selection.Vertices)
foreach(Vertex v in selectedverts)
{
// Move vertex from old position relative to the
// mouse position change since drag start
@ -192,7 +198,7 @@ namespace CodeImp.DoomBuilder.Editing
MoveGeometryRelative(new Vector2D(0f, 0f), false, false);
// If only a single vertex was selected, deselect it now
if(General.Map.Selection.Vertices.Count == 1) General.Map.Selection.ClearVertices();
if(selectedverts.Count == 1) General.Map.Map.ClearSelectedVertices();
// Update cached values
General.Map.Map.Update();
@ -242,13 +248,13 @@ namespace CodeImp.DoomBuilder.Editing
stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0, false);
// Find lines that moved during the drag
movinglines = General.Map.Map.LinedefsFromSelectedVertices(true, true);
movinglines = General.Map.Map.LinedefsFromSelectedVertices(false, true, true);
// Find all non-moving lines (inverse of movinglines)
fixedlines = General.Map.Map.InvertedCollection(movinglines);
// Find all non-moving lines
fixedlines = General.Map.Map.LinedefsFromSelectedVertices(true, false, false);
// Join nearby vertices
stitches += MapSet.JoinVertices(unselectedverts, General.Map.Selection.Vertices, true, General.Settings.StitchDistance);
stitches += MapSet.JoinVertices(unselectedverts, selectedverts, true, General.Settings.StitchDistance);
// Update cached values
General.Map.Map.Update();
@ -257,11 +263,13 @@ namespace CodeImp.DoomBuilder.Editing
stitches += MapSet.SplitLinesByVertices(movinglines, unselectedverts, General.Settings.StitchDistance);
// Split non-moving lines with selected vertices
stitches += MapSet.SplitLinesByVertices(fixedlines, General.Map.Selection.Vertices, General.Settings.StitchDistance);
stitches += MapSet.SplitLinesByVertices(fixedlines, selectedverts, General.Settings.StitchDistance);
// TODO: Join overlapping lines and remove looped lines
// Remove looped linedefs
stitches += MapSet.RemoveLoopedLinedefs(General.Map.Map.Linedefs);
// Join overlapping lines
stitches += MapSet.JoinOverlappingLines(General.Map.Map.Linedefs);
// No stitching done? then withdraw undo
if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo);
@ -269,7 +277,7 @@ namespace CodeImp.DoomBuilder.Editing
// ===== END GEOMETRY STITCHING
// If only a single vertex was selected, deselect it now
if(General.Map.Selection.Vertices.Count == 1) General.Map.Selection.ClearVertices();
if(selectedverts.Count == 1) General.Map.Map.ClearSelectedVertices();
// Update cached values
General.Map.Map.Update();
@ -294,7 +302,8 @@ namespace CodeImp.DoomBuilder.Editing
{
// Render lines and vertices
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
renderer.RenderVerticesSet(General.Map.Map.Vertices);
renderer.RenderVerticesSet(unselectedverts);
renderer.RenderVerticesSet(selectedverts);
// Draw the dragged item highlighted
// This is important to know, because this item is used

View file

@ -192,18 +192,9 @@ namespace CodeImp.DoomBuilder.Editing
// Item highlighted?
if(highlighted != null)
{
// Item already selected?
if(General.Map.Selection.Vertices.Contains(highlighted))
{
// Deselect
General.Map.Selection.RemoveVertex(highlighted);
}
else
{
// Select
General.Map.Selection.AddVertex(highlighted);
}
// Flip selection
highlighted.Selected = !highlighted.Selected;
// Update display
if(renderer.Start(false, false))
{
@ -250,11 +241,11 @@ namespace CodeImp.DoomBuilder.Editing
if(highlighted != null)
{
// Highlighted item not selected?
if(!General.Map.Selection.Vertices.Contains(highlighted))
if(!highlighted.Selected)
{
// Select only this vertex for dragging
General.Map.Selection.ClearVertices();
General.Map.Selection.AddVertex(highlighted);
General.Map.Map.ClearSelectedVertices();
highlighted.Selected = true;
}
// Start dragging the selection

View file

@ -75,7 +75,6 @@ namespace CodeImp.DoomBuilder
private Renderer2D renderer2d;
private Renderer3D renderer3d;
private WAD tempwad;
private MapSelection selection;
private GridSetup grid;
private UndoManager undoredo;
@ -99,7 +98,6 @@ namespace CodeImp.DoomBuilder
public Renderer2D Renderer2D { get { return renderer2d; } }
public Renderer3D Renderer3D { get { return renderer3d; } }
public GameConfiguration Config { get { return config; } }
public MapSelection Selection { get { return selection; } }
public GridSetup Grid { get { return grid; } }
public UndoManager UndoRedo { get { return undoredo; } }
@ -115,7 +113,6 @@ namespace CodeImp.DoomBuilder
// Basic objects
grid = new GridSetup();
selection = new MapSelection();
undoredo = new UndoManager();
}
@ -133,7 +130,6 @@ namespace CodeImp.DoomBuilder
ActionAttribute.UnbindMethods(this);
// Basic objects
if(selection != null) selection.Dispose();
if(undoredo != null) undoredo.Dispose();
// Dispose
@ -896,7 +892,7 @@ namespace CodeImp.DoomBuilder
public void ClearSelection()
{
// Clear selection
selection.ClearAll();
map.ClearAllSelected();
// Redraw
General.MainWindow.RedrawDisplay();
@ -906,7 +902,7 @@ namespace CodeImp.DoomBuilder
public void ChangeMapSet(MapSet newmap)
{
// Can't have a selection in an old map set
selection.ClearAll();
map.ClearAllSelected();
// Apply
map.Dispose();

View file

@ -72,7 +72,7 @@ namespace CodeImp.DoomBuilder.Map
private byte[] args;
// Selections
private int selected;
private bool selected;
// Cloning
private Linedef clone;
@ -93,7 +93,7 @@ namespace CodeImp.DoomBuilder.Map
public int Flags { get { return flags; } }
public int Action { get { return action; } }
public int Tag { get { return tag; } }
public int Selected { get { return selected; } set { selected = value; } }
public bool Selected { get { return selected; } set { selected = value; } }
public float LengthSq { get { return lengthsq; } }
public float Length { get { return length; } }
public float LengthInv { get { return lengthinv; } }
@ -364,6 +364,13 @@ namespace CodeImp.DoomBuilder.Map
return nl;
}
// This joins the line with another line
// This line will be disposed
public void Join(Linedef other)
{
// TODO
}
#endregion
#region ================== Changes

View file

@ -1,202 +0,0 @@
#region ================== Copyright (c) 2007 Pascal vd Heiden
/*
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#endregion
#region ================== Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using CodeImp.DoomBuilder.Geometry;
#endregion
namespace CodeImp.DoomBuilder.Map
{
public sealed class MapSelection : IDisposable
{
#region ================== Constants
#endregion
#region ================== Variables
// Selected items
private List<Vertex> vertices;
private List<Linedef> linedefs;
private List<Sector> sectors;
private List<Thing> things;
// Disposing
private bool isdisposed = false;
#endregion
#region ================== Properties
public ICollection<Vertex> Vertices { get { return vertices; } }
public ICollection<Linedef> Linedefs { get { return linedefs; } }
public ICollection<Sector> Sectors { get { return sectors; } }
public ICollection<Thing> Things { get { return things; } }
public bool IsDisposed { get { return isdisposed; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public MapSelection()
{
// Initialize
vertices = new List<Vertex>();
linedefs = new List<Linedef>();
sectors = new List<Sector>();
things = new List<Thing>();
// We have no destructor
GC.SuppressFinalize(this);
}
// Diposer
public void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Clean up
ClearThings();
ClearSectors();
ClearLinedefs();
ClearVertices();
// Done
isdisposed = true;
}
}
#endregion
#region ================== Management
// This adds a vertex
public void AddVertex(Vertex v)
{
// Select it
v.Selected++;
vertices.Add(v);
}
// This adds a linedef
public void AddLinedef(Linedef l)
{
// Select it
l.Selected++;
linedefs.Add(l);
}
// This adds a sector
public void AddSector(Sector s)
{
// Select it
s.Selected++;
sectors.Add(s);
}
// This adds a thing
public void AddThing(Thing t)
{
// Select it
t.Selected++;
things.Add(t);
}
// This removes a vertex
public void RemoveVertex(Vertex v)
{
// Remove it
v.Selected--;
vertices.Remove(v);
}
// This adds a linedef
public void RemoveLinedef(Linedef l)
{
// Remove it
l.Selected--;
linedefs.Remove(l);
}
// This adds a sector
public void RemoveSector(Sector s)
{
// Remove it
s.Selected--;
sectors.Remove(s);
}
// This adds a thing
public void RemoveThing(Thing t)
{
// Remove it
t.Selected--;
things.Remove(t);
}
// This clears vertices
public void ClearVertices()
{
// Remove it
foreach(Vertex v in vertices) v.Selected--;
vertices.Clear();
}
// This clears linedefs
public void ClearLinedefs()
{
// Remove it
foreach(Linedef l in linedefs) l.Selected--;
linedefs.Clear();
}
// This clears sectors
public void ClearSectors()
{
// Remove it
foreach(Sector s in sectors) s.Selected--;
sectors.Clear();
}
// This clears things
public void ClearThings()
{
// Remove it
foreach(Thing t in things) t.Selected--;
things.Clear();
}
// This clears all
public void ClearAll()
{
ClearThings();
ClearLinedefs();
ClearSectors();
ClearVertices();
}
#endregion
}
}

View file

@ -317,8 +317,153 @@ namespace CodeImp.DoomBuilder.Map
#endregion
#region ================== Selection
// This clears all selected items
public void ClearAllSelected()
{
ClearSelectedVertices();
ClearSelectedThings();
ClearSelectedLinedefs();
ClearSelectedSectors();
}
// This clears selected vertices
public void ClearSelectedVertices()
{
foreach(Vertex v in vertices) v.Selected = false;
}
// This clears selected things
public void ClearSelectedThings()
{
foreach(Thing t in things) t.Selected = false;
}
// This clears selected linedefs
public void ClearSelectedLinedefs()
{
foreach(Linedef l in linedefs) l.Selected = false;
}
// This clears selected sectors
public void ClearSelectedSectors()
{
foreach(Sector s in sectors) s.Selected = false;
}
// Returns a collection of vertices that match a selected state
public ICollection<Vertex> GetVerticesSelection(bool selected)
{
List<Vertex> list = new List<Vertex>();
foreach(Vertex v in vertices) if(v.Selected == selected) list.Add(v);
return list;
}
// Returns a collection of things that match a selected state
public ICollection<Thing> GetThingsSelection(bool selected)
{
List<Thing> list = new List<Thing>();
foreach(Thing t in things) if(t.Selected == selected) list.Add(t);
return list;
}
// Returns a collection of linedefs that match a selected state
public ICollection<Linedef> GetLinedefsSelection(bool selected)
{
List<Linedef> list = new List<Linedef>();
foreach(Linedef l in linedefs) if(l.Selected == selected) list.Add(l);
return list;
}
// Returns a collection of sectors that match a selected state
public ICollection<Sector> GetSectorsSelection(bool selected)
{
List<Sector> list = new List<Sector>();
foreach(Sector s in sectors) if(s.Selected == selected) list.Add(s);
return list;
}
#endregion
#region ================== Static Tools
// This joins overlapping lines together
// Returns the number of joins made
public static int JoinOverlappingLines(ICollection<Linedef> lines)
{
int joinsdone = 0;
bool joined;
do
{
// No joins yet
joined = false;
// Go for all the lines
foreach(Linedef l1 in lines)
{
// Go for all the lines
foreach(Linedef l2 in lines)
{
// Sharing vertices?
if( ((l1.Start == l2.Start) && (l1.End == l2.End)) ||
((l1.End == l2.Start) && (l1.Start == l2.End)))
{
// Not the same line?
if(l1 != l2)
{
// Merge these two linedefs
l1.Join(l2);
joinsdone++;
joined = true;
break;
}
}
}
// Will have to restart when joined
if(joined) break;
}
}
while(joined);
// Return result
return joinsdone;
}
// This removes looped linedefs (linedefs which reference the same vertex for start and end)
// Returns the number of linedefs removed
public static int RemoveLoopedLinedefs(ICollection<Linedef> lines)
{
int linesremoved = 0;
bool removedline;
do
{
// Nothing removed yet
removedline = false;
// Go for all the lines
foreach(Linedef l in lines)
{
// Check if referencing the same vertex twice
if(l.Start == l.End)
{
// Remove this line
l.Dispose();
linesremoved++;
removedline = true;
break;
}
}
}
while(removedline);
// Return result
return linesremoved;
}
// This joins nearby vertices from two collections. This does NOT join vertices
// within the same collection, only if they exist in both collections.
// The vertex from the second collection is moved to match the first vertex.
@ -585,7 +730,7 @@ namespace CodeImp.DoomBuilder.Map
// This makes a list of lines related to vertex selection
// A line is unstable when one vertex is selected and the other isn't.
public ICollection<Linedef> LinedefsFromSelectedVertices(bool includestable, bool includeunstable)
public ICollection<Linedef> LinedefsFromSelectedVertices(bool includeunselected, bool includestable, bool includeunstable)
{
List<Linedef> list = new List<Linedef>();
@ -593,8 +738,9 @@ namespace CodeImp.DoomBuilder.Map
foreach(Linedef l in linedefs)
{
// Check if this is to be included
if((includestable && ((l.Start.Selected > 0) && (l.End.Selected > 0))) ||
(includeunstable && ((l.Start.Selected > 0) || (l.End.Selected > 0))) )
if((includestable && (l.Start.Selected && l.End.Selected)) ||
(includeunstable && (l.Start.Selected ^ l.End.Selected)) ||
(includeunselected && (!l.Start.Selected && !l.End.Selected)) )
{
// Add to list
list.Add(l);
@ -604,30 +750,6 @@ namespace CodeImp.DoomBuilder.Map
// Return result
return list;
}
// This returns all vertices not in verts collection
public ICollection<Vertex> InvertedCollection(ICollection<Vertex> verts)
{
List<Vertex> list = new List<Vertex>();
// Go for all vertices
foreach(Vertex v in vertices) if(!verts.Contains(v)) list.Add(v);
// Return result
return list;
}
// This returns all linedefs not in lines collection
public ICollection<Linedef> InvertedCollection(ICollection<Linedef> lines)
{
List<Linedef> list = new List<Linedef>();
// Go for all lines
foreach(Linedef l in linedefs) if(!lines.Contains(l)) list.Add(l);
// Return result
return list;
}
// This finds the line closest to the specified position
public Linedef NearestLinedef(Vector2D pos) { return MapSet.NearestLinedef(linedefs, pos); }

View file

@ -59,7 +59,7 @@ namespace CodeImp.DoomBuilder.Map
private int brightness;
// Selections
private int selected;
private bool selected;
// Cloning
private Sector clone;
@ -84,7 +84,7 @@ namespace CodeImp.DoomBuilder.Map
public int Effect { get { return effect; } }
public int Tag { get { return tag; } }
public int Brightness { get { return brightness; } }
public int Selected { get { return selected; } set { selected = value; } }
public bool Selected { get { return selected; } set { selected = value; } }
public Sector Clone { get { return clone; } set { clone = value; } }
#endregion

View file

@ -148,6 +148,54 @@ namespace CodeImp.DoomBuilder.Map
s.longtexnamelow = longtexnamelow;
}
// This copies textures to another sidedef
// And possibly also the offsets
public void AddTexturesTo(Sidedef s)
{
int copyoffsets = 0;
// Upper texture set?
if((texnamehigh.Length > 0) && (texnamehigh[0] != '-'))
{
// Copy upper texture
s.texnamehigh = texnamehigh;
s.longtexnamehigh = longtexnamehigh;
// Counts as a half coice for copying offsets
copyoffsets += 1;
}
// Middle texture set?
if((texnamemid.Length > 0) && (texnamemid[0] != '-'))
{
// Copy middle texture
s.texnamemid = texnamemid;
s.longtexnamemid = longtexnamemid;
// Counts for copying offsets
copyoffsets += 2;
}
// Lower texture set?
if((texnamelow.Length > 0) && (texnamelow[0] != '-'))
{
// Copy middle texture
s.texnamelow = texnamelow;
s.longtexnamelow = longtexnamelow;
// Counts as a half coice for copying offsets
copyoffsets += 1;
}
// Copy offsets also?
if(copyoffsets >= 2)
{
// Copy offsets
s.offsetx = offsetx;
s.offsety = offsety;
}
}
#endregion
#region ================== Changes

View file

@ -66,7 +66,7 @@ namespace CodeImp.DoomBuilder.Map
private float iconoffset; // Arrow or dot coordinate offset on the texture
// Selections
private int selected;
private bool selected;
// Disposing
private bool isdisposed = false;
@ -82,7 +82,7 @@ namespace CodeImp.DoomBuilder.Map
public float Angle { get { return angle; } }
public int AngleDeg { get { return (int)(angle * Angle2D.PIDEG); } }
public int Flags { get { return flags; } }
public int Selected { get { return selected; } set { selected = value; } }
public bool Selected { get { return selected; } set { selected = value; } }
public float Size { get { return size; } }
public float IconOffset { get { return iconoffset; } }
public PixelColor Color { get { return color; } }

View file

@ -55,7 +55,7 @@ namespace CodeImp.DoomBuilder.Map
private LinkedList<Linedef> linedefs;
// Selections
private int selected;
private bool selected;
// Cloning
private Vertex clone;
@ -73,7 +73,7 @@ namespace CodeImp.DoomBuilder.Map
public int X { get { return x; } }
public int Y { get { return y; } }
public bool IsDisposed { get { return isdisposed; } }
public int Selected { get { return selected; } set { selected = value; } }
public bool Selected { get { return selected; } set { selected = value; } }
public Vertex Clone { get { return clone; } set { clone = value; } }
#endregion

View file

@ -596,7 +596,7 @@ namespace CodeImp.DoomBuilder.Rendering
public PixelColor DetermineThingColor(Thing t)
{
// Determine color
if(t.Selected > 0) return General.Colors.Selection;
if(t.Selected) return General.Colors.Selection;
else return t.Color;
}
@ -604,7 +604,7 @@ namespace CodeImp.DoomBuilder.Rendering
public int DetermineVertexColor(Vertex v)
{
// Determine color
if(v.Selected > 0) return ColorCollection.SELECTION;
if(v.Selected) return ColorCollection.SELECTION;
else return ColorCollection.VERTICES;
}
@ -615,7 +615,7 @@ namespace CodeImp.DoomBuilder.Rendering
if((l.Back == null) || (l.Front == null))
{
// Determine color
if(l.Selected > 0) return General.Colors.Selection;
if(l.Selected) return General.Colors.Selection;
else if(l.Action != 0) return General.Colors.Actions;
else return General.Colors.Linedefs;
}
@ -623,7 +623,7 @@ namespace CodeImp.DoomBuilder.Rendering
else
{
// Determine color
if(l.Selected > 0) return General.Colors.Selection;
if(l.Selected) return General.Colors.Selection;
else if(l.Action != 0) return General.Colors.Actions.WithAlpha(DOUBLESIDED_LINE_ALPHA);
else if((l.Flags & General.Map.Config.SoundLinedefFlags) != 0) return General.Colors.Sounds.WithAlpha(DOUBLESIDED_LINE_ALPHA);
else return General.Colors.Linedefs.WithAlpha(DOUBLESIDED_LINE_ALPHA);