Add dynamic fetching of tiles

This commit is contained in:
Maximilian Ammann 2022-01-21 15:48:05 +01:00
parent a8c62af787
commit 361283225a
4 changed files with 59 additions and 15 deletions

View File

@ -4,7 +4,7 @@ pub const MUNICH_X: u32 = 17425;
pub const MUNICH_Y: u32 = 11365; pub const MUNICH_Y: u32 = 11365;
pub const MUNICH_Z: u8 = 15; pub const MUNICH_Z: u8 = 15;
pub fn fetch_munich_tiles(worker_loop: &WorkerLoop) { pub fn fetch_munich_tiles(worker_loop: &mut WorkerLoop) {
// This size matches the amount of tiles which are loaded on zoom 15 on FHD // This size matches the amount of tiles which are loaded on zoom 15 on FHD
for x in 0..8 { for x in 0..8 {
for y in 0..5 { for y in 0..5 {

View File

@ -1,4 +1,4 @@
use std::collections::VecDeque; use std::collections::{HashSet, VecDeque};
use std::sync::{Arc, Condvar, Mutex}; use std::sync::{Arc, Condvar, Mutex};
@ -22,6 +22,7 @@ pub struct TesselatedLayer {
#[derive(Clone)] #[derive(Clone)]
pub struct WorkerLoop { pub struct WorkerLoop {
loaded_coords: Arc<Mutex<HashSet<TileCoords>>>,
requests: Arc<WorkQueue<TileCoords>>, requests: Arc<WorkQueue<TileCoords>>,
responses: Arc<WorkQueue<TesselatedLayer>>, responses: Arc<WorkQueue<TesselatedLayer>>,
} }
@ -35,14 +36,28 @@ impl Drop for WorkerLoop {
impl WorkerLoop { impl WorkerLoop {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
loaded_coords: Arc::new(Mutex::new(HashSet::new())),
requests: Arc::new(WorkQueue::new()), requests: Arc::new(WorkQueue::new()),
responses: Arc::new(WorkQueue::new()), responses: Arc::new(WorkQueue::new()),
} }
} }
pub fn fetch(&self, coords: TileCoords) { pub fn is_loaded(&self, coords: &TileCoords) -> bool {
info!("new tile request: {:?}", &coords); if let Ok(loaded_coords) = self.loaded_coords.lock() {
self.requests.push(coords); loaded_coords.contains(coords)
} else {
false
}
}
pub fn fetch(&mut self, coords: TileCoords) {
if let Ok(mut loaded_coords) = self.loaded_coords.lock() {
if loaded_coords.contains(&coords) {
return;
}
loaded_coords.insert(coords);
info!("new tile request: {:?}", &coords);
self.requests.push(coords);
}
} }
pub fn pop_all(&self) -> Vec<TesselatedLayer> { pub fn pop_all(&self) -> Vec<TesselatedLayer> {

View File

@ -11,12 +11,12 @@ use crate::render::render_state::RenderState;
pub async fn setup( pub async fn setup(
window: winit::window::Window, window: winit::window::Window,
event_loop: EventLoop<()>, event_loop: EventLoop<()>,
worker_loop: Box<WorkerLoop>, mut worker_loop: Box<WorkerLoop>,
) { ) {
info!("== mapr =="); info!("== mapr ==");
fetch_munich_tiles(worker_loop.as_ref()); /* fetch_munich_tiles(worker_loop.as_ref());
*/
let mut input = InputController::new(0.2, 100.0); let mut input = InputController::new(0.2, 100.0);
let mut maybe_state: Option<RenderState> = if cfg!(target_os = "android") { let mut maybe_state: Option<RenderState> = if cfg!(target_os = "android") {
None None
@ -84,7 +84,7 @@ pub async fn setup(
let dt = now - last_render_time; let dt = now - last_render_time;
last_render_time = now; last_render_time = now;
input.update_state(state, dt); input.update_state(state, dt);
state.upload_tile_geometry(&worker_loop); state.upload_tile_geometry(&mut worker_loop);
match state.render() { match state.render() {
Ok(_) => {} Ok(_) => {}
Err(wgpu::SurfaceError::Lost) => { Err(wgpu::SurfaceError::Lost) => {

View File

@ -1,6 +1,8 @@
use cgmath::{Point3, Vector3};
use std::default::Default; use std::default::Default;
use std::{cmp, iter}; use std::{cmp, iter};
use crate::coords::{TileCoords, WorldCoords, WorldTileCoords};
use wgpu::{Buffer, Limits, Queue}; use wgpu::{Buffer, Limits, Queue};
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use winit::window::Window; use winit::window::Window;
@ -347,9 +349,27 @@ impl RenderState {
// TODO: Could we draw inspiration from StagingBelt (https://docs.rs/wgpu/latest/wgpu/util/struct.StagingBelt.html)? // TODO: Could we draw inspiration from StagingBelt (https://docs.rs/wgpu/latest/wgpu/util/struct.StagingBelt.html)?
// TODO: What is StagingBelt for? // TODO: What is StagingBelt for?
pub fn upload_tile_geometry(&mut self, worker_loop: &WorkerLoop) { pub fn upload_tile_geometry(&mut self, worker_loop: &mut WorkerLoop) {
println!("1: {:?}", self.camera.view_bounding_box(&self.perspective)); if let Some(view_box) = self.camera.view_bounding_box(&self.perspective) {
println!("2: {:?}", self.camera.view_bounding_box2(&self.perspective)); /*let view_box = self.camera.view_bounding_box2(&self.perspective).unwrap();*/
let min_world: WorldCoords = Point3::new(view_box.min.x, view_box.min.y, 15.0).into();
let min_world_tile: WorldTileCoords = min_world.into();
let min_tile: TileCoords = min_world_tile.into();
let max_world: WorldCoords = Point3::new(view_box.max.x, view_box.max.y, 15.0).into();
let max_world_tile: WorldTileCoords = max_world.into();
let max_tile: TileCoords = max_world_tile.into();
for x in min_tile.x..max_tile.x + 1 {
for y in min_tile.y..max_tile.y + 1 {
let to_be_fetched = (x, y, 15).into();
if !worker_loop.is_loaded(&to_be_fetched) {
// FIXME: is_loaded is not correct right now
worker_loop.fetch(to_be_fetched);
}
}
}
}
let upload = worker_loop.pop_all(); let upload = worker_loop.pop_all();
@ -468,9 +488,18 @@ impl RenderState {
{ {
// Draw masks // Draw masks
pass.set_pipeline(&self.mask_pipeline); pass.set_pipeline(&self.mask_pipeline);
pass.set_vertex_buffer(0, self.tile_mask_instances_buffer.slice(..)); let masks = self.tile_mask_pattern.as_slice();
// Draw 7 squares each out of 6 vertices if !masks.is_empty() {
pass.draw(0..6, 0..self.tile_mask_pattern.instances()); pass.set_vertex_buffer(
0,
self.tile_mask_instances_buffer.slice(
0..masks.len() as u64
* std::mem::size_of::<ShaderTileMaskInstance>() as u64,
),
);
// Draw 7 squares each out of 6 vertices
pass.draw(0..6, 0..self.tile_mask_pattern.instances());
}
} }
{ {
for entry in self.buffer_pool.available_vertices() { for entry in self.buffer_pool.available_vertices() {