Browse Source

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
main
cinnaboot 5 months ago
parent
commit
79725a7875
  1. 6
      src/main.cpp
  2. 83
      src/renderer.cpp
  3. 5
      src/renderer.h
  4. 34
      src/ui_renderer.cpp
  5. 9
      src/ui_renderer.h

6
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();
}

83
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();

5
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

34
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",

9
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

Loading…
Cancel
Save