drawing current traffic signal turns as nicer arrows on the lanes

This commit is contained in:
Dustin Carlino 2018-11-27 10:45:40 -08:00
parent 93dd6b1c17
commit 53330e846c
3 changed files with 60 additions and 41 deletions

View File

@ -5,6 +5,7 @@ use map_model::{IntersectionID, LaneID, TurnType};
use objects::{Ctx, ID};
use piston::input::Key;
use plugins::{Plugin, PluginCtx};
use render::turn_markings;
#[derive(Clone, Debug)]
pub enum TurnCyclerState {
@ -91,16 +92,18 @@ impl Plugin for TurnCyclerState {
}
TurnCyclerState::Intersection(id) => {
if let Some(signal) = ctx.control_map.traffic_signals.get(&id) {
let color = Some(
ctx.cs
.get("turns allowed by traffic signal right now", Color::GREEN),
);
let (cycle, _) =
signal.current_cycle_and_remaining_time(ctx.sim.time.as_time());
// TODO Maybe don't show SharedSidewalkCorners at all, and highlight the
// Crosswalks.
for t in &cycle.turns {
ctx.draw_map.get_t(*t).draw_full(
g,
ctx.cs.get(
"turns allowed by traffic signal right now",
Color::GREEN.alpha(0.5),
),
);
for m in turn_markings(ctx.map.get_t(*t), ctx.map) {
m.draw(g, ctx.cs, color);
}
}
}
}

View File

@ -6,14 +6,14 @@ use dimensioned::si;
use ezgui::{Color, GfxCtx, Text};
use geom::{Bounds, Circle, Line, Polygon, Pt2D};
use map_model::{
IntersectionType, Lane, LaneID, LaneType, Map, Road, LANE_THICKNESS, PARKING_SPOT_LENGTH,
IntersectionType, Lane, LaneID, LaneType, Map, Road, Turn, LANE_THICKNESS, PARKING_SPOT_LENGTH,
};
use objects::{Ctx, ID};
use render::{RenderOptions, Renderable, BIG_ARROW_THICKNESS, PARCEL_BOUNDARY_THICKNESS};
const MIN_ZOOM_FOR_LANE_MARKERS: f64 = 5.0;
struct Marking {
pub struct Marking {
lines: Vec<Line>,
// Weird indirection to keep the color definition close to the marking definition, without
// needing to plumb in a ColorScheme immediately.
@ -23,6 +23,25 @@ struct Marking {
arrow_head_length: Option<f64>,
}
impl Marking {
pub fn draw(&self, g: &mut GfxCtx, cs: &mut ColorScheme, default_color: Option<Color>) {
let color = default_color.unwrap_or_else(|| (self.color)(cs));
for line in &self.lines {
if let Some(head_length) = self.arrow_head_length {
if self.round {
g.draw_rounded_arrow(color, self.thickness, head_length, line);
} else {
g.draw_arrow(color, self.thickness, head_length, line);
}
} else if self.round {
g.draw_rounded_line(color, self.thickness, line);
} else {
g.draw_line(color, self.thickness, line);
}
}
}
}
pub struct DrawLane {
pub id: LaneID,
pub polygon: Polygon,
@ -127,19 +146,7 @@ impl Renderable for DrawLane {
if opts.cam_zoom >= MIN_ZOOM_FOR_LANE_MARKERS {
for m in &self.markings {
for line in &m.lines {
if let Some(head_length) = m.arrow_head_length {
if m.round {
g.draw_rounded_arrow((m.color)(ctx.cs), m.thickness, head_length, line);
} else {
g.draw_arrow((m.color)(ctx.cs), m.thickness, head_length, line);
}
} else if m.round {
g.draw_rounded_line((m.color)(ctx.cs), m.thickness, line);
} else {
g.draw_line((m.color)(ctx.cs), m.thickness, line);
}
}
m.draw(g, ctx.cs, None);
}
}
@ -302,23 +309,32 @@ fn calculate_turn_markings(map: &Map, lane: &Lane) -> Vec<Marking> {
return results;
}
for turn in map.get_turns_from_lane(lane.id) {
results.extend(turn_markings(turn, map));
}
results
}
// Returns either 0 or 2 markings -- one for the common line base, one for the turn itself.
pub fn turn_markings(turn: &Turn, map: &Map) -> Vec<Marking> {
let lane = map.get_l(turn.id.src);
// If the lane's too small, don't bother.
// TODO Maybe a Trace for the common line would actually look fine.
if let Some((base_pt, base_angle)) = lane.safe_dist_along(lane.length() - 5.0 * si::M) {
// Common line base
results.push(Marking {
lines: vec![Line::new(
base_pt,
base_pt.project_away(2.0, base_angle.opposite()),
)],
color: Box::new(|cs| cs.get("turn restrictions on lane", Color::WHITE).alpha(0.8)),
thickness: 0.1,
round: true,
arrow_head_length: None,
});
for turn in map.get_turns_from_lane(lane.id) {
results.push(Marking {
vec![
// Common line base
Marking {
lines: vec![Line::new(
base_pt,
base_pt.project_away(2.0, base_angle.opposite()),
)],
color: Box::new(|cs| cs.get("turn restrictions on lane", Color::WHITE).alpha(0.8)),
thickness: 0.1,
round: true,
arrow_head_length: None,
},
Marking {
lines: vec![Line::new(
base_pt,
base_pt.project_away(LANE_THICKNESS / 2.0, turn.line.angle()),
@ -327,9 +343,9 @@ fn calculate_turn_markings(map: &Map, lane: &Lane) -> Vec<Marking> {
thickness: 0.1,
round: true,
arrow_head_length: Some(0.5),
});
}
},
]
} else {
Vec::new()
}
results
}

View File

@ -21,7 +21,7 @@ pub use render::area::DrawArea;
use render::bike::DrawBike;
use render::car::DrawCar;
pub use render::extra_shape::ExtraShapeID;
pub use render::lane::DrawLane;
pub use render::lane::{turn_markings, DrawLane};
pub use render::map::DrawMap;
pub use render::pedestrian::DrawPedestrian;
pub use render::turn::DrawTurn;