mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Add a third TripEndpoint case to appear at an exact Position (lane + distance). This is a necessary step before simplifying Scenario's IndividTrip to use TripEndpoints and mode instead of SpawnTrip. #258
This commit is contained in:
parent
5ea3c2ba6f
commit
2abeebc55e
@ -383,6 +383,7 @@ pub fn schedule(
|
||||
}
|
||||
}
|
||||
TripEndpoint::Border(_) => "off-map".to_string(),
|
||||
TripEndpoint::SuddenlyAppear(_) => "suddenly appear".to_string(),
|
||||
};
|
||||
rows.push(
|
||||
Text::from(Line(format!(
|
||||
@ -412,6 +413,7 @@ pub fn schedule(
|
||||
}
|
||||
}
|
||||
TripEndpoint::Border(_) => "off-map".to_string(),
|
||||
TripEndpoint::SuddenlyAppear(_) => "suddenly disappear".to_string(),
|
||||
};
|
||||
rows.push(
|
||||
Text::from(Line(format!(
|
||||
|
@ -899,5 +899,13 @@ fn endpoint(endpt: &TripEndpoint, app: &App) -> (ID, Pt2D, String) {
|
||||
),
|
||||
)
|
||||
}
|
||||
TripEndpoint::SuddenlyAppear(pos) => (
|
||||
ID::Lane(pos.lane()),
|
||||
pos.pt(&app.primary.map),
|
||||
format!(
|
||||
"suddenly appear {} along",
|
||||
pos.dist_along().to_string(&app.opts.units)
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -85,10 +85,12 @@ impl CommuterPatterns {
|
||||
let block1 = match trip.start {
|
||||
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
||||
TripEndpoint::Border(i) => border_to_block[&i],
|
||||
TripEndpoint::SuddenlyAppear(_) => continue,
|
||||
};
|
||||
let block2 = match trip.end {
|
||||
TripEndpoint::Bldg(b) => bldg_to_block[&b],
|
||||
TripEndpoint::Border(i) => border_to_block[&i],
|
||||
TripEndpoint::SuddenlyAppear(_) => continue,
|
||||
};
|
||||
// Totally ignore trips within the same block
|
||||
if block1 != block2 {
|
||||
@ -151,6 +153,7 @@ impl CommuterPatterns {
|
||||
count.inc(self.border_to_block[&i]);
|
||||
}
|
||||
}
|
||||
TripEndpoint::SuddenlyAppear(_) => {}
|
||||
}
|
||||
} else {
|
||||
match trip.start {
|
||||
@ -162,6 +165,7 @@ impl CommuterPatterns {
|
||||
count.inc(self.border_to_block[&i]);
|
||||
}
|
||||
}
|
||||
TripEndpoint::SuddenlyAppear(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
|
||||
.centered_on(match trip.start {
|
||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
||||
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
||||
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
|
||||
}),
|
||||
);
|
||||
batch.append(
|
||||
@ -182,6 +183,7 @@ fn preview_route(g: &mut GfxCtx, app: &App, id: TripID) -> GeomBatch {
|
||||
.centered_on(match trip.end {
|
||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(b).label_center,
|
||||
TripEndpoint::Border(i) => app.primary.map.get_i(i).polygon.center(),
|
||||
TripEndpoint::SuddenlyAppear(pos) => pos.pt(&app.primary.map),
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -433,6 +433,7 @@ impl State<App> for AgentSpawner {
|
||||
match endpt {
|
||||
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
|
||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -442,6 +443,7 @@ impl State<App> for AgentSpawner {
|
||||
match endpt {
|
||||
TripEndpoint::Border(i) => app.primary.map.get_i(*i).polygon.clone(),
|
||||
TripEndpoint::Bldg(b) => app.primary.map.get_b(*b).polygon.clone(),
|
||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||
},
|
||||
);
|
||||
if let Some(p) = poly {
|
||||
@ -513,8 +515,14 @@ pub fn spawn_agents_around(i: IntersectionID, app: &mut App) {
|
||||
now,
|
||||
TripSpec::JustWalking {
|
||||
start: SidewalkSpot::suddenly_appear(
|
||||
lane.id,
|
||||
Scenario::rand_dist(&mut rng, 0.1 * lane.length(), 0.9 * lane.length()),
|
||||
Position::new(
|
||||
lane.id,
|
||||
Scenario::rand_dist(
|
||||
&mut rng,
|
||||
0.1 * lane.length(),
|
||||
0.9 * lane.length(),
|
||||
),
|
||||
),
|
||||
map,
|
||||
),
|
||||
goal: SidewalkSpot::building(
|
||||
|
@ -523,12 +523,12 @@ impl SidewalkSpot {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn suddenly_appear(l: LaneID, dist: Distance, map: &Map) -> SidewalkSpot {
|
||||
let lane = map.get_l(l);
|
||||
pub fn suddenly_appear(pos: Position, map: &Map) -> SidewalkSpot {
|
||||
let lane = map.get_l(pos.lane());
|
||||
assert!(lane.is_walkable());
|
||||
assert!(dist <= lane.length());
|
||||
assert!(pos.dist_along() <= lane.length());
|
||||
SidewalkSpot {
|
||||
sidewalk_pos: Position::new(l, dist),
|
||||
sidewalk_pos: pos,
|
||||
connection: SidewalkPOI::SuddenlyAppear,
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +159,8 @@ impl ScenarioGenerator {
|
||||
(TripEndpoint::Border(_), TripEndpoint::Border(_)) => {
|
||||
num_trips_passthru += 1;
|
||||
}
|
||||
(TripEndpoint::SuddenlyAppear(_), _) => unreachable!(),
|
||||
(_, TripEndpoint::SuddenlyAppear(_)) => unreachable!(),
|
||||
};
|
||||
|
||||
(home, work, fork_rng(rng))
|
||||
|
@ -511,9 +511,7 @@ impl SpawnTrip {
|
||||
|
||||
pub fn start(&self, map: &Map) -> TripEndpoint {
|
||||
match self {
|
||||
SpawnTrip::VehicleAppearing { ref start, .. } => {
|
||||
TripEndpoint::Border(map.get_l(start.lane()).src_i)
|
||||
}
|
||||
SpawnTrip::VehicleAppearing { start, .. } => TripEndpoint::SuddenlyAppear(*start),
|
||||
SpawnTrip::FromBorder { dr, .. } => TripEndpoint::Border(dr.src_i(map)),
|
||||
SpawnTrip::UsingParkedCar(b, _) => TripEndpoint::Bldg(*b),
|
||||
SpawnTrip::UsingBike(b, _) => TripEndpoint::Bldg(*b),
|
||||
@ -521,9 +519,7 @@ impl SpawnTrip {
|
||||
match spot.connection {
|
||||
SidewalkPOI::Building(b) => TripEndpoint::Bldg(b),
|
||||
SidewalkPOI::Border(i) => TripEndpoint::Border(i),
|
||||
SidewalkPOI::SuddenlyAppear => {
|
||||
TripEndpoint::Border(map.get_l(spot.sidewalk_pos.lane()).src_i)
|
||||
}
|
||||
SidewalkPOI::SuddenlyAppear => TripEndpoint::SuddenlyAppear(spot.sidewalk_pos),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -565,6 +561,11 @@ impl SpawnTrip {
|
||||
goal: to.driving_goal(PathConstraints::Car, map)?,
|
||||
is_bike: false,
|
||||
},
|
||||
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
|
||||
start,
|
||||
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||
is_bike: false,
|
||||
},
|
||||
},
|
||||
TripMode::Bike => match from {
|
||||
TripEndpoint::Bldg(b) => {
|
||||
@ -575,6 +576,11 @@ impl SpawnTrip {
|
||||
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||
is_bike: true,
|
||||
},
|
||||
TripEndpoint::SuddenlyAppear(start) => SpawnTrip::VehicleAppearing {
|
||||
start,
|
||||
goal: to.driving_goal(PathConstraints::Bike, map)?,
|
||||
is_bike: true,
|
||||
},
|
||||
},
|
||||
TripMode::Walk => {
|
||||
SpawnTrip::JustWalking(from.start_sidewalk_spot(map)?, to.end_sidewalk_spot(map)?)
|
||||
@ -610,11 +616,11 @@ impl PersonSpec {
|
||||
// Once off-map, re-enter via any border node.
|
||||
let end_bldg = match pair.0.trip.end(map) {
|
||||
TripEndpoint::Bldg(b) => Some(b),
|
||||
TripEndpoint::Border(_) => None,
|
||||
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
|
||||
};
|
||||
let start_bldg = match pair.1.trip.start(map) {
|
||||
TripEndpoint::Bldg(b) => Some(b),
|
||||
TripEndpoint::Border(_) => None,
|
||||
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => None,
|
||||
};
|
||||
|
||||
if end_bldg != start_bldg {
|
||||
|
@ -150,7 +150,7 @@ impl TripManager {
|
||||
.push(Event::PersonEntersBuilding(trip.person, b));
|
||||
PersonState::Inside(b)
|
||||
}
|
||||
TripEndpoint::Border(_) => PersonState::OffMap,
|
||||
TripEndpoint::Border(_) | TripEndpoint::SuddenlyAppear(_) => PersonState::OffMap,
|
||||
};
|
||||
}
|
||||
if let Some(t) = person.trips.last() {
|
||||
@ -715,20 +715,20 @@ impl TripManager {
|
||||
if let PersonState::Inside(b) = self.people[person.0].state {
|
||||
self.events.push(Event::PersonLeavesBuilding(person, b));
|
||||
}
|
||||
match trip.info.end {
|
||||
// Warp to the destination
|
||||
self.people[person.0].state = match trip.info.end {
|
||||
TripEndpoint::Bldg(b) => {
|
||||
self.events.push(Event::PersonEntersBuilding(person, b));
|
||||
PersonState::Inside(b)
|
||||
}
|
||||
TripEndpoint::Border(i) => {
|
||||
self.events.push(Event::PersonLeavesMap(person, None, i));
|
||||
PersonState::OffMap
|
||||
}
|
||||
}
|
||||
|
||||
// Warp to the destination
|
||||
self.people[person.0].state = match trip.info.end {
|
||||
TripEndpoint::Bldg(b) => PersonState::Inside(b),
|
||||
TripEndpoint::Border(_) => PersonState::OffMap,
|
||||
// Can't end trips here yet
|
||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||
};
|
||||
|
||||
// Don't forget the car!
|
||||
if let Some(vehicle) = abandoned_vehicle {
|
||||
if vehicle.vehicle_type == VehicleType::Car {
|
||||
@ -1515,10 +1515,13 @@ impl TripMode {
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies where a trip begins or ends.
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
|
||||
pub enum TripEndpoint {
|
||||
Bldg(BuildingID),
|
||||
Border(IntersectionID),
|
||||
/// Used for interactive spawning, tests, etc. For now, only valid as a trip's start.
|
||||
SuddenlyAppear(Position),
|
||||
}
|
||||
|
||||
impl TripEndpoint {
|
||||
@ -1576,6 +1579,7 @@ fn pos(endpt: TripEndpoint, mode: TripMode, from: bool, map: &Map) -> Option<Pos
|
||||
.map(|l| Position::start(*l))
|
||||
}),
|
||||
},
|
||||
TripEndpoint::SuddenlyAppear(pos) => Some(pos),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1643,6 +1647,7 @@ impl TripEndpoint {
|
||||
match self {
|
||||
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
||||
TripEndpoint::Border(i) => SidewalkSpot::start_at_border(*i, map),
|
||||
TripEndpoint::SuddenlyAppear(pos) => Some(SidewalkSpot::suddenly_appear(*pos, map)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1650,6 +1655,7 @@ impl TripEndpoint {
|
||||
match self {
|
||||
TripEndpoint::Bldg(b) => Some(SidewalkSpot::building(*b, map)),
|
||||
TripEndpoint::Border(i) => SidewalkSpot::end_at_border(*i, map),
|
||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1663,6 +1669,7 @@ impl TripEndpoint {
|
||||
TripEndpoint::Border(i) => {
|
||||
DrivingGoal::end_at_border(map.get_i(*i).some_incoming_road(map)?, constraints, map)
|
||||
}
|
||||
TripEndpoint::SuddenlyAppear(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user