game/render/
mod.rs

1use geom::{Distance, Pt2D, Tessellation};
2use map_gui::colors::ColorScheme;
3use map_gui::render::DrawOptions;
4use map_gui::AppLike;
5use map_model::{Map, NORMAL_LANE_THICKNESS, SIDEWALK_THICKNESS};
6use sim::{DrawCarInput, PersonID, Sim, VehicleType};
7use widgetry::{Color, GfxCtx, Prerender};
8
9pub use crate::render::agents::{AgentCache, UnzoomedAgents};
10use crate::render::bike::DrawBike;
11use crate::render::car::DrawCar;
12pub use crate::render::pedestrian::{DrawPedCrowd, DrawPedestrian};
13use crate::ID;
14
15mod agents;
16mod bike;
17mod car;
18mod pedestrian;
19
20// Like map_gui's Renderable, but uses our ID type
21pub trait GameRenderable {
22    // TODO This is expensive for the PedCrowd case. :( Returning a borrow is awkward, because most
23    // Renderables are better off storing the inner ID directly.
24    fn get_id(&self) -> ID;
25    fn draw(&self, g: &mut GfxCtx, app: &dyn AppLike, opts: &DrawOptions);
26    // Higher z-ordered objects are drawn later. Default to low so roads at -1 don't vanish.
27    fn get_zorder(&self) -> isize {
28        -5
29    }
30    // This outline is drawn over the base object to show that it's selected. It also represents
31    // the boundaries for quadtrees. This isn't called often; don't worry about caching.
32    fn get_outline(&self, map: &Map) -> Tessellation;
33    fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool;
34}
35
36impl<R: map_gui::render::Renderable> GameRenderable for R {
37    fn get_id(&self) -> ID {
38        self.get_id().into()
39    }
40    fn draw(&self, g: &mut GfxCtx, app: &dyn AppLike, opts: &DrawOptions) {
41        self.draw(g, app, opts);
42    }
43    fn get_zorder(&self) -> isize {
44        self.get_zorder()
45    }
46    fn get_outline(&self, map: &Map) -> Tessellation {
47        self.get_outline(map)
48    }
49    fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool {
50        self.contains_pt(pt, map)
51    }
52}
53
54fn draw_vehicle(
55    input: DrawCarInput,
56    map: &Map,
57    sim: &Sim,
58    prerender: &Prerender,
59    cs: &ColorScheme,
60) -> Box<dyn GameRenderable> {
61    if input.id.vehicle_type == VehicleType::Bike {
62        Box::new(DrawBike::new(input, map, sim, prerender, cs))
63    } else {
64        Box::new(DrawCar::new(input, map, sim, prerender, cs))
65    }
66}
67
68pub fn unzoomed_agent_radius(vt: Option<VehicleType>) -> Distance {
69    // Lane thickness is a little hard to see, so double it. Most of the time, the circles don't
70    // leak out of the road too much.
71    if vt.is_some() {
72        4.0 * NORMAL_LANE_THICKNESS
73    } else {
74        4.0 * SIDEWALK_THICKNESS
75    }
76}
77
78/// If the sim has highlighted people, then fade all others out.
79fn grey_out_unhighlighted_people(color: Color, person: &Option<PersonID>, sim: &Sim) -> Color {
80    if let Some(ref highlighted) = sim.get_highlighted_people() {
81        if person
82            .as_ref()
83            .map(|p| !highlighted.contains(p))
84            .unwrap_or(false)
85        {
86            return color.tint(0.5);
87        }
88    }
89    color
90}