mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Add a camera which is not used yet
This commit is contained in:
parent
daeabb4d77
commit
80c840007f
11
Cargo.lock
generated
11
Cargo.lock
generated
@ -200,6 +200,16 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cgmath"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.3"
|
version = "2.33.3"
|
||||||
@ -1168,6 +1178,7 @@ name = "mapr"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"cgmath",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"console_log",
|
"console_log",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
|||||||
@ -28,6 +28,7 @@ geo = "0.18.0"
|
|||||||
geo-types = "0.7"
|
geo-types = "0.7"
|
||||||
# proj = "0.24" FIXME: Incompatible with wasm
|
# proj = "0.24" FIXME: Incompatible with wasm
|
||||||
# mbutiles = "0.1.1" FIXME: Incompatible with wasm
|
# mbutiles = "0.1.1" FIXME: Incompatible with wasm
|
||||||
|
cgmath = "0.18"
|
||||||
|
|
||||||
# Rendering
|
# Rendering
|
||||||
winit = { version = "0.25" }
|
winit = { version = "0.25" }
|
||||||
|
|||||||
16
src/main.rs
16
src/main.rs
@ -23,13 +23,20 @@ async fn setup(window: Window, event_loop: EventLoop<()>) {
|
|||||||
// Important: This kick-starts the rendering loop
|
// Important: This kick-starts the rendering loop
|
||||||
// window.request_redraw();
|
// window.request_redraw();
|
||||||
|
|
||||||
|
let mut last_render_time = std::time::Instant::now();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
|
Event::DeviceEvent {
|
||||||
|
ref event,
|
||||||
|
.. // We're not using device_id currently
|
||||||
|
} => {
|
||||||
|
state.input(event);
|
||||||
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
ref event,
|
ref event,
|
||||||
window_id,
|
window_id,
|
||||||
} if window_id == window.id() => {
|
} if window_id == window.id() => {
|
||||||
if !state.input(event) {
|
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::CloseRequested
|
WindowEvent::CloseRequested
|
||||||
| WindowEvent::KeyboardInput {
|
| WindowEvent::KeyboardInput {
|
||||||
@ -50,10 +57,13 @@ async fn setup(window: Window, event_loop: EventLoop<()>) {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
state.update();
|
let now = std::time::Instant::now();
|
||||||
|
let dt = now - last_render_time;
|
||||||
|
last_render_time = now;
|
||||||
|
state.update(dt);
|
||||||
match state.render() {
|
match state.render() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
// Reconfigure the surface if lost
|
// Reconfigure the surface if lost
|
||||||
|
|||||||
234
src/render/camera.rs
Normal file
234
src/render/camera.rs
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
use std::f32::consts::FRAC_PI_2;
|
||||||
|
|
||||||
|
use cgmath::prelude::*;
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||||
|
1.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 1.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.5, 0.0,
|
||||||
|
0.0, 0.0, 0.5, 1.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
const SAFE_FRAC_PI_2: f32 = FRAC_PI_2 - 0.0001;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Camera {
|
||||||
|
pub position: cgmath::Point3<f32>,
|
||||||
|
yaw: cgmath::Rad<f32>,
|
||||||
|
pitch: cgmath::Rad<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Camera {
|
||||||
|
pub fn new<
|
||||||
|
V: Into<cgmath::Point3<f32>>,
|
||||||
|
Y: Into<cgmath::Rad<f32>>,
|
||||||
|
P: Into<cgmath::Rad<f32>>,
|
||||||
|
>(
|
||||||
|
position: V,
|
||||||
|
yaw: Y,
|
||||||
|
pitch: P,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
position: position.into(),
|
||||||
|
yaw: yaw.into(),
|
||||||
|
pitch: pitch.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calc_matrix(&self) -> cgmath::Matrix4<f32> {
|
||||||
|
cgmath::Matrix4::look_to_rh(
|
||||||
|
self.position,
|
||||||
|
cgmath::Vector3::new(self.yaw.0.cos(), self.pitch.0.sin(), self.yaw.0.sin())
|
||||||
|
.normalize(),
|
||||||
|
cgmath::Vector3::unit_y(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Projection {
|
||||||
|
aspect: f32,
|
||||||
|
fovy: cgmath::Rad<f32>,
|
||||||
|
znear: f32,
|
||||||
|
zfar: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Projection {
|
||||||
|
pub fn new<F: Into<cgmath::Rad<f32>>>(
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
fovy: F,
|
||||||
|
znear: f32,
|
||||||
|
zfar: f32,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
aspect: width as f32 / height as f32,
|
||||||
|
fovy: fovy.into(),
|
||||||
|
znear,
|
||||||
|
zfar,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, width: u32, height: u32) {
|
||||||
|
self.aspect = width as f32 / height as f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calc_matrix(&self) -> cgmath::Matrix4<f32> {
|
||||||
|
OPENGL_TO_WGPU_MATRIX * cgmath::perspective(self.fovy, self.aspect, self.znear, self.zfar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CameraController {
|
||||||
|
amount_left: f32,
|
||||||
|
amount_right: f32,
|
||||||
|
amount_forward: f32,
|
||||||
|
amount_backward: f32,
|
||||||
|
amount_up: f32,
|
||||||
|
amount_down: f32,
|
||||||
|
rotate_horizontal: f32,
|
||||||
|
rotate_vertical: f32,
|
||||||
|
scroll: f32,
|
||||||
|
speed: f32,
|
||||||
|
sensitivity: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CameraController {
|
||||||
|
pub fn new(speed: f32, sensitivity: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
amount_left: 0.0,
|
||||||
|
amount_right: 0.0,
|
||||||
|
amount_forward: 0.0,
|
||||||
|
amount_backward: 0.0,
|
||||||
|
amount_up: 0.0,
|
||||||
|
amount_down: 0.0,
|
||||||
|
rotate_horizontal: 0.0,
|
||||||
|
rotate_vertical: 0.0,
|
||||||
|
scroll: 0.0,
|
||||||
|
speed,
|
||||||
|
sensitivity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_keyboard(
|
||||||
|
&mut self,
|
||||||
|
key: winit::event::VirtualKeyCode,
|
||||||
|
state: winit::event::ElementState,
|
||||||
|
) -> bool {
|
||||||
|
let amount = if state == winit::event::ElementState::Pressed {
|
||||||
|
1.0
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
match key {
|
||||||
|
winit::event::VirtualKeyCode::W | winit::event::VirtualKeyCode::Up => {
|
||||||
|
self.amount_forward = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
winit::event::VirtualKeyCode::S | winit::event::VirtualKeyCode::Down => {
|
||||||
|
self.amount_backward = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
winit::event::VirtualKeyCode::A | winit::event::VirtualKeyCode::Left => {
|
||||||
|
self.amount_left = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
winit::event::VirtualKeyCode::D | winit::event::VirtualKeyCode::Right => {
|
||||||
|
self.amount_right = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
winit::event::VirtualKeyCode::Space => {
|
||||||
|
self.amount_up = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
winit::event::VirtualKeyCode::LShift => {
|
||||||
|
self.amount_down = amount;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_mouse(&mut self, mouse_dx: f64, mouse_dy: f64) {
|
||||||
|
self.rotate_horizontal = mouse_dx as f32;
|
||||||
|
self.rotate_vertical = mouse_dy as f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_scroll(&mut self, delta: &winit::event::MouseScrollDelta) {
|
||||||
|
self.scroll = -match delta {
|
||||||
|
// I'm assuming a line is about 100 pixels
|
||||||
|
winit::event::MouseScrollDelta::LineDelta(_, scroll) => scroll * 100.0,
|
||||||
|
winit::event::MouseScrollDelta::PixelDelta(winit::dpi::PhysicalPosition {
|
||||||
|
y: scroll,
|
||||||
|
..
|
||||||
|
}) => *scroll as f32,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_camera(&mut self, camera: &mut Camera, dt: std::time::Duration) {
|
||||||
|
let dt = dt.as_secs_f32();
|
||||||
|
|
||||||
|
// Move forward/backward and left/right
|
||||||
|
let (yaw_sin, yaw_cos) = camera.yaw.0.sin_cos();
|
||||||
|
let forward = cgmath::Vector3::new(yaw_cos, 0.0, yaw_sin).normalize();
|
||||||
|
let right = cgmath::Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
|
||||||
|
camera.position += forward * (self.amount_forward - self.amount_backward) * self.speed * dt;
|
||||||
|
camera.position += right * (self.amount_right - self.amount_left) * self.speed * dt;
|
||||||
|
|
||||||
|
// Move in/out (aka. "zoom")
|
||||||
|
// Note: this isn't an actual zoom. The camera's position
|
||||||
|
// changes when zooming. I've added this to make it easier
|
||||||
|
// to get closer to an object you want to focus on.
|
||||||
|
let (pitch_sin, pitch_cos) = camera.pitch.0.sin_cos();
|
||||||
|
let scrollward =
|
||||||
|
cgmath::Vector3::new(pitch_cos * yaw_cos, pitch_sin, pitch_cos * yaw_sin).normalize();
|
||||||
|
camera.position += scrollward * self.scroll * self.speed * self.sensitivity * dt;
|
||||||
|
self.scroll = 0.0;
|
||||||
|
|
||||||
|
// Move up/down. Since we don't use roll, we can just
|
||||||
|
// modify the y coordinate directly.
|
||||||
|
camera.position.y += (self.amount_up - self.amount_down) * self.speed * dt;
|
||||||
|
|
||||||
|
// Rotate
|
||||||
|
camera.yaw += cgmath::Rad(self.rotate_horizontal) * self.sensitivity * dt;
|
||||||
|
camera.pitch += cgmath::Rad(-self.rotate_vertical) * self.sensitivity * dt;
|
||||||
|
|
||||||
|
// If process_mouse isn't called every frame, these values
|
||||||
|
// will not get set to zero, and the camera will rotate
|
||||||
|
// when moving in a non cardinal direction.
|
||||||
|
self.rotate_horizontal = 0.0;
|
||||||
|
self.rotate_vertical = 0.0;
|
||||||
|
|
||||||
|
// Keep the camera's angle from going too high/low.
|
||||||
|
if camera.pitch < -cgmath::Rad(SAFE_FRAC_PI_2) {
|
||||||
|
camera.pitch = -cgmath::Rad(SAFE_FRAC_PI_2);
|
||||||
|
} else if camera.pitch > cgmath::Rad(SAFE_FRAC_PI_2) {
|
||||||
|
camera.pitch = cgmath::Rad(SAFE_FRAC_PI_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct CameraUniform {
|
||||||
|
pub view_position: [f32; 4],
|
||||||
|
pub view_proj: [[f32; 4]; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl bytemuck::Pod for CameraUniform {}
|
||||||
|
unsafe impl bytemuck::Zeroable for CameraUniform {}
|
||||||
|
|
||||||
|
impl CameraUniform {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
view_position: [0.0; 4],
|
||||||
|
view_proj: cgmath::Matrix4::identity().into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATED!
|
||||||
|
pub(crate) fn update_view_proj(&mut self, camera: &Camera, projection: &Projection) {
|
||||||
|
self.view_position = camera.position.to_homogeneous().into();
|
||||||
|
self.view_proj = (projection.calc_matrix() * camera.calc_matrix()).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,5 +4,6 @@ mod shader_ffi;
|
|||||||
mod tesselation;
|
mod tesselation;
|
||||||
mod texture;
|
mod texture;
|
||||||
mod platform_constants;
|
mod platform_constants;
|
||||||
|
mod camera;
|
||||||
|
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
|||||||
@ -1,23 +1,41 @@
|
|||||||
|
use crate::render::camera;
|
||||||
|
use crate::render::camera::Camera;
|
||||||
|
|
||||||
type Vec2f32 = [f32; 2];
|
type Vec2f32 = [f32; 2];
|
||||||
type Vec4f32 = [f32; 4];
|
type Vec4f32 = [f32; 4];
|
||||||
|
type Mat4f32 = [Vec4f32; 4];
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Globals {
|
pub struct Globals {
|
||||||
pub resolution: Vec2f32,
|
pub view_proj: Mat4f32, // 64 bytes
|
||||||
pub scroll_offset: Vec2f32,
|
pub view_position: Vec4f32, // 16 bytes
|
||||||
pub zoom: f32,
|
pub resolution: Vec2f32, // 8 bytes
|
||||||
_pad1: u32, // _padX aligns it to 8 bytes = AlignOf(Vec2f32=vec2<f32>):
|
pub scroll_offset: Vec2f32, // 8 bytes
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
pub zoom: f32, // 4 bytes
|
||||||
|
_pad1: i32, // _padX aligns it to 8 bytes = AlignOf(Vec2f32=vec2<f32>):
|
||||||
|
// https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
||||||
|
_pad2: i32,
|
||||||
|
_pad3: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Globals {
|
impl Globals {
|
||||||
pub fn new(resolution: Vec2f32, scroll_offset: Vec2f32, zoom: f32) -> Self {
|
pub fn new(
|
||||||
|
view_proj: Mat4f32,
|
||||||
|
view_position: Vec4f32,
|
||||||
|
resolution: Vec2f32,
|
||||||
|
scroll_offset: Vec2f32,
|
||||||
|
zoom: f32,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
view_proj,
|
||||||
|
view_position,
|
||||||
resolution,
|
resolution,
|
||||||
scroll_offset,
|
scroll_offset,
|
||||||
zoom,
|
zoom,
|
||||||
_pad1: Default::default(),
|
_pad1: Default::default(),
|
||||||
|
_pad2: Default::default(),
|
||||||
|
_pad3: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +49,7 @@ pub struct GpuVertex {
|
|||||||
pub position: Vec2f32,
|
pub position: Vec2f32,
|
||||||
pub normal: Vec2f32,
|
pub normal: Vec2f32,
|
||||||
pub prim_id: u32,
|
pub prim_id: u32,
|
||||||
_pad1: u32, // _padX aligns it to 8 bytes = AlignOf(Vec2f32=vec2<f32>):
|
_pad1: i32, // _padX aligns it to 8 bytes = AlignOf(Vec2f32=vec2<f32>):
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
// https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +59,7 @@ impl GpuVertex {
|
|||||||
position,
|
position,
|
||||||
normal,
|
normal,
|
||||||
prim_id,
|
prim_id,
|
||||||
_pad1: Default::default(),
|
_pad1: Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,8 +76,8 @@ pub struct Primitive {
|
|||||||
pub width: f32,
|
pub width: f32,
|
||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
pub scale: f32,
|
pub scale: f32,
|
||||||
_pad1: u32, // _padX aligns it to 16 bytes = AlignOf(Vec4f32/vec4<f32>):
|
_pad1: i32, // _padX aligns it to 16 bytes = AlignOf(Vec4f32/vec4<f32>):
|
||||||
_pad2: u32, // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
_pad2: i32, // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Primitive {
|
impl Default for Primitive {
|
||||||
@ -91,12 +109,3 @@ impl Primitive {
|
|||||||
|
|
||||||
unsafe impl bytemuck::Pod for Primitive {}
|
unsafe impl bytemuck::Pod for Primitive {}
|
||||||
unsafe impl bytemuck::Zeroable for Primitive {}
|
unsafe impl bytemuck::Zeroable for Primitive {}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct BgPoint {
|
|
||||||
pub point: [f32; 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl bytemuck::Pod for BgPoint {}
|
|
||||||
unsafe impl bytemuck::Zeroable for BgPoint {}
|
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
[[block]]
|
[[block]]
|
||||||
struct Globals {
|
struct Globals {
|
||||||
|
view_position: vec4<f32>;
|
||||||
|
view_proj: mat4x4<f32>;
|
||||||
resolution: vec2<f32>;
|
resolution: vec2<f32>;
|
||||||
scroll_offset: vec2<f32>;
|
scroll_offset: vec2<f32>;
|
||||||
zoom: f32;
|
zoom: f32;
|
||||||
|
pad1: i32;
|
||||||
|
pad2: i32;
|
||||||
|
pad3: i32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Primitive {
|
struct Primitive {
|
||||||
|
|||||||
@ -6,10 +6,11 @@ use lyon::math::Vector;
|
|||||||
use lyon::tessellation::VertexBuffers;
|
use lyon::tessellation::VertexBuffers;
|
||||||
use vector_tile::parse_tile_reader;
|
use vector_tile::parse_tile_reader;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{DeviceEvent, ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
use winit::window::Window;
|
use winit::window::Window;
|
||||||
|
|
||||||
use crate::fps_meter::FPSMeter;
|
use crate::fps_meter::FPSMeter;
|
||||||
|
use crate::render::camera;
|
||||||
use crate::render::tesselation::TileMask;
|
use crate::render::tesselation::TileMask;
|
||||||
|
|
||||||
use super::piplines::*;
|
use super::piplines::*;
|
||||||
@ -79,6 +80,11 @@ pub struct State {
|
|||||||
tile_mask_indices_uniform_buffer: wgpu::Buffer,
|
tile_mask_indices_uniform_buffer: wgpu::Buffer,
|
||||||
tile_mask_range: Range<u32>,
|
tile_mask_range: Range<u32>,
|
||||||
|
|
||||||
|
camera: camera::Camera, // UPDATED!
|
||||||
|
projection: camera::Projection, // NEW!
|
||||||
|
camera_controller: camera::CameraController, // UPDATED!
|
||||||
|
camera_uniform: camera::CameraUniform, // UPDATED!
|
||||||
|
|
||||||
scene: SceneParams,
|
scene: SceneParams,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +339,19 @@ impl State {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let camera = camera::Camera::new((0.0, 5.0, 10.0), cgmath::Deg(-90.0), cgmath::Deg(-20.0));
|
||||||
|
let projection = camera::Projection::new(
|
||||||
|
surface_config.width,
|
||||||
|
surface_config.height,
|
||||||
|
cgmath::Deg(45.0),
|
||||||
|
0.1,
|
||||||
|
100.0,
|
||||||
|
);
|
||||||
|
let camera_controller = camera::CameraController::new(4.0, 0.4);
|
||||||
|
let mut camera_uniform = camera::CameraUniform::new();
|
||||||
|
|
||||||
|
camera_uniform.update_view_proj(&camera, &projection);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
surface,
|
surface,
|
||||||
device,
|
device,
|
||||||
@ -356,6 +375,10 @@ impl State {
|
|||||||
tile_stroke_range,
|
tile_stroke_range,
|
||||||
tile_mask_indices_uniform_buffer,
|
tile_mask_indices_uniform_buffer,
|
||||||
tile_mask_range,
|
tile_mask_range,
|
||||||
|
camera,
|
||||||
|
projection,
|
||||||
|
camera_controller,
|
||||||
|
camera_uniform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,6 +389,8 @@ impl State {
|
|||||||
self.surface_config.height = new_size.height;
|
self.surface_config.height = new_size.height;
|
||||||
self.surface.configure(&self.device, &self.surface_config);
|
self.surface.configure(&self.device, &self.surface_config);
|
||||||
|
|
||||||
|
self.projection.resize(new_size.width, new_size.height);
|
||||||
|
|
||||||
// Re-configure depth buffer
|
// Re-configure depth buffer
|
||||||
self.depth_texture = Texture::create_depth_texture(
|
self.depth_texture = Texture::create_depth_texture(
|
||||||
&self.device,
|
&self.device,
|
||||||
@ -387,23 +412,21 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input(&mut self, event: &WindowEvent) -> bool {
|
pub fn input(&mut self, event: &DeviceEvent) -> bool {
|
||||||
let scene = &mut self.scene;
|
let scene = &mut self.scene;
|
||||||
let found = match event {
|
match event {
|
||||||
WindowEvent::KeyboardInput {
|
DeviceEvent::Key(KeyboardInput {
|
||||||
input:
|
virtual_keycode: Some(key),
|
||||||
KeyboardInput {
|
state,
|
||||||
state: ElementState::Pressed,
|
|
||||||
virtual_keycode: Some(key),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
} => match key {
|
}) => match key {
|
||||||
VirtualKeyCode::PageDown => {
|
VirtualKeyCode::PageDown => {
|
||||||
|
println!("PageDown");
|
||||||
scene.target_zoom *= 0.8;
|
scene.target_zoom *= 0.8;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
VirtualKeyCode::PageUp => {
|
VirtualKeyCode::PageUp => {
|
||||||
|
println!("PageUp");
|
||||||
scene.target_zoom *= 1.25;
|
scene.target_zoom *= 1.25;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -431,12 +454,27 @@ impl State {
|
|||||||
scene.target_stroke_width *= 0.8;
|
scene.target_stroke_width *= 0.8;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_key => false,
|
_key => self.camera_controller.process_keyboard(*key, *state),
|
||||||
},
|
},
|
||||||
_evt => false,
|
DeviceEvent::MouseWheel { delta, .. } => {
|
||||||
};
|
self.camera_controller.process_scroll(delta);
|
||||||
|
true
|
||||||
found
|
}
|
||||||
|
DeviceEvent::Button {
|
||||||
|
button: 1, // Left Mouse Button
|
||||||
|
state,
|
||||||
|
} => {
|
||||||
|
//self.mouse_pressed = *state == ElementState::Pressed;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
DeviceEvent::MouseMotion { delta } => {
|
||||||
|
//if self.mouse_pressed {
|
||||||
|
// self.camera_controller.process_mouse(delta.0, delta.1);
|
||||||
|
//}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||||
@ -451,6 +489,8 @@ impl State {
|
|||||||
&self.globals_uniform_buffer,
|
&self.globals_uniform_buffer,
|
||||||
0,
|
0,
|
||||||
bytemuck::cast_slice(&[Globals::new(
|
bytemuck::cast_slice(&[Globals::new(
|
||||||
|
self.camera_uniform.view_proj,
|
||||||
|
self.camera_uniform.view_position,
|
||||||
[self.size.width as f32, self.size.height as f32],
|
[self.size.width as f32, self.size.height as f32],
|
||||||
scene.scroll.to_array(),
|
scene.scroll.to_array(),
|
||||||
scene.zoom,
|
scene.zoom,
|
||||||
@ -539,10 +579,14 @@ impl State {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self, dt: std::time::Duration) {
|
||||||
let scene = &mut self.scene;
|
let scene = &mut self.scene;
|
||||||
let time_secs = self.fps_meter.time_secs as f32;
|
let time_secs = self.fps_meter.time_secs as f32;
|
||||||
|
|
||||||
|
self.camera_controller.update_camera(&mut self.camera, dt);
|
||||||
|
self.camera_uniform
|
||||||
|
.update_view_proj(&self.camera, &self.projection);
|
||||||
|
|
||||||
// Animate the zoom to match target_zoom
|
// Animate the zoom to match target_zoom
|
||||||
scene.zoom += (scene.target_zoom - scene.zoom) / 3.0;
|
scene.zoom += (scene.target_zoom - scene.zoom) / 3.0;
|
||||||
scene.scroll = scene.scroll + (scene.target_scroll - scene.scroll) / 3.0;
|
scene.scroll = scene.scroll + (scene.target_scroll - scene.scroll) / 3.0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user