use std::sync::Arc; use winit::{ 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 { pub fn new(speed: f32) -> Self { Self { speed, forward: 0.0, cursor_start: (0.0, 0.0), movement: (0.0, 0.0), is_moving: false, zoom_level: 1.0, } } 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 { self.is_moving = true; return true; } else { self.is_moving = false; self.movement = (0.0, 0.0); } 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 { 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.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, }, _ => false, } } pub fn update_camera(&mut self, camera: &mut Camera) { use cgmath::InnerSpace; let forward = camera.target - camera.eye; let forward_norm = forward.normalize(); if self.forward > 0.0 { camera.eye += forward_norm * self.speed; } else if self.forward < 0.0 { camera.eye -= forward_norm * self.speed; } camera.eye.x += self.movement.0; camera.eye.y += self.movement.1; camera.target.x += self.movement.0; camera.target.y += self.movement.1; self.forward = 0.0; } }