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