diff --git a/scenarios/voyager_1.sim b/scenarios/voyager_1.sim index cbd3b83..e4351ad 100644 --- a/scenarios/voyager_1.sim +++ b/scenarios/voyager_1.sim @@ -1 +1 @@ -{"bodies":[{"children":[{"children":[],"data":{"mass":5.97219e24,"starting_position":{"x":-140968752.6119205,"y":42678857.74469588,"z":-25254.74791200459},"starting_velocity":{"x":-9.120162775175537,"y":-28.61319460879634,"z":-0.001164064214398408},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"axial_tilt":23.439281,"simulate":true,"naif_id":-1,"light_source":null}},{"children":[],"data":{"mass":721.0,"starting_position":{"x":-478755881.5606613,"y":626054143.9714329,"z":8162617.640802503},"starting_velocity":{"x":-13.59995211599172,"y":7.453842974225971,"z":-0.06438163739849133},"name":"Voyager-1","model_path":"voyager.glb","diameter":0.34,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"naif_id":-1,"light_source":null}},{"children":[{"children":[],"data":{"mass":8.931938e22,"starting_position":{"x":-493605925.879685,"y":575473831.0733274,"z":265175719.89332935},"starting_velocity":{"x":-9.978391983021908,"y":-3.7823007484817617,"z":-2.279987471012407},"name":"Io","model_path":"io.glb","diameter":3643.2,"rotation_speed":2547.36,"axial_tilt":0.0,"simulate":true,"naif_id":55501,"light_source":null}},{"children":[],"data":{"mass":4.799844e22,"starting_position":{"x":-477194029.517708,"y":556538490.081504,"z":249403655.71783304},"starting_velocity":{"x":-12.757436408817693,"y":-7.563126779474686,"z":-4.3494285120587115},"name":"Europa","model_path":"europa.glb","diameter":1560.8,"rotation_speed":5113.70064,"axial_tilt":0.0,"simulate":true,"naif_id":55502,"light_source":null}},{"children":[],"data":{"mass":1.4819e23,"starting_position":{"x":-486818965.27222335,"y":547266799.9050096,"z":253312203.97226703},"starting_velocity":{"x":-12.338585855725498,"y":-6.213844491167524,"z":-2.2017724479586405},"name":"Ganymede","model_path":"ganymede.glb","diameter":5268.2,"rotation_speed":10303.2,"axial_tilt":0.0,"simulate":true,"naif_id":55503,"light_source":null}},{"children":[],"data":{"mass":1.075938e23,"starting_position":{"x":-485964054.4773958,"y":595772805.8749864,"z":262952504.4681254},"starting_velocity":{"x":-8.30759289228536,"y":-6.896388751529391,"z":-2.180655899725101},"name":"Callisto","model_path":"callisto.glb","diameter":4820.6,"rotation_speed":24032.16,"axial_tilt":0.0,"simulate":true,"naif_id":55504,"light_source":null}}],"data":{"mass":1.8981999999999999e27,"starting_position":{"x":-479848914.5271239,"y":572958028.2936275,"z":257301363.24801183},"starting_velocity":{"x":-10.530416675065974,"y":-6.83225142804572,"z":-2.672213707159385},"name":"Jupiter","model_path":"jupiter.glb","diameter":139822.0,"rotation_speed":595.0,"axial_tilt":3.13,"simulate":true,"naif_id":5,"light_source":null}},{"children":[{"children":[],"data":{"mass":1.3452e23,"starting_position":{"x":-1317155945.9130914,"y":401685520.2661368,"z":221893876.7955563},"starting_velocity":{"x":-9.109829090037053,"y":-7.800989933081476,"z":-2.9359612621322944},"name":"Titan","model_path":"titan.glb","diameter":5149.46,"rotation_speed":22920.0,"axial_tilt":0.0,"simulate":true,"naif_id":606,"light_source":null}},{"children":[],"data":{"mass":2.3064854e21,"starting_position":{"x":-1317382065.4602823,"y":400972997.6578921,"z":221961663.9500768},"starting_velocity":{"x":-11.964844277122554,"y":-10.124933789839565,"z":-2.5597577939355545},"name":"Rhea","model_path":"rhea.glb","diameter":763.5,"rotation_speed":6480.0,"axial_tilt":0.0,"simulate":true,"naif_id":605,"light_source":null}},{"children":[],"data":{"mass":1.8056591e21,"starting_position":{"x":-1318561544.5943272,"y":397100581.45783347,"z":221666433.0104799},"starting_velocity":{"x":-0.7035327859354465,"y":-9.49338661268315,"z":-4.117463427766138},"name":"Iapetus","model_path":"iapetus.glb","diameter":1470.0,"rotation_speed":113760.0,"axial_tilt":0.0,"simulate":true,"naif_id":608,"light_source":null}},{"children":[],"data":{"mass":1.0954868e21,"starting_position":{"x":-1316974778.9178972,"y":400233150.94101655,"z":221978521.7508267},"starting_velocity":{"x":2.1798879595542897,"y":-0.45446507747606546,"z":-4.45063449430418},"name":"Dione","model_path":"dione.glb","diameter":1123.0,"rotation_speed":3941.1576,"axial_tilt":0.0,"simulate":true,"naif_id":604,"light_source":null}},{"children":[],"data":{"mass":6.174959e20,"starting_position":{"x":-1317564624.039431,"y":400392597.6125812,"z":222023174.2808789},"starting_velocity":{"x":-1.1379697756912446,"y":-19.56390177319556,"z":-2.790506179151342},"name":"Tethys","model_path":"tethys.glb","diameter":1062.0,"rotation_speed":2718.0,"axial_tilt":0.0,"simulate":true,"naif_id":603,"light_source":null}},{"children":[],"data":{"mass":3.75094e19,"starting_position":{"x":-1317457696.975204,"y":400423814.833281,"z":222004140.48551643},"starting_velocity":{"x":-0.8831812142331659,"y":-22.805919749933615,"z":-2.919858165732254},"name":"Mimas","model_path":"mimas.glb","diameter":396.0,"rotation_speed":1356.0,"axial_tilt":0.0,"simulate":true,"naif_id":601,"light_source":null}},{"children":[],"data":{"mass":1.080318e20,"starting_position":{"x":-1317091549.573697,"y":400602202.1932426,"z":221961416.07156047},"starting_velocity":{"x":-11.380791737588428,"y":1.433197828984678,"z":-3.42730656043974},"name":"Enceladus","model_path":"enceladus.glb","diameter":504.0,"rotation_speed":1973.11392,"axial_tilt":0.0,"simulate":true,"naif_id":602,"light_source":null}}],"data":{"mass":5.6834e26,"starting_position":{"x":-1317279006.668406,"y":400456460.90597373,"z":221988296.4282521},"starting_velocity":{"x":-3.677373856296947,"y":-8.517486004011271,"z":-3.358977485433484},"name":"Saturn","model_path":"saturn.glb","diameter":116464.0,"rotation_speed":633.0,"axial_tilt":26.73,"simulate":true,"naif_id":699,"light_source":null}}],"data":{"mass":1.9885e30,"starting_position":{"x":961232.2255364412,"y":-409638.1359710687,"z":-26920.33308127907},"starting_velocity":{"x":0.01057748426413201,"y":0.01000902911669899,"z":-0.0003291835695185871},"name":"Sol","model_path":"sun.glb","diameter":1392000.0,"rotation_speed":38880.0,"axial_tilt":7.25,"simulate":true,"naif_id":-1,"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true}}}],"data_sets":["de440s.bsp","sat441.bsp"],"starting_time_millis":289353600000,"title":"Voyager 1 Jupiter Flyby","description":"A scenario showcasing the Jupiter flyby from Voyager-1","scale":1e-7,"timestep":20} \ No newline at end of file +{"bodies":[{"children":[{"children":[],"data":{"mass":5.97219e24,"starting_position":{"x":-140968752.6119205,"y":42678857.74469588,"z":-25254.74791200459},"starting_velocity":{"x":-9.120162775175537,"y":-28.61319460879634,"z":-0.001164064214398408},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"axial_tilt":23.439281,"simulate":true,"naif_id":-1,"light_source":null}},{"children":[],"data":{"mass":721.0,"starting_position":{"x":-478755881.5606613,"y":626054143.9714329,"z":8162617.640802503},"starting_velocity":{"x":-13.59995211599172,"y":7.453842974225971,"z":-0.06438163739849133},"name":"Voyager-1","model_path":"voyager.glb","diameter":0.34,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"naif_id":-1,"light_source":null}},{"children":[{"children":[],"data":{"mass":8.931938e22,"starting_position":{"x":-493605925.879685,"y":575473831.0733274,"z":265175719.89332935},"starting_velocity":{"x":-9.978391983021908,"y":-3.7823007484817617,"z":-2.279987471012407},"name":"Io","model_path":"io.glb","diameter":3643.2,"rotation_speed":2547.36,"axial_tilt":0.0,"simulate":true,"naif_id":55501,"light_source":null}},{"children":[],"data":{"mass":4.799844e22,"starting_position":{"x":-477194029.517708,"y":556538490.081504,"z":249403655.71783304},"starting_velocity":{"x":-12.757436408817693,"y":-7.563126779474686,"z":-4.3494285120587115},"name":"Europa","model_path":"europa.glb","diameter":1560.8,"rotation_speed":5113.70064,"axial_tilt":0.0,"simulate":true,"naif_id":55502,"light_source":null}},{"children":[],"data":{"mass":1.4819e23,"starting_position":{"x":-486818965.27222335,"y":547266799.9050096,"z":253312203.97226703},"starting_velocity":{"x":-12.338585855725498,"y":-6.213844491167524,"z":-2.2017724479586405},"name":"Ganymede","model_path":"ganymede.glb","diameter":5268.2,"rotation_speed":10303.2,"axial_tilt":0.0,"simulate":true,"naif_id":55503,"light_source":null}},{"children":[],"data":{"mass":1.075938e23,"starting_position":{"x":-485964054.4773958,"y":595772805.8749864,"z":262952504.4681254},"starting_velocity":{"x":-8.30759289228536,"y":-6.896388751529391,"z":-2.180655899725101},"name":"Callisto","model_path":"callisto.glb","diameter":4820.6,"rotation_speed":24032.16,"axial_tilt":0.0,"simulate":true,"naif_id":55504,"light_source":null}}],"data":{"mass":1.8982e27,"starting_position":{"x":-479848914.5271239,"y":572958028.2936275,"z":257301363.24801183},"starting_velocity":{"x":-10.530416675065974,"y":-6.83225142804572,"z":-2.672213707159385},"name":"Jupiter","model_path":"jupiter.glb","diameter":139822.0,"rotation_speed":595.0,"axial_tilt":3.13,"simulate":true,"naif_id":5,"light_source":null}},{"children":[{"children":[],"data":{"mass":1.3452e23,"starting_position":{"x":-1317155945.9130914,"y":401685520.2661368,"z":221893876.7955563},"starting_velocity":{"x":-9.109829090037053,"y":-7.800989933081476,"z":-2.9359612621322944},"name":"Titan","model_path":"titan.glb","diameter":5149.46,"rotation_speed":22920.0,"axial_tilt":0.0,"simulate":true,"naif_id":606,"light_source":null}},{"children":[],"data":{"mass":2.3064854e21,"starting_position":{"x":-1317382065.4602823,"y":400972997.6578921,"z":221961663.9500768},"starting_velocity":{"x":-11.964844277122554,"y":-10.124933789839565,"z":-2.5597577939355545},"name":"Rhea","model_path":"rhea.glb","diameter":763.5,"rotation_speed":6480.0,"axial_tilt":0.0,"simulate":true,"naif_id":605,"light_source":null}},{"children":[],"data":{"mass":1.8056591e21,"starting_position":{"x":-1318561544.5943272,"y":397100581.45783347,"z":221666433.0104799},"starting_velocity":{"x":-0.7035327859354465,"y":-9.49338661268315,"z":-4.117463427766138},"name":"Iapetus","model_path":"iapetus.glb","diameter":1470.0,"rotation_speed":113760.0,"axial_tilt":0.0,"simulate":true,"naif_id":608,"light_source":null}},{"children":[],"data":{"mass":1.0954868e21,"starting_position":{"x":-1316974778.9178972,"y":400233150.94101655,"z":221978521.7508267},"starting_velocity":{"x":2.1798879595542897,"y":-0.45446507747606546,"z":-4.45063449430418},"name":"Dione","model_path":"dione.glb","diameter":1123.0,"rotation_speed":3941.1576,"axial_tilt":0.0,"simulate":true,"naif_id":604,"light_source":null}},{"children":[],"data":{"mass":6.174959e20,"starting_position":{"x":-1317564624.039431,"y":400392597.6125812,"z":222023174.2808789},"starting_velocity":{"x":-1.1379697756912446,"y":-19.56390177319556,"z":-2.790506179151342},"name":"Tethys","model_path":"tethys.glb","diameter":1062.0,"rotation_speed":2718.0,"axial_tilt":0.0,"simulate":true,"naif_id":603,"light_source":null}},{"children":[],"data":{"mass":3.75094e19,"starting_position":{"x":-1317457696.975204,"y":400423814.833281,"z":222004140.48551643},"starting_velocity":{"x":-0.8831812142331659,"y":-22.805919749933615,"z":-2.919858165732254},"name":"Mimas","model_path":"mimas.glb","diameter":396.0,"rotation_speed":1356.0,"axial_tilt":0.0,"simulate":true,"naif_id":601,"light_source":null}},{"children":[],"data":{"mass":1.080318e20,"starting_position":{"x":-1317091549.573697,"y":400602202.1932426,"z":221961416.07156047},"starting_velocity":{"x":-11.380791737588428,"y":1.433197828984678,"z":-3.42730656043974},"name":"Enceladus","model_path":"enceladus.glb","diameter":504.0,"rotation_speed":1973.11392,"axial_tilt":0.0,"simulate":true,"naif_id":602,"light_source":null}}],"data":{"mass":5.6834e26,"starting_position":{"x":-1317279006.668406,"y":400456460.90597373,"z":221988296.4282521},"starting_velocity":{"x":-3.677373856296947,"y":-8.517486004011271,"z":-3.358977485433484},"name":"Saturn","model_path":"saturn.glb","diameter":116464.0,"rotation_speed":633.0,"axial_tilt":26.73,"simulate":true,"naif_id":699,"light_source":null}}],"data":{"mass":1.9885e30,"starting_position":{"x":961232.2255364412,"y":-409638.1359710687,"z":-26920.33308127907},"starting_velocity":{"x":0.01057748426413201,"y":0.01000902911669899,"z":-0.0003291835695185871},"name":"Sol","model_path":"sun.glb","diameter":1392000.0,"rotation_speed":38880.0,"axial_tilt":7.25,"simulate":true,"naif_id":-1,"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true}}}],"data_sets":["de440s.bsp","sat441.bsp","pck11.pca"],"starting_time_millis":289353600000,"title":"Voyager 1 Jupiter Flyby","description":"A scenario showcasing the Jupiter flyby from Voyager-1","scale":1e-7,"timestep":20} \ No newline at end of file diff --git a/src/simulation/asset/serialization.rs b/src/simulation/asset/serialization.rs index 248b7a1..553f9f6 100644 --- a/src/simulation/asset/serialization.rs +++ b/src/simulation/asset/serialization.rs @@ -1,3 +1,4 @@ +use anise::structure::planetocentric::ellipsoid::Ellipsoid; use bevy::asset::io::file::FileAssetReader; use bevy::asset::io::{AssetSource, AssetSourceBuilder, AssetSourceId, Reader}; use bevy::asset::AsyncReadExt; @@ -67,6 +68,10 @@ pub struct SerializedBodyData { pub simulate: bool, #[serde(default = "default_id")] pub naif_id: i32, + #[serde(default = "default_id")] + pub orientation_id: i32, + #[serde(default = "default_ellipsoid")] + pub ellipsoid: Ellipsoid, pub light_source: Option } @@ -78,6 +83,10 @@ fn default_spk() -> Vec { Vec::new() } +fn default_ellipsoid() -> Ellipsoid { + Ellipsoid::from_sphere(1.0) +} + #[derive(Debug, Serialize, Deserialize, TypePath, Clone)] pub struct SerializedLightSource { pub intensity: f32, diff --git a/src/simulation/components/anise.rs b/src/simulation/components/anise.rs index 678a78d..b2882aa 100644 --- a/src/simulation/components/anise.rs +++ b/src/simulation/components/anise.rs @@ -1,17 +1,17 @@ -use crate::simulation::components::horizons::NaifIdComponent; +use crate::simulation::components::horizons::AniseMetadata; use crate::simulation::components::selection::SelectedEntity; use crate::simulation::scenario::loading::LoadingState; use crate::simulation::scenario::setup::ScenarioData; use crate::simulation::ui::editor_body_panel::EditorPanelState; use crate::simulation::ui::toast::{error_toast, success_toast, ToastContainer}; -use crate::simulation::SimState; -use anise::constants::frames::{JUPITER_BARYCENTER_J2000, SSB_J2000}; -use anise::constants::orientations::J2000; +use crate::simulation::{SimState, SimStateType}; +use anise::constants::frames::{IAU_EARTH_FRAME, JUPITER_BARYCENTER_J2000, SSB_J2000}; +use anise::constants::orientations::{IAU_EARTH, J2000}; use anise::math::Vector3; use anise::prelude::{Almanac, Epoch, Frame, SPK}; use bevy::app::Plugin; use bevy::math::DVec3; -use bevy::prelude::{in_state, IntoSystemConfigs, OnEnter, Query, Res, ResMut, Resource, Update}; +use bevy::prelude::{in_state, IntoSystemConfigs, OnEnter, Query, Res, ResMut, Resource, State, Update}; use reqwest::get; pub struct AnisePlugin; @@ -35,7 +35,7 @@ impl Default for AlmanacHolder { pub fn retrieve_starting_data( selected_entity: Res, - bodies: Query<&NaifIdComponent>, + mut bodies: Query<&mut AniseMetadata>, almanac: Res, mut e_state: ResMut, scenario: Res, @@ -43,23 +43,31 @@ pub fn retrieve_starting_data( ) { // Define an Epoch in the dynamical barycentric time scale let epoch = Epoch::from_unix_milliseconds(scenario.starting_time_millis as f64); - let id = selected_entity.entity.map(|e| bodies.get(e).ok()).flatten().unwrap(); + let mut metadata = selected_entity.entity.map(|e| bodies.get_mut(e).ok()).flatten().unwrap(); let state = almanac.0 .translate( - Frame::new(id.0, J2000), // Target + Frame::new(metadata.target_id, J2000), // Target SSB_J2000, // Observer epoch, None, ); if let Ok(s) = state { - toasts.0.add(success_toast(&format!("Retrieved data for {}", id.0))); + toasts.0.add(success_toast(&format!("Retrieved data for {}", metadata.target_id))); e_state.new_velocity = vector3_to_dvec3(s.velocity_km_s); e_state.new_position = vector3_to_dvec3(s.radius_km); } else { println!("{:?}", state); toasts.0.add(error_toast(format!("Error: {:?}", state.unwrap_err()).as_str())); } + + let full_frame = almanac.0.frame_from_uid(Frame::new(metadata.target_id, metadata.orientation_id)); + + if let Ok(f) = full_frame { + e_state.ellipsoid = f.shape.unwrap(); + } else { + toasts.0.add(error_toast(format!("Error: {:?}", full_frame.unwrap_err()).as_str())); + } } fn vector3_to_dvec3(v: Vector3) -> DVec3 { @@ -70,32 +78,31 @@ fn spk_file_loading( mut almanac: ResMut, mut toasts: ResMut, mut scenario_data: ResMut, - mut loading_state: ResMut + mut loading_state: ResMut, + sim_type: Res ) { - if loading_state.loaded_spk_files || !loading_state.spawned_bodies { + if loading_state.loaded_spk_files || !loading_state.spawned_bodies || *sim_type == SimStateType::Simulation { return; } - load_spk_files(scenario_data.spk_files.clone(), &mut almanac, &mut toasts); + load_spice_files(scenario_data.spice_files.clone(), &mut almanac, &mut toasts); loading_state.loaded_spk_files = true; } -pub fn load_spk_files( +pub fn load_spice_files( paths: Vec, almanac: &mut AlmanacHolder, toasts: &mut ToastContainer ) { let mut missing_paths = Vec::new(); for path in paths { - let spk = SPK::load(format!("data/{}", path).as_str()).unwrap(); - if let Ok(a) = almanac.0.with_spk(spk) { + if let Ok(a) = almanac.0.load(format!("data/{}", path).as_str()) { almanac.0 = a; - // get_target_frames(&almanac.0); } else { missing_paths.push(path); } } if !missing_paths.is_empty() { - toasts.0.add(error_toast(format!("Couldn't load the following SPK files: {}", missing_paths.join(", ")).as_str())); + toasts.0.add(error_toast(format!("Couldn't load the following SPICE files: {}", missing_paths.join(", ")).as_str())); } } diff --git a/src/simulation/components/body.rs b/src/simulation/components/body.rs index c1a3d68..c46466d 100644 --- a/src/simulation/components/body.rs +++ b/src/simulation/components/body.rs @@ -6,7 +6,8 @@ use bevy::math::{DVec3, Vec3}; use bevy::prelude::{default, Bundle, Component, Entity, Handle, Reflect, Scene, Srgba, Transform}; use bevy::render::primitives::Aabb; use std::collections::VecDeque; -use crate::simulation::components::horizons::NaifIdComponent; +use anise::structure::planetocentric::ellipsoid::Ellipsoid; +use crate::simulation::components::horizons::AniseMetadata; #[derive(Component, Clone, Default, Reflect, Copy)] pub struct Mass(pub f64); @@ -82,12 +83,21 @@ impl Default for OrbitSettings { #[derive(Component, Reflect, Clone, Default)] pub struct SimPosition(pub DVec3); -#[derive(Component, Reflect, Clone, Default)] +#[derive(Component, Reflect, Clone)] pub struct Diameter { pub num: f32, pub applied: bool, - pub aabb: Option + pub ellipsoid: Ellipsoid, + pub path: String, + +} + +impl Default for Diameter { + + fn default() -> Self { + Diameter { num: 0.0, applied: false, ellipsoid: Ellipsoid::from_sphere(1.0), path: "".to_string() } + } } @@ -130,7 +140,7 @@ pub struct BodyBundle { pub axial_tilt: AxialTilt, pub diameter: Diameter, pub billboard_visible: BillboardVisible, - pub naif_id: NaifIdComponent, + pub naif_id: AniseMetadata, } @@ -145,6 +155,8 @@ impl From for BodyBundle { model_path: ModelPath(format!("models/{}#Scene0", value.data.model_path)), diameter: Diameter { num: (value.data.diameter * 1000.0) as f32, + path: value.data.model_path, + ellipsoid: value.data.ellipsoid, ..default() }, axial_tilt: AxialTilt { @@ -152,7 +164,10 @@ impl From for BodyBundle { ..default() }, rotation_speed: RotationSpeed(value.data.rotation_speed), - naif_id: NaifIdComponent(value.data.naif_id), + naif_id: AniseMetadata { + target_id: value.data.naif_id, + orientation_id: value.data.orientation_id, + }, ..default() } } diff --git a/src/simulation/components/diameter.rs b/src/simulation/components/diameter.rs index 4d3afec..a0710fa 100644 --- a/src/simulation/components/diameter.rs +++ b/src/simulation/components/diameter.rs @@ -1,6 +1,7 @@ use bevy::{app::{App, Plugin}, math::Vec3A, prelude::{in_state, Children, GlobalTransform, Handle, IntoSystemConfigs, Mesh, Query, Res, ResMut, Transform, Update, Vec3, With}, render::primitives::{Aabb, Sphere}, scene::{SceneInstance, SceneSpawner}}; use bevy::ecs::query::QueryManyIter; -use bevy::prelude::{AssetServer, Entity, Name}; +use bevy::prelude::{AssetServer, Entity, Local, Name}; +use bevy::utils::HashMap; use crate::simulation::SimState; use crate::simulation::components::body::SceneHandle; use crate::simulation::components::body::{Diameter, Scale}; @@ -25,7 +26,8 @@ pub fn apply_real_diameter( spawner: Res, mut loading_state: ResMut, asset_server: Res, - s_scale: Res + s_scale: Res, + mut aabbs: Local> ) { if !bodies.is_empty() && bodies.iter().all(|(_, _, _, diameter, _, _)| { diameter.applied @@ -41,12 +43,12 @@ pub fn apply_real_diameter( if !spawner.instance_is_ready(**scene) { continue; } - let aabb = if let Some(aabb) = diameter.aabb { - aabb + let aabb = if let Some(aabb) = aabbs.get(&diameter.path.clone()) { + *aabb } else { let m = meshes.iter_many(spawner.iter_instance_entities(**scene)); let aabb = calculate_aabb(m); - diameter.aabb = Some(aabb); + aabbs.insert(diameter.path.clone(), aabb); aabb }; transform.scale = Vec3::splat(s_scale.m_to_unit_32(diameter.num) / 1.7) / (Vec3::from(aabb.half_extents)); //not dividing by 1.7 for the diameter makes them to big which doesn't work with satellites very close to their planet diff --git a/src/simulation/components/horizons.rs b/src/simulation/components/horizons.rs index 61c8748..faae6c5 100644 --- a/src/simulation/components/horizons.rs +++ b/src/simulation/components/horizons.rs @@ -3,6 +3,7 @@ use crate::simulation::asset::serialization::SerializedVec; use bevy::utils::HashMap; use reqwest::blocking::Client; use std::str::FromStr; +use anise::structure::planetocentric::ellipsoid::Ellipsoid; use bevy::math::DVec3; use bevy::prelude::{Component, Plugin, Query, Res, ResMut, Resource}; use chrono::NaiveDateTime; @@ -29,8 +30,24 @@ impl Default for HorizonsClient { } } -#[derive(Component, Clone, Default)] -pub struct NaifIdComponent(pub i32); +#[derive(Component, Clone, Debug)] +pub struct AniseMetadata { + + pub target_id: i32, + pub orientation_id: i32, + +} + +impl Default for AniseMetadata { + + fn default() -> Self { + Self { + target_id: -1, + orientation_id: -1, + } + } + +} const HORIZONS_API_URL: &'static str = "https://ssd.jpl.nasa.gov/api/horizons.api?format=text"; @@ -126,7 +143,7 @@ pub fn get_starting_data_horizons( pub fn retrieve_starting_data_horizons( selected_entity: Res, - bodies: Query<&NaifIdComponent>, + bodies: Query<&AniseMetadata>, client: Res, mut state: ResMut, scenario: Res, @@ -138,7 +155,7 @@ pub fn retrieve_starting_data_horizons( let stop_date = (starting_date + chrono::Duration::days(1)).format("%Y-%m-%d").to_string(); let id = bodies.get(entity).unwrap(); let parameters = HorizonsApiParameters::with_defaults() - .with_command(id.0) + .with_command(id.target_id) .with_start_time(start_date.as_str()) .with_stop_time(stop_date.as_str()); if let Ok((pos, vel)) = get_starting_data_horizons(parameters, client.0.clone()) { diff --git a/src/simulation/scenario/loading.rs b/src/simulation/scenario/loading.rs index 0b9780f..734726d 100644 --- a/src/simulation/scenario/loading.rs +++ b/src/simulation/scenario/loading.rs @@ -1,7 +1,7 @@ use bevy::{app::{App, Plugin}, prelude::{AssetServer, BuildChildren, Color, Commands, Component, default, Entity, in_state, IntoSystemConfigs, Label, NextState, NodeBundle, OnEnter, OnExit, Query, Res, ResMut, Resource, TextBundle, Update, With, Visibility, Has, Children, DespawnRecursiveExt}, text::{Text, TextStyle}, ui::{AlignItems, FlexDirection, JustifyContent, Node, Style, UiImage, UiRect, Val}}; use crate::{menu::BackgroundImage}; -use crate::simulation::SimState; +use crate::simulation::{SimState, SimStateType}; pub struct LoadingPlugin; @@ -41,8 +41,8 @@ impl LoadingState { self.total_bodies = 0; } - pub fn is_done(&self) -> bool { - self.scaled_bodies && self.tilted_bodies && self.loaded_spk_files && self.spawned_bodies + pub fn is_done(&self, is_sim: bool) -> bool { + self.scaled_bodies && self.tilted_bodies && (self.loaded_spk_files || is_sim) && self.spawned_bodies } } @@ -105,20 +105,22 @@ fn spawn_loading( fn loading_system( loading_state: ResMut, mut sim_state: ResMut>, + sim_type: Res ) { - if loading_state.is_done() { + if loading_state.is_done(*sim_type == SimStateType::Simulation) { sim_state.set(SimState::Loaded) } } fn update_progress( mut marker: Query<&mut Text, With>, - loading_state: Res + loading_state: Res, + sim_type: Res ) { - let text0 = loading_text("Spawning bodies", loading_state.spawned_bodies); - let text1 = loading_text(format!("Scaling bodies: {}/{}", loading_state.scaled_bodies_count, loading_state.total_bodies).as_str(), loading_state.scaled_bodies); - let text2 = loading_text("Rotating bodies", loading_state.tilted_bodies); - let text3 = loading_text("Loading SPK files", loading_state.loaded_spk_files); + let text0 = loading_text("Spawning bodies", loading_state.spawned_bodies, false); + let text1 = loading_text(format!("Scaling bodies: {}/{}", loading_state.scaled_bodies_count, loading_state.total_bodies).as_str(), loading_state.scaled_bodies, false); + let text2 = loading_text("Rotating bodies", loading_state.tilted_bodies, false); + let text3 = loading_text("Loading SPK files", loading_state.loaded_spk_files, *sim_type == SimStateType::Simulation); let new_text = format!("{}\n{}\n{}\n{}", text0, text1, text2, text3); if let Ok(mut text) = marker.get_single_mut() { let old_text = text.sections.first_mut().unwrap(); @@ -128,9 +130,11 @@ fn update_progress( } } -fn loading_text(text: &str, predicate: bool) -> String { +fn loading_text(text: &str, predicate: bool, skip: bool) -> String { if predicate { format!("Done - {}", text) + } else if skip { + format!("Skipped - {}", text) } else { format!("In Progress - {}", text) } diff --git a/src/simulation/scenario/save_scenario.rs b/src/simulation/scenario/save_scenario.rs index 19c96c2..12c183d 100644 --- a/src/simulation/scenario/save_scenario.rs +++ b/src/simulation/scenario/save_scenario.rs @@ -10,7 +10,7 @@ use bevy::prelude::{default, AssetServer, Assets, Entity, PointLight, Query, Res use std::fs; use egui_toast::{Toast, ToastKind, ToastOptions}; use crate::simulation::asset::serialization::{SerializedBody, SerializedBodyData, SerializedLightSource, SerializedVec, SimulationData}; -use crate::simulation::components::horizons::NaifIdComponent; +use crate::simulation::components::horizons::AniseMetadata; use crate::simulation::components::scale::SimulationScale; use crate::simulation::components::speed::Speed; use crate::simulation::units::converter::unscale_lumen; @@ -32,7 +32,7 @@ pub struct SystemPanelSet<'w, 's> { selected_scenario: ResMut<'w, SelectedScenario>, bodies_asset: ResMut<'w, Assets>, scenario_data: ResMut<'w, ScenarioData>, - bodies: Query<'w, 's, (Entity, &'static Mass, &'static SimPosition, &'static Velocity, &'static Name, &'static ModelPath, &'static Diameter, &'static RotationSpeed, &'static AxialTilt, Option<&'static BodyChildren>, &'static NaifIdComponent, Option<&'static Star>)>, + bodies: Query<'w, 's, (Entity, &'static Mass, &'static SimPosition, &'static Velocity, &'static Name, &'static ModelPath, &'static Diameter, &'static RotationSpeed, &'static AxialTilt, Option<&'static BodyChildren>, &'static AniseMetadata, Option<&'static Star>)>, lights: Query<'w, 's, (&'static LightSource, &'static PointLight, &'static Visibility)>, toasts: ResMut<'w, ToastContainer>, scale: Res<'w, SimulationScale>, @@ -53,7 +53,7 @@ pub fn save_scenario( description: scenario_data.description.clone(), scale: system_panel_set.scale.0, timestep: system_panel_set.speed.0 as i32, - data_sets: scenario_data.spk_files.clone(), + data_sets: scenario_data.spice_files.clone(), }; let serialized_data = serde_json::to_string(&simulation_data).unwrap(); fs::write(format!("scenarios/{}", file_path), serialized_data).unwrap(); @@ -100,7 +100,7 @@ fn collect_moons(system_panel_set: &SystemPanelSet, children: BodyChildren) -> V fn find_body_data(system_panel_set: &SystemPanelSet, entity: Entity) -> Option<(SerializedBodyData, Option)> { system_panel_set.bodies.iter().find(|(e, _, _, _, _, _, _, _, _, _, _, _)| *e == entity) .map(|(_, m, p, v, n, mp, d, rs, at, child, naif, _)| ( - create_serialized_body_data(m.0, p.0 / 1000.0, v.0 / 1000.0, n.to_string(), mp.cleaned(), d.num as f64 / 1000.0, rs.0, at.num, None, naif.0), + create_serialized_body_data(m.0, p.0 / 1000.0, v.0 / 1000.0, n.to_string(), mp.cleaned(), d.num as f64 / 1000.0, rs.0, at.num, None, naif.clone()), child.map(|c| c.clone()) )) } @@ -114,7 +114,7 @@ fn create_serialized_body_data( rotation_speed: f64, axial_tilt: f32, light_source: Option, - naif_id: i32, + anise_metadata: AniseMetadata, ) -> SerializedBodyData { SerializedBodyData { mass, @@ -126,8 +126,10 @@ fn create_serialized_body_data( rotation_speed, axial_tilt, simulate: true, + ellipsoid: anise_metadata.ellipsoid, light_source, - naif_id + naif_id: anise_metadata.target_id, + orientation_id: anise_metadata.target_id } } diff --git a/src/simulation/scenario/setup.rs b/src/simulation/scenario/setup.rs index 6d6e37f..098cb6d 100644 --- a/src/simulation/scenario/setup.rs +++ b/src/simulation/scenario/setup.rs @@ -46,7 +46,7 @@ pub struct ScenarioData { pub description: String, pub timestep: i32, pub scale: f32, - pub spk_files: Vec + pub spice_files: Vec } @@ -59,7 +59,7 @@ impl From for ScenarioData { description: value.description, timestep: value.timestep, scale: value.scale, - spk_files: value.data_sets + spice_files: value.data_sets } } } diff --git a/src/simulation/ui/editor_body_panel.rs b/src/simulation/ui/editor_body_panel.rs index b726504..718844b 100644 --- a/src/simulation/ui/editor_body_panel.rs +++ b/src/simulation/ui/editor_body_panel.rs @@ -1,3 +1,4 @@ +use anise::structure::planetocentric::ellipsoid::Ellipsoid; use bevy::asset::{AssetServer, Assets}; use crate::simulation::components::apsis::ApsisBody; use crate::simulation::components::body::{AxialTilt, BodyChildren, BodyParent, Diameter, LightSource, Mass, ModelPath, OrbitSettings, RotationSpeed, Scale, SceneEntity, SceneHandle, SimPosition, Velocity}; @@ -11,7 +12,7 @@ use bevy_egui::{egui, EguiContexts}; use egui_toast::{Toast, ToastKind, ToastOptions}; use crate::simulation::scenario::setup::spawn_scene; use crate::simulation::components::editor::{EditorSystemType, EditorSystems}; -use crate::simulation::components::horizons::NaifIdComponent; +use crate::simulation::components::horizons::AniseMetadata; use crate::simulation::components::scale::SimulationScale; use crate::simulation::render::star_billboard::StarBillboard; use crate::simulation::ui::components::vector_field; @@ -19,12 +20,13 @@ use crate::simulation::ui::toast::{success_toast, ToastContainer}; use crate::simulation::ui::UiState; use crate::simulation::units::converter::{km_to_m, km_to_m_dvec, km_to_m_f64, m_to_km, m_to_km_dvec, m_to_km_f64, scale_lumen, unscale_lumen}; -#[derive(Debug, Default, Clone, Resource)] +#[derive(Debug, Clone, Resource)] pub struct EditorPanelState { pub entity: Option, pub new_name: String, pub new_position: DVec3, pub new_velocity: DVec3, + pub ellipsoid: Ellipsoid, pub new_mass: f64, pub new_diameter: f32, pub new_rotation_speed: f64, @@ -33,6 +35,28 @@ pub struct EditorPanelState { pub show_delete_confirm: bool, pub new_light_settings: Option, pub naif_id: i32, + pub orientation_id: i32, +} + +impl Default for EditorPanelState { + fn default() -> Self { + Self { + entity: None, + new_name: "".to_string(), + new_position: DVec3::ZERO, + new_velocity: DVec3::ZERO, + ellipsoid: Ellipsoid::from_sphere(1.0), + new_mass: 0.0, + new_diameter: 0.0, + new_rotation_speed: 0.0, + new_axial_tilt: 0.0, + new_model_path: "".to_string(), + show_delete_confirm: false, + new_light_settings: None, + naif_id: -1, + orientation_id: -1, + } + } } #[derive(Debug, Default, Clone, Copy)] @@ -46,7 +70,7 @@ pub struct LightSettings { pub fn editor_body_panel( mut egui_context: EguiContexts, selected_entity: Res, - mut query: Query<(Entity, &mut Name, &mut SimPosition, &mut Velocity, &mut Mass, &mut Diameter, &mut RotationSpeed, &mut AxialTilt, &mut ModelPath, &mut SceneHandle, &mut NaifIdComponent), With>, + mut query: Query<(Entity, &mut Name, &mut SimPosition, &mut Velocity, &mut Mass, &mut Diameter, &mut RotationSpeed, &mut AxialTilt, &mut ModelPath, &mut SceneHandle, &mut AniseMetadata), With>, scene_query: Query>, mut state: ResMut, mut commands: Commands, @@ -92,7 +116,7 @@ fn initialize_state( model_path: &ModelPath, light: Option<&(Mut, &LightSource, Mut)>, scale: &SimulationScale, - horizons_id: &Mut, + anise_metadata: &Mut, ) { *state = EditorPanelState { entity: Some(s_entity), @@ -111,7 +135,9 @@ fn initialize_state( enabled: **visible == Visibility::Visible, range: scale.unit_to_m_32(light.range), }), - naif_id: horizons_id.0, + naif_id: anise_metadata.target_id, + ellipsoid: diameter.ellipsoid, + orientation_id: anise_metadata.orientation_id, }; } @@ -127,7 +153,7 @@ fn display_body_panel( tilt: &mut AxialTilt, model_path: &mut ModelPath, scene: &mut SceneHandle, - horizons: &mut Mut, + horizons: &mut Mut, commands: &mut Commands, systems: &Res, assets: &Res, @@ -161,6 +187,10 @@ fn display_body_properties(ui: &mut egui::Ui, state: &mut EditorPanelState) { ui.label("Naif ID"); ui.add(egui::DragValue::new(&mut state.naif_id)); }); + ui.horizontal(|ui| { + ui.label("Orientation ID"); + ui.add(egui::DragValue::new(&mut state.orientation_id)); + }); ui.horizontal(|ui| { ui.label("Model Path"); ui.text_edit_singleline(&mut state.new_model_path); @@ -183,6 +213,25 @@ fn display_body_properties(ui: &mut egui::Ui, state: &mut EditorPanelState) { }); vector_field(ui, "Position (km)", &mut state.new_position); vector_field(ui, "Velocity (km/s)", &mut state.new_velocity); + ellipsoid(ui, state); +} + +fn ellipsoid(ui: &mut egui::Ui, state: &mut EditorPanelState) { + ui.vertical(|ui| { + ui.heading("Ellipsoid"); + ui.horizontal(|ui| { + ui.label("Polar Radius (km)"); + ui.add(egui::DragValue::new(&mut state.ellipsoid.polar_radius_km)); + }); + ui.horizontal(|ui| { + ui.label("Semi major equatorial radius (km)"); + ui.add(egui::DragValue::new(&mut state.ellipsoid.semi_major_equatorial_radius_km)); + }); + ui.horizontal(|ui| { + ui.label("Semi minor equatorial radius (km)"); + ui.add(egui::DragValue::new(&mut state.ellipsoid.semi_minor_equatorial_radius_km)); + }); + }); } fn display_light_source(ui: &mut egui::Ui, state: &mut EditorPanelState) { @@ -228,7 +277,7 @@ fn display_bottom_buttons( tilt: &mut AxialTilt, model_path: &mut ModelPath, scene: &mut SceneHandle, - horizons: &mut Mut, + horizons: &mut Mut, commands: &mut Commands, systems: &Res, assets: &Res, @@ -281,7 +330,7 @@ fn apply_changes( tilt: &mut AxialTilt, model_path: &mut ModelPath, scene: &mut SceneHandle, - horizons_id: &mut NaifIdComponent, + anise_metadata: &mut AniseMetadata, commands: &mut Commands, systems: &Res, assets: &Res, @@ -298,11 +347,15 @@ fn apply_changes( let new_diameter = km_to_m(state.new_diameter); diameter.applied = new_diameter == diameter.num; diameter.num = new_diameter; + diameter.ellipsoid = state.ellipsoid; rotation_speed.0 = state.new_rotation_speed; let new_tilt = state.new_axial_tilt; tilt.applied = new_tilt == tilt.num; tilt.num = new_tilt; - *horizons_id = NaifIdComponent(state.naif_id); + *anise_metadata = AniseMetadata { + target_id: state.naif_id, + orientation_id: state.orientation_id, + }; if let Some((mut light, _, mut visible)) = light { light.color = state.new_light_settings.as_ref().unwrap().color; if let Some(material) = billboard_material { @@ -341,6 +394,7 @@ fn apply_changes( } if model_path.cleaned() != state.new_model_path { *model_path = ModelPath::from_cleaned(state.new_model_path.as_str()); + diameter.path = model_path.0.clone(); let asset_handle: Handle = assets.load(model_path.clone().0); commands.entity(scene_query.get(scene.1).unwrap()).despawn_recursive(); scene.0 = asset_handle.clone(); @@ -351,8 +405,6 @@ fn apply_changes( parent ); }); - - diameter.aabb = None; } commands.run_system(systems.0[EditorSystemType::UPDATE_POSITIONS]); commands.run_system(systems.0[EditorSystemType::UPDATE_DIAMETER]); diff --git a/src/simulation/ui/metadata.rs b/src/simulation/ui/metadata.rs index 92eeb66..a9ea5ae 100644 --- a/src/simulation/ui/metadata.rs +++ b/src/simulation/ui/metadata.rs @@ -10,7 +10,7 @@ use bevy_egui::egui::ComboBox; use chrono::{NaiveTime, Timelike}; use egui_extras::DatePickerButton; use crate::simulation::scenario::setup::ScenarioData; -use crate::simulation::components::anise::{load_spk_files, AlmanacHolder}; +use crate::simulation::components::anise::{load_spice_files, AlmanacHolder}; use crate::simulation::components::scale::SimulationScale; use crate::simulation::components::speed::Speed; use crate::simulation::SimState; @@ -123,46 +123,46 @@ fn edit_simulation_settings(ui: &mut egui::Ui, scale: &mut SimulationScale, spee fn edit_spk_files( ui: &mut egui::Ui, scenario_data: &mut ScenarioData, - selected_spk_file: &mut String, - new_spk_file: &mut String, + selected_spice_file: &mut String, + new_spice_file: &mut String, toasts: &mut ToastContainer, almanac_holder: &mut AlmanacHolder ) { - ui.heading("SPK Files"); + ui.heading("SPICE Files"); ui.horizontal(|ui| { - let mut selected = selected_spk_file.clone(); + let mut selected = selected_spice_file.clone(); if selected.is_empty() { selected = "None".to_string(); } - ui.label("Included SPK Files:"); + ui.label("Loaded SPICE Files:"); ComboBox::from_label("").selected_text(selected).show_ui(ui, |ui| { - for file in scenario_data.spk_files.clone() { - ui.selectable_value(selected_spk_file, file.clone(), file); + for file in scenario_data.spice_files.clone() { + ui.selectable_value(selected_spice_file, file.clone(), file); } }); - if ui.button("Remove").on_hover_text("Remove selected SPK file").clicked() { - if let Some(index) = scenario_data.spk_files.iter().position(|f| f == selected_spk_file) { - scenario_data.spk_files.remove(index); - *selected_spk_file = "".to_string(); - toasts.0.add(success_toast("SPK file removed")); - load_spk_files(scenario_data.spk_files.clone(), almanac_holder, toasts); + if ui.button("Remove").on_hover_text("Remove selected SPICE file").clicked() { + if let Some(index) = scenario_data.spice_files.iter().position(|f| f == selected_spice_file) { + scenario_data.spice_files.remove(index); + *selected_spice_file = "".to_string(); + toasts.0.add(success_toast("SPICE file removed")); + load_spice_files(scenario_data.spice_files.clone(), almanac_holder, toasts); } } }); - ui.text_edit_singleline(new_spk_file); + ui.text_edit_singleline(new_spice_file); ui.horizontal(|ui| { - if ui.button("Select SPK File").clicked() { - match tinyfiledialogs::open_file_dialog("Select BSP file", "data.bsp", Some((&["*.bsp"], "BSP files"))) { + if ui.button("Select SPICE File").clicked() { + match tinyfiledialogs::open_file_dialog("Select SPICE file", "data.bsp", Some((&["*.bsp", "*.pca"], "SPICE files"))) { Some(file) => { - *new_spk_file = file; + *new_spice_file = file; }, None => { toasts.0.add(error_toast("No file selected")); }, } } - if ui.button("Load SPK File").clicked() { - if let Err(e) = load_scenario_file(scenario_data, selected_spk_file, new_spk_file, toasts, almanac_holder) { + if ui.button("Load SPICE File").clicked() { + if let Err(e) = load_scenario_file(scenario_data, selected_spice_file, new_spice_file, toasts, almanac_holder) { toasts.0.add(error_toast(&e)); } } @@ -185,29 +185,32 @@ fn load_scenario_file( if new_spk_file.is_empty() { return Err("No file selected".to_string()); } + let mut copied = false; if !fs::exists(&data_path).unwrap_or(false) { + copied = true; fs::copy(new_spk_file.clone(), &data_path).map_err(|_| "Failed to copy file".to_string())?; - } else if scenario_data.spk_files.contains(&file_name) { - return Err("SPK file already added".to_string()); + } else if scenario_data.spice_files.contains(&file_name) { + return Err("SPICE file already added".to_string()); } match load_spk(data_path.clone(), &almanac_holder.0) { Ok(almanac) => { almanac_holder.0 = almanac; - scenario_data.spk_files.push(file_name.clone()); + scenario_data.spice_files.push(file_name.clone()); *selected_spk_file = file_name; *new_spk_file = "".to_string(); - toasts.0.add(success_toast("SPK file added and loaded")); + toasts.0.add(success_toast("SPICE file added and loaded")); Ok(()) }, - Err(_) => { - fs::remove_file(data_path).map_err(|_| "Failed to remove file".to_string())?; - Err("Failed to load SPK file".to_string()) + Err(e) => { + if copied { + fs::remove_file(data_path).map_err(|_| "Failed to remove file".to_string())?; + } + Err("Failed to load SPICE file".to_string()) } } } fn load_spk(path: String, almanac: &Almanac) -> Result { - let daf = SPK::load(path.as_str()).map_err(|_| ())?; - let almanac = almanac.with_spk(daf).map_err(|_| ())?; + let almanac = almanac.load(&*path).map_err(|_| ())?; Ok(almanac) } \ No newline at end of file diff --git a/src/simulation/ui/mod.rs b/src/simulation/ui/mod.rs index a5ddd71..c92315a 100644 --- a/src/simulation/ui/mod.rs +++ b/src/simulation/ui/mod.rs @@ -5,7 +5,7 @@ pub mod debug_window; pub mod components; pub mod scenario_selection; mod sim_body_panel; -pub mod simulation_bottom_bar; +pub mod sim_bottom_bar; pub mod editor_bottom_bar; pub mod toast; mod metadata; @@ -56,7 +56,7 @@ use crate::simulation::ui::editor_bottom_bar::editor_bottom_bar; use crate::simulation::ui::metadata::MetadataPlugin; use crate::simulation::ui::scenario_selection::ScenarioSelectionPlugin; use crate::simulation::ui::sim_body_panel::sim_body_panel; -use crate::simulation::ui::simulation_bottom_bar::simulation_bottom_bar; +use crate::simulation::ui::sim_bottom_bar::simulation_bottom_bar; use crate::simulation::ui::toast::ToastPlugin; //use crate::fps::Fps; use crate::utils::{sim_state_type_editor, sim_state_type_simulation}; diff --git a/src/simulation/ui/scenario_selection.rs b/src/simulation/ui/scenario_selection.rs index 988a151..a8645ca 100644 --- a/src/simulation/ui/scenario_selection.rs +++ b/src/simulation/ui/scenario_selection.rs @@ -12,7 +12,7 @@ use crate::simulation::scenario::setup::ScenarioData; use crate::simulation::{SimState, SimStateType}; use crate::simulation::asset::{from_scenario_source, SCENARIO_ASSET_SOURCE}; use crate::simulation::asset::serialization::SimulationData; -use crate::simulation::components::anise::{load_spk_files, AlmanacHolder}; +use crate::simulation::components::anise::{load_spice_files, AlmanacHolder}; use crate::simulation::components::scale::SimulationScale; use crate::simulation::components::speed::Speed; use crate::simulation::ui::toast::{error_toast, ToastContainer}; diff --git a/src/simulation/ui/simulation_bottom_bar.rs b/src/simulation/ui/sim_bottom_bar.rs similarity index 100% rename from src/simulation/ui/simulation_bottom_bar.rs rename to src/simulation/ui/sim_bottom_bar.rs