diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index 39bba6b469..d4655e0f49 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -10,6 +10,7 @@ const INTERP_TIME: f32 = 0.1; pub const MIN_ZOOM: f32 = 0.1; // Possible TODO: Add more modes +#[derive(PartialEq, Clone, Copy)] pub enum CameraMode { FirstPerson, ThirdPerson, @@ -19,12 +20,11 @@ pub struct Camera { tgt_focus: Vec3, focus: Vec3, ori: Vec3, - pub tgt_dist: f32, + tgt_dist: f32, dist: f32, fov: f32, aspect: f32, mode: CameraMode, - can_zoom: bool, last_time: Option, } @@ -41,7 +41,6 @@ impl Camera { fov: 1.1, aspect, mode, - can_zoom: false, last_time: None, } @@ -115,10 +114,13 @@ impl Camera { /// Zoom the camera by the given delta, limiting the input accordingly. pub fn zoom_by(&mut self, delta: f32) { - if self.can_zoom { - // Clamp camera dist to the 0 <= x <= infinity range - self.tgt_dist = (self.tgt_dist + delta).max(2.0).min(100.0); - } + match self.mode { + CameraMode::ThirdPerson => { + // Clamp camera dist to the 2 <= x <= infinity range + self.tgt_dist = (self.tgt_dist + delta).max(2.0); + } + CameraMode::FirstPerson => {} + }; } /// Get the distance of the camera from the target @@ -173,18 +175,21 @@ impl Camera { /// Set the mode of the camera. pub fn set_mode(&mut self, mode: CameraMode) { - self.mode = mode; - match self.mode { - CameraMode::ThirdPerson => { - self.can_zoom = true; - if self.tgt_dist == MIN_ZOOM { + if self.mode != mode { + self.mode = mode; + match self.mode { + CameraMode::ThirdPerson => { self.zoom_by(5.0); } - } - CameraMode::FirstPerson => { - self.set_distance(MIN_ZOOM); - self.can_zoom = false; + CameraMode::FirstPerson => { + self.set_distance(MIN_ZOOM); + } } } } + + /// Get the mode of the camera + pub fn get_mode(&self) -> CameraMode { + self.mode + } } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 5fd0d89035..9152d33558 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -7,7 +7,7 @@ use crate::{ render::{ Consts, FigureBoneData, FigureLocals, FigurePipeline, Globals, Light, Mesh, Model, Renderer, }, - scene::camera::{Camera, MIN_ZOOM}, + scene::camera::{Camera, CameraMode}, }; use client::Client; use common::{ @@ -900,7 +900,7 @@ impl FigureMgr { .0; // Don't render the player's body while in first person mode - if camera.tgt_dist == MIN_ZOOM + if camera.get_mode() == CameraMode::FirstPerson && client .state() .read_storage::() diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 6d22c499e4..882d78cb2b 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -2,7 +2,7 @@ use crate::{ hud::{DebugInfo, Event as HudEvent, Hud}, key_state::KeyState, render::Renderer, - scene::Scene, + scene::{camera::Camera, Scene}, settings::Settings, window::{Event, GameInput, Window}, Direction, Error, GlobalState, PlayState, PlayStateResult, @@ -91,6 +91,13 @@ impl PlayState for SessionState { self.client.borrow_mut().send_chat(cmd.to_string()); } } + // Compute camera data + let get_cam_data = |camera: &Camera, client: &Client| { + let (view_mat, _, cam_pos) = camera.compute_dependents(client); + let cam_dir: Vec3 = Vec3::from(view_mat.inverted() * -Vec4::unit_z()); + + (cam_dir, cam_pos) + }; // Game loop let mut current_client_state = self.client.borrow().get_client_state(); @@ -121,9 +128,7 @@ impl PlayState for SessionState { .get(client.entity()) .is_some() { - let cam_pos = self.scene.camera().compute_dependents(&client).2; - let cam_dir = - (self.scene.camera().get_focus_pos() - cam_pos).normalized(); + let (cam_dir, cam_pos) = get_cam_data(&self.scene.camera(), &client); let (d, b) = { let terrain = client.state().terrain(); @@ -150,9 +155,8 @@ impl PlayState for SessionState { .get(client.entity()) .is_some() { - let cam_pos = self.scene.camera().compute_dependents(&client).2; - let cam_dir = - (self.scene.camera().get_focus_pos() - cam_pos).normalized(); + let (cam_dir, cam_pos) = + get_cam_data(&self.scene.camera(), &client); let (d, b) = { let terrain = client.state().terrain(); @@ -179,9 +183,8 @@ impl PlayState for SessionState { .is_some() { if state { - let cam_pos = self.scene.camera().compute_dependents(&client).2; - let cam_dir = - (self.scene.camera().get_focus_pos() - cam_pos).normalized(); + let (cam_dir, cam_pos) = + get_cam_data(&self.scene.camera(), &client); if let Ok(Some(block)) = client .state()