diff --git a/src/controller.rs b/src/controller.rs index d88b8b1..696caf9 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -1,16 +1,22 @@ +use std::sync::Arc; + use winit::{ - event::{ElementState, KeyEvent, MouseButton, MouseScrollDelta, WindowEvent}, + dpi::PhysicalSize, + event::{MouseButton, MouseScrollDelta, WindowEvent}, keyboard::{KeyCode, PhysicalKey}, }; use crate::camera::Camera; +const MAX_ZOOM_LEVEL: f32 = 15.0; + pub struct CameraController { speed: f32, forward: f32, cursor_start: (f32, f32), movement: (f32, f32), is_moving: bool, + zoom_level: f32, } impl CameraController { @@ -21,10 +27,11 @@ impl CameraController { cursor_start: (0.0, 0.0), movement: (0.0, 0.0), is_moving: false, + zoom_level: 1.0, } } - pub fn process_events(&mut self, event: &WindowEvent) -> bool { + pub fn process_events(&mut self, window_size: (f64, f64), event: &WindowEvent) -> bool { match event { WindowEvent::MouseInput { state, button, .. } => { if state.is_pressed() && *button == MouseButton::Left { @@ -38,22 +45,42 @@ impl CameraController { false } WindowEvent::CursorMoved { position, .. } => { + let mut x = 0.0; + let mut y = 0.0; + if !self.is_moving { self.cursor_start = (position.x as f32, position.y as f32); + + x = match position.x { + x if x < 100.0 => -0.0005, + x if x > window_size.0 - 100.0 => 0.0005, + _ => 0.0, + }; + + y = match position.y { + y if y < 100.0 => 0.0005, + y if y > window_size.1 - 100.0 => -0.0005, + _ => 0.0, + }; } else { - let x = -self.cursor_start.0 + position.x as f32; - let x = x * 0.000001; - let y = self.cursor_start.1 - position.y as f32; - let y = y * 0.000001; - - self.movement = (x, y); + x = -self.cursor_start.0 + position.x as f32; + x *= 0.000001; + y = self.cursor_start.1 - position.y as f32; + y *= 0.000001; } + + self.movement = (x, y); + true } WindowEvent::MouseWheel { delta, .. } => match delta { MouseScrollDelta::LineDelta(_, y) => { - self.forward = *y; + self.zoom_level += y; + if self.zoom_level >= 0.0 && self.zoom_level <= MAX_ZOOM_LEVEL { + self.forward = *y; + } + self.zoom_level = self.zoom_level.clamp(0.0, MAX_ZOOM_LEVEL); true } _ => false, @@ -75,13 +102,11 @@ impl CameraController { camera.eye -= forward_norm * self.speed; } - if self.is_moving { - camera.eye.x += self.movement.0; - camera.eye.y += self.movement.1; + camera.eye.x += self.movement.0; + camera.eye.y += self.movement.1; - camera.target.x += self.movement.0; - camera.target.y += self.movement.1; - } + camera.target.x += self.movement.0; + camera.target.y += self.movement.1; self.forward = 0.0; } diff --git a/src/state.rs b/src/state.rs index 54a568a..835f752 100644 --- a/src/state.rs +++ b/src/state.rs @@ -42,6 +42,7 @@ pub struct State<'a> { queue: wgpu::Queue, config: wgpu::SurfaceConfiguration, size: winit::dpi::PhysicalSize, + wsize: (f64, f64), pub window: Arc, render_pipeline: wgpu::RenderPipeline, vertex_buffer: wgpu::Buffer, @@ -56,6 +57,7 @@ pub struct State<'a> { impl<'a> State<'a> { pub fn new(window: Arc, image: image::RgbaImage) -> Self { let window_size = window.inner_size(); + let wsize = (window_size.width as f64, window_size.height as f64); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::PRIMARY, @@ -178,6 +180,7 @@ impl<'a> State<'a> { queue, config, size: window_size, + wsize, window, render_pipeline, vertex_buffer, @@ -193,6 +196,7 @@ impl<'a> State<'a> { pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { if new_size.width > 0 && new_size.height > 0 { self.size = new_size; + self.wsize = (new_size.width as f64, new_size.height as f64); self.config.width = new_size.width; self.config.height = new_size.height; self.surface.configure(&self.device, &self.config); @@ -200,7 +204,7 @@ impl<'a> State<'a> { } pub fn input(&mut self, event: &winit::event::WindowEvent) -> bool { - self.camera_controller.process_events(&event); + self.camera_controller.process_events(self.wsize, event); false }