From 80c79ae58c1837296e9022c3b2eee2253d045e79 Mon Sep 17 00:00:00 2001 From: Jan Tennert Date: Mon, 23 Sep 2024 22:03:53 +0200 Subject: [PATCH] even more stuff --- Cargo.lock | 3 + Cargo.toml | 2 +- assets/scenarios/earth_satellites.sim | 851 +++++++++++++++++ assets/scenarios/solar_system.sim | 858 +++++++++++++++++- src/main.rs | 4 +- src/menu.rs | 7 - src/serialization.rs | 9 + src/setup.rs | 101 ++- src/simulation/components/body.rs | 15 +- src/simulation/components/editor.rs | 52 +- src/simulation/components/reset.rs | 7 +- src/simulation/render/star_billboard.rs | 6 +- src/simulation/ui/editor_body_panel.rs | 330 +++++++ src/simulation/ui/mod.rs | 10 +- src/simulation/ui/scenario_selection.rs | 55 +- .../ui/{body_panel.rs => sim_body_panel.rs} | 169 +--- src/simulation/ui/system_panel.rs | 18 +- 17 files changed, 2222 insertions(+), 275 deletions(-) create mode 100644 assets/scenarios/earth_satellites.sim create mode 100644 src/simulation/ui/editor_body_panel.rs rename src/simulation/ui/{body_panel.rs => sim_body_panel.rs} (60%) diff --git a/Cargo.lock b/Cargo.lock index ed5aebb..809ccc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -483,12 +483,15 @@ dependencies = [ "bevy_asset", "bevy_color", "bevy_core", + "bevy_core_pipeline", "bevy_ecs", "bevy_egui", "bevy_hierarchy", "bevy_log", "bevy_math", + "bevy_pbr", "bevy_reflect", + "bevy_render", "bevy_state", "bevy_time", "bevy_utils", diff --git a/Cargo.toml b/Cargo.toml index 41d6662..44165f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ lto = "thin" bevy = { version = "0.14.2" } bevy_easings = "0.14" #bevy_panorbit_camera = { git = "https://github.com/jan-tennert/bevy_panorbit_camera", rev = "7e3c3f8" } -bevy-inspector-egui = { version = "0.26.0", default-features = false } +bevy-inspector-egui = { version = "0.26.0"} #bevy_mod_picking = "0.15" bevy_egui = "0.29.0" chrono = "0.4.23" diff --git a/assets/scenarios/earth_satellites.sim b/assets/scenarios/earth_satellites.sim new file mode 100644 index 0000000..6b2bddb --- /dev/null +++ b/assets/scenarios/earth_satellites.sim @@ -0,0 +1,851 @@ +{ + "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 + }, + "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": "Earth Satellites", + "description": "A scenario with all major satellites orbiting the Earth." +} \ No newline at end of file diff --git a/assets/scenarios/solar_system.sim b/assets/scenarios/solar_system.sim index 26c1045..523febc 100644 --- a/assets/scenarios/solar_system.sim +++ b/assets/scenarios/solar_system.sim @@ -1 +1,857 @@ -{"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},"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": [ + { + "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": "#fc0303", + "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 diff --git a/src/main.rs b/src/main.rs index 191f676..6dde349 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ use bevy::render::RenderPlugin; use bevy::window::{PresentMode, Window, WindowPlugin}; use bevy::DefaultPlugins; use bevy_egui::EguiPlugin; +use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_mod_billboard::plugin::BillboardPlugin; use serialization::SerializationPlugin; @@ -74,9 +75,10 @@ fn main() { ..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/menu.rs b/src/menu.rs index f63856f..95ba338 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -32,7 +32,6 @@ fn despawn_menu( enum MenuButtonType { START, - EDITOR, EXIT } @@ -104,7 +103,6 @@ fn spawn_menu( Label )); button("Start", MenuButtonType::START, parent); - button("Editor", MenuButtonType::EDITOR, parent); button("Exit", MenuButtonType::EXIT, parent); }); *visibility = Visibility::Visible; @@ -159,16 +157,11 @@ fn button_system( Interaction::Pressed => { match button.0 { MenuButtonType::START => { - *sim_type = SimStateType::Simulation; let _ = state.set(SimState::ScenarioSelection); } MenuButtonType::EXIT => { exit.send(AppExit::Success); } - MenuButtonType::EDITOR => { - *sim_type = SimStateType::Editor; - let _ = state.set(SimState::ScenarioSelection); - } } } Interaction::Hovered => { diff --git a/src/serialization.rs b/src/serialization.rs index c062509..30e770b 100644 --- a/src/serialization.rs +++ b/src/serialization.rs @@ -48,6 +48,15 @@ pub struct SerializedBodyData { pub rotation_speed: f64, pub axial_tilt: f32, pub simulate: bool, + pub light_source: Option +} + +#[derive(Debug, Deserialize, TypePath, Clone)] +pub struct SerializedLightSource { + pub intensity: f64, + pub range: f64, + pub color: String, + pub enabled: bool } #[derive(Default)] diff --git a/src/setup.rs b/src/setup.rs index b5be9d9..f1b56c6 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,6 +1,7 @@ use bevy::app::{App, Plugin}; use bevy::asset::AssetServer; use bevy::color::Color::Hsla; +use bevy::color::palettes::css::WHITE; use bevy::core::Name; use bevy::core_pipeline::bloom::BloomSettings; use bevy::core_pipeline::Skybox; @@ -14,52 +15,36 @@ use bevy::scene::Scene; use bevy::text::{JustifyText, TextSection, TextStyle}; use bevy_mod_billboard::{BillboardLockAxisBundle, BillboardTextBundle}; use crate::simulation::components::apsis::ApsisBody; -use crate::simulation::components::body::{BodyBundle, BodyChildren, BodyParent, Moon, OrbitSettings, Planet, SceneEntity, SceneHandle, Star}; +use crate::simulation::components::body::{BodyBundle, BodyChildren, BodyParent, LightSource, Moon, OrbitSettings, Planet, SceneEntity, SceneHandle, Star}; use crate::simulation::components::camera::PanOrbitCamera; use crate::constants::M_TO_UNIT; use crate::simulation::loading::LoadingState; use crate::simulation::components::selection::SelectedEntity; use crate::serialization::{SerializedBody, SerializedVec, SimulationData}; +use crate::simulation::components::editor::CreateBodyType; use crate::simulation::SimState; use crate::simulation::render::skybox::Cubemap; use crate::simulation::render::star_billboard::StarBillboard; +use crate::simulation::ui::scenario_selection::SelectedScenario; 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(OnEnter(SimState::Loading), load_bodies) .add_systems(Update, setup_planets.run_if(in_state(SimState::Loading))); } } -#[derive(Resource, Default)] -pub struct BodiesHandle { - - handle: Handle, - pub spawned: bool - -} - #[derive(Resource, Default)] pub struct StartingTime(pub i64); -pub fn load_bodies( - assets: Res, - mut bodies_handle: ResMut -) { - // let bodies = Bodies::all(); - bodies_handle.handle = assets.load("scenarios/solar_system.sim"); -} - pub fn setup_planets( mut commands: Commands, assets: Res, - mut bodies_handle: ResMut, + mut selected_scenario: ResMut, bodies_asset: ResMut>, mut starting_time: ResMut, mut loading_state: ResMut, @@ -67,11 +52,11 @@ pub fn setup_planets( mut meshes: ResMut>, mut materials: ResMut>, ) { - if bodies_handle.spawned { + if selected_scenario.spawned { return; } let mut total_count = 0; - let bodies = bodies_asset.get(&bodies_handle.handle); + let bodies = bodies_asset.get(&selected_scenario.handle); if bodies.cloned().is_none() { return; } @@ -93,20 +78,29 @@ pub fn setup_planets( //planets vector for adding BodyChildren later let mut planets: Vec = vec![]; - star.insert(PointLightBundle { - point_light: PointLight { - color: Color::rgba(1.0, 1.0, 1.0, 1.0), - intensity: 15000000000000.0, - shadows_enabled: true, - range: 30000000000000000.0, - radius: 1000000000000000.0, - ..default() - }, - ..default() - }); + let mut star_color = WHITE.into(); + if let Some(source) = &entry.data.light_source { + star.with_children(|parent| { + star_color = Srgba::hex(&source.color).unwrap().into(); + parent.spawn(PointLightBundle { + point_light: PointLight { + color: star_color, + intensity: (source.intensity * M_TO_UNIT.powf(2.)) as f32, + shadows_enabled: true, + range: (source.range * M_TO_UNIT) as f32, //TODO: make this a variable + radius: (entry.data.diameter / 2.0 * M_TO_UNIT) as f32, + ..default() + }, + visibility: if source.enabled { Visibility::Visible } else { Visibility::Hidden }, + ..default() + }).insert(LightSource(star_id)); + }); + } + let srgb = star_color.to_srgba(); + star_color = Srgba::rgb(srgb.red * 30.0, srgb.green * 30.0, srgb.blue * 30.0).into(); //add the star's components - apply_body(BodyBundle::from(entry.clone()), Star::default(), &assets, &mut star, &mut meshes, &mut materials, calculate_hue(s_index as f32, stars as f32), true); + apply_body(BodyBundle::from(entry.clone()), CreateBodyType::Star, &assets, &mut star, &mut meshes, &mut materials, calculate_hue(s_index as f32, stars as f32), star_color); //planet count in star system for coloring later let planet_count = entry.children.iter().filter(|p| p.data.simulate).count(); @@ -132,7 +126,7 @@ pub fn setup_planets( let de_planet_entry = *planet_entry; //add the planet's components - apply_body(BodyBundle::from(de_planet_entry.clone()), Planet, &assets, &mut planet, &mut meshes, &mut materials,calculate_hue(p_index as f32, planet_count as f32), false); + apply_body(BodyBundle::from(de_planet_entry.clone()), CreateBodyType::Planet, &assets, &mut planet, &mut meshes, &mut materials,calculate_hue(p_index as f32, planet_count as f32), WHITE.into()); //for the tree-based ui later planets.push(planet_id); @@ -156,7 +150,7 @@ pub fn setup_planets( moons.push(moon.id()); //add the moon's components - apply_body(BodyBundle::from(moon_entry.clone()), Moon, &assets, &mut moon, &mut meshes, &mut materials, calculate_hue(m_index as f32, moon_count as f32), false); + apply_body(BodyBundle::from(moon_entry.clone()), CreateBodyType::Moon, &assets, &mut moon, &mut meshes, &mut materials, calculate_hue(m_index as f32, moon_count as f32), WHITE.into()); moon.insert(BodyParent(planet_id)); } planet.insert(BodyParent(star_id)); @@ -164,7 +158,7 @@ pub fn setup_planets( } star.insert(BodyChildren(planets)); } - bodies_handle.spawned = true; + selected_scenario.spawned = true; loading_state.loaded_bodies = true; loading_state.total_bodies = total_count as i32; } @@ -195,26 +189,39 @@ fn serialized_vec_to_vec( pub fn apply_body( bundle: BodyBundle, - body_type: impl Bundle, + body_type: CreateBodyType, assets: &Res, entity: &mut EntityCommands, meshes: &mut ResMut>, materials: &mut ResMut>, hue: f32, - is_star: bool, + star_color: Color ) { let asset_handle: Handle = assets.load(bundle.model_path.clone().0); let color: Color = Hsva::new(hue, 1.0, 0.5, 1.0).into(); entity.insert(bundle.clone()); - entity.insert(body_type); + match body_type { + CreateBodyType::Moon => { + entity.insert(Moon); + } + CreateBodyType::Planet => { + entity.insert(Planet); + } + CreateBodyType::Star => { + entity.insert(Star { + use_imposter: true, + }); + } + } entity.insert(OrbitSettings { color, ..default() }); - if !is_star { + if body_type != CreateBodyType::Star { entity.insert(ApsisBody::default()); } let mut scene_entity_id = None; + let id = &entity.id(); entity.with_children(|parent| { scene_entity_id = Some(spawn_scene( @@ -229,12 +236,14 @@ pub fn apply_body( parent ); - if is_star { + if body_type == CreateBodyType::Star { spawn_imposter( bundle.clone(), parent, meshes, - materials + materials, + star_color, + *id, ); } }); @@ -246,14 +255,16 @@ fn spawn_imposter( parent: &mut ChildBuilder, meshes: &mut ResMut>, materials: &mut ResMut>, + color: Color, + parent_id: Entity, ) { parent.spawn(PbrBundle { mesh: meshes.add(Circle::new(bundle.diameter.num * 3.0)), - material: materials.add(Color::from(Srgba::rgb(30.0, 30.0, 0.0))), + material: materials.add(color), visibility: Visibility::Hidden, ..default() }) - .insert(StarBillboard) + .insert(StarBillboard(parent_id)) .insert(Name::new(format!("{} Imposter Billboard", bundle.name))); } diff --git a/src/simulation/components/body.rs b/src/simulation/components/body.rs index 71bfa3e..9cb546b 100644 --- a/src/simulation/components/body.rs +++ b/src/simulation/components/body.rs @@ -78,15 +78,6 @@ impl Default for OrbitSettings { } -#[derive(Component, Reflect, Clone, Default)] -pub struct LightSource { - pub intensity: f32, - pub shadows_enabled: bool, - pub range: f32, - pub radius: f32, - pub enabled: bool -} - #[derive(Component, Reflect, Clone, Default)] pub struct SimPosition(pub DVec3); @@ -105,12 +96,15 @@ pub struct SceneHandle(pub Handle, pub Entity); #[derive(Component, Reflect, Clone)] pub struct SceneEntity; +#[derive(Component, Reflect, Clone)] +pub struct LightSource(pub Entity); + //Types: #[derive(Component, Reflect, Clone, Default)] pub struct Star { pub use_imposter: bool, - + } #[derive(Component, Reflect, Clone, Default)] @@ -130,7 +124,6 @@ pub struct BodyBundle { pub scale: Scale, pub name: Name, pub model_path: ModelPath, - pub light: LightSource, pub orbit: OrbitSettings, pub rotation_speed: RotationSpeed, pub axial_tilt: AxialTilt, diff --git a/src/simulation/components/editor.rs b/src/simulation/components/editor.rs index 54817b0..67d8eef 100644 --- a/src/simulation/components/editor.rs +++ b/src/simulation/components/editor.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use bevy::app::{App, Plugin}; +use bevy::color::palettes::css::WHITE; use bevy::ecs::observer::TriggerTargets; use bevy::ecs::system::SystemId; use bevy::prelude::{AssetServer, Assets, Bundle, Commands, Entity, FromWorld, IntoSystemConfigs, Local, Mesh, OnEnter, Query, Res, ResMut, Resource, SpatialBundle, StandardMaterial, Transform, Update, Vec3, World}; @@ -28,7 +29,15 @@ pub struct EditorSystems(pub HashMap); #[derive(Resource, Default, PartialOrd, PartialEq, Eq, Clone, Debug)] pub struct CreateBodyState { pub parent: Option, - pub create_as_moon: bool, //Or planet + pub body_type: CreateBodyType, +} + +#[derive(Default, Clone, Debug, Eq, PartialEq, PartialOrd)] +pub enum CreateBodyType { + #[default] + Moon, + Planet, + Star } impl FromWorld for EditorSystems { @@ -86,32 +95,23 @@ fn create_empty_body( mut index: Local ) { let mut entity_commands = commands.spawn(SpatialBundle::default()); - if create_body_state.create_as_moon { - apply_body( - BodyBundle::empty(*index), - Moon, - &mut assets, - &mut entity_commands, - &mut meshes, - &mut materials, - 0.0, - false, - ); - } else { - apply_body( - BodyBundle::empty(*index), - Planet, - &mut assets, - &mut entity_commands, - &mut meshes, - &mut materials, - 0.0, - false, - ); + apply_body( + BodyBundle::empty(*index), + create_body_state.body_type.clone(), + &mut assets, + &mut entity_commands, + &mut meshes, + &mut materials, + 0.0, + WHITE.into() + ); + if create_body_state.body_type != CreateBodyType::Moon { entity_commands.insert(BodyChildren(Vec::new())); - }; - entity_commands.insert(BodyParent(create_body_state.parent.unwrap())); - parent_query.get_mut(create_body_state.parent.unwrap()).unwrap().0.push(entity_commands.id()); + } + if let Some(parent) = create_body_state.parent { + entity_commands.insert(BodyParent(parent)); + parent_query.get_mut(parent).unwrap().0.push(entity_commands.id()); + } selected_entity.entity = Some(entity_commands.id()); create_body_state.parent = None; *index += 1; diff --git a/src/simulation/components/reset.rs b/src/simulation/components/reset.rs index 70cc87f..ddc637e 100644 --- a/src/simulation/components/reset.rs +++ b/src/simulation/components/reset.rs @@ -1,6 +1,6 @@ use bevy::prelude::{App, Camera, Commands, DespawnRecursiveExt, Entity, NextState, OnEnter, OnExit, Plugin, Query, ResMut, Vec3, With, Without}; -use crate::{constants::{DEFAULT_SUB_STEPS, DEFAULT_TIMESTEP}, setup::BodiesHandle}; +use crate::{constants::{DEFAULT_SUB_STEPS, DEFAULT_TIMESTEP}}; use crate::simulation::components::body::Mass; use crate::simulation::components::camera::{PanOrbitCamera, DEFAULT_CAM_RADIUS}; use crate::simulation::components::physics::{Pause, SubSteps}; @@ -9,6 +9,7 @@ use crate::simulation::components::speed::Speed; use crate::simulation::loading::LoadingState; use crate::simulation::SimState; use crate::simulation::ui::{SimTime, StepType, UiState}; +use crate::simulation::ui::scenario_selection::SelectedScenario; pub struct ResetPlugin; @@ -29,7 +30,7 @@ fn clean_up( mut pause: ResMut, mut sim_time: ResMut, mut selected_entity: ResMut, - mut bodies: ResMut, + mut scenario: ResMut, mut sub_steps: ResMut, mut loading_state: ResMut, mut commands: Commands, @@ -44,7 +45,7 @@ fn clean_up( sim_time.0 = 0.0; selected_entity.entity = None; sub_steps.0 = DEFAULT_SUB_STEPS; - bodies.spawned = false; + scenario.spawned = false; loading_state.reset(); let mut cam = camera.single_mut(); cam.focus = Vec3::ZERO; diff --git a/src/simulation/render/star_billboard.rs b/src/simulation/render/star_billboard.rs index defd53e..438fd12 100644 --- a/src/simulation/render/star_billboard.rs +++ b/src/simulation/render/star_billboard.rs @@ -1,6 +1,6 @@ use bevy::app::{App, Plugin, Update}; use bevy::math::Vec3; -use bevy::prelude::{Camera, Children, Component, in_state, IntoSystemConfigs, Parent, Query, Transform, Visibility, With, Without}; +use bevy::prelude::{Camera, Children, Component, in_state, IntoSystemConfigs, Parent, Query, Transform, Visibility, With, Without, Entity, Color}; use bevy::scene::SceneInstance; use crate::simulation::components::body::Star; @@ -21,8 +21,8 @@ impl Plugin for StarBillboardPlugin { } -#[derive(Component, Debug, Default)] -pub struct StarBillboard; +#[derive(Component, Debug)] +pub struct StarBillboard(pub Entity); fn change_sun_renderer( camera: Query<(&Transform, &Camera), (Without, Without)>, diff --git a/src/simulation/ui/editor_body_panel.rs b/src/simulation/ui/editor_body_panel.rs new file mode 100644 index 0000000..655d3f0 --- /dev/null +++ b/src/simulation/ui/editor_body_panel.rs @@ -0,0 +1,330 @@ +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}; +use crate::constants::{G, M_TO_AU, M_TO_UNIT}; +use crate::simulation::components::selection::SelectedEntity; +use crate::unit::{format_length, format_seconds}; +use bevy::core::Name; +use bevy::math::DVec3; +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 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::UiState; + +#[derive(Debug, Default, Clone, Resource)] +pub struct EditorPanelState { + pub entity: Option, + pub new_name: String, + pub new_position: DVec3, + pub new_velocity: DVec3, + pub new_mass: f64, + pub new_diameter: f32, + pub new_rotation_speed: f64, + pub new_axial_tilt: f32, + pub new_model_path: String, + pub show_delete_confirm: bool, + pub new_light_settings: Option +} + +#[derive(Debug, Default, Clone, Copy)] +pub struct LightSettings { + pub color: Color, + pub intensity: f64, + pub range: f64, + pub enabled: bool, +} + +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), With>, + scene_query: Query>, + mut state: ResMut, + mut commands: Commands, + systems: Res, + assets: Res, + mut light_query: Query<(&mut PointLight, &LightSource, &mut Visibility)>, + mut billboards: Query<(&StarBillboard, &mut Handle)>, + mut materials: ResMut>, +) { + if egui_context.try_ctx_mut().is_none() { + return; + } + 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)); + let mut billboard_material = billboards.iter_mut().find(|(b, _)| b.0 == entity).map(|(_, m)| m.clone()); + 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); + } + } else { + state.entity = None; + } +} + +fn initialize_state( + state: &mut EditorPanelState, + s_entity: Entity, + name: &Name, + pos: &SimPosition, + vel: &Velocity, + mass: &Mass, + diameter: &Diameter, + rotation_speed: &RotationSpeed, + tilt: &AxialTilt, + model_path: &ModelPath, + light: Option<&(Mut, &LightSource, Mut)> +) { + *state = EditorPanelState { + entity: Some(s_entity), + new_name: name.to_string(), + new_position: pos.0, + new_velocity: vel.0, + new_mass: mass.0, + new_diameter: (diameter.num / 1000.0) / M_TO_UNIT as f32, + new_rotation_speed: rotation_speed.0, + new_axial_tilt: tilt.num, + new_model_path: model_path.cleaned(), + show_delete_confirm: false, + new_light_settings: light.map(|(light, _, visible)| LightSettings { + color: (*light).color, + intensity: (*light).intensity as f64 / M_TO_UNIT.powf(2.), + enabled: **visible == Visibility::Visible, + range: (*light).range as f64 / M_TO_UNIT, + }) + }; +} + +fn display_body_panel( + ctx: &mut Context, + state: &mut EditorPanelState, + name: &mut Name, + pos: &mut SimPosition, + vel: &mut Velocity, + mass: &mut Mass, + diameter: &mut Diameter, + rotation_speed: &mut RotationSpeed, + tilt: &mut AxialTilt, + model_path: &mut ModelPath, + scene: &mut SceneHandle, + commands: &mut Commands, + systems: &Res, + assets: &Res, + light: Option<(Mut, &LightSource, Mut)>, + scene_query: Query>, + billboard_material: Option<&mut Handle>, + materials: &mut ResMut> +) { + egui::SidePanel::right("body_panel") + .resizable(true) + .show(ctx, |ui| { + ScrollArea::vertical() + .auto_shrink(true) + .show(ui, |ui| { + 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); + }); + }); +} + +fn display_body_properties(ui: &mut egui::Ui, state: &mut EditorPanelState) { + ui.horizontal(|ui| { + ui.label("Name"); + ui.text_edit_singleline(&mut state.new_name); + }); + ui.horizontal(|ui| { + ui.label("Model Path"); + ui.text_edit_singleline(&mut state.new_model_path); + }); + ui.horizontal(|ui| { + ui.label("Mass (kg)"); + ui.add(egui::DragValue::new(&mut state.new_mass)); + }); + ui.horizontal(|ui| { + ui.label("Diameter (km)"); + ui.add(egui::DragValue::new(&mut state.new_diameter)); + }); + ui.horizontal(|ui| { + ui.label("Rotation Speed (min/rotation)"); + ui.add(egui::DragValue::new(&mut state.new_rotation_speed)); + }); + ui.horizontal(|ui| { + 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); +} + +fn display_light_source(ui: &mut egui::Ui, state: &mut EditorPanelState) { + ui.heading("Light Source"); + if let Some(mut light) = state.new_light_settings.as_mut() { + ui.horizontal(|ui| { + ui.label("Intensity (Lm)"); + ui.add(egui::DragValue::new(&mut light.intensity)); + }); + ui.horizontal(|ui| { + ui.label("Range (m)"); + ui.add(egui::DragValue::new(&mut light.range)); + }); + ui.horizontal(|ui| { + ui.label("Color"); + let color = light.color.to_srgba(); + let mut rgb = [color.red, color.green, color.blue]; + ui.color_edit_button_rgb(&mut rgb); + light.color = Srgba::rgb(rgb[0], rgb[1], rgb[2]).into(); + }); + ui.checkbox(&mut light.enabled, "Enabled"); + } else { + if ui.button("Add Light Source").on_hover_text("Add a light source to the body").clicked() { + state.new_light_settings = Some(LightSettings { + color: Color::WHITE, + intensity: 100.0, + range: 100.0, + enabled: true, + }); + } + } +} + +fn display_bottom_buttons( + ui: &mut egui::Ui, + state: &mut EditorPanelState, + name: &mut Name, + pos: &mut SimPosition, + vel: &mut Velocity, + mass: &mut Mass, + diameter: &mut Diameter, + rotation_speed: &mut RotationSpeed, + tilt: &mut AxialTilt, + model_path: &mut ModelPath, + scene: &mut SceneHandle, + commands: &mut Commands, + systems: &Res, + assets: &Res, + light: Option<(Mut, &LightSource, Mut)>, + scene_query: Query>, + billboard_material: Option<&mut Handle>, + materials: &mut ResMut> +) { + 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); + } + if ui.button("Reset").on_hover_text("Reset to original values").clicked() { + // Reset logic here + } + if state.show_delete_confirm { + ui.label("Are you sure?"); + if ui.button("Yes").on_hover_text("Delete selected body").clicked() { + commands.entity(state.entity.unwrap()).despawn_recursive(); + state.show_delete_confirm = false; + } + if ui.button("No").on_hover_text("Cancel deletion").clicked() { + state.show_delete_confirm = false; + } + } else { + if ui.button("Delete").on_hover_text("Delete selected body").clicked() { + state.show_delete_confirm = true; + } + } + }); + ui.separator(); + }); +} + +fn apply_changes( + state: &mut EditorPanelState, + name: &mut Name, + pos: &mut SimPosition, + vel: &mut Velocity, + mass: &mut Mass, + diameter: &mut Diameter, + rotation_speed: &mut RotationSpeed, + tilt: &mut AxialTilt, + model_path: &mut ModelPath, + scene: &mut SceneHandle, + commands: &mut Commands, + systems: &Res, + assets: &Res, + light: Option<(Mut, &LightSource, Mut)>, + scene_query: Query>, + billboard_material: Option<&mut Handle>, + materials: &mut ResMut> +) { + name.set(state.new_name.clone()); + pos.0 = state.new_position; + vel.0 = state.new_velocity; + mass.0 = state.new_mass; + let new_diameter = state.new_diameter * M_TO_UNIT as f32 * 1000.0; + diameter.applied = new_diameter == diameter.num; + diameter.num = new_diameter; + rotation_speed.0 = state.new_rotation_speed; + let new_tilt = state.new_axial_tilt; + tilt.applied = new_tilt == tilt.num; + tilt.num = new_tilt; + if let Some((mut light, _, mut visible)) = light { + light.color = state.new_light_settings.as_ref().unwrap().color; + if let Some(material) = billboard_material { + let color = light.color.to_srgba(); + let mut rgb = [color.red, color.green, color.blue]; + let new_color: Color = Srgba::rgb(rgb[0] * 30.0, rgb[1] * 30.0, rgb[2] * 30.0).into(); + let mut material = materials.get_mut(material).unwrap(); + material.base_color = new_color; + } + light.intensity = (state.new_light_settings.as_ref().unwrap().intensity * M_TO_UNIT.powf(2.)) as f32; + light.range = (state.new_light_settings.as_ref().unwrap().range * M_TO_UNIT) as f32; + *visible = if state.new_light_settings.as_ref().unwrap().enabled { + Visibility::Visible + } else { + Visibility::Hidden + }; + } else if let Some(light) = state.new_light_settings.as_ref() { + commands.entity(state.entity.unwrap()).with_children(|parent| { + parent.spawn(LightSource(state.entity.unwrap())) + .insert(PointLightBundle { + point_light: PointLight { + color: light.color, + intensity: (light.intensity * M_TO_UNIT.powf(2.)) as f32, + range: (light.range * M_TO_UNIT) as f32, + radius: new_diameter / 2.0, + ..default() + }, + visibility: if light.enabled { + Visibility::Visible + } else { + Visibility::Hidden + }, + ..Default::default() + }); + }); + } + if model_path.cleaned() != state.new_model_path { + *model_path = ModelPath::from_cleaned(state.new_model_path.as_str()); + 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(); + commands.entity(state.entity.unwrap()).with_children(|parent| { + scene.1 = spawn_scene( + asset_handle, + state.new_name.as_str(), + parent + ); + }); + + diameter.aabb = None; + } + commands.run_system(systems.0[EditorSystemType::UPDATE_POSITIONS]); + commands.run_system(systems.0[EditorSystemType::UPDATE_DIAMETER]); + commands.run_system(systems.0[EditorSystemType::UPDATE_TILT]); +} \ No newline at end of file diff --git a/src/simulation/ui/mod.rs b/src/simulation/ui/mod.rs index f0727b9..b5d094f 100644 --- a/src/simulation/ui/mod.rs +++ b/src/simulation/ui/mod.rs @@ -1,9 +1,10 @@ mod bottom_bar; pub mod system_panel; -mod body_panel; +mod editor_body_panel; pub mod debug_window; -mod components; -mod scenario_selection; +pub mod components; +pub mod scenario_selection; +mod sim_body_panel; use bevy::{ core_pipeline::Skybox, @@ -46,9 +47,10 @@ use crate::simulation::render::skybox::Cubemap; use crate::simulation::ui::bottom_bar::bottom_bar; use crate::simulation::ui::system_panel::system_panel; use crate::simulation::components::speed::Speed; -use crate::simulation::ui::body_panel::{editor_body_panel, sim_body_panel, EditorPanelState}; +use crate::simulation::ui::editor_body_panel::{editor_body_panel, EditorPanelState}; use crate::simulation::ui::debug_window::DebugPlugin; use crate::simulation::ui::scenario_selection::ScenarioSelectionPlugin; +use crate::simulation::ui::sim_body_panel::sim_body_panel; use crate::unit::format_seconds; 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 c9716e0..3ced148 100644 --- a/src/simulation/ui/scenario_selection.rs +++ b/src/simulation/ui/scenario_selection.rs @@ -1,11 +1,12 @@ use bevy::app::{App, Plugin, Update}; use bevy::asset::LoadedFolder; -use bevy::prelude::{in_state, AssetServer, Assets, Commands, Handle, IntoSystemConfigs, OnEnter, OnExit, Res, ResMut, Resource}; -use bevy_egui::egui::CentralPanel; +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, EguiContexts}; use image::load; use crate::serialization::SimulationData; -use crate::simulation::SimState; +use crate::simulation::{SimState, SimStateType}; pub struct ScenarioSelectionPlugin; @@ -13,6 +14,7 @@ impl Plugin for ScenarioSelectionPlugin { fn build(&self, app: &mut App) { app + .init_resource::() .add_systems(OnEnter(SimState::ScenarioSelection), load_scenarios) .add_systems(Update, spawn_menu.run_if(in_state(SimState::ScenarioSelection))); } @@ -21,6 +23,14 @@ impl Plugin for ScenarioSelectionPlugin { #[derive(Resource)] pub struct ScenarioFolder(pub Handle); +#[derive(Resource, Default)] +pub struct SelectedScenario { + + pub handle: Handle, + pub spawned: bool + +} + fn load_scenarios( assets: Res, mut commands: Commands @@ -30,14 +40,18 @@ fn load_scenarios( } fn spawn_menu( - mut commands: Commands, mut egui_context: EguiContexts, scenario_folder: Res, folders: Res>, bodies_asset: ResMut>, + assets: Res, + mut selected_scenario: ResMut, + mut sim_state: ResMut>, + mut images: Local>, + mut sim_state_type: ResMut ) { CentralPanel::default() - .show(&egui_context.ctx_mut(), |ui| { + .show(&egui_context.ctx_mut().clone(), |ui| { ui.heading("Scenario Selection"); ui.separator(); ui.label("Select a scenario to load:"); @@ -46,16 +60,39 @@ fn spawn_menu( for handle in loaded_folder.handles.clone() { let path = handle.path().unwrap().path(); let file_name = path.file_name().unwrap().to_str().unwrap(); - if let Some(scenario) = bodies_asset.get(&handle.typed()) { + if !file_name.ends_with(".sim") { + continue; + } + let image_handle: TextureId = if images.get(file_name).is_some() { + images.get(file_name).unwrap().clone() + } else { + let handle: Handle = assets.load(format!("scenarios/{}", file_name.replace("sim", "png"))); + let t_id = egui_context.add_image(handle); + images.insert(file_name.to_string(), t_id); + t_id + }; + let typed_handle: Handle = handle.typed(); + if let Some(scenario) = bodies_asset.get(&typed_handle) { let title = &scenario.title; let description = &scenario.description; ui.horizontal(|ui| { + ui.image(egui::load::SizedTexture::new(image_handle, [100.0, 100.0])); ui.vertical(|ui| { ui.heading(title); ui.label(description); - if ui.button("Load").clicked() { - // Load scenario - } + ui.with_layout(Layout::left_to_right(Align::BOTTOM), |ui| { + let loading_button = ui.button("Load").on_hover_text("Load scenario"); + let edit_button = ui.button("Edit").on_hover_text("Edit scenario in editor"); + if loading_button.clicked() { + selected_scenario.handle = typed_handle; + sim_state.set(SimState::Loading); + *sim_state_type = SimStateType::Simulation; + } else if edit_button.clicked() { + selected_scenario.handle = typed_handle; + sim_state.set(SimState::Loading); + *sim_state_type = SimStateType::Editor; + } + }); }); }); ui.separator(); diff --git a/src/simulation/ui/body_panel.rs b/src/simulation/ui/sim_body_panel.rs similarity index 60% rename from src/simulation/ui/body_panel.rs rename to src/simulation/ui/sim_body_panel.rs index 44b4aaf..768dd80 100644 --- a/src/simulation/ui/body_panel.rs +++ b/src/simulation/ui/sim_body_panel.rs @@ -1,164 +1,15 @@ -use bevy::asset::AssetServer; -use crate::simulation::components::apsis::ApsisBody; -use crate::simulation::components::body::{AxialTilt, BodyChildren, BodyParent, Diameter, Mass, ModelPath, OrbitSettings, RotationSpeed, Scale, SceneEntity, SceneHandle, SimPosition, Velocity}; -use crate::constants::{G, M_TO_AU, M_TO_UNIT}; -use crate::simulation::components::selection::SelectedEntity; -use crate::unit::{format_length, format_seconds}; +use bevy::color::Srgba; use bevy::core::Name; -use bevy::math::DVec3; -use bevy::prelude::{BuildChildren, Camera, Commands, DespawnRecursiveExt, Entity, Handle, Mut, Query, Res, ResMut, Resource, Scene, Srgba, Transform, Vec3, With, Without}; -use bevy_egui::egui::{Align, Layout, RichText, ScrollArea}; +use bevy::math::Vec3; +use bevy::prelude::{Camera, Commands, DespawnRecursiveExt, Entity, Mut, Query, Res, ResMut, Transform, Without}; use bevy_egui::{egui, EguiContexts}; -use crate::setup::spawn_scene; -use crate::simulation::components::editor::{EditorSystemType, EditorSystems}; -use crate::simulation::ui::components::vector_field; +use bevy_egui::egui::{RichText, ScrollArea}; +use crate::constants::{G, M_TO_AU, M_TO_UNIT}; +use crate::simulation::components::apsis::ApsisBody; +use crate::simulation::components::body::{BodyChildren, BodyParent, Diameter, Mass, OrbitSettings, RotationSpeed, Scale, SimPosition, Velocity}; +use crate::simulation::components::selection::SelectedEntity; use crate::simulation::ui::UiState; - -#[derive(Debug, Default, Clone, Resource)] -pub struct EditorPanelState { - pub entity: Option, - pub new_name: String, - pub new_position: DVec3, - pub new_velocity: DVec3, - pub new_mass: f64, - pub new_diameter: f32, - pub new_rotation_speed: f64, - pub new_axial_tilt: f32, - pub new_model_path: String, - pub show_delete_confirm: bool, -} - -impl EditorPanelState { - - pub fn new(entity: Entity, name: String, position: DVec3, velocity: DVec3, mass: f64, diameter: f32, rotation_speed: f64, axial_tilt: f32, model_path: String) -> Self { - EditorPanelState { - entity: Some(entity), - new_name: name, - new_position: position, - new_velocity: velocity, - new_mass: mass, - new_diameter: diameter, - new_rotation_speed: rotation_speed, - new_axial_tilt: axial_tilt, - new_model_path: model_path, - show_delete_confirm: false, - } - } - -} - -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), With>, - mut scene_query: Query>, - mut state: ResMut, - mut commands: Commands, - systems: Res, - assets: Res, -) { - if egui_context.try_ctx_mut().is_none() { - return; - } - 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) { - if(state.entity.is_none() || state.entity.unwrap() != s_entity) { - *state = EditorPanelState::new(s_entity, name.to_string(), pos.0, vel.0, mass.0, (diameter.num / 1000.0) / M_TO_UNIT as f32, rotation_speed.0, tilt.num, model_path.cleaned()); - } - egui::SidePanel::right("body_panel") - // .max_width(250.0) - .resizable(true) - .show(egui_context.ctx_mut(), |ui| { - ScrollArea::vertical() - .auto_shrink(true) - .show(ui, |ui| { - ui.heading("Body"); - ui.horizontal(|ui| { - ui.label("Name"); - ui.text_edit_singleline(&mut state.new_name); - }); - ui.horizontal(|ui| { - ui.label("Model Path"); - ui.text_edit_singleline(&mut state.new_model_path); - }); - ui.horizontal(|ui| { - ui.label("Mass (kg)"); - ui.add(egui::DragValue::new(&mut state.new_mass)); - }); - ui.horizontal(|ui| { - ui.label("Diameter (km)"); - ui.add(egui::DragValue::new(&mut state.new_diameter)); - }); - ui.horizontal(|ui| { - ui.label("Rotation Speed (min/rotation)"); - ui.add(egui::DragValue::new(&mut state.new_rotation_speed)); - }); - ui.horizontal(|ui| { - 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); - ui.with_layout(Layout::bottom_up(Align::Center), |ui| { - ui.horizontal(|ui| { - if ui.button("Apply").on_hover_text("Apply changes").clicked() { - name.set(state.new_name.clone()); - pos.0 = state.new_position; - vel.0 = state.new_velocity; - mass.0 = state.new_mass; - let new_diameter = state.new_diameter * M_TO_UNIT as f32 * 1000.0; - diameter.applied = new_diameter == diameter.num; - diameter.num = new_diameter; - rotation_speed.0 = state.new_rotation_speed; - let new_tilt = state.new_axial_tilt; - tilt.applied = new_tilt == tilt.num; - tilt.num = new_tilt; - if model_path.cleaned() != state.new_model_path { - *model_path = ModelPath::from_cleaned(state.new_model_path.as_str()); - 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(); - commands.entity(entity).with_children(|parent| { - scene.1 = spawn_scene( - asset_handle, - state.new_name.as_str(), - parent - ); - }); - - diameter.aabb = None; - } - commands.run_system(systems.0[EditorSystemType::UPDATE_POSITIONS]); - commands.run_system(systems.0[EditorSystemType::UPDATE_DIAMETER]); - commands.run_system(systems.0[EditorSystemType::UPDATE_TILT]); - } - if ui.button("Reset").on_hover_text("Reset to original values").clicked() { - *state = EditorPanelState::new(s_entity, name.to_string(), pos.0, vel.0, mass.0, (diameter.num / 1000.0) / M_TO_UNIT as f32, rotation_speed.0, tilt.num, model_path.cleaned()); - } - if state.show_delete_confirm { - ui.label("Are you sure?"); - if ui.button("Yes").on_hover_text("Delete selected body").clicked() { - commands.entity(entity).despawn_recursive(); - state.show_delete_confirm = false; - } - if ui.button("No").on_hover_text("Cancel deletion").clicked() { - state.show_delete_confirm = false; - } - } else { - if ui.button("Delete").on_hover_text("Delete selected body").clicked() { - state.show_delete_confirm = true; - } - } - }); - ui.separator(); - }); - }); - }); - } - } else { - state.entity = None; - } -} +use crate::unit::{format_length, format_seconds}; pub fn sim_body_panel( mut egui_context: EguiContexts, @@ -376,4 +227,4 @@ pub fn sim_body_panel( }); } } -} +} \ No newline at end of file diff --git a/src/simulation/ui/system_panel.rs b/src/simulation/ui/system_panel.rs index cbb040f..16d9668 100644 --- a/src/simulation/ui/system_panel.rs +++ b/src/simulation/ui/system_panel.rs @@ -1,7 +1,7 @@ use crate::simulation::components::billboard::BillboardSettings; use crate::simulation::components::body::{BodyChildren, Moon, Planet, Star}; use crate::simulation::components::camera::PanOrbitCamera; -use crate::simulation::components::editor::{CreateBodyState, EditorSystemType, EditorSystems}; +use crate::simulation::components::editor::{CreateBodyState, CreateBodyType, EditorSystemType, EditorSystems}; use crate::simulation::components::orbit_lines::OrbitOffset; use crate::simulation::components::selection::SelectedEntity; use crate::simulation::render::skybox::Cubemap; @@ -71,7 +71,7 @@ fn body_tree( default_open: bool, add_body: impl FnOnce(&mut Ui) -> R, show_button: bool, - create_as_moon: bool, + body_type: CreateBodyType ) -> Option { let id = ui.make_persistent_id(name.as_str()); let mut new_create_body = None; @@ -82,7 +82,7 @@ fn body_tree( if show_button && ui.button("+").on_hover_text("Create child").clicked() { new_create_body = Some(CreateBodyState { parent: Some(entity), - create_as_moon, + body_type, }); } }); @@ -133,7 +133,7 @@ pub fn system_panel( } } } - }, show_button, true); + }, show_button, CreateBodyType::Moon); if p_selected && !p_old_selected { system_panel_set.selected_entity.change_entity(p_entity, ctrl_hold) } @@ -143,7 +143,7 @@ pub fn system_panel( } } } - }, show_button, false); + }, show_button, CreateBodyType::Planet); if s_selected && !s_old_selected { system_panel_set.selected_entity.change_entity(s_entity, ctrl_hold) } @@ -152,6 +152,14 @@ pub fn system_panel( system_panel_set.commands.run_system(system_panel_set.systems.0[EditorSystemType::CREATE_BODY]); } } + if ui.button("+").on_hover_text("Create new major body").clicked() { + *system_panel_set.create_body_state = CreateBodyState { + parent: None, + body_type: CreateBodyType::Star, + }; + system_panel_set.commands.run_system(system_panel_set.systems.0[EditorSystemType::CREATE_BODY]); + } + ui.separator(); ui.heading("Options"); ui.checkbox(&mut camera.hdr, "HDR/Bloom"); let skybox_enabled = skybox.is_some();