summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/shaders/tacmap/body.wgsl20
-rw-r--r--assets/shaders/tacmap/grid.wgsl3
-rw-r--r--assets/shaders/tacmap/orbit.wgsl10
-rw-r--r--src/solar_system/orbit.rs2
-rw-r--r--src/tacmap.rs9
-rw-r--r--src/tacmap/camera.rs100
-rw-r--r--src/ui.rs25
-rw-r--r--src/ui/bodies_window.rs41
-rw-r--r--src/ui/camera_info.rs58
-rw-r--r--src/window.rs5
10 files changed, 123 insertions, 150 deletions
diff --git a/assets/shaders/tacmap/body.wgsl b/assets/shaders/tacmap/body.wgsl
index e91c841..0cfd5f9 100644
--- a/assets/shaders/tacmap/body.wgsl
+++ b/assets/shaders/tacmap/body.wgsl
@@ -6,14 +6,16 @@ struct InstanceInput {
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
- @location(0) local_position: vec3<f32>
+ @location(0) local_position: vec3<f32>,
+ @location(1) distance: f32
};
struct CameraUniform {
view: mat4x4<f32>,
proj: mat4x4<f32>,
- pos: vec3<f32>,
- scale: f32
+ abs_pos: vec3<f32>,
+ rel_pos: vec3<f32>,
+ scale: f32,
};
@group(0) @binding(0)
@@ -49,18 +51,18 @@ fn vs_main(
//Scale the world around the camera scale and translate about the camera's
//absolute (/target) position
let relative_pos = instance.position;
- let origin_pos = (instance.origin - camera.pos);
+ let origin_pos = instance.origin - camera.abs_pos;
- if all(relative_pos != origin_pos) {
+ /*if all(relative_pos != origin_pos) {
if length(relative_pos) < 0.01 / camera.scale {
if length(relative_pos) != 0.0 {
out.clip_position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
return out;
}
}
- }
+ }*/
- let instance_pos = (relative_pos + origin_pos) * camera.scale;
+ let instance_pos = (relative_pos + origin_pos - camera.rel_pos) * camera.scale;
let view_proj = camera.proj * view;
@@ -76,6 +78,7 @@ fn vs_main(
}
out.local_position = model;
+ out.distance = length(instance_pos);
return out;
}
@@ -88,5 +91,6 @@ fn fs_main(in: VertexOutput
if point_dist > 1.0 {
alpha = 0.0;
}
- return vec4<f32>(1.0, 1.0, 1.0, alpha);
+ let color = vec3<f32>(1.0, 1.0, 1.0) / clamp(in.distance, 1.0, 1.5);
+ return vec4<f32>(color, alpha);
}
diff --git a/assets/shaders/tacmap/grid.wgsl b/assets/shaders/tacmap/grid.wgsl
index 822e957..1d2c4dc 100644
--- a/assets/shaders/tacmap/grid.wgsl
+++ b/assets/shaders/tacmap/grid.wgsl
@@ -7,7 +7,8 @@ struct VertexOutput {
struct CameraUniform {
view: mat4x4<f32>,
proj: mat4x4<f32>,
- pos: vec3<f32>,
+ abs_pos: vec3<f32>,
+ rel_pos: vec3<f32>,
scale: f32
};
diff --git a/assets/shaders/tacmap/orbit.wgsl b/assets/shaders/tacmap/orbit.wgsl
index 901200f..a890fd8 100644
--- a/assets/shaders/tacmap/orbit.wgsl
+++ b/assets/shaders/tacmap/orbit.wgsl
@@ -11,7 +11,8 @@ struct VertexOutput {
struct CameraUniform {
view: mat4x4<f32>,
proj: mat4x4<f32>,
- pos: vec3<f32>,
+ abs_pos: vec3<f32>,
+ rel_pos: vec3<f32>,
scale: f32
};
@@ -37,13 +38,10 @@ fn vs_main(
origins[model.origin][1],
origins[model.origin][2]);
- let model_pos = ((origin - camera.pos) + model.position) * camera.scale;
- let origin_pos = (origin - camera.pos) * camera.scale;
+ let model_pos = ((origin - camera.abs_pos - camera.rel_pos) + model.position) * camera.scale;
+ let origin_pos = (origin - camera.abs_pos - camera.rel_pos) * camera.scale;
let view = camera.view;
- let camera_right = vec3<f32>(view[0][0], view[1][0], view[2][0]);
- let camera_up = vec3<f32>(view[0][1], view[1][1], view[2][1]);
- let camera_forward = vec3<f32>(view[0][2], view[1][2], view[2][2]);
let orbit_normal = normalize(model.position);
var normal = orbit_normal;
diff --git a/src/solar_system/orbit.rs b/src/solar_system/orbit.rs
index 1800127..3a1d129 100644
--- a/src/solar_system/orbit.rs
+++ b/src/solar_system/orbit.rs
@@ -63,6 +63,8 @@ impl StaticOrbit
self.parent
}
+ pub fn sma(&self) -> Kilometers { self.semi_major_axis }
+
pub fn calculate_position_at(
&self,
sgp: f64,
diff --git a/src/tacmap.rs b/src/tacmap.rs
index b093fc1..cd9d878 100644
--- a/src/tacmap.rs
+++ b/src/tacmap.rs
@@ -80,10 +80,7 @@ impl TacticalMap
ui_state: &mut ui::State,
dt: Duration)
{
- ui_state.camera_info.camera_scale = self.camera.get_scale();
- ui_state.camera_info.camera_pos = Some(self.camera.get_abs_position());
- ui_state.camera_info.camera_rot = Some(self.camera.get_rotation());
- self.camera.set_target(ui_state.camera_info.target);
+ self.camera.set_target(ui_state.camera_target);
self.camera_controller.update(&mut self.camera, solar_system, ui_state, dt);
}
@@ -164,7 +161,7 @@ impl TacticalMap
let scaled_radius = (screen_size.y * body.radius() * self.camera.get_scale()).max(16.0);
let world_pos = solar_system.body_position(body);
- let local_pos = world_pos - self.camera.get_abs_position();
+ let local_pos = world_pos - self.camera.get_combined_position();
let origin_pos = match body.get_orbit() {
Some(orbit) => {
@@ -172,7 +169,7 @@ impl TacticalMap
},
None => cgmath::vec3(0.0, 0.0, 0.0)
};
- let origin_local_pos = origin_pos - self.camera.get_abs_position();
+ let origin_local_pos = origin_pos - self.camera.get_origin_position();
let scaled_pos = local_pos * self.camera.get_scale() as f64;
let scaled_origin_pos = origin_local_pos * self.camera.get_scale() as f64;
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)
diff --git a/src/ui.rs b/src/ui.rs
index 6a48f2d..235481d 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,22 +1,21 @@
pub mod topbar;
-pub mod camera_info;
pub mod bodies_window;
pub mod fleet_window;
use std::{borrow::Borrow, cell::RefCell};
-
-use crate::{GameState, eguictx::EguiCtx, ui::{bodies_window::BodiesWindowState, camera_info::CameraWindowState, fleet_window::FleetWindowState, topbar::TopBarState}};
-
-mod ui {
-
-}
+use crate::GameState;
+use crate::eguictx::EguiCtx;
+use crate::solar_system::body::BodyId;
+use crate::ui::bodies_window::BodiesWindowState;
+use crate::ui::fleet_window::FleetWindowState;
+use crate::ui::topbar::TopBarState;
#[derive(Default, Clone)]
pub struct State
{
+ pub camera_target: Option<BodyId>,
pub topbar_sate: TopBarState,
- pub camera_info: CameraWindowState,
pub bodies_window: BodiesWindowState,
pub fleet_window: FleetWindowState
@@ -45,17 +44,11 @@ impl State
None => return
};
- CameraWindowState::render(
- self,
- &game_state,
- eguictx);
-
if self.topbar_sate.bodies_window_visible {
let bodies_window_action =
self.bodies_window.render(current_system, eguictx);
-
- if let Some(body) = bodies_window_action.focus_body {
- self.camera_info.target = Some(body);
+ if bodies_window_action.focus_body.is_some() {
+ self.camera_target = bodies_window_action.focus_body;
}
}
diff --git a/src/ui/bodies_window.rs b/src/ui/bodies_window.rs
index 6300f5f..ece605b 100644
--- a/src/ui/bodies_window.rs
+++ b/src/ui/bodies_window.rs
@@ -4,6 +4,7 @@ use crate::eguictx::EguiCtx;
use crate::ntree::{NTree, NTreeNode};
use crate::solar_system::body::{BodyId, OrbitalBody};
use crate::solar_system::{SolarSystem, SystemId};
+use crate::timeman::TimeMan;
#[derive(Default, Clone)]
@@ -159,13 +160,39 @@ impl BodiesWindowState
};
ui.separator();
- egui::Frame::canvas(ui.style())
- .show(ui, |ui| {
- ui.set_width(200.0);
- ui.vertical_centered(|ui| {
- ui.label(
- egui::RichText::new(selected_body.name())
- .heading());
+ ui.vertical(|ui| {
+ egui::Frame::canvas(ui.style())
+ .show(ui, |ui| {
+ ui.set_width(200.0);
+ ui.vertical_centered(|ui| {
+ ui.label(
+ egui::RichText::new(selected_body.name())
+ .heading());
+ ui.separator();
+ });
+
+ ui.vertical(|ui| {
+ ui.vertical_centered(|ui| {
+ ui.label("Physical Properties");
+ });
+ ui.label(format!("Mass: {:.4E} kg", selected_body.mass()));
+ ui.label(format!("Radius: {} km", selected_body.radius()));
+
+ if let Some(orbit) = selected_body.get_orbit() {
+ ui.vertical_centered(|ui| {
+ ui.label("Orbital Properties");
+ });
+ ui.label(format!("Orbiting {}",
+ star_system.body(orbit.parent()).name()
+ ));
+ ui.label(format!("Period: {}",
+ TimeMan::format_duration(orbit.period(selected_body))
+ ));
+ ui.label(format!("Semi-major Axis: {:.4E} km",
+ orbit.sma()
+ ));
+ }
+ });
});
ui.horizontal(|ui| {
diff --git a/src/ui/camera_info.rs b/src/ui/camera_info.rs
deleted file mode 100644
index 5332370..0000000
--- a/src/ui/camera_info.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-use std::cell::RefCell;
-
-use crate::{GameState, eguictx::EguiCtx, solar_system, ui};
-
-
-#[derive(Default, Clone)]
-pub struct CameraWindowState
-{
- pub camera_scale: f32,
- pub camera_pos: Option<cgmath::Vector3<f64>>,
- pub camera_rot: Option<cgmath::Vector2<cgmath::Rad<f32>>>,
- pub target: Option<solar_system::body::BodyId>,
-}
-
-impl CameraWindowState
-{
- pub fn render(
- ui_state: &mut ui::State,
- game_state: &GameState,
- eguictx: &EguiCtx)
- {
- let topbar_state = &ui_state.topbar_sate;
- if topbar_state.current_system.is_none() {
- return;
- }
-
- let camera_state = &mut ui_state.camera_info;
-
- let current_system = &game_state.solar_systems()[topbar_state.current_system.unwrap()];
-
- egui::Window::new("Debug Camera Info")
- .title_bar(false)
- .show(eguictx.context(), |ui| {
- ui.vertical(|ui| {
- let selected_body_label = match camera_state.target {
- Some(id) => current_system.bodies()[id].name(),
- None => ""
- };
-
- ui.separator();
-
- egui::ComboBox::from_label("Camera Target")
- .selected_text(selected_body_label)
- .show_ui(ui, |ui| {
-
- for (i, body) in current_system.bodies().iter().enumerate() {
- ui.selectable_value(
- &mut camera_state.target,
- Some(i),
- body.name());
- }
- });
-
- ui.label(format!("Scale: {}", camera_state.camera_scale));
- });
- });
- }
-}
diff --git a/src/window.rs b/src/window.rs
index 3461a53..d895040 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -40,14 +40,11 @@ impl GameWindow
let tacmap = TacticalMap::new(&wgpuctx);
let ui_state = ui::State{
+ camera_target: Some(0),
topbar_sate: ui::topbar::TopBarState {
current_system : Some(0),
..Default::default()
},
- camera_info: ui::camera_info::CameraWindowState {
- target: Some(0),
- ..Default::default()
- },
..Default::default()
};