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 std::f32::consts::PI;
|
||||
use std::f64::consts::PI as PI64;
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub struct CommandsPlugin;
|
||||
impl Plugin for CommandsPlugin {
|
||||
|
@ -68,6 +69,9 @@ struct ParserState {
|
|||
is_sun: bool,
|
||||
is_moon: bool,
|
||||
is_point_of_interest: bool,
|
||||
orbit_distance: Option<f64>,
|
||||
orbit_object_id: Option<String>,
|
||||
orbit_phase: Option<f64>,
|
||||
has_physics: bool,
|
||||
has_ring: bool,
|
||||
wants_maxrotation: Option<f64>,
|
||||
|
@ -119,6 +123,9 @@ impl Default for ParserState {
|
|||
is_sun: false,
|
||||
is_moon: false,
|
||||
is_point_of_interest: false,
|
||||
orbit_distance: None,
|
||||
orbit_object_id: None,
|
||||
orbit_phase: None,
|
||||
has_physics: true,
|
||||
has_ring: false,
|
||||
wants_maxrotation: None,
|
||||
|
@ -227,14 +234,20 @@ pub fn load_defs(
|
|||
["relativeto", id] => {
|
||||
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] => {
|
||||
if let (Ok(r), Ok(phase)) = (radius_str.parse::<f64>(), phase_str.parse::<f64>()) {
|
||||
let phase_deg = phase * PI64 * 2.0;
|
||||
state.pos = DVec3::new(
|
||||
state.pos.x + r * phase_deg.cos(),
|
||||
state.pos.y,
|
||||
state.pos.z + r * phase_deg.sin(),
|
||||
);
|
||||
state.orbit_distance = Some(r);
|
||||
state.orbit_phase = Some(phase * PI64 * 2.0);
|
||||
}
|
||||
else {
|
||||
error!("Can't parse float: {line}");
|
||||
|
@ -492,7 +505,7 @@ fn spawn_entities(
|
|||
let state = &state_wrapper.0;
|
||||
if state.class == DefClass::Actor {
|
||||
// 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()) {
|
||||
Some(pos) => {
|
||||
state.pos + *pos
|
||||
|
@ -505,6 +518,30 @@ fn spawn_entities(
|
|||
} else {
|
||||
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 {
|
||||
5.0
|
||||
} else if state.is_moon && settings.large_moons {
|
||||
|
@ -526,7 +563,7 @@ fn spawn_entities(
|
|||
actor.insert(SleepingDisabled);
|
||||
actor.insert(world::DespawnOnPlayerDeath);
|
||||
actor.insert(actor::HitPoints::default());
|
||||
actor.insert(Position::from(relative_pos));
|
||||
actor.insert(Position::from(absolute_pos));
|
||||
actor.insert(Rotation::from(state.rotation));
|
||||
if state.is_sphere {
|
||||
let sphere_texture_handle = if let Some(model) = &state.model {
|
||||
|
@ -653,7 +690,7 @@ fn spawn_entities(
|
|||
}
|
||||
if !state.id.is_empty() {
|
||||
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() {
|
||||
actor.insert(chat::Talker {
|
||||
|
@ -730,10 +767,10 @@ fn spawn_entities(
|
|||
ring_radius: nature::JUPITER_RING_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()
|
||||
},
|
||||
Position::new(relative_pos),
|
||||
Position::new(absolute_pos),
|
||||
Rotation::from(Quat::IDENTITY),
|
||||
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
||||
NotShadowCaster,
|
||||
|
|
|
@ -152,7 +152,7 @@ actor 0 0 0 io
|
|||
name Io
|
||||
id io
|
||||
relativeto jupiter
|
||||
orbit 421700e3 0.65
|
||||
orbitaround jupiter 421700e3
|
||||
scale 1822e3
|
||||
rotationy -0.40
|
||||
rotationx -0.50
|
||||
|
@ -165,7 +165,7 @@ actor 0 0 0 europa
|
|||
name Europa
|
||||
id europa
|
||||
relativeto jupiter
|
||||
orbit 670900e3 0.35
|
||||
orbitaround jupiter 670900e3
|
||||
scale 1561e3
|
||||
rotationy 0.20
|
||||
rotationx -0.50
|
||||
|
@ -178,7 +178,7 @@ actor 0 0 0 ganymede
|
|||
name Ganymede
|
||||
id ganymede
|
||||
relativeto jupiter
|
||||
orbit 1070400e3 0.93
|
||||
orbitaround jupiter 1070400e3
|
||||
scale 2634e3
|
||||
rotationy -0.40
|
||||
rotationx -0.50
|
||||
|
@ -191,7 +191,7 @@ actor 0 0 0 callisto
|
|||
name Callisto
|
||||
id callisto
|
||||
relativeto jupiter
|
||||
orbit 1882700e3 0.45
|
||||
orbitaround jupiter 1882700e3
|
||||
scale 2410e3
|
||||
rotationy -0.40
|
||||
rotationx -0.50
|
||||
|
@ -204,7 +204,7 @@ actor 0 0 0 moonlet
|
|||
name Thebe
|
||||
relativeto jupiter
|
||||
id thebe
|
||||
orbit 221900e3 0.66
|
||||
orbitaround jupiter 221900e3
|
||||
scale 50e3
|
||||
angularmomentum 0 0.025 0
|
||||
actor -55e3 44e3 0 suitv2
|
||||
|
@ -226,7 +226,7 @@ actor 0 0 0 moonlet
|
|||
name Metis
|
||||
relativeto jupiter
|
||||
id metis
|
||||
orbit 128000e3 0.8
|
||||
orbitaround jupiter 128000e3
|
||||
scale 21.5e3
|
||||
angularmomentum 0 0.025 0
|
||||
|
||||
|
@ -234,7 +234,7 @@ actor 0 0 0 moonlet
|
|||
name Adrastea
|
||||
relativeto jupiter
|
||||
id adrastea
|
||||
orbit 129000e3 0.5
|
||||
orbitaround jupiter 129000e3
|
||||
scale 8.2e3
|
||||
angularmomentum 0 0.025 0
|
||||
|
||||
|
@ -242,7 +242,7 @@ actor 0 0 0 moonlet
|
|||
name Amalthea
|
||||
relativeto jupiter
|
||||
id amalthea
|
||||
orbit 181365.84e3 0.2
|
||||
orbitaround jupiter 181365.84e3
|
||||
scale 83.5e3
|
||||
angularmomentum 0 0.025 0
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
//
|
||||
// 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 OXY_S: f32 = OXYGEN_USE_KG_PER_S;
|
||||
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 EARTH_GRAVITY: f32 = 9.81;
|
||||
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 JUPITER_RADIUS: f64 = 71_492_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)
|
||||
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 {
|
||||
(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