From 79725a787508d93cce0d0b7ac0f1824cbd8bfb47 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Fri, 30 Jan 2026 08:08:44 -0500 Subject: [PATCH] Simplify camera targeting by removing spacecraft selection from renderer - Remove selected_craft_index from RenderState, move to UIState - Camera now always targets bodies (directly selected or parent of selected spacecraft) - UI handles all spacecraft selection logic - Remove ~30 lines of duplicate/special-case code from renderer - Update all renderer functions to single body-focused path - Update UI rendering functions to use ui_state->selected_craft_index --- src/main.cpp | 6 ++-- src/renderer.cpp | 83 +++++++-------------------------------------- src/renderer.h | 5 ++- src/ui_renderer.cpp | 34 +++++++++---------- src/ui_renderer.h | 9 ++--- 5 files changed, 40 insertions(+), 97 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bc1e4c2..e5ad4c0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,6 +40,7 @@ void run_gui_simulation(SimulationState* sim) { UIState ui_state; ui_state.body_list_scroll = 0; ui_state.body_list_active = -1; + ui_state.selected_craft_index = -1; // Find root body (body with parent_index == -1) int root_body_index = -1; @@ -52,7 +53,6 @@ void run_gui_simulation(SimulationState* sim) { // Initialize render state render_state.selected_body_index = root_body_index >= 0 ? root_body_index : -1; - render_state.selected_craft_index = -1; render_state.camera_target_enabled = root_body_index >= 0; render_state.last_target_index = root_body_index >= 0 ? root_body_index : -1; render_state.camera_offset = (Vector3){ 0, 50, 100 }; @@ -106,8 +106,8 @@ void run_gui_simulation(SimulationState* sim) { // Render UI panels render_info(sim); render_body_list_ui(sim, &render_state, &ui_state); - render_body_info_ui(sim, &render_state); - render_maneuver_list_ui(sim, &render_state); + render_body_info_ui(sim, &render_state, &ui_state); + render_maneuver_list_ui(sim, &render_state, &ui_state); end_frame(); } diff --git a/src/renderer.cpp b/src/renderer.cpp index 36ab5af..7536e36 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -182,32 +182,18 @@ void setup_camera(RenderState* render_state) { } static bool has_target_changed(RenderState* render_state) { - int current_target = -1; - if (render_state->selected_body_index >= 0) { - current_target = render_state->selected_body_index; - } else if (render_state->selected_craft_index >= 0) { - current_target = -(render_state->selected_craft_index + 1); - } + int current_target = render_state->selected_body_index; return current_target != render_state->last_target_index; } static void update_camera_target(RenderState* render_state, SimulationState* sim) { - if (render_state->selected_body_index >= 0) { - CelestialBody* body = &sim->bodies[render_state->selected_body_index]; + if (render_state->selected_body_index < 0) return; - // Camera target is at origin for selected body - render_state->camera.target = (Vector3){0, 0, 0}; - - // Set initial camera position based on children distance - float distance = get_initial_camera_distance(body, sim, render_state); - render_state->camera.position = (Vector3){0, distance * CAMERA_INITIAL_HEIGHT_FACTOR, distance}; - render_state->camera_offset = render_state->camera.position; - } else if (render_state->selected_craft_index >= 0) { - Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; - Vector3 craft_pos = sim_to_render(craft->global_position, render_state->distance_scale); - render_state->camera.target = craft_pos; - render_state->camera.position = Vector3Add(craft_pos, render_state->camera_offset); - } + CelestialBody* body = &sim->bodies[render_state->selected_body_index]; + render_state->camera.target = (Vector3){0, 0, 0}; + float distance = get_initial_camera_distance(body, sim, render_state); + render_state->camera.position = (Vector3){0, distance * CAMERA_INITIAL_HEIGHT_FACTOR, distance}; + render_state->camera_offset = render_state->camera.position; } static void rotate_camera_orbitally(RenderState* render_state, float angle) { @@ -237,24 +223,13 @@ static void rotate_camera_orbitally(RenderState* render_state, float angle) { } static float get_target_min_distance(RenderState* render_state, SimulationState* sim) { - float target_radius = 0.0f; - - if (render_state->selected_body_index >= 0) { - CelestialBody* body = &sim->bodies[render_state->selected_body_index]; - target_radius = scale_radius(body->radius, render_state->distance_scale); - } else if (render_state->selected_craft_index >= 0) { - Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; - if (craft->parent_index >= 0 && craft->parent_index < sim->body_count) { - CelestialBody* parent = &sim->bodies[craft->parent_index]; - target_radius = scale_radius(parent->radius, render_state->distance_scale); - target_radius *= MIN_DISTANCE_SPACECRAFT_PARENT_RADIUS_MULT; - } else { - return MIN_DISTANCE_SPACECRAFT_DEFAULT; - } - } else { + if (render_state->selected_body_index < 0) { return CAMERA_MIN_DISTANCE; } + CelestialBody* body = &sim->bodies[render_state->selected_body_index]; + float target_radius = scale_radius(body->radius, render_state->distance_scale); + float radius_based_dist = target_radius * MIN_DISTANCE_BODY_RADIUS_MULT; float cull_based_dist = target_radius + CAMERA_NEAR_CULL_DISTANCE + 0.001f; return (radius_based_dist > cull_based_dist) ? radius_based_dist : cull_based_dist; @@ -294,13 +269,7 @@ static void zoom_camera(RenderState* render_state, SimulationState* sim, ZoomDir } static void update_last_target(RenderState* render_state) { - if (render_state->selected_body_index >= 0) { - render_state->last_target_index = render_state->selected_body_index; - } else if (render_state->selected_craft_index >= 0) { - render_state->last_target_index = -(render_state->selected_craft_index + 1); - } else { - render_state->last_target_index = -1; - } + render_state->last_target_index = render_state->selected_body_index; } // Update camera with keyboard/mouse controls @@ -311,15 +280,8 @@ void update_camera(RenderState* render_state, SimulationState* sim) { if (target_changed) { update_camera_target(render_state, sim); } else if (render_state->selected_body_index >= 0) { - // Body selected - camera orbits around origin (body at 0,0,0 in render space) render_state->camera.target = (Vector3){0, 0, 0}; render_state->camera.position = render_state->camera_offset; - } else if (render_state->selected_craft_index >= 0) { - // Spacecraft selected - camera orbits around spacecraft - Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; - Vector3 craft_pos = sim_to_render(craft->global_position, render_state->distance_scale); - render_state->camera.target = craft_pos; - render_state->camera.position = Vector3Add(craft_pos, render_state->camera_offset); } } @@ -721,28 +683,9 @@ void render_simulation(SimulationState* sim, RenderState* render_state) { // Just draw orbit here Vec3 origin_vec = {0, 0, 0}; render_orbit(craft_rel, craft->local_velocity, origin_vec, selected->mass, (Color){0, 255, 255, 128}, render_state); - } - } - - } else if (render_state->selected_craft_index >= 0) { - // === SPACECRAFT SELECTED MODE === - Spacecraft* selected = &sim->spacecraft[render_state->selected_craft_index]; - - // Render parent body (for reference) - if (selected->parent_index >= 0 && selected->parent_index < sim->body_count) { - CelestialBody* parent = &sim->bodies[selected->parent_index]; - Vec3 parent_rel = vec3_sub(parent->global_position, selected->global_position); - Vector3 parent_pos = sim_to_render(parent_rel, render_state->distance_scale); - float parent_radius = scale_radius(parent->radius, render_state->distance_scale); - Color parent_color = {(unsigned char)(parent->color[0]*255), (unsigned char)(parent->color[1]*255), (unsigned char)(parent->color[2]*255), 255}; - - DrawSphere(parent_pos, parent_radius, parent_color); - - // Render spacecraft's orbit around parent - Vec3 origin_vec = {0, 0, 0}; - render_orbit(origin_vec, selected->local_velocity, parent_rel, parent->mass, (Color){0, 255, 255, 128}, render_state); } } + } EndMode3D(); diff --git a/src/renderer.h b/src/renderer.h index bd5454c..c464775 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -12,10 +12,9 @@ struct RenderState { double distance_scale; // Scale factor for distances double size_scale; // Scale factor for body sizes int selected_body_index; // -1 = no selection - int selected_craft_index; // -1 = no selection - bool camera_target_enabled; // Whether camera follows selected body/craft + bool camera_target_enabled; // Whether camera follows selected body Vector3 camera_offset; // Offset from target when following body - int last_target_index; // Tracks body or craft index (negative = spacecraft) + int last_target_index; // Tracks body index for change detection Texture2D spacecraft_texture; // Shared texture for all spacecraft Texture2D maneuver_textures[6]; // One per burn direction diff --git a/src/ui_renderer.cpp b/src/ui_renderer.cpp index 96ba3ac..7bf2428 100644 --- a/src/ui_renderer.cpp +++ b/src/ui_renderer.cpp @@ -123,22 +123,22 @@ void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIStat int previous_active = ui_state->body_list_active; GuiListView(list_bounds, list_text, &ui_state->body_list_scroll, &ui_state->body_list_active); + ui_state->selected_craft_index = -1; + // Check if an item was selected if (ui_state->body_list_active >= 0 && ui_state->body_list_active != previous_active) { if (ui_state->body_list_active < sim->body_count) { - // A body was selected render_state->selected_body_index = ui_state->body_list_active; - render_state->selected_craft_index = -1; render_state->camera_target_enabled = true; printf("Camera follow enabled for body: %s\n", sim->bodies[render_state->selected_body_index].name); } else { - // A spacecraft was selected int craft_index = ui_state->body_list_active - sim->body_count; if (craft_index >= 0 && craft_index < sim->craft_count) { - render_state->selected_body_index = -1; - render_state->selected_craft_index = craft_index; + Spacecraft* craft = &sim->spacecraft[craft_index]; + render_state->selected_body_index = craft->parent_index; + ui_state->selected_craft_index = craft_index; render_state->camera_target_enabled = true; - printf("Camera follow enabled for spacecraft: %s\n", sim->spacecraft[craft_index].name); + printf("Camera follow enabled for spacecraft: %s\n", craft->name); } } } @@ -147,7 +147,7 @@ void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIStat } // Render body information UI panel -void render_body_info_ui(SimulationState* sim, RenderState* render_state) { +void render_body_info_ui(SimulationState* sim, RenderState* render_state, UIState* ui_state) { // Panel dimensions int panel_width = 250; int panel_height = 300; @@ -155,7 +155,7 @@ void render_body_info_ui(SimulationState* sim, RenderState* render_state) { int panel_y = 10; if ((render_state->selected_body_index < 0 || render_state->selected_body_index >= sim->body_count) && - (render_state->selected_craft_index < 0 || render_state->selected_craft_index >= sim->craft_count)) { + (ui_state->selected_craft_index < 0 || ui_state->selected_craft_index >= sim->craft_count)) { // No body or spacecraft selected - render empty panel Rectangle panel_bounds = { (float)panel_x, (float)panel_y, (float)panel_width, (float)panel_height }; GuiWindowBox(panel_bounds, "Info"); @@ -248,8 +248,8 @@ void render_body_info_ui(SimulationState* sim, RenderState* render_state) { } // Check if a spacecraft is selected - if (render_state->selected_craft_index >= 0 && render_state->selected_craft_index < sim->craft_count) { - Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; + if (ui_state->selected_craft_index >= 0 && ui_state->selected_craft_index < sim->craft_count) { + Spacecraft* craft = &sim->spacecraft[ui_state->selected_craft_index]; // Draw window (no close button - panels always shown) GuiWindowBox(panel_bounds, craft->name); @@ -289,7 +289,7 @@ void render_body_info_ui(SimulationState* sim, RenderState* render_state) { int pending_maneuvers = 0; int executed_maneuvers = 0; for (int i = 0; i < sim->maneuver_count; i++) { - if (sim->maneuvers[i].craft_index == render_state->selected_craft_index) { + if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { if (sim->maneuvers[i].executed) { executed_maneuvers++; } else { @@ -320,8 +320,8 @@ void render_body_info_ui(SimulationState* sim, RenderState* render_state) { } // Render maneuver list UI panel -void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state) { - if (render_state->selected_craft_index < 0 || render_state->selected_craft_index >= sim->craft_count) { +void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state, UIState* ui_state) { + if (ui_state->selected_craft_index < 0 || ui_state->selected_craft_index >= sim->craft_count) { return; // No spacecraft selected } @@ -332,7 +332,7 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state) { Rectangle panel_bounds = { (float)panel_x, (float)panel_y, (float)panel_width, (float)panel_height }; - Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; + Spacecraft* craft = &sim->spacecraft[ui_state->selected_craft_index]; // Create title with spacecraft name char title[128]; @@ -344,7 +344,7 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state) { // Count maneuvers for this spacecraft int craft_maneuver_count = 0; for (int i = 0; i < sim->maneuver_count; i++) { - if (sim->maneuvers[i].craft_index == render_state->selected_craft_index) { + if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { craft_maneuver_count++; } } @@ -370,7 +370,7 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state) { int offset = 0; for (int i = 0; i < sim->maneuver_count; i++) { - if (sim->maneuvers[i].craft_index == render_state->selected_craft_index) { + if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { if (offset > 0) { offset += snprintf(maneuver_list_text + offset, buffer_size - offset, ";"); } @@ -398,7 +398,7 @@ void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state) { details_text[0] = '\0'; for (int i = 0; i < sim->maneuver_count; i++) { - if (sim->maneuvers[i].craft_index == render_state->selected_craft_index) { + if (sim->maneuvers[i].craft_index == ui_state->selected_craft_index) { if (sim->maneuvers[i].executed) { snprintf(details_text, sizeof(details_text), "Last executed:\n%s\nΔv: %.1f m/s\nTime: %.1f s", diff --git a/src/ui_renderer.h b/src/ui_renderer.h index 66f1c69..472c5e9 100644 --- a/src/ui_renderer.h +++ b/src/ui_renderer.h @@ -7,8 +7,9 @@ // UI state struct UIState { - int body_list_scroll; // Scroll position for body list - int body_list_active; // Active item index in body list + int body_list_scroll; // Scroll position for body list + int body_list_active; // Active item index in body list + int selected_craft_index; // Selected spacecraft index (-1 = no selection) }; void gui_init(); @@ -16,7 +17,7 @@ void gui_init(); // UI rendering functions void render_info(SimulationState* sim); void render_body_list_ui(SimulationState* sim, RenderState* render_state, UIState* ui_state); -void render_body_info_ui(SimulationState* sim, RenderState* render_state); -void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state); +void render_body_info_ui(SimulationState* sim, RenderState* render_state, UIState* ui_state); +void render_maneuver_list_ui(SimulationState* sim, RenderState* render_state, UIState* ui_state); #endif