mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Simplify coordination calculation
This commit is contained in:
parent
bdf905b6b4
commit
c54f3ee84b
107
src/coords.rs
Normal file
107
src/coords.rs
Normal file
@ -0,0 +1,107 @@
|
||||
use crate::render::shader_ffi::Vec3f32;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct TileCoords {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub z: u8,
|
||||
}
|
||||
|
||||
impl TileCoords {
|
||||
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,
|
||||
z: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TileCoords {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "T({x}, {y}, {z})", x = self.x, y = self.y, z = self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u32, u32, u8)> for TileCoords {
|
||||
fn from(tuple: (u32, u32, u8)) -> Self {
|
||||
TileCoords {
|
||||
x: tuple.0,
|
||||
y: tuple.1,
|
||||
z: tuple.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct WorldTileCoords {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub z: u8,
|
||||
}
|
||||
|
||||
impl WorldTileCoords {
|
||||
pub fn into_world(self, extent: u16) -> WorldCoords {
|
||||
WorldCoords {
|
||||
x: self.x as f32 * extent as f32,
|
||||
y: self.y as f32 * extent as f32 + extent as f32, // We add extent here as we want the upper left corner
|
||||
z: self.z as f32,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stencil_reference_value(&self) -> u8 {
|
||||
match (self.x, self.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,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for WorldTileCoords {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "WT({x}, {y}, {z})", x = self.x, y = self.y, z = self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(i32, i32, u8)> for WorldTileCoords {
|
||||
fn from(tuple: (i32, i32, u8)) -> Self {
|
||||
WorldTileCoords {
|
||||
x: tuple.0,
|
||||
y: tuple.1,
|
||||
z: tuple.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct WorldCoords {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub z: f32,
|
||||
}
|
||||
|
||||
impl WorldCoords {
|
||||
pub fn into_shader_coords(self) -> Vec3f32 {
|
||||
[self.x, self.y, self.z]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for WorldCoords {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "W({x}, {y}, {z})", x = self.x, y = self.y, z = self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(f32, f32, f32)> for WorldCoords {
|
||||
fn from(tuple: (f32, f32, f32)) -> Self {
|
||||
WorldCoords {
|
||||
x: tuple.0,
|
||||
y: tuple.1,
|
||||
z: tuple.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,10 +5,11 @@ use std::sync::{Arc, Condvar, Mutex};
|
||||
use log::{error, info};
|
||||
use lyon::tessellation::VertexBuffers;
|
||||
|
||||
use crate::coords::TileCoords;
|
||||
use vector_tile::parse_tile_bytes;
|
||||
use vector_tile::tile::Tile;
|
||||
|
||||
use crate::io::{static_database, TileCoords};
|
||||
use crate::io::static_database;
|
||||
use crate::render::shader_ffi::GpuVertexUniform;
|
||||
use crate::tesselation::{IndexDataType, Tesselated};
|
||||
|
||||
|
||||
@ -2,32 +2,3 @@ use std::fmt::{Display, Formatter};
|
||||
|
||||
pub mod cache;
|
||||
pub mod static_database;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct TileCoords {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub z: u8,
|
||||
}
|
||||
|
||||
impl TileCoords {
|
||||
fn hash(&self) -> u32 {
|
||||
self.x + self.y + self.z as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for TileCoords {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "({x}, {y}, {z})", x = self.x, y = self.y, z = self.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<TileCoords> for (u32, u32, u8) {
|
||||
fn into(self) -> TileCoords {
|
||||
TileCoords {
|
||||
x: self.0,
|
||||
y: self.1,
|
||||
z: self.2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::concat;
|
||||
use std::env;
|
||||
|
||||
use crate::io::TileCoords;
|
||||
use crate::coords::TileCoords;
|
||||
use include_dir::{include_dir, Dir, File};
|
||||
|
||||
static TILES: Dir = include_dir!("$OUT_DIR/extracted-tiles");
|
||||
|
||||
@ -2,6 +2,7 @@ mod fps_meter;
|
||||
mod input;
|
||||
mod platform;
|
||||
|
||||
pub(crate) mod coords;
|
||||
pub(crate) mod example;
|
||||
pub(crate) mod render;
|
||||
pub(crate) mod util;
|
||||
|
||||
@ -8,7 +8,7 @@ use std::ops::Range;
|
||||
|
||||
use lyon::tessellation::VertexBuffers;
|
||||
|
||||
use crate::io::TileCoords;
|
||||
use crate::coords::TileCoords;
|
||||
use crate::render::shader_ffi::GpuVertexUniform;
|
||||
use crate::tesselation::IndexDataType;
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use bytemuck_derive::{Pod, Zeroable};
|
||||
use cgmath::SquareMatrix;
|
||||
|
||||
type Vec2f32 = [f32; 2];
|
||||
type Vec4f32 = [f32; 4];
|
||||
type Mat4f32 = [Vec4f32; 4];
|
||||
pub type Vec2f32 = [f32; 2];
|
||||
pub type Vec3f32 = [f32; 3];
|
||||
pub type Vec4f32 = [f32; 4];
|
||||
pub type Mat4f32 = [Vec4f32; 4];
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||
@ -100,18 +101,16 @@ impl MaskInstanceUniform {
|
||||
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||
pub struct TileUniform {
|
||||
pub color: Vec4f32,
|
||||
pub translate: Vec2f32,
|
||||
_pad1: i32, // _padX aligns it to 16 bytes = AlignOf(Vec4f32/vec4<f32>):
|
||||
_pad2: i32, // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
||||
pub translate: Vec3f32,
|
||||
_pad1: i32, // _padX aligns it to 16 bytes = AlignOf(Vec4f32/vec4<f32>): // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
||||
}
|
||||
|
||||
impl TileUniform {
|
||||
pub fn new(color: Vec4f32, translate: Vec2f32) -> Self {
|
||||
pub fn new(color: Vec4f32, translate: Vec3f32) -> Self {
|
||||
Self {
|
||||
color,
|
||||
translate,
|
||||
_pad1: Default::default(),
|
||||
_pad2: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ pub mod tile {
|
||||
// translate
|
||||
wgpu::VertexAttribute {
|
||||
offset: wgpu::VertexFormat::Float32x4.size(),
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
shader_location: 4,
|
||||
},
|
||||
],
|
||||
|
||||
@ -8,13 +8,6 @@ struct GlobalsUniform {
|
||||
camera: CameraUniform;
|
||||
};
|
||||
|
||||
struct TileUniform {
|
||||
color: vec4<f32>;
|
||||
translate: vec2<f32>;
|
||||
pad1: i32;
|
||||
pad2: i32;
|
||||
};
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> globals: GlobalsUniform;
|
||||
|
||||
struct VertexOutput {
|
||||
@ -28,15 +21,16 @@ fn main(
|
||||
[[location(1)]] normal: vec2<f32>,
|
||||
[[location(2)]] tile_id: u32,
|
||||
[[location(3)]] color: vec4<f32>,
|
||||
[[location(4)]] translate: vec2<f32>,
|
||||
[[location(4)]] translate: vec3<f32>,
|
||||
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
||||
) -> VertexOutput {
|
||||
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 = vec2<f32>(1.0, -1.0) * (position + normal * 3.0) + translate;
|
||||
let world_pos = vec3<f32>(1.0, -1.0, 1.0) * vec3<f32>(position + normal * width, z) + translate;
|
||||
|
||||
let position = globals.camera.view_proj * vec4<f32>(world_pos, z, 1.0);
|
||||
let position = globals.camera.view_proj * vec4<f32>(world_pos, 1.0);
|
||||
|
||||
return VertexOutput(color, position);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ use std::default::Default;
|
||||
use std::io::Cursor;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::coords::{TileCoords, WorldTileCoords};
|
||||
use crate::example::{MUNICH_X, MUNICH_Y};
|
||||
use log::{trace, warn};
|
||||
use lyon::tessellation::VertexBuffers;
|
||||
@ -16,7 +17,7 @@ use winit::window::Window;
|
||||
|
||||
use crate::fps_meter::FPSMeter;
|
||||
use crate::io::cache::Cache;
|
||||
use crate::io::{static_database, TileCoords};
|
||||
use crate::io::static_database;
|
||||
use crate::platform::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
||||
use crate::render::buffer_pool::{BackingBufferDescriptor, BufferPool};
|
||||
use crate::render::{camera, shaders};
|
||||
@ -381,10 +382,10 @@ impl State {
|
||||
|
||||
let uniform = TileUniform::new(
|
||||
[0.0, 0.0, 0.0, 1.0],
|
||||
[
|
||||
(new_coords.x - MUNICH_X) as f32 * 4096.0,
|
||||
-1.0 * (new_coords.y - MUNICH_Y) as f32 * 4096.0, // FIXME: Improve conversion to world tile coordinates
|
||||
],
|
||||
new_coords
|
||||
.into_world_tile()
|
||||
.into_world(4096)
|
||||
.into_shader_coords(),
|
||||
);
|
||||
self.queue.write_buffer(
|
||||
&self.tiles_uniform_buffer,
|
||||
@ -465,21 +466,9 @@ impl State {
|
||||
}
|
||||
{
|
||||
for entry in self.buffer_pool.available_vertices() {
|
||||
let TileCoords { x, y, .. } = entry.coords;
|
||||
|
||||
// FIXME: Improve conversion
|
||||
let world_x = x as i32 - MUNICH_X as i32;
|
||||
let world_y = (y as i32 - MUNICH_Y as i32 + 1) * -1;
|
||||
|
||||
pass.set_pipeline(&self.render_pipeline);
|
||||
let reference = match (world_x, world_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,
|
||||
_ => 0,
|
||||
};
|
||||
pass.set_stencil_reference(reference);
|
||||
let reference = entry.coords.into_world_tile().stencil_reference_value();
|
||||
pass.set_stencil_reference(reference as u32);
|
||||
pass.set_index_buffer(
|
||||
self.buffer_pool
|
||||
.indices()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user