mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 07:52:05 +03:00
simplify some render/ code by using GeomBatch
This commit is contained in:
parent
222ddf6a96
commit
de51b1c154
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
||||||
use ezgui::{Color, GfxCtx};
|
use ezgui::{Color, GeomBatch, GfxCtx};
|
||||||
use geom::Polygon;
|
use geom::Polygon;
|
||||||
use map_model::{Area, AreaID, AreaType, Map};
|
use map_model::{Area, AreaID, AreaType, Map};
|
||||||
|
|
||||||
@ -9,13 +9,15 @@ pub struct DrawArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DrawArea {
|
impl DrawArea {
|
||||||
pub fn new(area: &Area, cs: &ColorScheme) -> (DrawArea, Color, Polygon) {
|
pub fn new(area: &Area, cs: &ColorScheme, batch: &mut GeomBatch) -> DrawArea {
|
||||||
let color = match area.area_type {
|
batch.push(
|
||||||
|
match area.area_type {
|
||||||
AreaType::Park => cs.get_def("park area", Color::rgb(200, 250, 204)),
|
AreaType::Park => cs.get_def("park area", Color::rgb(200, 250, 204)),
|
||||||
AreaType::Water => cs.get_def("water area", Color::rgb(170, 211, 223)),
|
AreaType::Water => cs.get_def("water area", Color::rgb(170, 211, 223)),
|
||||||
};
|
},
|
||||||
|
area.polygon.clone(),
|
||||||
(DrawArea { id: area.id }, color, area.polygon.clone())
|
);
|
||||||
|
DrawArea { id: area.id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
||||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender};
|
||||||
use geom::{Circle, Distance, Line, PolyLine, Polygon};
|
use geom::{Circle, Distance, Line, PolyLine, Polygon};
|
||||||
use map_model::{Map, LANE_THICKNESS};
|
use map_model::{Map, LANE_THICKNESS};
|
||||||
use sim::{CarID, CarStatus, DrawCarInput};
|
use sim::{CarID, CarStatus, DrawCarInput};
|
||||||
@ -21,7 +21,7 @@ impl DrawBike {
|
|||||||
prerender: &Prerender,
|
prerender: &Prerender,
|
||||||
cs: &ColorScheme,
|
cs: &ColorScheme,
|
||||||
) -> DrawBike {
|
) -> DrawBike {
|
||||||
let mut draw_default = Vec::new();
|
let mut draw_default = GeomBatch::new();
|
||||||
|
|
||||||
// TODO Share constants with DrawPedestrian
|
// TODO Share constants with DrawPedestrian
|
||||||
let body_radius = LANE_THICKNESS / 4.0;
|
let body_radius = LANE_THICKNESS / 4.0;
|
||||||
@ -33,48 +33,48 @@ impl DrawBike {
|
|||||||
CarStatus::Stuck => cs.get_def("stuck bike", Color::RED),
|
CarStatus::Stuck => cs.get_def("stuck bike", Color::RED),
|
||||||
CarStatus::Parked => panic!("Can't have a parked bike {}", input.id),
|
CarStatus::Parked => panic!("Can't have a parked bike {}", input.id),
|
||||||
};
|
};
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
cs.get_def("bike frame", Color::rgb(0, 128, 128)),
|
cs.get_def("bike frame", Color::rgb(0, 128, 128)),
|
||||||
input.body.make_polygons(Distance::meters(0.4)),
|
input.body.make_polygons(Distance::meters(0.4)),
|
||||||
));
|
);
|
||||||
|
|
||||||
let (body_pos, facing) = input.body.dist_along(0.4 * input.body.length());
|
let (body_pos, facing) = input.body.dist_along(0.4 * input.body.length());
|
||||||
let body_circle = Circle::new(body_pos, body_radius);
|
let body_circle = Circle::new(body_pos, body_radius);
|
||||||
draw_default.push((body_color, body_circle.to_polygon()));
|
draw_default.push(body_color, body_circle.to_polygon());
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
cs.get("pedestrian head"),
|
cs.get("pedestrian head"),
|
||||||
Circle::new(body_pos, 0.5 * body_radius).to_polygon(),
|
Circle::new(body_pos, 0.5 * body_radius).to_polygon(),
|
||||||
));
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Handlebars
|
// Handlebars
|
||||||
let (hand_pos, hand_angle) = input.body.dist_along(0.9 * input.body.length());
|
let (hand_pos, hand_angle) = input.body.dist_along(0.9 * input.body.length());
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
cs.get("bike frame"),
|
cs.get("bike frame"),
|
||||||
Line::new(
|
Line::new(
|
||||||
hand_pos.project_away(body_radius, hand_angle.rotate_degs(90.0)),
|
hand_pos.project_away(body_radius, hand_angle.rotate_degs(90.0)),
|
||||||
hand_pos.project_away(body_radius, hand_angle.rotate_degs(-90.0)),
|
hand_pos.project_away(body_radius, hand_angle.rotate_degs(-90.0)),
|
||||||
)
|
)
|
||||||
.make_polygons(Distance::meters(0.1)),
|
.make_polygons(Distance::meters(0.1)),
|
||||||
));
|
);
|
||||||
|
|
||||||
// Hands
|
// Hands
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
body_color,
|
body_color,
|
||||||
Line::new(
|
Line::new(
|
||||||
body_pos.project_away(0.9 * body_radius, facing.rotate_degs(-30.0)),
|
body_pos.project_away(0.9 * body_radius, facing.rotate_degs(-30.0)),
|
||||||
hand_pos.project_away(0.4 * body_radius, hand_angle.rotate_degs(-90.0)),
|
hand_pos.project_away(0.4 * body_radius, hand_angle.rotate_degs(-90.0)),
|
||||||
)
|
)
|
||||||
.make_polygons(Distance::meters(0.08)),
|
.make_polygons(Distance::meters(0.08)),
|
||||||
));
|
);
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
body_color,
|
body_color,
|
||||||
Line::new(
|
Line::new(
|
||||||
body_pos.project_away(0.9 * body_radius, facing.rotate_degs(30.0)),
|
body_pos.project_away(0.9 * body_radius, facing.rotate_degs(30.0)),
|
||||||
hand_pos.project_away(0.4 * body_radius, hand_angle.rotate_degs(90.0)),
|
hand_pos.project_away(0.4 * body_radius, hand_angle.rotate_degs(90.0)),
|
||||||
)
|
)
|
||||||
.make_polygons(Distance::meters(0.08)),
|
.make_polygons(Distance::meters(0.08)),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = input.waiting_for_turn {
|
if let Some(t) = input.waiting_for_turn {
|
||||||
@ -86,7 +86,7 @@ impl DrawBike {
|
|||||||
.make_arrow(Distance::meters(0.25))
|
.make_arrow(Distance::meters(0.25))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
draw_default.push((cs.get("blinker on"), poly));
|
draw_default.push(cs.get("blinker on"), poly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
||||||
use ezgui::{Color, GfxCtx};
|
use ezgui::{Color, GeomBatch, GfxCtx};
|
||||||
use geom::{Distance, Line, PolyLine, Polygon, Pt2D};
|
use geom::{Distance, Line, PolyLine, Polygon, Pt2D};
|
||||||
use map_model::{Building, BuildingID, BuildingType, Map, LANE_THICKNESS};
|
use map_model::{Building, BuildingID, BuildingType, Map, LANE_THICKNESS};
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ pub struct DrawBuilding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DrawBuilding {
|
impl DrawBuilding {
|
||||||
pub fn new(bldg: &Building, cs: &ColorScheme) -> (DrawBuilding, Vec<(Color, Polygon)>) {
|
pub fn new(bldg: &Building, cs: &ColorScheme, batch: &mut GeomBatch) -> DrawBuilding {
|
||||||
// Trim the front path line away from the sidewalk's center line, so that it doesn't
|
// Trim the front path line away from the sidewalk's center line, so that it doesn't
|
||||||
// overlap. For now, this cleanup is visual; it doesn't belong in the map_model layer.
|
// overlap. For now, this cleanup is visual; it doesn't belong in the map_model layer.
|
||||||
let mut front_path_line = bldg.front_path.line.clone();
|
let mut front_path_line = bldg.front_path.line.clone();
|
||||||
@ -23,25 +23,21 @@ impl DrawBuilding {
|
|||||||
}
|
}
|
||||||
let front_path = front_path_line.make_polygons(Distance::meters(1.0));
|
let front_path = front_path_line.make_polygons(Distance::meters(1.0));
|
||||||
|
|
||||||
let default_draw = vec![
|
batch.push(
|
||||||
(
|
|
||||||
match bldg.building_type {
|
match bldg.building_type {
|
||||||
BuildingType::Residence => {
|
BuildingType::Residence => {
|
||||||
cs.get_def("residential building", Color::rgb(218, 165, 32))
|
cs.get_def("residential building", Color::rgb(218, 165, 32))
|
||||||
}
|
}
|
||||||
BuildingType::Business => {
|
BuildingType::Business => cs.get_def("business building", Color::rgb(210, 105, 30)),
|
||||||
cs.get_def("business building", Color::rgb(210, 105, 30))
|
|
||||||
}
|
|
||||||
BuildingType::Unknown => {
|
BuildingType::Unknown => {
|
||||||
cs.get_def("unknown building", Color::rgb_f(0.7, 0.7, 0.7))
|
cs.get_def("unknown building", Color::rgb_f(0.7, 0.7, 0.7))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bldg.polygon.clone(),
|
bldg.polygon.clone(),
|
||||||
),
|
);
|
||||||
(cs.get_def("building path", Color::grey(0.6)), front_path),
|
batch.push(cs.get_def("building path", Color::grey(0.6)), front_path);
|
||||||
];
|
|
||||||
|
|
||||||
(DrawBuilding { id: bldg.id }, default_draw)
|
DrawBuilding { id: bldg.id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
||||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender};
|
||||||
use geom::{Angle, Circle, Distance, PolyLine, Polygon, Pt2D};
|
use geom::{Angle, Circle, Distance, PolyLine, Polygon, Pt2D};
|
||||||
use map_model::{Map, TurnType};
|
use map_model::{Map, TurnType};
|
||||||
use sim::{CarID, CarStatus, DrawCarInput};
|
use sim::{CarID, CarStatus, DrawCarInput};
|
||||||
@ -18,10 +18,10 @@ pub struct DrawCar {
|
|||||||
|
|
||||||
impl DrawCar {
|
impl DrawCar {
|
||||||
pub fn new(input: DrawCarInput, map: &Map, prerender: &Prerender, cs: &ColorScheme) -> DrawCar {
|
pub fn new(input: DrawCarInput, map: &Map, prerender: &Prerender, cs: &ColorScheme) -> DrawCar {
|
||||||
let mut draw_default = Vec::new();
|
let mut draw_default = GeomBatch::new();
|
||||||
|
|
||||||
let body_polygon = input.body.make_polygons(CAR_WIDTH);
|
let body_polygon = input.body.make_polygons(CAR_WIDTH);
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
// TODO if it's a bus, color it differently -- but how? :\
|
// TODO if it's a bus, color it differently -- but how? :\
|
||||||
// TODO color.shift(input.id.0) actually looks pretty bad still
|
// TODO color.shift(input.id.0) actually looks pretty bad still
|
||||||
match input.status {
|
match input.status {
|
||||||
@ -31,7 +31,7 @@ impl DrawCar {
|
|||||||
CarStatus::Parked => cs.get_def("parked car", Color::rgb(180, 233, 76)),
|
CarStatus::Parked => cs.get_def("parked car", Color::rgb(180, 233, 76)),
|
||||||
},
|
},
|
||||||
body_polygon.clone(),
|
body_polygon.clone(),
|
||||||
));
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
let window_length_gap = Distance::meters(0.2);
|
let window_length_gap = Distance::meters(0.2);
|
||||||
@ -62,8 +62,8 @@ impl DrawCar {
|
|||||||
angle.rotate_degs(90.0),
|
angle.rotate_degs(90.0),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
draw_default.push((cs.get_def("car window", Color::BLACK), front_window));
|
draw_default.push(cs.get_def("car window", Color::BLACK), front_window);
|
||||||
draw_default.push((cs.get("car window"), back_window));
|
draw_default.push(cs.get("car window"), back_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@ impl DrawCar {
|
|||||||
|
|
||||||
let bg_color = cs.get_def("blinker background", Color::grey(0.2));
|
let bg_color = cs.get_def("blinker background", Color::grey(0.2));
|
||||||
for c in vec![&front_left, &front_right, &back_left, &back_right] {
|
for c in vec![&front_left, &front_right, &back_left, &back_right] {
|
||||||
draw_default.push((bg_color, c.to_polygon()));
|
draw_default.push(bg_color, c.to_polygon());
|
||||||
}
|
}
|
||||||
|
|
||||||
let arrow_color = cs.get_def("blinker on", Color::RED);
|
let arrow_color = cs.get_def("blinker on", Color::RED);
|
||||||
@ -105,33 +105,33 @@ impl DrawCar {
|
|||||||
match turn.turn_type {
|
match turn.turn_type {
|
||||||
TurnType::Left | TurnType::LaneChangeLeft => {
|
TurnType::Left | TurnType::LaneChangeLeft => {
|
||||||
for circle in vec![front_left, back_left] {
|
for circle in vec![front_left, back_left] {
|
||||||
for poly in PolyLine::new(vec![
|
draw_default.extend(
|
||||||
|
arrow_color,
|
||||||
|
PolyLine::new(vec![
|
||||||
circle.center.project_away(radius / 2.0, angle.opposite()),
|
circle.center.project_away(radius / 2.0, angle.opposite()),
|
||||||
circle.center.project_away(radius / 2.0, angle),
|
circle.center.project_away(radius / 2.0, angle),
|
||||||
])
|
])
|
||||||
.make_arrow(Distance::meters(0.15))
|
.make_arrow(Distance::meters(0.15))
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
{
|
);
|
||||||
draw_default.push((arrow_color, poly));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TurnType::Right | TurnType::LaneChangeRight => {
|
TurnType::Right | TurnType::LaneChangeRight => {
|
||||||
for circle in vec![front_right, back_right] {
|
for circle in vec![front_right, back_right] {
|
||||||
for poly in PolyLine::new(vec![
|
draw_default.extend(
|
||||||
|
arrow_color,
|
||||||
|
PolyLine::new(vec![
|
||||||
circle.center.project_away(radius / 2.0, angle.opposite()),
|
circle.center.project_away(radius / 2.0, angle.opposite()),
|
||||||
circle.center.project_away(radius / 2.0, angle),
|
circle.center.project_away(radius / 2.0, angle),
|
||||||
])
|
])
|
||||||
.make_arrow(Distance::meters(0.15))
|
.make_arrow(Distance::meters(0.15))
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
{
|
);
|
||||||
draw_default.push((arrow_color, poly));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TurnType::Straight => {
|
TurnType::Straight => {
|
||||||
draw_default.push((arrow_color, back_left.to_polygon()));
|
draw_default.push(arrow_color, back_left.to_polygon());
|
||||||
draw_default.push((arrow_color, back_right.to_polygon()));
|
draw_default.push(arrow_color, back_right.to_polygon());
|
||||||
}
|
}
|
||||||
TurnType::Crosswalk | TurnType::SharedSidewalkCorner => unreachable!(),
|
TurnType::Crosswalk | TurnType::SharedSidewalkCorner => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ impl DrawIntersection {
|
|||||||
timer: &mut Timer,
|
timer: &mut Timer,
|
||||||
) -> DrawIntersection {
|
) -> DrawIntersection {
|
||||||
// Order matters... main polygon first, then sidewalk corners.
|
// Order matters... main polygon first, then sidewalk corners.
|
||||||
let mut default_geom = vec![(
|
let mut default_geom = GeomBatch::new();
|
||||||
|
default_geom.push(
|
||||||
match i.intersection_type {
|
match i.intersection_type {
|
||||||
IntersectionType::Border => {
|
IntersectionType::Border => {
|
||||||
cs.get_def("border intersection", Color::rgb(50, 205, 50))
|
cs.get_def("border intersection", Color::rgb(50, 205, 50))
|
||||||
@ -40,12 +41,8 @@ impl DrawIntersection {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
i.polygon.clone(),
|
i.polygon.clone(),
|
||||||
)];
|
|
||||||
default_geom.extend(
|
|
||||||
calculate_corners(i, map, timer)
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| (cs.get("sidewalk"), p)),
|
|
||||||
);
|
);
|
||||||
|
default_geom.extend(cs.get("sidewalk"), calculate_corners(i, map, timer));
|
||||||
match i.intersection_type {
|
match i.intersection_type {
|
||||||
IntersectionType::Border => {
|
IntersectionType::Border => {
|
||||||
if i.roads.len() != 1 {
|
if i.roads.len() != 1 {
|
||||||
@ -53,13 +50,12 @@ impl DrawIntersection {
|
|||||||
}
|
}
|
||||||
let r = map.get_r(*i.roads.iter().next().unwrap());
|
let r = map.get_r(*i.roads.iter().next().unwrap());
|
||||||
default_geom.extend(
|
default_geom.extend(
|
||||||
calculate_border_arrows(i, r, timer)
|
cs.get_def("incoming border node arrow", Color::PURPLE),
|
||||||
.into_iter()
|
calculate_border_arrows(i, r, timer),
|
||||||
.map(|p| (cs.get_def("incoming border node arrow", Color::PURPLE), p)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
IntersectionType::StopSign => {
|
IntersectionType::StopSign => {
|
||||||
default_geom.extend(calculate_stop_sign(map, cs, map.get_stop_sign(i.id)));
|
calculate_stop_sign(&mut default_geom, map, cs, map.get_stop_sign(i.id));
|
||||||
}
|
}
|
||||||
IntersectionType::TrafficSignal => {}
|
IntersectionType::TrafficSignal => {}
|
||||||
}
|
}
|
||||||
@ -498,14 +494,9 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, timer: &mut Timer) -> Vec
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_stop_sign(
|
fn calculate_stop_sign(batch: &mut GeomBatch, map: &Map, cs: &ColorScheme, sign: &ControlStopSign) {
|
||||||
map: &Map,
|
|
||||||
cs: &ColorScheme,
|
|
||||||
sign: &ControlStopSign,
|
|
||||||
) -> Vec<(Color, Polygon)> {
|
|
||||||
let trim_back = Distance::meters(0.7);
|
let trim_back = Distance::meters(0.7);
|
||||||
|
|
||||||
let mut result = Vec::new();
|
|
||||||
for (_, ss) in &sign.roads {
|
for (_, ss) in &sign.roads {
|
||||||
if ss.enabled {
|
if ss.enabled {
|
||||||
let rightmost = &map.get_l(*ss.travel_lanes.last().unwrap()).lane_center_pts;
|
let rightmost = &map.get_l(*ss.travel_lanes.last().unwrap()).lane_center_pts;
|
||||||
@ -517,12 +508,12 @@ fn calculate_stop_sign(
|
|||||||
.last_line()
|
.last_line()
|
||||||
.shift_right(1.0 * LANE_THICKNESS);
|
.shift_right(1.0 * LANE_THICKNESS);
|
||||||
|
|
||||||
result.push((
|
batch.push(
|
||||||
cs.get_def("stop sign on side of road", Color::RED),
|
cs.get_def("stop sign on side of road", Color::RED),
|
||||||
make_octagon(last_line.pt2(), Distance::meters(1.0), last_line.angle()),
|
make_octagon(last_line.pt2(), Distance::meters(1.0), last_line.angle()),
|
||||||
));
|
);
|
||||||
// A little pole for it too!
|
// A little pole for it too!
|
||||||
result.push((
|
batch.push(
|
||||||
cs.get_def("stop sign pole", Color::grey(0.5)),
|
cs.get_def("stop sign pole", Color::grey(0.5)),
|
||||||
Line::new(
|
Line::new(
|
||||||
last_line
|
last_line
|
||||||
@ -534,10 +525,9 @@ fn calculate_stop_sign(
|
|||||||
.project_away(Distance::meters(0.9), last_line.angle().opposite()),
|
.project_away(Distance::meters(0.9), last_line.angle().opposite()),
|
||||||
)
|
)
|
||||||
.make_polygons(Distance::meters(0.3)),
|
.make_polygons(Distance::meters(0.3)),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO A squished octagon would look better
|
// TODO A squished octagon would look better
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
use crate::render::{DrawCtx, DrawOptions, Renderable, OUTLINE_THICKNESS};
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender};
|
||||||
use geom::{Circle, Distance, Line, PolyLine, Polygon, Pt2D};
|
use geom::{Circle, Distance, Line, PolyLine, Polygon, Pt2D};
|
||||||
use map_model::{Lane, LaneID, LaneType, Map, Road, TurnType, LANE_THICKNESS, PARKING_SPOT_LENGTH};
|
use map_model::{Lane, LaneID, LaneType, Map, Road, TurnType, LANE_THICKNESS, PARKING_SPOT_LENGTH};
|
||||||
|
|
||||||
@ -25,7 +25,8 @@ impl DrawLane {
|
|||||||
let road = map.get_r(lane.parent);
|
let road = map.get_r(lane.parent);
|
||||||
let polygon = lane.lane_center_pts.make_polygons(LANE_THICKNESS);
|
let polygon = lane.lane_center_pts.make_polygons(LANE_THICKNESS);
|
||||||
|
|
||||||
let mut draw: Vec<(Color, Polygon)> = vec![(
|
let mut draw = GeomBatch::new();
|
||||||
|
draw.push(
|
||||||
match lane.lane_type {
|
match lane.lane_type {
|
||||||
LaneType::Driving => cs.get_def("driving lane", Color::BLACK),
|
LaneType::Driving => cs.get_def("driving lane", Color::BLACK),
|
||||||
LaneType::Bus => cs.get_def("bus lane", Color::rgb(190, 74, 76)),
|
LaneType::Bus => cs.get_def("bus lane", Color::rgb(190, 74, 76)),
|
||||||
@ -34,18 +35,30 @@ impl DrawLane {
|
|||||||
LaneType::Biking => cs.get_def("bike lane", Color::rgb(15, 125, 75)),
|
LaneType::Biking => cs.get_def("bike lane", Color::rgb(15, 125, 75)),
|
||||||
},
|
},
|
||||||
polygon.clone(),
|
polygon.clone(),
|
||||||
)];
|
);
|
||||||
if draw_lane_markings {
|
if draw_lane_markings {
|
||||||
match lane.lane_type {
|
match lane.lane_type {
|
||||||
LaneType::Sidewalk => {
|
LaneType::Sidewalk => {
|
||||||
draw.extend(calculate_sidewalk_lines(lane, cs));
|
draw.extend(
|
||||||
|
cs.get_def("sidewalk lines", Color::grey(0.7)),
|
||||||
|
calculate_sidewalk_lines(lane),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
LaneType::Parking => {
|
LaneType::Parking => {
|
||||||
draw.extend(calculate_parking_lines(lane, cs));
|
draw.extend(
|
||||||
|
cs.get_def("parking lines", Color::WHITE),
|
||||||
|
calculate_parking_lines(lane),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
LaneType::Driving | LaneType::Bus => {
|
LaneType::Driving | LaneType::Bus => {
|
||||||
draw.extend(calculate_driving_lines(lane, road, cs, timer));
|
draw.extend(
|
||||||
draw.extend(calculate_turn_markings(map, lane, cs, timer));
|
cs.get_def("dashed lane line", Color::WHITE),
|
||||||
|
calculate_driving_lines(lane, road, timer),
|
||||||
|
);
|
||||||
|
draw.extend(
|
||||||
|
cs.get_def("turn restrictions on lane", Color::WHITE),
|
||||||
|
calculate_turn_markings(map, lane, timer),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
LaneType::Biking => {}
|
LaneType::Biking => {}
|
||||||
};
|
};
|
||||||
@ -121,9 +134,8 @@ fn perp_line(l: Line, length: Distance) -> Line {
|
|||||||
Line::new(pt1, pt2)
|
Line::new(pt1, pt2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_sidewalk_lines(lane: &Lane, cs: &ColorScheme) -> Vec<(Color, Polygon)> {
|
fn calculate_sidewalk_lines(lane: &Lane) -> Vec<Polygon> {
|
||||||
let tile_every = LANE_THICKNESS;
|
let tile_every = LANE_THICKNESS;
|
||||||
let color = cs.get_def("sidewalk lines", Color::grey(0.7));
|
|
||||||
|
|
||||||
let length = lane.length();
|
let length = lane.length();
|
||||||
|
|
||||||
@ -134,20 +146,18 @@ fn calculate_sidewalk_lines(lane: &Lane, cs: &ColorScheme) -> Vec<(Color, Polygo
|
|||||||
let (pt, angle) = lane.dist_along(dist_along);
|
let (pt, angle) = lane.dist_along(dist_along);
|
||||||
// Reuse perp_line. Project away an arbitrary amount
|
// Reuse perp_line. Project away an arbitrary amount
|
||||||
let pt2 = pt.project_away(Distance::meters(1.0), angle);
|
let pt2 = pt.project_away(Distance::meters(1.0), angle);
|
||||||
result.push((
|
result.push(
|
||||||
color,
|
|
||||||
perp_line(Line::new(pt, pt2), LANE_THICKNESS).make_polygons(Distance::meters(0.25)),
|
perp_line(Line::new(pt, pt2), LANE_THICKNESS).make_polygons(Distance::meters(0.25)),
|
||||||
));
|
);
|
||||||
dist_along += tile_every;
|
dist_along += tile_every;
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_parking_lines(lane: &Lane, cs: &ColorScheme) -> Vec<(Color, Polygon)> {
|
fn calculate_parking_lines(lane: &Lane) -> Vec<Polygon> {
|
||||||
// meters, but the dims get annoying below to remove
|
// meters, but the dims get annoying below to remove
|
||||||
let leg_length = Distance::meters(1.0);
|
let leg_length = Distance::meters(1.0);
|
||||||
let color = cs.get_def("parking lines", Color::WHITE);
|
|
||||||
|
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
let num_spots = lane.number_parking_spots();
|
let num_spots = lane.number_parking_spots();
|
||||||
@ -160,34 +170,20 @@ fn calculate_parking_lines(lane: &Lane, cs: &ColorScheme) -> Vec<(Color, Polygon
|
|||||||
let t_pt = pt.project_away(LANE_THICKNESS * 0.4, perp_angle);
|
let t_pt = pt.project_away(LANE_THICKNESS * 0.4, perp_angle);
|
||||||
// The perp leg
|
// The perp leg
|
||||||
let p1 = t_pt.project_away(leg_length, perp_angle.opposite());
|
let p1 = t_pt.project_away(leg_length, perp_angle.opposite());
|
||||||
result.push((
|
result.push(Line::new(t_pt, p1).make_polygons(Distance::meters(0.25)));
|
||||||
color,
|
|
||||||
Line::new(t_pt, p1).make_polygons(Distance::meters(0.25)),
|
|
||||||
));
|
|
||||||
// Upper leg
|
// Upper leg
|
||||||
let p2 = t_pt.project_away(leg_length, lane_angle);
|
let p2 = t_pt.project_away(leg_length, lane_angle);
|
||||||
result.push((
|
result.push(Line::new(t_pt, p2).make_polygons(Distance::meters(0.25)));
|
||||||
color,
|
|
||||||
Line::new(t_pt, p2).make_polygons(Distance::meters(0.25)),
|
|
||||||
));
|
|
||||||
// Lower leg
|
// Lower leg
|
||||||
let p3 = t_pt.project_away(leg_length, lane_angle.opposite());
|
let p3 = t_pt.project_away(leg_length, lane_angle.opposite());
|
||||||
result.push((
|
result.push(Line::new(t_pt, p3).make_polygons(Distance::meters(0.25)));
|
||||||
color,
|
|
||||||
Line::new(t_pt, p3).make_polygons(Distance::meters(0.25)),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_driving_lines(
|
fn calculate_driving_lines(lane: &Lane, parent: &Road, timer: &mut Timer) -> Vec<Polygon> {
|
||||||
lane: &Lane,
|
|
||||||
parent: &Road,
|
|
||||||
cs: &ColorScheme,
|
|
||||||
timer: &mut Timer,
|
|
||||||
) -> Vec<(Color, Polygon)> {
|
|
||||||
// The leftmost lanes don't have dashed white lines.
|
// The leftmost lanes don't have dashed white lines.
|
||||||
if parent.dir_and_offset(lane.id).1 == 0 {
|
if parent.dir_and_offset(lane.id).1 == 0 {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@ -204,22 +200,13 @@ fn calculate_driving_lines(
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
// Don't draw the dashes too close to the ends.
|
// Don't draw the dashes too close to the ends.
|
||||||
let polygons = lane_edge_pts
|
lane_edge_pts
|
||||||
.exact_slice(dash_separation, lane_edge_pts.length() - dash_separation)
|
.exact_slice(dash_separation, lane_edge_pts.length() - dash_separation)
|
||||||
.dashed_polygons(Distance::meters(0.25), dash_len, dash_separation);
|
.dashed_polygons(Distance::meters(0.25), dash_len, dash_separation)
|
||||||
polygons
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| (cs.get_def("dashed lane line", Color::WHITE), p))
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_turn_markings(
|
fn calculate_turn_markings(map: &Map, lane: &Lane, timer: &mut Timer) -> Vec<Polygon> {
|
||||||
map: &Map,
|
let mut results = Vec::new();
|
||||||
lane: &Lane,
|
|
||||||
cs: &ColorScheme,
|
|
||||||
timer: &mut Timer,
|
|
||||||
) -> Vec<(Color, Polygon)> {
|
|
||||||
let mut results: Vec<(Color, Polygon)> = Vec::new();
|
|
||||||
|
|
||||||
// Are there multiple driving lanes on this side of the road?
|
// Are there multiple driving lanes on this side of the road?
|
||||||
if map
|
if map
|
||||||
@ -232,14 +219,13 @@ fn calculate_turn_markings(
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
let color = cs.get_def("turn restrictions on lane", Color::WHITE);
|
|
||||||
let thickness = Distance::meters(0.2);
|
let thickness = Distance::meters(0.2);
|
||||||
|
|
||||||
let common_base = lane.lane_center_pts.exact_slice(
|
let common_base = lane.lane_center_pts.exact_slice(
|
||||||
lane.length() - Distance::meters(7.0),
|
lane.length() - Distance::meters(7.0),
|
||||||
lane.length() - Distance::meters(5.0),
|
lane.length() - Distance::meters(5.0),
|
||||||
);
|
);
|
||||||
results.push((color, common_base.make_polygons(thickness)));
|
results.push(common_base.make_polygons(thickness));
|
||||||
|
|
||||||
// TODO Maybe draw arrows per target road, not lane
|
// TODO Maybe draw arrows per target road, not lane
|
||||||
for turn in map.get_turns_from_lane(lane.id) {
|
for turn in map.get_turns_from_lane(lane.id) {
|
||||||
@ -255,9 +241,7 @@ fn calculate_turn_markings(
|
|||||||
.project_away(LANE_THICKNESS / 2.0, turn.angle()),
|
.project_away(LANE_THICKNESS / 2.0, turn.angle()),
|
||||||
])
|
])
|
||||||
.make_arrow(thickness)
|
.make_arrow(thickness)
|
||||||
.with_context(timer, format!("turn_markings for {}", turn.id))
|
.with_context(timer, format!("turn_markings for {}", turn.id)),
|
||||||
.into_iter()
|
|
||||||
.map(|p| (color, p)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ use crate::render::Renderable;
|
|||||||
use crate::ui::Flags;
|
use crate::ui::Flags;
|
||||||
use aabb_quadtree::QuadTree;
|
use aabb_quadtree::QuadTree;
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use ezgui::{Color, Drawable, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, Prerender};
|
||||||
use geom::{Bounds, Duration, FindClosest, Polygon};
|
use geom::{Bounds, Duration, FindClosest};
|
||||||
use map_model::{
|
use map_model::{
|
||||||
AreaID, BuildingID, BusStopID, DirectedRoadID, IntersectionID, IntersectionType, Lane, LaneID,
|
AreaID, BuildingID, BusStopID, DirectedRoadID, IntersectionID, IntersectionType, Lane, LaneID,
|
||||||
Map, RoadID, Traversable, Turn, TurnID, TurnType, LANE_THICKNESS,
|
Map, RoadID, Traversable, Turn, TurnID, TurnType, LANE_THICKNESS,
|
||||||
@ -52,19 +52,19 @@ impl DrawMap {
|
|||||||
timer: &mut Timer,
|
timer: &mut Timer,
|
||||||
) -> DrawMap {
|
) -> DrawMap {
|
||||||
let mut roads: Vec<DrawRoad> = Vec::new();
|
let mut roads: Vec<DrawRoad> = Vec::new();
|
||||||
let mut all_roads: Vec<(Color, Polygon)> = Vec::new();
|
let mut all_roads = GeomBatch::new();
|
||||||
timer.start_iter("make DrawRoads", map.all_roads().len());
|
timer.start_iter("make DrawRoads", map.all_roads().len());
|
||||||
for r in map.all_roads() {
|
for r in map.all_roads() {
|
||||||
timer.next();
|
timer.next();
|
||||||
let draw_r = DrawRoad::new(r, cs, prerender);
|
let draw_r = DrawRoad::new(r, cs, prerender);
|
||||||
all_roads.push((
|
all_roads.push(
|
||||||
osm_rank_to_color(cs, r.get_rank()),
|
osm_rank_to_color(cs, r.get_rank()),
|
||||||
r.get_thick_polygon().get(timer),
|
r.get_thick_polygon().get(timer),
|
||||||
));
|
);
|
||||||
all_roads.push((
|
all_roads.push(
|
||||||
cs.get_def("unzoomed outline", Color::BLACK),
|
cs.get_def("unzoomed outline", Color::BLACK),
|
||||||
draw_r.get_outline(map),
|
draw_r.get_outline(map),
|
||||||
));
|
);
|
||||||
roads.push(draw_r);
|
roads.push(draw_r);
|
||||||
}
|
}
|
||||||
let draw_all_thick_roads = prerender.upload(all_roads);
|
let draw_all_thick_roads = prerender.upload(all_roads);
|
||||||
@ -100,32 +100,30 @@ impl DrawMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut intersections: Vec<DrawIntersection> = Vec::new();
|
let mut intersections: Vec<DrawIntersection> = Vec::new();
|
||||||
let mut all_intersections: Vec<(Color, Polygon)> = Vec::new();
|
let mut all_intersections = GeomBatch::new();
|
||||||
timer.start_iter("make DrawIntersections", map.all_intersections().len());
|
timer.start_iter("make DrawIntersections", map.all_intersections().len());
|
||||||
for i in map.all_intersections() {
|
for i in map.all_intersections() {
|
||||||
timer.next();
|
timer.next();
|
||||||
let draw_i = DrawIntersection::new(i, map, cs, prerender, timer);
|
let draw_i = DrawIntersection::new(i, map, cs, prerender, timer);
|
||||||
if i.intersection_type == IntersectionType::StopSign {
|
if i.intersection_type == IntersectionType::StopSign {
|
||||||
all_intersections.push((osm_rank_to_color(cs, i.get_rank(map)), i.polygon.clone()));
|
all_intersections.push(osm_rank_to_color(cs, i.get_rank(map)), i.polygon.clone());
|
||||||
all_intersections.push((cs.get("unzoomed outline"), draw_i.get_outline(map)));
|
all_intersections.push(cs.get("unzoomed outline"), draw_i.get_outline(map));
|
||||||
} else {
|
} else {
|
||||||
all_intersections.push((
|
all_intersections.push(
|
||||||
cs.get_def("unzoomed interesting intersection", Color::BLACK),
|
cs.get_def("unzoomed interesting intersection", Color::BLACK),
|
||||||
i.polygon.clone(),
|
i.polygon.clone(),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
intersections.push(draw_i);
|
intersections.push(draw_i);
|
||||||
}
|
}
|
||||||
let draw_all_unzoomed_intersections = prerender.upload(all_intersections);
|
let draw_all_unzoomed_intersections = prerender.upload(all_intersections);
|
||||||
|
|
||||||
let mut buildings: Vec<DrawBuilding> = Vec::new();
|
let mut buildings: Vec<DrawBuilding> = Vec::new();
|
||||||
let mut all_buildings: Vec<(Color, Polygon)> = Vec::new();
|
let mut all_buildings = GeomBatch::new();
|
||||||
timer.start_iter("make DrawBuildings", map.all_buildings().len());
|
timer.start_iter("make DrawBuildings", map.all_buildings().len());
|
||||||
for b in map.all_buildings() {
|
for b in map.all_buildings() {
|
||||||
timer.next();
|
timer.next();
|
||||||
let (b, draw) = DrawBuilding::new(b, cs);
|
buildings.push(DrawBuilding::new(b, cs, &mut all_buildings));
|
||||||
buildings.push(b);
|
|
||||||
all_buildings.extend(draw);
|
|
||||||
}
|
}
|
||||||
let draw_all_buildings = prerender.upload(all_buildings);
|
let draw_all_buildings = prerender.upload(all_buildings);
|
||||||
|
|
||||||
@ -169,13 +167,11 @@ impl DrawMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut areas: Vec<DrawArea> = Vec::new();
|
let mut areas: Vec<DrawArea> = Vec::new();
|
||||||
let mut all_areas: Vec<(Color, Polygon)> = Vec::new();
|
let mut all_areas = GeomBatch::new();
|
||||||
timer.start_iter("make DrawAreas", map.all_areas().len());
|
timer.start_iter("make DrawAreas", map.all_areas().len());
|
||||||
for a in map.all_areas() {
|
for a in map.all_areas() {
|
||||||
timer.next();
|
timer.next();
|
||||||
let (draw, color, poly) = DrawArea::new(a, cs);
|
areas.push(DrawArea::new(a, cs, &mut all_areas));
|
||||||
areas.push(draw);
|
|
||||||
all_areas.push((color, poly));
|
|
||||||
}
|
}
|
||||||
let draw_all_areas = prerender.upload(all_areas);
|
let draw_all_areas = prerender.upload(all_areas);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
use crate::render::{DrawCtx, DrawOptions, Renderable};
|
||||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender};
|
||||||
use geom::{Circle, Distance, PolyLine, Polygon};
|
use geom::{Circle, Distance, PolyLine, Polygon};
|
||||||
use map_model::{Map, LANE_THICKNESS};
|
use map_model::{Map, LANE_THICKNESS};
|
||||||
use sim::{DrawPedestrianInput, PedestrianID};
|
use sim::{DrawPedestrianInput, PedestrianID};
|
||||||
@ -27,7 +27,7 @@ impl DrawPedestrian {
|
|||||||
// - front paths are too skinny
|
// - front paths are too skinny
|
||||||
let radius = LANE_THICKNESS / 4.0;
|
let radius = LANE_THICKNESS / 4.0;
|
||||||
|
|
||||||
let mut draw_default = Vec::new();
|
let mut draw_default = GeomBatch::new();
|
||||||
|
|
||||||
let foot_radius = 0.2 * radius;
|
let foot_radius = 0.2 * radius;
|
||||||
let left_foot = Circle::new(
|
let left_foot = Circle::new(
|
||||||
@ -47,11 +47,11 @@ impl DrawPedestrian {
|
|||||||
let jitter = input.id.0 % 2 == 0;
|
let jitter = input.id.0 % 2 == 0;
|
||||||
let remainder = step_count % 6;
|
let remainder = step_count % 6;
|
||||||
if input.waiting_for_turn.is_some() {
|
if input.waiting_for_turn.is_some() {
|
||||||
draw_default.push((foot_color, left_foot.to_polygon()));
|
draw_default.push(foot_color, left_foot.to_polygon());
|
||||||
draw_default.push((foot_color, right_foot.to_polygon()));
|
draw_default.push(foot_color, right_foot.to_polygon());
|
||||||
} else if jitter == (remainder < 3) {
|
} else if jitter == (remainder < 3) {
|
||||||
draw_default.push((foot_color, left_foot.to_polygon()));
|
draw_default.push(foot_color, left_foot.to_polygon());
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
foot_color,
|
foot_color,
|
||||||
Circle::new(
|
Circle::new(
|
||||||
input
|
input
|
||||||
@ -60,10 +60,10 @@ impl DrawPedestrian {
|
|||||||
foot_radius,
|
foot_radius,
|
||||||
)
|
)
|
||||||
.to_polygon(),
|
.to_polygon(),
|
||||||
));
|
);
|
||||||
} else {
|
} else {
|
||||||
draw_default.push((foot_color, right_foot.to_polygon()));
|
draw_default.push(foot_color, right_foot.to_polygon());
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
foot_color,
|
foot_color,
|
||||||
Circle::new(
|
Circle::new(
|
||||||
input
|
input
|
||||||
@ -72,7 +72,7 @@ impl DrawPedestrian {
|
|||||||
foot_radius,
|
foot_radius,
|
||||||
)
|
)
|
||||||
.to_polygon(),
|
.to_polygon(),
|
||||||
));
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let body_circle = Circle::new(input.pos, radius);
|
let body_circle = Circle::new(input.pos, radius);
|
||||||
@ -85,11 +85,11 @@ impl DrawPedestrian {
|
|||||||
.shift(input.id.0)
|
.shift(input.id.0)
|
||||||
};
|
};
|
||||||
// TODO Arms would look fabulous.
|
// TODO Arms would look fabulous.
|
||||||
draw_default.push((body_color, body_circle.to_polygon()));
|
draw_default.push(body_color, body_circle.to_polygon());
|
||||||
draw_default.push((
|
draw_default.push(
|
||||||
cs.get_def("pedestrian head", Color::rgb(139, 69, 19)),
|
cs.get_def("pedestrian head", Color::rgb(139, 69, 19)),
|
||||||
head_circle.to_polygon(),
|
head_circle.to_polygon(),
|
||||||
));
|
);
|
||||||
|
|
||||||
if let Some(t) = input.waiting_for_turn {
|
if let Some(t) = input.waiting_for_turn {
|
||||||
// A silly idea for peds... use hands to point at their turn?
|
// A silly idea for peds... use hands to point at their turn?
|
||||||
@ -101,7 +101,7 @@ impl DrawPedestrian {
|
|||||||
.make_arrow(Distance::meters(0.25))
|
.make_arrow(Distance::meters(0.25))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
draw_default.push((cs.get("blinker on"), poly));
|
draw_default.push(cs.get("blinker on"), poly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::helpers::{ColorScheme, ID};
|
use crate::helpers::{ColorScheme, ID};
|
||||||
use crate::render::{DrawCtx, DrawOptions, Renderable, BIG_ARROW_THICKNESS, OUTLINE_THICKNESS};
|
use crate::render::{DrawCtx, DrawOptions, Renderable, BIG_ARROW_THICKNESS, OUTLINE_THICKNESS};
|
||||||
use ezgui::{Color, Drawable, GfxCtx, Prerender};
|
use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Prerender};
|
||||||
use geom::{Polygon, Pt2D};
|
use geom::{Polygon, Pt2D};
|
||||||
use map_model::{Map, Road, RoadID};
|
use map_model::{Map, Road, RoadID};
|
||||||
|
|
||||||
@ -13,13 +13,15 @@ pub struct DrawRoad {
|
|||||||
|
|
||||||
impl DrawRoad {
|
impl DrawRoad {
|
||||||
pub fn new(r: &Road, cs: &ColorScheme, prerender: &Prerender) -> DrawRoad {
|
pub fn new(r: &Road, cs: &ColorScheme, prerender: &Prerender) -> DrawRoad {
|
||||||
|
let mut draw = GeomBatch::new();
|
||||||
|
draw.push(
|
||||||
|
cs.get_def("road center line", Color::YELLOW),
|
||||||
|
r.center_pts.make_polygons(BIG_ARROW_THICKNESS),
|
||||||
|
);
|
||||||
DrawRoad {
|
DrawRoad {
|
||||||
id: r.id,
|
id: r.id,
|
||||||
zorder: r.get_zorder(),
|
zorder: r.get_zorder(),
|
||||||
draw_center_line: prerender.upload(vec![(
|
draw_center_line: prerender.upload(draw),
|
||||||
cs.get_def("road center line", Color::YELLOW),
|
|
||||||
r.center_pts.make_polygons(BIG_ARROW_THICKNESS),
|
|
||||||
)]),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ impl DrawCrosswalk {
|
|||||||
Line::new(pts[1], pts[2])
|
Line::new(pts[1], pts[2])
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut draw = Vec::new();
|
let mut draw = GeomBatch::new();
|
||||||
let available_length = line.length() - (boundary * 2.0);
|
let available_length = line.length() - (boundary * 2.0);
|
||||||
if available_length > Distance::ZERO {
|
if available_length > Distance::ZERO {
|
||||||
let num_markings = (available_length / tile_every).floor() as usize;
|
let num_markings = (available_length / tile_every).floor() as usize;
|
||||||
@ -131,11 +131,11 @@ impl DrawCrosswalk {
|
|||||||
let pt1 = line.dist_along(dist_along);
|
let pt1 = line.dist_along(dist_along);
|
||||||
// Reuse perp_line. Project away an arbitrary amount
|
// Reuse perp_line. Project away an arbitrary amount
|
||||||
let pt2 = pt1.project_away(Distance::meters(1.0), turn.angle());
|
let pt2 = pt1.project_away(Distance::meters(1.0), turn.angle());
|
||||||
draw.push((
|
draw.push(
|
||||||
cs.get_def("crosswalk", Color::WHITE),
|
cs.get_def("crosswalk", Color::WHITE),
|
||||||
perp_line(Line::new(pt1, pt2), LANE_THICKNESS)
|
perp_line(Line::new(pt1, pt2), LANE_THICKNESS)
|
||||||
.make_polygons(CROSSWALK_LINE_THICKNESS),
|
.make_polygons(CROSSWALK_LINE_THICKNESS),
|
||||||
));
|
);
|
||||||
dist_along += tile_every;
|
dist_along += tile_every;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,11 +135,9 @@ impl<'a> GfxCtx<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_polygons(&mut self, color: Color, polygons: &Vec<Polygon>) {
|
pub fn draw_polygons(&mut self, color: Color, polygons: &Vec<Polygon>) {
|
||||||
self.draw_polygon_batch(polygons.iter().map(|p| (color, p)).collect())
|
let obj = self
|
||||||
}
|
.prerender
|
||||||
|
.upload_temporary(polygons.iter().map(|p| (color, p)).collect());
|
||||||
pub fn draw_polygon_batch(&mut self, list: Vec<(Color, &Polygon)>) {
|
|
||||||
let obj = self.prerender.upload_temporary(list);
|
|
||||||
self.redraw(&obj);
|
self.redraw(&obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +282,7 @@ impl<'a> GfxCtx<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct GeomBatch {
|
pub struct GeomBatch {
|
||||||
list: Vec<(Color, Polygon)>,
|
pub(crate) list: Vec<(Color, Polygon)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GeomBatch {
|
impl GeomBatch {
|
||||||
@ -304,6 +302,7 @@ impl GeomBatch {
|
|||||||
|
|
||||||
pub fn draw(self, g: &mut GfxCtx) {
|
pub fn draw(self, g: &mut GfxCtx) {
|
||||||
let refs = self.list.iter().map(|(color, p)| (*color, p)).collect();
|
let refs = self.list.iter().map(|(color, p)| (*color, p)).collect();
|
||||||
g.draw_polygon_batch(refs);
|
let obj = g.prerender.upload_temporary(refs);
|
||||||
|
g.redraw(&obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use crate::input::ContextMenu;
|
use crate::input::ContextMenu;
|
||||||
use crate::text::FONT_SIZE;
|
use crate::text::FONT_SIZE;
|
||||||
use crate::{Canvas, Color, GfxCtx, HorizontalAlignment, Text, UserInput, VerticalAlignment};
|
use crate::{
|
||||||
|
Canvas, Color, GeomBatch, GfxCtx, HorizontalAlignment, Text, UserInput, VerticalAlignment,
|
||||||
|
};
|
||||||
use abstutil::{elapsed_seconds, Timer, TimerSink};
|
use abstutil::{elapsed_seconds, Timer, TimerSink};
|
||||||
use geom::Polygon;
|
use geom::Polygon;
|
||||||
use glium::implement_vertex;
|
use glium::implement_vertex;
|
||||||
@ -41,8 +43,8 @@ impl<'a> Prerender<'a> {
|
|||||||
self.actually_upload(true, list)
|
self.actually_upload(true, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload(&self, list: Vec<(Color, Polygon)>) -> Drawable {
|
pub fn upload(&self, batch: GeomBatch) -> Drawable {
|
||||||
let borrows = list.iter().map(|(c, p)| (*c, p)).collect();
|
let borrows = batch.list.iter().map(|(c, p)| (*c, p)).collect();
|
||||||
self.actually_upload(true, borrows)
|
self.actually_upload(true, borrows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user