diff --git a/game/src/info/building.rs b/game/src/info/building.rs index 50895b53f4..b052db78a6 100644 --- a/game/src/info/building.rs +++ b/game/src/info/building.rs @@ -289,10 +289,12 @@ pub fn draw_occupants(details: &mut Details, app: &App, id: BuildingID, focus: O DrawPedestrian::geometry( &mut details.zoomed, + &app.primary.sim, &app.cs, &DrawPedestrianInput { // Lies id: PedestrianID(person.0), + person, pos, facing: Angle::degrees(90.0), waiting_for_turn: None, diff --git a/map_gui/src/render/agents.rs b/map_gui/src/render/agents.rs index 43262b7fe1..c35c842def 100644 --- a/map_gui/src/render/agents.rs +++ b/map_gui/src/render/agents.rs @@ -59,12 +59,12 @@ impl AgentCache { let mut list: Vec> = Vec::new(); for c in sim.get_draw_cars(on, map).into_iter() { - list.push(draw_vehicle(c, map, prerender, cs)); + list.push(draw_vehicle(c, map, sim, prerender, cs)); } let (loners, crowds) = sim.get_draw_peds(on, map); for p in loners { list.push(Box::new(DrawPedestrian::new( - p, step_count, map, prerender, cs, + p, step_count, map, sim, prerender, cs, ))); } for c in crowds { @@ -146,7 +146,7 @@ impl AgentCache { let mut cnt = 0; for input in app.sim().get_all_draw_cars(app.map()) { cnt += 1; - draw_vehicle(input, app.map(), g.prerender, app.cs()); + draw_vehicle(input, app.map(), app.sim(), g.prerender, app.cs()); } println!( "At {}, debugged {} cars", diff --git a/map_gui/src/render/bike.rs b/map_gui/src/render/bike.rs index 224ce2da66..2d50b608f5 100644 --- a/map_gui/src/render/bike.rs +++ b/map_gui/src/render/bike.rs @@ -1,10 +1,10 @@ use geom::{ArrowCap, Circle, Distance, Line, PolyLine, Polygon, Pt2D}; use map_model::{Map, SIDEWALK_THICKNESS}; -use sim::{CarID, DrawCarInput}; +use sim::{CarID, DrawCarInput, Sim}; use widgetry::{Drawable, GeomBatch, GfxCtx, Prerender}; use crate::colors::ColorScheme; -use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS}; +use crate::render::{grey_out_unhighlighted_people, DrawOptions, Renderable, OUTLINE_THICKNESS}; use crate::{AppLike, ID}; pub struct DrawBike { @@ -20,6 +20,7 @@ impl DrawBike { pub fn new( input: DrawCarInput, map: &Map, + sim: &Sim, prerender: &Prerender, cs: &ColorScheme, ) -> DrawBike { @@ -27,7 +28,8 @@ impl DrawBike { // TODO Share constants with DrawPedestrian let body_radius = SIDEWALK_THICKNESS / 4.0; - let body_color = cs.rotating_color_agents(input.id.0); + let body_color = + grey_out_unhighlighted_people(cs.rotating_color_agents(input.id.0), &input.person, sim); draw_default.push( cs.bike_frame, input.body.make_polygons(Distance::meters(0.4)), diff --git a/map_gui/src/render/car.rs b/map_gui/src/render/car.rs index abcf52e5dc..ce0bc863e6 100644 --- a/map_gui/src/render/car.rs +++ b/map_gui/src/render/car.rs @@ -1,10 +1,10 @@ use geom::{Angle, ArrowCap, Distance, PolyLine, Polygon, Pt2D, Ring}; use map_model::{Map, TurnType}; -use sim::{CarID, CarStatus, DrawCarInput, VehicleType}; +use sim::{CarID, CarStatus, DrawCarInput, Sim, VehicleType}; use widgetry::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text}; use crate::colors::ColorScheme; -use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS}; +use crate::render::{grey_out_unhighlighted_people, DrawOptions, Renderable, OUTLINE_THICKNESS}; use crate::{AppLike, ID}; const CAR_WIDTH: Distance = Distance::const_meters(1.75); @@ -19,7 +19,13 @@ pub struct DrawCar { } impl DrawCar { - pub fn new(input: DrawCarInput, map: &Map, prerender: &Prerender, cs: &ColorScheme) -> DrawCar { + pub fn new( + input: DrawCarInput, + map: &Map, + sim: &Sim, + prerender: &Prerender, + cs: &ColorScheme, + ) -> DrawCar { let mut draw_default = GeomBatch::new(); // Wheels @@ -75,7 +81,7 @@ impl DrawCar { } }; - draw_default.push(zoomed_color_car(&input, cs), body_polygon.clone()); + draw_default.push(zoomed_color_car(&input, sim, cs), body_polygon.clone()); if input.status == CarStatus::Parked { draw_default.append( GeomBatch::load_svg(prerender, "system/assets/map/parked_car.svg") @@ -234,15 +240,16 @@ fn thick_line_from_angle( PolyLine::must_new(vec![pt, pt2]).make_polygons(thickness) } -fn zoomed_color_car(input: &DrawCarInput, cs: &ColorScheme) -> Color { +fn zoomed_color_car(input: &DrawCarInput, sim: &Sim, cs: &ColorScheme) -> Color { if input.id.1 == VehicleType::Bus { cs.bus_body } else if input.id.1 == VehicleType::Train { cs.train_body } else { - match input.status { + let color = match input.status { CarStatus::Moving => cs.rotating_color_agents(input.id.0), CarStatus::Parked => cs.parked_car, - } + }; + grey_out_unhighlighted_people(color, &input.person, sim) } } diff --git a/map_gui/src/render/mod.rs b/map_gui/src/render/mod.rs index ea49320725..871a1bb686 100644 --- a/map_gui/src/render/mod.rs +++ b/map_gui/src/render/mod.rs @@ -2,8 +2,8 @@ use geom::{Distance, Polygon, Pt2D}; use map_model::{IntersectionID, Map, NORMAL_LANE_THICKNESS, SIDEWALK_THICKNESS}; -use sim::{DrawCarInput, VehicleType}; -use widgetry::{GfxCtx, Prerender}; +use sim::{DrawCarInput, PersonID, Sim, VehicleType}; +use widgetry::{Color, GfxCtx, Prerender}; use crate::colors::ColorScheme; pub use crate::render::agents::{AgentCache, UnzoomedAgents}; @@ -61,13 +61,14 @@ pub trait Renderable { fn draw_vehicle( input: DrawCarInput, map: &Map, + sim: &Sim, prerender: &Prerender, cs: &ColorScheme, ) -> Box { if input.id.1 == VehicleType::Bike { - Box::new(DrawBike::new(input, map, prerender, cs)) + Box::new(DrawBike::new(input, map, sim, prerender, cs)) } else { - Box::new(DrawCar::new(input, map, prerender, cs)) + Box::new(DrawCar::new(input, map, sim, prerender, cs)) } } @@ -101,3 +102,17 @@ pub fn unzoomed_agent_radius(vt: Option) -> Distance { 4.0 * SIDEWALK_THICKNESS } } + +/// If the sim has highlighted people, then fade all others out. +fn grey_out_unhighlighted_people(color: Color, person: &Option, sim: &Sim) -> Color { + if let Some(ref highlighted) = sim.get_highlighted_people() { + if person + .as_ref() + .map(|p| !highlighted.contains(p)) + .unwrap_or(false) + { + return color.tint(0.5); + } + } + color +} diff --git a/map_gui/src/render/pedestrian.rs b/map_gui/src/render/pedestrian.rs index 9587cf2bc3..1abc36e6cb 100644 --- a/map_gui/src/render/pedestrian.rs +++ b/map_gui/src/render/pedestrian.rs @@ -1,10 +1,10 @@ use geom::{ArrowCap, Circle, Distance, PolyLine, Polygon, Pt2D}; use map_model::{DrivingSide, Map, SIDEWALK_THICKNESS}; -use sim::{DrawPedCrowdInput, DrawPedestrianInput, PedCrowdLocation, PedestrianID}; +use sim::{DrawPedCrowdInput, DrawPedestrianInput, PedCrowdLocation, PedestrianID, Sim}; use widgetry::{Color, Drawable, GeomBatch, GfxCtx, Line, Prerender, Text}; use crate::colors::ColorScheme; -use crate::render::{DrawOptions, Renderable, OUTLINE_THICKNESS}; +use crate::render::{grey_out_unhighlighted_people, DrawOptions, Renderable, OUTLINE_THICKNESS}; use crate::{AppLike, ID}; pub struct DrawPedestrian { @@ -20,11 +20,12 @@ impl DrawPedestrian { input: DrawPedestrianInput, step_count: usize, map: &Map, + sim: &Sim, prerender: &Prerender, cs: &ColorScheme, ) -> DrawPedestrian { let mut draw_default = GeomBatch::new(); - DrawPedestrian::geometry(&mut draw_default, cs, &input, step_count); + DrawPedestrian::geometry(&mut draw_default, sim, cs, &input, step_count); let radius = SIDEWALK_THICKNESS / 4.0; // TODO make const after const fn is better let body_circle = Circle::new(input.pos, radius); @@ -52,6 +53,7 @@ impl DrawPedestrian { pub fn geometry( batch: &mut GeomBatch, + sim: &Sim, cs: &ColorScheme, input: &DrawPedestrianInput, step_count: usize, @@ -156,11 +158,15 @@ impl DrawPedestrian { let head_circle = Circle::new(input.pos, 0.5 * radius); batch.push( - if input.preparing_bike { - cs.ped_preparing_bike_body - } else { - cs.rotating_color_agents(input.id.0) - }, + grey_out_unhighlighted_people( + if input.preparing_bike { + cs.ped_preparing_bike_body + } else { + cs.rotating_color_agents(input.id.0) + }, + &Some(input.person), + sim, + ), body_circle.to_polygon(), ); batch.push(cs.ped_head, head_circle.to_polygon()); diff --git a/sim/src/mechanics/car.rs b/sim/src/mechanics/car.rs index 1a31b147fb..b1395aca92 100644 --- a/sim/src/mechanics/car.rs +++ b/sim/src/mechanics/car.rs @@ -241,6 +241,7 @@ impl Car { None }, body, + person: self.trip_and_person.map(|(_, p)| p), } } diff --git a/sim/src/mechanics/parking.rs b/sim/src/mechanics/parking.rs index 5effe8bfb1..82760d6b14 100644 --- a/sim/src/mechanics/parking.rs +++ b/sim/src/mechanics/parking.rs @@ -356,6 +356,7 @@ impl ParkingSim for NormalParkingSimState { on: Traversable::Lane(lane), partly_on: Vec::new(), label: None, + person: None, body: map .get_l(lane) @@ -378,6 +379,7 @@ impl ParkingSim for NormalParkingSimState { on: Traversable::Lane(pl.driving_pos.lane()), partly_on: Vec::new(), label: None, + person: None, body: PolyLine::must_new(vec![ pt.project_away(buffer, *angle), diff --git a/sim/src/mechanics/walking.rs b/sim/src/mechanics/walking.rs index 644326e2c5..ccf49fc4da 100644 --- a/sim/src/mechanics/walking.rs +++ b/sim/src/mechanics/walking.rs @@ -751,6 +751,7 @@ impl Pedestrian { ), waiting_for_bus: matches!(self.state, PedState::WaitingForBus(_, _)), on, + person: self.person, } } diff --git a/sim/src/render.rs b/sim/src/render.rs index 9a1ad00767..13776274a1 100644 --- a/sim/src/render.rs +++ b/sim/src/render.rs @@ -14,6 +14,7 @@ pub struct DrawPedestrianInput { pub preparing_bike: bool, pub waiting_for_bus: bool, pub on: Traversable, + pub person: PersonID, } pub struct DrawPedCrowdInput { @@ -42,6 +43,8 @@ pub struct DrawCarInput { /// Possibly the rest pub partly_on: Vec, pub label: Option, + /// None means a bus or parked car. Note parked cars do NOT express their owner here! + pub person: Option, // Starts at the BACK of the car. pub body: PolyLine,