Files
rust-engine/src/game/player.rs
2020-12-02 10:21:51 +01:00

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);
}
}