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.rs100
1 files changed, 56 insertions, 44 deletions
diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs
index 57856e2..af163b8 100644
--- a/src/tacmap/camera.rs
+++ b/src/tacmap/camera.rs
@@ -1,16 +1,17 @@
use std::time::Duration;
-use cgmath::{InnerSpace, Point3, Rad, Vector2, Vector3, perspective};
+use cgmath::{InnerSpace, Point3, Rad, Vector2, Vector3, Zero, perspective};
use winit::event::ElementState;
use winit::keyboard::KeyCode;
+use crate::solar_system::body::OrbitalBody;
use crate::solar_system::{self, Kilometers, SolarSystem};
use crate::ui;
use crate::wgpuctx::WgpuCtx;
pub struct Camera
{
- abs_position: Vector3<Kilometers>,
+ origin_position: Vector3<Kilometers>,
rel_position: Vector3<f32>,
pitch: Rad<f32>,
yaw: Rad<f32>,
@@ -38,8 +39,10 @@ pub struct CameraUniform
{
view: [[f32;4];4],
proj: [[f32;4];4],
- pos: [f32;3],
- scale: f32
+ origin_pos: [f32;3],
+ _pad0: u32,
+ rel_pos: [f32;3],
+ scale: f32,
}
pub struct Projection
@@ -94,7 +97,7 @@ impl Camera
}
);
Self {
- abs_position: position.into(),
+ origin_position: position.into(),
rel_position: Vector3::new(0.0, 0.0, 0.0),
yaw: yaw.into(),
pitch: pitch.into(),
@@ -109,12 +112,12 @@ impl Camera
pub fn get_scale(&self) -> f32
{ self.scale }
- pub fn get_abs_position(&self) -> Vector3<Kilometers>
- { self.abs_position }
+ pub fn get_origin_position(&self) -> Vector3<Kilometers>
+ { self.origin_position }
pub fn get_combined_position(&self) -> Vector3<Kilometers>
{
- self.abs_position + self.rel_position.map(|v| { v as f64 })
+ self.origin_position + self.rel_position.map(|v| { v as f64 })
}
pub fn get_rotation(&self) -> Vector2<Rad<f32>>
@@ -170,7 +173,7 @@ impl Camera
{
if target == self.target { return; }
if !target.is_some() || !self.target.is_some() {
- self.abs_position = self.get_combined_position();
+ self.origin_position = self.get_combined_position();
self.rel_position = Vector3::new(0.0, 0.0, 0.0);
}
self.target = target;
@@ -180,21 +183,25 @@ impl Camera
&self)
-> cgmath::Matrix4<f32> {
- let (yaw_sin, yaw_cos) = self.pitch.0.sin_cos();
- let (pitch_sin, pitch_cos) = self.yaw.0.sin_cos();
+ let (yaw_sin, yaw_cos) = self.yaw.0.sin_cos();
+ let (pitch_sin, pitch_cos) = self.pitch.0.sin_cos();
+
+ let eye_pos = cgmath::point3(
+ pitch_cos * yaw_cos,
+ pitch_sin,
+ pitch_cos * yaw_sin
+ );
if self.target.is_some() {
cgmath::Matrix4::look_at_rh(
- Point3::new(self.rel_position.x, self.rel_position.y, self.rel_position.z),
- Point3::new(0.0, 0.0, 0.0),
+ eye_pos,
+ cgmath::point3(0.0, 0.0, 0.0),
Vector3::unit_y())
}else{
cgmath::Matrix4::look_to_rh(
- Point3::new(0.0, 0.0, 0.0),
- Vector3::new(
- pitch_cos * yaw_cos,
- pitch_sin,
- pitch_cos * yaw_sin
+ cgmath::point3(0.0, 0.0, 0.0),
+ cgmath::vec3(
+ eye_pos.x, eye_pos.y, eye_pos.z
).normalize(),
Vector3::unit_y()
)
@@ -209,10 +216,17 @@ impl Camera
CameraUniform {
view: (self.view_matrix()).into(),
proj: projection.projection_matrix().into(),
- pos: [ self.abs_position.x as f32,
- self.abs_position.y as f32,
- self.abs_position.z as f32 ],
- scale: self.scale
+ origin_pos: [
+ self.origin_position.x as f32,
+ self.origin_position.y as f32,
+ self.origin_position.z as f32 ],
+ rel_pos: [
+ self.rel_position.x as f32,
+ self.rel_position.y as f32,
+ self.rel_position.z as f32 ],
+ scale: self.scale,
+
+ _pad0: 0
}
}
} //impl Camera
@@ -252,14 +266,25 @@ impl CameraController
fn update_orbit(
&mut self,
camera: &mut Camera,
- target: Vector3<Kilometers>,
- target_radius: f32,
+ solar_system: &SolarSystem,
+ target: &OrbitalBody,
dt: Duration)
{
+ let target_radius = (target.radius() * 2.0).max(1.0);
camera.scale *= 1.0 + ((self.scale_delta.y - self.scale_delta.x) * 0.1);
camera.scale = f32::max(1e-16, f32::min(1.0 / target_radius, camera.scale));
- camera.abs_position = target;
+ match target.get_orbit() {
+ Some(orbit) => {
+ let parent = solar_system.body(orbit.parent());
+ camera.origin_position = parent.absolute_position(solar_system);
+ camera.rel_position = target.relative_position().map(|v| { v as f32 });
+ },
+ None => {
+ camera.origin_position = target.absolute_position(solar_system);
+ camera.rel_position.set_zero();
+ }
+ }
let dt = dt.as_secs_f32();
let speed = 1.0;
@@ -274,16 +299,6 @@ impl CameraController
{ camera.pitch.0 = polar_final; }
camera.yaw.0 += azimuth_diff;
-
- let (az_sin, az_cos) = camera.yaw.0.sin_cos();
- let (p_sin, p_cos) = camera.pitch.0.sin_cos();
-
- let radius = 1.0;
- camera.rel_position = Vector3::new(
- radius * p_cos * az_cos,
- radius * p_sin,
- radius * p_cos * az_sin
- );
}
fn update_pan(
@@ -302,12 +317,9 @@ impl CameraController
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
let up = Vector3::new(0.0, 1.0, 0.0);
- 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.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.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;
@@ -320,14 +332,14 @@ impl CameraController
ui_state: &mut ui::State,
dt: Duration)
{
- match ui_state.camera_info.target {
+ match ui_state.camera_target {
Some(body_id) => {
let body = &solar_system.bodies()[body_id];
self.update_orbit(
camera,
- solar_system.body_position(body).cast().unwrap(),
- (body.radius() * 2.0).max(1.0),
+ solar_system,
+ body,
dt);
}
None => self.update_pan(camera, dt)