mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
some improvements in sector drawing (still very buggy though)
This commit is contained in:
parent
b5b7875f75
commit
3c0e66a36e
5 changed files with 195 additions and 38 deletions
|
@ -174,14 +174,65 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
ld.Selected = true;
|
||||
newlines.Add(ld);
|
||||
|
||||
// Should we split this line to merge with intersecting lines?
|
||||
if(points[i - 1].stitch || points[i].stitch)
|
||||
{
|
||||
// Check if any other lines intersect this line
|
||||
List<float> intersections = new List<float>();
|
||||
foreach(Linedef ld2 in map.Linedefs)
|
||||
{
|
||||
// Not the same as the subject line
|
||||
if(ld2 != ld)
|
||||
{
|
||||
// Intersecting?
|
||||
// We only keep the unit length from the start of the line and
|
||||
// do the real splitting later, when all intersections are known
|
||||
float u = ld.GetIntersectionU(ld2);
|
||||
if(!float.IsNaN(u) && (u > 0.0f) && (u < 1.0f)) intersections.Add(u);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the intersections
|
||||
intersections.Sort();
|
||||
|
||||
// Go for all found intersections
|
||||
Linedef splitline = ld;
|
||||
Line2D measureline = ld.GetLine2D();
|
||||
foreach(float u in intersections)
|
||||
{
|
||||
// Calculate exact coordinates where to split
|
||||
// We use measureline for this, because the original line
|
||||
// may already have changed in length due to a previous split
|
||||
Vector2D splitpoint = measureline.GetCoordinatesAt(u);
|
||||
|
||||
// Make the vertex
|
||||
Vertex splitvertex = map.CreateVertex((int)splitpoint.x, (int)splitpoint.y);
|
||||
|
||||
// The Split method ties the end of the original line to the given
|
||||
// vertex and starts a new line at the given vertex, so continue
|
||||
// splitting with the new line, because the intersections are sorted
|
||||
// from low to high (beginning at the original line start)
|
||||
splitline = splitline.Split(splitvertex);
|
||||
newlines.Add(splitline);
|
||||
newverts.Add(splitvertex);
|
||||
mergeverts.Add(splitvertex);
|
||||
}
|
||||
}
|
||||
|
||||
// Next
|
||||
v1 = v2;
|
||||
}
|
||||
|
||||
|
||||
// STEP 2: Merge the new geometry
|
||||
foreach(Vertex v in mergeverts) v.Marked = true;
|
||||
MapSet.JoinVertices(mergeverts, mergeverts, true, General.Settings.StitchDistance);
|
||||
map.StitchGeometry();
|
||||
|
||||
// Re-find our new lines, because they have been merged with the other geometry
|
||||
newlines = map.GetMarkedLinedefs(true);
|
||||
|
||||
// Split the new lines with the new vertices so that self-intersecting draws also work
|
||||
MapSet.SplitLinesByVertices(newlines, mergeverts, General.Settings.StitchDistance, null);
|
||||
|
||||
// STEP 3: Make sectors where possible
|
||||
bool[] frontsdone = new bool[newlines.Count];
|
||||
|
@ -240,6 +291,9 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make corrections for backward linedefs
|
||||
MapSet.FlipBackwardLinedefs(newlines);
|
||||
|
||||
// Update cached values
|
||||
map.Update();
|
||||
|
@ -300,10 +354,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
// This updates the dragging
|
||||
private void Update()
|
||||
{
|
||||
PixelColor color;
|
||||
|
||||
snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
|
||||
snaptonearest = General.Interface.CtrlState ^ General.Interface.AutoMerge;
|
||||
|
||||
Vector2D lastp = new Vector2D(0, 0);
|
||||
DrawnVertex lastp = new DrawnVertex();
|
||||
DrawnVertex curp = GetCurrentPosition();
|
||||
float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale;
|
||||
|
||||
|
@ -314,15 +370,28 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
if(points.Count > 0)
|
||||
{
|
||||
// Render lines
|
||||
lastp = points[0].pos;
|
||||
lastp = points[0];
|
||||
for(int i = 1; i < points.Count; i++)
|
||||
{
|
||||
renderer.RenderLine(lastp, points[i].pos, LINE_THICKNESS, General.Colors.Selection, true);
|
||||
lastp = points[i].pos;
|
||||
// Determine line color
|
||||
if(lastp.stitch || points[i].stitch)
|
||||
color = General.Colors.Highlight;
|
||||
else
|
||||
color = General.Colors.Selection;
|
||||
|
||||
// Render line
|
||||
renderer.RenderLine(lastp.pos, points[i].pos, LINE_THICKNESS, color, true);
|
||||
lastp = points[i];
|
||||
}
|
||||
|
||||
|
||||
// Determine line color
|
||||
if(lastp.stitch || snaptonearest)
|
||||
color = General.Colors.Highlight;
|
||||
else
|
||||
color = General.Colors.Selection;
|
||||
|
||||
// Render line to cursor
|
||||
renderer.RenderLine(lastp, curp.pos, LINE_THICKNESS, General.Colors.Highlight, true);
|
||||
renderer.RenderLine(lastp.pos, curp.pos, LINE_THICKNESS, color, true);
|
||||
|
||||
// Render vertices
|
||||
for(int i = 0; i < points.Count; i++)
|
||||
|
@ -338,8 +407,12 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
}
|
||||
}
|
||||
|
||||
// Determine point color
|
||||
if(snaptonearest) color = General.Colors.Highlight;
|
||||
else color = General.Colors.Selection;
|
||||
|
||||
// Render vertex at cursor
|
||||
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.Highlight, true);
|
||||
renderer.RenderRectangleFilled(new RectangleF(curp.pos.x - vsize, curp.pos.y - vsize, vsize * 2.0f, vsize * 2.0f), color, true);
|
||||
|
||||
// Done
|
||||
renderer.Finish();
|
||||
|
|
|
@ -329,36 +329,43 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|||
{
|
||||
// Find the nearest linedef within highlight range
|
||||
Linedef l = General.Map.Map.NearestLinedef(mousemappos);
|
||||
|
||||
// Check on which side of the linedef the mouse is
|
||||
float side = l.SideOfLine(mousemappos);
|
||||
if(side > 0)
|
||||
if(l != null)
|
||||
{
|
||||
// Is there a sidedef here?
|
||||
if(l.Back != null)
|
||||
// Check on which side of the linedef the mouse is
|
||||
float side = l.SideOfLine(mousemappos);
|
||||
if(side > 0)
|
||||
{
|
||||
// Highlight if not the same
|
||||
if(l.Back.Sector != highlighted) Highlight(l.Back.Sector);
|
||||
// Is there a sidedef here?
|
||||
if(l.Back != null)
|
||||
{
|
||||
// Highlight if not the same
|
||||
if(l.Back.Sector != highlighted) Highlight(l.Back.Sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Highlight nothing
|
||||
if(highlighted != null) Highlight(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Highlight nothing
|
||||
if(highlighted != null) Highlight(null);
|
||||
// Is there a sidedef here?
|
||||
if(l.Front != null)
|
||||
{
|
||||
// Highlight if not the same
|
||||
if(l.Front.Sector != highlighted) Highlight(l.Front.Sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Highlight nothing
|
||||
if(highlighted != null) Highlight(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a sidedef here?
|
||||
if(l.Front != null)
|
||||
{
|
||||
// Highlight if not the same
|
||||
if(l.Front.Sector != highlighted) Highlight(l.Front.Sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Highlight nothing
|
||||
if(highlighted != null) Highlight(null);
|
||||
}
|
||||
// Highlight nothing
|
||||
if(highlighted != null) Highlight(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
if(lines.Count == 1)
|
||||
{
|
||||
// Are we allowed to trace along this line again?
|
||||
if(tracecount[nextline] < 2)
|
||||
if(!tracecount.ContainsKey(nextline) || (tracecount[nextline] < 2))
|
||||
{
|
||||
// Turn around and go back along the other side of the line
|
||||
nextfront = !nextfront;
|
||||
|
@ -275,9 +275,18 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
Linedef prevline = nextline;
|
||||
if(lines[0] == nextline) nextline = lines[1]; else nextline = lines[0];
|
||||
|
||||
// Check if front side changes
|
||||
if((prevline.Start == nextline.Start) ||
|
||||
(prevline.End == nextline.End)) nextfront = !nextfront;
|
||||
// Are we allowed to trace this line again?
|
||||
if(!tracecount.ContainsKey(nextline) || (tracecount[nextline] < 2))
|
||||
{
|
||||
// Check if front side changes
|
||||
if((prevline.Start == nextline.Start) ||
|
||||
(prevline.End == nextline.End)) nextfront = !nextfront;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more lines, trace ends here
|
||||
path = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Continue as long as we have not reached the start yet
|
||||
|
|
|
@ -306,6 +306,51 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This flips the linedef's vertex attachments
|
||||
public void FlipVertices()
|
||||
{
|
||||
Vertex v = start;
|
||||
start = end;
|
||||
end = v;
|
||||
NeedUpdate();
|
||||
}
|
||||
|
||||
// This flips the sidedefs
|
||||
public void FlipSidedefs()
|
||||
{
|
||||
Sidedef sd = front;
|
||||
front = back;
|
||||
back = sd;
|
||||
}
|
||||
|
||||
// This makes a Line2D instance
|
||||
public Line2D GetLine2D()
|
||||
{
|
||||
return new Line2D(start.Position, end.Position);
|
||||
}
|
||||
|
||||
// This gets the intersection point with another line
|
||||
public float GetIntersectionU(Linedef other)
|
||||
{
|
||||
return GetIntersectionU(other.GetLine2D());
|
||||
}
|
||||
|
||||
// This gets the intersection point with another line
|
||||
// Returns NaN when no intersection exists.
|
||||
public float GetIntersectionU(Line2D otherline)
|
||||
{
|
||||
float u;
|
||||
Line2D thisline = this.GetLine2D();
|
||||
if(!otherline.GetIntersection(thisline, out u)) u = float.NaN;
|
||||
return u;
|
||||
}
|
||||
|
||||
// This returns a vector of coordinates at the given unit length
|
||||
public Vector2D GetCoordinatesAt(float u)
|
||||
{
|
||||
return GetLine2D().GetCoordinatesAt(u);
|
||||
}
|
||||
|
||||
// This returns a point for testing on one side
|
||||
public Vector2D GetSidePoint(bool front)
|
||||
{
|
||||
|
|
|
@ -470,7 +470,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
|
||||
// Returns a collection of vertices that match a marked state
|
||||
public ICollection<Vertex> GetMarkedVertices(bool mark)
|
||||
public List<Vertex> GetMarkedVertices(bool mark)
|
||||
{
|
||||
List<Vertex> list = new List<Vertex>(vertices.Count >> 1);
|
||||
foreach(Vertex v in vertices) if(v.Marked == mark) list.Add(v);
|
||||
|
@ -478,7 +478,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
|
||||
// Returns a collection of things that match a marked state
|
||||
public ICollection<Thing> GetMarkedThings(bool mark)
|
||||
public List<Thing> GetMarkedThings(bool mark)
|
||||
{
|
||||
List<Thing> list = new List<Thing>(things.Count >> 1);
|
||||
foreach(Thing t in things) if(t.Marked == mark) list.Add(t);
|
||||
|
@ -486,7 +486,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
|
||||
// Returns a collection of linedefs that match a marked state
|
||||
public ICollection<Linedef> GetMarkedLinedefs(bool mark)
|
||||
public List<Linedef> GetMarkedLinedefs(bool mark)
|
||||
{
|
||||
List<Linedef> list = new List<Linedef>(linedefs.Count >> 1);
|
||||
foreach(Linedef l in linedefs) if(l.Marked == mark) list.Add(l);
|
||||
|
@ -494,7 +494,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
|
||||
// Returns a collection of sectors that match a marked state
|
||||
public ICollection<Sector> GetMarkedSectors(bool mark)
|
||||
public List<Sector> GetMarkedSectors(bool mark)
|
||||
{
|
||||
List<Sector> list = new List<Sector>(sectors.Count >> 1);
|
||||
foreach(Sector s in sectors) if(s.Marked == mark) list.Add(s);
|
||||
|
@ -949,7 +949,30 @@ namespace CodeImp.DoomBuilder.Map
|
|||
// Return result
|
||||
return joinsdone;
|
||||
}
|
||||
|
||||
|
||||
// This corrects lines that have a back sidedef but no front
|
||||
// sidedef by flipping them. Returns the number of flips made.
|
||||
public static int FlipBackwardLinedefs(ICollection<Linedef> lines)
|
||||
{
|
||||
int flipsdone = 0;
|
||||
|
||||
// Examine all lines
|
||||
foreach(Linedef l in lines)
|
||||
{
|
||||
// Back side but no front side?
|
||||
if((l.Back != null) && (l.Front == null))
|
||||
{
|
||||
// Flip that linedef!
|
||||
l.FlipVertices();
|
||||
l.FlipSidedefs();
|
||||
flipsdone++;
|
||||
}
|
||||
}
|
||||
|
||||
// Return result
|
||||
return flipsdone;
|
||||
}
|
||||
|
||||
// This splits the given lines with the given vertices
|
||||
// All affected lines will be added to changedlines
|
||||
// Returns the number of splits made
|
||||
|
|
Loading…
Reference in a new issue