From 89820ef9e12bec4516ff843ffe10cfc9ce30017e Mon Sep 17 00:00:00 2001 From: Jan Tennert Date: Sun, 6 Oct 2024 19:43:20 +0200 Subject: [PATCH] work on shapes, rotations --- scenarios/earth_satellites.sim | 2 +- scenarios/solar_system.sim | 2 +- scenarios/solar_system_copy.sim | 2 +- src/main.rs | 5 +- src/simulation/asset/default_values.rs | 26 +++++++ src/simulation/asset/mod.rs | 1 + src/simulation/asset/serialization.rs | 62 +++++++++++++---- src/simulation/components/anise.rs | 22 +++++- src/simulation/components/billboard.rs | 82 ++++++++++++++-------- src/simulation/components/body.rs | 23 ++++--- src/simulation/components/diameter.rs | 45 ++++++++++-- src/simulation/components/horizons.rs | 7 +- src/simulation/components/rotation.rs | 21 +++--- src/simulation/scenario/save_scenario.rs | 25 ++++--- src/simulation/ui/editor_body_panel.rs | 88 ++++++++++++++++-------- src/simulation/ui/sim_body_panel.rs | 2 +- src/simulation/ui/toast.rs | 10 +++ 17 files changed, 304 insertions(+), 121 deletions(-) create mode 100644 src/simulation/asset/default_values.rs diff --git a/scenarios/earth_satellites.sim b/scenarios/earth_satellites.sim index 1cc1fb8..643fdec 100644 --- a/scenarios/earth_satellites.sim +++ b/scenarios/earth_satellites.sim @@ -1 +1 @@ -{"bodies":[{"children":[{"children":[{"children":[],"data":{"mass":450000.0,"starting_position":{"x":139697751.6768489,"y":-55457691.56188262,"z":26726.49883086234},"starting_velocity":{"x":8.512277308736511,"y":20.73621312430883,"z":-2.743211831320219},"name":"ISS","model_path":"iss.glb","diameter":0.1,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"horizons_id":-1,"light_source":null}},{"children":[],"data":{"mass":10800.0,"starting_position":{"x":139708447.6237727,"y":-55461983.31379145,"z":33786.01008588448},"starting_velocity":{"x":13.95250317957649,"y":32.23801340370306,"z":-4.892445364940268},"name":"Hubble","model_path":"hubble.glb","diameter":0.01,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"horizons_id":-48,"light_source":null}}],"data":{"mass":5.972e24,"starting_position":{"x":139702454.0,"y":-55460536.0,"z":30732.9},"starting_velocity":{"x":10.34793,"y":27.64442411692169,"z":-0.001120445580937712},"name":"Earth","model_path":"earth_4k_2.glb","diameter":12742.0,"rotation_speed":1436.0,"axial_tilt":23.44,"simulate":true,"horizons_id":399,"light_source":null}}],"data":{"mass":1.9885e30,"starting_position":{"x":-982171.6832391358,"y":-655394.8782055749,"z":28787.74341113935},"starting_velocity":{"x":0.01127558914848326,"y":-0.008532815916463004,"z":-0.0001656555243002107},"name":"Sun","model_path":"sun.glb","diameter":1392700.032,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"horizons_id":-1,"light_source":{"intensity":3.75e28,"range":9e30,"color":"#FFFFFF","enabled":true}}}],"starting_time_millis":1725148800000,"title":"Earth Satellites","description":"A scenario with all major satellites orbiting the Earth.","scale":1.0,"timestep":150} \ No newline at end of file +{"bodies":[{"children":[{"children":[{"children":[],"data":{"mass":450000.0,"starting_position":{"x":139697751.6768489,"y":-55457691.56188262,"z":26726.49883086234},"starting_velocity":{"x":8.512277308736511,"y":20.73621312430883,"z":-2.743211831320219},"name":"ISS","model_path":"iss.glb","diameter":0.1,"rotation_speed":0.0,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"children":[],"data":{"mass":10800.0,"starting_position":{"x":139708447.6237727,"y":-55461983.31379145,"z":33786.01008588448},"starting_velocity":{"x":13.95250317957649,"y":32.23801340370306,"z":-4.892445364940268},"name":"Hubble","model_path":"hubble.glb","diameter":0.01,"rotation_speed":0.0,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data":{"mass":5.972e24,"starting_position":{"x":139703169.6031987,"y":-50894516.80238317,"z":-22031976.570581574},"starting_velocity":{"x":10.34755584668519,"y":25.363844384635943,"z":10.995351298282669},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"simulate":true,"naif_id":399,"fixed_body_frame":{"target_id":399,"orientation_id":399},"ellipsoid":{"semi_major_equatorial_radius_km":6378.1366,"semi_minor_equatorial_radius_km":6378.1366,"polar_radius_km":6356.7519},"light_source":null,"rotation_matrix":{"x":{"x":0.9411901831626892,"y":0.3378687798976898,"z":0.0023979549296200275},"y":{"x":-0.3378697335720062,"y":0.9411928653717041,"z":-6.617409326281631e-6},"z":{"x":-0.002259173896163702,"y":-0.000803968112450093,"z":0.9999971389770508}}}}],"data":{"mass":1.9885e30,"starting_position":{"x":-982171.6832391358,"y":-655394.8782055749,"z":28787.74341113935},"starting_velocity":{"x":0.01127558914848326,"y":-0.008532815916463004,"z":-0.0001656555243002107},"name":"Sun","model_path":"sun.glb","diameter":1392700.032,"rotation_speed":0.0,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":{"intensity":3.75e28,"range":9e30,"color":"#FFFFFF","enabled":true},"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data_sets":["pck11.pca","de440s.bsp"],"starting_time_millis":1725148800000,"title":"Earth Satellites","description":"A scenario with all major satellites orbiting the Earth.","scale":1e-7,"timestep":150} \ No newline at end of file diff --git a/scenarios/solar_system.sim b/scenarios/solar_system.sim index c825238..3ced4c9 100644 --- a/scenarios/solar_system.sim +++ b/scenarios/solar_system.sim @@ -1 +1 @@ -{"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":4880.0,"rotation_speed":84480.0,"axial_tilt":0.0,"simulate":true,"horizons_id":199,"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,"horizons_id":299,"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,"horizons_id":-1,"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,"horizons_id":399,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":499,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":599,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":699,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":799,"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,"horizons_id":-1,"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,"horizons_id":899,"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,"horizons_id":999,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":-1,"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,"horizons_id":10,"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true}}}],"starting_time_millis":1696118400000,"title":"Solar System","description":"A scenario with all major bodies and their major moons in the Solar System.","scale":1e-7,"timestep":900} \ 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":4880.0,"rotation_speed":84480.0,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data":{"mass":5.97219e24,"starting_position":{"x":147358586.05329105,"y":17002981.684467822,"z":7404288.410651642},"starting_velocity":{"x":-4.22677,"y":26.9877,"z":11.6975},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"simulate":true,"naif_id":399,"fixed_body_frame":{"target_id":399,"orientation_id":399},"ellipsoid":{"semi_major_equatorial_radius_km":0.0,"semi_minor_equatorial_radius_km":0.0,"polar_radius_km":0.0},"light_source":null,"rotation_matrix":{"x":{"x":0.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":0.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":0.0}}}},{"children":[{"children":[],"data":{"mass":1.0659e16,"starting_position":{"x":-204679122.06151548,"y":-115660039.4768454,"z":-47524649.116718315},"starting_velocity":{"x":14.736714782788324,"y":-14.430709749461556,"z":-7.482596217108307},"name":"Phobos","model_path":"phobos.glb","diameter":22.16,"rotation_speed":0.0,"simulate":true,"naif_id":401,"fixed_body_frame":{"target_id":401,"orientation_id":401},"ellipsoid":{"semi_major_equatorial_radius_km":13.0,"semi_minor_equatorial_radius_km":11.4,"polar_radius_km":9.1},"light_source":null,"rotation_matrix":{"x":{"x":-0.872372567653656,"y":0.18020516633987427,"z":0.45441412925720215},"y":{"x":-0.38781988620758057,"y":-0.8210297226905823,"z":-0.41893425583839417},"z":{"x":0.2975933849811554,"y":-0.54169762134552,"z":0.786130964756012}}}},{"children":[],"data":{"mass":1476200000000000.0,"starting_position":{"x":-204683595.81183848,"y":-115640212.72236688,"z":-47511218.96727485},"starting_velocity":{"x":12.617388154586395,"y":-16.711138179735215,"z":-7.543924345414295},"name":"Deimos","model_path":"deimos.glb","diameter":12.54,"rotation_speed":0.0,"simulate":true,"naif_id":402,"fixed_body_frame":{"target_id":402,"orientation_id":402},"ellipsoid":{"semi_major_equatorial_radius_km":7.8,"semi_minor_equatorial_radius_km":6.0,"polar_radius_km":5.1},"light_source":null,"rotation_matrix":{"x":{"x":0.023294659331440926,"y":0.9131309390068054,"z":0.407000333070755},"y":{"x":-0.8789875507354736,"y":0.2126566469669342,"z":-0.4267997741699219},"z":{"x":-0.47627538442611694,"y":-0.34780606627464294,"z":0.8075844645500183}}}}],"data":{"mass":6.4171e23,"starting_position":{"x":-204688400.957271,"y":-115657278.4760396,"z":-47517814.124955125},"starting_velocity":{"x":13.574092366316675,"y":-16.780060567161765,"z":-8.06243730513897},"name":"Mars","model_path":"mars.glb","diameter":6779.0,"rotation_speed":1476.0,"simulate":true,"naif_id":499,"fixed_body_frame":{"target_id":499,"orientation_id":499},"ellipsoid":{"semi_major_equatorial_radius_km":4000.0,"semi_minor_equatorial_radius_km":4000.0,"polar_radius_km":3376.2},"light_source":null,"rotation_matrix":{"x":{"x":-0.45149776339530945,"y":0.7727369070053101,"z":0.4461248815059662},"y":{"x":-0.8714249730110168,"y":-0.2744281589984894,"z":-0.40658047795295715},"z":{"x":-0.19175052642822266,"y":-0.5723345279693604,"z":0.7972859740257263}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"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,"simulate":true,"naif_id":799,"fixed_body_frame":{"target_id":799,"orientation_id":799},"ellipsoid":{"semi_major_equatorial_radius_km":25559.0,"semi_minor_equatorial_radius_km":25559.0,"polar_radius_km":24973.0},"light_source":null,"rotation_matrix":{"x":{"x":0.8032926321029663,"y":-0.5565762519836426,"z":-0.2119995802640915},"y":{"x":-0.3204410970211029,"y":-0.10384531319141388,"z":-0.9415591359138489},"z":{"x":0.5020343065261841,"y":0.8242809176445007,"z":-0.26176807284355164}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}},{"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"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,"simulate":true,"naif_id":-1,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true},"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data_sets":["pck11.pca","de440s.bsp","mar097.bsp"],"starting_time_millis":1696118400000,"title":"Solar System","description":"A scenario with all major bodies and their major moons in the Solar System.","scale":1e-7,"timestep":900} \ No newline at end of file diff --git a/scenarios/solar_system_copy.sim b/scenarios/solar_system_copy.sim index 1788691..9fc6d01 100644 --- a/scenarios/solar_system_copy.sim +++ b/scenarios/solar_system_copy.sim @@ -1 +1 @@ -{"bodies":[{"children":[{"children":[{"children":[],"data":{"mass":7.34767e22,"starting_position":{"x":132652620.33908576,"y":59288362.34723856,"z":25700653.622645397},"starting_velocity":{"x":-12.522181069822803,"y":24.478434326887943,"z":10.569978575134488},"name":"Moon","model_path":"moon.glb","diameter":3744.8,"rotation_speed":0.0,"axial_tilt":0.0,"simulate":true,"gravity_param":0.0,"naif_id":301,"orientation_id":301,"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null}}],"data":{"mass":5.97219e24,"starting_position":{"x":132661907.41300352,"y":59622737.91959965,"z":25879893.321551036},"starting_velocity":{"x":-13.555126596660894,"y":24.447022096986885,"z":10.59802290045933},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"axial_tilt":23.439281,"simulate":true,"gravity_param":0.0,"naif_id":399,"orientation_id":399,"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null}},{"children":[],"data":{"mass":6.4171e23,"starting_position":{"x":-179797351.86843538,"y":-141545418.16021723,"z":-60062982.27940703},"starting_velocity":{"x":16.704581229673664,"y":-14.67524995138464,"z":-7.181472156593413},"name":"Mars","model_path":"mars.glb","diameter":6779.0,"rotation_speed":1476.0,"axial_tilt":25.19,"simulate":true,"gravity_param":0.0,"naif_id":499,"orientation_id":499,"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null}}],"data":{"mass":1.9885e30,"starting_position":{"x":-1241873.683433827,"y":-337542.17983616004,"z":-111583.58952210216},"starting_velocity":{"x":0.0,"y":0.0,"z":0.0},"name":"Sol","model_path":"sun.glb","diameter":1492000.0,"rotation_speed":38880.0,"axial_tilt":7.25,"simulate":true,"gravity_param":132712440041.93938,"naif_id":10,"orientation_id":10,"ellipsoid":{"semi_major_equatorial_radius_km":695700.0,"semi_minor_equatorial_radius_km":695700.0,"polar_radius_km":695700.0},"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true}}}],"data_sets":["de440s.bsp","sat441.bsp","pck11.pca"],"starting_time_millis":1697760000000,"title":"Solar System Copy","description":"","scale":1e-7,"timestep":900} \ No newline at end of file +{"bodies":[{"children":[{"children":[{"children":[],"data":{"mass":7.34767e22,"starting_position":{"x":132652620.33908576,"y":59288362.34723856,"z":25700653.622645397},"starting_velocity":{"x":-12.522181069822803,"y":24.478434326887943,"z":10.569978575134488},"name":"Moon","model_path":"moon.glb","diameter":3744.8,"rotation_speed":0.0,"simulate":true,"naif_id":301,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":1.0,"semi_minor_equatorial_radius_km":1.0,"polar_radius_km":1.0},"light_source":null,"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data":{"mass":5.97219e24,"starting_position":{"x":132661907.41300352,"y":59622737.91959965,"z":25879893.321551036},"starting_velocity":{"x":-13.555126596660894,"y":24.447022096986885,"z":10.59802290045933},"name":"Earth","model_path":"earth.glb","diameter":12742.0,"rotation_speed":1436.0,"simulate":true,"naif_id":399,"fixed_body_frame":{"target_id":399,"orientation_id":399},"ellipsoid":{"semi_major_equatorial_radius_km":6378.1366,"semi_minor_equatorial_radius_km":6378.1366,"polar_radius_km":6356.7519},"light_source":null,"rotation_matrix":{"x":{"x":0.8844501972198486,"y":-0.46662887930870056,"z":0.002313583390787244},"y":{"x":0.46663013100624084,"y":0.8844525218009949,"z":-6.15993440078455e-6},"z":{"x":-0.0020433804020285606,"y":0.0010850358521565795,"z":0.9999973177909851}}}},{"children":[],"data":{"mass":6.4171e23,"starting_position":{"x":-179797351.86843538,"y":-141545418.16021723,"z":-60062982.27940703},"starting_velocity":{"x":16.704581229673664,"y":-14.67524995138464,"z":-7.181472156593413},"name":"Mars","model_path":"mars.glb","diameter":6779.0,"rotation_speed":1476.0,"simulate":true,"naif_id":499,"fixed_body_frame":{"target_id":499,"orientation_id":499},"ellipsoid":{"semi_major_equatorial_radius_km":3396.19,"semi_minor_equatorial_radius_km":3396.19,"polar_radius_km":3376.2},"light_source":null,"rotation_matrix":{"x":{"x":0.35471034049987793,"y":-0.8216767311096191,"z":0.44612547755241394},"y":{"x":0.898221492767334,"y":0.16700273752212524,"z":-0.4065811038017273},"z":{"x":0.2595740556716919,"y":0.5449380278587341,"z":0.7972853183746338}}}}],"data":{"mass":1.9885e30,"starting_position":{"x":-1241873.683433827,"y":-337542.17983616004,"z":-111583.58952210216},"starting_velocity":{"x":0.0,"y":0.0,"z":0.0},"name":"Sol","model_path":"sun.glb","diameter":1492000.0,"rotation_speed":38880.0,"simulate":true,"naif_id":10,"fixed_body_frame":{"target_id":-1,"orientation_id":-1},"ellipsoid":{"semi_major_equatorial_radius_km":695700.0,"semi_minor_equatorial_radius_km":695700.0,"polar_radius_km":695700.0},"light_source":{"intensity":3.75e28,"range":4436820000000.0,"color":"#FFFFFF","enabled":true},"rotation_matrix":{"x":{"x":1.0,"y":0.0,"z":0.0},"y":{"x":0.0,"y":1.0,"z":0.0},"z":{"x":0.0,"y":0.0,"z":1.0}}}}],"data_sets":["de440s.bsp","sat441.bsp","pck11.pca"],"starting_time_millis":1697760000000,"title":"Solar System Copy","description":"","scale":1e-7,"timestep":900} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ed52810..0e33d1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,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 crate::menu::MenuPlugin; use simulation::scenario::setup::SetupPlugin; @@ -75,10 +76,10 @@ fn main() { ..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/simulation/asset/default_values.rs b/src/simulation/asset/default_values.rs new file mode 100644 index 0000000..89370da --- /dev/null +++ b/src/simulation/asset/default_values.rs @@ -0,0 +1,26 @@ +use anise::structure::planetocentric::ellipsoid::Ellipsoid; +use bevy::prelude::Mat3; +use crate::simulation::asset::serialization::{SerializedFixedBodyFrame, SerializedMat3}; + +pub fn default_id() -> i32 { + -1 +} + +pub fn default_frame() -> SerializedFixedBodyFrame { + SerializedFixedBodyFrame { + target_id: default_id(), + orientation_id: default_id() + } +} + +pub fn default_spk() -> Vec { + Vec::new() +} + +pub fn default_ellipsoid() -> Ellipsoid { + Ellipsoid::from_sphere(1.0) +} + +pub fn default_rot_matrix() -> SerializedMat3 { + SerializedMat3::from(Mat3::IDENTITY) +} \ No newline at end of file diff --git a/src/simulation/asset/mod.rs b/src/simulation/asset/mod.rs index b0af105..2b9675c 100644 --- a/src/simulation/asset/mod.rs +++ b/src/simulation/asset/mod.rs @@ -3,6 +3,7 @@ use bevy::asset::AssetPath; use bevy::asset::io::AssetSourceId; pub mod serialization; +mod default_values; pub const SCENARIO_ASSET_SOURCE: &str = "scenarios"; diff --git a/src/simulation/asset/serialization.rs b/src/simulation/asset/serialization.rs index 553f9f6..c70a04d 100644 --- a/src/simulation/asset/serialization.rs +++ b/src/simulation/asset/serialization.rs @@ -2,13 +2,14 @@ use anise::structure::planetocentric::ellipsoid::Ellipsoid; use bevy::asset::io::file::FileAssetReader; use bevy::asset::io::{AssetSource, AssetSourceBuilder, AssetSourceId, Reader}; use bevy::asset::AsyncReadExt; -use bevy::prelude::{Asset, AssetApp}; +use bevy::prelude::{Asset, AssetApp, Mat3, Vec3}; use bevy::{ asset::{AssetLoader, LoadContext}, math::DVec3, prelude::Plugin, reflect::TypePath, utils::BoxedFuture, }; use serde::{Deserialize, Serialize}; +use crate::simulation::asset::default_values::*; #[derive(Debug, Deserialize, Serialize, TypePath, Asset, Clone)] pub struct SimulationData { @@ -35,6 +36,33 @@ pub struct SerializedVec { pub z: f64 } +#[derive(Debug, Deserialize, Serialize, TypePath, Clone, Copy)] +pub struct SerializedMat3 { + pub x: SerializedVec, + pub y: SerializedVec, + pub z: SerializedVec +} + +impl From for SerializedMat3 { + + fn from(value: Mat3) -> Self { + SerializedMat3 { + x: SerializedVec::from(value.x_axis.as_dvec3()), + y: SerializedVec::from(value.y_axis.as_dvec3()), + z: SerializedVec::from(value.z_axis.as_dvec3()) + } + } + +} + +impl From for Mat3 { + + fn from(value: SerializedMat3) -> Self { + Mat3::from_cols(value.x.into(), value.y.into(), value.z.into()) + } + +} + impl From for DVec3 { fn from(value: SerializedVec) -> Self { @@ -43,6 +71,15 @@ impl From for DVec3 { } +impl From for Vec3 { + + fn from(value: SerializedVec) -> Self { + DVec3::new(value.x, value.y, value.z).as_vec3() + } + +} + + impl From for SerializedVec { fn from(value: DVec3) -> Self { @@ -64,27 +101,22 @@ pub struct SerializedBodyData { pub model_path: String, pub diameter: f64, pub rotation_speed: f64, - pub axial_tilt: f32, pub simulate: bool, #[serde(default = "default_id")] pub naif_id: i32, - #[serde(default = "default_id")] - pub orientation_id: i32, + #[serde(default = "default_frame")] + pub fixed_body_frame: SerializedFixedBodyFrame, #[serde(default = "default_ellipsoid")] pub ellipsoid: Ellipsoid, - pub light_source: Option -} - -fn default_id() -> i32 { - -1 + pub light_source: Option, + #[serde(default = "default_rot_matrix")] + pub rotation_matrix: SerializedMat3 } -fn default_spk() -> Vec { - Vec::new() -} - -fn default_ellipsoid() -> Ellipsoid { - Ellipsoid::from_sphere(1.0) +#[derive(Debug, Serialize, Deserialize, TypePath, Clone)] +pub struct SerializedFixedBodyFrame { + pub target_id: i32, + pub orientation_id: i32 } #[derive(Debug, Serialize, Deserialize, TypePath, Clone)] diff --git a/src/simulation/components/anise.rs b/src/simulation/components/anise.rs index f8b5558..885109e 100644 --- a/src/simulation/components/anise.rs +++ b/src/simulation/components/anise.rs @@ -14,7 +14,7 @@ use anise::prelude::{Almanac, Epoch, Frame, SPK}; use anise::structure::planetocentric::ellipsoid::Ellipsoid; use bevy::app::Plugin; use bevy::math::DVec3; -use bevy::prelude::{in_state, IntoSystemConfigs, Local, OnEnter, Query, Res, ResMut, Resource, State, Update}; +use bevy::prelude::{in_state, IntoSystemConfigs, Local, OnEnter, Quat, Query, Res, ResMut, Resource, State, Update}; use bevy_async_task::{AsyncTaskRunner, AsyncTaskStatus}; use reqwest::get; @@ -50,13 +50,13 @@ pub fn retrieve_starting_data( let mut metadata = selected_entity.entity.map(|e| bodies.get_mut(e).ok()).flatten().unwrap(); let state = almanac.0 .translate( - Frame::new(metadata.target_id, J2000), // Target + Frame::new(metadata.ephemeris_id, J2000), // Target SSB_J2000, // Observer epoch, None, ); if let Ok(s) = state { - toasts.0.add(success_toast(&format!("Retrieved data for {}", metadata.target_id))); + toasts.0.add(success_toast(&format!("Retrieved data for {}", metadata.ephemeris_id))); e_state.new_velocity = vector3_to_dvec3(s.velocity_km_s); e_state.new_position = vector3_to_dvec3(s.radius_km); } else { @@ -70,6 +70,22 @@ pub fn retrieve_starting_data( } else { toasts.0.add(error_toast(format!("Error: {:?}", full_frame.unwrap_err()).as_str())); } + + let dcm = almanac.0.rotation_to_parent(Frame::new(metadata.target_id, metadata.orientation_id), epoch); + + if let Ok(d) = dcm { + e_state.rotation_matrix = matrix3_to_mat3(d.rot_mat); + } else { + toasts.0.add(error_toast(format!("Error: {:?}", dcm.unwrap_err()).as_str())); + } +} + +fn matrix3_to_mat3(m: anise::math::Matrix3) -> bevy::math::Mat3 { + bevy::math::Mat3::from_cols( + bevy::math::Vec3::new(m.data.0[0][0] as f32, m.data.0[0][1] as f32, m.data.0[0][2] as f32), + bevy::math::Vec3::new(m.data.0[1][0] as f32, m.data.0[1][1] as f32, m.data.0[1][2] as f32), + bevy::math::Vec3::new(m.data.0[2][0] as f32, m.data.0[2][1] as f32, m.data.0[2][2] as f32) + ) } fn vector3_to_dvec3(v: Vector3) -> DVec3 { diff --git a/src/simulation/components/billboard.rs b/src/simulation/components/billboard.rs index 681b99a..c3dfb8d 100644 --- a/src/simulation/components/billboard.rs +++ b/src/simulation/components/billboard.rs @@ -1,11 +1,13 @@ use bevy::app::{App, Plugin}; use bevy::math::Vec3; -use bevy::prelude::{Children, in_state, IntoSystemConfigs, Query, Res, Resource, Transform, Update, Visibility, With, Without, Has, Name}; +use bevy::prelude::{Children, in_state, IntoSystemConfigs, Query, Res, Resource, Transform, Update, Visibility, With, Without, Has, Name, Window, Camera, GlobalTransform, Vec2, Projection, PerspectiveProjection, Entity, Gizmos, Srgba}; +use bevy::render::camera::CameraProjection; use bevy::text::Text; +use bevy::utils::HashMap; use bevy_mod_billboard::text::BillboardTextBounds; use crate::simulation::components::apsis::ApsisBody; -use crate::simulation::components::body::{Diameter, Moon, Planet, Star, BillboardVisible}; +use crate::simulation::components::body::{Diameter, Moon, Planet, Star, BillboardVisible, BodyParent}; use crate::simulation::components::camera::{pan_orbit_camera, PanOrbitCamera}; use crate::simulation::components::scale::SimulationScale; use crate::simulation::SimState; @@ -16,6 +18,7 @@ const PLANET_VISIBILITY_THRESHOLD: f32 = 1700.0; //if the camera's radius is les //const MOON_VISIBILITY_THRESHOLD: f32 = 0.001; //if the camera's radius is less than this, moons' names will be hidden const RADIUS_DIVIDER: f32 = 3700.0; const TRANSLATION_MULTIPLIER: f32 = 2000.0; +const VISIBILITY_THRESHOLD: f32 = 20.; pub struct BodyBillboardPlugin; @@ -24,7 +27,7 @@ impl Plugin for BodyBillboardPlugin { fn build(&self, app: &mut App) { app .init_resource::() - .add_systems(Update, ((auto_scale_billboards).chain().after(pan_orbit_camera)).run_if(in_state(SimState::Loaded))); + .add_systems(Update, (auto_scale_billboards.after(pan_orbit_camera)).run_if(in_state(SimState::Loaded))); } } @@ -42,11 +45,12 @@ impl Default for BillboardSettings { } fn auto_scale_billboards( - mut bodies: Query<(&Children, &Transform, &Diameter, &mut BillboardVisible, Option<&ApsisBody>, Has, Has), Without>, + mut bodies: Query<(Entity, &Name, &Children, &Transform, &Diameter, &mut BillboardVisible, Option<&ApsisBody>, Has, Has, Option<&BodyParent>), Without>, mut billboards: Query<(&Text, &mut Transform, &mut Visibility), With>, - camera: Query<(&PanOrbitCamera, &Transform), (Without, Without, Without, Without)>, + camera: Query<(&Transform, &GlobalTransform, &Camera), (Without, Without, Without, Without)>, settings: Res, - scale: Res + scale: Res, + mut gizmos: Gizmos, ) { if !settings.show { for (_, _, mut visible) in billboards.iter_mut() { @@ -54,31 +58,35 @@ fn auto_scale_billboards( } return; } - let (cam, c_transform) = camera.single(); - let radius = cam.radius; - for (children, p_transform, diameter, mut billboard_visible, apsis, planet, star) in bodies.iter_mut() { + let (c_transform, global_trans, cam) = camera.single(); + let mut parent_pos = HashMap::default(); + for (entity, n, _, transform, _, _, _, _, _, p) in &mut bodies { + parent_pos.insert(entity, transform.translation.clone()); + } + for (_, name, children, p_transform, diameter, mut billboard_visible, apsis, planet, star, p) in bodies.iter_mut() { + let mut predicate = true; + if p.is_some() { + let parent_transform = parent_pos.get(&p.unwrap().0).unwrap_or(&Vec3::ZERO); + let distance_to_parent = calculate_screen_distance(&p_transform.translation, &parent_transform, &cam, &global_trans); + if distance_to_parent < VISIBILITY_THRESHOLD { + predicate = false; + } + } let distance_to_cam = c_transform.translation.distance(p_transform.translation) / STAR_IMPOSTER_DIVIDER; - let predicate = if planet { - radius > PLANET_VISIBILITY_THRESHOLD && radius < STAR_VISIBILITY_THRESHOLD - } else if star { - radius > STAR_VISIBILITY_THRESHOLD - } else { - radius < PLANET_VISIBILITY_THRESHOLD && radius > (scale.m_to_unit_32(diameter.num) * 2.0) && (scale.m_to_unit_32(apsis.unwrap().perihelion.distance) * 50.0 > radius) - }; let offset = if star { distance_to_cam } else { - scale.m_to_unit_32(diameter.num) / distance_to_cam * 0.01 + diameter.num * scale.0 }; billboard_visible.0 = !settings.dynamic_hide || predicate; billboard( &mut billboards, c_transform, p_transform, - radius, offset, children, - !settings.dynamic_hide || predicate + !settings.dynamic_hide || predicate, + &mut gizmos ) } } @@ -87,15 +95,15 @@ fn billboard( billboards: &mut Query<(&Text, &mut Transform, &mut Visibility), With>, c_transform: &Transform, p_transform: &Transform, - radius: f32, offset: f32, children: &Children, - predicate: bool + predicate: bool, + x: &mut Gizmos ) { for child in children.iter() { if let Ok((_, mut transform, mut visible)) = billboards.get_mut(*child) { if predicate { - apply_billboard(*c_transform, radius, *p_transform, &mut transform, offset); + apply_billboard(*c_transform, *p_transform, &mut transform, offset, x); *visible = Visibility::Visible; } else { *visible = Visibility::Hidden; @@ -105,16 +113,32 @@ fn billboard( } fn apply_billboard( - camera: Transform, - cam_radius: f32, - body: Transform, - b_transform: &mut Transform, - multiplier: f32, + camera: Transform, //camera transform + body: Transform, //body transform + b_transform: &mut Transform, //billboard transform + multiplier: f32, //This is the diameter of the body + x: &mut Gizmos, ) { let direction = (body.translation - camera.translation).normalize(); let cam_up = camera.rotation * Vec3::Y; let cam_right = cam_up.cross(direction).normalize(); let orthogonal = direction.cross(cam_right).normalize(); - b_transform.scale = body.scale.recip() * (cam_radius / RADIUS_DIVIDER); - b_transform.translation = orthogonal * TRANSLATION_MULTIPLIER * multiplier; //just extend the orthogonal vector by a constant + let cam_distance = camera.translation.distance(body.translation); + b_transform.scale = body.scale.recip() * (cam_distance / RADIUS_DIVIDER); + b_transform.translation = orthogonal * multiplier; //just extend the orthogonal vector by a constant + // x.line(body.translation, body.translation+orthogonal * multiplier, Srgba::RED); +} + +fn calculate_screen_distance( + object1: &Vec3, + object2: &Vec3, + camera: &Camera, + camera_transform: &GlobalTransform, +) -> f32 { + // Convert 3D positions to 2D screen coordinates + let screen_pos1 = camera.world_to_viewport(camera_transform, *object1).unwrap_or(Vec2::ZERO); + let screen_pos2 = camera.world_to_viewport(camera_transform, *object2).unwrap_or(Vec2::ZERO); + + // Calculate the distance between the two points in 2D screen space + (screen_pos1 - screen_pos2).length() } \ No newline at end of file diff --git a/src/simulation/components/body.rs b/src/simulation/components/body.rs index 2e0480a..e334f6e 100644 --- a/src/simulation/components/body.rs +++ b/src/simulation/components/body.rs @@ -2,7 +2,7 @@ use crate::simulation::asset::serialization::SerializedBody; use bevy::color::palettes::css; use bevy::color::Color; use bevy::core::Name; -use bevy::math::{DVec3, Vec3}; +use bevy::math::{DVec3, Mat3, Vec3}; use bevy::prelude::{default, Bundle, Component, Entity, Handle, Reflect, Scene, Srgba, Transform}; use bevy::render::primitives::Aabb; use std::collections::VecDeque; @@ -25,9 +25,9 @@ pub struct Scale(pub f32); pub struct RotationSpeed(pub f64); #[derive(Component, Reflect, Clone, Default, Copy)] -pub struct AxialTilt { - pub num: f32, - pub axis: Option, +pub struct BodyRotation { + pub matrix: Mat3, + pub axis: Vec3, pub applied: bool } @@ -137,7 +137,7 @@ pub struct BodyBundle { pub model_path: ModelPath, pub orbit: OrbitSettings, pub rotation_speed: RotationSpeed, - pub axial_tilt: AxialTilt, + pub rotation: BodyRotation, pub diameter: Diameter, pub billboard_visible: BillboardVisible, pub naif_id: AniseMetadata, @@ -159,14 +159,15 @@ impl From for BodyBundle { ellipsoid: value.data.ellipsoid, ..default() }, - axial_tilt: AxialTilt { - num: value.data.axial_tilt, + rotation: BodyRotation { + matrix: Mat3::from(value.data.rotation_matrix), ..default() }, rotation_speed: RotationSpeed(value.data.rotation_speed), naif_id: AniseMetadata { - target_id: value.data.naif_id, - orientation_id: value.data.orientation_id, + ephemeris_id: value.data.naif_id, + orientation_id: value.data.fixed_body_frame.orientation_id, + target_id: value.data.fixed_body_frame.target_id, }, ..default() } @@ -187,8 +188,8 @@ impl BodyBundle { num: 0.0, ..default() }, - axial_tilt: AxialTilt { - num: 0.0, + rotation: BodyRotation { + matrix: Mat3::IDENTITY, ..default() }, rotation_speed: RotationSpeed(0.0), diff --git a/src/simulation/components/diameter.rs b/src/simulation/components/diameter.rs index a0710fa..de23501 100644 --- a/src/simulation/components/diameter.rs +++ b/src/simulation/components/diameter.rs @@ -1,12 +1,14 @@ 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::asset::LoadState; use bevy::ecs::query::QueryManyIter; -use bevy::prelude::{AssetServer, Entity, Local, Name}; +use bevy::prelude::{AssetServer, Entity, Local, Name, Resource}; use bevy::utils::HashMap; use crate::simulation::SimState; use crate::simulation::components::body::SceneHandle; use crate::simulation::components::body::{Diameter, Scale}; use crate::simulation::components::scale::SimulationScale; use crate::simulation::scenario::loading::LoadingState; +use crate::simulation::ui::toast::{important_error_toast, ToastContainer}; pub struct DiameterPlugin; @@ -14,11 +16,15 @@ impl Plugin for DiameterPlugin { fn build(&self, app: &mut App) { app - .add_systems(Update, apply_real_diameter.run_if(in_state(SimState::Loading))); + .init_resource::() + .add_systems(Update, apply_real_diameter.run_if(in_state(SimState::Loading))); } } +#[derive(Default, Resource)] +pub struct SavedAabbs(HashMap); + pub fn apply_real_diameter( mut bodies: Query<(&Children, &Name, &SceneHandle, &mut Diameter, &mut Transform, &mut Scale)>, scenes: Query<&SceneInstance>, @@ -27,7 +33,8 @@ pub fn apply_real_diameter( mut loading_state: ResMut, asset_server: Res, s_scale: Res, - mut aabbs: Local> + mut toasts: ResMut, + mut aabbs: ResMut ) { if !bodies.is_empty() && bodies.iter().all(|(_, _, _, diameter, _, _)| { diameter.applied @@ -35,7 +42,23 @@ pub fn apply_real_diameter( loading_state.scaled_bodies = true; } for (children, name, handle, mut diameter, mut transform, mut scale) in &mut bodies { - if diameter.applied || asset_server.get_load_state(&handle.0) != Some(bevy::asset::LoadState::Loaded) { + if diameter.applied || asset_server.get_load_state(&handle.0) != Some(LoadState::Loaded) { + if !diameter.applied { + match asset_server.get_load_state(&handle.0) { + None => {} + Some(a) => { + match a { + LoadState::NotLoaded => {} + LoadState::Loading => {} + LoadState::Loaded => {} + LoadState::Failed(e) => { + toasts.0.add(important_error_toast(format!("Failed to load asset for body '{}': {}", name.as_str(), e).as_str())); + diameter.applied = true; + } + } + } + } + } continue; } for children in children { @@ -43,15 +66,23 @@ pub fn apply_real_diameter( if !spawner.instance_is_ready(**scene) { continue; } - let aabb = if let Some(aabb) = aabbs.get(&diameter.path.clone()) { + let aabb = if let Some(aabb) = aabbs.0.get(&diameter.path.clone()) { *aabb } else { let m = meshes.iter_many(spawner.iter_instance_entities(**scene)); let aabb = calculate_aabb(m); - aabbs.insert(diameter.path.clone(), aabb); + aabbs.0.insert(diameter.path.clone(), aabb); aabb }; - transform.scale = Vec3::splat(s_scale.m_to_unit_32(diameter.num) / 1.7) / (Vec3::from(aabb.half_extents)); //not dividing by 1.7 for the diameter makes them to big which doesn't work with satellites very close to their planet + //TODO: Fix this + let semi_major_radius_units = s_scale.m_to_unit_32((diameter.ellipsoid.semi_major_equatorial_radius_km * 1000.0) as f32); // km to meters + let semi_minor_radius_units = s_scale.m_to_unit_32((diameter.ellipsoid.semi_minor_equatorial_radius_km * 1000.0) as f32); + let polar_radius_units = s_scale.m_to_unit_32((diameter.ellipsoid.polar_radius_km * 1000.0) as f32); + transform.scale = Vec3::new( + semi_major_radius_units / (aabb.half_extents.x * 2.0), + polar_radius_units / (aabb.half_extents.y * 2.0), + semi_minor_radius_units / (aabb.half_extents.z * 2.0) + ); scale.0 = transform.scale.x; diameter.applied = true; loading_state.scaled_bodies_count += 1; diff --git a/src/simulation/components/horizons.rs b/src/simulation/components/horizons.rs index faae6c5..d6a1bbe 100644 --- a/src/simulation/components/horizons.rs +++ b/src/simulation/components/horizons.rs @@ -33,6 +33,8 @@ impl Default for HorizonsClient { #[derive(Component, Clone, Debug)] pub struct AniseMetadata { + pub ephemeris_id: i32, + //For constants and rotation pub target_id: i32, pub orientation_id: i32, @@ -42,8 +44,9 @@ impl Default for AniseMetadata { fn default() -> Self { Self { - target_id: -1, + ephemeris_id: -1, orientation_id: -1, + target_id: -1 } } @@ -155,7 +158,7 @@ pub fn retrieve_starting_data_horizons( let stop_date = (starting_date + chrono::Duration::days(1)).format("%Y-%m-%d").to_string(); let id = bodies.get(entity).unwrap(); let parameters = HorizonsApiParameters::with_defaults() - .with_command(id.target_id) + .with_command(id.ephemeris_id) .with_start_time(start_date.as_str()) .with_stop_time(stop_date.as_str()); if let Ok((pos, vel)) = get_starting_data_horizons(parameters, client.0.clone()) { diff --git a/src/simulation/components/rotation.rs b/src/simulation/components/rotation.rs index bad4a01..ad99611 100644 --- a/src/simulation/components/rotation.rs +++ b/src/simulation/components/rotation.rs @@ -7,7 +7,7 @@ use bevy::prelude::{in_state, IntoSystemConfigs, Quat, Query, Res, ResMut, Trans use bevy::scene::SceneInstance; use bevy::time::Time; -use crate::simulation::components::body::{AxialTilt, Diameter, RotationSpeed, Star}; +use crate::simulation::components::body::{BodyRotation, Diameter, RotationSpeed, Star}; use crate::constants::DAY_IN_SECONDS; use crate::simulation::scenario::loading::LoadingState; use crate::simulation::components::physics::{Pause, SubSteps}; @@ -29,24 +29,27 @@ impl Plugin for RotationPlugin { } pub fn axial_tilt( - mut query: Query<(&mut AxialTilt, &Diameter, &Children)>, + mut query: Query<(&mut BodyRotation, &Diameter, &Children)>, mut scenes: Query<&mut Transform, (With, Without)>, mut loading_state: ResMut, ) { if query.iter().all(|(tilt, _, _)| tilt.applied) { loading_state.tilted_bodies = true; } - for (mut tilt, diameter, children) in &mut query { - if tilt.applied || !diameter.applied { + for (mut rotation, diameter, children) in &mut query { + if rotation.applied || !diameter.applied { continue; } + println!("Applying axial tilt to body"); for child in children.iter() { if let Ok(mut transform) = scenes.get_mut(*child) { - transform.rotate_x(PI / 2.0); + /*transform.rotate_x(PI / 2.0); let tilted = Quat::from_axis_angle(Vec3::X, tilt.num.to_radians()) * Vec3::Z; transform.rotate_x(tilt.num.to_radians()); - tilt.axis = Some(tilted); - tilt.applied = true; + tilt.axis = Some(tilted);*/ + transform.rotation = Quat::from_mat3(&rotation.matrix); + rotation.axis = transform.translation * Vec3::Z; + rotation.applied = true; break; } } @@ -54,7 +57,7 @@ pub fn axial_tilt( } fn rotate_bodies( - query: Query<(&RotationSpeed, &Diameter, &AxialTilt, &Children)>, + query: Query<(&RotationSpeed, &Diameter, &BodyRotation, &Children)>, mut scenes: Query<&mut Transform, With>, time: Res