mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Refactor coordinate system such that it is simpler
This commit is contained in:
parent
3a230010ca
commit
600a404516
@ -1,7 +1,15 @@
|
||||
//! File which exposes all kinds of coordinates used throughout mapr
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use crate::render::shader_ffi::Vec3f32;
|
||||
|
||||
/// Every tile has tile coordinates. These tile coordinates are also called
|
||||
/// [Slippy map tilenames](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames).
|
||||
///
|
||||
/// # Coordinate System Origin
|
||||
///
|
||||
/// For Web Mercator the origin of the coordinate system is in the upper-left corner.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct TileCoords {
|
||||
pub x: u32,
|
||||
@ -10,10 +18,12 @@ pub struct TileCoords {
|
||||
}
|
||||
|
||||
impl TileCoords {
|
||||
/// Transforms the tile coordinates as defined by the tile grid into a representation which is
|
||||
/// used in the 3d-world.
|
||||
pub fn into_world_tile(self) -> WorldTileCoords {
|
||||
WorldTileCoords {
|
||||
x: self.x as i32 - crate::example::MUNICH_X as i32,
|
||||
y: (self.y as i32 - crate::example::MUNICH_Y as i32 + 1) * -1,
|
||||
y: self.y as i32 - crate::example::MUNICH_Y as i32,
|
||||
z: 0,
|
||||
}
|
||||
}
|
||||
@ -35,6 +45,13 @@ impl From<(u32, u32, u8)> for TileCoords {
|
||||
}
|
||||
}
|
||||
|
||||
/// Every tile has tile coordinates. Every tile coordinate can be mapped to a coordinate within
|
||||
/// the world. This provides the freedom to map from [TMS](https://wiki.openstreetmap.org/wiki/TMS)
|
||||
/// to [Slippy_map_tilenames](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames).
|
||||
///
|
||||
/// # Coordinate System Origin
|
||||
///
|
||||
/// The origin of the coordinate system is in the upper-left corner.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct WorldTileCoords {
|
||||
pub x: i32,
|
||||
@ -46,7 +63,7 @@ impl WorldTileCoords {
|
||||
pub fn into_world(self, extent: f32) -> WorldCoords {
|
||||
WorldCoords {
|
||||
x: self.x as f32 * extent,
|
||||
y: self.y as f32 * extent + extent, // We add extent here as we want the upper left corner
|
||||
y: self.y as f32 * extent,
|
||||
z: self.z as f32,
|
||||
}
|
||||
}
|
||||
@ -54,7 +71,7 @@ impl WorldTileCoords {
|
||||
pub fn into_aligned(self) -> AlignedWorldTileCoords {
|
||||
AlignedWorldTileCoords(WorldTileCoords {
|
||||
x: self.x / 2 * 2,
|
||||
y: self.y / 2 * 2 - 1,
|
||||
y: self.y / 2 * 2,
|
||||
z: self.z,
|
||||
})
|
||||
}
|
||||
@ -76,6 +93,14 @@ impl From<(i32, i32, u8)> for WorldTileCoords {
|
||||
}
|
||||
}
|
||||
|
||||
/// An aligned world tile coordinate aligns a world coordinate at a 4x4 tile raster within the
|
||||
/// world. The aligned coordinates is defined by the coordinates of the upper left tile in the 4x4
|
||||
/// tile raster divided by 2 and rounding to the ceiling.
|
||||
///
|
||||
///
|
||||
/// # Coordinate System Origin
|
||||
///
|
||||
/// The origin of the coordinate system is in the upper-left corner.
|
||||
pub struct AlignedWorldTileCoords(pub WorldTileCoords);
|
||||
|
||||
impl AlignedWorldTileCoords {
|
||||
@ -83,15 +108,15 @@ impl AlignedWorldTileCoords {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn to_upper_right(&self) -> WorldTileCoords {
|
||||
pub fn upper_right(&self) -> WorldTileCoords {
|
||||
WorldTileCoords {
|
||||
x: self.0.x + 1,
|
||||
y: self.0.y + 1,
|
||||
y: self.0.y,
|
||||
z: self.0.z,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_lower_left(&self) -> WorldTileCoords {
|
||||
pub fn lower_left(&self) -> WorldTileCoords {
|
||||
WorldTileCoords {
|
||||
x: self.0.x,
|
||||
y: self.0.y - 1,
|
||||
@ -99,10 +124,10 @@ impl AlignedWorldTileCoords {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_lower_right(&self) -> WorldTileCoords {
|
||||
pub fn lower_right(&self) -> WorldTileCoords {
|
||||
WorldTileCoords {
|
||||
x: self.0.x - 1,
|
||||
y: self.0.y - 1,
|
||||
x: self.0.x + 1,
|
||||
y: self.0.y + 1,
|
||||
z: self.0.z,
|
||||
}
|
||||
}
|
||||
@ -115,6 +140,11 @@ pub struct WorldCoords {
|
||||
pub z: f32,
|
||||
}
|
||||
|
||||
/// Actual coordinates within the 3d world.
|
||||
///
|
||||
/// # Coordinate System Origin
|
||||
///
|
||||
/// The origin of the coordinate system is in the upper-left corner.
|
||||
impl WorldCoords {
|
||||
pub fn into_shader_coords(self) -> Vec3f32 {
|
||||
[self.x, self.y, self.z]
|
||||
|
||||
@ -11,6 +11,14 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f64> = cgmath::Matrix4::new(
|
||||
0.0, 0.0, 0.5, 1.0,
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const FLIP_Y: cgmath::Matrix4<f64> = cgmath::Matrix4::new(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Camera {
|
||||
pub position: cgmath::Point3<f64>,
|
||||
@ -35,7 +43,7 @@ impl Camera {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calc_matrix(&self) -> cgmath::Matrix4<f64> {
|
||||
fn calc_matrix(&self) -> cgmath::Matrix4<f64> {
|
||||
cgmath::Matrix4::look_to_rh(
|
||||
self.position,
|
||||
cgmath::Vector3::new(self.yaw.0.cos(), self.pitch.0.sin(), self.yaw.0.sin())
|
||||
@ -45,7 +53,7 @@ impl Camera {
|
||||
}
|
||||
|
||||
pub fn calc_view_proj(&self, perspective: &Perspective) -> Matrix4<f64> {
|
||||
perspective.calc_matrix() * self.calc_matrix()
|
||||
FLIP_Y * perspective.calc_matrix() * self.calc_matrix()
|
||||
}
|
||||
|
||||
pub fn create_camera_uniform(&self, perspective: &Perspective) -> CameraUniform {
|
||||
@ -84,7 +92,7 @@ impl Perspective {
|
||||
self.aspect = width as f64 / height as f64;
|
||||
}
|
||||
|
||||
pub fn calc_matrix(&self) -> cgmath::Matrix4<f64> {
|
||||
fn calc_matrix(&self) -> cgmath::Matrix4<f64> {
|
||||
OPENGL_TO_WGPU_MATRIX * cgmath::perspective(self.fovy, self.aspect, self.znear, self.zfar)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
mod buffer_pool;
|
||||
|
||||
mod piplines;
|
||||
mod shaders;
|
||||
mod stencil_pattern;
|
||||
mod texture;
|
||||
|
||||
pub mod camera;
|
||||
pub mod options;
|
||||
pub mod render_state;
|
||||
pub mod shader_ffi;
|
||||
|
||||
1
src/render/options.rs
Normal file
1
src/render/options.rs
Normal file
@ -0,0 +1 @@
|
||||
pub const DEBUG_STENCIL_PATTERN: bool = false;
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::render::options::DEBUG_STENCIL_PATTERN;
|
||||
use wgpu::{FragmentState, PipelineLayout, RenderPipelineDescriptor, VertexState};
|
||||
|
||||
use super::texture::DEPTH_TEXTURE_FORMAT;
|
||||
@ -7,20 +8,10 @@ use super::texture::DEPTH_TEXTURE_FORMAT;
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pipeline_layout`:
|
||||
/// * `vertex_state`:
|
||||
/// * `fragment_state`:
|
||||
/// * `sample_count`:
|
||||
/// * `update_stencil`: Fragments passing through the pipeline will be able to update the stencil
|
||||
/// buffer. This is used for masking
|
||||
///
|
||||
/// returns: RenderPipelineDescriptor
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
pub fn create_map_render_pipeline_description<'a>(
|
||||
pipeline_layout: &'a PipelineLayout,
|
||||
vertex_state: VertexState<'a>,
|
||||
@ -37,7 +28,11 @@ pub fn create_map_render_pipeline_description<'a>(
|
||||
}
|
||||
} else {
|
||||
wgpu::StencilFaceState {
|
||||
compare: wgpu::CompareFunction::Equal,
|
||||
compare: if DEBUG_STENCIL_PATTERN {
|
||||
wgpu::CompareFunction::Always
|
||||
} else {
|
||||
wgpu::CompareFunction::Equal
|
||||
},
|
||||
fail_op: wgpu::StencilOperation::Keep,
|
||||
depth_fail_op: wgpu::StencilOperation::Keep,
|
||||
pass_op: wgpu::StencilOperation::Keep,
|
||||
|
||||
@ -6,14 +6,13 @@ use wgpu::{Buffer, BufferAddress, Limits, Queue};
|
||||
use winit::dpi::PhysicalSize;
|
||||
use winit::window::Window;
|
||||
|
||||
use crate::fps_meter::FPSMeter;
|
||||
use crate::io::cache::Cache;
|
||||
use crate::platform::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
||||
use crate::render::buffer_pool::{BackingBufferDescriptor, BufferPool};
|
||||
use crate::render::stencil_pattern::TileMaskPattern;
|
||||
use crate::render::{camera, shaders};
|
||||
use crate::tesselation::IndexDataType;
|
||||
use crate::util::measure::Measure;
|
||||
use crate::util::FPSMeter;
|
||||
|
||||
use super::piplines::*;
|
||||
use super::shader_ffi::*;
|
||||
@ -82,8 +81,6 @@ impl SceneParams {
|
||||
|
||||
impl RenderState {
|
||||
pub async fn new(window: &Window) -> Self {
|
||||
let mut measure = Measure::time();
|
||||
|
||||
let sample_count = 4;
|
||||
|
||||
let size = if cfg!(target_os = "android") {
|
||||
@ -271,8 +268,6 @@ impl RenderState {
|
||||
100000.0,
|
||||
);
|
||||
|
||||
measure.breadcrumb("initialized");
|
||||
|
||||
Self {
|
||||
instance,
|
||||
surface,
|
||||
|
||||
@ -123,7 +123,9 @@ pub mod tile {
|
||||
|
||||
pub mod tile_mask {
|
||||
use crate::platform::COLOR_TEXTURE_FORMAT;
|
||||
use crate::render::options::DEBUG_STENCIL_PATTERN;
|
||||
use crate::render::shader_ffi::MaskInstanceUniform;
|
||||
use wgpu::ColorWrites;
|
||||
|
||||
use super::{FragmentShaderState, VertexShaderState};
|
||||
|
||||
@ -168,7 +170,15 @@ pub mod tile_mask {
|
||||
&[wgpu::ColorTargetState {
|
||||
format: COLOR_TEXTURE_FORMAT,
|
||||
blend: None,
|
||||
write_mask: wgpu::ColorWrites::empty(),
|
||||
write_mask: mask_write_mask(),
|
||||
}],
|
||||
);
|
||||
|
||||
pub const fn mask_write_mask() -> ColorWrites {
|
||||
if DEBUG_STENCIL_PATTERN {
|
||||
wgpu::ColorWrites::ALL
|
||||
} else {
|
||||
wgpu::ColorWrites::empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,8 +26,7 @@ fn main(
|
||||
let z = 0.0;
|
||||
let width = 3.0;
|
||||
|
||||
// position the anchor of a tile at the top left, instead of bottom right
|
||||
let world_pos = vec3<f32>(1.0, -1.0, 1.0) * vec3<f32>(position + normal * width, z) + translate;
|
||||
let world_pos = vec3<f32>(position + normal * width, z) + translate;
|
||||
|
||||
let position = globals.camera.view_proj * vec4<f32>(world_pos, 1.0);
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ impl TileMaskPattern {
|
||||
}
|
||||
|
||||
fn vertical(&mut self, dx: i32, dy: i32, anchor_x: f32, anchor_y: f32, extent: f32) {
|
||||
for i in 0..(dx.abs() / 2) {
|
||||
for i in 0..(dx.abs() / 2 + 1) {
|
||||
self.pattern.push(MaskInstanceUniform::new(
|
||||
[anchor_x + ((i * 2) + 1) as f32 * extent, anchor_y],
|
||||
1.0,
|
||||
@ -82,9 +82,9 @@ impl TileMaskPattern {
|
||||
}
|
||||
|
||||
fn horizontal(&mut self, dx: i32, dy: i32, anchor_x: f32, anchor_y: f32, extent: f32) {
|
||||
for i in 0..(dy.abs() / 2) {
|
||||
for i in 0..(dy.abs() / 2 + 1) {
|
||||
self.pattern.push(MaskInstanceUniform::new(
|
||||
[anchor_x, anchor_y - extent - (i * 2) as f32 * extent],
|
||||
[anchor_x, anchor_y + (i * 2) as f32 * extent],
|
||||
dx as f32,
|
||||
1.0,
|
||||
[0.0, 0.0, 1.0, 1.0],
|
||||
@ -94,10 +94,10 @@ impl TileMaskPattern {
|
||||
|
||||
pub fn stencil_reference_value(&self, world_coords: &WorldTileCoords) -> u8 {
|
||||
match (world_coords.x, world_coords.y) {
|
||||
(x, y) if x % 2 == 0 && y % 2 == 0 => 1,
|
||||
(x, y) if x % 2 == 0 && y % 2 != 0 => 2,
|
||||
(x, y) if x % 2 != 0 && y % 2 == 0 => 3,
|
||||
(x, y) if x % 2 != 0 && y % 2 != 0 => 4,
|
||||
(x, y) if x % 2 == 0 && y % 2 == 0 => 2,
|
||||
(x, y) if x % 2 == 0 && y % 2 != 0 => 1,
|
||||
(x, y) if x % 2 != 0 && y % 2 == 0 => 4,
|
||||
(x, y) if x % 2 != 0 && y % 2 != 0 => 3,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@ -109,11 +109,11 @@ impl TileMaskPattern {
|
||||
|
||||
self.pattern.clear();
|
||||
|
||||
let start: WorldTileCoords = (self.bounding_box.min_x, self.bounding_box.max_y, z).into(); // upper left corner
|
||||
let end: WorldTileCoords = (self.bounding_box.max_x, self.bounding_box.min_y, z).into(); // lower right corner
|
||||
let start: WorldTileCoords = (self.bounding_box.min_x, self.bounding_box.min_y, z).into(); // upper left corner
|
||||
let end: WorldTileCoords = (self.bounding_box.max_x, self.bounding_box.max_y, z).into(); // lower right corner
|
||||
|
||||
let aligned_start = start.into_aligned();
|
||||
let aligned_end = end.into_aligned().to_lower_right();
|
||||
let aligned_end = end.into_aligned().lower_right();
|
||||
|
||||
let start_world = start.into_world(extent);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user