camera rotation
This commit is contained in:
+2
-3
@@ -2,7 +2,6 @@ use std::sync::Arc;
|
||||
use winit::event::Event;
|
||||
use winit::{window::Window, dpi::PhysicalSize, event::WindowEvent};
|
||||
use wgpu::util::DeviceExt;
|
||||
use futures::executor::block_on;
|
||||
|
||||
use crate::vertex::Vertex;
|
||||
use crate::texture::Texture;
|
||||
@@ -51,7 +50,7 @@ impl App {
|
||||
format: adapter.get_swap_chain_preferred_format(&surface),
|
||||
width: size.width,
|
||||
height: size.height,
|
||||
present_mode: wgpu::PresentMode::Mailbox, // Fifo = Vsync
|
||||
present_mode: wgpu::PresentMode::Immediate, // Fifo = Vsync
|
||||
};
|
||||
let swapchain = device.create_swap_chain(&surface, &swapchain_desc);
|
||||
(swapchain_desc, swapchain)
|
||||
@@ -217,7 +216,7 @@ impl App {
|
||||
let camera = Camera::new((0.0, 0.0, 2.0).into(), (0.0, 0.0, -1.0).into(), aspect);
|
||||
let mut uniforms = Uniforms::new();
|
||||
uniforms.update_projection_matrix(&camera);
|
||||
let camera_controller = CameraController::new(2.0);
|
||||
let camera_controller = CameraController::new();
|
||||
|
||||
// Buffers
|
||||
let vertex_buffer = Self::create_buffer(&device, wgpu::BufferUsage::VERTEX, bytemuck::cast_slice(VERTICES));
|
||||
|
||||
+38
-16
@@ -1,6 +1,6 @@
|
||||
use winit::event::Event;
|
||||
use winit::event::{WindowEvent, DeviceEvent, KeyboardInput, ElementState, VirtualKeyCode};
|
||||
use cgmath::InnerSpace;
|
||||
use cgmath::{InnerSpace, Matrix4, Rad, Deg, Transform, Vector3};
|
||||
use crate::camera::Camera;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -11,25 +11,39 @@ struct CameraMovement {
|
||||
pub back: bool,
|
||||
pub left: bool,
|
||||
pub right: bool,
|
||||
pub speed: f32,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct CameraRotation {
|
||||
pub yaw: f32, // vertical axis
|
||||
pub pitch: f32, // horizontal axis
|
||||
pub last_update: Option<std::time::Instant>
|
||||
pub sensitivity: f32,
|
||||
}
|
||||
|
||||
impl CameraRotation {
|
||||
|
||||
fn yaw_rad(&mut self) -> Rad<f32> { Rad::from(Deg(self.yaw)) }
|
||||
fn pitch_rad(&mut self) -> Rad<f32> { Rad::from(Deg(self.pitch)) }
|
||||
|
||||
fn yaw_rot(&mut self) -> Matrix4<f32> { Matrix4::from_angle_y(-self.yaw_rad()) }
|
||||
fn pitch_rot(&mut self)-> Matrix4<f32> { Matrix4::from_angle_x(-self.pitch_rad()) }
|
||||
}
|
||||
|
||||
pub struct CameraController {
|
||||
movement: CameraMovement,
|
||||
rotation: CameraRotation,
|
||||
speed: f32
|
||||
}
|
||||
|
||||
impl CameraController {
|
||||
pub fn new(speed: f32) -> Self {
|
||||
let rotation = CameraRotation { yaw: 0.0, pitch: 0.0, last_update: None };
|
||||
Self { movement: CameraMovement::default(), rotation, speed }
|
||||
pub fn new() -> Self {
|
||||
|
||||
let mut movement = CameraMovement::default();
|
||||
movement.speed = 2.0;
|
||||
let mut rotation = CameraRotation::default();
|
||||
rotation.sensitivity = 0.2;
|
||||
|
||||
Self { movement, rotation }
|
||||
}
|
||||
|
||||
pub fn handle_input(&mut self, event: &Event<()>) -> bool {
|
||||
@@ -39,8 +53,8 @@ impl CameraController {
|
||||
WindowEvent::KeyboardInput { input: KeyboardInput { state, virtual_keycode: Some(keycode), .. }, .. } => {
|
||||
let is_pressed = *state == ElementState::Pressed;
|
||||
match keycode {
|
||||
VirtualKeyCode::Space => { self.movement.up = is_pressed; true }
|
||||
VirtualKeyCode::LShift => { self.movement.down = is_pressed; true }
|
||||
VirtualKeyCode::Q => { self.movement.down = is_pressed; true }
|
||||
VirtualKeyCode::E | VirtualKeyCode::Space => { self.movement.up = is_pressed; true }
|
||||
VirtualKeyCode::W | VirtualKeyCode::Up => { self.movement.fwd = is_pressed; true }
|
||||
VirtualKeyCode::A | VirtualKeyCode::Left => { self.movement.left = is_pressed; true }
|
||||
VirtualKeyCode::S | VirtualKeyCode::Down => { self.movement.back = is_pressed; true }
|
||||
@@ -54,12 +68,14 @@ impl CameraController {
|
||||
Event::DeviceEvent { device_id: _, event } => {
|
||||
match event {
|
||||
DeviceEvent::MouseMotion { delta } => {
|
||||
if let Some(last_update) = self.rotation.last_update {
|
||||
let elapsed = last_update.elapsed().as_secs_f32();
|
||||
self.rotation.yaw += (delta.0 as f32) / elapsed;
|
||||
self.rotation.pitch += (delta.1 as f32) / elapsed;
|
||||
}
|
||||
self.rotation.last_update = Some(std::time::Instant::now());
|
||||
// Increment
|
||||
self.rotation.yaw += delta.0 as f32 * self.rotation.sensitivity;
|
||||
self.rotation.pitch -= delta.1 as f32 * self.rotation.sensitivity;
|
||||
// Clamp
|
||||
if self.rotation.yaw > 360.0 { self.rotation.yaw -= 360.0; }
|
||||
if self.rotation.yaw < 0.0 { self.rotation.yaw += 360.0; }
|
||||
self.rotation.pitch = self.rotation.pitch.clamp(-70.0, 70.0);
|
||||
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
@@ -71,8 +87,14 @@ impl CameraController {
|
||||
|
||||
pub fn update_camera(&mut self, camera: &mut Camera, delta_time: f32) {
|
||||
|
||||
// Rotation
|
||||
let yaw_rot = self.rotation.yaw_rot();
|
||||
let pitch_rot = self.rotation.pitch_rot();
|
||||
camera.forward = yaw_rot.transform_vector(pitch_rot.transform_vector(Vector3::unit_z()));
|
||||
camera.up = yaw_rot.transform_vector(pitch_rot.transform_vector(Vector3::unit_y()));
|
||||
|
||||
// Movement amount
|
||||
let amount = delta_time * self.speed;
|
||||
let amount = delta_time * self.movement.speed;
|
||||
|
||||
// Forward and backwards
|
||||
if self.movement.fwd && camera.forward.magnitude() > amount { camera.position += camera.forward.normalize() * amount; }
|
||||
@@ -87,6 +109,6 @@ impl CameraController {
|
||||
if self.movement.right { camera.position += right * amount; }
|
||||
if self.movement.left { camera.position -= right * amount; }
|
||||
|
||||
println!("Yaw: {}", self.rotation.yaw);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user