Skip to content

Commit ffe81e6

Browse files
committed
fix panning
1 parent dbf845d commit ffe81e6

8 files changed

Lines changed: 104 additions & 56 deletions

File tree

src/bin/app_state.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ impl AppState {
4040
.expect("Unable to load the style file. Please consult the log."),
4141
screen: Screen::new(
4242
center,
43-
size.width,
44-
size.height,
45-
CONFIG.renderer.tile_size,
46-
hidpi_factor,
43+
size.width as f32,
44+
size.height as f32,
45+
CONFIG.renderer.tile_size as f32,
46+
hidpi_factor as f32,
4747
),
4848
zoom,
4949
hovered_objects: Arc::new(Mutex::new(Vec::new())),
@@ -216,7 +216,7 @@ impl AppState {
216216
self.screen.center = tile_to_world_space(&tile_coordinate);
217217
}
218218

219-
pub(crate) fn scale_factor_updated(&mut self, scale_factor: f64) {
219+
pub(crate) fn scale_factor_updated(&mut self, scale_factor: f32) {
220220
self.screen = Screen::new(
221221
self.screen.center,
222222
self.screen.width,

src/bin/drawing/painter.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ impl Painter {
428428
let mut i = 0;
429429
for vt in visible_tiles {
430430
let extent = vt.extent() as f32;
431-
let matrix = screen.tile_to_global_space(z, &vt.tile_id());
431+
let matrix = screen.tile_to_screen(z, &vt.tile_id());
432432
for float in matrix.as_slice() {
433433
data[i] = *float;
434434
i += 1;
@@ -741,9 +741,7 @@ impl Painter {
741741
) / 2.0;
742742

743743
for (i, tile_id) in app_state.visible_tiles().iter().enumerate() {
744-
let matrix = app_state
745-
.screen
746-
.tile_to_global_space(app_state.zoom, tile_id);
744+
let matrix = app_state.screen.tile_to_screen(app_state.zoom, tile_id);
747745
let start = (matrix * vec).xy() + vec2(1.0, 1.0);
748746
let s = vec2(
749747
(start.x * screen_dimensions.x)
@@ -755,7 +753,7 @@ impl Painter {
755753
.max(0.0)
756754
.min(screen_dimensions.y * 2.0),
757755
);
758-
let matrix = app_state.screen.tile_to_global_space(
756+
let matrix = app_state.screen.tile_to_screen(
759757
app_state.zoom,
760758
&(*tile_id + TileId::new(tile_id.z, 1, 1)),
761759
);

src/bin/drawing/ui/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ pub mod state;
22
pub mod views;
33
pub mod widgets;
44

5-
use std::fmt::format;
65
use std::sync::Arc;
76

87
use egui::color_picker::Alpha;

src/bin/main.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use std::sync::Arc;
77

88
use crate::config::CONFIG;
99
use clap::Parser;
10-
use lyon::math::vector;
10+
use lyon::{
11+
geom::euclid::{self, point2},
12+
math::vector,
13+
};
14+
use nalgebra_glm::{vec2, vec3, vec4, Mat4};
1115
use osm::math::{deg2num, tile_to_world_space, TileId};
1216
use winit::{
1317
application::ApplicationHandler,
@@ -83,8 +87,8 @@ fn main() {
8387
.hud
8488
.platform
8589
.handle_event(&winit::event::WindowEvent::Resized(PhysicalSize::new(
86-
screen.width,
87-
screen.height,
90+
screen.width as u32,
91+
screen.height as u32,
8892
)));
8993

9094
event_loop.run_app(&mut application).unwrap();
@@ -115,13 +119,15 @@ impl ApplicationHandler for Application {
115119
match event {
116120
WindowEvent::Destroyed => event_loop.exit(),
117121
WindowEvent::Resized(physical_size) => {
118-
self.app_state.screen.width = physical_size.width.min(8192);
119-
self.app_state.screen.height = physical_size.height.min(8192);
120-
self.painter
121-
.resize(self.app_state.screen.width, self.app_state.screen.height);
122+
self.app_state.screen.width = physical_size.width.min(8192) as f32;
123+
self.app_state.screen.height = physical_size.height.min(8192) as f32;
124+
self.painter.resize(
125+
self.app_state.screen.width as u32,
126+
self.app_state.screen.height as u32,
127+
);
122128
}
123129
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
124-
self.app_state.scale_factor_updated(scale_factor)
130+
self.app_state.scale_factor_updated(scale_factor as f32)
125131
}
126132
WindowEvent::KeyboardInput {
127133
event:
@@ -174,30 +180,25 @@ impl ApplicationHandler for Application {
174180
}
175181
}
176182
WindowEvent::CursorMoved { position, .. } => {
177-
let logical_position = position.to_logical(self.painter.get_hidpi_factor());
178-
let size = self.app_state.screen.tile_size() as f32;
179-
let mut delta = vector(
180-
(logical_position.x - self.last_pos.x) as f32,
181-
(logical_position.y - self.last_pos.y) as f32,
182-
);
183-
let zoom_x = (self.app_state.screen.width as f32)
184-
/ size
185-
/ 2f32.powf(self.app_state.zoom)
186-
/ size
187-
/ 1.13;
188-
let zoom_y = (self.app_state.screen.height as f32)
189-
/ size
190-
/ 2f32.powf(self.app_state.zoom)
191-
/ size
192-
/ 1.13;
193-
delta.x *= zoom_x;
194-
delta.y *= zoom_y;
183+
let logical_position = position.to_logical(self.painter.get_hidpi_factor() / 2.0);
184+
185+
let screen_to_global = self.app_state.screen.screen_to_world(self.app_state.zoom);
186+
let new_pos = screen_to_global
187+
* vec4(
188+
logical_position.x as f32,
189+
logical_position.y as f32,
190+
0.0,
191+
0.0,
192+
);
193+
let old_pos = screen_to_global
194+
* vec4(self.last_pos.x as f32, self.last_pos.y as f32, 0.0, 0.0);
195+
let delta_new = new_pos - old_pos;
195196

196197
self.last_pos = logical_position;
197198

198199
if !ui_event {
199200
if self.mouse_down {
200-
self.app_state.screen.center -= delta;
201+
self.app_state.screen.center -= euclid::vec2(delta_new.x, delta_new.y);
201202
}
202203

203204
self.app_state.update_hovered_objects((
@@ -210,8 +211,8 @@ impl ApplicationHandler for Application {
210211
self.hud
211212
.platform
212213
.handle_event(&winit::event::WindowEvent::Resized(PhysicalSize::new(
213-
self.app_state.screen.width,
214-
self.app_state.screen.height,
214+
self.app_state.screen.width as u32,
215+
self.app_state.screen.height as u32,
215216
)));
216217
if !event_loop.exiting() {
217218
self.painter.update_shader();

src/lib/interaction/collider.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ use super::tile_collider::TileCollider;
1515
pub struct Collider {}
1616

1717
impl Collider {
18+
/// Get the hovered objects
19+
///
20+
/// * point: The pointer in logical coordinates (divided by DPI ratio)
1821
pub fn get_hovered_objects(
1922
visible_tiles: &[VisibleTile],
2023
screen: &Screen,
@@ -30,11 +33,12 @@ impl Collider {
3033
objects,
3134
} in visible_tiles
3235
{
33-
let matrix = screen.tile_to_global_space(zoom, tile_id);
36+
let matrix = screen.tile_to_screen(zoom, tile_id);
3437
let matrix = nalgebra_glm::inverse(&matrix);
38+
// The point in GPU coordinates.
3539
let screen_point = Point::new(
36-
point.0 / (screen.width / 2) as f32 - 1.0,
37-
point.1 / (screen.height / 2) as f32 - 1.0,
40+
point.0 / (screen.width / 2f32) - 1.0,
41+
point.1 / (screen.height / 2f32) - 1.0,
3842
);
3943
let global_point = matrix * Vector4::new(screen_point.x, screen_point.y, 0.0, 1.0);
4044
let tile_point = Point::new(global_point.x, global_point.y) * *extent;

src/lib/math/screen.rs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,31 @@ use nalgebra_glm as glm;
44
#[derive(Debug, Clone)]
55
pub struct Screen {
66
pub center: Point,
7-
pub width: u32,
8-
pub height: u32,
9-
tile_size: u32,
7+
pub width: f32,
8+
pub height: f32,
9+
tile_size: f32,
1010
}
1111

1212
impl Screen {
13-
pub fn new(center: Point, width: u32, height: u32, tile_size: u32, hidpi_factor: f64) -> Self {
13+
pub fn new(center: Point, width: f32, height: f32, tile_size: f32, hidpi_factor: f32) -> Self {
1414
Self {
1515
center,
1616
width,
1717
height,
18-
tile_size: (tile_size as f64 * hidpi_factor) as u32,
18+
tile_size: tile_size * hidpi_factor,
1919
}
2020
}
2121

22-
pub fn tile_size(&self) -> u32 {
22+
pub fn tile_size(&self) -> f32 {
2323
self.tile_size
2424
}
2525

2626
pub fn get_tile_boundaries_for_zoom_level(&self, z: f32, scale: u32) -> TileField {
2727
let z = z.min(14.0);
2828
let px_to_world =
29-
self.width as f32 / self.tile_size() as f32 / 2.0 / 2f32.powi(z as i32) / scale as f32;
29+
self.width as f32 / self.tile_size() / 2.0 / 2f32.powi(z as i32) / scale as f32;
3030
let py_to_world =
31-
self.height as f32 / self.tile_size() as f32 / 2.0 / 2f32.powi(z as i32) / scale as f32;
31+
self.height as f32 / self.tile_size() / 2.0 / 2f32.powi(z as i32) / scale as f32;
3232

3333
let top_left: TileId =
3434
world_to_tile_space(&(self.center - vector(px_to_world, py_to_world)), z as u32).into();
@@ -37,18 +37,64 @@ impl Screen {
3737
TileField::new(top_left, bottom_right + TileId::new(z as u32, 1, 0))
3838
}
3939

40-
pub fn tile_to_global_space(&self, z: f32, coordinate: &TileId) -> glm::TMat4<f32> {
40+
pub fn tile_to_screen(&self, z: f32, coordinate: &TileId) -> glm::TMat4<f32> {
4141
let zoom = 1.0 / 2f32.powi(coordinate.z as i32);
4242
let zoom = glm::scaling(&glm::vec3(zoom, zoom, 1.0));
4343
let pos = glm::translation(&glm::vec3(coordinate.x as f32, coordinate.y as f32, 0.0));
4444
self.global_to_screen(z) * zoom * pos
4545
}
4646

4747
pub fn global_to_screen(&self, z: f32) -> glm::TMat4<f32> {
48-
let zoom_x = 2.0f32.powf(z) / (self.width as f32 / 2.0) * self.tile_size() as f32;
49-
let zoom_y = 2.0f32.powf(z) / (self.height as f32 / 2.0) * self.tile_size() as f32;
48+
let zoom_x = 2.0f32.powf(z) / (self.width as f32 / 2.0) * self.tile_size();
49+
let zoom_y = 2.0f32.powf(z) / (self.height as f32 / 2.0) * self.tile_size();
5050
let zoom = glm::scaling(&glm::vec3(zoom_x, zoom_y, 1.0));
5151
let position = glm::translation(&glm::vec3(-self.center.x, -self.center.y, 0.0));
5252
zoom * position
5353
}
54+
55+
pub fn screen_to_gpu(&self) -> glm::TMat4<f32> {
56+
let scale = glm::vec3(1.0, 1.0, 1.0).component_div(&glm::vec3(
57+
self.width / 2.0,
58+
self.height / 2.0,
59+
1.0,
60+
));
61+
glm::scaling(&scale)
62+
}
63+
64+
pub fn screen_to_world(&self, z: f32) -> glm::TMat4<f32> {
65+
// TODO: make logical width instead of phyiscal.
66+
glm::translation2d(&glm::vec2(dbg!(self.center.x), self.center.y))
67+
* glm::scaling2d(&glm::vec2(
68+
1.0 / 2.0 * f32::powf(2.0, -z) / self.tile_size(),
69+
1.0 / 2.0 * f32::powf(2.0, -z) / self.tile_size(),
70+
));
71+
72+
let matrix = self.global_to_screen(z);
73+
let screen_to_global = nalgebra_glm::inverse(&matrix);
74+
75+
let pixel_to_screen = glm::translation(&glm::vec3(-1.0, -1.0, 0.0))
76+
* glm::scaling(&glm::vec3(
77+
1.0 / (self.width / 2.0),
78+
1.0 / (self.height / 2.0),
79+
1.0,
80+
));
81+
82+
screen_to_global * pixel_to_screen
83+
}
84+
85+
pub fn global_to_tile_space(&self, z: f32, coordinate: &TileId) -> glm::TMat4<f32> {
86+
self.tile_to_screen(z, coordinate).try_inverse().unwrap()
87+
}
88+
89+
// pub fn screen_to_global(&self, z: f32) -> glm::TMat4<f32> {
90+
// // self.global_to_screen(z).try_inverse().unwrap()
91+
// let zoom_x = 2.0f32.powf(z) / (self.width / 2.0) * self.tile_size() * 2.0;
92+
// let zoom_y = 2.0f32.powf(z) / (self.height / 2.0) * self.tile_size() * 2.0;
93+
// let zoom = glm::scaling(&glm::vec3(zoom_x, zoom_y, 1.0));
94+
// (zoom).try_inverse().unwrap()
95+
96+
// glm::
97+
// }
98+
99+
// screen (px distorted) -> screen (square normalized coordinates) -> world (square coordinates) -> mercator lat lon
54100
}

src/lib/math/tile_field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'a> Iterator for TileIterator<'a> {
8181
#[test]
8282
fn get_tile_boundaries_for_8_zoom() {
8383
use super::*;
84-
let bb = Screen::new(point(47.607_372, 6.114297), 800, 800, 256, 1.0);
84+
let bb = Screen::new(point(47.607_372, 6.114297), 800f32, 800f32, 256f32, 1.0);
8585
let tile_field = bb.get_tile_boundaries_for_zoom_level(8.0, 1);
8686

8787
assert_eq!(tile_field.iter().count(), 20);

src/lib/vector_tile/tile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ impl Tile {
470470
screen: &'a Screen,
471471
z: f32,
472472
) -> impl Iterator<Item = TextArea<'a>> {
473-
let matrix = screen.tile_to_global_space(z, &self.tile_id());
473+
let matrix = screen.tile_to_screen(z, &self.tile_id());
474474
self.text
475475
.iter()
476476
.zip(self.text_buffers.iter())

0 commit comments

Comments
 (0)