115 lines
3.6 KiB
Rust
115 lines
3.6 KiB
Rust
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<f32>,
|
|
pub rotation: Quaternion<f32>,
|
|
pub view: Matrix4<f32>,
|
|
pub proj: Matrix4<f32>,
|
|
}
|
|
|
|
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<f32>) -> Vector3<f32> {
|
|
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<MeshHandle>
|
|
}
|
|
|
|
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);
|
|
}
|
|
} |