use a regularly spaced marking for construction instead of the weird

stripes. clean up the hack in the shader
This commit is contained in:
Dustin Carlino 2020-06-24 08:36:47 -07:00
parent 626636ece7
commit 07bf9725d4
12 changed files with 93 additions and 82 deletions

View File

@ -1,8 +1,9 @@
# A/B Street # A/B Street
Ever been on a bus stuck in traffic, wondering why there are cars parked on the Ever been stuck in traffic on a bus, wondering why is there legal street parking
road instead of a bus lane? A/B Street is a game exploring how small changes to instead of a dedicated bus lane? A/B Street is a game exploring how small
a city affect the movement of drivers, cyclists, transit users, and pedestrians. changes to a city affect the movement of drivers, cyclists, transit users, and
pedestrians.
- Play on - Play on
[Windows](https://github.com/dabreegster/abstreet/releases/download/v0.2.0a/abstreet_windows_v0_2_0d.zip), [Windows](https://github.com/dabreegster/abstreet/releases/download/v0.2.0a/abstreet_windows_v0_2_0d.zip),

View File

@ -0,0 +1,13 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.22041 3.26611H3.01807C2.38268 3.26611 1.86768 3.78119 1.86768 4.4165V35.8002C1.86768 36.3158 2.28572 36.7338 2.80127 36.7338H5.43721C5.95283 36.7338 6.3708 36.3157 6.3708 35.8002V4.4165C6.3708 3.78111 5.85572 3.26611 5.22041 3.26611Z" fill="#D4D2D3"/>
<path d="M34.7793 3.26611H36.9816C37.617 3.26611 38.132 3.78119 38.132 4.4165V35.8002C38.132 36.3158 37.714 36.7338 37.1984 36.7338H34.5625C34.0469 36.7338 33.6289 36.3157 33.6289 35.8002V4.4165C33.6289 3.78111 34.144 3.26611 34.7793 3.26611Z" fill="#D4D2D3"/>
<path d="M5.81445 3.27881L2.01609 5.02623L0 9.09342V15.3676L7.93016 10.4966L12.0887 3.27881H5.81445Z" fill="white"/>
<path d="M17.8708 3.27881L7.92999 10.4966L3.4353 17.7144H9.70952L18.7901 11.8541L24.145 3.27881H17.8708Z" fill="white"/>
<path d="M29.9275 3.27881L18.7904 11.8541L15.4919 17.7144H21.7662L30.8831 11.5369L36.2017 3.27881H29.9275Z" fill="white"/>
<path d="M29.9273 12.8218L27.5483 17.7143H33.8225L38.3064 15.3675L39.9999 11.5369V5.2627L29.9273 12.8218Z" fill="white"/>
<path d="M39.9999 11.5371V15.8468C39.9999 16.8783 39.1636 17.7145 38.1322 17.7145H33.8225L39.9999 11.5371Z" fill="#FF6D00"/>
<path d="M39.9999 5.14662V5.26279L27.5484 17.7144H21.7661L36.2016 3.27881H38.1322C39.1636 3.27881 39.9999 4.11514 39.9999 5.14662Z" fill="#FF6D00"/>
<path d="M29.9275 3.27881L15.4919 17.7144H9.70972L24.1452 3.27881H29.9275Z" fill="#FF6D00"/>
<path d="M17.871 3.27881L3.43547 17.7144H1.86773C0.836328 17.7144 0 16.878 0 15.8465V15.3675L12.0887 3.27881H17.871Z" fill="#FF6D00"/>
<path d="M5.81445 3.27881L0 9.09342V5.14662C0 4.11514 0.836328 3.27889 1.86773 3.27889H5.81445V3.27881Z" fill="#FF6D00"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -164,8 +164,7 @@ pub struct Drawable {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Vertex { struct Vertex {
position: [f32; 2], position: [f32; 2],
// Each type of Color encodes something different here. See the actually_upload method and // RGBA
// fragment_140.glsl.
// TODO Make this u8? // TODO Make this u8?
style: [f32; 4], style: [f32; 4],
} }

View File

@ -24,7 +24,6 @@ impl fmt::Display for Color {
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub enum FancyColor { pub enum FancyColor {
RGBA(Color), RGBA(Color),
Hatching,
LinearGradient(LinearGradient), LinearGradient(LinearGradient),
} }
@ -163,7 +162,6 @@ impl FancyColor {
pub(crate) fn style(&self, pt: Pt2D) -> [f32; 4] { pub(crate) fn style(&self, pt: Pt2D) -> [f32; 4] {
match self { match self {
FancyColor::RGBA(c) => [c.r, c.g, c.b, c.a], FancyColor::RGBA(c) => [c.r, c.g, c.b, c.a],
FancyColor::Hatching => [100.0, 0.0, 0.0, 0.0],
FancyColor::LinearGradient(ref lg) => { FancyColor::LinearGradient(ref lg) => {
let c = lg.interp(pt); let c = lg.interp(pt);
[c.r, c.g, c.b, c.a] [c.r, c.g, c.b, c.a]

View File

@ -170,6 +170,20 @@ impl GeomBatch {
self self
} }
/// Rotates each polygon in the batch relative to the center of the entire batch.
pub fn rotate_around_batch_center(mut self, angle: Angle) -> GeomBatch {
let mut bounds = Bounds::new();
for (_, poly) in &self.list {
bounds.union(poly.get_bounds());
}
let center = bounds.center();
for (_, poly) in &mut self.list {
*poly = poly.rotate_around(angle, center);
}
self
}
/// Scales the batch by some factor. /// Scales the batch by some factor.
pub fn scale(mut self, factor: f64) -> GeomBatch { pub fn scale(mut self, factor: f64) -> GeomBatch {
for (_, poly) in &mut self.list { for (_, poly) in &mut self.list {

View File

@ -9,20 +9,9 @@ in vec4 pass_style;
out vec4 f_color; out vec4 f_color;
void main() { void main() {
// See actually_upload in drawing.rs to understand the different things encoded. // https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems
if (pass_style[0] == 100.0) { //float gray = dot(pass_style.rgb, vec3(0.299, 0.587, 0.114));
float map_x = (gl_FragCoord.x + transform[0]) / transform[2]; //f_color = vec4(vec3(gray), pass_style.a);
float map_y = (window[1] - gl_FragCoord.y + transform[1]) / transform[2];
if (mod(map_x + map_y, 2.0) <= 0.5) { f_color = pass_style;
f_color = vec4(1.0, 1.0, 1.0, 1.0);
} else {
// Let the polygon with its original colors show instead.
discard;
}
} else {
// https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems
//float gray = dot(pass_style.rgb, vec3(0.299, 0.587, 0.114));
//f_color = vec4(vec3(gray), pass_style.a);
f_color = pass_style;
}
} }

View File

@ -12,20 +12,9 @@ in vec4 pass_style;
out vec4 f_color; out vec4 f_color;
void main() { void main() {
// See actually_upload in drawing.rs to understand the different things encoded. // https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems
if (pass_style[0] == 100.0) { //float gray = dot(pass_style.rgb, vec3(0.299, 0.587, 0.114));
float map_x = (gl_FragCoord.x + transform[0]) / transform[2]; //f_color = vec4(vec3(gray), pass_style.a);
float map_y = (window[1] - gl_FragCoord.y + transform[1]) / transform[2];
if (mod(map_x + map_y, 2.0) <= 0.5) { f_color = pass_style;
f_color = vec4(1.0, 1.0, 1.0, 1.0);
} else {
// Let the polygon with its original colors show instead.
discard;
}
} else {
// https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems
//float gray = dot(pass_style.rgb, vec3(0.299, 0.587, 0.114));
//f_color = vec4(vec3(gray), pass_style.a);
f_color = pass_style;
}
} }

View File

@ -58,7 +58,6 @@ pub struct ColorScheme {
pub bus_lane: Color, pub bus_lane: Color,
pub parking_lane: Color, pub parking_lane: Color,
pub bike_lane: Color, pub bike_lane: Color,
pub under_construction: Color,
pub sidewalk: Color, pub sidewalk: Color,
pub sidewalk_lines: Color, pub sidewalk_lines: Color,
pub general_road_marking: Color, pub general_road_marking: Color,
@ -156,7 +155,6 @@ impl ColorScheme {
bus_lane: Color::rgb(190, 74, 76), bus_lane: Color::rgb(190, 74, 76),
parking_lane: Color::grey(0.2), parking_lane: Color::grey(0.2),
bike_lane: Color::rgb(15, 125, 75), bike_lane: Color::rgb(15, 125, 75),
under_construction: Color::rgb(255, 109, 0),
sidewalk: Color::grey(0.8), sidewalk: Color::grey(0.8),
sidewalk_lines: Color::grey(0.7), sidewalk_lines: Color::grey(0.7),
general_road_marking: Color::WHITE, general_road_marking: Color::WHITE,

View File

@ -57,7 +57,7 @@ impl StopSignEditor {
} else { } else {
Btn::text_fg("reset to default").inactive(ctx) Btn::text_fg("reset to default").inactive(ctx)
}, },
Btn::text_fg("close intersection for construction").build_def(ctx, None), Btn::text_fg("close intersection for construction").build_def(ctx, hotkey(Key::C)),
Btn::text_fg("convert to traffic signal").build_def(ctx, None), Btn::text_fg("convert to traffic signal").build_def(ctx, None),
Btn::text_fg("Finish").build_def(ctx, hotkey(Key::Escape)), Btn::text_fg("Finish").build_def(ctx, hotkey(Key::Escape)),
]) ])

View File

@ -6,7 +6,7 @@ use crate::render::{
draw_signal_phase, DrawOptions, Renderable, CROSSWALK_LINE_THICKNESS, OUTLINE_THICKNESS, draw_signal_phase, DrawOptions, Renderable, CROSSWALK_LINE_THICKNESS, OUTLINE_THICKNESS,
}; };
use abstutil::Timer; use abstutil::Timer;
use ezgui::{Color, Drawable, FancyColor, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text}; use ezgui::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, RewriteColor, Text};
use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D, Time, EPSILON_DIST}; use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D, Time, EPSILON_DIST};
use map_model::raw::DrivingSide; use map_model::raw::DrivingSide;
use map_model::{ use map_model::{
@ -33,14 +33,7 @@ impl DrawIntersection {
) -> DrawIntersection { ) -> DrawIntersection {
// Order matters... main polygon first, then sidewalk corners. // Order matters... main polygon first, then sidewalk corners.
let mut default_geom = GeomBatch::new(); let mut default_geom = GeomBatch::new();
default_geom.push( default_geom.push(cs.normal_intersection, i.polygon.clone());
if i.is_closed() {
cs.under_construction
} else {
cs.normal_intersection
},
i.polygon.clone(),
);
default_geom.extend(cs.sidewalk, calculate_corners(i, map, timer)); default_geom.extend(cs.sidewalk, calculate_corners(i, map, timer));
for turn in &map.get_turns_in_intersection(i.id) { for turn in &map.get_turns_in_intersection(i.id) {
@ -71,7 +64,15 @@ impl DrawIntersection {
} }
} }
IntersectionType::Construction => { IntersectionType::Construction => {
default_geom.fancy_push(FancyColor::Hatching, i.polygon.clone()); // TODO Centering seems weird
default_geom.append(
GeomBatch::mapspace_svg(
prerender,
"../data/system/assets/map/under_construction.svg",
)
.scale(0.08)
.centered_on(i.polygon.center()),
);
} }
IntersectionType::TrafficSignal => {} IntersectionType::TrafficSignal => {}
} }

View File

@ -3,7 +3,7 @@ use crate::colors::ColorScheme;
use crate::helpers::ID; use crate::helpers::ID;
use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS}; use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS};
use abstutil::Timer; use abstutil::Timer;
use ezgui::{Drawable, FancyColor, GeomBatch, GfxCtx, Prerender, RewriteColor}; use ezgui::{Drawable, GeomBatch, GfxCtx, Prerender, RewriteColor};
use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D}; use geom::{Angle, ArrowCap, Distance, Line, PolyLine, Polygon, Pt2D};
use map_model::{Lane, LaneID, LaneType, Map, Road, TurnType, PARKING_SPOT_LENGTH}; use map_model::{Lane, LaneID, LaneType, Map, Road, TurnType, PARKING_SPOT_LENGTH};
@ -19,7 +19,7 @@ pub struct AlmostDrawLane {
impl AlmostDrawLane { impl AlmostDrawLane {
pub fn finish(mut self, prerender: &Prerender, _: &ColorScheme, lane: &Lane) -> DrawLane { pub fn finish(mut self, prerender: &Prerender, _: &ColorScheme, lane: &Lane) -> DrawLane {
// Need prerender to load the (cached) SVGs // Need prerender to load the (cached) SVGs
if lane.is_bus() { if lane.is_bus() || lane.is_biking() || lane.lane_type == LaneType::Construction {
let buffer = Distance::meters(2.0); let buffer = Distance::meters(2.0);
let btwn = Distance::meters(30.0); let btwn = Distance::meters(30.0);
let len = lane.lane_center_pts.length(); let len = lane.lane_center_pts.length();
@ -27,28 +27,38 @@ impl AlmostDrawLane {
let mut dist = buffer; let mut dist = buffer;
while dist + buffer <= len { while dist + buffer <= len {
let (pt, angle) = lane.lane_center_pts.dist_along(dist); let (pt, angle) = lane.lane_center_pts.dist_along(dist);
self.draw_default.append( if lane.is_bus() {
GeomBatch::mapspace_svg(prerender, "../data/system/assets/map/bus_only.svg") self.draw_default.append(
GeomBatch::mapspace_svg(
prerender,
"../data/system/assets/map/bus_only.svg",
)
.scale(0.06) .scale(0.06)
.centered_on(pt) .centered_on(pt)
.rotate(angle.shortest_rotation_towards(Angle::new_degs(-90.0))), .rotate(angle.shortest_rotation_towards(Angle::new_degs(-90.0))),
); );
dist += btwn; } else if lane.is_biking() {
} self.draw_default.append(
} else if lane.is_biking() { GeomBatch::mapspace_svg(prerender, "../data/system/assets/meters/bike.svg")
let buffer = Distance::meters(2.0); .scale(0.06)
let btwn = Distance::meters(30.0); .centered_on(pt)
let len = lane.lane_center_pts.length(); .rotate(angle.shortest_rotation_towards(Angle::new_degs(-90.0))),
);
let mut dist = buffer; } else if lane.lane_type == LaneType::Construction {
while dist + buffer <= len { // TODO Still not quite centered right, but close enough
let (pt, angle) = lane.lane_center_pts.dist_along(dist); self.draw_default.append(
self.draw_default.append( GeomBatch::mapspace_svg(
GeomBatch::mapspace_svg(prerender, "../data/system/assets/meters/bike.svg") prerender,
.scale(0.06) "../data/system/assets/map/under_construction.svg",
.centered_on(pt) )
.rotate(angle.shortest_rotation_towards(Angle::new_degs(-90.0))), .scale(0.05)
); .rotate_around_batch_center(
angle.shortest_rotation_towards(Angle::new_degs(-90.0)),
)
.autocrop()
.centered_on(pt),
);
}
dist += btwn; dist += btwn;
} }
} }
@ -94,7 +104,7 @@ impl DrawLane {
LaneType::Sidewalk => cs.sidewalk, LaneType::Sidewalk => cs.sidewalk,
LaneType::Biking => cs.bike_lane, LaneType::Biking => cs.bike_lane,
LaneType::SharedLeftTurn => cs.driving_lane, LaneType::SharedLeftTurn => cs.driving_lane,
LaneType::Construction => cs.under_construction, LaneType::Construction => cs.parking_lane,
}, },
polygon.clone(), polygon.clone(),
); );
@ -137,10 +147,7 @@ impl DrawLane {
.make_polygons(Distance::meters(0.25)), .make_polygons(Distance::meters(0.25)),
); );
} }
LaneType::Construction => { LaneType::Construction => {}
// TODO Can't put this in ColorScheme without switching to FancyColor
draw.fancy_push(FancyColor::Hatching, polygon.clone());
}
}; };
} }

View File

@ -136,18 +136,20 @@ impl Polygon {
} }
pub fn rotate(&self, angle: Angle) -> Polygon { pub fn rotate(&self, angle: Angle) -> Polygon {
let center = self.center(); self.rotate_around(angle, self.center())
}
pub fn rotate_around(&self, angle: Angle, pivot: Pt2D) -> Polygon {
Polygon { Polygon {
points: self points: self
.points .points
.iter() .iter()
.map(|pt| { .map(|pt| {
let origin_pt = Pt2D::new(pt.x() - center.x(), pt.y() - center.y()); let origin_pt = Pt2D::new(pt.x() - pivot.x(), pt.y() - pivot.y());
let (sin, cos) = angle.normalized_radians().sin_cos(); let (sin, cos) = angle.normalized_radians().sin_cos();
Pt2D::new( Pt2D::new(
center.x() + origin_pt.x() * cos - origin_pt.y() * sin, pivot.x() + origin_pt.x() * cos - origin_pt.y() * sin,
center.y() + origin_pt.y() * cos + origin_pt.x() * sin, pivot.y() + origin_pt.y() * cos + origin_pt.x() * sin,
) )
}) })
.collect(), .collect(),