Browse Source

Add camera follow feature for selected body

Features:
- Add camera_follow_body flag to RenderState
- Update update_camera() to follow selected body when enabled
- F key toggles camera follow (requires body selected)
- Camera still rotates and zooms around followed body
- Removed old focus_camera() function (superseded by new implementation)
- Updated help text to show F key for camera follow toggle

Technical details:
- Camera target updates to body position each frame when following
- Existing rotation/zoom controls work relative to new target position
- Maintains orbital camera control pattern
main
cinnaboot 6 months ago
parent
commit
969af97fe0
  1. 15
      src/main.cpp
  2. 29
      src/renderer.cpp
  3. 4
      src/renderer.h

15
src/main.cpp

@ -42,6 +42,7 @@ void run_gui_simulation(SimulationState* sim) {
render_state.show_body_info = false; render_state.show_body_info = false;
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
bool paused = false; bool paused = false;
double speed_multiplier = 1.0; double speed_multiplier = 1.0;
@ -54,6 +55,7 @@ void run_gui_simulation(SimulationState* sim) {
printf(" +/-: Speed up/slow down simulation\n"); printf(" +/-: Speed up/slow down simulation\n");
printf(" I: Toggle info display\n"); printf(" I: Toggle info display\n");
printf(" B: Toggle body list\n"); printf(" B: Toggle body list\n");
printf(" F: Toggle camera follow on selected body\n");
printf(" ESC: Quit\n\n"); printf(" ESC: Quit\n\n");
while (!WindowShouldClose()) { while (!WindowShouldClose()) {
@ -80,18 +82,7 @@ void run_gui_simulation(SimulationState* sim) {
} }
} }
#if 0 update_camera(&render_state, sim);
/****
* Hacks ahead...
*/
int focus_index = 4; // earth: 2, jupiter, 4
if (sim->body_count >= focus_index) {
Vector3 offset = {0, 2, 10};
focus_camera(&render_state, &sim->bodies[focus_index], offset);
}
#else
update_camera(&render_state);
#endif
render_simulation(sim, &render_state); render_simulation(sim, &render_state);
} }

29
src/renderer.cpp

@ -7,6 +7,9 @@
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include "raygui.h" #include "raygui.h"
// Forward declarations
static Vector3 sim_to_render(Vec3 pos, double scale);
// Initialize raylib window // Initialize raylib window
void init_renderer(int width, int height, const char* title) { void init_renderer(int width, int height, const char* title) {
InitWindow(width, height, title); InitWindow(width, height, title);
@ -33,7 +36,15 @@ void setup_camera(RenderState* render_state) {
} }
// Update camera with keyboard/mouse controls // Update camera with keyboard/mouse controls
void update_camera(RenderState* render_state) { void update_camera(RenderState* render_state, SimulationState* sim) {
// If following a body, update target to body position
if (render_state->camera_follow_body && render_state->selected_body_index >= 0 &&
render_state->selected_body_index < sim->body_count) {
CelestialBody* body = &sim->bodies[render_state->selected_body_index];
Vector3 body_pos = sim_to_render(body->position, render_state->distance_scale);
render_state->camera.target = body_pos;
}
// Orbital camera rotation with arrow keys // Orbital camera rotation with arrow keys
float camera_distance = Vector3Distance(render_state->camera.position, render_state->camera.target); float camera_distance = Vector3Distance(render_state->camera.position, render_state->camera.target);
float angle_speed = 0.02f; float angle_speed = 0.02f;
@ -77,6 +88,16 @@ void update_camera(RenderState* render_state) {
if (IsKeyPressed(KEY_B)) { if (IsKeyPressed(KEY_B)) {
render_state->show_body_list = !render_state->show_body_list; render_state->show_body_list = !render_state->show_body_list;
} }
// Toggle camera follow with F key
if (IsKeyPressed(KEY_F)) {
if (render_state->selected_body_index >= 0) {
render_state->camera_follow_body = !render_state->camera_follow_body;
printf("Camera follow: %s\n", render_state->camera_follow_body ? "enabled" : "disabled");
} else {
render_state->camera_follow_body = false;
}
}
} }
// Transform from simulation coordinates (XY plane) to render coordinates (XZ plane) // Transform from simulation coordinates (XY plane) to render coordinates (XZ plane)
@ -89,11 +110,7 @@ Vector3 sim_to_render(Vec3 pos, double scale) {
}; };
} }
void focus_camera(RenderState* render_state, CelestialBody* body, Vector3& offset) {
Vector3 p = sim_to_render(body->position, render_state->distance_scale);
render_state->camera.position = (Vector3){ p.x, p.y + offset.y, p.z + offset.z};
render_state->camera.target = p;
}
// Scale a radius for rendering (with minimum visible size) // Scale a radius for rendering (with minimum visible size)
float scale_radius(double radius, double scale) { float scale_radius(double radius, double scale) {

4
src/renderer.h

@ -15,6 +15,7 @@ struct RenderState {
bool show_body_info; // Toggle for info panel bool show_body_info; // Toggle for info panel
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
}; };
// Renderer initialization and cleanup // Renderer initialization and cleanup
@ -23,8 +24,7 @@ void close_renderer();
// Camera setup and control // Camera setup and control
void setup_camera(RenderState* render_state); void setup_camera(RenderState* render_state);
void update_camera(RenderState* render_state); void update_camera(RenderState* render_state, SimulationState* sim);
void focus_camera(RenderState* render_state, CelestialBody* body, Vector3& offset);
// Rendering functions // Rendering functions
void render_body(CelestialBody* body, RenderState* render_state); void render_body(CelestialBody* body, RenderState* render_state);

Loading…
Cancel
Save