mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 17:37:22 +03:00
replace small_spawn with something to instantiate any scenario for the map
This commit is contained in:
parent
f8cee896bf
commit
27e933fbf8
@ -105,3 +105,20 @@ https://www.reddit.com/r/gamedev/comments/2yfyi5/drawing_lines_is_hard/
|
||||
https://blog.mapbox.com/drawing-antialiased-lines-with-opengl-8766f34192dc
|
||||
http://artgrammer.blogspot.com/2011/07/drawing-polylines-by-tessellation.html
|
||||
https://www.reddit.com/r/GraphicsProgramming/
|
||||
|
||||
|
||||
- are all the sources of doubling back strangely just directly fixable in the geom?
|
||||
- keep miter joins, but limit how far out we can explode?
|
||||
- bevel joins
|
||||
- outlines miss bevels on one edge
|
||||
- now there are little gaps between adjacent lanes
|
||||
- slow!
|
||||
- some bugs that cover a thick triangular area
|
||||
- refactor all the methods... confusing.
|
||||
- ideas
|
||||
- https://stackoverflow.com/questions/5641769/how-to-draw-an-outline-around-any-line
|
||||
- http://old.cescg.org/CESCG99/SKrivograd/
|
||||
- https://www.codeproject.com/Articles/226569/Drawing-polylines-by-tessellation
|
||||
- https://stackoverflow.com/questions/36475254/polylines-outline-construction-drawing-thick-polylines
|
||||
- https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader
|
||||
- https://stackoverflow.com/questions/687173/how-do-i-render-thick-2d-lines-as-polygons
|
||||
|
@ -47,7 +47,7 @@ impl SandboxMode {
|
||||
(hotkey(Key::Y), "load previous sim state"),
|
||||
(hotkey(Key::U), "load next sim state"),
|
||||
(hotkey(Key::X), "reset sim"),
|
||||
(hotkey(Key::S), "seed the sim with agents"),
|
||||
(hotkey(Key::S), "start a scenario"),
|
||||
],
|
||||
vec![
|
||||
// TODO Strange to always have this. Really it's a case of stacked modal?
|
||||
@ -96,8 +96,8 @@ impl State for SandboxMode {
|
||||
return t;
|
||||
}
|
||||
|
||||
if let Some(spawner) = spawner::AgentSpawner::new(ctx, ui, &mut self.menu) {
|
||||
return Transition::Push(Box::new(spawner));
|
||||
if let Some(new_state) = spawner::AgentSpawner::new(ctx, ui, &mut self.menu) {
|
||||
return Transition::Push(new_state);
|
||||
}
|
||||
if let Some(explorer) = RouteExplorer::new(ctx, ui) {
|
||||
return Transition::Push(Box::new(explorer));
|
||||
|
@ -4,10 +4,11 @@ use crate::helpers::ID;
|
||||
use crate::render::DrawOptions;
|
||||
use crate::ui::{ShowEverything, UI};
|
||||
use abstutil::Timer;
|
||||
use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu};
|
||||
use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard};
|
||||
use geom::{Duration, PolyLine};
|
||||
use map_model::{
|
||||
BuildingID, IntersectionID, IntersectionType, LaneType, PathRequest, Position, LANE_THICKNESS,
|
||||
BuildingID, IntersectionID, IntersectionType, LaneType, Map, PathRequest, Position,
|
||||
LANE_THICKNESS,
|
||||
};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::Rng;
|
||||
@ -38,7 +39,7 @@ impl AgentSpawner {
|
||||
ctx: &mut EventCtx,
|
||||
ui: &mut UI,
|
||||
sandbox_menu: &mut ModalMenu,
|
||||
) -> Option<AgentSpawner> {
|
||||
) -> Option<Box<State>> {
|
||||
let menu = ModalMenu::new(
|
||||
"Agent Spawner",
|
||||
vec![vec![(hotkey(Key::Escape), "quit")]],
|
||||
@ -51,22 +52,22 @@ impl AgentSpawner {
|
||||
.input
|
||||
.contextual_action(Key::F3, "spawn a pedestrian starting here")
|
||||
{
|
||||
return Some(AgentSpawner {
|
||||
return Some(Box::new(AgentSpawner {
|
||||
menu,
|
||||
from: Source::Walking(id),
|
||||
maybe_goal: None,
|
||||
});
|
||||
}));
|
||||
}
|
||||
if let Some(pos) = Position::bldg_via_driving(id, map) {
|
||||
if ctx
|
||||
.input
|
||||
.contextual_action(Key::F4, "spawn a car starting here")
|
||||
{
|
||||
return Some(AgentSpawner {
|
||||
return Some(Box::new(AgentSpawner {
|
||||
menu,
|
||||
from: Source::Driving(pos),
|
||||
maybe_goal: None,
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,11 +77,11 @@ impl AgentSpawner {
|
||||
.input
|
||||
.contextual_action(Key::F3, "spawn an agent starting here")
|
||||
{
|
||||
return Some(AgentSpawner {
|
||||
return Some(Box::new(AgentSpawner {
|
||||
menu,
|
||||
from: Source::Driving(Position::new(id, map.get_l(id).length() / 2.0)),
|
||||
maybe_goal: None,
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
Some(ID::Intersection(i)) => {
|
||||
@ -92,25 +93,10 @@ impl AgentSpawner {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if ui.primary.sim.is_empty() {
|
||||
if sandbox_menu.action("seed the sim with agents") {
|
||||
// TODO This covers up the map. :\
|
||||
ctx.loading_screen("seed sim with agents", |_, timer| {
|
||||
let map = &ui.primary.map;
|
||||
let s = if let Some(n) = ui.primary.current_flags.num_agents {
|
||||
Scenario::scaled_run(map, n)
|
||||
} else {
|
||||
Scenario::small_run(map)
|
||||
};
|
||||
s.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
map,
|
||||
&mut ui.primary.current_flags.sim_flags.make_rng(),
|
||||
timer,
|
||||
);
|
||||
ui.primary.sim.step(map, SMALL_DT);
|
||||
});
|
||||
}
|
||||
if ui.primary.sim.is_empty() && sandbox_menu.action("start a scenario") {
|
||||
return Some(Box::new(InstantiateScenario {
|
||||
wizard: Wizard::new(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -371,3 +357,75 @@ fn spawn_agents_around(i: IntersectionID, ui: &mut UI, ctx: &EventCtx) {
|
||||
sim.step(map, SMALL_DT);
|
||||
ui.recalculate_current_selection(ctx);
|
||||
}
|
||||
|
||||
// TODO Dedupe with code from mission/mod.rs.
|
||||
struct InstantiateScenario {
|
||||
wizard: Wizard,
|
||||
}
|
||||
|
||||
impl State for InstantiateScenario {
|
||||
fn event(&mut self, ctx: &mut EventCtx, ui: &mut UI) -> Transition {
|
||||
if let Some(scenario) = pick_scenario(
|
||||
ui.primary.current_flags.num_agents,
|
||||
&ui.primary.map,
|
||||
&mut self.wizard.wrap(ctx),
|
||||
) {
|
||||
ctx.loading_screen("instantiate scenario", |_, timer| {
|
||||
scenario.instantiate(
|
||||
&mut ui.primary.sim,
|
||||
&ui.primary.map,
|
||||
&mut ui.primary.current_flags.sim_flags.make_rng(),
|
||||
timer,
|
||||
);
|
||||
ui.primary.sim.step(&ui.primary.map, SMALL_DT);
|
||||
});
|
||||
return Transition::Pop;
|
||||
} else if self.wizard.aborted() {
|
||||
return Transition::Pop;
|
||||
}
|
||||
Transition::Keep
|
||||
}
|
||||
|
||||
fn draw(&self, g: &mut GfxCtx, _: &UI) {
|
||||
self.wizard.draw(g);
|
||||
}
|
||||
}
|
||||
|
||||
fn pick_scenario(
|
||||
num_agents: Option<usize>,
|
||||
map: &Map,
|
||||
wizard: &mut WrappedWizard,
|
||||
) -> Option<Scenario> {
|
||||
let builtin = if let Some(n) = num_agents {
|
||||
format!("random scenario with {} agents", n)
|
||||
} else {
|
||||
"random scenario with some agents".to_string()
|
||||
};
|
||||
let map_name = map.get_name().to_string();
|
||||
let (_, scenario_name) = wizard.choose_something_no_keys::<String>(
|
||||
"Instantiate which scenario?",
|
||||
Box::new(move || {
|
||||
let mut list = vec![
|
||||
(builtin.clone(), "builtin".to_string()),
|
||||
("just buses".to_string(), "just buses".to_string()),
|
||||
];
|
||||
list.extend(abstutil::list_all_objects("scenarios", &map_name));
|
||||
list
|
||||
}),
|
||||
)?;
|
||||
Some(if scenario_name == "builtin" {
|
||||
if let Some(n) = num_agents {
|
||||
Scenario::scaled_run(map, n)
|
||||
} else {
|
||||
Scenario::small_run(map)
|
||||
}
|
||||
} else if scenario_name == "just buses" {
|
||||
Scenario::empty(map)
|
||||
} else {
|
||||
abstutil::read_binary(
|
||||
&format!("../data/scenarios/{}/{}.bin", map.get_name(), scenario_name),
|
||||
&mut Timer::throwaway(),
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
|
@ -249,6 +249,18 @@ impl Scenario {
|
||||
s
|
||||
}
|
||||
|
||||
// Just buses.
|
||||
pub fn empty(map: &Map) -> Scenario {
|
||||
Scenario {
|
||||
scenario_name: "just buses".to_string(),
|
||||
map_name: map.get_name().to_string(),
|
||||
seed_parked_cars: Vec::new(),
|
||||
spawn_over_time: Vec::new(),
|
||||
border_spawn_over_time: Vec::new(),
|
||||
individ_trips: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// No border agents here, because making the count work is hard.
|
||||
pub fn scaled_run(map: &Map, num_agents: usize) -> Scenario {
|
||||
Scenario {
|
||||
|
Loading…
Reference in New Issue
Block a user