WIP jupiter atmosphere
This commit is contained in:
parent
dbfe4a7790
commit
2d185a810b
68
src/actor.rs
68
src/actor.rs
|
@ -58,12 +58,20 @@ impl Plugin for ActorPlugin {
|
|||
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
handle_gforce
|
||||
.run_if(game_running)
|
||||
.run_if(alive)
|
||||
.after(PhysicsSet::Sync)
|
||||
.after(sync::position_to_transform)
|
||||
.after(handle_wants_acceleration),
|
||||
(
|
||||
handle_gforce
|
||||
.run_if(game_running)
|
||||
.run_if(alive)
|
||||
.after(PhysicsSet::Sync)
|
||||
.after(sync::position_to_transform)
|
||||
.after(handle_wants_acceleration),
|
||||
handle_atmosphere
|
||||
.run_if(game_running)
|
||||
.run_if(alive)
|
||||
.after(PhysicsSet::Sync)
|
||||
.after(sync::position_to_transform)
|
||||
.before(handle_gforce),
|
||||
),
|
||||
);
|
||||
app.add_systems(
|
||||
Update,
|
||||
|
@ -205,6 +213,13 @@ pub struct WantsMatchVelocityWith(pub String);
|
|||
pub struct Identifier(pub String);
|
||||
#[derive(Component)]
|
||||
pub struct OrbitsJupiter;
|
||||
#[derive(Component)]
|
||||
pub struct ExperiencesAtmosphere;
|
||||
#[derive(Component, Debug)]
|
||||
pub struct HasAtmosphere {
|
||||
pub r_inner: f64,
|
||||
pub r_outer: f64,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct LifeForm {
|
||||
|
@ -1109,3 +1124,44 @@ fn handle_gravity(
|
|||
v.0 += accel;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_atmosphere(
|
||||
time: Res<Time>,
|
||||
q_atmosphere: Query<(&Position, Option<&LinearVelocity>, &HasAtmosphere)>,
|
||||
mut q_actor: Query<
|
||||
(&Position, &mut LinearVelocity),
|
||||
(With<ExperiencesAtmosphere>, Without<HasAtmosphere>),
|
||||
>,
|
||||
) {
|
||||
let dt = time.delta_seconds() as f64;
|
||||
|
||||
for (pos, mut v) in &mut q_actor {
|
||||
for (atmo_pos, atmo_v, atmo) in &q_atmosphere {
|
||||
let distance = atmo_pos.distance(pos.0);
|
||||
if distance < atmo.r_outer {
|
||||
// height is between 0.0 (collides with planet) and 1.0 (outside of atmosphere)
|
||||
let height = if distance < atmo.r_inner {
|
||||
0.0
|
||||
} else {
|
||||
(distance - atmo.r_inner) / (atmo.r_outer - atmo.r_inner)
|
||||
};
|
||||
|
||||
let dv = if let Some(atmo_v) = atmo_v {
|
||||
v.0 - atmo_v.0
|
||||
} else {
|
||||
v.0
|
||||
};
|
||||
let friction = dv * (1.0 - height).powf(4.0) / 4.0;
|
||||
v.0 -= friction;
|
||||
|
||||
if distance < atmo.r_inner {
|
||||
let outward = (pos.0 - atmo_pos.0).normalize();
|
||||
let buoyancy = outward * (atmo.r_inner - distance) * dt * 10.0;
|
||||
v.0 += buoyancy;
|
||||
}
|
||||
|
||||
continue; // max. 1 atmosphere
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
25
src/cmd.rs
25
src/cmd.rs
|
@ -103,6 +103,7 @@ struct ParserState {
|
|||
is_tidally_locked: bool,
|
||||
is_mirror: bool,
|
||||
is_orbitring: bool,
|
||||
atmosphere: Option<String>,
|
||||
orbit_distance: Option<f64>,
|
||||
orbit_object_id: Option<String>,
|
||||
orbit_phase: Option<f64>,
|
||||
|
@ -168,6 +169,7 @@ impl Default for ParserState {
|
|||
is_tidally_locked: false,
|
||||
is_mirror: false,
|
||||
is_orbitring: false,
|
||||
atmosphere: None,
|
||||
orbit_distance: None,
|
||||
orbit_object_id: None,
|
||||
orbit_phase: None,
|
||||
|
@ -647,6 +649,9 @@ pub fn load_defs(mut ew_spawn: EventWriter<SpawnEvent>) {
|
|||
["collider", "handcrafted"] => {
|
||||
state.collider_is_one_mesh_of_scene = true;
|
||||
}
|
||||
["atmosphere", atmosphere_id] => {
|
||||
state.atmosphere = Some(atmosphere_id.to_string());
|
||||
}
|
||||
["player", "yes"] => {
|
||||
state.is_player = true;
|
||||
state.is_alive = true;
|
||||
|
@ -1465,6 +1470,8 @@ fn spawn_entities(
|
|||
});
|
||||
}
|
||||
if state.is_player || state.is_vehicle {
|
||||
actor.insert(actor::ExperiencesAtmosphere);
|
||||
|
||||
// used to apply mouse movement to actor rotation
|
||||
actor.insert(ExternalTorque::ZERO.with_persistence(false));
|
||||
}
|
||||
|
@ -1582,6 +1589,24 @@ fn spawn_entities(
|
|||
));
|
||||
});
|
||||
}
|
||||
if state.atmosphere.is_some() {
|
||||
let atmosphere_id = state.atmosphere.clone().unwrap();
|
||||
let component = match atmosphere_id.as_str() {
|
||||
"jupiter" => {
|
||||
Some(actor::HasAtmosphere {
|
||||
r_inner: scale.x as f64 * 1.01,
|
||||
r_outer: scale.x as f64 * 1.01 + nature::JUPITER_ATMO_HEIGHT,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
error!("Unknown atmosphere id `{atmosphere_id}`");
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(component) = component {
|
||||
actor.insert(component);
|
||||
}
|
||||
}
|
||||
actor_entity = actor.id();
|
||||
|
||||
for ar_asset_name in &state.ar_models {
|
||||
|
|
|
@ -85,6 +85,7 @@ actor 0 0 0
|
|||
sphere yes
|
||||
ring yes
|
||||
aurora yes
|
||||
atmosphere jupiter
|
||||
physics off
|
||||
rotationy 3.13
|
||||
rotationz 135
|
||||
|
|
|
@ -34,6 +34,8 @@ pub const SOL_MASS: f64 = 1.9885e30;
|
|||
pub const JUPITER_MASS: f64 = 1.8982e27;
|
||||
pub const EARTH_MASS: f64 = 5.972168e24;
|
||||
|
||||
pub const JUPITER_ATMO_HEIGHT: f64 = 1_000_000.0;
|
||||
|
||||
// Arbitrary offset to time epoch, to generate more interesting orbital arrangements:
|
||||
pub const ORBIT_TIME_OFFSET: f64 = 614533234154.0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue