From 3d3864171785c589872bf23faaaa3a421f56ee4e Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Wed, 22 Apr 2026 10:51:13 -0400 Subject: complete orbit camera. add most large solar bodies --- assets/shaders/tacbody.wgsl | 7 +- assets/systems/sol.csv | 201 +++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 1 + src/solar_system.rs | 41 ++++++--- src/tacmap.rs | 17 ++-- src/tacmap/camera.rs | 83 +++++++++--------- src/tacmap/render.rs | 21 +++-- src/timeman.rs | 16 ++-- src/ui.rs | 114 +++++++++++++++++++++++++ src/ui/camera_info.rs | 74 ++++++++++++++++ src/window.rs | 31 ++++--- src/window/ui.rs | 120 -------------------------- 12 files changed, 514 insertions(+), 212 deletions(-) create mode 100644 src/ui.rs create mode 100644 src/ui/camera_info.rs delete mode 100644 src/window/ui.rs diff --git a/assets/shaders/tacbody.wgsl b/assets/shaders/tacbody.wgsl index 99392ac..62adcdd 100644 --- a/assets/shaders/tacbody.wgsl +++ b/assets/shaders/tacbody.wgsl @@ -38,8 +38,9 @@ fn vs_main( let min_size = 0.025; - //Scale the world around the camera scale. - let instance_pos = instance.position * camera.scale; + //Scale the world around the camera scale and translate about the camera's + //absolute (/target) position + let instance_pos = (instance.position) * camera.scale; let view_proj = camera.proj * view; @@ -49,7 +50,7 @@ fn vs_main( let vertex_dist = length(vertex_view_pos - center_view_pos) / center_view_pos.w; if vertex_dist < min_size { out.clip_position = center_view_pos / center_view_pos.w; - out.clip_position += camera.proj * vec4(model.position.xy * (min_size / 2), 0.0, 0.0); + out.clip_position += camera.proj * vec4(model.position.xy * (min_size / 2.0), 0.0, 0.0); }else{ out.clip_position = vertex_view_pos; } diff --git a/assets/systems/sol.csv b/assets/systems/sol.csv index 1c6dcfd..0de0291 100644 --- a/assets/systems/sol.csv +++ b/assets/systems/sol.csv @@ -1,3 +1,198 @@ -name,orbits,mass,radius,eccentricity,inclination,long_asc_node,long_periapsis,sgp,mean_long,semi_major_axis -Sol,,1.988475e30,695700.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -Earth,0,5.97217e24,6371.0,0.0167,0.1249,-0.1965,1.7966,3.986e14,1.7534,149598023 +name,orbits,mass,radius,eccentricity,inclination,long_asc_node,long_periapsis,sgp,mean_long,semi_major_axis +Sun,,1.98841e+30,695700.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +Mercury,0,3.3020000000000006e+23,2439.4,0.2056302933705567,0.12226056374145156,0.84352702699409,1.3518416341935338,132712462073.14793,4.402605310024959,57909068.29452708 +Venus,0,4.868500000000001e+24,6051.84,0.006755786251885615,0.05924676613057432,1.3382900934083817,2.30146691896849,132712764899.87138,3.1761346920564177,108208168.1709291 +Earth,0,5.97219e+24,6371.01,0.01711862906746885,7.2973718151563756e-06,2.357603289547775,8.060086467777777,132712838641.71489,14.319138343662642,149665014.5528626 +Mars,0,6.4171e+23,3389.0,0.09331510145811761,0.03228643528075944,0.865020182634384,5.866040947536561,132712482869.65425,6.203875303082545,227939132.9739321 +Jupiter,0,0,69911.0,0.04878759429164036,0.022770099256999625,1.753901435747497,6.554762318421465,132839126573.17976,6.883156962270264,778557615.6961257 +Saturn,0,5.6834e+26,58232.0,0.05563834267345058,0.04335838361458921,1.9844334258635508,7.846393880418469,132750371247.51375,13.43887486213043,1433436205.58977 +Uranus,0,8.6813e+25,25362.0,0.04439276513323943,0.013485736371195343,1.2916264872535133,2.9774177552754657,132718233991.88972,5.4713113171768875,2876789143.055653 +Neptune,0,1.02409e+26,24624.0,0.01120359481511804,0.030896063778029965,2.3000625565876027,6.965603443672412,132719275144.42485,11.610012311252664,4501986665.679727 +Pluto,0,1.3069999999999998e+22,1188.0,0.2494484952274253,0.3008188938556382,1.9205592608875255,3.9308062102251338,132712440910.60551,4.177659550156696,5919776464.668311 +Moon,3,7.349e+22,1737.0,0.06314721685094304,0.09146001755875816,2.1634762017486735,7.55519397478505,403503.2356254801,10.115125544334436,381874.5248499886 +Phobos,4,1.08e+20,13.1,0.01469841851969655,0.4547752413925335,1.4803034911358524,7.463027998110535,42828.37556611086,10.77605446953754,9378.610328444505 +Deimos,4,1.8e+20,7.8,0.0003299624878237082,0.481176275777402,1.460304185350636,5.15856598276248,42828.37495351195,5.247472196393151,23458.18251161354 +Io,5,0,1821.49,0.004715688921345897,0.03861746506217218,5.879184262283335,7.033979354786218,126692491.81583658,12.88350630646032,422036.4314844596 +Europa,5,0,1560.8,0.009812823575576082,0.03125834441797786,5.805466566368347,10.249897631574104,126689734.61247002,16.27845749593515,671248.4976902213 +Ganymede,5,0,2631.2,0.001457215292672099,0.038644173456834206,5.989496057893187,11.571195363504751,126696419.73312312,16.40660856148493,1070497.481019323 +Callisto,5,0,2410.3,0.007439434600948234,0.035201828790876126,5.898211233324125,6.179678648829006,126693711.18377298,7.665283510202031,1882772.953875105 +Amalthea,5,0,83.5,0.006131496682479541,0.042622496009152834,5.7667538742407185,7.601401826435993,126686532.06493385,13.470357815243212,181996.7340166629 +Himalia,5,0,85.0,0.1661999684637328,0.5279080348785393,1.1203649433447742,6.725312954857192,126686532.05192283,8.090896879576654,11372112.63008802 +Elara,5,0,40.0,0.2218660080128935,0.5046147489712316,1.9686876193359442,4.2361106637237995,126686531.9003704,10.290774473025145,11741166.76466171 +Pasiphae,5,0,18.0,0.3795395076401018,2.4449867373553333,5.5108577503857985,8.527298922882686,126686531.9003704,13.400685662858741,23425241.16212726 +Sinope,5,0,14.0,0.3164145814772745,2.6552974577214616,5.375990120287716,11.559321221290515,126686531.9003704,14.307351969936411,22968782.47446919 +Lysithea,5,0,12.0,0.1367857686807304,0.48627128470281067,0.16126183480077358,1.0033161898216347,126686531.9003704,6.736173532523992,11739916.52273718 +Carme,5,0,15.0,0.242478793789235,2.8749558721603066,2.0158361338871753,2.1289772162852527,126686531.9003704,6.657696609523392,24202893.12094299 +Ananke,5,0,10.0,0.3803569875212374,2.6468768003651455,0.23898419445193397,1.6129064863854086,126686531.9003704,6.357055310016165,21683828.75538572 +Leda,5,0,5.0,0.172562240187277,0.4813329528164319,3.785196617153587,8.519933221898869,126686531.9003704,12.579707787660913,11140304.88851313 +Thebe,5,0,49.3,0.01524351586882957,0.057321113382734705,5.90086342320734,6.367381612810837,126686531.9305184,9.552476861642898,222383.8316001035 +Adrastea,5,0,8.2,0.007460306513267502,0.038566007448231264,5.894689065282206,9.975668691455562,126686531.9005094,9.995065782918829,129874.6420817262 +Metis,5,0,21.5,0.00612909691510393,0.038696889017770436,5.893176690389734,9.184132427873644,126686531.9028714,15.43277337066054,128877.9814710768 +Callirrhoe,5,0,0.0,0.1976600922803021,2.4288588421603614,4.8552687920988875,5.091145850221602,126686531.9003704,7.148945365210003,23032602.915287 +Themisto,5,0,0.0,0.1967488051235012,0.8025759371310424,3.537217251434987,7.661133865550351,126686531.9003704,12.707929981941364,7396776.253819576 +Megaclite,5,0,0.0,0.4465444914716494,2.652246980443281,5.099166774038082,10.508774066163623,126686531.9003704,12.534841377508544,24608518.04025361 +Taygete,5,0,0.0,0.2921957581010093,2.827997222640246,5.249656034121917,8.875099045725529,126686531.9003704,10.907884470033798,22217140.77402277 +Chaldene,5,0,0.0,0.2023650851538333,2.8924710469933754,2.3466772834604304,6.386728001667526,126686531.9003704,11.195188490373987,23426746.66490304 +Harpalyke,5,0,0.0,0.2544728538458849,2.617340721252638,0.6205674953595897,2.440393313997703,126686531.9003704,6.899328689445834,21571841.44651141 +Kalyke,5,0,0.0,0.3038746288553837,2.904990685461275,0.6581293789729374,4.85477937697065,126686531.9003704,8.781498691760008,22250677.91409567 +Iocaste,5,0,0.0,0.2423615778838066,2.6002913259680454,4.693130848582014,6.2881564108697265,126686531.9003704,9.46510208292259,21118031.39301891 +Erinome,5,0,0.0,0.323655963895905,2.8139539038258508,5.431081378990347,11.711271545648748,126686531.9003704,16.479508211432414,23508771.87674819 +Isonoe,5,0,0.0,0.1519311728652023,2.897939227285438,2.3399800371726425,4.626586542573252,126686531.9003704,6.657274991342909,23872493.54397819 +Praxidike,5,0,0.0,0.1814463083753398,2.498273536281937,4.909696068720551,8.095808945882098,126686531.9003704,10.328773081096756,20448959.76711051 +Autonoe,5,0,0.0,0.2154936754539014,2.6226812361277787,4.621215664811568,5.689879555407112,126686531.9003704,8.0293605483285,24864729.95197445 +Thyone,5,0,0.0,0.4302048375437417,2.6162382224140788,4.202306930265727,6.036095508851227,126686531.9003704,10.269894717780172,20601585.40911181 +Hermippe,5,0,0.0,0.1831117333571984,2.616591014366626,5.765312737204649,10.604517726611277,126686531.9003704,13.370295280486502,21296585.86620484 +Aitne,5,0,0.0,0.3778620738384784,2.8938885405351122,6.255443714136797,7.515212063665569,126686531.9003704,9.619375264819258,22197919.10562307 +Eurydome,5,0,0.0,0.2204793916890918,2.549518187916801,5.195695352638055,9.094391272753953,126686531.9003704,14.012873533748142,22877281.07192879 +Euanthe,5,0,0.0,0.2339634133787023,2.547682164867028,4.628025305394059,10.07956258234589,126686531.9003704,16.250823497046277,20535035.26944764 +Euporie,5,0,0.0,0.120835998146515,2.5670716598086116,1.1065094589362532,3.019737723684281,126686531.9003704,4.001621548305704,19545134.38372267 +Orthosie,5,0,0.0,0.3005129189155479,2.5183889251937037,3.7062607731026107,7.977624707076791,126686531.9003704,10.790094728804437,20689183.18103206 +Sponde,5,0,0.0,0.2485663622513233,2.652531540286478,1.9072618231193363,2.8955749206014834,126686531.9003704,5.991963169910999,24528926.1602971 +Kale,5,0,0.0,0.2311183212056169,2.9097964043210216,0.989245852357804,2.1963078562418095,126686531.9003704,5.2675293924877105,23061659.16692859 +Pasithee,5,0,0.0,0.3182853129737261,2.847774629889573,5.550140785687939,9.179324146597281,126686531.9003704,13.328341503353691,23237364.3274696 +Hegemone,5,0,0.0,0.3781834532138578,2.555527329119117,5.4360332257995925,8.790276192871037,126686531.9003704,12.999089068997781,23245337.05021968 +Mneme,5,0,0.0,0.309081546284718,2.581642678744907,0.016237742290971285,0.8909646087253341,126686531.9003704,5.011309205820043,20476569.42391071 +Aoede,5,0,0.0,0.5973786012175527,2.731014739901271,2.7310578687587053,3.482564047586793,126686531.9003704,7.1066736456834265,22992342.60079308 +Thelxinoe,5,0,0.0,0.1704920425161695,2.6352483976704275,3.05295407442034,8.40973583821587,126686531.9003704,13.212055465891922,20675091.19215431 +Arche,5,0,0.0,0.2056172205402724,2.83890098328702,5.817963582588227,8.83012031277728,126686531.9003704,9.421969060806585,22467814.32570489 +Kallichore,5,0,0.0,0.1621737756550101,2.8926340088767644,0.4171534169763623,6.573145149631185,126686531.9003704,7.737413839450872,22134609.49089593 +Helike,5,0,0.0,0.1526607979402507,2.71000308432797,1.6504833575560622,6.9774868776916605,126686531.9003704,7.775073083043429,20820754.89465492 +Carpo,5,0,0.0,0.2031983534554527,1.024539082511612,0.9095406304435024,2.4886940861621265,126686531.9003704,8.364170000944315,16925445.42260925 +Eukelade,5,0,0.0,0.2214987184292226,2.8934777311295656,3.498260923324021,8.560538340837773,126686531.9003704,12.648422999341443,24227073.62992587 +Cyllene,5,0,0.0,0.2802720440980859,2.4685219634385724,4.426801634454883,7.473959950111424,126686531.9003704,10.148405622518947,23348703.78962577 +Kore,5,0,0.0,0.2478075354293065,2.395878586341489,5.657808275980963,8.019707784125693,126686531.9003704,8.728401233811924,23658733.80230949 +Herse,5,0,0.0,0.3148772986567324,2.8200871138788033,5.226599840939807,11.231844426450426,126686531.9003704,13.380705703177416,23244188.80058314 +S2010_J1,5,0,0.0,0.3210606252853301,2.8070966531845625,4.969443005015482,8.034206454230443,126686531.9003704,11.235157938899842,22433234.39611587 +S2010_J2,5,0,0.0,0.2057526644645962,2.5628733748514017,6.235659870436373,6.737685213078592,126686531.9003704,11.843485704298011,21129685.34182228 +Dia,5,0,0.0,0.182930161024708,0.48105719715755724,5.129804797005582,7.993807050927407,126686531.9003704,13.595045803960033,12315846.5632231 +S2016_J1,5,0,0.0,0.3875331270513935,2.5310834126635324,4.323884722267483,9.532904489707922,126686531.9003704,13.291281674958803,20346358.11830464 +S2003_J18,5,0,0.0,0.06389192758971185,2.545349471167113,2.91037708735752,4.412182533754045,126686531.9003704,8.822276577283223,20788562.18209846 +S2011_J2,5,0,0.0,0.5103931682212471,2.7430409635450976,0.4338520685842705,5.0229024660773085,126686531.9003704,10.216524273552157,23915773.02169935 +Eirene,5,0,0.0,0.2389246071357166,2.8974510408078142,3.142135468645045,4.649533525536385,126686531.9003704,10.526686730647445,22395283.42230558 +Philophrosyne,5,0,0.0,0.09146335950674479,2.5395731532504793,4.089805219795507,4.107541442296512,126686531.9003704,5.657343844251257,21808132.69721803 +S2017_J1,5,0,0.0,0.2934064758254378,2.5375866946644976,4.395413942715047,5.698443028620905,126686531.9003704,10.0630279880972,22645930.12887298 +Eupheme,5,0,0.0,0.2902489694139416,2.611152449601225,3.9702413963179226,5.253957122183653,126686531.9003704,11.185401018389737,20943662.01400921 +S2003_J19,5,0,0.0,0.158954656487365,2.881807784573629,0.3820532823330615,3.642244533124773,126686531.9003704,7.078830410621714,23687141.81846834 +Valetudo,5,0,0.0,0.1481793182290554,0.5596607271990678,5.082663867540582,10.604403402543344,126686531.9003704,12.182898112127276,18738029.52202487 +S2017_J2,5,0,0.0,0.1959953847198447,2.8700441100199003,6.273490105101661,8.943527029743617,126686531.9003704,13.798357432869743,22061974.76432372 +S2017_J3,5,0,0.0,0.2126228487743277,2.610579778896396,0.4873552820516491,2.3317373654518216,126686531.9003704,6.440332134033964,21530718.54336384 +Pandia,5,0,0.0,0.1455600412441361,0.49211520107218915,4.3595687458404,7.652709850458432,126686531.9003704,10.418816301380286,11547977.99927832 +S2017_J5,5,0,0.0,0.3390543805742626,2.9139831892973986,0.739034345521789,5.844659629960608,126686531.9003704,7.0526565837127,23724381.12409825 +S2017_J6,5,0,0.0,0.3469120080195556,2.4861311341641232,5.4585510146913085,5.7291154455232185,126686531.9003704,8.27800306127388,22523891.43754988 +S2017_J7,5,0,0.0,0.3366201390795697,2.58767832744654,4.6237512762038975,9.662529103481884,126686531.9003704,15.822545117002319,20915477.23673877 +S2017_J8,5,0,0.0,0.2605117312940345,2.882194831180225,1.697959142279315,7.466603354479444,126686531.9003704,13.564756457587748,22381678.36298777 +S2017_J9,5,0,0.0,0.2941686771108317,2.7246576635441597,4.28157191293436,9.105453192553078,126686531.9003704,13.351156224107076,21198127.07082193 +Ersa,5,0,0.0,0.1372917029965884,0.5230106566397636,1.984993006482692,7.2320993292577604,126686531.9003704,11.959153827808215,11342307.36298009 +S2011_J1,5,0,0.0,0.1786250737925076,2.865249406800963,4.425064512052962,5.303641414939245,126686531.9003704,9.238365145714553,23028502.18186307 +Mimas,6,3.75e+19,198.8,0.02175634846415301,0.4712852821481416,3.002960190333883,4.900576118243826,37931208.73785044,5.553295359850831,186036.8223903924 +Enceladus,6,1.0805e+20,252.3,0.006351597350212341,0.48960016503634135,2.9584481976400534,5.32307306791626,37931213.44472836,5.444432765504109,238419.8688441309 +Tethys,6,6.176e+20,536.3,0.0009698778768676897,0.4750913474160461,2.9321134489149943,5.690729804774174,37931247.44789053,11.806063643067493,294980.2530852608 +Dione,6,1.09572e+21,562.5,0.002928360145096942,0.48941467144643996,2.9578129179196515,5.836478693022438,37931279.350433394,11.631959019030479,377652.1784818554 +Rhea,6,2.309e+21,764.5,0.0008002149724314739,0.49290571863720206,2.9493307126312978,5.842769335555987,37931360.17611358,9.453892406990327,527225.2527315543 +Titan,6,1.3455299999999999e+23,2575.5,0.02860066256432539,0.4837762765193331,2.9537805703120874,5.823261184252294,37940184.37145719,8.675760947469714,1221934.800913171 +Hyperion,6,1.08e+19,133.0,0.126730863824527,0.4748871428931781,2.9374766417713714,6.230795460515917,37931206.60485305,7.463065351245633,1485060.66650382 +Iapetus,6,1.8059e+21,734.5,0.02786249162022612,0.30086342381741976,2.4380810648672413,6.446376219534038,37931326.749467686,10.076968116251834,3562566.556811612 +Phoebe,6,8.289e+18,106.6,0.165405199982644,3.0239349829824484,4.593689285872114,10.767442981780192,37931206.789147675,11.791061834948644,12943784.54486596 +Janus,6,1.9800000000000003e+18,101.7,0.006166614098338093,0.48841539690762686,2.964432933052476,5.825164797409277,37931206.360938184,7.216913685288836,152034.0298378808 +Epimetheus,6,5.5e+17,64.9,0.00603242796139321,0.48412214328961206,2.9648565966488074,6.989353826784916,37931206.269485004,10.447980290876307,152072.854457989 +Helene,6,0,0.0,0.008038750374726936,0.4875468666324474,2.965444094098645,5.921989766782803,37931206.23483741,6.267380558906925,377855.551765011 +Telesto,6,0,16.3,0.001082579111920228,0.4692273229095975,2.9514542980973304,6.7243291092336595,37931206.23436167,12.839075192137408,294982.2154231849 +Calypso,6,0,15.3,0.0006104378298273683,0.49213148215780744,2.903478294086474,4.206429004842772,37931206.23436167,4.49360558609789,294940.7422356942 +Atlas,6,0,20.5,0.005196549727214316,0.4895319608349911,2.958775046866233,8.987470691899283,37931206.23473356,15.054675167331922,138324.4161211837 +Prometheus,6,1.4e+17,68.2,0.004807274664644071,0.48959693261944515,2.9585129084747575,3.4627892766482056,37931206.24511375,3.9309629273044866,140026.824726521 +Pandora,6,1.3e+17,52.2,0.004055307701602707,0.48932076522361767,2.960586819441114,7.123519921243396,37931206.23436167,8.14998492092321,142348.2506944552 +Pan,6,0,17.2,0.005063676085631714,0.48958950851205424,2.9587985918990043,4.820821352323277,37931206.23436167,11.102855668160792,134263.6247793693 +Ymir,6,0,0.0,0.3944324581590973,3.0185438110556633,3.5733042878772876,4.3659312666120025,37931206.23436167,8.14648151913759,22398298.41701081 +Paaliaq,6,0,0.0,0.4648291075578432,0.8258533327526711,6.164466122384929,10.308260146919912,37931206.23436167,15.625511668223439,14919840.26908436 +Tarvos,6,0,0.0,0.6449342030970687,0.5915984611684059,1.670009582873096,6.608668764539281,37931206.23436167,11.072347318002652,18574845.76298451 +Ijiraq,6,0,0.0,0.3682747417446802,0.8659442982391191,2.6616366263751767,3.857854712695275,37931206.23436167,4.353779635437956,11327117.44761699 +Suttungr,6,0,0.0,0.120611010930652,3.0488249149430104,4.418850930468428,5.544085725367595,37931206.23436167,11.090263186101389,19596424.08346783 +Kiviuq,6,0,0.0,0.1581711093180609,0.8510912057914954,6.154534944908413,7.757009087724102,37931206.23436167,10.6983951456934,11303837.21284421 +Mundilfari,6,0,0.0,0.2469688535276221,2.9581643983668804,1.3793103688280368,6.710466815083391,37931206.23436167,8.407697324305026,18723859.8783339 +Albiorix,6,0,0.0,0.4917334359913308,0.6473952650081867,1.9392237919853705,3.0348086462549277,37931206.23436167,3.335249233809628,16398357.04349433 +Skathi,6,0,0.0,0.2239598243795358,2.5806989677148255,4.957867821526885,8.494075863861042,37931206.23436167,10.539318967609873,15500179.92000291 +Erriapus,6,0,0.0,0.617653473355569,0.599096562451495,2.55177611104589,7.437322932851261,37931206.23436167,12.789119058339818,17210680.89813892 +Siarnaq,6,0,0.0,0.3908564526639059,0.8464950335310043,1.1163748122970465,2.309854924960175,37931206.23436167,5.638406471582597,17560075.2675432 +Thrymr,6,0,0.0,0.5054339669259785,3.053759439116833,4.314690328168167,5.921009520494753,37931206.23436167,12.04504702318564,20320774.14243359 +Narvi,6,0,0.0,0.2691086970406526,2.4221640997612166,3.1248186867162913,6.23470715545532,37931206.23436167,8.13963700920362,19510928.56636147 +Methone,6,0,0.0,0.003170797619850931,0.48964092848689683,2.9581537171674643,5.3062831834012005,37931206.23436167,5.583771249750031,194695.8307563677 +Pallene,6,0,0.0,0.005979127885571862,0.48928267631511124,2.9520421031984694,4.704402198895856,37931206.23436167,4.723437567456444,212707.8857073742 +Polydeuces,6,0,0.0,0.01907613447456014,0.492274879505576,2.9618284885256623,8.917016530075504,37931206.23436167,10.164090480016592,377405.1192454056 +Daphnis,6,0,0.0,0.004843868547657344,0.48960732220010933,2.958875920091211,4.93964929967227,37931206.23436167,4.941699265245442,137169.4055794578 +Aegir,6,0,0.0,0.2868425154340613,2.9297145725628453,3.1771900750113993,7.451180720465005,37931206.23436167,7.925561064057661,20825709.27643795 +Bebhionn,6,0,0.0,0.3777087812925531,0.7568279358090894,3.4504003295717034,3.5367687781594856,37931206.23436167,6.399469396302889,17194214.99491686 +Bergelmir,6,0,0.0,0.1195265225843454,2.7793326632936703,3.6268968078081802,5.971246067058427,37931206.23436167,11.399113859122458,19011491.9104785 +Bestla,6,0,0.0,0.6179802254518031,2.552891723021767,4.938273879234135,6.430506063119838,37931206.23436167,10.605924254455623,20167919.11972351 +Farbauti,6,0,0.0,0.2444381671778622,2.730899566912758,2.4106930661479935,8.40536452804103,37931206.23436167,13.382315590385833,20449033.77495886 +Fenrir,6,0,0.0,0.1912102582614899,2.8727867405735164,4.0966522584130995,6.100760779923803,37931206.23436167,8.676986914051625,21893320.7868848 +Fornjot,6,0,0.0,0.2672628168261117,2.931900974524335,4.69983723612461,10.319484420647022,37931206.23436167,14.370165397906083,24999515.65473308 +Hati,6,0,0.0,0.4292764461011132,2.8012903681193637,5.521198828682244,5.701772953111148,37931206.23436167,8.901148746119503,19394717.8965803 +Hyrrokkin,6,0,0.0,0.4619527555698056,2.70167597545097,0.7007734121526012,5.321849175052495,37931206.23436167,10.47250626955085,18558046.92636919 +Kari,6,0,0.0,0.4693191406946912,2.556875432531966,5.031533127824373,7.827526220955339,37931206.23436167,13.055528882189368,22433422.35332508 +Loge,6,0,0.0,0.1943065946192154,2.8841959600269167,5.81170487011614,6.167402573342012,37931206.23436167,12.070403588093233,22775282.13031904 +Skoll,6,0,0.0,0.4564323615599525,2.674587661609745,5.131759554298513,8.38217568029393,37931206.23436167,9.239632307476379,17674176.90243748 +Surtur,6,0,0.0,0.5459025109544823,2.9305348952582237,4.454342793193538,9.938696195958016,37931206.23436167,12.742245872506935,22171006.47780826 +Anthe,6,0,0.0,0.001106339853080138,0.4894968193923412,2.9581447896394706,7.161686401385616,37931206.23436167,13.362983891669334,198105.6135361587 +Jarnsaxa,6,0,0.0,0.2824615408903135,2.849680512080075,0.16063743125188487,4.158663759400225,37931206.23436167,7.54527243587623,19009411.04944567 +Greip,6,0,0.0,0.3021028258686689,3.010366350039816,5.859345188352119,8.405276544613876,37931206.23436167,13.77453669598205,18348595.75600506 +Tarqeq,6,0,0.0,0.1039237928742909,0.8793620770384236,1.6293350160147928,2.8798260056128377,37931206.23436167,4.973657424081472,17644401.57279597 +Aegaeon,6,0,0.0,0.003271443897654165,0.4895689931694547,2.9588188149903707,4.057272610621565,37931206.23436167,4.090658663215381,168028.2592022763 +Gridr,6,0,0.0,0.1598140996102149,2.8312340620946044,5.773364183524638,10.518532564875045,37931206.23436167,12.927435268854403,19276465.5256161 +Angrboda,6,0,0.0,0.1900064996943967,3.098832110798138,4.878411170664638,6.701674371232632,37931206.23436167,8.471819576389205,20966645.1189135 +Skrymir,6,0,0.0,0.4775923968422296,3.107172732038587,3.1036700835737854,4.297560920321759,37931206.23436167,5.417771343106054,21417795.95073909 +Gerd,6,0,0.0,0.6198423089579217,3.041227857061265,4.540633086852932,9.898504097214047,37931206.23436167,13.569028932236087,20601669.44813279 +S2004_S26,6,0,0.0,0.0879536391925707,2.979453131208997,5.740554737818609,8.326038922018169,37931206.23436167,10.624464576746492,27114281.51279718 +Eggther,6,0,0.0,0.172668559406008,2.9192225018207965,1.4730030772417777,3.7409023710838207,37931206.23436167,8.642139132075997,20145682.99235166 +S2004_S29,6,0,0.0,0.4789780006080462,0.6757080108527679,2.7557248445643685,8.158214945554526,37931206.23436167,11.646530243611249,16841921.43347099 +Beli,6,0,0.0,0.09561845720389078,2.752625430672901,4.516010761083898,9.121299435878083,37931206.23436167,15.210929848605181,20773783.42197962 +Gunnlod,6,0,0.0,0.226076682689381,2.7357081254105426,5.119796371565419,5.548274930000551,37931206.23436167,8.66055015673005,21197365.96146452 +Thiazzi,6,0,0.0,0.6450848691149605,2.845339836325127,1.2720219777086248,6.562462436528079,37931206.23436167,8.670399220881375,23127332.4760807 +S2004_S34,6,0,0.0,0.3017190320668735,2.8740792360253704,5.106131423796398,11.293352382424656,37931206.23436167,11.730300214523249,24395304.99783318 +Alvaldi,6,0,0.0,0.2582184555697478,3.0726499457143404,5.612695574561711,8.89301863110616,37931206.23436167,14.509329182967388,22102349.14392762 +Geirrod,6,0,0.0,0.5736601843779979,2.627325491987274,2.231025380152224,8.33209987954837,37931206.23436167,10.04278565670569,22261401.74397198 +Ariel,7,0,581.1,0.001520812328868678,1.7055238633372776,2.925966800119804,3.717591278449178,5794034.041087669,6.384356082881187,190941.3469791885 +Umbriel,7,0,584.7,0.004170165145635332,1.7045944407677416,2.925838230568413,8.771847680053078,5794036.01334512,13.505588651166109,266012.188748696 +Titania,7,0,788.9,0.002479000317146799,1.7072525972262438,2.9254827496728866,6.45308589643617,5794173.410976084,7.751903648376653,436292.6755951638 +Oberon,7,0,761.4,0.0005523244847399845,1.7082558923561093,2.927886276952037,7.361139954006116,5794164.820180837,8.992958069369323,583549.944051016 +Miranda,7,0,0.0,0.001509798566639019,1.697405197138473,3.0034949304422995,7.559190468573284,5793954.715868137,8.642374810004048,129871.7551017135 +Cordelia,7,0,13.0,0.001322303729150208,1.7046518404795383,2.92349786656146,6.231179060502699,5793950.610340896,12.303231132790366,49835.21385103573 +Ophelia,7,0,16.0,0.009279607221164311,1.7048819042316854,2.922359381437089,3.5358837869201247,5793950.610340896,7.047959938570141,53837.07958124099 +Bianca,7,0,22.0,0.006446752078773073,1.6656362575352601,2.9172399567793548,8.365898388836268,5793950.610340896,13.403299126167246,59235.41271928998 +Cressida,7,0,33.0,0.004665124201944303,1.693686481780893,2.9548805111637932,7.099234139382491,5793950.610340896,8.256192849589539,61833.71506841925 +Desdemona,7,0,29.0,0.007827487450406784,1.71396646483352,2.980453444044353,7.796118667648966,5793950.610340896,13.745391798195458,62724.85919270847 +Juliet,7,0,42.0,0.006323344950837767,1.7501603306176914,2.9547137521233404,5.865963861743799,5793950.610340896,10.578426620280958,64422.10596238832 +Portia,7,0,55.0,0.003018625125577158,1.6599097021136702,2.9164286363637926,5.510304372977769,5793950.610340896,7.703267276427566,66158.63687770942 +Rosalind,7,0,29.0,0.00412170850266697,1.7204124073588467,2.951533685362481,4.685607790922413,5793950.610340896,10.580628838249778,69986.49424719805 +Belinda,7,0,34.0,0.002256686752468195,1.6808834271929978,2.9231736241907242,3.940822296259206,5793950.610340896,4.033975871306257,75310.73686843611 +Puck,7,0,77.0,0.009536232265293406,1.7048512607886783,2.9075232556612227,7.804280500035663,5793950.610340896,13.814393421181046,86053.09044142197 +Caliban,7,0,0.0,0.08119724815091556,2.4395398793560035,3.0557860615412857,8.977352145903668,5793950.610340896,9.435707579754553,7169876.3040474 +Sycorax,7,0,0.0,0.5134933040044672,2.6634967891903325,4.460969341893711,4.761734554716822,5793950.610340896,9.327494522222826,12178044.04987088 +Prospero,7,0,0.0,0.3229690891358025,2.5534618210625966,5.587057556919946,8.57836030091678,5793950.610340896,12.898454939490968,16286787.27820091 +Setebos,7,0,0.0,0.5585285941031115,2.556328401839425,4.35938020887576,4.423691237442906,5793950.610340896,7.444744692929646,17444178.31282778 +Stephano,7,0,0.0,0.1442159484550798,2.4722326502112297,3.306631916736132,3.80781066708052,5793950.610340896,8.26704282023073,7956684.35891261 +Trinculo,7,0,0.0,0.2229358202983595,2.8998788315836728,3.471297555174544,6.290512818486576,5793950.610340896,9.480807060445638,8498978.290312508 +Francisco,7,0,0.0,0.1377336702085726,2.5752706070000526,1.7979481740761092,3.9497507669274645,5793950.610340896,4.336907601149294,4277264.165989432 +Margaret,7,0,0.0,0.8276202314642419,0.8971670323981537,0.45902219270181294,1.7412212308613622,5793950.610340896,7.393436065507443,14468609.00141123 +Ferdinand,7,0,0.0,0.4211557089199063,2.918002234580213,3.9017866549636517,6.815350138250478,5793950.610340896,7.185439269827814,20408683.17999136 +Perdita,7,0,0.0,0.004380469857484663,1.678102924874288,2.931543797527558,8.079972023027052,5793950.610340896,12.051635395666803,76469.27923712372 +Mab,7,0,0.0,0.006169189441036547,1.737383382584908,2.9238544136920397,6.591154345174909,5793950.610340896,6.7091776639548595,97778.33738100463 +Cupid,7,0,0.0,0.007655878765124752,1.706812362947364,2.890327652443929,8.42242982146135,5793950.610340896,9.41976392569748,74448.62171786895 +Triton,8,0,1352.6,6.368939270099938e-06,2.2733923964622478,3.767321786172477,5.07133263202976,6836531.640925204,11.353027071265348,354765.8843162152 +Nereid,8,0,170.0,0.750641162299629,0.08832265400549195,5.577894798221993,10.76155286447748,6835103.145462294,14.52493295748952,5511154.843796642 +Naiad,8,0,29.0,0.001531450161272326,0.5775096822286722,0.8901547398369463,2.673117960374534,6835103.153992576,8.95626615537538,48293.45616575299 +Thalassa,8,0,40.0,0.001491738603351986,0.4965889248838783,0.858148620912089,5.613521044466604,6835103.169051026,11.839049112680527,50139.68945302315 +Despina,8,0,74.0,0.0009735678520727593,0.4977097432424236,0.8538408978164691,2.284326351341239,6835103.262194134,2.566930328840952,52588.09043833725 +Galatea,8,0,79.0,0.001016334887946172,0.4974479956766216,0.8521132517748609,1.7867627201253198,6835103.335360798,1.89622517827695,62005.18586605151 +Larissa,8,0,96.0,0.000665776046466113,0.49893186508174503,0.8439846651671378,4.0786671407727875,6835103.400306035,6.7481034570845635,73592.28986650139 +Proteus,8,0,208.0,0.0004901325001554036,0.5059993551135175,0.8426269796820822,6.5456336330743765,6835105.728884674,11.496610988744049,117674.7445063193 +Halimede,8,0,0.0,0.2599145942848126,1.9512946717376756,3.7951960677176637,6.533534844152109,6835103.145462294,10.547369174302855,16605281.25905555 +Psamathe,8,0,0.0,0.3411775966649227,2.154469849443864,5.590952948264428,7.836362600783113,6835103.145462294,11.036358106366983,46984377.98359938 +Sao,8,0,0.0,0.1403272551314755,0.9248408198127013,1.0850115342240123,2.1681427287980366,6835103.145462294,2.413293659787219,22181932.61364008 +Laomedeia,8,0,0.0,0.3733535934039463,0.6572933275601466,0.9240855670674438,3.242865872642059,6835103.145462294,5.9413355717414245,23528889.36977404 +Neso,8,0,0.0,0.6203866551970727,2.474016010154743,0.5955778744977669,1.7693830770379806,6835103.145462294,5.69193516639977,51344182.89142882 +Hippocamp,8,0,0.0,0.0007323455258285733,0.5029197227502565,0.8480234789374675,6.073440657377766,6835103.145462294,11.437603430463884,105317.1068878638 +Charon,9,0,0.0,0.0001610672790944719,1.9703163256269232,3.968733624593348,6.980918888206121,975.4272614547626,9.575614967851319,19595.76204124312 +Nix,9,0,18.0,0.2041774417402857,1.9702750628633936,3.9692148607076523,9.288801456899037,869.3276188072467,11.98979386083055,39325.7446167599 +Hydra,9,0,18.5,0.3668688814492705,1.966753778407219,3.9717984728128894,8.916677920677023,869.3281305936245,14.955091038013421,98706.39573541206 +Kerberos,9,0,6.0,0.5554927391018276,1.9763845546072847,3.966095125284709,9.179753572315702,869.3261830156587,15.410385151662753,133083.7395696985 +Styx,9,0,5.2,0.1008358017600682,1.9698650260911206,3.9678696540695384,9.138903004384982,869.3261630850667,14.127864821967695,42207.15400974844 diff --git a/src/main.rs b/src/main.rs index ae4233e..d872cc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod window; +mod ui; mod tacmap; mod wgpuctx; mod eguictx; diff --git a/src/solar_system.rs b/src/solar_system.rs index 6730719..c98a0e8 100644 --- a/src/solar_system.rs +++ b/src/solar_system.rs @@ -1,9 +1,8 @@ -use cgmath::Point3; use serde::{Deserialize}; -use crate::{GameState, known_stars::{KNOWN_STARS, StarNotFoundError}, timeman::Second}; +use crate::{GameState, known_stars::{KNOWN_STARS, StarNotFoundError}, timeman::{Second, TimeMan}}; use std::{cell::RefCell, error::Error}; -const GRAVITATIONAL_CONSTANT: f64 = 6.67408e-11; +const GRAVITATIONAL_CONSTANT: f64 = 6.67408e-20; pub type Kilograms = f64; pub type Kilometers = f64; @@ -34,7 +33,7 @@ pub struct SerialOrbitalBody pub struct OrbitalBody { body: SerialOrbitalBody, - position: Option> + position: Option> } pub struct SolarSystem @@ -60,14 +59,17 @@ impl SolarSystem match record.orbits { Some(orbits) => { if record.sgp == 0.0 { - record.sgp = bodies[orbits].body.mass + record.mass * GRAVITATIONAL_CONSTANT; + record.sgp = (bodies[orbits].body.mass + record.mass) * GRAVITATIONAL_CONSTANT; } } None => {} } println!("New body: {:?}", record); - bodies.push(OrbitalBody { body: record, position: None }); + bodies.push(OrbitalBody { + body: record, + position: None + }); } Ok(Self { @@ -105,6 +107,21 @@ impl SolarSystem self.time = Some(time); } + pub fn body_position( + &self, + body: &OrbitalBody) + -> cgmath::Vector3 + { + match body.body.orbits { + Some(parent) => { + let body_pos = body.position(); + let parent_pos = self.bodies[parent].position(); + body_pos + parent_pos + }, + None => body.position() + } + } + pub fn update( &mut self, time: Second) @@ -125,15 +142,15 @@ impl OrbitalBody { pub fn name(&self) -> &String { &self.body.name } pub fn radius(&self) -> f32 { self.body.radius as f32 } - pub fn position(&self) -> Point3 { self.position.unwrap() } + pub fn position(&self) -> cgmath::Vector3 { self.position.unwrap() } fn calculate_orbit_at( &self, time: Second) - -> Point3 + -> cgmath::Vector3 { if self.body.orbits.is_none() { - return Point3::::new(0.0, 0.0, 0.0); + return cgmath::Vector3::::new(0.0, 0.0, 0.0); } let eccentricity = self.body.eccentricity; @@ -141,8 +158,8 @@ impl OrbitalBody let long_asc_node = self.body.long_asc_node; let arg_periaps = self.body.long_periapsis - long_asc_node; - let sma_cubed = self.body.semi_major_axis.powf(3.0); - let mean_motion = (self.body.sgp / sma_cubed.abs()).sqrt(); + let sma_cubed = self.body.semi_major_axis.powf(3.0); + let mean_motion = (self.body.sgp / sma_cubed).sqrt(); let mean_anomaly_epoch = self.body.mean_long - self.body.long_periapsis; let mean_anomaly = mean_anomaly_epoch + (mean_motion * time as f64); @@ -179,7 +196,7 @@ impl OrbitalBody let y = r * i_sin * vw_sin; let z = r * (omega_sin * vw_cos + omega_cos * vw_sin * i_cos); - Point3::::new(x, y, z) + cgmath::Vector3::::new(x, y, z) } } diff --git a/src/tacmap.rs b/src/tacmap.rs index b245f77..e4cb76a 100644 --- a/src/tacmap.rs +++ b/src/tacmap.rs @@ -16,10 +16,10 @@ use crate::GameState; use crate::canvas::Canvas; use crate::solar_system::SolarSystem; use crate::solar_system::SystemId; +use crate::ui; use crate::wgpuctx::WgpuCtx; use render::*; use camera::*; -use crate::window::ui::GameWindowUiState; pub struct TacticalMap { @@ -51,7 +51,7 @@ impl TacticalMap let camera = Camera::new( wgpuctx, - cgmath::Point3::::new(0.0, 0.0, 1.0), + cgmath::Vector3::new(0.0, 0.0, 1.0), cgmath::Deg(0.0), cgmath::Rad(0.0)); @@ -59,7 +59,7 @@ impl TacticalMap surface_size.width, surface_size.height, cgmath::Deg(60.0), - (0.1, 1000.0)); + (0.01, 1000.0)); Self { canvas: canvas, @@ -83,12 +83,13 @@ impl TacticalMap pub fn update( &mut self, game_state: &RefCell, - ui_state: &mut GameWindowUiState, + ui_state: &mut ui::State, dt: Duration) { - ui_state.camera_scale = self.camera.get_scale(); - ui_state.camera_pos = Some(self.camera.get_position()); - self.camera.set_target(ui_state.camera_target); + ui_state.camera_info.camera_scale = self.camera.get_scale(); + ui_state.camera_info.camera_pos = Some(self.camera.get_abs_position()); + ui_state.camera_info.camera_rot = Some(self.camera.get_rotation()); + self.camera.set_target(ui_state.camera_info.target); self.camera_controller.update(&mut self.camera, game_state, ui_state, dt); } @@ -138,7 +139,7 @@ impl TacticalMap //Update buffers for the current system and time. tacrender.rebuild(wgpuctx, current_system); match tacrender.update( - wgpuctx, current_system, + wgpuctx, current_system, &self.camera, game_state.timeman().seconds()) { Ok(()) => {}, diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs index c6ee5c0..c573cfb 100644 --- a/src/tacmap/camera.rs +++ b/src/tacmap/camera.rs @@ -1,9 +1,9 @@ use std::{cell::RefCell, time::Duration}; -use cgmath::{EuclideanSpace, InnerSpace, Point3, Rad, Vector2, Vector3, Vector4, Zero, perspective}; +use cgmath::{EuclideanSpace, InnerSpace, Point2, Point3, Rad, Vector2, Vector3, Vector4, Zero, perspective}; use winit::{event::ElementState, keyboard::KeyCode}; -use crate::{GameState, solar_system, wgpuctx::WgpuCtx, window::ui::GameWindowUiState}; +use crate::{GameState, solar_system::{self, Kilometers}, ui, wgpuctx::WgpuCtx}; pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::from_cols( Vector4::new(1.0, 0.0, 0.0, 0.0), @@ -14,8 +14,8 @@ pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4 = cgmath::Matrix4::from_co pub struct Camera { - abs_position: Point3, - rel_position: Point3, + abs_position: Vector3, + rel_position: Vector3, pitch: Rad, yaw: Rad, scale: f32, @@ -55,7 +55,7 @@ pub struct Projection impl Camera { pub fn new< - V: Into>, + V: Into>, Y: Into>, P: Into> >( @@ -98,11 +98,11 @@ impl Camera ); Self { abs_position: position.into(), - rel_position: Point3::new(0.0, 0.0, 0.0), + rel_position: Vector3::new(0.0, 0.0, 0.0), yaw: yaw.into(), pitch: pitch.into(), - scale: 1.0, - target: None, + scale: 1e-7, + target: Some(0), buffer: buffer, staging_buffer: staging_buffer, bindgroup: bind_group @@ -112,12 +112,17 @@ impl Camera pub fn get_scale(&self) -> f32 { self.scale } - pub fn get_position(&self) -> Point3 + pub fn get_abs_position(&self) -> Vector3 + { self.abs_position } + + pub fn get_combined_position(&self) -> Vector3 + { + self.abs_position + self.rel_position.map(|v| { v as f64 }) + } + + pub fn get_rotation(&self) -> Vector2> { - Point3::new( - self.abs_position.x + self.rel_position.x, - self.abs_position.y + self.rel_position.y, - self.abs_position.z + self.rel_position.z) + Vector2::new(self.yaw, self.pitch) } pub fn bindgroup_layout(wgpuctx: &WgpuCtx) @@ -168,15 +173,12 @@ impl Camera { if target == self.target { return; } if !target.is_some() || !self.target.is_some() { - self.abs_position = self.get_position(); - self.rel_position = Point3::new(0.0, 0.0, 0.0); + self.abs_position = self.get_combined_position(); + self.rel_position = Vector3::new(0.0, 0.0, 0.0); } self.target = target; } - pub fn get_target(&self) -> Option - { self.target } - pub fn view_matrix( &self) -> cgmath::Matrix4 { @@ -186,12 +188,12 @@ impl Camera if self.target.is_some() { cgmath::Matrix4::look_at_rh( - self.get_position(), - self.abs_position, + Point3::new(self.rel_position.x, self.rel_position.y, self.rel_position.z), + Point3::new(0.0, 0.0, 0.0), Vector3::unit_y()) }else{ cgmath::Matrix4::look_to_rh( - self.get_position(), + Point3::new(0.0, 0.0, 0.0), Vector3::new( pitch_cos * yaw_cos, pitch_sin, @@ -250,25 +252,26 @@ impl CameraController fn update_orbit( &mut self, camera: &mut Camera, - target: Point3, + target: Vector3, min_radius: f32, dt: Duration) { - camera.abs_position = target * camera.scale; + camera.abs_position = target; let dt = dt.as_secs_f32(); let speed = 1.0; - let current_radius = camera.rel_position.to_vec().magnitude(); + let current_radius = camera.rel_position.magnitude(); let polar_diff = (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt; let azimuth_diff = (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt; let dist_diff = (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt; - camera.pitch.0 += polar_diff; - let polar_cap = cgmath::Deg(179.999).0; - if camera.pitch.0 > polar_cap { camera.pitch.0 = polar_cap; } - if camera.pitch.0 < -polar_cap { camera.pitch.0 = -polar_cap; } + let polar_final = camera.pitch.0 + polar_diff; + let polar_cap = Into::>::into(cgmath::Deg(89.999)).0; + if polar_final > polar_cap { camera.pitch.0 = polar_cap; } else + if polar_final < -polar_cap { camera.pitch.0 = -polar_cap; } else + { camera.pitch.0 = polar_final; } camera.yaw.0 += azimuth_diff; @@ -276,7 +279,7 @@ impl CameraController let (p_sin, p_cos) = camera.pitch.0.sin_cos(); let radius = f32::max(min_radius * camera.scale, current_radius + dist_diff); - camera.rel_position = Point3::new( + camera.rel_position = Vector3::new( radius * p_cos * az_cos, radius * p_sin, radius * p_cos * az_sin @@ -296,12 +299,12 @@ impl CameraController let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize(); let up = Vector3::new(0.0, 1.0, 0.0); - - camera.rel_position += forward * (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt; - camera.rel_position += right * (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt; - camera.rel_position += up * (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt; - - camera.abs_position = camera.rel_position; + camera.abs_position += (forward * (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt) + .map(|v| { v as f64 } ); + camera.abs_position += (right * (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt) + .map(|v| { v as f64 }); + camera.abs_position += (up * (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt) + .map(|v| { v as f64 }); camera.pitch.0 += (self.rotation_pos_delta.x - self.rotation_neg_delta.x) * speed * dt; camera.yaw.0 += (self.rotation_pos_delta.y - self.rotation_neg_delta.y) * speed * dt; @@ -311,13 +314,13 @@ impl CameraController &mut self, camera: &mut Camera, game_state: &RefCell, - ui_state: &mut GameWindowUiState, + ui_state: &mut ui::State, dt: Duration) { camera.scale *= 1.0 + ((self.scale_delta.y - self.scale_delta.x) * 0.1); - camera.scale = f32::max(1e-16, f32::min(1.0, camera.scale)); + camera.scale = f32::max(1e-16, f32::min(1e-6, camera.scale)); - match ui_state.camera_target { + match ui_state.camera_info.target { Some(body_id) => { let game_state = game_state.borrow(); let solar_systems = game_state.solar_systems(); @@ -329,8 +332,8 @@ impl CameraController let body = ¤t_system.bodies()[body_id]; self.update_orbit( camera, - body.position().cast().unwrap(), - body.radius(), + current_system.body_position(body).cast().unwrap(), + body.radius() * 2.0, dt); } None => self.update_pan(camera, dt) diff --git a/src/tacmap/render.rs b/src/tacmap/render.rs index 0f6b409..26d6977 100644 --- a/src/tacmap/render.rs +++ b/src/tacmap/render.rs @@ -9,7 +9,7 @@ use crate::{solar_system::{SolarSystem, SystemId}, timeman::Second, vertex::{sel struct BodyInstance { - position: cgmath::Point3, + position: cgmath::Vector3, radius: f32 } @@ -36,6 +36,7 @@ pub struct BodyRenderer { needs_rebuild: bool, last_time: Option, + last_pos: Option>, pipeline: wgpu::RenderPipeline, @@ -73,6 +74,7 @@ impl BodyRenderer Self { needs_rebuild: true, last_time: None, + last_pos: None, pipeline: render_pipeline, body_vertex_buffer, body_instance_buffer: None @@ -113,6 +115,7 @@ impl BodyRenderer ); self.last_time = None; + self.last_pos = None; self.body_instance_buffer = Some((bodies.len(), buffer)); } @@ -120,21 +123,21 @@ impl BodyRenderer &mut self, wgpuctx: &WgpuCtx, solar_system: &SolarSystem, + camera: &Camera, time: Second) -> Result<(), Box> { //If the last updated time is the same, we don't need to update //the positions of all the bodies. - match self.last_time { - Some(last_time) => { - if last_time == time { - return Ok(()); - } + if self.last_time.is_some_and(|last_time| { last_time == time }) { + if self.last_pos.is_some_and(|last_pos| { last_pos == camera.get_abs_position() }) { + return Ok(()) } - None => {} } self.last_time = Some(time); + self.last_pos = Some(camera.get_abs_position()); + let (_, bodies_buffer) = match &self.body_instance_buffer { Some(tuple) => tuple, None => return Err(Box::new(NeedsRebuildError)) @@ -142,9 +145,9 @@ impl BodyRenderer let bodies = solar_system.bodies(); let body_instances = bodies.iter().map(|body| { - let position = body.position(); + let position = solar_system.body_position(body); BodyInstance { - position: position, + position: (position - self.last_pos.unwrap()), radius: body.radius() }.raw() }).collect::>(); diff --git a/src/timeman.rs b/src/timeman.rs index 9d17999..32a6f45 100644 --- a/src/timeman.rs +++ b/src/timeman.rs @@ -4,14 +4,18 @@ use std::{fmt::Display, string}; use std::error::Error; use crate::GameState; -use crate::window::ui::GameWindowUiState; pub type Second = u64; +pub const MINUTE: Second = 60; +pub const HOUR: Second = MINUTE * 60; +pub const DAY: Second = HOUR * 24; +pub const YEAR: Second = DAY * 365; + pub struct TimeMan { time: Second, - auto_tick: Option + pub auto_tick: Option } impl TimeMan @@ -58,11 +62,11 @@ impl TimeMan } format!("{}{}{}{}{}", - if seconds > 0 { format!("{}s", seconds) } else { format!("") }, - if minutes > 0 { format!("{}m", minutes) } else { format!("") }, - if hours > 0 { format!("{}h", hours) } else { format!("") }, + if years > 0 { format!("{}y", years) } else { format!("") }, if days > 0 { format!("{}d", days) } else { format!("") }, - if years > 0 { format!("{}y", years) } else { format!("") }) + if hours > 0 { format!("{}h", hours) } else { format!("") }, + if minutes > 0 { format!("{}m", minutes) } else { format!("") }, + if seconds > 0 { format!("{}s", seconds) } else { format!("") }) } diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..f6f7721 --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,114 @@ +pub mod camera_info; + +use std::cell::RefCell; + +use cgmath::Vector3; + +use crate::{GameState, eguictx::EguiCtx, solar_system, timeman::{self, Second, TimeMan}, ui::camera_info::CameraWindowState}; + +mod ui { + pub use super::camera_info; +} + +#[derive(Default, Clone)] +pub struct State +{ + pub current_system: Option, + pub auto_time: Option, + pub do_auto_tick: bool, + + pub camera_info: CameraWindowState +} + +impl State +{ + pub fn render( + &mut self, + game_state: &RefCell, + eguictx: &EguiCtx) + { + State::render_topbar(self, game_state, eguictx); + + CameraWindowState::render( + self, + game_state, + eguictx); + } + + fn render_topbar( + state: &mut State, + game_state: &RefCell, + eguictx: &EguiCtx) + { + let mut game_state = game_state.borrow_mut(); + + egui::TopBottomPanel::top("topbar").show( + eguictx.context(), + |ui| { + + ui.horizontal(|ui| { + let solar_systems = game_state.solar_systems(); + let selected_system_label = match state.current_system { + Some(id) => solar_systems[id].name(), + None => "" + }; + + egui::ComboBox::from_label("Current System") + .selected_text(selected_system_label) + .show_ui(ui, |ui| { + + for (i, system) in solar_systems.iter().enumerate() { + ui.selectable_value( + &mut state.current_system, + Some(i), + system.name() + ); + } + }); + + let current_system = match state.current_system { + Some(id) => &solar_systems[id], + None => return + }; + }); + + ui.horizontal(|ui| { + ui.label(format!("Time: {: <16}", TimeMan::format_duration(game_state.timeman().seconds()))); + + let button_seconds = [ + 1, + 5, + 30, + timeman::MINUTE, + timeman::MINUTE * 5, + timeman::MINUTE * 30, + timeman::HOUR, + timeman::DAY, + timeman::DAY * 5, + timeman::YEAR + ]; + let selected_button = state.auto_time; + + button_seconds.iter().for_each(|&seconds| { + ui.vertical(|ui| { + let auto_selected = match selected_button { + Some(o) => o == seconds, + None => false + }; + let label = TimeMan::format_duration(seconds); + + if ui.button(label.clone()).clicked() { + game_state.timeman_mut().advance(seconds); + } + + if ui.add(egui::Button::new(label.clone()).selected(auto_selected)).clicked() { + state.auto_time = Some(seconds); + } + }); + }); + + ui.checkbox(&mut state.do_auto_tick, "Auto"); + }); + }); + } +} diff --git a/src/ui/camera_info.rs b/src/ui/camera_info.rs new file mode 100644 index 0000000..35cd54b --- /dev/null +++ b/src/ui/camera_info.rs @@ -0,0 +1,74 @@ +use std::cell::RefCell; + +use crate::{GameState, eguictx::EguiCtx, solar_system, ui}; + + +#[derive(Default, Clone)] +pub struct CameraWindowState +{ + pub camera_scale: f32, + pub camera_pos: Option>, + pub camera_rot: Option>>, + pub target: Option, +} + +impl CameraWindowState +{ + pub fn render( + ui_state: &mut ui::State, + game_state: &RefCell, + eguictx: &EguiCtx) + { + if ui_state.current_system.is_none() { + return; + } + + let camera_state = &mut ui_state.camera_info; + let game_state = game_state.borrow(); + + let current_system = &game_state.solar_systems()[ui_state.current_system.unwrap()]; + + egui::Window::new("Camera Info").show(eguictx.context(), |ui| { + ui.vertical(|ui| { + let selected_body_label = match camera_state.target { + Some(id) => current_system.bodies()[id].name(), + None => "" + }; + + ui.separator(); + + egui::ComboBox::from_label("Camera Target") + .selected_text(selected_body_label) + .show_ui(ui, |ui| { + + for (i, body) in current_system.bodies().iter().enumerate() { + ui.selectable_value( + &mut camera_state.target, + Some(i), + body.name()); + } + }); + + ui.label(format!("Scale: {}", camera_state.camera_scale)); + match camera_state.camera_pos { + Some(pos) => { ui.label(format!("Pos x:{:^10} y:{:^10} z:{:^10}", + pos.x, + pos.y, + pos.z + )); }, + None => {} + } + match camera_state.camera_rot { + Some(rot) => { + ui.label(format!("pitch:{:^10} yaw:{:^10}", + rot.y.0, + rot.x.0, + )); + }, + None => {} + } + + }); + }); + } +} diff --git a/src/window.rs b/src/window.rs index 0be88e7..28c69f8 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,9 +1,3 @@ -pub mod ui; - -mod window { - pub use super::ui; -} - use std::cell::RefCell; use std::sync::{Arc}; use std::time::Duration; @@ -12,13 +6,11 @@ use winit::event::{ElementState, WindowEvent}; use winit::keyboard::KeyCode; use crate::tacmap::TacticalMap; -use crate::{GameState, SystemicApp}; +use crate::{GameState, SystemicApp, ui}; use crate::solar_system::{SolarSystem, SystemId}; use crate::wgpuctx::{RenderPassBuilder, WgpuCtx}; use crate::eguictx::EguiCtx; -use ui::*; - pub struct GameWindow { window: Arc, @@ -27,7 +19,7 @@ pub struct GameWindow tactical_map: TacticalMap, - ui_state: GameWindowUiState + ui_state: ui::State } impl GameWindow @@ -51,6 +43,15 @@ impl GameWindow winit::dpi::LogicalPosition::new(0.0, 0.0), winit::dpi::LogicalSize::new(1.0, 1.0)); + let ui_state = ui::State{ + current_system: Some(0), + camera_info: ui::camera_info::CameraWindowState { + target: Some(0), + ..Default::default() + }, + ..Default::default() + }; + Ok(Self { window: window, wgpuctx: wgpuctx, @@ -66,6 +67,14 @@ impl GameWindow game_state: &RefCell, dt: Duration) { + { + let mut game_state = game_state.borrow_mut(); + if self.ui_state.do_auto_tick { + game_state.timeman.auto_tick = self.ui_state.auto_time; + }else{ + game_state.timeman.auto_tick = None; + } + } self.tactical_map.update(game_state, &mut self.ui_state, dt); } @@ -103,7 +112,7 @@ impl GameWindow } { self.eguictx.prepare(&self.window); - self.ui_state = GameWindowUiState::render(&self.ui_state, game_state, &self.eguictx); + self.ui_state.render(game_state, &self.eguictx); self.eguictx.present( &self.window, diff --git a/src/window/ui.rs b/src/window/ui.rs deleted file mode 100644 index 60cd795..0000000 --- a/src/window/ui.rs +++ /dev/null @@ -1,120 +0,0 @@ -use std::cell::RefCell; - -use cgmath::Vector3; - -use crate::{GameState, eguictx::EguiCtx, solar_system, timeman::{Second, TimeMan}}; - -#[derive(Default, Clone)] -pub struct GameWindowUiState -{ - pub current_system: Option, - pub camera_scale: f32, - pub camera_pos: Option>, - pub camera_target: Option, - pub auto_time: Option, - pub do_auto_tick: bool -} - -impl GameWindowUiState -{ - pub fn render( - old_state: &GameWindowUiState, - game_state: &RefCell, - eguictx: &EguiCtx) - -> Self - { - let mut new_state = old_state.clone(); - - { GameWindowUiState::render_topbar(&mut new_state, game_state, eguictx); } - - new_state - } - - fn render_topbar( - state: &mut GameWindowUiState, - game_state: &RefCell, - eguictx: &EguiCtx) - { - let mut game_state = game_state.borrow_mut(); - - egui::TopBottomPanel::top("topbar").show( - eguictx.context(), - |ui| { - - ui.horizontal(|ui| { - let solar_systems = game_state.solar_systems(); - let selected_system_label = match state.current_system { - Some(id) => solar_systems[id].name(), - None => "" - }; - - egui::ComboBox::from_label("Current System") - .selected_text(selected_system_label) - .show_ui(ui, |ui| { - - for (i, system) in solar_systems.iter().enumerate() { - ui.selectable_value( - &mut state.current_system, - Some(i), - system.name() - ); - } - }); - - let current_system = match state.current_system { - Some(id) => &solar_systems[id], - None => return - }; - - let selected_body_label = match state.camera_target { - Some(id) => current_system.bodies()[id].name(), - None => "" - }; - - ui.separator(); - - egui::ComboBox::from_label("Camera Target") - .selected_text(selected_body_label) - .show_ui(ui, |ui| { - - for (i, body) in current_system.bodies().iter().enumerate() { - ui.selectable_value( - &mut state.camera_target, - Some(i), - body.name()); - } - }); - - match state.camera_pos { - Some(pos) => { ui.label(format!("Pos x{} y{} z{}", pos.x, pos.y, pos.z)); }, - None => {} - } - }); - - ui.horizontal(|ui| { - ui.label(format!("Time: {}", TimeMan::format_duration(game_state.timeman().seconds()))); - - let button_seconds = [1, 5, 30, 60, 60*5, 60*30, 60*60, 60*60*24, 60*60*24*5, 60*60*24*30]; - let selected_button = state.auto_time; - - button_seconds.iter().for_each(|&seconds| { - ui.vertical(|ui| { - let auto_selected = match selected_button { - Some(o) => o == seconds, - None => false - }; - let label = TimeMan::format_duration(seconds); - - if ui.button(label.clone()).clicked() { - game_state.timeman_mut().advance(seconds); - } - - if ui.add(egui::Button::new(label.clone()).selected(auto_selected)).clicked() { - state.auto_time = Some(seconds); - } - }); - }); - }); - }); - } -} -- cgit v1.2.3