mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-27 16:36:02 +03:00
use a regularly spaced marking for construction instead of the weird
stripes. clean up the hack in the shader
This commit is contained in:
parent
626636ece7
commit
07bf9725d4
@ -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),
|
||||||
|
13
data/system/assets/map/under_construction.svg
Normal file
13
data/system/assets/map/under_construction.svg
Normal 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 |
@ -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],
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)),
|
||||||
])
|
])
|
||||||
|
@ -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 => {}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
|
Loading…
Reference in New Issue
Block a user