summaryrefslogtreecommitdiff
path: root/src/gfx/camera.rs
diff options
context:
space:
mode:
authorLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-24 02:34:27 +0200
committerLizzy Fleckenstein <eliasfleckenstein@web.de>2023-05-24 02:34:27 +0200
commit63d0c704e889f0b05f03f39903378324ca5b6431 (patch)
treec94be1e2dabc05fba54577d2a639da44a6f65c04 /src/gfx/camera.rs
parentef8c75b9dc47142527fc1741d75cf34c66c3ac9d (diff)
downloadmt_client-63d0c704e889f0b05f03f39903378324ca5b6431.tar.xz
Respect server-sent movement settings
Diffstat (limited to 'src/gfx/camera.rs')
-rw-r--r--src/gfx/camera.rs119
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);
}