diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-05-24 02:34:27 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-05-24 02:34:27 +0200 |
commit | 63d0c704e889f0b05f03f39903378324ca5b6431 (patch) | |
tree | c94be1e2dabc05fba54577d2a639da44a6f65c04 /src/gfx/camera.rs | |
parent | ef8c75b9dc47142527fc1741d75cf34c66c3ac9d (diff) | |
download | mt_client-63d0c704e889f0b05f03f39903378324ca5b6431.tar.xz |
Respect server-sent movement settings
Diffstat (limited to 'src/gfx/camera.rs')
-rw-r--r-- | src/gfx/camera.rs | 119 |
1 files changed, 98 insertions, 21 deletions
diff --git a/src/gfx/camera.rs b/src/gfx/camera.rs index 874c9fc..32d39ad 100644 --- a/src/gfx/camera.rs +++ b/src/gfx/camera.rs @@ -1,57 +1,134 @@ use super::{gpu::Gpu, util::MatrixUniform}; -use cgmath::{prelude::*, Deg, Matrix4, Rad}; +use cgmath::{prelude::*, Deg, Euler, Matrix3, Matrix4, Point3, Rad, Vector3}; use collision::Frustum; -use fps_camera::{FirstPerson, FirstPersonSettings}; use std::time::Duration; +#[derive(Default)] +pub struct CameraInput { + pub forward: bool, + pub left: bool, + pub backward: bool, + pub right: bool, + pub jump: bool, + pub sneak: bool, + pub mouse_x: f32, + pub mouse_y: f32, +} + pub struct Camera { + pub pos: Point3<f32>, + pub rot: Euler<Deg<f32>>, + pub speed: f32, pub fov: Rad<f32>, pub view: Matrix4<f32>, pub proj: Matrix4<f32>, pub frustum: Frustum<f32>, - pub first_person: FirstPerson, pub uniform: MatrixUniform, pub layout: wgpu::BindGroupLayout, + pub input: CameraInput, +} + +pub trait ToNative { + fn to_native(self) -> Self; +} + +impl<T> ToNative for Euler<T> +where + T: From<Deg<f32>> + std::ops::Add<T, Output = T> + std::ops::Neg<Output = T>, +{ + fn to_native(mut self) -> Self { + self.y = -self.y + Deg(270.0).into(); + self.z = -self.z; + self + } } impl Camera { pub fn new(gpu: &Gpu) -> Self { - let first_person = FirstPerson::new( - [0.0, 0.0, 0.0], - FirstPersonSettings { - speed_horizontal: 10.0, - speed_vertical: 10.0, - mouse_sensitivity_horizontal: 1.0, - mouse_sensitivity_vertical: 1.0, - }, - ); - let layout = MatrixUniform::layout(&gpu.device, "camera"); let uniform = MatrixUniform::new(&gpu.device, &layout, Matrix4::identity(), "camera", true); Self { + pos: Point3::new(0.0, 0.0, 0.0), + rot: Euler { + x: Deg(0.0), + y: Deg(0.0), + z: Deg(0.0), + }, + speed: 0.0, fov: Deg(90.0).into(), proj: Matrix4::identity(), view: Matrix4::identity(), frustum: Frustum::from_matrix4(Matrix4::identity()).unwrap(), - first_person, uniform, layout, + input: Default::default(), } } pub fn update(&mut self, gpu: &Gpu, dt: Duration) { - self.first_person.yaw += Rad::from(Deg(180.0)).0; - self.first_person.yaw *= -1.0; + let dt = dt.as_secs_f32(); + + let sensitivity = dt * 2.0; + + self.rot.y += Deg(sensitivity * self.input.mouse_x); + self.rot.z += Deg(sensitivity * self.input.mouse_y); + self.rot.z.0 = self.rot.z.0.min(89.9).max(-89.9); + + self.input.mouse_x = 0.0; + self.input.mouse_y = 0.0; + + let rot = Matrix3::from(self.rot.to_native()); - let cam = self.first_person.camera(dt.as_secs_f32()); + let forward = rot * Vector3::unit_x(); + let up = rot * Vector3::unit_y(); - self.first_person.yaw *= -1.0; - self.first_person.yaw -= Rad::from(Deg(180.0)).0; + { + let mut forward = forward; + let mut up = up; + let mut right = forward.cross(up); - self.first_person.position = cam.position; + let pitch_move = false; + + if !pitch_move { + forward.y = 0.0; + right.y = 0.0; + up = Vector3::unit_y(); + } + + let mut hdir = Vector3::zero(); + let mut vdir = Vector3::zero(); + + if self.input.forward { + hdir += forward; + } + if self.input.backward { + hdir -= forward; + } + if self.input.right { + hdir += right; + } + if self.input.left { + hdir -= right; + } + if self.input.jump { + vdir += up; + } + if self.input.sneak { + vdir -= up; + } + + self.pos += self.speed + * dt + * (vdir + + if hdir.is_zero() { + hdir + } else { + hdir.normalize() + }); + } - self.view = Matrix4::from(cam.orthogonal()); + self.view = Matrix4::look_at_dir(self.pos, forward, up); self.uniform.set(&gpu.queue, self.proj * self.view); } |