summaryrefslogtreecommitdiffstats
path: root/src/tacmap/camera.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tacmap/camera.rs')
-rw-r--r--src/tacmap/camera.rs83
1 files changed, 43 insertions, 40 deletions
diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs
index c6ee5c0..c573cfb 100644
--- a/src/tacmap/camera.rs
+++ b/src/tacmap/camera.rs
@@ -1,9 +1,9 @@
use std::{cell::RefCell, time::Duration};
-use cgmath::{EuclideanSpace, InnerSpace, Point3, Rad, Vector2, Vector3, Vector4, Zero, perspective};
+use cgmath::{EuclideanSpace, InnerSpace, Point2, Point3, Rad, Vector2, Vector3, Vector4, Zero, perspective};
use winit::{event::ElementState, keyboard::KeyCode};
-use crate::{GameState, solar_system, wgpuctx::WgpuCtx, window::ui::GameWindowUiState};
+use crate::{GameState, solar_system::{self, Kilometers}, ui, wgpuctx::WgpuCtx};
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::from_cols(
Vector4::new(1.0, 0.0, 0.0, 0.0),
@@ -14,8 +14,8 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::from_co
pub struct Camera
{
- abs_position: Point3<f32>,
- rel_position: Point3<f32>,
+ abs_position: Vector3<Kilometers>,
+ rel_position: Vector3<f32>,
pitch: Rad<f32>,
yaw: Rad<f32>,
scale: f32,
@@ -55,7 +55,7 @@ pub struct Projection
impl Camera
{
pub fn new<
- V: Into<Point3<f32>>,
+ V: Into<Vector3<Kilometers>>,
Y: Into<Rad<f32>>,
P: Into<Rad<f32>>
>(
@@ -98,11 +98,11 @@ impl Camera
);
Self {
abs_position: position.into(),
- rel_position: Point3::new(0.0, 0.0, 0.0),
+ rel_position: Vector3::new(0.0, 0.0, 0.0),
yaw: yaw.into(),
pitch: pitch.into(),
- scale: 1.0,
- target: None,
+ scale: 1e-7,
+ target: Some(0),
buffer: buffer,
staging_buffer: staging_buffer,
bindgroup: bind_group
@@ -112,12 +112,17 @@ impl Camera
pub fn get_scale(&self) -> f32
{ self.scale }
- pub fn get_position(&self) -> Point3<f32>
+ pub fn get_abs_position(&self) -> Vector3<Kilometers>
+ { self.abs_position }
+
+ pub fn get_combined_position(&self) -> Vector3<Kilometers>
+ {
+ self.abs_position + self.rel_position.map(|v| { v as f64 })
+ }
+
+ pub fn get_rotation(&self) -> Vector2<Rad<f32>>
{
- Point3::new(
- self.abs_position.x + self.rel_position.x,
- self.abs_position.y + self.rel_position.y,
- self.abs_position.z + self.rel_position.z)
+ Vector2::new(self.yaw, self.pitch)
}
pub fn bindgroup_layout(wgpuctx: &WgpuCtx)
@@ -168,15 +173,12 @@ impl Camera
{
if target == self.target { return; }
if !target.is_some() || !self.target.is_some() {
- self.abs_position = self.get_position();
- self.rel_position = Point3::new(0.0, 0.0, 0.0);
+ self.abs_position = self.get_combined_position();
+ self.rel_position = Vector3::new(0.0, 0.0, 0.0);
}
self.target = target;
}
- pub fn get_target(&self) -> Option<solar_system::BodyId>
- { self.target }
-
pub fn view_matrix(
&self)
-> cgmath::Matrix4<f32> {
@@ -186,12 +188,12 @@ impl Camera
if self.target.is_some() {
cgmath::Matrix4::look_at_rh(
- self.get_position(),
- self.abs_position,
+ Point3::new(self.rel_position.x, self.rel_position.y, self.rel_position.z),
+ Point3::new(0.0, 0.0, 0.0),
Vector3::unit_y())
}else{
cgmath::Matrix4::look_to_rh(
- self.get_position(),
+ Point3::new(0.0, 0.0, 0.0),
Vector3::new(
pitch_cos * yaw_cos,
pitch_sin,
@@ -250,25 +252,26 @@ impl CameraController
fn update_orbit(
&mut self,
camera: &mut Camera,
- target: Point3<f32>,
+ target: Vector3<Kilometers>,
min_radius: f32,
dt: Duration)
{
- camera.abs_position = target * camera.scale;
+ camera.abs_position = target;
let dt = dt.as_secs_f32();
let speed = 1.0;
- let current_radius = camera.rel_position.to_vec().magnitude();
+ let current_radius = camera.rel_position.magnitude();
let polar_diff = (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt;
let azimuth_diff = (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt;
let dist_diff = (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt;
- camera.pitch.0 += polar_diff;
- let polar_cap = cgmath::Deg(179.999).0;
- if camera.pitch.0 > polar_cap { camera.pitch.0 = polar_cap; }
- if camera.pitch.0 < -polar_cap { camera.pitch.0 = -polar_cap; }
+ let polar_final = camera.pitch.0 + polar_diff;
+ let polar_cap = Into::<Rad<f32>>::into(cgmath::Deg(89.999)).0;
+ if polar_final > polar_cap { camera.pitch.0 = polar_cap; } else
+ if polar_final < -polar_cap { camera.pitch.0 = -polar_cap; } else
+ { camera.pitch.0 = polar_final; }
camera.yaw.0 += azimuth_diff;
@@ -276,7 +279,7 @@ impl CameraController
let (p_sin, p_cos) = camera.pitch.0.sin_cos();
let radius = f32::max(min_radius * camera.scale, current_radius + dist_diff);
- camera.rel_position = Point3::new(
+ camera.rel_position = Vector3::new(
radius * p_cos * az_cos,
radius * p_sin,
radius * p_cos * az_sin
@@ -296,12 +299,12 @@ impl CameraController
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
let up = Vector3::new(0.0, 1.0, 0.0);
-
- camera.rel_position += forward * (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt;
- camera.rel_position += right * (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt;
- camera.rel_position += up * (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt;
-
- camera.abs_position = camera.rel_position;
+ camera.abs_position += (forward * (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt)
+ .map(|v| { v as f64 } );
+ camera.abs_position += (right * (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt)
+ .map(|v| { v as f64 });
+ camera.abs_position += (up * (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt)
+ .map(|v| { v as f64 });
camera.pitch.0 += (self.rotation_pos_delta.x - self.rotation_neg_delta.x) * speed * dt;
camera.yaw.0 += (self.rotation_pos_delta.y - self.rotation_neg_delta.y) * speed * dt;
@@ -311,13 +314,13 @@ impl CameraController
&mut self,
camera: &mut Camera,
game_state: &RefCell<GameState>,
- ui_state: &mut GameWindowUiState,
+ ui_state: &mut ui::State,
dt: Duration)
{
camera.scale *= 1.0 + ((self.scale_delta.y - self.scale_delta.x) * 0.1);
- camera.scale = f32::max(1e-16, f32::min(1.0, camera.scale));
+ camera.scale = f32::max(1e-16, f32::min(1e-6, camera.scale));
- match ui_state.camera_target {
+ match ui_state.camera_info.target {
Some(body_id) => {
let game_state = game_state.borrow();
let solar_systems = game_state.solar_systems();
@@ -329,8 +332,8 @@ impl CameraController
let body = &current_system.bodies()[body_id];
self.update_orbit(
camera,
- body.position().cast().unwrap(),
- body.radius(),
+ current_system.body_position(body).cast().unwrap(),
+ body.radius() * 2.0,
dt);
}
None => self.update_pan(camera, dt)