diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index 6ec3570cd4..be925c9508 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -9,7 +9,7 @@ use crate::{ PostProcessLocals, PostProcessPipeline, Renderer, SkyboxLocals, SkyboxPipeline, }, scene::{ - camera::Camera, + camera::{Camera, CameraMode}, figure::{FigureModelCache, FigureState}, }, }; @@ -52,7 +52,7 @@ impl Scene { Self { globals: renderer.create_consts(&[Globals::default()]).unwrap(), lights: renderer.create_consts(&[Light::default(); 32]).unwrap(), - camera: Camera::new(resolution.x / resolution.y), + camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson), skybox: Skybox { model: renderer.create_model(&create_skybox_mesh()).unwrap(), diff --git a/voxygen/src/scene/camera.rs b/voxygen/src/scene/camera.rs index 9e372dde9b..1bd759a2bb 100644 --- a/voxygen/src/scene/camera.rs +++ b/voxygen/src/scene/camera.rs @@ -8,6 +8,12 @@ const FAR_PLANE: f32 = 10000.0; const INTERP_TIME: f32 = 0.1; +// Possible TODO: Add more modes +pub enum CameraMode { + FirstPerson, + ThirdPerson +} + pub struct Camera { tgt_focus: Vec3, focus: Vec3, @@ -16,13 +22,15 @@ pub struct Camera { dist: f32, fov: f32, aspect: f32, + mode: CameraMode, + can_zoom: bool, last_time: Option, } impl Camera { /// Create a new `Camera` with default parameters. - pub fn new(aspect: f32) -> Self { + pub fn new(aspect: f32, mode: CameraMode) -> Self { Self { tgt_focus: Vec3::unit_z() * 10.0, focus: Vec3::unit_z() * 10.0, @@ -31,6 +39,9 @@ impl Camera { dist: 10.0, fov: 1.1, aspect, + mode, + can_zoom: false, + last_time: None, } } @@ -103,8 +114,10 @@ impl Camera { /// Zoom the camera by the given delta, limiting the input accordingly. pub fn zoom_by(&mut self, delta: f32) { - // Clamp camera dist to the 0 <= x <= infinity range - self.tgt_dist = (self.tgt_dist + delta).max(0.0); + if self.can_zoom { + // Clamp camera dist to the 0 <= x <= infinity range + self.tgt_dist = (self.tgt_dist + delta).max(0.0); + } } /// Get the distance of the camera from the target @@ -156,4 +169,18 @@ impl Camera { pub fn get_fov(&self) -> f32 { self.fov } + + /// 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; + }, + CameraMode::FirstPerson => { + self.set_distance(0.0); + self.can_zoom = false; + }, + } + } } diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 9aee0f750e..e74ecd25dd 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -2,7 +2,7 @@ pub mod camera; pub mod figure; pub mod terrain; -use self::{camera::Camera, figure::FigureMgr, terrain::Terrain}; +use self::{camera::{Camera, CameraMode}, figure::FigureMgr, terrain::Terrain}; use crate::{ render::{ create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals, @@ -52,7 +52,7 @@ impl Scene { Self { globals: renderer.create_consts(&[Globals::default()]).unwrap(), lights: renderer.create_consts(&[Light::default(); 32]).unwrap(), - camera: Camera::new(resolution.x / resolution.y), + camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson), skybox: Skybox { model: renderer.create_model(&create_skybox_mesh()).unwrap(), @@ -191,6 +191,17 @@ impl Scene { proj_mat, ); + if client + .state() + .read_storage::() + .get(client.entity()) + .is_some() + { + self.camera.set_mode(CameraMode::FirstPerson); + } else { + self.camera.set_mode(CameraMode::ThirdPerson); + } + // Maintain the figures. self.figure_mgr.maintain(renderer, client);