@ -8,15 +8,6 @@
# include <cstdio>
# include <cstdio>
# include <cmath>
# include <cmath>
// FIXME: I'm not a fan of this
static bool spacecraft_handled_this_frame [ 256 ] ;
static void reset_spacecraft_tracking ( int max_craft ) {
for ( int i = 0 ; i < max_craft & & i < 256 ; i + + ) {
spacecraft_handled_this_frame [ i ] = false ;
}
}
// Create a new simulation
// Create a new simulation
SimulationState * create_simulation ( int max_bodies , int max_craft , int max_maneuvers , double time_step ) {
SimulationState * create_simulation ( int max_bodies , int max_craft , int max_maneuvers , double time_step ) {
SimulationState * sim = ( SimulationState * ) malloc ( sizeof ( SimulationState ) ) ;
SimulationState * sim = ( SimulationState * ) malloc ( sizeof ( SimulationState ) ) ;
@ -172,10 +163,8 @@ void update_soi(CelestialBody* body, CelestialBody* parent, double semi_major_ax
}
}
void update_simulation ( SimulationState * sim ) {
void update_simulation ( SimulationState * sim ) {
reset_spacecraft_tracking ( sim - > max_craft ) ;
update_bodies_physics ( sim ) ;
update_bodies_physics ( sim ) ;
compute_global_coordinates ( sim ) ;
compute_global_coordinates ( sim ) ;
execute_pending_maneuvers ( sim ) ;
update_spacecraft_physics ( sim ) ;
update_spacecraft_physics ( sim ) ;
compute_spacecraft_globals ( sim ) ;
compute_spacecraft_globals ( sim ) ;
sim - > time + = sim - > dt ;
sim - > time + = sim - > dt ;
@ -298,10 +287,6 @@ void update_spacecraft_physics(SimulationState* sim) {
continue ;
continue ;
}
}
if ( spacecraft_handled_this_frame [ i ] ) {
continue ;
}
CelestialBody * parent = & sim - > bodies [ craft - > parent_index ] ;
CelestialBody * parent = & sim - > bodies [ craft - > parent_index ] ;
Vec3 expected_pos , expected_vel ;
Vec3 expected_pos , expected_vel ;
@ -312,46 +297,46 @@ void update_spacecraft_physics(SimulationState* sim) {
craft - > orbit = cartesian_to_orbital_elements ( craft - > local_position , craft - > local_velocity , parent - > mass ) ;
craft - > orbit = cartesian_to_orbital_elements ( craft - > local_position , craft - > local_velocity , parent - > mass ) ;
}
}
craft - > orbit = propagate_orbital_elements ( craft - > orbit , sim - > dt , parent - > mass ) ;
// Check if any pending maneuver fires this frame. If so, propagate
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
// to the burn time, execute the burn, then propagate the remaining
}
// timestep. This enables sub-step interpolation for true-anomaly
}
// triggers and sets up future interpolated time triggers.
// TODO: Test interpolated burns for TRIGGER_TIME — currently only
void execute_pending_maneuvers ( SimulationState * sim ) {
// TRIGGER_TRUE_ANOMALY provides sub-step timing via scheduled_dt.
for ( int i = 0 ; i < sim - > maneuver_count ; i + + ) {
// For time triggers, scheduled_dt is always 0, so the burn applies
Maneuver * maneuver = & sim - > maneuvers [ i ] ;
// at sim->time (step boundary). Could compute dt_to_burn =
// trigger_value - (sim->time - sim->dt) for exact placement.
if ( maneuver - > executed ) {
bool maneuver_fired = false ;
continue ;
double burn_dt = 0.0 ;
}
Maneuver * fired_maneuver = NULL ;
for ( int j = 0 ; j < sim - > maneuver_count ; j + + ) {
if ( maneuver - > craft_index < 0 | | maneuver - > craft_index > = sim - > craft_count ) {
Maneuver * maneuver = & sim - > maneuvers [ j ] ;
continue ;
if ( maneuver - > executed ) {
}
continue ;
}
Spacecraft * craft = & sim - > spacecraft [ maneuver - > craft_index ] ;
if ( maneuver - > craft_index ! = i ) {
continue ;
if ( craft - > parent_index < 0 | | craft - > parent_index > = sim - > body_count ) {
}
continue ;
if ( check_maneuver_trigger ( maneuver , craft , sim ) ) {
burn_dt = maneuver - > scheduled_dt ;
fired_maneuver = maneuver ;
maneuver_fired = true ;
break ;
}
}
}
if ( check_maneuver_trigger ( maneuver , craft , sim ) ) {
if ( maneuver_fired ) {
CelestialBody * parent = & sim - > bodies [ craft - > parent_index ] ;
craft - > orbit = propagate_orbital_elements ( craft - > orbit , burn_dt , parent - > mass ) ;
double dt_to_burn = maneuver - > scheduled_dt ;
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
if ( dt_to_burn > 0.0 ) {
craft - > orbit = propagate_orbital_elements ( craft - > orbit , dt_to_burn , parent - > mass ) ;
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
}
execute_maneuver ( maneuver , craft , sim , sim - > time + dt_to_ burn) ;
execute_maneuver ( fired_maneuver , craft , sim , sim - > time + burn_dt ) ;
double remaining_dt = sim - > dt - dt_to_ burn;
double remaining_dt = sim - > dt - burn_dt ;
craft - > orbit = propagate_orbital_elements ( craft - > orbit , remaining_dt , parent - > mass ) ;
craft - > orbit = propagate_orbital_elements ( craft - > orbit , remaining_dt , parent - > mass ) ;
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
} else {
spacecraft_handled_this_frame [ maneuver - > craft_index ] = true ;
craft - > orbit = propagate_orbital_elements ( craft - > orbit , sim - > dt , parent - > mass ) ;
maneuver - > scheduled_dt = 0.0 ;
orbital_elements_to_cartesian ( craft - > orbit , parent - > mass , & craft - > local_position , & craft - > local_velocity ) ;
}
}
}
}
}
}