set moon orbit phases according to real time clock
This commit is contained in:
parent
2eb2915f62
commit
7f5894f9f7
|
@ -19,6 +19,7 @@ use crate::{actor, camera, chat, hud, nature, shading, skeleton, var, world};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::f64::consts::PI as PI64;
|
use std::f64::consts::PI as PI64;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
pub struct CommandsPlugin;
|
pub struct CommandsPlugin;
|
||||||
impl Plugin for CommandsPlugin {
|
impl Plugin for CommandsPlugin {
|
||||||
|
@ -68,6 +69,9 @@ struct ParserState {
|
||||||
is_sun: bool,
|
is_sun: bool,
|
||||||
is_moon: bool,
|
is_moon: bool,
|
||||||
is_point_of_interest: bool,
|
is_point_of_interest: bool,
|
||||||
|
orbit_distance: Option<f64>,
|
||||||
|
orbit_object_id: Option<String>,
|
||||||
|
orbit_phase: Option<f64>,
|
||||||
has_physics: bool,
|
has_physics: bool,
|
||||||
has_ring: bool,
|
has_ring: bool,
|
||||||
wants_maxrotation: Option<f64>,
|
wants_maxrotation: Option<f64>,
|
||||||
|
@ -119,6 +123,9 @@ impl Default for ParserState {
|
||||||
is_sun: false,
|
is_sun: false,
|
||||||
is_moon: false,
|
is_moon: false,
|
||||||
is_point_of_interest: false,
|
is_point_of_interest: false,
|
||||||
|
orbit_distance: None,
|
||||||
|
orbit_object_id: None,
|
||||||
|
orbit_phase: None,
|
||||||
has_physics: true,
|
has_physics: true,
|
||||||
has_ring: false,
|
has_ring: false,
|
||||||
wants_maxrotation: None,
|
wants_maxrotation: None,
|
||||||
|
@ -227,14 +234,20 @@ pub fn load_defs(
|
||||||
["relativeto", id] => {
|
["relativeto", id] => {
|
||||||
state.relative_to = Some(id.to_string());
|
state.relative_to = Some(id.to_string());
|
||||||
}
|
}
|
||||||
|
["orbitaround", object_id, radius_str] => {
|
||||||
|
if let Ok(r) = radius_str.parse::<f64>() {
|
||||||
|
state.orbit_distance = Some(r);
|
||||||
|
state.orbit_object_id = Some(object_id.to_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error!("Can't parse float: {line}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
["orbit", radius_str, phase_str] => {
|
["orbit", radius_str, phase_str] => {
|
||||||
if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) {
|
if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) {
|
||||||
let phase_deg = phase * PI64 * 2.0;
|
state.orbit_distance = Some(r);
|
||||||
state.pos = DVec3::new(
|
state.orbit_phase = Some(phase * PI64 * 2.0);
|
||||||
state.pos.x + r * phase_deg.cos(),
|
|
||||||
state.pos.y,
|
|
||||||
state.pos.z + r * phase_deg.sin(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error!("Can't parse float: {line}");
|
error!("Can't parse float: {line}");
|
||||||
|
@ -492,7 +505,7 @@ fn spawn_entities(
|
||||||
let state = &state_wrapper.0;
|
let state = &state_wrapper.0;
|
||||||
if state.class == DefClass::Actor {
|
if state.class == DefClass::Actor {
|
||||||
// Preprocessing
|
// Preprocessing
|
||||||
let relative_pos = if let Some(id) = &state.relative_to {
|
let mut absolute_pos = if let Some(id) = &state.relative_to {
|
||||||
match id2pos.0.get(&id.to_string()) {
|
match id2pos.0.get(&id.to_string()) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
state.pos + *pos
|
state.pos + *pos
|
||||||
|
@ -505,6 +518,30 @@ fn spawn_entities(
|
||||||
} else {
|
} else {
|
||||||
state.pos
|
state.pos
|
||||||
};
|
};
|
||||||
|
if let Some(r) = state.orbit_distance {
|
||||||
|
let phase_radians: f64 = if let Some(phase_radians) = state.orbit_phase {
|
||||||
|
phase_radians
|
||||||
|
} else if let Some(id) = &state.orbit_object_id {
|
||||||
|
let mass = match id.as_str() {
|
||||||
|
"jupiter" => nature::JUPITER_MASS,
|
||||||
|
_ => {
|
||||||
|
error!("Found no mass for object `{id}`");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let orbital_period = nature::simple_orbital_period(mass, r);
|
||||||
|
if let Ok(epoch) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
|
||||||
|
PI64 * 2.0 * (epoch.as_secs_f64() % orbital_period) / orbital_period
|
||||||
|
} else {
|
||||||
|
error!("Can't determine current time `{id}`");
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("if state.orbit_distance is set, then either state.orbit_object_id or state.orbit_phase must be set as well.");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
absolute_pos += nature::phase_dist_to_coords(phase_radians, r);
|
||||||
|
}
|
||||||
let scale = Vec3::splat(if state.is_sun {
|
let scale = Vec3::splat(if state.is_sun {
|
||||||
5.0
|
5.0
|
||||||
} else if state.is_moon && settings.large_moons {
|
} else if state.is_moon && settings.large_moons {
|
||||||
|
@ -526,7 +563,7 @@ fn spawn_entities(
|
||||||
actor.insert(SleepingDisabled);
|
actor.insert(SleepingDisabled);
|
||||||
actor.insert(world::DespawnOnPlayerDeath);
|
actor.insert(world::DespawnOnPlayerDeath);
|
||||||
actor.insert(actor::HitPoints::default());
|
actor.insert(actor::HitPoints::default());
|
||||||
actor.insert(Position::from(relative_pos));
|
actor.insert(Position::from(absolute_pos));
|
||||||
actor.insert(Rotation::from(state.rotation));
|
actor.insert(Rotation::from(state.rotation));
|
||||||
if state.is_sphere {
|
if state.is_sphere {
|
||||||
let sphere_texture_handle = if let Some(model) = &state.model {
|
let sphere_texture_handle = if let Some(model) = &state.model {
|
||||||
|
@ -653,7 +690,7 @@ fn spawn_entities(
|
||||||
}
|
}
|
||||||
if !state.id.is_empty() {
|
if !state.id.is_empty() {
|
||||||
actor.insert(actor::Identifier(state.id.clone()));
|
actor.insert(actor::Identifier(state.id.clone()));
|
||||||
id2pos.0.insert(state.id.clone(), relative_pos);
|
id2pos.0.insert(state.id.clone(), absolute_pos);
|
||||||
}
|
}
|
||||||
if !state.chat.is_empty() {
|
if !state.chat.is_empty() {
|
||||||
actor.insert(chat::Talker {
|
actor.insert(chat::Talker {
|
||||||
|
@ -730,10 +767,10 @@ fn spawn_entities(
|
||||||
ring_radius: nature::JUPITER_RING_RADIUS as f32,
|
ring_radius: nature::JUPITER_RING_RADIUS as f32,
|
||||||
jupiter_radius: nature::JUPITER_RADIUS as f32,
|
jupiter_radius: nature::JUPITER_RADIUS as f32,
|
||||||
}),
|
}),
|
||||||
transform: Transform::from_translation(relative_pos.as_vec3()),
|
transform: Transform::from_translation(absolute_pos.as_vec3()),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Position::new(relative_pos),
|
Position::new(absolute_pos),
|
||||||
Rotation::from(Quat::IDENTITY),
|
Rotation::from(Quat::IDENTITY),
|
||||||
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
||||||
NotShadowCaster,
|
NotShadowCaster,
|
||||||
|
|
|
@ -152,7 +152,7 @@ actor 0 0 0 io
|
||||||
name Io
|
name Io
|
||||||
id io
|
id io
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
orbit 421700e3 0.65
|
orbitaround jupiter 421700e3
|
||||||
scale 1822e3
|
scale 1822e3
|
||||||
rotationy -0.40
|
rotationy -0.40
|
||||||
rotationx -0.50
|
rotationx -0.50
|
||||||
|
@ -165,7 +165,7 @@ actor 0 0 0 europa
|
||||||
name Europa
|
name Europa
|
||||||
id europa
|
id europa
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
orbit 670900e3 0.35
|
orbitaround jupiter 670900e3
|
||||||
scale 1561e3
|
scale 1561e3
|
||||||
rotationy 0.20
|
rotationy 0.20
|
||||||
rotationx -0.50
|
rotationx -0.50
|
||||||
|
@ -178,7 +178,7 @@ actor 0 0 0 ganymede
|
||||||
name Ganymede
|
name Ganymede
|
||||||
id ganymede
|
id ganymede
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
orbit 1070400e3 0.93
|
orbitaround jupiter 1070400e3
|
||||||
scale 2634e3
|
scale 2634e3
|
||||||
rotationy -0.40
|
rotationy -0.40
|
||||||
rotationx -0.50
|
rotationx -0.50
|
||||||
|
@ -191,7 +191,7 @@ actor 0 0 0 callisto
|
||||||
name Callisto
|
name Callisto
|
||||||
id callisto
|
id callisto
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
orbit 1882700e3 0.45
|
orbitaround jupiter 1882700e3
|
||||||
scale 2410e3
|
scale 2410e3
|
||||||
rotationy -0.40
|
rotationy -0.40
|
||||||
rotationx -0.50
|
rotationx -0.50
|
||||||
|
@ -204,7 +204,7 @@ actor 0 0 0 moonlet
|
||||||
name Thebe
|
name Thebe
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
id thebe
|
id thebe
|
||||||
orbit 221900e3 0.66
|
orbitaround jupiter 221900e3
|
||||||
scale 50e3
|
scale 50e3
|
||||||
angularmomentum 0 0.025 0
|
angularmomentum 0 0.025 0
|
||||||
actor -55e3 44e3 0 suitv2
|
actor -55e3 44e3 0 suitv2
|
||||||
|
@ -226,7 +226,7 @@ actor 0 0 0 moonlet
|
||||||
name Metis
|
name Metis
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
id metis
|
id metis
|
||||||
orbit 128000e3 0.8
|
orbitaround jupiter 128000e3
|
||||||
scale 21.5e3
|
scale 21.5e3
|
||||||
angularmomentum 0 0.025 0
|
angularmomentum 0 0.025 0
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ actor 0 0 0 moonlet
|
||||||
name Adrastea
|
name Adrastea
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
id adrastea
|
id adrastea
|
||||||
orbit 129000e3 0.5
|
orbitaround jupiter 129000e3
|
||||||
scale 8.2e3
|
scale 8.2e3
|
||||||
angularmomentum 0 0.025 0
|
angularmomentum 0 0.025 0
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ actor 0 0 0 moonlet
|
||||||
name Amalthea
|
name Amalthea
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
id amalthea
|
id amalthea
|
||||||
orbit 181365.84e3 0.2
|
orbitaround jupiter 181365.84e3
|
||||||
scale 83.5e3
|
scale 83.5e3
|
||||||
angularmomentum 0 0.025 0
|
angularmomentum 0 0.025 0
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
//
|
//
|
||||||
// This module manages the messy, impure parts of our universe.
|
// This module manages the messy, impure parts of our universe.
|
||||||
|
|
||||||
|
use bevy::math::DVec3;
|
||||||
|
use std::f64::consts::PI as PI64;
|
||||||
|
|
||||||
pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5;
|
pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5;
|
||||||
pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S;
|
pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S;
|
||||||
pub const OXY_M: f32 = OXYGEN_USE_KG_PER_S * 60.0;
|
pub const OXY_M: f32 = OXYGEN_USE_KG_PER_S * 60.0;
|
||||||
|
@ -20,10 +23,12 @@ pub const PARSEC2METER: f64 = 3.0857e16;
|
||||||
pub const DIST_JUPTER_SUN: f64 = 778479.0e6;
|
pub const DIST_JUPTER_SUN: f64 = 778479.0e6;
|
||||||
pub const EARTH_GRAVITY: f32 = 9.81;
|
pub const EARTH_GRAVITY: f32 = 9.81;
|
||||||
pub const C: f64 = 299792458.0; // m/s
|
pub const C: f64 = 299792458.0; // m/s
|
||||||
|
pub const G: f64 = 6.6743015e-11; // Gravitational constant in Nm²/kg²
|
||||||
|
|
||||||
pub const SOL_RADIUS: f64 = 696_300_000.0;
|
pub const SOL_RADIUS: f64 = 696_300_000.0;
|
||||||
pub const JUPITER_RADIUS: f64 = 71_492_000.0;
|
pub const JUPITER_RADIUS: f64 = 71_492_000.0;
|
||||||
pub const JUPITER_RING_RADIUS: f64 = 229_000_000.0;
|
pub const JUPITER_RING_RADIUS: f64 = 229_000_000.0;
|
||||||
|
pub const JUPITER_MASS: f64 = 1.8982e27;
|
||||||
|
|
||||||
// Each star's values: (x, y, z, magnitude, color index, distance, name)
|
// Each star's values: (x, y, z, magnitude, color index, distance, name)
|
||||||
pub const STARS: &[(f32, f32, f32, f32, f32, f32, &str)] = &include!("data/stars.in");
|
pub const STARS: &[(f32, f32, f32, f32, f32, f32, &str)] = &include!("data/stars.in");
|
||||||
|
@ -139,3 +144,15 @@ pub fn lorenz_factor(speed: f64) -> f64 {
|
||||||
pub fn lorenz_factor_custom_c(speed: f64, c: f64) -> f64 {
|
pub fn lorenz_factor_custom_c(speed: f64, c: f64) -> f64 {
|
||||||
(1.0 - (speed.powf(2.0) / c.powf(2.0))).sqrt()
|
(1.0 - (speed.powf(2.0) / c.powf(2.0))).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn simple_orbital_period(mass: f64, distance: f64) -> f64 {
|
||||||
|
return 2.0 * PI64 * (distance.powf(3.0) / (G * mass)).sqrt();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn phase_dist_to_coords(phase_radians: f64, distance: f64) -> DVec3 {
|
||||||
|
return DVec3::new(
|
||||||
|
distance * phase_radians.cos(),
|
||||||
|
0.0,
|
||||||
|
distance * phase_radians.sin(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue