private static void ApplyHorizontalOffset(SortedVisualSide side, SortedVisualSide prevside, bool forward, Dictionary <int, bool> processed) { // Set offset if (!processed.ContainsKey(side.Index)) { if (prevside != null) { if (forward) { side.Bounds.X = prevside.Bounds.X + (int)Math.Round(prevside.Side.Sidedef.Line.Length); } else { side.Bounds.X = prevside.Bounds.X - (int)Math.Round(side.Side.Sidedef.Line.Length); } } processed.Add(side.Index, false); } // Repeat for NextSides foreach (KeyValuePair <SortedVisualSide, bool> pair in side.NextSides) { if (!processed.ContainsKey(pair.Key.Index)) { ApplyHorizontalOffset(pair.Key, side, true, processed); } } // Repeat for PreviousSides foreach (KeyValuePair <SortedVisualSide, bool> pair in side.PreviousSides) { if (!processed.ContainsKey(pair.Key.Index)) { ApplyHorizontalOffset(pair.Key, side, false, processed); } } }
// Connect sides, left to right and sort them into connected groups // NextSides - sides connected to the right (Start) vertex, // PreviousSides - sides connected to the left (End) vertex private static Dictionary <int, List <SortedVisualSide> > ConnectSides(List <BaseVisualGeometrySidedef> allsides) { Dictionary <int, List <SortedVisualSide> > result = new Dictionary <int, List <SortedVisualSide> >(); List <SortedVisualSide> sides = new List <SortedVisualSide>(allsides.Count); int groupindex = 0; foreach (BaseVisualGeometrySidedef side in allsides) { sides.Add(new SortedVisualSide(side)); } foreach (SortedVisualSide curside in sides) { if (curside.GroupIndex == -1) { curside.GroupIndex = groupindex++; } // Find sides connected to the end of curside foreach (SortedVisualSide nextside in sides) { if (curside.Index == nextside.Index) { continue; } if (nextside.Start == curside.End && nextside.End != curside.Start) { // Add both ways if (!nextside.PreviousSides.ContainsKey(curside)) { nextside.PreviousSides.Add(curside, false); nextside.GroupIndex = curside.GroupIndex; } if (!curside.NextSides.ContainsKey(nextside)) { curside.NextSides.Add(nextside, false); nextside.GroupIndex = curside.GroupIndex; } } } // Find sides connected to the start of curside foreach (SortedVisualSide prevside in sides) { if (curside.Index == prevside.Index) { continue; } if (prevside.End == curside.Start && prevside.Start != curside.End) { // Add both ways if (!prevside.NextSides.ContainsKey(curside)) { prevside.NextSides.Add(curside, false); prevside.GroupIndex = curside.GroupIndex; } if (!curside.PreviousSides.ContainsKey(prevside)) { curside.PreviousSides.Add(prevside, false); prevside.GroupIndex = curside.GroupIndex; } } } // Add to collection if (!result.ContainsKey(curside.GroupIndex)) { result.Add(curside.GroupIndex, new List <SortedVisualSide>()); } result[curside.GroupIndex].Add(curside); } // Try to find the left-most side foreach (KeyValuePair <int, List <SortedVisualSide> > pair in result) { SortedVisualSide start = pair.Value[0]; foreach (SortedVisualSide side in pair.Value) { if (side.PreviousSides.Count == 0) { start = side; break; } } // Set horizontal offsets... ApplyHorizontalOffset(start, null, true, new Dictionary <int, bool>()); } return(result); }