witchcraft_renderer/types/
camera.rs1use cgmath::Matrix4;
2
3#[rustfmt::skip]
5pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
6 1.0, 0.0, 0.0, 0.0,
7 0.0, 1.0, 0.0, 0.0,
8 0.0, 0.0, 0.5, 0.0,
9 0.0, 0.0, 0.5, 1.0,
10);
11
12pub struct Camera {
14 pub eye: cgmath::Point3<f32>,
15 pub target: cgmath::Point3<f32>,
16 pub up: cgmath::Vector3<f32>,
17 pub aspect: f32,
18 pub fovy: f32,
19 pub zfar: f32,
20 pub znear: f32,
21}
22impl Camera {
23 pub fn build_view_proj_matrix(&self) -> Matrix4<f32> {
24 let view = cgmath::Matrix4::look_at_rh(self.eye, self.target, self.up);
26 let proj = cgmath::perspective(cgmath::Deg(self.fovy), self.aspect, self.znear, self.zfar);
28
29 OPENGL_TO_WGPU_MATRIX * proj * view }
31}
32
33#[repr(C)]
34#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
35pub struct CameraUniform {
36 view_proj: [[f32; 4]; 4],
38}
39impl CameraUniform {
40 pub fn new() -> Self {
41 use cgmath::SquareMatrix;
42 Self {
43 view_proj: cgmath::Matrix4::identity().into(),
44 }
45 }
46
47 pub fn update_view_proj(&mut self, camera: &Camera) {
48 self.view_proj = camera.build_view_proj_matrix().into();
49 }
50}
51
52#[derive(Clone, Copy)]
53pub enum CameraControllerMovement {
54 X(f32),
56 Y(f32),
58 Z(f32),
60 RotX(f32),
62 RotY(f32),
64 RotZ(f32),
66}
67
68pub struct CameraController<'a> {
70 camera: &'a mut Camera,
71}
72impl<'a> CameraController<'a> {
73 pub fn new(camera: &'a mut Camera) -> Self {
74 Self { camera: camera }
75 }
76
77 pub fn update_camera(&mut self, movement: CameraControllerMovement) {
79 use cgmath::InnerSpace;
80 let forward = self.camera.target - self.camera.eye;
82 let right = forward.normalize().cross(self.camera.up);
83
84 use crate::CameraControllerMovement::*;
85 match movement {
86 X(x) => self.camera.eye += right.normalize() * x,
87 Y(y) => self.camera.eye += self.camera.up * y,
88 Z(z) => self.camera.eye += forward.normalize() * z,
89 RotX(rot) => {
90 self.camera.eye = self.camera.target
91 - (forward + self.camera.up * rot).normalize() * forward.magnitude()
92 }
93 RotY(rot) => {
94 self.camera.eye =
95 self.camera.target - (forward + forward * rot).normalize() * forward.magnitude()
96 }
97 RotZ(rot) => {
98 self.camera.eye = self.camera.target
99 - (forward + self.camera.up * rot).normalize() * forward.magnitude()
100 }
101 }
102 }
103
104 pub fn update_camera_batch(&mut self, movements: &[CameraControllerMovement]) {
106 for movement in movements {
107 self.update_camera(*movement);
108 }
109 }
110}