mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Move input handler code to own module
This commit is contained in:
parent
05775e712e
commit
d75c72f401
144
src/input/camera_controller.rs
Normal file
144
src/input/camera_controller.rs
Normal file
@ -0,0 +1,144 @@
|
||||
use std::f32::consts::FRAC_PI_2;
|
||||
|
||||
use cgmath::InnerSpace;
|
||||
|
||||
const SAFE_FRAC_PI_2: f32 = FRAC_PI_2 - 0.0001;
|
||||
|
||||
#[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_touch(&mut self, touch_dx: f64, touch_dy: f64) {
|
||||
self.amount_right += touch_dx as f32;
|
||||
self.amount_up += touch_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 crate::render::camera::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
124
src/input/mod.rs
Normal file
124
src/input/mod.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use std::time::Duration;
|
||||
use winit::event::{
|
||||
DeviceEvent, ElementState, KeyboardInput, MouseButton, TouchPhase, WindowEvent,
|
||||
};
|
||||
use winit::window::Window;
|
||||
|
||||
use crate::input::camera_controller::CameraController;
|
||||
use crate::render::state::{SceneParams, State};
|
||||
|
||||
mod camera_controller;
|
||||
|
||||
pub struct InputHandler {
|
||||
camera_controller: CameraController,
|
||||
|
||||
last_touch: Option<(f64, f64)>,
|
||||
mouse_pressed: bool,
|
||||
target_stroke_width: f32,
|
||||
}
|
||||
|
||||
impl InputHandler {
|
||||
pub fn new() -> Self {
|
||||
let camera_controller = CameraController::new(3000.0, 0.2);
|
||||
Self {
|
||||
target_stroke_width: 1.0,
|
||||
last_touch: None,
|
||||
mouse_pressed: false,
|
||||
camera_controller,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_input(&mut self, event: &DeviceEvent, window: &Window) -> bool {
|
||||
match event {
|
||||
DeviceEvent::MouseMotion { delta } => {
|
||||
if self.mouse_pressed {
|
||||
self.camera_controller.process_mouse(
|
||||
delta.0 / window.scale_factor(),
|
||||
delta.1 / window.scale_factor(),
|
||||
);
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn window_input(&mut self, event: &WindowEvent, window: &Window) -> bool {
|
||||
match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => match key {
|
||||
winit::event::VirtualKeyCode::Z => {
|
||||
self.target_stroke_width *= 1.2;
|
||||
true
|
||||
}
|
||||
winit::event::VirtualKeyCode::H => {
|
||||
self.target_stroke_width *= 0.8;
|
||||
true
|
||||
}
|
||||
_ => self.camera_controller.process_keyboard(*key, *state),
|
||||
},
|
||||
WindowEvent::Touch(touch) => {
|
||||
match touch.phase {
|
||||
TouchPhase::Started => {
|
||||
self.last_touch = Some((touch.location.x, touch.location.y))
|
||||
}
|
||||
TouchPhase::Moved | TouchPhase::Ended => {
|
||||
if let Some(start) = self.last_touch {
|
||||
let delta_x = start.0 - touch.location.x;
|
||||
let delta_y = start.1 - touch.location.y;
|
||||
self.camera_controller.process_touch(
|
||||
delta_x / window.scale_factor(),
|
||||
delta_y / window.scale_factor(),
|
||||
);
|
||||
}
|
||||
|
||||
self.last_touch = Some((touch.location.x, touch.location.y))
|
||||
}
|
||||
TouchPhase::Cancelled => {}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
self.camera_controller.process_scroll(delta);
|
||||
true
|
||||
}
|
||||
WindowEvent::MouseInput {
|
||||
button: MouseButton::Left, // Left Mouse Button
|
||||
state,
|
||||
..
|
||||
} => {
|
||||
self.mouse_pressed = *state == ElementState::Pressed;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_state(&mut self, state: &mut State, dt: Duration) {
|
||||
let scene = &mut state.scene;
|
||||
self.camera_controller.update_camera(&mut state.camera, dt);
|
||||
|
||||
// Animate the stroke_width to match target_stroke_width
|
||||
scene.stroke_width =
|
||||
scene.stroke_width + (self.target_stroke_width - scene.stroke_width) / 5.0;
|
||||
|
||||
// Animate the strokes of primitive
|
||||
scene.cpu_primitives[0 as usize].width = scene.stroke_width;
|
||||
/*
|
||||
scene.cpu_primitives[STROKE_PRIM_ID as usize].color = [
|
||||
(time_secs * 0.8 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs * 0.5 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs - 1.6).sin() * 0.1 + 0.1,
|
||||
1.0,
|
||||
];
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
mod fps_meter;
|
||||
mod input;
|
||||
mod io;
|
||||
pub mod main_loop;
|
||||
mod platform;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
use log::{info, trace};
|
||||
use log::{error, info, trace};
|
||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
|
||||
use crate::input::InputHandler;
|
||||
use crate::platform::Instant;
|
||||
use crate::render::state::State;
|
||||
|
||||
pub async fn setup(window: winit::window::Window, event_loop: EventLoop<()>) {
|
||||
info!("== mapr ==");
|
||||
|
||||
let mut input = InputHandler::new();
|
||||
let mut state = State::new(&window).await;
|
||||
|
||||
let mut last_render_time = Instant::now();
|
||||
@ -19,14 +21,14 @@ pub async fn setup(window: winit::window::Window, event_loop: EventLoop<()>) {
|
||||
.. // We're not using device_id currently
|
||||
} => {
|
||||
trace!("{:?}", event);
|
||||
state.device_input(event, &window);
|
||||
input.device_input(event,&window);
|
||||
}
|
||||
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == window.id() => {
|
||||
if !state.window_input(event, &window) {
|
||||
if !input.window_input(event, &window) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested
|
||||
| WindowEvent::KeyboardInput {
|
||||
@ -53,13 +55,19 @@ pub async fn setup(window: winit::window::Window, event_loop: EventLoop<()>) {
|
||||
let now = Instant::now();
|
||||
let dt = now - last_render_time;
|
||||
last_render_time = now;
|
||||
state.update(dt);
|
||||
input.update_state( &mut state, dt);
|
||||
match state.render() {
|
||||
Ok(_) => {}
|
||||
// Reconfigure the surface if lost
|
||||
Err(wgpu::SurfaceError::Lost) => state.resize(state.size),
|
||||
Err(wgpu::SurfaceError::Lost) => {
|
||||
error!("Surface Lost");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
},
|
||||
// The system is out of memory, we should probably quit
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
error!("Out of Memory");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
},
|
||||
// All other errors (Outdated, Timeout) should be resolved by the next frame
|
||||
Err(e) => eprintln!("{:?}", e),
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use std::f32::consts::FRAC_PI_2;
|
||||
|
||||
use cgmath::prelude::*;
|
||||
|
||||
use crate::render::shader_ffi::CameraUniform;
|
||||
@ -12,13 +10,11 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||
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>,
|
||||
pub yaw: cgmath::Rad<f32>,
|
||||
pub pitch: cgmath::Rad<f32>,
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
@ -46,6 +42,12 @@ impl Camera {
|
||||
cgmath::Vector3::unit_y(),
|
||||
)
|
||||
}
|
||||
pub fn create_camera_uniform(&self, projection: &Projection) -> CameraUniform {
|
||||
CameraUniform::new(
|
||||
(projection.calc_matrix() * self.calc_matrix()).into(),
|
||||
self.position.to_homogeneous().into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Projection {
|
||||
@ -79,145 +81,3 @@ impl Projection {
|
||||
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_touch(&mut self, touch_dx: f64, touch_dy: f64) {
|
||||
self.amount_right += touch_dx as f32;
|
||||
self.amount_up += touch_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);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_camera_uniform(camera: &Camera, projection: &Projection) -> CameraUniform {
|
||||
CameraUniform::new(
|
||||
(projection.calc_matrix() * camera.calc_matrix()).into(),
|
||||
camera.position.to_homogeneous().into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
mod camera;
|
||||
mod piplines;
|
||||
mod shader_ffi;
|
||||
mod tesselation;
|
||||
mod texture;
|
||||
|
||||
mod shaders;
|
||||
|
||||
pub mod camera;
|
||||
pub mod state;
|
||||
|
||||
@ -16,7 +16,7 @@ use vector_tile::parse_tile_reader;
|
||||
|
||||
use crate::fps_meter::FPSMeter;
|
||||
use crate::io::static_database;
|
||||
use crate::render::camera::CameraController;
|
||||
use crate::platform::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
||||
use crate::render::tesselation::TileMask;
|
||||
use crate::render::{camera, shaders};
|
||||
|
||||
@ -24,23 +24,16 @@ use super::piplines::*;
|
||||
use super::shader_ffi::*;
|
||||
use super::tesselation::Tesselated;
|
||||
use super::texture::Texture;
|
||||
use crate::platform::{COLOR_TEXTURE_FORMAT, MIN_BUFFER_SIZE};
|
||||
|
||||
pub struct SceneParams {
|
||||
stroke_width: f32,
|
||||
target_stroke_width: f32,
|
||||
|
||||
last_touch: Option<(f64, f64)>,
|
||||
|
||||
cpu_primitives: Vec<PrimitiveUniform>,
|
||||
pub stroke_width: f32,
|
||||
pub cpu_primitives: Vec<PrimitiveUniform>,
|
||||
}
|
||||
|
||||
impl Default for SceneParams {
|
||||
fn default() -> Self {
|
||||
SceneParams {
|
||||
stroke_width: 1.0,
|
||||
target_stroke_width: 1.0,
|
||||
last_touch: None,
|
||||
cpu_primitives: vec![],
|
||||
}
|
||||
}
|
||||
@ -69,7 +62,7 @@ pub struct State {
|
||||
surface_config: wgpu::SurfaceConfiguration,
|
||||
suspended: bool,
|
||||
|
||||
pub size: winit::dpi::PhysicalSize<u32>,
|
||||
size: winit::dpi::PhysicalSize<u32>,
|
||||
|
||||
render_pipeline: wgpu::RenderPipeline,
|
||||
mask_pipeline: wgpu::RenderPipeline,
|
||||
@ -95,12 +88,10 @@ pub struct State {
|
||||
tile_mask_range: Range<u32>,
|
||||
tile_mask_instances: wgpu::Buffer,
|
||||
|
||||
camera: camera::Camera,
|
||||
pub(crate) camera: camera::Camera,
|
||||
projection: camera::Projection,
|
||||
camera_controller: camera::CameraController,
|
||||
mouse_pressed: bool,
|
||||
|
||||
scene: SceneParams,
|
||||
pub scene: SceneParams,
|
||||
}
|
||||
|
||||
impl SceneParams {
|
||||
@ -401,7 +392,6 @@ impl State {
|
||||
0.1,
|
||||
100000.0,
|
||||
);
|
||||
let camera_controller = camera::CameraController::new(3000.0, 0.2);
|
||||
|
||||
Self {
|
||||
instance,
|
||||
@ -431,8 +421,6 @@ impl State {
|
||||
tile_mask_instances,
|
||||
camera,
|
||||
projection,
|
||||
camera_controller,
|
||||
mouse_pressed: false,
|
||||
tile2_stroke_range,
|
||||
suspended: false, // Initially the app is not suspended
|
||||
}
|
||||
@ -483,81 +471,6 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_input(&mut self, event: &DeviceEvent, window: &Window) -> bool {
|
||||
match event {
|
||||
DeviceEvent::MouseMotion { delta } => {
|
||||
if self.mouse_pressed {
|
||||
warn!("mouse {}", delta.0);
|
||||
self.camera_controller.process_mouse(
|
||||
delta.0 / window.scale_factor(),
|
||||
delta.1 / window.scale_factor(),
|
||||
);
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn window_input(&mut self, event: &WindowEvent, window: &Window) -> bool {
|
||||
match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state,
|
||||
virtual_keycode: Some(key),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => match key {
|
||||
winit::event::VirtualKeyCode::Z => {
|
||||
self.scene.target_stroke_width *= 1.2;
|
||||
true
|
||||
}
|
||||
winit::event::VirtualKeyCode::H => {
|
||||
self.scene.target_stroke_width *= 0.8;
|
||||
true
|
||||
}
|
||||
_ => self.camera_controller.process_keyboard(*key, *state),
|
||||
},
|
||||
WindowEvent::Touch(touch) => {
|
||||
match touch.phase {
|
||||
TouchPhase::Started => {
|
||||
self.scene.last_touch = Some((touch.location.x, touch.location.y))
|
||||
}
|
||||
TouchPhase::Moved | TouchPhase::Ended => {
|
||||
if let Some(start) = self.scene.last_touch {
|
||||
let delta_x = start.0 - touch.location.x;
|
||||
let delta_y = start.1 - touch.location.y;
|
||||
self.camera_controller.process_touch(
|
||||
delta_x / window.scale_factor(),
|
||||
delta_y / window.scale_factor(),
|
||||
);
|
||||
}
|
||||
|
||||
self.scene.last_touch = Some((touch.location.x, touch.location.y))
|
||||
}
|
||||
TouchPhase::Cancelled => {}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
self.camera_controller.process_scroll(delta);
|
||||
true
|
||||
}
|
||||
WindowEvent::MouseInput {
|
||||
button: MouseButton::Left, // Left Mouse Button
|
||||
state,
|
||||
..
|
||||
} => {
|
||||
self.mouse_pressed = *state == ElementState::Pressed;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
|
||||
let frame = self.surface.get_current_texture()?;
|
||||
let scene = &mut self.scene;
|
||||
@ -570,7 +483,7 @@ impl State {
|
||||
&self.globals_uniform_buffer,
|
||||
0,
|
||||
bytemuck::cast_slice(&[GlobalsUniform::new(
|
||||
CameraController::create_camera_uniform(&self.camera, &self.projection),
|
||||
self.camera.create_camera_uniform(&self.projection),
|
||||
)]),
|
||||
);
|
||||
|
||||
@ -662,31 +575,10 @@ impl State {
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
frame.present();
|
||||
|
||||
self.fps_meter.update_and_print();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&mut self, dt: std::time::Duration) {
|
||||
let scene = &mut self.scene;
|
||||
|
||||
self.camera_controller.update_camera(&mut self.camera, dt);
|
||||
|
||||
// Animate the stroke_width to match target_stroke_width
|
||||
scene.stroke_width =
|
||||
scene.stroke_width + (scene.target_stroke_width - scene.stroke_width) / 5.0;
|
||||
|
||||
// Animate the strokes of primitive
|
||||
scene.cpu_primitives[STROKE_PRIM_ID as usize].width = scene.stroke_width;
|
||||
/*
|
||||
scene.cpu_primitives[STROKE_PRIM_ID as usize].color = [
|
||||
(time_secs * 0.8 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs * 0.5 - 1.6).sin() * 0.1 + 0.1,
|
||||
(time_secs - 1.6).sin() * 0.1 + 0.1,
|
||||
1.0,
|
||||
];
|
||||
*/
|
||||
self.fps_meter.update_and_print()
|
||||
}
|
||||
|
||||
pub fn is_suspended(&self) -> bool {
|
||||
self.suspended
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user