drawing individual cars, without handling transitions yet

This commit is contained in:
Dustin Carlino 2019-02-19 16:52:52 -08:00
parent 6aafb908b6
commit 02bc78002f
2 changed files with 90 additions and 6 deletions

View File

@ -1,8 +1,9 @@
use crate::objects::{DrawCtx, ID};
use crate::plugins::sim::new_des_model;
use crate::plugins::{BlockingPlugin, PluginCtx};
use crate::render::MIN_ZOOM_FOR_DETAIL;
use ezgui::{EventLoopMode, GfxCtx, Key};
use geom::Duration;
use geom::{Duration, Speed};
use map_model::{LaneID, Map, Traversable};
use rand::seq::SliceRandom;
use rand::SeedableRng;
@ -69,7 +70,11 @@ impl BlockingPlugin for EvenSimplerModelController {
}
fn draw(&self, g: &mut GfxCtx, ctx: &DrawCtx) {
self.world.draw_unzoomed(self.current_time, g, &ctx.map);
if g.canvas.cam_zoom >= MIN_ZOOM_FOR_DETAIL {
self.world.draw_detailed(self.current_time, g, &ctx.map);
} else {
self.world.draw_unzoomed(self.current_time, g, &ctx.map);
}
}
}
@ -103,9 +108,16 @@ fn populate_world(start: LaneID, map: &Map) -> new_des_model::World {
last_lane = t.id.dst;
}
// Throw a slow vehicle in the middle
let max_speed = if i == 4 {
Some(Speed::miles_per_hour(10.0))
} else {
None
};
world.spawn_car(
CarID::tmp_new(i, VehicleType::Car),
None,
max_speed,
path.clone(),
Duration::seconds(1.0) * (i as f64),
);

View File

@ -4,7 +4,8 @@ use map_model::{IntersectionID, LaneID, Map, Traversable, TurnID, LANE_THICKNESS
use sim::CarID;
use std::collections::{BTreeMap, VecDeque};
const VEHICLE_LENGTH: Distance = Distance::const_meters(5.0);
const VEHICLE_LENGTH: Distance = Distance::const_meters(4.0);
const FOLLOWING_DISTANCE: Distance = Distance::const_meters(1.0);
const FREEFLOW: Color = Color::CYAN;
const WAITING: Color = Color::RED;
@ -30,7 +31,9 @@ impl World {
Queue {
id: l.id,
cars: VecDeque::new(),
max_capacity: ((l.length() / VEHICLE_LENGTH).floor() as usize).max(1),
max_capacity: ((l.length() / (VEHICLE_LENGTH + FOLLOWING_DISTANCE)).floor()
as usize)
.max(1),
},
);
}
@ -73,7 +76,8 @@ impl World {
}
let l = map.get_l(queue.id);
let end_of_waiting_queue = l.length() - (num_waiting as f64) * VEHICLE_LENGTH;
let end_of_waiting_queue =
l.length() - (num_waiting as f64) * (VEHICLE_LENGTH + FOLLOWING_DISTANCE);
if freeflow_head.is_some() {
// The freeflow block can range from [0, end_of_waiting_queue].
@ -124,6 +128,74 @@ impl World {
}
}
pub fn draw_detailed(&self, time: Duration, g: &mut GfxCtx, map: &Map) {
for queue in self.queues.values() {
if queue.cars.is_empty() {
continue;
}
let l = map.get_l(queue.id);
let mut last_car_back: Option<Distance> = None;
for car in &queue.cars {
let (front, color) = match car.state {
CarState::Queued => {
if last_car_back.is_none() {
(l.length(), WAITING)
} else {
// TODO If the last car is still CrossingLane, then kinda weird to draw
// us as queued
(last_car_back.unwrap() - FOLLOWING_DISTANCE, WAITING)
}
}
CarState::CrossingLane(ref i) => {
let bound = last_car_back
.map(|b| b - FOLLOWING_DISTANCE)
.unwrap_or(l.length());
(i.percent(time) * bound, FREEFLOW)
}
CarState::CrossingTurn(_) => unreachable!(),
};
let back = front - VEHICLE_LENGTH;
if back < Distance::ZERO {
println!("Messed up on {}", queue.id);
break;
} else {
last_car_back = Some(back);
g.draw_polygon(
color,
&l.lane_center_pts
.slice(back, front)
.unwrap()
.0
.make_polygons(LANE_THICKNESS),
);
}
}
}
for i in self.intersections.values() {
if let Some(ref car) = i.accepted {
let t = map.get_t(car.path[0].as_turn());
let percent = match car.state {
CarState::CrossingTurn(ref int) => int.percent(time),
_ => unreachable!(),
};
// TODO The VEHICLE_LENGTH is confusing...
let tail = percent * t.geom.length();
g.draw_polygon(
FREEFLOW,
&t.geom
.slice(tail, tail + VEHICLE_LENGTH)
.unwrap()
.0
.make_polygons(LANE_THICKNESS),
);
}
}
}
pub fn spawn_car(
&mut self,
id: CarID,