WIP making DrawPed implement Renderable

This commit is contained in:
Dustin Carlino 2018-09-13 21:55:55 -07:00
parent 48a47ff013
commit b3d2a5c5be
11 changed files with 119 additions and 89 deletions

View File

@ -980,8 +980,11 @@ so it feels like we implicitly have a big enum of active plugin, with each of th
= basically, make UI.event() just the active plugin list thing as much as possible.
- deal with overlapping keys that still kinda happen (sim ctrl, escape game)
- bug: do need to recalculate current_selection whenever anything potentially changes camera, like follow
- make draw car/ped implement renderable.
- move Draw* to editor crate, and have an intermediate thing exposed from sim and do the translation in get_blah_onscreen.
- then rethink colors, with simplified single plugin
- then finally try out a unified quadtree!
= then finally try out a unified quadtree!
= make parcels selectable as well?
- and see how much boilerplate a new type would need, by adding bus stops and water/parks

View File

@ -104,6 +104,7 @@ fn debug(id: &ID, map: &Map, control_map: &ControlMap, sim: &mut Sim) {
}
}
// TODO Renderable has tooltip_lines... decide what goes where
fn tooltip_lines(id: ID, map: &Map, draw_map: &DrawMap, sim: &Sim) -> Vec<String> {
match id {
ID::Lane(id) => draw_map.get_l(id).tooltip_lines(map),

View File

@ -55,7 +55,7 @@ impl FollowState {
}
FollowState::FollowingPedestrian(id) => {
if let Some(p) = sim.get_draw_ped(*id, map) {
let pt = p.focus_pt();
let pt = p.pos;
canvas.center_on_map_pt(pt.x(), pt.y());
input.key_pressed(Key::Return, "stop following")
} else {

View File

@ -122,7 +122,7 @@ fn warp(line: String, map: &Map, sim: &Sim, canvas: &mut Canvas, selected: &mut
if let Some(p) = sim.get_draw_ped(id, map) {
println!("Warping to {}", id);
*selected = Some(ID::Pedestrian(id));
p.focus_pt()
p.pos
} else {
println!("{} doesn't exist", id);
return;

View File

@ -6,6 +6,7 @@ mod intersection;
mod lane;
mod map;
mod parcel;
mod pedestrian;
mod turn;
use aabb_quadtree::geom::{Point, Rect};
@ -16,6 +17,7 @@ use graphics::types::Color;
use map_model::{geometry, Map};
pub use render::lane::DrawLane;
pub use render::map::DrawMap;
pub use render::pedestrian::DrawPedestrian;
pub use render::turn::DrawTurn;
use std::f64;
use std::fmt;

View File

@ -0,0 +1,70 @@
use aabb_quadtree::geom::Rect;
use colors::ColorScheme;
use ezgui::GfxCtx;
use geom::Pt2D;
use graphics;
use graphics::types::Color;
use map_model::{geometry, Map};
use render::Renderable;
use sim::{DrawPedestrianInput, PedestrianID};
const RADIUS: f64 = 1.0;
// TODO should this live in editor/render?
pub struct DrawPedestrian {
pub id: PedestrianID,
circle: [f64; 4],
turn_arrow: Option<[f64; 4]>,
}
impl DrawPedestrian {
pub fn new(input: DrawPedestrianInput, map: &Map) -> DrawPedestrian {
let turn_arrow = if let Some(t) = input.waiting_for_turn {
// TODO this isn't quite right, but good enough for now
let angle = map.get_t(t).line.angle();
let arrow_pt = input.pos.project_away(RADIUS, angle.opposite());
Some([arrow_pt.x(), arrow_pt.y(), input.pos.x(), input.pos.y()])
} else {
None
};
DrawPedestrian {
id: input.id,
circle: geometry::make_circle(input.pos, RADIUS),
turn_arrow,
}
}
}
impl Renderable for DrawPedestrian {
type ID = PedestrianID;
fn get_id(&self) -> PedestrianID {
self.id
}
fn draw(&self, g: &mut GfxCtx, color: Color, _cs: &ColorScheme) {
g.draw_ellipse(color, self.circle);
// TODO tune color, sizes
if let Some(a) = self.turn_arrow {
g.draw_arrow(
&graphics::Line::new_round([0.0, 1.0, 1.0, 1.0], 0.25),
a,
0.3,
);
}
}
fn get_bbox(&self) -> Rect {
geometry::circle_to_bbox(&self.circle)
}
fn contains_pt(&self, pt: Pt2D) -> bool {
geometry::point_in_circle(&self.circle, pt)
}
fn tooltip_lines(&self, _map: &Map) -> Vec<String> {
vec![self.id.to_string()]
}
}

View File

@ -342,7 +342,8 @@ impl UI {
return Some(ID::Car(c.id));
}
}
for p in &self.sim.get_draw_peds_on_lane(l.id, &self.map) {
for p in self.sim.get_draw_peds_on_lane(l.id, &self.map).into_iter() {
let p = render::DrawPedestrian::new(p, &self.map);
if p.contains_pt(pt) {
return Some(ID::Pedestrian(p.id));
}
@ -365,7 +366,8 @@ impl UI {
return Some(ID::Car(c.id));
}
}
for p in &self.sim.get_draw_peds_on_turn(*t, &self.map) {
for p in self.sim.get_draw_peds_on_turn(*t, &self.map).into_iter() {
let p = render::DrawPedestrian::new(p, &self.map);
if p.contains_pt(pt) {
return Some(ID::Pedestrian(p.id));
}
@ -656,8 +658,9 @@ impl UI {
for c in &self.sim.get_draw_cars_on_turn(*t, &self.map) {
c.draw(g, self.color_car(c.id));
}
for p in &self.sim.get_draw_peds_on_turn(*t, &self.map) {
p.draw(g, self.color_ped(p.id));
for p in self.sim.get_draw_peds_on_turn(*t, &self.map).into_iter() {
let p = render::DrawPedestrian::new(p, &self.map);
p.draw(g, self.color_ped(p.id), &self.cs);
}
}
}
@ -689,8 +692,9 @@ impl UI {
for c in &self.sim.get_draw_cars_on_lane(l.id, &self.map) {
c.draw(g, self.color_car(c.id));
}
for p in &self.sim.get_draw_peds_on_lane(l.id, &self.map) {
p.draw(g, self.color_ped(p.id));
for p in self.sim.get_draw_peds_on_lane(l.id, &self.map).into_iter() {
let p = render::DrawPedestrian::new(p, &self.map);
p.draw(g, self.color_ped(p.id), &self.cs);
}
}

View File

@ -1,54 +0,0 @@
use ezgui::GfxCtx;
use geom::Pt2D;
use graphics;
use map_model::{geometry, Turn};
use PedestrianID;
const RADIUS: f64 = 1.0;
// TODO should this live in editor/render?
pub struct DrawPedestrian {
pub id: PedestrianID,
circle: [f64; 4],
turn_arrow: Option<[f64; 4]>,
}
impl DrawPedestrian {
pub fn new(id: PedestrianID, pos: Pt2D, waiting_for_turn: Option<&Turn>) -> DrawPedestrian {
let turn_arrow = if let Some(t) = waiting_for_turn {
// TODO this isn't quite right, but good enough for now
let angle = t.line.angle();
let arrow_pt = pos.project_away(RADIUS, angle.opposite());
Some([arrow_pt.x(), arrow_pt.y(), pos.x(), pos.y()])
} else {
None
};
DrawPedestrian {
id,
circle: geometry::make_circle(pos, RADIUS),
turn_arrow,
}
}
pub fn draw(&self, g: &mut GfxCtx, color: graphics::types::Color) {
g.draw_ellipse(color, self.circle);
// TODO tune color, sizes
if let Some(a) = self.turn_arrow {
g.draw_arrow(
&graphics::Line::new_round([0.0, 1.0, 1.0, 1.0], 0.25),
a,
0.3,
);
}
}
pub fn contains_pt(&self, pt: Pt2D) -> bool {
geometry::point_in_circle(&self.circle, pt)
}
pub fn focus_pt(&self) -> Pt2D {
geometry::center_of_circle(&self.circle)
}
}

View File

@ -28,7 +28,6 @@ extern crate serde;
extern crate serde_derive;
mod draw_car;
mod draw_ped;
mod driving;
mod events;
mod helpers;
@ -346,3 +345,10 @@ impl ParkedCar {
ParkedCar { car, spot }
}
}
// Intermediate structures so that sim and editor crates don't have a cyclic dependency.
pub struct DrawPedestrianInput {
pub id: PedestrianID,
pub pos: Pt2D,
pub waiting_for_turn: Option<TurnID>,
}

View File

@ -4,7 +4,6 @@ use abstutil;
use control::ControlMap;
use dimensioned::si;
use draw_car::DrawCar;
use draw_ped::DrawPedestrian;
use driving::DrivingSimState;
use failure::Error;
use instrument::capture_backtrace;
@ -23,7 +22,7 @@ use transit::TransitSimState;
use trips::TripManager;
use view::WorldView;
use walking::WalkingSimState;
use {AgentID, CarID, CarState, Event, PedestrianID, Tick, TIMESTEP};
use {AgentID, CarID, CarState, DrawPedestrianInput, Event, PedestrianID, Tick, TIMESTEP};
#[derive(Serialize, Deserialize, Derivative)]
#[derivative(PartialEq, Eq)]
@ -234,7 +233,7 @@ impl Sim {
})
}
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrian> {
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput> {
self.walking_state.get_draw_ped(id, map)
}
@ -257,11 +256,11 @@ impl Sim {
.get_draw_cars_on_turn(t, self.time, map, &self.car_properties)
}
pub fn get_draw_peds_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawPedestrian> {
pub fn get_draw_peds_on_lane(&self, l: LaneID, map: &Map) -> Vec<DrawPedestrianInput> {
self.walking_state.get_draw_peds_on_lane(map.get_l(l), map)
}
pub fn get_draw_peds_on_turn(&self, t: TurnID, map: &Map) -> Vec<DrawPedestrian> {
pub fn get_draw_peds_on_turn(&self, t: TurnID, map: &Map) -> Vec<DrawPedestrianInput> {
self.walking_state.get_draw_peds_on_turn(map.get_t(t))
}

View File

@ -1,7 +1,6 @@
use abstutil;
use abstutil::{deserialize_multimap, serialize_multimap};
use dimensioned::si;
use draw_ped::DrawPedestrian;
use failure::Error;
use geom::{Line, Pt2D};
use instrument::capture_backtrace;
@ -13,8 +12,8 @@ use std;
use std::collections::{BTreeMap, VecDeque};
use view::{AgentView, WorldView};
use {
AgentID, Distance, Event, InvariantViolated, On, ParkingSpot, PedestrianID, Speed, Time,
TIMESTEP,
AgentID, Distance, DrawPedestrianInput, Event, InvariantViolated, On, ParkingSpot,
PedestrianID, Speed, Time, TIMESTEP,
};
// TODO tune these!
@ -455,37 +454,37 @@ impl WalkingSimState {
}
}
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrian> {
pub fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput> {
let ped = self.peds.get(&id)?;
Some(DrawPedestrian::new(
Some(DrawPedestrianInput {
id,
ped.get_pos(map),
pos: ped.get_pos(map),
// TODO this isnt correct, but works right now because this is only called by warp
None,
))
waiting_for_turn: None,
})
}
pub fn get_draw_peds_on_lane(&self, l: &Lane, map: &Map) -> Vec<DrawPedestrian> {
pub fn get_draw_peds_on_lane(&self, l: &Lane, map: &Map) -> Vec<DrawPedestrianInput> {
let mut result = Vec::new();
for id in self.peds_per_sidewalk.get_vec(&l.id).unwrap_or(&Vec::new()) {
let ped = &self.peds[id];
result.push(DrawPedestrian::new(
*id,
ped.get_pos(map),
ped.waiting_for.map(|on| map.get_t(on.as_turn())),
));
result.push(DrawPedestrianInput {
id: *id,
pos: ped.get_pos(map),
waiting_for_turn: ped.waiting_for.map(|on| on.as_turn()),
});
}
result
}
pub fn get_draw_peds_on_turn(&self, t: &Turn) -> Vec<DrawPedestrian> {
pub fn get_draw_peds_on_turn(&self, t: &Turn) -> Vec<DrawPedestrianInput> {
let mut result = Vec::new();
for id in self.peds_per_turn.get_vec(&t.id).unwrap_or(&Vec::new()) {
result.push(DrawPedestrian::new(
*id,
t.dist_along(self.peds[id].dist_along).0,
None,
));
result.push(DrawPedestrianInput {
id: *id,
pos: t.dist_along(self.peds[id].dist_along).0,
waiting_for_turn: None,
});
}
result
}