diff --git a/assets/sprites/speedometer.png b/assets/sprites/speedometer.png
new file mode 100644
index 0000000..3ee1100
Binary files /dev/null and b/assets/sprites/speedometer.png differ
diff --git a/media/speedometer.svg b/media/speedometer.svg
new file mode 100644
index 0000000..3324dac
--- /dev/null
+++ b/media/speedometer.svg
@@ -0,0 +1,246 @@
+
+
+
+
diff --git a/media/speedometer2.svg b/media/speedometer2.svg
new file mode 100644
index 0000000..2655e94
--- /dev/null
+++ b/media/speedometer2.svg
@@ -0,0 +1,295 @@
+
+
+
+
diff --git a/src/hud.rs b/src/hud.rs
index 907e810..1aa4bfe 100644
--- a/src/hud.rs
+++ b/src/hud.rs
@@ -74,6 +74,7 @@ impl Plugin for HudPlugin {
#[derive(Component)] struct NodeChoiceText;
#[derive(Component)] struct NodeCurrentChatLine;
#[derive(Component)] struct Reticule;
+#[derive(Component)] struct Speedometer;
#[derive(Component)] pub struct ToggleableHudElement;
#[derive(Component)] pub struct ToggleableHudMapElement;
#[derive(Component)] struct Selectagon;
@@ -319,6 +320,36 @@ fn setup(
));
});
+ // Add Speedometer
+ let reticule_handle: Handle = asset_server.load("sprites/speedometer.png");
+ commands.spawn((
+ NodeBundle {
+ style: Style {
+ width: Val::VMin(10.0),
+ height: Val::Percent(100.0),
+ align_items: AlignItems::End,
+ overflow: Overflow::clip(),
+ ..default()
+ },
+ visibility,
+ ..default()
+ },
+ Speedometer,
+ ToggleableHudElement,
+ )).with_children(|builder| {
+ builder.spawn((
+ ImageBundle {
+ image: UiImage::new(reticule_handle),
+ style: Style {
+ width: Val::VMin(50.0),
+ height: Val::VMin(10.0),
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ ));
+ });
+
// Chat "subtitles" and choices
commands.spawn(NodeBundle {
style: Style {
@@ -395,6 +426,7 @@ fn update_hud(
mut q_node_currentline: Query<&mut Text, (With, Without, Without, Without)>,
query_all_actors: Query<&actor::Actor>,
settings: Res,
+ mut q_speedometer: Query<&mut Style, With>,
q_target: Query<(&IsClickable, Option<&Position>, Option<&LinearVelocity>), With>,
) {
// TODO only when hud is actually on
@@ -494,6 +526,14 @@ fn update_hud(
let speed_readable = nature::readable_distance(speed);
text.sections[14].value = format!("\n{speed_readable}/s\n{gforce:.1}g{dev_speed}");
+ if let Ok(mut speedometer) = q_speedometer.get_single_mut() {
+ let custom_c = nature::C / 1000.0;
+ let fraction = nature::lorenz_factor_custom_c(custom_c - speed, custom_c) as f32;
+ info!(fraction);
+ let wid = (fraction * 100.0).clamp(0.0, 100.0);
+ speedometer.width = Val::VMin(wid);
+ }
+
if target_multiple {
text.sections[15].value = "\n\nERROR: MULTIPLE TARGETS".to_string();
}
diff --git a/src/nature.rs b/src/nature.rs
index 70fddf5..c9bccaa 100644
--- a/src/nature.rs
+++ b/src/nature.rs
@@ -19,6 +19,7 @@ pub const LIGHTYEAR2METER: f64 = 9_460_730_472_580_800.0;
pub const PARSEC2METER: f64 = 3.0857e16;
pub const DIST_JUPTER_SUN: f64 = 778479.0e6;
pub const EARTH_GRAVITY: f32 = 9.81;
+pub const C: f64 = 299792458.0; // m/s
pub const SOL_RADIUS: f64 = 696_300_000.0;
pub const JUPITER_RADIUS: f64 = 71_492_000.0;
@@ -118,3 +119,11 @@ pub fn readable_distance(distance: f64) -> String {
}
return format!("{distance:.1}m");
}
+
+pub fn lorenz_factor(speed: f64) -> f64 {
+ (1.0 - (speed.powf(2.0) / C.powf(2.0))).sqrt()
+}
+
+pub fn lorenz_factor_custom_c(speed: f64, c: f64) -> f64 {
+ (1.0 - (speed.powf(2.0) / c.powf(2.0))).sqrt()
+}