use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3, SquareMatrix, vec3, Vector3}; use crate::game::player::PlayerMovementMode::{FirstPerson, Flying}; use crate::input::InputState; use crate::MeshHandle; use crate::vulkan::{ gameobject::Updatable, VulkanRenderer }; pub struct Camera { pub fov_y: f32, pub position: Vector3, pub rotation: Quaternion, pub view: Matrix4, pub proj: Matrix4, } impl Camera { pub fn new() -> Camera { Camera { fov_y: 45.0, position: vec3(0.0, 0.0, 0.0), rotation: Quaternion::one(), view: Matrix4::identity(), proj: Matrix4::identity(), } } pub fn update(&mut self, renderer: &mut VulkanRenderer) { // Camera stuff self.view = Matrix4::from(self.rotation) * Matrix4::from_translation(self.position); self.proj = cgmath::perspective( Rad::from(Deg(self.fov_y)), renderer.game_data.dimensions[0] as f32 / renderer.game_data.dimensions[1] as f32, 0.1, 100.0 ); self.proj.y.y *= -1.0; renderer.game_data.line_push_constants.view = self.view.into(); renderer.game_data.line_push_constants.projection = self.proj.into(); } pub fn transform_vector(&self, vec: Vector3) -> Vector3 { self.rotation.invert().rotate_vector(vec) } } #[derive(PartialEq)] pub enum PlayerMovementMode { FirstPerson, Flying, } pub struct Player { pub camera: Camera, pub movement_mode: PlayerMovementMode, pub movement_speed: f32, pub look_sensitivity: f32, pub height: f32, cube_mesh: Option } impl Player { pub fn new() -> Player { Player { camera: Camera::new(), movement_mode: FirstPerson, movement_speed: 3.0, look_sensitivity: 10.0, height: -1.0, cube_mesh: None } } } impl Updatable for Player { fn update(&mut self, delta_time: f32, input: &InputState, renderer: &mut VulkanRenderer) { // Rotation self.camera.rotation = self.camera.rotation * Quaternion::from_angle_y(Deg(input.get_axis("look_horizontal") * delta_time * self.look_sensitivity)); self.camera.rotation = Quaternion::from_angle_x(Deg(input.get_axis("look_vertical") * delta_time * self.look_sensitivity)) * self.camera.rotation; // Movement if self.movement_mode == FirstPerson { self.camera.position.y = self.height; let mut forward_vector = self.camera.transform_vector(vec3(0.0, 0.0, 1.0)); forward_vector.y = 0.0; forward_vector = forward_vector.normalize(); self.camera.position += forward_vector * delta_time * input.get_axis("move_forward") * self.movement_speed; let right_vector = forward_vector.cross(vec3(0.0, 1.0, 0.0)); self.camera.position += right_vector * delta_time * input.get_axis("move_sideways") * self.movement_speed; } else if self.movement_mode == Flying { self.camera.position += self.camera.transform_vector(vec3( input.get_axis("move_sideways") * -self.movement_speed, 0.0, input.get_axis("move_forward") * self.movement_speed)) * delta_time; } // Spawn cube if input.button_just_released("test") { if self.cube_mesh.is_none() { // self.cube_mesh = Some() } } // Update self.camera.update(renderer); } }