mirror of
https://github.com/guilhermewerner/wgpu-renderer
synced 2025-06-15 21:34:21 +00:00
Update project
This commit is contained in:
20
Source/Camera/Camera.rs
Normal file
20
Source/Camera/Camera.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use super::OPENGL_TO_WGPU_MATRIX;
|
||||
|
||||
pub struct Camera {
|
||||
pub eye: cgmath::Point3<f32>,
|
||||
pub target: cgmath::Point3<f32>,
|
||||
pub up: cgmath::Vector3<f32>,
|
||||
pub aspect: f32,
|
||||
pub fovy: f32,
|
||||
pub znear: f32,
|
||||
pub zfar: f32,
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn BuildViewProjectionMatrix(&self) -> cgmath::Matrix4<f32> {
|
||||
let view = cgmath::Matrix4::look_at_rh(self.eye, self.target, self.up);
|
||||
let proj = cgmath::perspective(cgmath::Deg(self.fovy), self.aspect, self.znear, self.zfar);
|
||||
|
||||
OPENGL_TO_WGPU_MATRIX * proj * view
|
||||
}
|
||||
}
|
105
Source/Camera/CameraController.rs
Normal file
105
Source/Camera/CameraController.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use super::Camera;
|
||||
use winit::event::*;
|
||||
|
||||
pub struct CameraController {
|
||||
pub speed: f32,
|
||||
pub is_up_pressed: bool,
|
||||
pub is_down_pressed: bool,
|
||||
pub is_forward_pressed: bool,
|
||||
pub is_backward_pressed: bool,
|
||||
pub is_left_pressed: bool,
|
||||
pub is_right_pressed: bool,
|
||||
}
|
||||
|
||||
impl CameraController {
|
||||
pub fn New(speed: f32) -> Self {
|
||||
Self {
|
||||
speed,
|
||||
is_up_pressed: false,
|
||||
is_down_pressed: false,
|
||||
is_forward_pressed: false,
|
||||
is_backward_pressed: false,
|
||||
is_left_pressed: false,
|
||||
is_right_pressed: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ProcessEvents(&mut self, event: &WindowEvent) -> bool {
|
||||
match event {
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state,
|
||||
virtual_keycode: Some(keycode),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let is_pressed = *state == ElementState::Pressed;
|
||||
match keycode {
|
||||
VirtualKeyCode::Space => {
|
||||
self.is_up_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
VirtualKeyCode::LShift => {
|
||||
self.is_down_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
VirtualKeyCode::W | VirtualKeyCode::Up => {
|
||||
self.is_forward_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
VirtualKeyCode::A | VirtualKeyCode::Left => {
|
||||
self.is_left_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
VirtualKeyCode::S | VirtualKeyCode::Down => {
|
||||
self.is_backward_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
VirtualKeyCode::D | VirtualKeyCode::Right => {
|
||||
self.is_right_pressed = is_pressed;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn UpdateCamera(&self, camera: &mut Camera) {
|
||||
use cgmath::InnerSpace;
|
||||
|
||||
let forward = camera.target - camera.eye;
|
||||
let forward_norm = forward.normalize();
|
||||
let forward_mag = forward.magnitude();
|
||||
|
||||
// Prevents glitching when camera gets too close to the
|
||||
// center of the scene.
|
||||
if self.is_forward_pressed && forward_mag > self.speed {
|
||||
camera.eye += forward_norm * self.speed;
|
||||
}
|
||||
|
||||
if self.is_backward_pressed {
|
||||
camera.eye -= forward_norm * self.speed;
|
||||
}
|
||||
|
||||
let right = forward_norm.cross(camera.up);
|
||||
|
||||
// Redo radius calc in case the up/ down is pressed.
|
||||
let forward = camera.target - camera.eye;
|
||||
let forward_mag = forward.magnitude();
|
||||
|
||||
if self.is_right_pressed {
|
||||
// Rescale the distance between the target and eye so
|
||||
// that it doesn't change. The eye therefore still
|
||||
// lies on the circle made by the target and eye.
|
||||
camera.eye = camera.target - (forward + right * self.speed).normalize() * forward_mag;
|
||||
}
|
||||
|
||||
if self.is_left_pressed {
|
||||
camera.eye = camera.target - (forward - right * self.speed).normalize() * forward_mag;
|
||||
}
|
||||
}
|
||||
}
|
24
Source/Camera/CameraUniform.rs
Normal file
24
Source/Camera/CameraUniform.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use super::Camera;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use cgmath::SquareMatrix;
|
||||
|
||||
// This is so we can store this in a buffer
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Pod, Zeroable)]
|
||||
pub struct CameraUniform {
|
||||
// We can't use cgmath with bytemuck directly so we'll have
|
||||
// to convert the Matrix4 into a 4x4 f32 array
|
||||
pub view_proj: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
impl CameraUniform {
|
||||
pub fn New() -> Self {
|
||||
Self {
|
||||
view_proj: cgmath::Matrix4::identity().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn UpdateViewProjection(&mut self, camera: &Camera) {
|
||||
self.view_proj = camera.BuildViewProjectionMatrix().into();
|
||||
}
|
||||
}
|
20
Source/Camera/mod.rs
Normal file
20
Source/Camera/mod.rs
Normal file
@ -0,0 +1,20 @@
|
||||
/// Matrix to scale and translate from OpenGL coordinate system to WGPU.
|
||||
#[rustfmt::skip]
|
||||
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.0, 0.0, 0.5, 1.0,
|
||||
);
|
||||
|
||||
#[path = "Camera.rs"]
|
||||
mod _Camera;
|
||||
pub use self::_Camera::*;
|
||||
|
||||
#[path = "CameraController.rs"]
|
||||
mod _CameraController;
|
||||
pub use self::_CameraController::*;
|
||||
|
||||
#[path = "CameraUniform.rs"]
|
||||
mod _CameraUniform;
|
||||
pub use self::_CameraUniform::*;
|
Reference in New Issue
Block a user