mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed first-person zoom, added fixation to allow more precise mouse movement when zoomed
This commit is contained in:
parent
0b1a820762
commit
6f15233448
@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Explosions no longer change block colours within safe zones
|
- Explosions no longer change block colours within safe zones
|
||||||
- The 'spot' system, which generates smaller site-like structures and scenarios
|
- The 'spot' system, which generates smaller site-like structures and scenarios
|
||||||
- Chestnut and cedar tree varieties
|
- Chestnut and cedar tree varieties
|
||||||
|
- Shooting sprites, such as apples and hives, can knock them out of trees
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -1020,14 +1020,13 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_bonk(server: &mut Server, pos: Vec3<f32>, owner: Option<Uid>, target: Option<Uid>) {
|
pub fn handle_bonk(server: &mut Server, pos: Vec3<f32>, _owner: Option<Uid>, target: Option<Uid>) {
|
||||||
let ecs = &server.state.ecs();
|
let ecs = &server.state.ecs();
|
||||||
let terrain = ecs.read_resource::<TerrainGrid>();
|
let terrain = ecs.read_resource::<TerrainGrid>();
|
||||||
let mut block_change = ecs.write_resource::<BlockChange>();
|
let mut block_change = ecs.write_resource::<BlockChange>();
|
||||||
|
|
||||||
if let Some(_target) = target {
|
if let Some(_target) = target {
|
||||||
// TODO: bonk entities but do no damage?
|
// TODO: bonk entities but do no damage?
|
||||||
drop(owner);
|
|
||||||
} else {
|
} else {
|
||||||
use common::terrain::SpriteKind;
|
use common::terrain::SpriteKind;
|
||||||
let pos = pos.map(|e| e.floor() as i32);
|
let pos = pos.map(|e| e.floor() as i32);
|
||||||
|
@ -49,6 +49,8 @@ pub struct Camera {
|
|||||||
dist: f32,
|
dist: f32,
|
||||||
tgt_fov: f32,
|
tgt_fov: f32,
|
||||||
fov: f32,
|
fov: f32,
|
||||||
|
tgt_fixate: f32,
|
||||||
|
fixate: f32,
|
||||||
aspect: f32,
|
aspect: f32,
|
||||||
mode: CameraMode,
|
mode: CameraMode,
|
||||||
|
|
||||||
@ -327,6 +329,8 @@ impl Camera {
|
|||||||
dist: 10.0,
|
dist: 10.0,
|
||||||
tgt_fov: 1.1,
|
tgt_fov: 1.1,
|
||||||
fov: 1.1,
|
fov: 1.1,
|
||||||
|
tgt_fixate: 1.0,
|
||||||
|
fixate: 1.0,
|
||||||
aspect,
|
aspect,
|
||||||
mode,
|
mode,
|
||||||
|
|
||||||
@ -466,13 +470,14 @@ impl Camera {
|
|||||||
* Mat4::translation_3d(-self.focus.map(|e| e.fract()));
|
* Mat4::translation_3d(-self.focus.map(|e| e.fract()));
|
||||||
let view_mat_inv: Mat4<f32> = view_mat.inverted();
|
let view_mat_inv: Mat4<f32> = view_mat.inverted();
|
||||||
|
|
||||||
|
let fov = self.get_effective_fov();
|
||||||
// NOTE: We reverse the far and near planes to produce an inverted depth
|
// NOTE: We reverse the far and near planes to produce an inverted depth
|
||||||
// buffer (1 to 0 z planes).
|
// buffer (1 to 0 z planes).
|
||||||
let proj_mat =
|
let proj_mat =
|
||||||
perspective_rh_zo_general(self.fov, self.aspect, 1.0 / FAR_PLANE, 1.0 / NEAR_PLANE);
|
perspective_rh_zo_general(fov, self.aspect, 1.0 / FAR_PLANE, 1.0 / NEAR_PLANE);
|
||||||
// For treeculler, we also produce a version without inverted depth.
|
// For treeculler, we also produce a version without inverted depth.
|
||||||
let proj_mat_treeculler =
|
let proj_mat_treeculler =
|
||||||
perspective_rh_zo_general(self.fov, self.aspect, 1.0 / NEAR_PLANE, 1.0 / FAR_PLANE);
|
perspective_rh_zo_general(fov, self.aspect, 1.0 / NEAR_PLANE, 1.0 / FAR_PLANE);
|
||||||
|
|
||||||
Dependents {
|
Dependents {
|
||||||
view_mat,
|
view_mat,
|
||||||
@ -501,6 +506,7 @@ impl Camera {
|
|||||||
/// Rotate the camera about its focus by the given delta, limiting the input
|
/// Rotate the camera about its focus by the given delta, limiting the input
|
||||||
/// accordingly.
|
/// accordingly.
|
||||||
pub fn rotate_by(&mut self, delta: Vec3<f32>) {
|
pub fn rotate_by(&mut self, delta: Vec3<f32>) {
|
||||||
|
let delta = delta * self.fixate;
|
||||||
// Wrap camera yaw
|
// Wrap camera yaw
|
||||||
self.tgt_ori.x = (self.tgt_ori.x + delta.x).rem_euclid(2.0 * PI);
|
self.tgt_ori.x = (self.tgt_ori.x + delta.x).rem_euclid(2.0 * PI);
|
||||||
// Clamp camera pitch to the vertical limits
|
// Clamp camera pitch to the vertical limits
|
||||||
@ -575,6 +581,14 @@ impl Camera {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.fixate - self.tgt_fixate).abs() > 0.01 {
|
||||||
|
self.fixate = vek::Lerp::lerp(
|
||||||
|
self.fixate,
|
||||||
|
self.tgt_fixate,
|
||||||
|
0.65 * (delta as f32) / self.interp_time(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (self.focus - self.tgt_focus).magnitude_squared() > 0.001 {
|
if (self.focus - self.tgt_focus).magnitude_squared() > 0.001 {
|
||||||
let lerped_focus = Lerp::lerp(
|
let lerped_focus = Lerp::lerp(
|
||||||
self.focus,
|
self.focus,
|
||||||
@ -639,12 +653,20 @@ impl Camera {
|
|||||||
/// Get the orientation of the camera.
|
/// Get the orientation of the camera.
|
||||||
pub fn get_orientation(&self) -> Vec3<f32> { self.ori }
|
pub fn get_orientation(&self) -> Vec3<f32> { self.ori }
|
||||||
|
|
||||||
/// Get the field of view of the camera in radians.
|
/// Get the field of view of the camera in radians, taking into account
|
||||||
pub fn get_fov(&self) -> f32 { self.fov }
|
/// fixation.
|
||||||
|
pub fn get_effective_fov(&self) -> f32 { self.fov * self.fixate }
|
||||||
|
|
||||||
|
// /// Get the field of view of the camera in radians.
|
||||||
|
// pub fn get_fov(&self) -> f32 { self.fov }
|
||||||
|
|
||||||
/// Set the field of view of the camera in radians.
|
/// Set the field of view of the camera in radians.
|
||||||
pub fn set_fov(&mut self, fov: f32) { self.tgt_fov = fov; }
|
pub fn set_fov(&mut self, fov: f32) { self.tgt_fov = fov; }
|
||||||
|
|
||||||
|
/// Set the 'fixation' proportion, allowing the camera to focus in with
|
||||||
|
/// precise aiming. Fixation is applied on top of the regular FoV.
|
||||||
|
pub fn set_fixate(&mut self, fixate: f32) { self.tgt_fixate = fixate; }
|
||||||
|
|
||||||
/// Set the FOV in degrees
|
/// Set the FOV in degrees
|
||||||
pub fn set_fov_deg(&mut self, fov: u16) {
|
pub fn set_fov_deg(&mut self, fov: u16) {
|
||||||
//Magic value comes from pi/180; no use recalculating.
|
//Magic value comes from pi/180; no use recalculating.
|
||||||
|
@ -682,7 +682,7 @@ impl Scene {
|
|||||||
let sun_dir = scene_data.get_sun_dir();
|
let sun_dir = scene_data.get_sun_dir();
|
||||||
let is_daylight = sun_dir.z < 0.0;
|
let is_daylight = sun_dir.z < 0.0;
|
||||||
if renderer.pipeline_modes().shadow.is_map() && (is_daylight || !lights.is_empty()) {
|
if renderer.pipeline_modes().shadow.is_map() && (is_daylight || !lights.is_empty()) {
|
||||||
let fov = self.camera.get_fov();
|
let fov = self.camera.get_effective_fov();
|
||||||
let aspect_ratio = self.camera.get_aspect_ratio();
|
let aspect_ratio = self.camera.get_aspect_ratio();
|
||||||
|
|
||||||
let view_dir = ((focus_pos.map(f32::fract)) - cam_pos).normalized();
|
let view_dir = ((focus_pos.map(f32::fract)) - cam_pos).normalized();
|
||||||
|
@ -77,7 +77,6 @@ pub struct SessionState {
|
|||||||
target_entity: Option<specs::Entity>,
|
target_entity: Option<specs::Entity>,
|
||||||
selected_entity: Option<(specs::Entity, std::time::Instant)>,
|
selected_entity: Option<(specs::Entity, std::time::Instant)>,
|
||||||
interactable: Option<Interactable>,
|
interactable: Option<Interactable>,
|
||||||
saved_zoom_dist: Option<f32>,
|
|
||||||
hitboxes: HashMap<specs::Entity, DebugShapeId>,
|
hitboxes: HashMap<specs::Entity, DebugShapeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +124,6 @@ impl SessionState {
|
|||||||
target_entity: None,
|
target_entity: None,
|
||||||
selected_entity: None,
|
selected_entity: None,
|
||||||
interactable: None,
|
interactable: None,
|
||||||
saved_zoom_dist: None,
|
|
||||||
hitboxes: HashMap::new(),
|
hitboxes: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,18 +326,8 @@ impl PlayState for SessionState {
|
|||||||
if cr.charge_frac() > 0.5 {
|
if cr.charge_frac() > 0.5 {
|
||||||
fov_scaling -= 3.0 * cr.charge_frac() / 5.0;
|
fov_scaling -= 3.0 * cr.charge_frac() / 5.0;
|
||||||
}
|
}
|
||||||
let max_dist = if let Some(dist) = self.saved_zoom_dist {
|
|
||||||
dist
|
|
||||||
} else {
|
|
||||||
let dist = camera.get_distance();
|
|
||||||
self.saved_zoom_dist = Some(dist);
|
|
||||||
dist
|
|
||||||
};
|
|
||||||
camera.set_distance(Lerp::lerp(max_dist, 2.0, 1.0 - fov_scaling));
|
|
||||||
} else if let Some(dist) = self.saved_zoom_dist.take() {
|
|
||||||
camera.set_distance(dist);
|
|
||||||
}
|
}
|
||||||
camera.set_fov((global_state.settings.graphics.fov as f32 * fov_scaling).to_radians());
|
camera.set_fixate(fov_scaling);
|
||||||
|
|
||||||
// Compute camera data
|
// Compute camera data
|
||||||
camera.compute_dependents(&*self.client.borrow().state().terrain());
|
camera.compute_dependents(&*self.client.borrow().state().terrain());
|
||||||
|
Loading…
Reference in New Issue
Block a user