diff --git a/src/simulation.cpp b/src/simulation.cpp index 9258776..96046b8 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -8,15 +8,6 @@ #include #include -// 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 SimulationState* create_simulation(int max_bodies, int max_craft, int max_maneuvers, double time_step) { 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) { - reset_spacecraft_tracking(sim->max_craft); update_bodies_physics(sim); compute_global_coordinates(sim); - execute_pending_maneuvers(sim); update_spacecraft_physics(sim); compute_spacecraft_globals(sim); sim->time += sim->dt; @@ -298,10 +287,6 @@ void update_spacecraft_physics(SimulationState* sim) { continue; } - if (spacecraft_handled_this_frame[i]) { - continue; - } - CelestialBody* parent = &sim->bodies[craft->parent_index]; 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 = propagate_orbital_elements(craft->orbit, sim->dt, parent->mass); - orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity); - } -} - -void execute_pending_maneuvers(SimulationState* sim) { - for (int i = 0; i < sim->maneuver_count; i++) { - Maneuver* maneuver = &sim->maneuvers[i]; - - if (maneuver->executed) { - continue; - } - - if (maneuver->craft_index < 0 || maneuver->craft_index >= sim->craft_count) { - continue; - } - - Spacecraft* craft = &sim->spacecraft[maneuver->craft_index]; - - if (craft->parent_index < 0 || craft->parent_index >= sim->body_count) { - continue; + // Check if any pending maneuver fires this frame. If so, propagate + // 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 + // TRIGGER_TRUE_ANOMALY provides sub-step timing via scheduled_dt. + // For time triggers, scheduled_dt is always 0, so the burn applies + // at sim->time (step boundary). Could compute dt_to_burn = + // trigger_value - (sim->time - sim->dt) for exact placement. + bool maneuver_fired = false; + double burn_dt = 0.0; + Maneuver* fired_maneuver = NULL; + for (int j = 0; j < sim->maneuver_count; j++) { + Maneuver* maneuver = &sim->maneuvers[j]; + if (maneuver->executed) { + continue; + } + if (maneuver->craft_index != i) { + 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)) { - CelestialBody* parent = &sim->bodies[craft->parent_index]; - double dt_to_burn = maneuver->scheduled_dt; - - 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); - } + if (maneuver_fired) { + craft->orbit = propagate_orbital_elements(craft->orbit, burn_dt, 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); orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity); - - spacecraft_handled_this_frame[maneuver->craft_index] = true; - maneuver->scheduled_dt = 0.0; + } else { + craft->orbit = propagate_orbital_elements(craft->orbit, sim->dt, parent->mass); + orbital_elements_to_cartesian(craft->orbit, parent->mass, &craft->local_position, &craft->local_velocity); } } } diff --git a/src/simulation.h b/src/simulation.h index d3af6c0..8c14e34 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -47,7 +47,6 @@ void compute_global_coordinates(SimulationState* sim); // Simulation update helper functions void update_bodies_physics(SimulationState* sim); void update_spacecraft_physics(SimulationState* sim); -void execute_pending_maneuvers(SimulationState* sim); void compute_spacecraft_globals(SimulationState* sim); // Initialize orbital objects from orbital elements