mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 11:44:25 +03:00
caching Renderables for agents
This commit is contained in:
parent
ff80d0d445
commit
bc4ba647bc
@ -3,7 +3,8 @@
|
|||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
- cache draw stuff
|
- cache draw stuff
|
||||||
- carefully. dont upload unbounded stuff to GPU in time travel.
|
- use a Drawable in DrawPed/DrawCar/DrawBike.
|
||||||
|
- fix the process_objects callback nonsense
|
||||||
|
|
||||||
## Quick n easy
|
## Quick n easy
|
||||||
|
|
||||||
|
@ -98,6 +98,10 @@ impl TimeTravel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GetDrawAgents for TimeTravel {
|
impl GetDrawAgents for TimeTravel {
|
||||||
|
fn tick(&self) -> Tick {
|
||||||
|
self.current_tick.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_draw_car(&self, id: CarID, _map: &Map) -> Option<DrawCarInput> {
|
fn get_draw_car(&self, id: CarID, _map: &Map) -> Option<DrawCarInput> {
|
||||||
self.get_current_state().cars.get(&id).cloned()
|
self.get_current_state().cars.get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@ use map_model::{
|
|||||||
AreaID, BuildingID, BusStopID, FindClosest, IntersectionID, Lane, LaneID, Map, ParcelID,
|
AreaID, BuildingID, BusStopID, FindClosest, IntersectionID, Lane, LaneID, Map, ParcelID,
|
||||||
RoadID, Traversable, Turn, TurnID, LANE_THICKNESS,
|
RoadID, Traversable, Turn, TurnID, LANE_THICKNESS,
|
||||||
};
|
};
|
||||||
use sim::GetDrawAgents;
|
use sim::{GetDrawAgents, Tick};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
@ -39,6 +40,8 @@ pub struct DrawMap {
|
|||||||
pub bus_stops: HashMap<BusStopID, DrawBusStop>,
|
pub bus_stops: HashMap<BusStopID, DrawBusStop>,
|
||||||
pub areas: Vec<DrawArea>,
|
pub areas: Vec<DrawArea>,
|
||||||
|
|
||||||
|
agents: RefCell<AgentCache>,
|
||||||
|
|
||||||
quadtree: QuadTree<ID>,
|
quadtree: QuadTree<ID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +174,11 @@ impl DrawMap {
|
|||||||
bus_stops,
|
bus_stops,
|
||||||
areas,
|
areas,
|
||||||
|
|
||||||
|
agents: RefCell::new(AgentCache {
|
||||||
|
tick: None,
|
||||||
|
agents_per_on: HashMap::new(),
|
||||||
|
}),
|
||||||
|
|
||||||
quadtree,
|
quadtree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,9 +290,8 @@ impl DrawMap {
|
|||||||
let mut extra_shapes: Vec<Box<&Renderable>> = Vec::new();
|
let mut extra_shapes: Vec<Box<&Renderable>> = Vec::new();
|
||||||
let mut bus_stops: Vec<Box<&Renderable>> = Vec::new();
|
let mut bus_stops: Vec<Box<&Renderable>> = Vec::new();
|
||||||
let mut turn_icons: Vec<Box<&Renderable>> = Vec::new();
|
let mut turn_icons: Vec<Box<&Renderable>> = Vec::new();
|
||||||
|
// We can't immediately grab the Renderables; we need to do it all at once at the end.
|
||||||
let mut cars: Vec<Box<Renderable>> = Vec::new();
|
let mut agents_on: Vec<Traversable> = Vec::new();
|
||||||
let mut peds: Vec<Box<Renderable>> = Vec::new();
|
|
||||||
|
|
||||||
for &(id, _, _) in &self.quadtree.query(screen_bounds.as_bbox()) {
|
for &(id, _, _) in &self.quadtree.query(screen_bounds.as_bbox()) {
|
||||||
if show_objs.show(*id) {
|
if show_objs.show(*id) {
|
||||||
@ -294,12 +301,18 @@ impl DrawMap {
|
|||||||
ID::Lane(id) => {
|
ID::Lane(id) => {
|
||||||
lanes.push(Box::new(self.get_l(*id)));
|
lanes.push(Box::new(self.get_l(*id)));
|
||||||
if !show_objs.show_icons_for(map.get_l(*id).dst_i) {
|
if !show_objs.show_icons_for(map.get_l(*id).dst_i) {
|
||||||
for c in sim.get_draw_cars(Traversable::Lane(*id), map).into_iter() {
|
let on = Traversable::Lane(*id);
|
||||||
cars.push(draw_vehicle(c, map));
|
if !self.agents.borrow().has(sim.tick(), on) {
|
||||||
}
|
let mut list: Vec<Box<Renderable>> = Vec::new();
|
||||||
for p in sim.get_draw_peds(Traversable::Lane(*id), map).into_iter() {
|
for c in sim.get_draw_cars(on, map).into_iter() {
|
||||||
peds.push(Box::new(DrawPedestrian::new(p, map)));
|
list.push(draw_vehicle(c, map));
|
||||||
|
}
|
||||||
|
for p in sim.get_draw_peds(on, map).into_iter() {
|
||||||
|
list.push(Box::new(DrawPedestrian::new(p, map)));
|
||||||
|
}
|
||||||
|
self.agents.borrow_mut().put(sim.tick(), on, list);
|
||||||
}
|
}
|
||||||
|
agents_on.push(on);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ID::Intersection(id) => {
|
ID::Intersection(id) => {
|
||||||
@ -308,12 +321,18 @@ impl DrawMap {
|
|||||||
if show_objs.show_icons_for(*id) {
|
if show_objs.show_icons_for(*id) {
|
||||||
turn_icons.push(Box::new(self.get_t(*t)));
|
turn_icons.push(Box::new(self.get_t(*t)));
|
||||||
} else {
|
} else {
|
||||||
for c in sim.get_draw_cars(Traversable::Turn(*t), map).into_iter() {
|
let on = Traversable::Turn(*t);
|
||||||
cars.push(draw_vehicle(c, map));
|
if !self.agents.borrow().has(sim.tick(), on) {
|
||||||
}
|
let mut list: Vec<Box<Renderable>> = Vec::new();
|
||||||
for p in sim.get_draw_peds(Traversable::Turn(*t), map).into_iter() {
|
for c in sim.get_draw_cars(on, map).into_iter() {
|
||||||
peds.push(Box::new(DrawPedestrian::new(p, map)));
|
list.push(draw_vehicle(c, map));
|
||||||
|
}
|
||||||
|
for p in sim.get_draw_peds(on, map).into_iter() {
|
||||||
|
list.push(Box::new(DrawPedestrian::new(p, map)));
|
||||||
|
}
|
||||||
|
self.agents.borrow_mut().put(sim.tick(), on, list);
|
||||||
}
|
}
|
||||||
|
agents_on.push(on);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,11 +359,11 @@ impl DrawMap {
|
|||||||
borrows.extend(extra_shapes);
|
borrows.extend(extra_shapes);
|
||||||
borrows.extend(bus_stops);
|
borrows.extend(bus_stops);
|
||||||
borrows.extend(turn_icons);
|
borrows.extend(turn_icons);
|
||||||
for c in &cars {
|
let cache = self.agents.borrow();
|
||||||
borrows.push(Box::new(c.borrow()));
|
for on in agents_on {
|
||||||
}
|
for obj in cache.get(on) {
|
||||||
for p in &peds {
|
borrows.push(obj);
|
||||||
borrows.push(Box::new(p.borrow()));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a stable sort.
|
// This is a stable sort.
|
||||||
@ -361,3 +380,35 @@ impl DrawMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AgentCache {
|
||||||
|
tick: Option<Tick>,
|
||||||
|
agents_per_on: HashMap<Traversable, Vec<Box<Renderable>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AgentCache {
|
||||||
|
fn has(&self, tick: Tick, on: Traversable) -> bool {
|
||||||
|
if Some(tick) != self.tick {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.agents_per_on.contains_key(&on)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must call has() first.
|
||||||
|
fn get(&self, on: Traversable) -> Vec<Box<&Renderable>> {
|
||||||
|
self.agents_per_on[&on]
|
||||||
|
.iter()
|
||||||
|
.map(|obj| Box::new(obj.borrow()))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put(&mut self, tick: Tick, on: Traversable, agents: Vec<Box<Renderable>>) {
|
||||||
|
if Some(tick) != self.tick {
|
||||||
|
self.agents_per_on.clear();
|
||||||
|
self.tick = Some(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(!self.agents_per_on.contains_key(&on));
|
||||||
|
self.agents_per_on.insert(on, agents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{CarID, PedestrianID, Sim, VehicleType};
|
use crate::{CarID, PedestrianID, Sim, Tick, VehicleType};
|
||||||
use geom::{PolyLine, Pt2D};
|
use geom::{PolyLine, Pt2D};
|
||||||
use map_model::{LaneType, Map, Trace, Traversable, TurnID};
|
use map_model::{LaneType, Map, Trace, Traversable, TurnID};
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ pub enum CarState {
|
|||||||
// actually good for main sim too; we're constantly calculating stuff while sim is paused
|
// actually good for main sim too; we're constantly calculating stuff while sim is paused
|
||||||
// otherwise? except we don't know what to calculate. maybe cache it?
|
// otherwise? except we don't know what to calculate. maybe cache it?
|
||||||
pub trait GetDrawAgents {
|
pub trait GetDrawAgents {
|
||||||
|
fn tick(&self) -> Tick;
|
||||||
fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput>;
|
fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput>;
|
||||||
fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput>;
|
fn get_draw_ped(&self, id: PedestrianID, map: &Map) -> Option<DrawPedestrianInput>;
|
||||||
fn get_draw_cars(&self, on: Traversable, map: &Map) -> Vec<DrawCarInput>;
|
fn get_draw_cars(&self, on: Traversable, map: &Map) -> Vec<DrawCarInput>;
|
||||||
@ -46,6 +47,10 @@ pub trait GetDrawAgents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GetDrawAgents for Sim {
|
impl GetDrawAgents for Sim {
|
||||||
|
fn tick(&self) -> Tick {
|
||||||
|
self.time
|
||||||
|
}
|
||||||
|
|
||||||
fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput> {
|
fn get_draw_car(&self, id: CarID, map: &Map) -> Option<DrawCarInput> {
|
||||||
self.driving_state
|
self.driving_state
|
||||||
.get_draw_car(id, self.time, map)
|
.get_draw_car(id, self.time, map)
|
||||||
|
Loading…
Reference in New Issue
Block a user