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