From e5889a1fe4a56e31c9c777e812409431aaa4a463 Mon Sep 17 00:00:00 2001 From: Jan Tennert Date: Wed, 25 Sep 2024 20:27:41 +0200 Subject: [PATCH] stuff --- Cargo.lock | 23 +- Cargo.toml | 2 + assets/scenarios/solar_system_copy.sim | 858 +-------------------- src/main.rs | 6 +- src/serialization.rs | 12 +- src/setup.rs | 34 +- src/simulation/components/billboard.rs | 4 +- src/simulation/components/body.rs | 3 +- src/simulation/components/diameter.rs | 4 +- src/simulation/components/direction.rs | 11 +- src/simulation/components/orbit_lines.rs | 4 +- src/simulation/components/save_scenario.rs | 67 +- src/simulation/components/selection.rs | 2 +- src/simulation/ui/editor_body_panel.rs | 34 +- src/simulation/ui/editor_bottom_bar.rs | 6 +- src/simulation/ui/mod.rs | 5 +- src/simulation/ui/scenario_selection.rs | 120 ++- src/simulation/ui/sim_body_panel.rs | 2 +- src/simulation/ui/simulation_bottom_bar.rs | 6 +- src/simulation/ui/toast.rs | 52 ++ 20 files changed, 315 insertions(+), 940 deletions(-) create mode 100644 src/simulation/ui/toast.rs diff --git a/Cargo.lock b/Cargo.lock index 809ccc0..1ac5a88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,11 @@ dependencies = [ "bevy_mod_billboard", "blocking", "chrono", + "egui-toast", "image 0.24.7", "serde", "serde_json", + "tinyfiledialogs", "winit 0.28.7", ] @@ -2177,6 +2179,15 @@ dependencies = [ "nohash-hasher", ] +[[package]] +name = "egui-toast" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6652cccda84ba174437caa128e4e28a3502a3c62c9e39e381c24f1f0445946f1" +dependencies = [ + "egui", +] + [[package]] name = "either" version = "1.9.0" @@ -4152,7 +4163,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.2.0", "proc-macro2", "quote", "syn 2.0.77", @@ -5894,6 +5905,16 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tinyfiledialogs" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25fa0bc43a6566e2cc6d7ac96df3fa5a57beba34445bead1b368ba8fe9ca568" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 44165f9..d490e58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,5 @@ image = "0.24.7" bevy_mod_billboard = "0.7.0" blocking = "1.5.1" anise = "0.4.3" +egui-toast = "0.14.0" +tinyfiledialogs = "3.0" diff --git a/assets/scenarios/solar_system_copy.sim b/assets/scenarios/solar_system_copy.sim index da0217d..fa78f20 100644 --- a/assets/scenarios/solar_system_copy.sim +++ b/assets/scenarios/solar_system_copy.sim @@ -1,857 +1 @@ -{ - "bodies": [ - { - "data": { - "mass": 1.9885E30, - "starting_position": { - "x": -1253558.344523507, - "y": -331931.4431501561, - "z": 31972.046837662 - }, - "starting_velocity": { - "x": 0.006931107133912123, - "y": -0.01362000313964326, - "z": -4.54388831820406E-5 - }, - "name": "Sol", - "model_path": "sun.glb", - "diameter": 1392000.0, - "rotation_speed": 38880.0, - "axial_tilt": 7.25, - "simulate": true, - "light_source": { - "intensity": 3.75E28, - "range": 4436820000000, - "color": "#ffffff", - "enabled": true - } - }, - "children": [ - { - "data": { - "mass": 5.97219E24, - "starting_position": { - "x": 1.47358878457139E8, - "y": 1.854315256927273E7, - "z": 29904.29803438578 - }, - "starting_velocity": { - "x": -4.226365231723641, - "y": 29.41379349033467, - "z": -0.002828583292782128 - }, - "name": "Earth", - "model_path": "earth.glb", - "diameter": 12742.0, - "rotation_speed": 1436.0, - "axial_tilt": 23.4392811, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 7.348E22, - "starting_position": { - "x": 1.4768044919678E8, - "y": 1.872052246844263E7, - "z": 32437.75744153466 - }, - "starting_velocity": { - "x": -4.694794112410923, - "y": 30.37390017058626, - "z": 0.09549595923954257 - }, - "name": "Moon", - "model_path": "moon.glb", - "diameter": 1738.1, - "rotation_speed": 39343.68, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 420000.0, - "starting_position": { - "x": 1.473527157673001E8, - "y": 1.854377197753885E7, - "z": 32687.02643421665 - }, - "starting_velocity": { - "x": -1.45562616429677, - "y": 26.86558693275802, - "z": 6.676360863324918 - }, - "name": "ISS", - "model_path": "iss.glb", - "diameter": 0.11, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": false - }, - "children": [] - }, - { - "data": { - "mass": 12200.0, - "starting_position": { - "x": 1.473574824275498E8, - "y": 1.853650067043575E7, - "z": 31105.44444823079 - }, - "starting_velocity": { - "x": 2.337654024613603, - "y": 28.72201739576322, - "z": 3.768849345271146 - }, - "name": "Hubble", - "model_path": "hubble.glb", - "diameter": 0.013, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": false - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 5.6834E26, - "starting_position": { - "x": 1.317721699784666E9, - "y": -6.263762138853518E8, - "z": -4.157355925955266E7 - }, - "starting_velocity": { - "x": 3.608323540191913, - "y": 8.705880483493228, - "z": -0.2953903588682212 - }, - "name": "Saturn", - "model_path": "saturn.glb", - "diameter": 116464.0, - "rotation_speed": 633.0, - "axial_tilt": 26.73, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 1.3452E23, - "starting_position": { - "x": 1.317062395789841E9, - "y": -6.254109541976979E8, - "z": -4.200566301576936E7 - }, - "starting_velocity": { - "x": -1.060852998165573, - "y": 6.402666517530363, - "z": 1.357634287951674 - }, - "name": "Titan", - "model_path": "titan.glb", - "diameter": 5149.46, - "rotation_speed": 22920.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 2.3064854E21, - "starting_position": { - "x": 1.317198227126551E9, - "y": -6.263121286545614E8, - "z": -4.155952859529075E7 - }, - "starting_velocity": { - "x": 2.806558904291587, - "y": 1.2701482567137, - "z": 3.694364144037066 - }, - "name": "Rhea", - "model_path": "rhea.glb", - "diameter": 763.5, - "rotation_speed": 6480.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.8056591E21, - "starting_position": { - "x": 1.320855160609993E9, - "y": -6.278521340465181E8, - "z": -4.186440417667893E7 - }, - "starting_velocity": { - "x": 4.854646792968393, - "y": 11.66248870085356, - "z": -1.230081930411274 - }, - "name": "Iapetus", - "model_path": "iapetus.glb", - "diameter": 1470.0, - "rotation_speed": 113760.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.0954867999999999E21, - "starting_position": { - "x": 1.318063919760553E9, - "y": -6.26526636509911E8, - "z": -4.152808612631324E7 - }, - "starting_velocity": { - "x": 7.705841565764674, - "y": 16.66690708035977, - "z": -4.861168661971909 - }, - "name": "Dione", - "model_path": "dione.glb", - "diameter": 1123.0, - "rotation_speed": 3941.1576, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 6.174959E20, - "starting_position": { - "x": 1.317498514533114E9, - "y": -6.261968167390172E8, - "z": -4.164324520863017E7 - }, - "starting_velocity": { - "x": -3.711987600444088, - "y": 1.440318005837302, - "z": 4.443003247932851 - }, - "name": "Tethys", - "model_path": "tethys.glb", - "diameter": 1062.0, - "rotation_speed": 2718.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 3.75094E19, - "starting_position": { - "x": 1.317862368973109E9, - "y": -6.262736478866278E8, - "z": -4.163625521668619E7 - }, - "starting_velocity": { - "x": -5.466336813759373, - "y": 18.80368314533501, - "z": -4.960595064530139 - }, - "name": "Mimas", - "model_path": "mimas.glb", - "diameter": 396.0, - "rotation_speed": 1356.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.080318E20, - "starting_position": { - "x": 1.317897357123477E9, - "y": -6.265236953599699E8, - "z": -4.15133347885673E7 - }, - "starting_velocity": { - "x": 12.03172552201499, - "y": 16.74134008425769, - "z": -5.324491936368194 - }, - "name": "Enceladus", - "model_path": "enceladus.glb", - "diameter": 504.0, - "rotation_speed": 1973.11392, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 1.8982E27, - "starting_position": { - "x": 5.91116405042928E8, - "y": 4.48612773658671E8, - "z": -1.508610682481316E7 - }, - "starting_velocity": { - "x": -8.045068878300311, - "y": 11.02381638213635, - "z": 0.1341531152888358 - }, - "name": "Jupiter", - "model_path": "jupiter.glb", - "diameter": 139822.0, - "rotation_speed": 595.0, - "axial_tilt": 3.13, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 8.931938E22, - "starting_position": { - "x": 5.910424467821088E8, - "y": 4.481963687394117E8, - "z": -1.510185010929203E7 - }, - "starting_velocity": { - "x": 8.957736595686779, - "y": 7.959026250920237, - "z": 0.2787009746093063 - }, - "name": "Io", - "model_path": "io.glb", - "diameter": 3643.2, - "rotation_speed": 2547.36, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 4.799844E22, - "starting_position": { - "x": 5.917799042824603E8, - "y": 4.486983281930672E8, - "z": -1.506823606685701E7 - }, - "starting_velocity": { - "x": -9.693151465294227, - "y": 24.69741639214316, - "z": 0.569429680046083 - }, - "name": "Europa", - "model_path": "europa.glb", - "diameter": 1560.8, - "rotation_speed": 5113.70064, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.4819E23, - "starting_position": { - "x": 5.920393829735433E8, - "y": 4.480741128331422E8, - "z": -1.509370908536822E7 - }, - "starting_velocity": { - "x": -2.558462326557859, - "y": 20.43120719962253, - "z": 0.5697972593813327 - }, - "name": "Ganymede", - "model_path": "ganymede.glb", - "diameter": 5268.2, - "rotation_speed": 10303.2, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.075938E23, - "starting_position": { - "x": 5.928184462926141E8, - "y": 4.478344900349652E8, - "z": -1.508781974881226E7 - }, - "starting_velocity": { - "x": -4.643871215581399, - "y": 18.53965996642426, - "z": 0.4153266498041814 - }, - "name": "Callisto", - "model_path": "callisto.glb", - "diameter": 4820.6, - "rotation_speed": 24032.16, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 4.8675E24, - "starting_position": { - "x": 8.476483460935698E7, - "y": 6.527795533113867E7, - "z": -4030295.749102697 - }, - "starting_velocity": { - "x": -21.33838684070412, - "y": 27.68230884313838, - "z": 1.611943339470342 - }, - "name": "Venus", - "model_path": "venus.glb", - "diameter": 12103.6, - "rotation_speed": 349946.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 3.3011E23, - "starting_position": { - "x": -2.65823594034951E7, - "y": 4.047607508223532E7, - "z": 5690109.263829736 - }, - "starting_velocity": { - "x": -51.19740738494808, - "y": -23.82829179403439, - "z": 2.750476586235273 - }, - "name": "Mercury", - "model_path": "mercury.glb", - "diameter": 4880.0, - "rotation_speed": 84480.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 8.681E25, - "starting_position": { - "x": 1.876848145196212E9, - "y": 2.256742495428547E9, - "z": -1.593333878791571E7 - }, - "starting_velocity": { - "x": -5.285944969180821, - "y": 4.037177487005098, - "z": 0.0832885977451503 - }, - "name": "Uranus", - "model_path": "uranus.glb", - "diameter": 50724.0, - "rotation_speed": 1034.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 6.4E19, - "starting_position": { - "x": 1.876793591976653E9, - "y": 2.256780204161452E9, - "z": -1.582184453453541E7 - }, - "starting_velocity": { - "x": 0.5593250277603632, - "y": 3.223358609129066, - "z": 3.227082066969737 - }, - "name": "Miranda", - "model_path": "miranda.glb", - "diameter": 471.6, - "rotation_speed": 2035.40976, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.251E21, - "starting_position": { - "x": 1.87669550752492E9, - "y": 2.256760167205151E9, - "z": -1.604669083471954E7 - }, - "starting_velocity": { - "x": -8.385308784191833, - "y": 5.318928951790138, - "z": 4.453089305595049 - }, - "name": "Ariel", - "model_path": "ariel.glb", - "diameter": 1157.8, - "rotation_speed": 3629.34576, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.275E21, - "starting_position": { - "x": 1.877032097119599E9, - "y": 2.256677176877903E9, - "z": -1.611531210892296E7 - }, - "starting_velocity": { - "x": -8.506198828430891, - "y": 4.275436104814067, - "z": -3.265378937492151 - }, - "name": "Umbriel", - "model_path": "umbriel.glb", - "diameter": 1169.4, - "rotation_speed": 5904.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 3.4E21, - "starting_position": { - "x": 1.876446721049093E9, - "y": 2.256849468855134E9, - "z": -1.579768942792165E7 - }, - "starting_velocity": { - "x": -4.077764161868127, - "y": 4.250690343060523, - "z": 3.508220529443759 - }, - "name": "Titania", - "model_path": "titania.glb", - "diameter": 1576.8, - "rotation_speed": 12528.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 3.076E21, - "starting_position": { - "x": 1.876691132612216E9, - "y": 2.256854991280804E9, - "z": -1.538266894913125E7 - }, - "starting_velocity": { - "x": -2.324170074400168, - "y": 3.526797505106853, - "z": 1.030057319525953 - }, - "name": "Oberon", - "model_path": "oberon.glb", - "diameter": 1522.8, - "rotation_speed": 19440.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 1.024E26, - "starting_position": { - "x": 4.46073781433013E9, - "y": -3.117194956197202E8, - "z": -9.638308729856475E7 - }, - "starting_velocity": { - "x": 0.3424898338191547, - "y": 5.454448402599064, - "z": -0.1196973250551823 - }, - "name": "Neptune", - "model_path": "neptune.glb", - "diameter": 49244.0, - "rotation_speed": 960.0, - "axial_tilt": 28.32, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 2.139E22, - "starting_position": { - "x": 4.46043565553476E9, - "y": -3.118210796191955E8, - "z": -9.622740008927625E7 - }, - "starting_velocity": { - "x": 0.6549830743821887, - "y": 8.816651890055235, - "z": 2.683376921837763 - }, - "name": "Triton", - "model_path": "triton.glb", - "diameter": 2706.8, - "rotation_speed": 8496.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 1.303E22, - "starting_position": { - "x": 2.534605027840262E9, - "y": -4.550728311952005E9, - "z": -2.46201602553565E8 - }, - "starting_velocity": { - "x": 4.90550581768183, - "y": 1.466573354685091, - "z": -1.58125012378935 - }, - "name": "Pluto", - "model_path": "pluto.glb", - "diameter": 2376.6, - "rotation_speed": 9201.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 1.586E21, - "starting_position": { - "x": 2.534602841613384E9, - "y": -4.550740270530462E9, - "z": -2.46216972222549E8 - }, - "starting_velocity": { - "x": 4.743470035507049, - "y": 1.357540337784795, - "z": -1.47338180231602 - }, - "name": "Charon", - "model_path": "charon.glb", - "diameter": 1212.0, - "rotation_speed": 9197.28, - "axial_tilt": 0.0, - "simulate": false - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 6.4171E23, - "starting_position": { - "x": -2.046893400400904E8, - "y": -1.250136923437167E8, - "z": 2409131.185058415 - }, - "starting_velocity": { - "x": 13.57395490411145, - "y": -18.60254221026088, - "z": -0.7224152414868863 - }, - "name": "Mars", - "model_path": "mars.glb", - "diameter": 6779.0, - "rotation_speed": 1476.0, - "axial_tilt": 25.19, - "simulate": true - }, - "children": [ - { - "data": { - "mass": 1.0659E16, - "starting_position": { - "x": -2.046811201572424E8, - "y": -1.250112401183025E8, - "z": 2405122.029878475 - }, - "starting_velocity": { - "x": 13.1724712527701, - "y": -16.55773129437739, - "z": -0.3519634910822811 - }, - "name": "Phobos", - "model_path": "phobos.glb", - "diameter": 22.16, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.4762E15, - "starting_position": { - "x": -2.046898065944895E8, - "y": -1.24990331767902E8, - "z": 2411141.282914884 - }, - "starting_velocity": { - "x": 12.33964871357277, - "y": -18.67418157402109, - "z": -0.1763597828023391 - }, - "name": "Deimos", - "model_path": "deimos.glb", - "diameter": 12.54, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - } - ] - }, - { - "data": { - "mass": 9.38392E20, - "starting_position": { - "x": -2.762371221893816E8, - "y": -2.903518150199021E8, - "z": 4.151164079416633E7 - }, - "starting_velocity": { - "x": 12.07056566717051, - "y": -13.70357563530193, - "z": -2.655445328553542 - }, - "name": "Ceres", - "model_path": "ceres.glb", - "diameter": 939.4, - "rotation_speed": 540.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 1.6466E22, - "starting_position": { - "x": 1.280400740948511E10, - "y": 5.796599006941406E9, - "z": -2.733004417387743E9 - }, - "starting_velocity": { - "x": -0.7745567938606255, - "y": 1.50385470985689, - "z": 1.614258646777714 - }, - "name": "Eris", - "model_path": "eris.glb", - "diameter": 2326.0, - "rotation_speed": 1554.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 2.2E14, - "starting_position": { - "x": -2.974525169762023E9, - "y": 4.071518952895051E9, - "z": -1.489577717564979E9 - }, - "starting_velocity": { - "x": 0.7036787387939378, - "y": 0.567179895714418, - "z": 0.09880162683010832 - }, - "name": "Halley's Comet", - "model_path": "deimos.glb", - "diameter": 11.0, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 721.9, - "starting_position": { - "x": 5.567899398702804E9, - "y": -1.48929564919915E10, - "z": -1.234693053386691E10 - }, - "starting_velocity": { - "x": 4.222130606182812, - "y": -9.357402996434875, - "z": -11.33474239077342 - }, - "name": "Voyager-2", - "model_path": "voyager.glb", - "diameter": 0.001, - "rotation_speed": 0.0, - "axial_tilt": 0.0, - "simulate": true - }, - "children": [] - }, - { - "data": { - "mass": 3.1E21, - "starting_position": { - "x": -6.899004382898172E9, - "y": -1.090297370986418E9, - "z": 3.649000392627125E9 - }, - "starting_velocity": { - "x": 0.2044745917565618, - "y": -3.731030512801199, - "z": -0.4904247640299213 - }, - "name": "Makemake", - "model_path": "makemake.glb", - "diameter": 1430.0, - "rotation_speed": 1350.0, - "axial_tilt": 28.96, - "simulate": true - }, - "children": [] - } - ] - } - ], - "starting_time_millis": 1696118400000, - "title": "Solar System", - "description": "A scenario with all major bodies and their major moons in the Solar System." -} \ No newline at end of file +{"bodies":[{"children":[{"children":[],"data":{"mass":3.3011e23,"starting_position":{"x":-26582359.4034951,"y":40476075.08223532,"z":5690109.263829736},"starting_velocity":{"x":-51.19740738494808,"y":-23.82829179403439,"z":2.750476586235273},"name":"Mercury","model_path":"mercury.glb","diameter":5151.0,"rotation_speed":84480.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":4.8675e24,"starting_position":{"x":84764834.60935698,"y":65277955.33113867,"z":-4030295.749102697},"starting_velocity":{"x":-21.33838684070412,"y":27.68230884313838,"z":1.611943339470342},"name":"Venus","model_path":"venus.glb","diameter":12103.6,"rotation_speed":349946.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":7.348e22,"starting_position":{"x":147680449.19678,"y":18720522.46844263,"z":32437.75744153466},"starting_velocity":{"x":-4.694794112410923,"y":30.37390017058626,"z":0.09549595923954256},"name":"Moon","model_path":"moon.glb","diameter":1738.1,"rotation_speed":39343.68,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":5.97219e24,"starting_position":{"x":147358878.457139,"y":18543152.56927273,"z":29904.29803438578},"starting_velocity":{"x":-4.226365231723641,"y":29.41379349033467,"z":-0.002828583292782128},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"axial_tilt":23.439281,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":1.0659e16,"starting_position":{"x":-204681120.1572424,"y":-125011240.1183025,"z":2405122.029878475},"starting_velocity":{"x":13.1724712527701,"y":-16.55773129437739,"z":-0.3519634910822811},"name":"Phobos","model_path":"phobos.glb","diameter":22.16,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1476200000000000.0,"starting_position":{"x":-204689806.5944895,"y":-124990331.767902,"z":2411141.282914884},"starting_velocity":{"x":12.33964871357277,"y":-18.67418157402109,"z":-0.1763597828023391},"name":"Deimos","model_path":"deimos.glb","diameter":12.54,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":6.4171e23,"starting_position":{"x":-204689340.0400904,"y":-125013692.3437167,"z":2409131.185058415},"starting_velocity":{"x":13.57395490411145,"y":-18.60254221026088,"z":-0.7224152414868863},"name":"Mars","model_path":"mars.glb","diameter":6779.0,"rotation_speed":1476.0,"axial_tilt":25.19,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":9.38392e20,"starting_position":{"x":-276237122.1893816,"y":-290351815.0199021,"z":41511640.79416633},"starting_velocity":{"x":12.07056566717051,"y":-13.70357563530193,"z":-2.655445328553542},"name":"Ceres","model_path":"ceres.glb","diameter":939.4,"rotation_speed":540.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":8.931938e22,"starting_position":{"x":591042446.7821088,"y":448196368.7394117,"z":-15101850.10929203},"starting_velocity":{"x":8.957736595686779,"y":7.959026250920237,"z":0.2787009746093063},"name":"Io","model_path":"io.glb","diameter":3643.2,"rotation_speed":2547.36,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":4.799844e22,"starting_position":{"x":591779904.2824603,"y":448698328.1930672,"z":-15068236.06685701},"starting_velocity":{"x":-9.693151465294228,"y":24.69741639214316,"z":0.569429680046083},"name":"Europa","model_path":"europa.glb","diameter":1560.8,"rotation_speed":5113.70064,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.4819e23,"starting_position":{"x":592039382.9735433,"y":448074112.8331422,"z":-15093709.08536822},"starting_velocity":{"x":-2.558462326557859,"y":20.43120719962253,"z":0.5697972593813327},"name":"Ganymede","model_path":"ganymede.glb","diameter":5268.2,"rotation_speed":10303.2,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.075938e23,"starting_position":{"x":592818446.2926141,"y":447834490.0349652,"z":-15087819.74881226},"starting_velocity":{"x":-4.643871215581399,"y":18.53965996642426,"z":0.4153266498041814},"name":"Callisto","model_path":"callisto.glb","diameter":4820.6,"rotation_speed":24032.16,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":1.8981999999999999e27,"starting_position":{"x":591116405.042928,"y":448612773.658671,"z":-15086106.82481316},"starting_velocity":{"x":-8.045068878300311,"y":11.02381638213635,"z":0.1341531152888358},"name":"Jupiter","model_path":"jupiter.glb","diameter":139822.0,"rotation_speed":595.0,"axial_tilt":3.13,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":1.3452e23,"starting_position":{"x":1317062395.789841,"y":-625410954.1976979,"z":-42005663.01576936},"starting_velocity":{"x":-1.060852998165573,"y":6.402666517530363,"z":1.357634287951674},"name":"Titan","model_path":"titan.glb","diameter":5149.46,"rotation_speed":22920.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":2.3064854e21,"starting_position":{"x":1317198227.126551,"y":-626312128.6545614,"z":-41559528.59529075},"starting_velocity":{"x":2.806558904291587,"y":1.2701482567137,"z":3.694364144037066},"name":"Rhea","model_path":"rhea.glb","diameter":763.5,"rotation_speed":6480.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.8056591e21,"starting_position":{"x":1320855160.609993,"y":-627852134.0465181,"z":-41864404.17667893},"starting_velocity":{"x":4.854646792968393,"y":11.66248870085356,"z":-1.230081930411274},"name":"Iapetus","model_path":"iapetus.glb","diameter":1470.0,"rotation_speed":113760.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.0954868e21,"starting_position":{"x":1318063919.760553,"y":-626526636.509911,"z":-41528086.12631324},"starting_velocity":{"x":7.705841565764674,"y":16.66690708035977,"z":-4.861168661971909},"name":"Dione","model_path":"dione.glb","diameter":1123.0,"rotation_speed":3941.1576,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":6.174959e20,"starting_position":{"x":1317498514.533114,"y":-626196816.7390172,"z":-41643245.20863017},"starting_velocity":{"x":-3.711987600444088,"y":1.440318005837302,"z":4.443003247932851},"name":"Tethys","model_path":"tethys.glb","diameter":1062.0,"rotation_speed":2718.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":3.75094e19,"starting_position":{"x":1317862368.9731088,"y":-626273647.8866278,"z":-41636255.21668619},"starting_velocity":{"x":-5.466336813759373,"y":18.80368314533501,"z":-4.960595064530139},"name":"Mimas","model_path":"mimas.glb","diameter":396.0,"rotation_speed":1356.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.080318e20,"starting_position":{"x":1317897357.123477,"y":-626523695.3599699,"z":-41513334.7885673},"starting_velocity":{"x":12.03172552201499,"y":16.74134008425769,"z":-5.324491936368194},"name":"Enceladus","model_path":"enceladus.glb","diameter":504.0,"rotation_speed":1973.11392,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":5.6834e26,"starting_position":{"x":1317721699.784666,"y":-626376213.8853518,"z":-41573559.25955266},"starting_velocity":{"x":3.608323540191913,"y":8.705880483493228,"z":-0.2953903588682212},"name":"Saturn","model_path":"saturn.glb","diameter":116464.0,"rotation_speed":633.0,"axial_tilt":26.73,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":6.4e19,"starting_position":{"x":1876793591.976653,"y":2256780204.161452,"z":-15821844.53453541},"starting_velocity":{"x":0.5593250277603632,"y":3.223358609129066,"z":3.227082066969737},"name":"Miranda","model_path":"miranda.glb","diameter":471.6,"rotation_speed":2035.40976,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.251e21,"starting_position":{"x":1876695507.52492,"y":2256760167.205151,"z":-16046690.83471954},"starting_velocity":{"x":-8.385308784191833,"y":5.318928951790138,"z":4.453089305595049},"name":"Ariel","model_path":"ariel.glb","diameter":1157.8,"rotation_speed":3629.34576,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.275e21,"starting_position":{"x":1877032097.119599,"y":2256677176.877903,"z":-16115312.10892296},"starting_velocity":{"x":-8.506198828430891,"y":4.275436104814068,"z":-3.265378937492151},"name":"Umbriel","model_path":"umbriel.glb","diameter":1169.4,"rotation_speed":5904.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":3.4e21,"starting_position":{"x":1876446721.049093,"y":2256849468.855134,"z":-15797689.42792165},"starting_velocity":{"x":-4.077764161868127,"y":4.250690343060523,"z":3.508220529443759},"name":"Titania","model_path":"titania.glb","diameter":1576.8,"rotation_speed":12528.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":3.076e21,"starting_position":{"x":1876691132.612216,"y":2256854991.280804,"z":-15382668.94913125},"starting_velocity":{"x":-2.324170074400168,"y":3.526797505106853,"z":1.030057319525953},"name":"Oberon","model_path":"oberon.glb","diameter":1522.8,"rotation_speed":19440.0,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":8.681e25,"starting_position":{"x":1876848145.196212,"y":2256742495.428547,"z":-15933338.78791571},"starting_velocity":{"x":-5.285944969180821,"y":4.037177487005098,"z":0.0832885977451503},"name":"Uranus","model_path":"uranus.glb","diameter":50724.0,"rotation_speed":1034.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[{"children":[],"data":{"mass":2.139e22,"starting_position":{"x":4460435655.53476,"y":-311821079.6191955,"z":-96227400.08927624},"starting_velocity":{"x":0.6549830743821887,"y":8.816651890055235,"z":2.683376921837763},"name":"Triton","model_path":"triton.glb","diameter":2706.8,"rotation_speed":8496.0,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":1.024e26,"starting_position":{"x":4460737814.33013,"y":-311719495.6197202,"z":-96383087.29856476},"starting_velocity":{"x":0.3424898338191547,"y":5.454448402599064,"z":-0.1196973250551823},"name":"Neptune","model_path":"neptune.glb","diameter":49244.0,"rotation_speed":960.0,"axial_tilt":28.32,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.303e22,"starting_position":{"x":2534605027.840262,"y":-4550728311.952005,"z":-246201602.553565},"starting_velocity":{"x":4.90550581768183,"y":1.466573354685091,"z":-1.58125012378935},"name":"Pluto","model_path":"pluto.glb","diameter":2376.6,"rotation_speed":9201.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":220000000000000.0,"starting_position":{"x":-2974525169.762023,"y":4071518952.895051,"z":-1489577717.564979},"starting_velocity":{"x":0.7036787387939378,"y":0.567179895714418,"z":0.09880162683010832},"name":"Halley's Comet","model_path":"deimos.glb","diameter":11.0,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":3.1e21,"starting_position":{"x":-6899004382.898172,"y":-1090297370.986418,"z":3649000392.627125},"starting_velocity":{"x":0.2044745917565618,"y":-3.731030512801199,"z":-0.4904247640299213},"name":"Makemake","model_path":"makemake.glb","diameter":1430.0,"rotation_speed":1350.0,"axial_tilt":28.96,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":1.6466e22,"starting_position":{"x":12804007409.48511,"y":5796599006.941406,"z":-2733004417.387743},"starting_velocity":{"x":-0.7745567938606255,"y":1.50385470985689,"z":1.614258646777714},"name":"Eris","model_path":"eris.glb","diameter":2326.0,"rotation_speed":1554.0,"axial_tilt":0.0,"simulate":true,"light_source":null}},{"children":[],"data":{"mass":721.9,"starting_position":{"x":5567899398.702804,"y":-14892956491.9915,"z":-12346930533.86691},"starting_velocity":{"x":4.222130606182812,"y":-9.357402996434876,"z":-11.33474239077342},"name":"Voyager-2","model_path":"voyager.glb","diameter":0.001,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"light_source":null}}],"data":{"mass":1.9885e30,"starting_position":{"x":-1253558.344523507,"y":-331931.4431501561,"z":31972.046837662},"starting_velocity":{"x":0.006931107133912123,"y":-0.01362000313964326,"z":-0.0000454388831820406},"name":"Sol","model_path":"sun.glb","diameter":1392000.0,"rotation_speed":38880.0,"axial_tilt":7.25,"simulate":true,"light_source":{"intensity":3.7500000351027205e28,"range":4436820000000.0,"color":"#002EFF","enabled":true}}}],"starting_time_millis":1696118400000,"title":"Solar System2dd","description":"A scenario with all major bodies and their major moons in the Solar System."} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6dde349..ea1fb48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,12 +73,12 @@ fn main() { ..default() }), ..default() - }) + }) ) - .add_plugins(WorldInspectorPlugin::default()) + // .add_plugins(WorldInspectorPlugin::default()) .add_plugins(EditorPlugin) .add_plugins(SimulationPlugin) - // .add_plugins(EguiPlugin) + .add_plugins(EguiPlugin) .add_plugins(SerializationPlugin) .add_plugins(BillboardPlugin) .add_plugins(SetupPlugin) diff --git a/src/serialization.rs b/src/serialization.rs index fc8294a..95f1ced 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -6,9 +6,9 @@ use bevy::{ math::DVec3, prelude::Plugin, reflect::{TypePath}, utils::BoxedFuture, }; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; -#[derive(Debug, Deserialize, TypePath, Asset, Clone)] +#[derive(Debug, Deserialize, Serialize, TypePath, Asset, Clone)] pub struct SimulationData { pub bodies: Vec, pub starting_time_millis: i64, @@ -16,13 +16,13 @@ pub struct SimulationData { pub description: String, } -#[derive(Debug, Deserialize, TypePath, Clone)] +#[derive(Debug, Deserialize, Serialize, TypePath, Clone)] pub struct SerializedBody { pub children: Vec, pub data: SerializedBodyData } -#[derive(Debug, Deserialize, TypePath, Clone, Copy)] +#[derive(Debug, Deserialize, Serialize, TypePath, Clone, Copy)] pub struct SerializedVec { pub x: f64, pub y: f64, @@ -49,7 +49,7 @@ impl From for SerializedVec { } -#[derive(Debug, Deserialize, TypePath, Clone)] +#[derive(Debug, Serialize, Deserialize, TypePath, Clone)] pub struct SerializedBodyData { pub mass: f64, pub starting_position: SerializedVec, @@ -63,7 +63,7 @@ pub struct SerializedBodyData { pub light_source: Option } -#[derive(Debug, Deserialize, TypePath, Clone)] +#[derive(Debug, Serialize, Deserialize, TypePath, Clone)] pub struct SerializedLightSource { pub intensity: f64, pub range: f64, diff --git a/src/setup.rs b/src/setup.rs index f1b56c6..da5a5e1 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -9,7 +9,7 @@ use bevy::ecs::system::EntityCommands; use bevy::hierarchy::BuildChildren; use bevy::math::{DVec3, Vec3}; use bevy::pbr::{PbrBundle, PointLight, PointLightBundle}; -use bevy::prelude::{Assets, Bundle, Camera, Camera3dBundle, ChildBuilder, Color, Commands, default, Entity, Handle, in_state, IntoSystemConfigs, Mesh, OnEnter, PerspectiveProjection, Projection, Res, ResMut, Resource, SceneBundle, SpatialBundle, StandardMaterial, Startup, Transform, Update, Visibility, Circle, Srgba, Hsva}; +use bevy::prelude::{Assets, Bundle, Camera, Camera3dBundle, ChildBuilder, Color, Commands, default, Entity, Handle, in_state, IntoSystemConfigs, Mesh, OnEnter, PerspectiveProjection, Projection, Res, ResMut, Resource, SceneBundle, SpatialBundle, StandardMaterial, Startup, Transform, Update, Visibility, Circle, Srgba, Hsva, NextState}; use bevy::render::view::{GpuCulling, NoCpuCulling, RenderLayers}; use bevy::scene::Scene; use bevy::text::{JustifyText, TextSection, TextStyle}; @@ -32,25 +32,43 @@ pub struct SetupPlugin; impl Plugin for SetupPlugin { fn build(&self, app: &mut App) { app - .init_resource::() + .init_resource::() .add_systems(Startup, setup_camera) .add_systems(Update, setup_planets.run_if(in_state(SimState::Loading))); } } #[derive(Resource, Default)] -pub struct StartingTime(pub i64); +pub struct ScenarioData { + + pub starting_time_millis: i64, + pub title: String, + pub description: String + +} + +impl From for ScenarioData { + + fn from(value: SimulationData) -> Self { + Self { + starting_time_millis: value.starting_time_millis, + title: value.title, + description: value.description + } + } +} pub fn setup_planets( mut commands: Commands, assets: Res, mut selected_scenario: ResMut, bodies_asset: ResMut>, - mut starting_time: ResMut, + mut scenario_data: ResMut, mut loading_state: ResMut, mut selected_entity: ResMut, mut meshes: ResMut>, mut materials: ResMut>, + mut sim_state: ResMut>, ) { if selected_scenario.spawned { return; @@ -61,7 +79,7 @@ pub fn setup_planets( return; } let data = bodies.unwrap(); - starting_time.0 = data.starting_time_millis; + *scenario_data = ScenarioData::from(data.clone()); let stars = data.bodies.iter().count(); total_count += stars; @@ -161,6 +179,10 @@ pub fn setup_planets( selected_scenario.spawned = true; loading_state.loaded_bodies = true; loading_state.total_bodies = total_count as i32; + if stars == 0 { + loading_state.reset(); + sim_state.set(SimState::Loaded); + } } pub fn calculate_hue( @@ -259,7 +281,7 @@ fn spawn_imposter( parent_id: Entity, ) { parent.spawn(PbrBundle { - mesh: meshes.add(Circle::new(bundle.diameter.num * 3.0)), + mesh: meshes.add(Circle::new(bundle.diameter.num * 3.0 * M_TO_UNIT as f32)), material: materials.add(color), visibility: Visibility::Hidden, ..default() diff --git a/src/simulation/components/billboard.rs b/src/simulation/components/billboard.rs index 1ce27f4..afc0a06 100644 --- a/src/simulation/components/billboard.rs +++ b/src/simulation/components/billboard.rs @@ -61,12 +61,12 @@ fn auto_scale_billboards( } else if star { radius > STAR_VISIBILITY_THRESHOLD } else { - radius < PLANET_VISIBILITY_THRESHOLD && radius > (diameter.num * 2.0) && (apsis.unwrap().perihelion.distance as f64 * M_TO_UNIT * 50.0 > radius as f64) + radius < PLANET_VISIBILITY_THRESHOLD && radius > (diameter.num * 2.0 * M_TO_UNIT as f32) && (apsis.unwrap().perihelion.distance as f64 * M_TO_UNIT * 50.0 > radius as f64) }; let offset = if star { distance_to_cam } else { - diameter.num / distance_to_cam * 0.01 + diameter.num * M_TO_UNIT as f32 / distance_to_cam * 0.01 }; billboard_visible.0 = predicate; billboard( diff --git a/src/simulation/components/body.rs b/src/simulation/components/body.rs index 89c4a4a..c7ac549 100644 --- a/src/simulation/components/body.rs +++ b/src/simulation/components/body.rs @@ -84,7 +84,6 @@ pub struct SimPosition(pub DVec3); #[derive(Component, Reflect, Clone, Default)] pub struct Diameter { - //note this is scaled in units TODO: fix this pub num: f32, pub applied: bool, pub aabb: Option @@ -143,7 +142,7 @@ impl From for BodyBundle { name: Name::new(value.data.name), model_path: ModelPath(format!("models/{}#Scene0", value.data.model_path)), diameter: Diameter { - num: (value.data.diameter * 1000.0 *M_TO_UNIT) as f32, + num: (value.data.diameter * 1000.0) as f32, ..default() }, axial_tilt: AxialTilt { diff --git a/src/simulation/components/diameter.rs b/src/simulation/components/diameter.rs index e9ad5e1..462e9dd 100644 --- a/src/simulation/components/diameter.rs +++ b/src/simulation/components/diameter.rs @@ -1,7 +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 crate::constants::M_TO_UNIT; use crate::simulation::SimState; use crate::simulation::components::body::SceneHandle; use crate::simulation::components::body::{Diameter, Scale}; @@ -48,7 +48,7 @@ pub fn apply_real_diameter( diameter.aabb = Some(aabb); aabb }; - transform.scale = Vec3::splat(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 + transform.scale = Vec3::splat(diameter.num * M_TO_UNIT as f32 / 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 scale.0 = transform.scale.x; diameter.applied = true; loading_state.scaled_bodies_count += 1; diff --git a/src/simulation/components/direction.rs b/src/simulation/components/direction.rs index e390ae0..faba79b 100644 --- a/src/simulation/components/direction.rs +++ b/src/simulation/components/direction.rs @@ -1,5 +1,6 @@ use bevy::{app::{App, Plugin}, prelude::{in_state, Entity, Gizmos, IntoSystemConfigs, Query, Transform, Update, With}}; use bevy::color::palettes::css; +use crate::constants::M_TO_UNIT; use crate::simulation::SimState; use crate::simulation::components::body::{BodyChildren, Diameter, Moon, OrbitSettings, Planet, Velocity}; use crate::simulation::components::camera::pan_orbit_camera; @@ -21,20 +22,22 @@ fn display_force_and_velocity( mut gizmos: Gizmos ) { for (transform, _, orbit, diameter, velocity) in &planet_query { + let d = diameter.num as f64 * M_TO_UNIT; if orbit.display_force { - gizmos.arrow(transform.translation, transform.translation + (orbit.force_direction * diameter.num as f64 * orbit.arrow_scale as f64).as_vec3(), css::BLUE); + gizmos.arrow(transform.translation, transform.translation + (orbit.force_direction * d * orbit.arrow_scale as f64).as_vec3(), css::BLUE); } if orbit.display_velocity { - gizmos.arrow(transform.translation, transform.translation +(velocity.0.normalize() * diameter.num as f64 * orbit.arrow_scale as f64).as_vec3(), css::RED); + gizmos.arrow(transform.translation, transform.translation +(velocity.0.normalize() * d* orbit.arrow_scale as f64).as_vec3(), css::RED); } } for (entity, transform, orbit, diameter, velocity) in &moon_query { + let d = diameter.num as f64 * M_TO_UNIT; if orbit.display_force { - gizmos.arrow(transform.translation, transform.translation +(orbit.force_direction * diameter.num as f64 * orbit.arrow_scale as f64).as_vec3(), css::BLUE); + gizmos.arrow(transform.translation, transform.translation +(orbit.force_direction * d * orbit.arrow_scale as f64).as_vec3(), css::BLUE); } if orbit.display_velocity { if let Some((_, _, _, _, vel)) = planet_query.iter().find(|(_, ch, _, _, _)| ch.0.contains(&entity)) { - gizmos.arrow(transform.translation, transform.translation +((velocity.0 - vel.0).normalize() * diameter.num as f64 * orbit.arrow_scale as f64).as_vec3(), css::RED); + gizmos.arrow(transform.translation, transform.translation +((velocity.0 - vel.0).normalize() * d * orbit.arrow_scale as f64).as_vec3(), css::RED); } } } diff --git a/src/simulation/components/orbit_lines.rs b/src/simulation/components/orbit_lines.rs index 221f836..b995b24 100644 --- a/src/simulation/components/orbit_lines.rs +++ b/src/simulation/components/orbit_lines.rs @@ -59,7 +59,7 @@ fn update_lines( let cam = camera.single(); for (entity, mut orbit, pos, _, diameter, billboard_visible) in &mut planet_query { if orbit.draw_lines { - orbit.hide_lines = (cam.radius < diameter.num * PLANET_HIDE_MULTIPLIER && entity == selected_entity.entity.unwrap() || !billboard_visible.0) && ui_state.dyn_hide_orbit_lines; + orbit.hide_lines = (cam.radius < diameter.num * M_TO_UNIT as f32 * PLANET_HIDE_MULTIPLIER && entity == selected_entity.entity.unwrap() || !billboard_visible.0) && ui_state.dyn_hide_orbit_lines; let speed = speed.0 as f32 * (substeps.0 as f32); let max_step = (orbit.period as f32 / speed) * MULTIPLIER; if orbit.step >= max_step { @@ -76,7 +76,7 @@ fn update_lines( if let Some((_, _, p_pos, _, _, _)) = planet_query.iter().find(|(_, _, _, children, _, _)| { children.0.contains(&entity) }) { - orbit.hide_lines = (cam.radius < diameter.num * HIDE_MULTIPLIER && entity == selected_entity.entity.unwrap() || !billboard_visible.0) && ui_state.dyn_hide_orbit_lines; + orbit.hide_lines = (cam.radius < diameter.num * M_TO_UNIT as f32 * HIDE_MULTIPLIER && entity == selected_entity.entity.unwrap() || !billboard_visible.0) && ui_state.dyn_hide_orbit_lines; let speed = speed.0 as f32 * (substeps.0 as f32); let max_step = (orbit.period as f32 / speed) * MULTIPLIER; if orbit.step >= max_step { diff --git a/src/simulation/components/save_scenario.rs b/src/simulation/components/save_scenario.rs index e4aff2a..cb1366a 100644 --- a/src/simulation/components/save_scenario.rs +++ b/src/simulation/components/save_scenario.rs @@ -1,14 +1,16 @@ -use std::fs; -use bevy::app::Plugin; -use bevy::core::Name; -use bevy::ecs::system::SystemParam; -use bevy::math::DVec3; -use bevy::prelude::{AssetServer, Assets, Entity, PointLight, Query, Res, ResMut, Visibility}; use crate::constants::M_TO_UNIT; use crate::serialization::{SerializedBody, SerializedBodyData, SerializedLightSource, SerializedVec, SimulationData}; -use crate::setup::StartingTime; +use crate::setup::ScenarioData; use crate::simulation::components::body::{AxialTilt, BodyChildren, Diameter, LightSource, Mass, ModelPath, RotationSpeed, SimPosition, Star, Velocity}; use crate::simulation::ui::scenario_selection::SelectedScenario; +use crate::simulation::ui::toast::{success_toast, ToastContainer}; +use bevy::app::Plugin; +use bevy::core::Name; +use bevy::ecs::system::SystemParam; +use bevy::math::DVec3; +use bevy::prelude::{default, AssetServer, Assets, Entity, PointLight, Query, Res, ResMut, Visibility}; +use std::fs; +use egui_toast::{Toast, ToastKind, ToastOptions}; pub struct SaveScenarioPlugin; @@ -26,9 +28,11 @@ pub struct SystemPanelSet<'w, 's> { assets: Res<'w, AssetServer>, selected_scenario: ResMut<'w, SelectedScenario>, bodies_asset: ResMut<'w, Assets>, - starting_time: ResMut<'w, StartingTime>, - bodies: Query<'w, 's, (Entity, &'static Mass, &'static SimPosition, &'static Velocity, &'static Name, &'static ModelPath, &'static Diameter, &'static RotationSpeed, &'static AxialTilt, &'static BodyChildren, Option<&'static Star>)>, - lights: Query<'w, 's, (&'static LightSource, &'static PointLight, &'static Visibility)> + 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>, Option<&'static Star>)>, + lights: Query<'w, 's, (&'static LightSource, &'static PointLight, &'static Visibility)>, + toasts: ResMut<'w, ToastContainer> + } pub fn save_scenario( @@ -36,7 +40,16 @@ pub fn save_scenario( ) { let file_path = get_file_path(&system_panel_set); let bodies = collect_bodies(&system_panel_set); - + let scenario_data = &*system_panel_set.scenario_data; + let simulation_data: SimulationData = SimulationData { + bodies, + starting_time_millis: scenario_data.starting_time_millis, + title: scenario_data.title.clone(), + description: scenario_data.description.clone(), + }; + let serialized_data = serde_json::to_string(&simulation_data).unwrap(); + fs::write(format!("assets/scenarios/{}", file_path), serialized_data).unwrap(); + system_panel_set.toasts.0.add(success_toast("Scenario saved")); } fn get_file_path<'s>(system_panel_set: &'s SystemPanelSet) -> &'s str { @@ -45,18 +58,13 @@ fn get_file_path<'s>(system_panel_set: &'s SystemPanelSet) -> &'s str { fn collect_bodies(system_panel_set: &SystemPanelSet) -> Vec { let mut bodies = Vec::new(); - for (entity, mass, position, velocity, name, model_path, diameter, rotation_speed, axial_tilt, children, star) in system_panel_set.bodies.iter() { - if star.is_none() { - continue; - } - let data = create_serialized_body_data( - mass.0, position.0, velocity.0, name.to_string(), model_path.0.clone(), - diameter.num as f64, rotation_speed.0, axial_tilt.num, - find_light_source(system_panel_set, entity) - ); - let planets = collect_planets(system_panel_set, children.clone()); + system_panel_set.bodies.iter().filter(|(_, _, _, _, _, _, _, _, _, _, star)| star.is_some()).for_each(|(entity, _, _, _, _, _, _, _, _, children, _)| { + let mut data = find_body_data(system_panel_set, entity).map(|(data, _)| data).unwrap(); + let light_source = find_light_source(system_panel_set, entity); + data.light_source = light_source; + let planets = collect_planets(system_panel_set, children.unwrap().clone()); bodies.push(SerializedBody { children: planets, data }); - } + }); bodies } @@ -64,7 +72,8 @@ fn collect_planets(system_panel_set: &SystemPanelSet, children: BodyChildren) -> let mut planets = Vec::new(); for planet_entity in children.0.clone() { if let Some((planet_data, planet_children)) = find_body_data(system_panel_set, planet_entity) { - let moons = collect_moons(system_panel_set, planet_children); + let moons = collect_moons(system_panel_set, planet_children.unwrap().clone()); + println!("{:?}", moons); planets.push(SerializedBody { children: moons, data: planet_data.clone() }); } } @@ -81,11 +90,11 @@ fn collect_moons(system_panel_set: &SystemPanelSet, children: BodyChildren) -> V moons } -fn find_body_data(system_panel_set: &SystemPanelSet, entity: Entity) -> Option<(SerializedBodyData, BodyChildren)> { +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, _)| ( - create_serialized_body_data(m.0, p.0, v.0, n.to_string(), mp.0.clone(), d.num as f64, rs.0, at.num, None), - child.clone() + 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), + child.map(|c| c.clone()) )) } fn create_serialized_body_data( @@ -105,7 +114,7 @@ fn create_serialized_body_data( starting_velocity: SerializedVec::from(velocity), name, model_path, - diameter: diameter / M_TO_UNIT, + diameter, rotation_speed, axial_tilt, simulate: true, @@ -118,8 +127,8 @@ fn find_light_source( entity: Entity ) -> Option { system_panel_set.lights.iter().find(|(s, _, _)| s.0 == entity).map(|(_, light, visibility)| SerializedLightSource { - intensity: light.intensity as f64, - range: light.range as f64, + intensity: light.intensity as f64 / M_TO_UNIT.powf(2.), + range: light.range as f64 / M_TO_UNIT, color: light.color.to_srgba().to_hex(), enabled: visibility == &Visibility::Visible }) diff --git a/src/simulation/components/selection.rs b/src/simulation/components/selection.rs index d52ea0b..6772cc3 100644 --- a/src/simulation/components/selection.rs +++ b/src/simulation/components/selection.rs @@ -51,7 +51,7 @@ pub fn apply_camera_to_selection( } else if !selected_entity.changed_focus { let (_, _, diameter, _) = bodies.get(entity).unwrap(); let mut cam = camera.single_mut(); - cam.radius = (diameter.num * SELECTION_MULTIPLIER) as f32; + cam.radius = (diameter.num * SELECTION_MULTIPLIER * M_TO_UNIT as f32); if orbit_offset.enabled { cam.focus = Vec3::ZERO; } diff --git a/src/simulation/ui/editor_body_panel.rs b/src/simulation/ui/editor_body_panel.rs index 655d3f0..f46d453 100644 --- a/src/simulation/ui/editor_body_panel.rs +++ b/src/simulation/ui/editor_body_panel.rs @@ -10,10 +10,12 @@ use bevy::pbr::StandardMaterial; use bevy::prelude::{default, BuildChildren, Camera, Color, Commands, DespawnRecursiveExt, Entity, Handle, Mesh, Mut, PointLight, PointLightBundle, Query, Res, ResMut, Resource, Scene, Srgba, Transform, Vec3, Visibility, With, Without}; use bevy_egui::egui::{Align, Context, Layout, RichText, ScrollArea}; use bevy_egui::{egui, EguiContexts}; +use egui_toast::{Toast, ToastKind, ToastOptions}; use crate::setup::spawn_scene; use crate::simulation::components::editor::{EditorSystemType, EditorSystems}; use crate::simulation::render::star_billboard::StarBillboard; use crate::simulation::ui::components::vector_field; +use crate::simulation::ui::toast::{success_toast, ToastContainer}; use crate::simulation::ui::UiState; #[derive(Debug, Default, Clone, Resource)] @@ -51,10 +53,12 @@ pub fn editor_body_panel( mut light_query: Query<(&mut PointLight, &LightSource, &mut Visibility)>, mut billboards: Query<(&StarBillboard, &mut Handle)>, mut materials: ResMut>, + mut toast_container: ResMut ) { if egui_context.try_ctx_mut().is_none() { return; } + let mut apply = false; if let Some(s_entity) = selected_entity.entity { if let Ok((entity, mut name, mut pos, mut vel, mut mass, mut diameter, mut rotation_speed, mut tilt, mut model_path, mut scene)) = query.get_mut(s_entity) { let light = light_query.iter_mut().find(|(_, l, _)| l.0 == entity).map(|(a,b,c)| (a,b,c)); @@ -62,11 +66,14 @@ pub fn editor_body_panel( if state.entity.is_none() || state.entity.unwrap() != s_entity { initialize_state(state.as_mut(), s_entity, &name, &pos, &vel, &mass, &diameter, &rotation_speed, &tilt, &model_path, light.as_ref()); } - display_body_panel(egui_context.ctx_mut(), state.as_mut(), &mut name, &mut pos, &mut vel, &mut mass, &mut diameter, &mut rotation_speed, &mut tilt, &mut model_path, &mut scene, &mut commands, &systems, &assets, light, scene_query, billboard_material.as_mut(), &mut materials); + display_body_panel(egui_context.ctx_mut(), state.as_mut(), &mut name, &mut pos, &mut vel, &mut mass, &mut diameter, &mut rotation_speed, &mut tilt, &mut model_path, &mut scene, &mut commands, &systems, &assets, light, scene_query, billboard_material.as_mut(), &mut materials, &mut apply); } } else { state.entity = None; } + if apply { + toast_container.0.add(success_toast("Changes applied")); + } } fn initialize_state( @@ -85,10 +92,10 @@ fn initialize_state( *state = EditorPanelState { entity: Some(s_entity), new_name: name.to_string(), - new_position: pos.0, - new_velocity: vel.0, + new_position: pos.0 / 1000.0, + new_velocity: vel.0 / 1000.0, new_mass: mass.0, - new_diameter: (diameter.num / 1000.0) / M_TO_UNIT as f32, + new_diameter: (diameter.num / 1000.0), new_rotation_speed: rotation_speed.0, new_axial_tilt: tilt.num, new_model_path: model_path.cleaned(), @@ -120,7 +127,8 @@ fn display_body_panel( light: Option<(Mut, &LightSource, Mut)>, scene_query: Query>, billboard_material: Option<&mut Handle>, - materials: &mut ResMut> + materials: &mut ResMut>, + apply: &mut bool ) { egui::SidePanel::right("body_panel") .resizable(true) @@ -131,7 +139,7 @@ fn display_body_panel( ui.heading("Body"); display_body_properties(ui, state); display_light_source(ui, state); - display_bottom_buttons(ui, state, name, pos, vel, mass, diameter, rotation_speed, tilt, model_path, scene, commands, systems, assets, light, scene_query, billboard_material, materials); + display_bottom_buttons(ui, state, name, pos, vel, mass, diameter, rotation_speed, tilt, model_path, scene, commands, systems, assets, light, scene_query, billboard_material, materials, apply); }); }); } @@ -161,8 +169,8 @@ fn display_body_properties(ui: &mut egui::Ui, state: &mut EditorPanelState) { ui.label("Axial Tilt (degrees)"); ui.add(egui::DragValue::new(&mut state.new_axial_tilt)); }); - vector_field(ui, "Position (m)", &mut state.new_position); - vector_field(ui, "Velocity (m/s)", &mut state.new_velocity); + vector_field(ui, "Position (km)", &mut state.new_position); + vector_field(ui, "Velocity (km/s)", &mut state.new_velocity); } fn display_light_source(ui: &mut egui::Ui, state: &mut EditorPanelState) { @@ -214,12 +222,14 @@ fn display_bottom_buttons( light: Option<(Mut, &LightSource, Mut)>, scene_query: Query>, billboard_material: Option<&mut Handle>, - materials: &mut ResMut> + materials: &mut ResMut>, + apply: &mut bool ) { ui.with_layout(Layout::bottom_up(Align::Center), |ui| { ui.horizontal(|ui| { if ui.button("Apply").on_hover_text("Apply changes").clicked() { apply_changes(state, name, pos, vel, mass, diameter, rotation_speed, tilt, model_path, scene, commands, systems, assets, light, scene_query, billboard_material, materials); + *apply = true; } if ui.button("Reset").on_hover_text("Reset to original values").clicked() { // Reset logic here @@ -263,10 +273,10 @@ fn apply_changes( materials: &mut ResMut> ) { name.set(state.new_name.clone()); - pos.0 = state.new_position; - vel.0 = state.new_velocity; + pos.0 = state.new_position * 1000.0; + vel.0 = state.new_velocity * 1000.0; mass.0 = state.new_mass; - let new_diameter = state.new_diameter * M_TO_UNIT as f32 * 1000.0; + let new_diameter = state.new_diameter * 1000.0; diameter.applied = new_diameter == diameter.num; diameter.num = new_diameter; rotation_speed.0 = state.new_rotation_speed; diff --git a/src/simulation/ui/editor_bottom_bar.rs b/src/simulation/ui/editor_bottom_bar.rs index 95c834f..8228360 100644 --- a/src/simulation/ui/editor_bottom_bar.rs +++ b/src/simulation/ui/editor_bottom_bar.rs @@ -4,7 +4,7 @@ use bevy::window::PresentMode; use bevy_egui::{egui, EguiContexts}; use bevy_egui::egui::Align; use chrono::NaiveDateTime; -use crate::setup::StartingTime; +use crate::setup::ScenarioData; use crate::simulation::components::lock_on::LockOn; use crate::simulation::components::physics::{Pause, SubSteps}; use crate::simulation::components::speed::Speed; @@ -19,13 +19,13 @@ pub fn editor_bottom_bar( mut windows: Query<&mut Window>, mut lock_on_parent: ResMut, mut state: ResMut>, - starting_time: Res, + scenario_data: Res, diagnostics: Res, systems: Res, mut commands: Commands ) { let mut window = windows.single_mut(); - let date = get_date_from_millis(starting_time.0, sim_time.0); + let date = get_date_from_millis(scenario_data.starting_time_millis, sim_time.0); egui::TopBottomPanel::bottom("time_panel") .resizable(false) .show(egui_context.ctx_mut(), |ui| { diff --git a/src/simulation/ui/mod.rs b/src/simulation/ui/mod.rs index f6a7740..1ad97ab 100644 --- a/src/simulation/ui/mod.rs +++ b/src/simulation/ui/mod.rs @@ -7,6 +7,7 @@ pub mod scenario_selection; mod sim_body_panel; pub mod simulation_bottom_bar; pub mod editor_bottom_bar; +pub mod toast; use bevy::{ core_pipeline::Skybox, @@ -24,7 +25,7 @@ use bevy_inspector_egui::egui::{RichText, TextEdit}; use chrono::{Days, NaiveDateTime}; //use crate::fps::Fps; -use crate::{constants::{DAY_IN_SECONDS, M_TO_AU, M_TO_UNIT}, setup::StartingTime, unit::format_length}; +use crate::{constants::{DAY_IN_SECONDS, M_TO_AU, M_TO_UNIT}, unit::format_length}; use crate::simulation::components::billboard::BillboardSettings; use crate::simulation::components::body::BodyParent; use crate::constants::G; @@ -54,6 +55,7 @@ use crate::simulation::ui::editor_bottom_bar::editor_bottom_bar; 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::toast::ToastPlugin; use crate::unit::format_seconds; use crate::utils::{sim_state_type_editor, sim_state_type_simulation}; @@ -99,6 +101,7 @@ impl Plugin for InterfacePlugin { .init_resource::() .add_plugins(DebugPlugin) .add_plugins(ScenarioSelectionPlugin) + .add_plugins(ToastPlugin) .add_systems( Update, ( diff --git a/src/simulation/ui/scenario_selection.rs b/src/simulation/ui/scenario_selection.rs index 3ced148..688784f 100644 --- a/src/simulation/ui/scenario_selection.rs +++ b/src/simulation/ui/scenario_selection.rs @@ -1,12 +1,14 @@ +use std::fs; use bevy::app::{App, Plugin, Update}; use bevy::asset::LoadedFolder; use bevy::prelude::{in_state, AssetServer, Assets, Commands, Handle, Image, IntoSystemConfigs, Local, NextState, OnEnter, OnExit, Res, ResMut, Resource}; use bevy::utils::HashMap; -use bevy_egui::egui::{Align, CentralPanel, Layout, TextureId}; +use bevy_egui::egui::{Align, CentralPanel, Layout, SidePanel, TextureId}; use bevy_egui::{egui, EguiContexts}; use image::load; use crate::serialization::SimulationData; use crate::simulation::{SimState, SimStateType}; +use crate::simulation::ui::toast::{error_toast, ToastContainer}; pub struct ScenarioSelectionPlugin; @@ -15,8 +17,9 @@ impl Plugin for ScenarioSelectionPlugin { fn build(&self, app: &mut App) { app .init_resource::() + .init_resource::() .add_systems(OnEnter(SimState::ScenarioSelection), load_scenarios) - .add_systems(Update, spawn_menu.run_if(in_state(SimState::ScenarioSelection))); + .add_systems(Update, (creation_sidebar, show_menu).chain().run_if(in_state(SimState::ScenarioSelection))); } } @@ -31,6 +34,17 @@ pub struct SelectedScenario { } +#[derive(Resource, Default, Clone)] +pub struct SelectionState { + + pub show_creation: bool, + pub title: String, + pub description: String, + pub file_name: String, + pub image_path: String + +} + fn load_scenarios( assets: Res, mut commands: Commands @@ -39,7 +53,96 @@ fn load_scenarios( commands.insert_resource(ScenarioFolder(handle)); } -fn spawn_menu( +fn creation_sidebar( + mut egui_context: EguiContexts, + mut selection_state: ResMut, + mut sim_state: ResMut>, + mut sim_state_type: ResMut, + mut toasts: ResMut +) { + if !selection_state.show_creation { + return; + } + SidePanel::right("Create Scenario").default_width(300.0).resizable(true).show(&egui_context.ctx_mut(), |ui| { + ui.horizontal(|ui| { + ui.heading("Create new scenario"); + ui.separator(); + if ui.button("Cancel").clicked() { + selection_state.show_creation = false; + } + }); + ui.separator(); + ui.horizontal(|ui| { + ui.label("File name:"); + ui.text_edit_singleline(&mut selection_state.file_name); + }); + ui.horizontal(|ui| { + ui.label("Title:"); + ui.text_edit_singleline(&mut selection_state.title); + }); + ui.horizontal(|ui| { + ui.label("Description:"); + ui.text_edit_singleline(&mut selection_state.description); + }); + ui.horizontal(|ui| { + ui.label("Image path:"); + ui.text_edit_singleline(&mut selection_state.image_path); + if ui.button("Select").on_hover_text("Select image").clicked() { + match tinyfiledialogs::open_file_dialog("Open", "password.txt", None) { + Some(file) => { + selection_state.image_path = file; + }, + None => { + toasts.0.add(error_toast("No file selected")); + }, + } + }; + }); + ui.horizontal(|ui| { + if ui.button("Create").on_hover_text("Create scenario").clicked() { + if let Err(e) = validate_input(selection_state.clone()) { + toasts.0.add(error_toast(&e)); + } else { + let initial_data = SimulationData { + bodies: Vec::new(), + starting_time_millis: 0, + title: selection_state.title.clone(), + description: selection_state.description.clone() + }; + fs::write(format!("assets/scenarios/{}.sim", selection_state.file_name), serde_json::to_string(&initial_data).unwrap()).unwrap(); + fs::copy(&selection_state.image_path, format!("assets/scenarios/{}.png", selection_state.file_name)).unwrap(); + selection_state.show_creation = false; + } + }; + }); + }); +} + +fn validate_input(selection_state: SelectionState) -> Result<(), String> { + if let Ok(e) = fs::exists(&selection_state.image_path) { + if !e { + return Err("Image path cannot be accessed".to_string()); + } + } else { + return Err("Image path cannot be accessed".to_string()); + } + if let Ok(e) = fs::exists(format!("assets/scenarios/{}.sim", selection_state.file_name)) { + if e { + return Err("Scenario with file name already exists".to_string()); + } + } else { + return Err("File path cannot be accessed".to_string()); + } + if selection_state.file_name.is_empty() { + return Err("File name cannot be empty".to_string()); + } + if selection_state.title.is_empty() { + return Err("Title cannot be empty".to_string()); + } + Ok(()) +} + +fn show_menu( mut egui_context: EguiContexts, scenario_folder: Res, folders: Res>, @@ -48,11 +151,18 @@ fn spawn_menu( mut selected_scenario: ResMut, mut sim_state: ResMut>, mut images: Local>, - mut sim_state_type: ResMut + mut sim_state_type: ResMut, + mut selection_state: ResMut ) { CentralPanel::default() .show(&egui_context.ctx_mut().clone(), |ui| { - ui.heading("Scenario Selection"); + ui.horizontal(|ui| { + ui.heading("Scenario Selection"); + ui.separator(); + if ui.button("Create new").clicked() { + selection_state.show_creation = true; + } + }); ui.separator(); ui.label("Select a scenario to load:"); ui.separator(); diff --git a/src/simulation/ui/sim_body_panel.rs b/src/simulation/ui/sim_body_panel.rs index 768dd80..ab6e692 100644 --- a/src/simulation/ui/sim_body_panel.rs +++ b/src/simulation/ui/sim_body_panel.rs @@ -92,7 +92,7 @@ pub fn sim_body_panel( .size(16.0) .underline(), ); - let scaled_diameter = (diameter.num / M_TO_UNIT as f32) * n_scale; + let scaled_diameter = (diameter.num) * n_scale; ui.label(format!("{} km", scaled_diameter / 1000.0)); } diff --git a/src/simulation/ui/simulation_bottom_bar.rs b/src/simulation/ui/simulation_bottom_bar.rs index 049ca42..6d55818 100644 --- a/src/simulation/ui/simulation_bottom_bar.rs +++ b/src/simulation/ui/simulation_bottom_bar.rs @@ -5,7 +5,7 @@ use bevy_egui::{egui, EguiContexts}; use bevy_egui::egui::TextEdit; use chrono::NaiveDateTime; use crate::constants::DAY_IN_SECONDS; -use crate::setup::StartingTime; +use crate::setup::ScenarioData; use crate::simulation::components::lock_on::LockOn; use crate::simulation::components::physics::{Pause, SubSteps}; use crate::simulation::components::speed::Speed; @@ -22,7 +22,7 @@ pub fn simulation_bottom_bar( mut lock_on_parent: ResMut, mut pause: ResMut, mut state: ResMut>, - starting_time: Res, + scenario_data: Res, mut sub_steps: ResMut, mut ui_state: ResMut, diagnostics: Res, @@ -34,7 +34,7 @@ pub fn simulation_bottom_bar( if !pause.0 && *sim_type == SimStateType::Simulation { sim_time.0 += time.delta_seconds() * (((speed.0 * (sub_steps.0 as f64)) / (DAY_IN_SECONDS as f64)) as f32); } - let date = get_date_from_millis(starting_time.0, sim_time.0); + let date = get_date_from_millis(scenario_data.starting_time_millis, sim_time.0); let mut window = windows.single_mut(); egui::TopBottomPanel::bottom("time_panel") .resizable(false) diff --git a/src/simulation/ui/toast.rs b/src/simulation/ui/toast.rs new file mode 100644 index 0000000..21dc359 --- /dev/null +++ b/src/simulation/ui/toast.rs @@ -0,0 +1,52 @@ +use bevy::app::{App, Plugin, Update}; +use bevy::prelude::{default, ResMut, Resource}; +use bevy_egui::{EguiContext, EguiContexts}; +use egui_toast::{Toast, ToastKind, ToastOptions, Toasts}; + +pub struct ToastPlugin; + +impl Plugin for ToastPlugin { + + fn build(&self, app: &mut App) { + app + .init_resource::() + .add_systems(Update, show_toasts); + } + +} + +#[derive(Resource)] +pub struct ToastContainer(pub Toasts); + +impl Default for ToastContainer { + fn default() -> Self { + Self(Toasts::default()) + } +} + +fn show_toasts( + mut egui_context: EguiContexts, + mut toasts: ResMut +) { + toasts.0.show(egui_context.ctx_mut()); +} + +pub fn success_toast(text: &str) -> Toast { + Toast { + text: text.into(), + kind: ToastKind::Success, + options: ToastOptions::default() + .duration_in_seconds(3.0), + ..default() + } +} + +pub fn error_toast(text: &str) -> Toast { + Toast { + text: text.into(), + kind: ToastKind::Error, + options: ToastOptions::default() + .duration_in_seconds(3.0), + ..default() + } +} \ No newline at end of file