mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 15:03:20 +03:00
Simplify path trace API -- nobody needs dist_ahead. I think that was originally meant to be a performance trick to only draw the next little bit of a route
This commit is contained in:
parent
d4fa67ac87
commit
d00e7f7bca
@ -267,7 +267,7 @@ impl HoverOnBuilding {
|
||||
let mut batch = GeomBatch::new();
|
||||
if let Some(polyline) = isochrone
|
||||
.path_to(&app.map, hover_id)
|
||||
.and_then(|path| path.trace(&app.map, Distance::ZERO, None))
|
||||
.and_then(|path| path.trace(&app.map, Distance::ZERO))
|
||||
{
|
||||
let dashed_lines = polyline.dashed_lines(
|
||||
Distance::meters(0.75 * scale_factor),
|
||||
|
@ -430,7 +430,7 @@ fn calc_all_routes(ctx: &EventCtx, app: &mut App) -> (usize, Drawable) {
|
||||
Parallelism::Fastest,
|
||||
agents,
|
||||
|id| {
|
||||
sim.trace_route(id, map, None)
|
||||
sim.trace_route(id, map)
|
||||
.map(|trace| trace.make_polygons(NORMAL_LANE_THICKNESS))
|
||||
},
|
||||
) {
|
||||
|
@ -74,7 +74,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID
|
||||
.primary
|
||||
.sim
|
||||
.walking_path_to_nearest_parking_spot(&app.primary.map, id)
|
||||
.and_then(|path| path.trace(&app.primary.map, path.get_req().start.dist_along(), None))
|
||||
.and_then(|path| path.trace(&app.primary.map, path.get_req().start.dist_along()))
|
||||
{
|
||||
let color = app.cs.parking_trip;
|
||||
// TODO But this color doesn't show up well against the info panel...
|
||||
|
@ -746,7 +746,7 @@ fn make_trip_details(
|
||||
// This is expensive, so cache please
|
||||
if idx == open_trip.cached_routes.len() {
|
||||
if let Some(trace) =
|
||||
path.trace(map_for_pathfinding, path.get_req().start.dist_along(), None)
|
||||
path.trace(map_for_pathfinding, path.get_req().start.dist_along())
|
||||
{
|
||||
open_trip.cached_routes.push(Some((
|
||||
trace.make_polygons(Distance::meters(10.0)),
|
||||
|
@ -147,9 +147,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
|
||||
.get_trip_phases(id, &app.primary.map)
|
||||
{
|
||||
if let Some(path) = &p.path {
|
||||
if let Some(trace) =
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along(), None)
|
||||
{
|
||||
if let Some(trace) = path.trace(&app.primary.map, path.get_req().start.dist_along()) {
|
||||
batch.push(
|
||||
color_for_trip_phase(app, p.phase_type),
|
||||
trace.make_polygons(Distance::meters(20.0)),
|
||||
|
@ -322,7 +322,7 @@ impl State<App> for AgentSpawner {
|
||||
{
|
||||
self.goal = Some((
|
||||
to,
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along(), None)
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along())
|
||||
.map(|pl| pl.make_polygons(NORMAL_LANE_THICKNESS)),
|
||||
));
|
||||
} else {
|
||||
@ -387,7 +387,7 @@ impl State<App> for AgentSpawner {
|
||||
{
|
||||
self.goal = Some((
|
||||
hovering,
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along(), None)
|
||||
path.trace(&app.primary.map, path.get_req().start.dist_along())
|
||||
.map(|pl| pl.make_polygons(NORMAL_LANE_THICKNESS)),
|
||||
));
|
||||
} else {
|
||||
|
@ -44,8 +44,7 @@ impl RoutePreview {
|
||||
// Only draw the preview when zoomed in. If we wanted to do this unzoomed, we'd
|
||||
// want a different style; the dashed lines don't show up well.
|
||||
if zoomed {
|
||||
if let Some(trace) = app.primary.sim.trace_route(agent, &app.primary.map, None)
|
||||
{
|
||||
if let Some(trace) = app.primary.sim.trace_route(agent, &app.primary.map) {
|
||||
batch.extend(
|
||||
app.cs.route,
|
||||
trace.dashed_lines(
|
||||
|
@ -52,14 +52,14 @@ impl PathStep {
|
||||
self.as_traversable().as_turn()
|
||||
}
|
||||
|
||||
// Returns dist_remaining. start is relative to the start of the actual geometry -- so from the
|
||||
// lane's real start for ContraflowLane.
|
||||
fn slice(
|
||||
// start is relative to the start of the actual geometry -- so from the lane's real start for
|
||||
// ContraflowLane.
|
||||
fn exact_slice(
|
||||
&self,
|
||||
map: &Map,
|
||||
start: Distance,
|
||||
dist_ahead: Option<Distance>,
|
||||
) -> Result<(PolyLine, Distance), String> {
|
||||
) -> Result<PolyLine, String> {
|
||||
if let Some(d) = dist_ahead {
|
||||
if d < Distance::ZERO {
|
||||
panic!("Negative dist_ahead?! {}", d);
|
||||
@ -73,26 +73,26 @@ impl PathStep {
|
||||
PathStep::Lane(id) => {
|
||||
let pts = &map.get_l(*id).lane_center_pts;
|
||||
if let Some(d) = dist_ahead {
|
||||
pts.slice(start, start + d)
|
||||
pts.maybe_exact_slice(start, start + d)
|
||||
} else {
|
||||
pts.slice(start, pts.length())
|
||||
pts.maybe_exact_slice(start, pts.length())
|
||||
}
|
||||
}
|
||||
PathStep::ContraflowLane(id) => {
|
||||
let pts = map.get_l(*id).lane_center_pts.reversed();
|
||||
let reversed_start = pts.length() - start;
|
||||
if let Some(d) = dist_ahead {
|
||||
pts.slice(reversed_start, reversed_start + d)
|
||||
pts.maybe_exact_slice(reversed_start, reversed_start + d)
|
||||
} else {
|
||||
pts.slice(reversed_start, pts.length())
|
||||
pts.maybe_exact_slice(reversed_start, pts.length())
|
||||
}
|
||||
}
|
||||
PathStep::Turn(id) => {
|
||||
let pts = &map.get_t(*id).geom;
|
||||
if let Some(d) = dist_ahead {
|
||||
pts.slice(start, start + d)
|
||||
pts.maybe_exact_slice(start, start + d)
|
||||
} else {
|
||||
pts.slice(start, pts.length())
|
||||
pts.maybe_exact_slice(start, pts.length())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,73 +321,45 @@ impl Path {
|
||||
self.steps[self.steps.len() - 1]
|
||||
}
|
||||
|
||||
/// dist_ahead is unlimited when None. Note this starts at the beginning (or end, for some
|
||||
/// walking paths) of the first lane, not accounting for the original request's start distance.
|
||||
pub fn trace(
|
||||
&self,
|
||||
map: &Map,
|
||||
start_dist: Distance,
|
||||
dist_ahead: Option<Distance>,
|
||||
) -> Option<PolyLine> {
|
||||
let mut pts_so_far: Option<PolyLine> = None;
|
||||
let mut dist_remaining = dist_ahead;
|
||||
/// Traces along the path from a specified distance along the first step until the end.
|
||||
pub fn trace(&self, map: &Map, start_dist: Distance) -> Option<PolyLine> {
|
||||
let orig_end_dist = self.orig_req.end.dist_along();
|
||||
|
||||
if self.steps.len() == 1 {
|
||||
let dist = if start_dist < orig_end_dist {
|
||||
let dist_ahead = if start_dist < orig_end_dist {
|
||||
orig_end_dist - start_dist
|
||||
} else {
|
||||
start_dist - orig_end_dist
|
||||
};
|
||||
if let Some(d) = dist_remaining {
|
||||
if dist < d {
|
||||
dist_remaining = Some(dist);
|
||||
}
|
||||
} else {
|
||||
dist_remaining = Some(dist);
|
||||
}
|
||||
|
||||
// Why might this fail? It's possible there are paths on their last step that're
|
||||
// effectively empty, because they're a 0-length turn, or something like a pedestrian
|
||||
// crossing a front path and immediately getting on a bike.
|
||||
return self.steps[0]
|
||||
.exact_slice(map, start_dist, Some(dist_ahead))
|
||||
.ok();
|
||||
}
|
||||
|
||||
// Special case the first step.
|
||||
if let Ok((pts, dist)) = self.steps[0].slice(map, start_dist, dist_remaining) {
|
||||
let mut pts_so_far: Option<PolyLine> = None;
|
||||
|
||||
// Special case the first step with start_dist.
|
||||
if let Ok(pts) = self.steps[0].exact_slice(map, start_dist, None) {
|
||||
pts_so_far = Some(pts);
|
||||
if dist_remaining.is_some() {
|
||||
dist_remaining = Some(dist);
|
||||
}
|
||||
}
|
||||
|
||||
if self.steps.len() == 1 {
|
||||
// It's possible there are paths on their last step that're effectively empty, because
|
||||
// they're a 0-length turn, or something like a pedestrian crossing a front path and
|
||||
// immediately getting on a bike.
|
||||
return pts_so_far;
|
||||
}
|
||||
|
||||
// Crunch through the intermediate steps, as long as we can.
|
||||
for i in 1..self.steps.len() {
|
||||
if let Some(d) = dist_remaining {
|
||||
if d <= Distance::ZERO {
|
||||
// We know there's at least some geometry if we made it here, so unwrap to
|
||||
// verify that understanding.
|
||||
return Some(pts_so_far.unwrap());
|
||||
}
|
||||
}
|
||||
// If we made it to the last step, maybe use the end_dist.
|
||||
if i == self.steps.len() - 1 {
|
||||
let end_dist = match self.steps[i] {
|
||||
// Restrict the last step's slice
|
||||
let dist_ahead = if i == self.steps.len() - 1 {
|
||||
Some(match self.steps[i] {
|
||||
PathStep::ContraflowLane(l) => {
|
||||
map.get_l(l).lane_center_pts.reversed().length() - orig_end_dist
|
||||
}
|
||||
_ => orig_end_dist,
|
||||
};
|
||||
if let Some(d) = dist_remaining {
|
||||
if end_dist < d {
|
||||
dist_remaining = Some(end_dist);
|
||||
}
|
||||
} else {
|
||||
dist_remaining = Some(end_dist);
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let start_dist_this_step = match self.steps[i] {
|
||||
// TODO Length of a PolyLine can slightly change when points are reversed! That
|
||||
@ -395,9 +367,7 @@ impl Path {
|
||||
PathStep::ContraflowLane(l) => map.get_l(l).lane_center_pts.reversed().length(),
|
||||
_ => Distance::ZERO,
|
||||
};
|
||||
if let Ok((new_pts, dist)) =
|
||||
self.steps[i].slice(map, start_dist_this_step, dist_remaining)
|
||||
{
|
||||
if let Ok(new_pts) = self.steps[i].exact_slice(map, start_dist_this_step, dist_ahead) {
|
||||
if pts_so_far.is_some() {
|
||||
match pts_so_far.unwrap().extend(new_pts) {
|
||||
Ok(new) => {
|
||||
@ -411,9 +381,6 @@ impl Path {
|
||||
} else {
|
||||
pts_so_far = Some(new_pts);
|
||||
}
|
||||
if dist_remaining.is_some() {
|
||||
dist_remaining = Some(dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1047,16 +1047,10 @@ impl DrivingSimState {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn trace_route(
|
||||
&self,
|
||||
now: Time,
|
||||
id: CarID,
|
||||
map: &Map,
|
||||
dist_ahead: Option<Distance>,
|
||||
) -> Option<PolyLine> {
|
||||
pub fn trace_route(&self, now: Time, id: CarID, map: &Map) -> Option<PolyLine> {
|
||||
let car = self.cars.get(&id)?;
|
||||
let front = self.get_car_front(now, car);
|
||||
car.router.get_path().trace(map, front, dist_ahead)
|
||||
car.router.get_path().trace(map, front)
|
||||
}
|
||||
|
||||
pub fn percent_along_route(&self, id: CarID) -> f64 {
|
||||
|
@ -398,18 +398,12 @@ impl WalkingSimState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trace_route(
|
||||
&self,
|
||||
now: Time,
|
||||
id: PedestrianID,
|
||||
map: &Map,
|
||||
dist_ahead: Option<Distance>,
|
||||
) -> Option<PolyLine> {
|
||||
pub fn trace_route(&self, now: Time, id: PedestrianID, map: &Map) -> Option<PolyLine> {
|
||||
let p = self.peds.get(&id)?;
|
||||
let body_radius = SIDEWALK_THICKNESS / 4.0;
|
||||
let dist = (p.get_dist_along(now, map) + body_radius)
|
||||
.min(p.path.current_step().as_traversable().length(map));
|
||||
p.path.trace(map, dist, dist_ahead)
|
||||
p.path.trace(map, dist)
|
||||
}
|
||||
|
||||
pub fn get_path(&self, id: PedestrianID) -> Option<&Path> {
|
||||
|
@ -215,15 +215,10 @@ impl Sim {
|
||||
self.driving.get_all_driving_paths()
|
||||
}
|
||||
|
||||
pub fn trace_route(
|
||||
&self,
|
||||
id: AgentID,
|
||||
map: &Map,
|
||||
dist_ahead: Option<Distance>,
|
||||
) -> Option<PolyLine> {
|
||||
pub fn trace_route(&self, id: AgentID, map: &Map) -> Option<PolyLine> {
|
||||
match id {
|
||||
AgentID::Car(car) => self.driving.trace_route(self.time, car, map, dist_ahead),
|
||||
AgentID::Pedestrian(ped) => self.walking.trace_route(self.time, ped, map, dist_ahead),
|
||||
AgentID::Car(car) => self.driving.trace_route(self.time, car, map),
|
||||
AgentID::Pedestrian(ped) => self.walking.trace_route(self.time, ped, map),
|
||||
AgentID::BusPassenger(_, _) => None,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user