refactor some polyline methods for dashed rendering

This commit is contained in:
Dustin Carlino 2020-05-13 14:35:59 -07:00
parent dd99936fa0
commit cd3100e561
8 changed files with 64 additions and 79 deletions

View File

@ -1,6 +1,6 @@
use crate::app::App;
use crate::info::{header_btns, make_table, make_tabs, Details, Tab};
use crate::render::{dashed_lines, DrawPedestrian};
use crate::render::DrawPedestrian;
use ezgui::{Btn, Color, EventCtx, Line, Text, TextExt, Widget};
use geom::{Angle, Circle, Distance, Speed, Time};
use map_model::{BuildingID, LaneID, Traversable, SIDEWALK_THICKNESS};
@ -68,8 +68,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID
.push(color, pl.make_polygons(Distance::meters(10.0)));
details.zoomed.extend(
color,
dashed_lines(
&pl,
pl.dashed_lines(
Distance::meters(0.75),
Distance::meters(1.0),
Distance::meters(0.4),

View File

@ -1,7 +1,6 @@
use crate::app::App;
use crate::helpers::ID;
use crate::info::{make_table, Details, Tab};
use crate::render::dashed_lines;
use ezgui::{
Btn, Color, EventCtx, GeomBatch, Line, LinePlot, PlotOptions, RewriteColor, Series, Text,
TextExt, Widget,
@ -488,8 +487,7 @@ fn make_timeline(
.push(color, trace.make_polygons(Distance::meters(10.0)));
details.zoomed.extend(
color,
dashed_lines(
&trace,
trace.dashed_lines(
Distance::meters(0.75),
Distance::meters(1.0),
Distance::meters(0.4),

View File

@ -1,7 +1,7 @@
use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{dashed_lines, DrawOptions, Renderable, OUTLINE_THICKNESS};
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use abstutil::Timer;
use ezgui::{Drawable, FancyColor, GeomBatch, GfxCtx, Prerender, RewriteColor};
use geom::{Angle, Distance, Line, PolyLine, Polygon, Pt2D};
@ -257,8 +257,7 @@ fn calculate_driving_lines(
let lane_edge_pts = map
.left_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
.get(timer);
dashed_lines(
&lane_edge_pts,
lane_edge_pts.dashed_lines(
Distance::meters(0.25),
Distance::meters(1.0),
Distance::meters(1.5),

View File

@ -24,9 +24,9 @@ pub use crate::render::map::{AgentCache, AgentColorScheme, DrawMap};
pub use crate::render::pedestrian::{DrawPedCrowd, DrawPedestrian};
pub use crate::render::road::DrawRoad;
pub use crate::render::traffic_signal::{draw_signal_phase, make_signal_diagram};
pub use crate::render::turn::{DrawTurn, DrawTurnGroup};
pub use crate::render::turn::DrawTurnGroup;
use ezgui::{GfxCtx, Prerender};
use geom::{Distance, PolyLine, Polygon, Pt2D, EPSILON_DIST};
use geom::{Distance, Polygon, Pt2D};
use map_model::{IntersectionID, Map};
use sim::{DrawCarInput, VehicleType};
@ -72,20 +72,6 @@ fn draw_vehicle(
}
}
pub fn dashed_lines(
pl: &PolyLine,
width: Distance,
dash_len: Distance,
dash_separation: Distance,
) -> Vec<Polygon> {
if pl.length() < dash_separation * 2.0 + EPSILON_DIST {
return vec![pl.make_polygons(width)];
}
// Don't draw the dashes too close to the ends.
pl.exact_slice(dash_separation, pl.length() - dash_separation)
.dashed_polygons(width, dash_len, dash_separation)
}
// TODO Borrow, don't clone, and fix up lots of places storing indirect things to populate
// DrawOptions.
#[derive(Clone)]

View File

@ -1,7 +1,7 @@
use crate::app::App;
use crate::colors::ColorScheme;
use crate::helpers::ID;
use crate::render::{dashed_lines, DrawOptions, Renderable};
use crate::render::{DrawOptions, Renderable};
use ezgui::{Drawable, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text};
use geom::{Angle, Distance, Polygon, Pt2D};
use map_model::{LaneType, Map, Road, RoadID};
@ -31,7 +31,7 @@ impl DrawRoad {
{
draw.extend(
cs.road_center_line,
dashed_lines(&center, width, Distance::meters(2.0), Distance::meters(1.0)),
center.dashed_lines(width, Distance::meters(2.0), Distance::meters(1.0)),
);
}

View File

@ -1,51 +1,9 @@
use crate::render::BIG_ARROW_THICKNESS;
use ezgui::{Color, GeomBatch, GfxCtx};
use geom::{Distance, Line, PolyLine, Polygon};
use map_model::{IntersectionID, LaneID, Map, Turn, TurnGroupID};
use geom::{Distance, PolyLine, Polygon};
use map_model::{IntersectionID, LaneID, Map, TurnGroupID};
use std::collections::{HashMap, HashSet};
const TURN_ICON_ARROW_LENGTH: Distance = Distance::const_meters(1.5);
pub struct DrawTurn {}
impl DrawTurn {
pub fn draw_full(t: &Turn, g: &mut GfxCtx, color: Color) {
g.draw_polygon(
color,
&t.geom
.make_arrow(BIG_ARROW_THICKNESS)
.expect(format!("draw_full {}", t.id)),
);
}
// TODO make a polyline.dashed or something
// TODO get rid of all these weird DrawTurn things generally
pub fn draw_dashed(turn: &Turn, batch: &mut GeomBatch, color: Color) {
let dash_len = Distance::meters(1.0);
batch.extend(
color,
turn.geom
.dashed_polygons(BIG_ARROW_THICKNESS, dash_len, Distance::meters(0.5)),
);
// And a cap on the arrow. In case the last line is long, trim it to be the dash
// length.
let last_line = turn.geom.last_line();
let last_len = last_line.length();
let arrow_line = if last_len <= dash_len {
last_line
} else {
Line::new(last_line.dist_along(last_len - dash_len), last_line.pt2())
};
batch.push(
color,
arrow_line
.to_polyline()
.make_arrow(BIG_ARROW_THICKNESS)
.unwrap(),
);
}
}
pub struct DrawTurnGroup {
pub id: TurnGroupID,
pub block: Polygon,

View File

@ -1,7 +1,7 @@
use crate::app::{App, ShowEverything};
use crate::common::ColorLegend;
use crate::game::{DrawBaselayer, State, Transition};
use crate::render::{dashed_lines, draw_signal_phase, make_signal_diagram, DrawOptions, DrawTurn};
use crate::render::{draw_signal_phase, make_signal_diagram, DrawOptions, BIG_ARROW_THICKNESS};
use ezgui::{
hotkey, Btn, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key,
Line, Outcome, Text, VerticalAlignment, Widget,
@ -39,8 +39,7 @@ impl RoutePreview {
let mut batch = GeomBatch::new();
batch.extend(
app.cs.route,
dashed_lines(
&trace,
trace.dashed_lines(
Distance::meters(0.75),
Distance::meters(1.0),
Distance::meters(0.4),
@ -208,7 +207,10 @@ impl State for TurnExplorer {
if self.idx == 0 {
for turn in &app.primary.map.get_turns_from_lane(self.l) {
DrawTurn::draw_full(turn, g, color_turn_type(turn.turn_type).alpha(0.5));
g.draw_polygon(
color_turn_type(turn.turn_type).alpha(0.5),
&turn.geom.make_arrow(BIG_ARROW_THICKNESS).unwrap(),
);
}
} else {
let current = &app.primary.map.get_turns_from_lane(self.l)[self.idx - 1];
@ -216,12 +218,21 @@ impl State for TurnExplorer {
let mut batch = GeomBatch::new();
for t in app.primary.map.get_turns_in_intersection(current.id.parent) {
if current.conflicts_with(t) {
DrawTurn::draw_dashed(t, &mut batch, CONFLICTING_TURN);
batch.extend(
CONFLICTING_TURN,
t.geom.dashed_arrow(
BIG_ARROW_THICKNESS,
Distance::meters(1.0),
Distance::meters(0.5),
),
);
}
}
batch.push(
CURRENT_TURN,
current.geom.make_arrow(BIG_ARROW_THICKNESS).unwrap(),
);
batch.draw(g);
DrawTurn::draw_full(current, g, CURRENT_TURN);
}
self.composite.draw(g);

View File

@ -451,7 +451,7 @@ impl PolyLine {
Polygon::precomputed(points, indices)
}
pub fn dashed_polygons(
pub fn exact_dashed_polygons(
&self,
width: Distance,
dash_len: Distance,
@ -477,6 +477,20 @@ impl PolyLine {
polygons
}
// Don't draw the dashes too close to the ends.
pub fn dashed_lines(
&self,
width: Distance,
dash_len: Distance,
dash_separation: Distance,
) -> Vec<Polygon> {
if self.length() < dash_separation * 2.0 + EPSILON_DIST {
return vec![self.make_polygons(width)];
}
self.exact_slice(dash_separation, self.length() - dash_separation)
.exact_dashed_polygons(width, dash_len, dash_separation)
}
pub fn make_arrow(&self, thickness: Distance) -> Warn<Polygon> {
let head_size = thickness * 2.0;
let triangle_height = head_size / 2.0_f64.sqrt();
@ -544,6 +558,26 @@ impl PolyLine {
}
}
pub fn dashed_arrow(
&self,
width: Distance,
dash_len: Distance,
dash_separation: Distance,
) -> Vec<Polygon> {
let mut polygons = self.exact_dashed_polygons(width, dash_len, dash_separation);
// And a cap on the arrow. In case the last line is long, trim it to be the dash
// length.
let last_line = self.last_line();
let last_len = last_line.length();
let arrow_line = if last_len <= dash_len {
last_line
} else {
Line::new(last_line.dist_along(last_len - dash_len), last_line.pt2())
};
polygons.push(arrow_line.to_polyline().make_arrow(width).unwrap());
polygons
}
// Also return the angle of the line where the hit was found
// TODO Also return distance along self of the hit
pub fn intersection(&self, other: &PolyLine) -> Option<(Pt2D, Angle)> {