/* wearechat - generic multiplayer game with voip Copyright (C) 2025 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use glam::{Affine3A, EulerRot, Mat3, Mat4, Vec2, Vec3, vec3}; pub struct Camera { pos: Vec3, rot: Vec3, fov: f32, pub aspect: f32, } impl Default for Camera { fn default() -> Self { Self::new() } } impl Camera { pub fn new() -> Self { Self { aspect: 1., fov: 1., pos: Vec3::Z * 3., rot: Vec3::ZERO, } } pub fn update(&mut self, input_move: Vec3, input_rot: Vec2, dt: f32) { let speed = 5.; let vel_local = vec3(input_move.z, input_move.y, -input_move.x) * dt * speed; self.pos += self.rotation_mat() * vel_local; self.rot.x += input_rot.x * -0.002; self.rot.y += input_rot.y * -0.002; } pub fn position(&self) -> Vec3 { self.pos } pub fn rotation(&self) -> Vec3 { self.rot } pub fn rotation_mat(&self) -> Mat3 { Mat3::from_euler(EulerRot::YXZ, self.rot.x, self.rot.y, self.rot.z) } pub fn view_matrix(&self) -> Mat4 { Mat4::from_mat3(self.rotation_mat().inverse()) * Mat4::from_translation(-self.pos) } pub fn project_matrix(&self) -> Mat4 { Mat4::perspective_rh(self.fov, self.aspect, 0.01, 300.) } pub fn new_ui_affine(&self) -> Affine3A { Affine3A::from_mat3_translation( self.rotation_mat(), self.pos + self.rotation_mat() * vec3(0., 0., -3.), ) } }