diff --git a/src/camera.rs b/src/camera.rs index c857dce..7f0548e 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -8,6 +8,7 @@ use bevy::transform::TransformSystem; use bevy::math::{DVec3, DQuat}; use bevy_xpbd_3d::prelude::*; use std::f32::consts::PI; +use std::f64::consts::PI as PI64; use crate::{actor, audio, hud, var}; pub struct CameraPlugin; @@ -40,12 +41,13 @@ pub struct ShowOnlyInMap { #[derive(Resource)] pub struct MapCam { pub initialized: bool, - pub zoom_level: f32, - pub target_zoom_level: f32, - pub pitch: f32, - pub yaw: f32, + pub zoom_level: f64, + pub target_zoom_level: f64, + pub pitch: f64, + pub yaw: f64, pub offset_x: f64, pub offset_z: f64, + pub center: DVec3, } impl Default for MapCam { fn default() -> Self { @@ -53,10 +55,11 @@ impl Default for MapCam { initialized: false, zoom_level: 2.0, target_zoom_level: 10.0, - pitch: PI * 0.3, + pitch: PI64 * 0.3, yaw: 0.0, offset_x: 0.0, offset_z: 0.0, + center: DVec3::new(0.0, 0.0, 0.0), } } } @@ -154,10 +157,10 @@ pub fn update_map_camera( // direction parameter for the Transform.look_at function is ambiguous // at the extreme values and the orientation will flicker back/forth. let epsilon = 0.001; - let min_zoom = target.scale.x * 2.0; - let max_zoom = 17e18; // at this point, camera starts glitching - mapcam.pitch = (mapcam.pitch + mouse_delta.y / 180.0 * settings.mouse_sensitivity).clamp(-PI / 2.0 + epsilon, PI / 2.0 - epsilon); - mapcam.yaw += mouse_delta.x / 180.0 * settings.mouse_sensitivity; + let min_zoom: f64 = target.scale.x as f64 * 2.0; + let max_zoom: f64 = 17e18; // at this point, camera starts glitching + mapcam.pitch = (mapcam.pitch + mouse_delta.y as f64 / 180.0 * settings.mouse_sensitivity as f64).clamp(-PI64 / 2.0 + epsilon, PI64 / 2.0 - epsilon); + mapcam.yaw += mouse_delta.x as f64 / 180.0 * settings.mouse_sensitivity as f64; // Reset movement offset if target changes if !q_target_changed.is_empty() { @@ -166,8 +169,8 @@ pub fn update_map_camera( } // Get keyboard movement - let mut offset_x = 0.0; - let mut offset_z = 0.0; + let mut offset_x: f64 = 0.0; + let mut offset_z: f64 = 0.0; if keyboard_input.pressed(settings.key_forward) { offset_x -= 1.0; } @@ -181,18 +184,14 @@ pub fn update_map_camera( offset_z += 1.0; } - // Update movement offset - mapcam.offset_x += (0.01 * offset_x * mapcam.zoom_level) as f64; - mapcam.offset_z += (0.01 * offset_z * mapcam.zoom_level) as f64; - // Update zoom level if !mapcam.initialized { - let factor = if target == player_transform { 7.0 } else { 1.0 }; - mapcam.target_zoom_level *= target.scale.x * factor; - mapcam.zoom_level *= target.scale.x * factor; + let factor: f64 = if target == player_transform { 7.0 } else { 1.0 }; + mapcam.target_zoom_level *= target.scale.x as f64 * factor; + mapcam.zoom_level *= target.scale.x as f64 * factor; mapcam.initialized = true; } - let mut change_zoom = 0.0; + let mut change_zoom: f64 = 0.0; if keyboard_input.pressed(settings.key_map_zoom_out) { change_zoom += 0.5; } @@ -200,9 +199,9 @@ pub fn update_map_camera( change_zoom -= 0.5; } for wheel_event in er_mousewheel.read() { - change_zoom -= wheel_event.y * 3.0; + change_zoom -= wheel_event.y as f64 * 3.0; } - mapcam.target_zoom_level = (mapcam.target_zoom_level * 1.1f32.powf(change_zoom)).clamp(min_zoom, max_zoom); + mapcam.target_zoom_level = (mapcam.target_zoom_level * 1.1f64.powf(change_zoom)).clamp(min_zoom, max_zoom); let zoom_speed = 0.05; // should be between 0.0001 (slow) and 1.0 (instant) mapcam.zoom_level = (zoom_speed * mapcam.target_zoom_level + (1.0 - zoom_speed) * mapcam.zoom_level).clamp(min_zoom, max_zoom); @@ -211,9 +210,19 @@ pub fn update_map_camera( let offset = DVec3::new(mapcam.offset_x, 0.0, mapcam.offset_z); let point_of_view = offset + pov_rotation * (mapcam.zoom_level as f64 * DVec3::new(1.0, 0.0, 0.0)); + // Update movement offset + let mut direction = pov_rotation * DVec3::new(offset_x, 0.0, offset_z); + let speed = direction.length(); + direction.y = 0.0; + let direction = speed * direction.normalize_or_zero(); + + mapcam.offset_x += 0.01 * (direction.x * mapcam.zoom_level); + mapcam.offset_z += 0.01 * (direction.z * mapcam.zoom_level); + // Apply updates to camera + mapcam.center = target.translation.as_dvec3() + offset; camera_transform.translation = target.translation + point_of_view.as_vec3(); - camera_transform.look_at(target.translation + offset.as_vec3(), Vec3::Y); + camera_transform.look_at(mapcam.center.as_vec3(), Vec3::Y); } pub fn update_fov(