@@ -161,7 +161,8 @@ static void update_orbit_cache(Satellite* sat, double current_epoch) {
161161 double time_step = period_days / (ORBIT_CACHE_SIZE - 1 );
162162 for (int i = 0 ; i < ORBIT_CACHE_SIZE ; i ++ ) {
163163 double t = current_epoch + (i * time_step );
164- sat -> orbit_cache [i ] = Vector3Scale (calculate_position (sat , t ), 1.0f / DRAW_SCALE );
164+ double t_unix = get_unix_from_epoch (t );
165+ sat -> orbit_cache [i ] = Vector3Scale (calculate_position (sat , t_unix ), 1.0f / DRAW_SCALE );
165166 }
166167 sat -> orbit_cached = true;
167168}
@@ -181,7 +182,8 @@ static void draw_orbit_3d(Satellite* sat, double current_epoch, bool is_highligh
181182
182183 for (int i = 0 ; i <= segments ; i ++ ) {
183184 double t = current_epoch + (i * time_step );
184- Vector3 pos = Vector3Scale (calculate_position (sat , t ), 1.0f / DRAW_SCALE );
185+ double t_unix = get_unix_from_epoch (t );
186+ Vector3 pos = Vector3Scale (calculate_position (sat , t_unix ), 1.0f / DRAW_SCALE );
185187
186188 if (i > 0 ) DrawLine3D (prev_pos , pos , orbitColor );
187189 prev_pos = pos ;
@@ -382,6 +384,15 @@ int main(void) {
382384 }
383385 }
384386
387+ double current_unix = get_unix_from_epoch (current_epoch );
388+
389+ // precalculate all satellite positions for the current frame
390+ for (int i = 0 ; i < sat_count ; i ++ ) {
391+ // don't waste time calculating if it's hidden and not selected
392+ if (hide_unselected && selected_sat != NULL && & satellites [i ] != selected_sat ) continue ;
393+ satellites [i ].current_pos = calculate_position (& satellites [i ], current_unix );
394+ }
395+
385396 // fading math
386397 bool should_hide = (hide_unselected && selected_sat != NULL );
387398 if (should_hide ) {
@@ -432,7 +443,6 @@ int main(void) {
432443 float hit_radius_pixels = 12.0f * cfg .ui_scale ; // hitbox size in screen pixels
433444
434445 for (int i = 0 ; i < sat_count ; i ++ ) {
435- satellites [i ].current_pos = calculate_position (& satellites [i ], current_epoch );
436446 // prevent raycasting on hidden satellites
437447 if (hide_unselected && selected_sat != NULL && & satellites [i ] != selected_sat ) continue ;
438448
@@ -468,11 +478,13 @@ int main(void) {
468478 float closest_dist = 9999.0f ;
469479
470480 for (int i = 0 ; i < sat_count ; i ++ ) {
471- satellites [i ].current_pos = calculate_position (& satellites [i ], current_epoch );
472481 // Prevent raycasting on fading/hidden satellites
473482 if (hide_unselected && selected_sat != NULL && & satellites [i ] != selected_sat ) continue ;
474483
475484 Vector3 draw_pos = Vector3Scale (satellites [i ].current_pos , 1.0f / DRAW_SCALE );
485+
486+ // fast coarse culling via squared distance to avoid expensive sphere collision checks on distant satellites
487+ if (Vector3DistanceSqr (camera3d .target , draw_pos ) > (camDistance * camDistance * 16.0f )) continue ;
476488
477489 // adjust sphere radius based on distance to maintain consistent screen-size hitbox
478490 float distToCam = Vector3Distance (camera3d .position , draw_pos );
@@ -680,7 +692,8 @@ int main(void) {
680692
681693 for (int j = 0 ; j <= segments ; j ++ ) {
682694 double t = current_epoch + (j * time_step );
683- get_map_coordinates (calculate_position (& satellites [i ], t ), epoch_to_gmst (t ), cfg .earth_rotation_offset , map_w , map_h , & track_pts [j ].x , & track_pts [j ].y );
695+ double t_unix = get_unix_from_epoch (t );
696+ get_map_coordinates (calculate_position (& satellites [i ], t_unix ), epoch_to_gmst (t ), cfg .earth_rotation_offset , map_w , map_h , & track_pts [j ].x , & track_pts [j ].y );
684697 }
685698
686699 for (int offset_i = -1 ; offset_i <= 1 ; offset_i ++ ) {
@@ -816,9 +829,11 @@ int main(void) {
816829
817830 double t_peri = current_epoch + (diff_peri / active_sat -> mean_motion ) / 86400.0 ;
818831 double t_apo = current_epoch + (diff_apo / active_sat -> mean_motion ) / 86400.0 ;
832+ double t_peri_unix = get_unix_from_epoch (t_peri );
833+ double t_apo_unix = get_unix_from_epoch (t_apo );
819834
820- Vector3 draw_p = Vector3Scale (calculate_position (active_sat , t_peri ), 1.0f /DRAW_SCALE );
821- Vector3 draw_a = Vector3Scale (calculate_position (active_sat , t_apo ), 1.0f /DRAW_SCALE );
835+ Vector3 draw_p = Vector3Scale (calculate_position (active_sat , t_peri_unix ), 1.0f /DRAW_SCALE );
836+ Vector3 draw_a = Vector3Scale (calculate_position (active_sat , t_apo_unix ), 1.0f /DRAW_SCALE );
822837
823838 if (!IsOccludedByEarth (camera3d .position , draw_p , draw_earth_radius )) {
824839 Vector2 sp = GetWorldToScreen (draw_p , camera3d );
@@ -956,9 +971,11 @@ int main(void) {
956971
957972 double t_peri = current_epoch + (diff_peri / active_sat -> mean_motion ) / 86400.0 ;
958973 double t_apo = current_epoch + (diff_apo / active_sat -> mean_motion ) / 86400.0 ;
974+ double t_peri_unix = get_unix_from_epoch (t_peri );
975+ double t_apo_unix = get_unix_from_epoch (t_apo );
959976
960- double real_rp = Vector3Length (calculate_position (active_sat , t_peri ));
961- double real_ra = Vector3Length (calculate_position (active_sat , t_apo ));
977+ double real_rp = Vector3Length (calculate_position (active_sat , t_peri_unix ));
978+ double real_ra = Vector3Length (calculate_position (active_sat , t_apo_unix ));
962979 // hide the periapsis/apoapsis markers if they're currently behind the Earth in the 3D view, or just off the edge of the map in 2D
963980 if (is_2d_view ) {
964981 Vector2 p2 , a2 ;
@@ -974,8 +991,8 @@ int main(void) {
974991 periScreen = GetWorldToScreen2D (p2 , camera2d );
975992 apoScreen = GetWorldToScreen2D (a2 , camera2d );
976993 } else {
977- Vector3 draw_p = Vector3Scale (calculate_position (active_sat , t_peri ), 1.0f /DRAW_SCALE );
978- Vector3 draw_a = Vector3Scale (calculate_position (active_sat , t_apo ), 1.0f /DRAW_SCALE );
994+ Vector3 draw_p = Vector3Scale (calculate_position (active_sat , t_peri_unix ), 1.0f /DRAW_SCALE );
995+ Vector3 draw_a = Vector3Scale (calculate_position (active_sat , t_apo_unix ), 1.0f /DRAW_SCALE );
979996
980997 if (IsOccludedByEarth (camera3d .position , draw_p , draw_earth_radius )) show_peri = false;
981998 if (IsOccludedByEarth (camera3d .position , draw_a , draw_earth_radius )) show_apo = false;
0 commit comments