Simplify coordination calculation

This commit is contained in:
Maximilian Ammann 2022-01-07 17:37:54 +01:00
parent bdf905b6b4
commit c54f3ee84b
10 changed files with 132 additions and 70 deletions

107
src/coords.rs Normal file
View 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,
}
}
}

View File

@ -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};

View File

@ -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,
}
}
}

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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(),
}
}
}

View File

@ -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,
},
],

View File

@ -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);
}

View File

@ -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()