mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 16:02:23 +03:00
WIP making DrawPed implement Renderable
This commit is contained in:
parent
48a47ff013
commit
b3d2a5c5be
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
70
editor/src/render/pedestrian.rs
Normal file
70
editor/src/render/pedestrian.rs
Normal 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()]
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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>,
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user