More control options and zoom limits

master
Wynd 2024-11-05 23:06:28 +02:00
parent e1028d3d89
commit c2f7effc71
2 changed files with 45 additions and 16 deletions

View File

@ -1,16 +1,22 @@
use std::sync::Arc;
use winit::{ use winit::{
event::{ElementState, KeyEvent, MouseButton, MouseScrollDelta, WindowEvent}, dpi::PhysicalSize,
event::{MouseButton, MouseScrollDelta, WindowEvent},
keyboard::{KeyCode, PhysicalKey}, keyboard::{KeyCode, PhysicalKey},
}; };
use crate::camera::Camera; use crate::camera::Camera;
const MAX_ZOOM_LEVEL: f32 = 15.0;
pub struct CameraController { pub struct CameraController {
speed: f32, speed: f32,
forward: f32, forward: f32,
cursor_start: (f32, f32), cursor_start: (f32, f32),
movement: (f32, f32), movement: (f32, f32),
is_moving: bool, is_moving: bool,
zoom_level: f32,
} }
impl CameraController { impl CameraController {
@ -21,10 +27,11 @@ impl CameraController {
cursor_start: (0.0, 0.0), cursor_start: (0.0, 0.0),
movement: (0.0, 0.0), movement: (0.0, 0.0),
is_moving: false, 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 { match event {
WindowEvent::MouseInput { state, button, .. } => { WindowEvent::MouseInput { state, button, .. } => {
if state.is_pressed() && *button == MouseButton::Left { if state.is_pressed() && *button == MouseButton::Left {
@ -38,22 +45,42 @@ impl CameraController {
false false
} }
WindowEvent::CursorMoved { position, .. } => { WindowEvent::CursorMoved { position, .. } => {
let mut x = 0.0;
let mut y = 0.0;
if !self.is_moving { if !self.is_moving {
self.cursor_start = (position.x as f32, position.y as f32); 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 { else {
let x = -self.cursor_start.0 + position.x as f32; x = -self.cursor_start.0 + position.x as f32;
let x = x * 0.000001; x *= 0.000001;
let y = self.cursor_start.1 - position.y as f32; y = self.cursor_start.1 - position.y as f32;
let y = y * 0.000001; y *= 0.000001;
}
self.movement = (x, y); self.movement = (x, y);
}
true true
} }
WindowEvent::MouseWheel { delta, .. } => match delta { WindowEvent::MouseWheel { delta, .. } => match delta {
MouseScrollDelta::LineDelta(_, y) => { MouseScrollDelta::LineDelta(_, y) => {
self.zoom_level += y;
if self.zoom_level >= 0.0 && self.zoom_level <= MAX_ZOOM_LEVEL {
self.forward = *y; self.forward = *y;
}
self.zoom_level = self.zoom_level.clamp(0.0, MAX_ZOOM_LEVEL);
true true
} }
_ => false, _ => false,
@ -75,13 +102,11 @@ impl CameraController {
camera.eye -= forward_norm * self.speed; camera.eye -= forward_norm * self.speed;
} }
if self.is_moving {
camera.eye.x += self.movement.0; camera.eye.x += self.movement.0;
camera.eye.y += self.movement.1; camera.eye.y += self.movement.1;
camera.target.x += self.movement.0; camera.target.x += self.movement.0;
camera.target.y += self.movement.1; camera.target.y += self.movement.1;
}
self.forward = 0.0; self.forward = 0.0;
} }

View File

@ -42,6 +42,7 @@ pub struct State<'a> {
queue: wgpu::Queue, queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration, config: wgpu::SurfaceConfiguration,
size: winit::dpi::PhysicalSize<u32>, size: winit::dpi::PhysicalSize<u32>,
wsize: (f64, f64),
pub window: Arc<Window>, pub window: Arc<Window>,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
vertex_buffer: wgpu::Buffer, vertex_buffer: wgpu::Buffer,
@ -56,6 +57,7 @@ pub struct State<'a> {
impl<'a> State<'a> { impl<'a> State<'a> {
pub fn new(window: Arc<Window>, image: image::RgbaImage) -> Self { pub fn new(window: Arc<Window>, image: image::RgbaImage) -> Self {
let window_size = window.inner_size(); 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 { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::PRIMARY, backends: wgpu::Backends::PRIMARY,
@ -178,6 +180,7 @@ impl<'a> State<'a> {
queue, queue,
config, config,
size: window_size, size: window_size,
wsize,
window, window,
render_pipeline, render_pipeline,
vertex_buffer, vertex_buffer,
@ -193,6 +196,7 @@ impl<'a> State<'a> {
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
if new_size.width > 0 && new_size.height > 0 { if new_size.width > 0 && new_size.height > 0 {
self.size = new_size; self.size = new_size;
self.wsize = (new_size.width as f64, new_size.height as f64);
self.config.width = new_size.width; self.config.width = new_size.width;
self.config.height = new_size.height; self.config.height = new_size.height;
self.surface.configure(&self.device, &self.config); 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 { 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 false
} }