Browse Source

Preserve camera distance when switching bodies

Changes:
- Add previous_selected_body to RenderState
- Detect when selected_body_index changes
- Recalculate camera_offset when switching to new body
- Maintains same camera distance/orientation to new body

Technical details:
- Body selection change detected via previous_selected_body comparison
- When switching to new body:
  * Calculate new body position
  * Set camera target to new body
  * Use existing camera_offset (maintains distance)
  * Update camera.position = body_pos + offset
- Allows seamless transitions between bodies at same zoom level

Result: Camera maintains perspective when switching between
celestial bodies, no jarring distance changes.
main
cinnaboot 6 months ago
parent
commit
c858891398
  1. 1
      src/main.cpp
  2. 14
      src/renderer.cpp
  3. 1
      src/renderer.h

1
src/main.cpp

@ -38,6 +38,7 @@ void run_gui_simulation(SimulationState* sim) {
// Initialize UI state // Initialize UI state
render_state.selected_body_index = -1; // No selection initially render_state.selected_body_index = -1; // No selection initially
render_state.previous_selected_body = -1; // Previous selected body index
render_state.body_list_scroll = 0; // Initial scroll position render_state.body_list_scroll = 0; // Initial scroll position
render_state.body_list_active = -1; // No active item initially render_state.body_list_active = -1; // No active item initially
render_state.camera_follow_body = false; // Camera not following initially render_state.camera_follow_body = false; // Camera not following initially

14
src/renderer.cpp

@ -49,6 +49,17 @@ void update_camera(RenderState* render_state, SimulationState* sim) {
} }
} }
// Preserve distance when switching to different body
if (render_state->camera_follow_body && render_state->selected_body_index >= 0 &&
render_state->selected_body_index != render_state->previous_selected_body &&
render_state->selected_body_index < sim->body_count) {
// Body selection changed - recalculate offset to maintain distance
Vector3 body_pos = sim_to_render(sim->bodies[render_state->selected_body_index].position, render_state->distance_scale);
render_state->camera.target = body_pos;
// Use current offset to maintain distance to new body
render_state->camera.position = Vector3Add(body_pos, render_state->camera_offset);
}
// Update target position when following // Update target position when following
if (render_state->camera_follow_body && render_state->selected_body_index >= 0 && if (render_state->camera_follow_body && render_state->selected_body_index >= 0 &&
render_state->selected_body_index < sim->body_count) { render_state->selected_body_index < sim->body_count) {
@ -136,8 +147,9 @@ void update_camera(RenderState* render_state, SimulationState* sim) {
} }
} }
// Store previous follow state // Store previous follow state and selected body
render_state->was_following_body = render_state->camera_follow_body; render_state->was_following_body = render_state->camera_follow_body;
render_state->previous_selected_body = render_state->selected_body_index;
} }
// Transform from simulation coordinates (XY plane) to render coordinates (XZ plane) // Transform from simulation coordinates (XY plane) to render coordinates (XZ plane)

1
src/renderer.h

@ -10,6 +10,7 @@ struct RenderState {
double distance_scale; // Scale factor for distances double distance_scale; // Scale factor for distances
double size_scale; // Scale factor for body sizes double size_scale; // Scale factor for body sizes
int selected_body_index; // -1 = no selection int selected_body_index; // -1 = no selection
int previous_selected_body; // Previous selected body index
int body_list_scroll; // Scroll position for body list int body_list_scroll; // Scroll position for body list
int body_list_active; // Active item index in body list int body_list_active; // Active item index in body list
bool camera_follow_body; // Whether camera follows selected body bool camera_follow_body; // Whether camera follows selected body

Loading…
Cancel
Save