|
|
|
|
@ -3,6 +3,30 @@
|
|
|
|
|
#include <cmath> |
|
|
|
|
#include <cstdio> |
|
|
|
|
|
|
|
|
|
// Camera control constants
|
|
|
|
|
#define CAMERA_ORBIT_ANGLE_SPEED 0.02f |
|
|
|
|
#define CAMERA_ZOOM_DELTA 2.0f |
|
|
|
|
#define CAMERA_MIN_DISTANCE 0.1f |
|
|
|
|
#define CAMERA_INITIAL_HEIGHT_FACTOR 0.3f |
|
|
|
|
#define CAMERA_INITIAL_FOV 45.0f |
|
|
|
|
#define CAMERA_INITIAL_POSITION_Y 50.0f |
|
|
|
|
#define CAMERA_INITIAL_POSITION_Z 100.0f |
|
|
|
|
|
|
|
|
|
// Scaling constants
|
|
|
|
|
#define DISTANCE_SCALE_DEFAULT 1e-9 |
|
|
|
|
#define SIZE_SCALE_DEFAULT 0.02f |
|
|
|
|
|
|
|
|
|
// Initial camera distance fallback
|
|
|
|
|
#define INITIAL_DISTANCE_RADIUS_MULTIPLIER 100.0f |
|
|
|
|
|
|
|
|
|
// TODO: Consider extracting other hardcoded constants:
|
|
|
|
|
// - Reference grid parameters (lines 600-610)
|
|
|
|
|
// - Spacecraft rendering (screen size, color)
|
|
|
|
|
// - Maneuver marker rendering (size calculation, bounds)
|
|
|
|
|
// - Orbit rendering (segments, eccentricity thresholds, max true anomaly)
|
|
|
|
|
// - Screen space rendering (culling margins)
|
|
|
|
|
// - Child indicators (radius, font size)
|
|
|
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
|
static Vector3 sim_to_render(Vec3 pos, double scale); |
|
|
|
|
|
|
|
|
|
@ -125,14 +149,14 @@ float calculate_spacecraft_angle(Vec3 velocity, Camera3D camera) {
|
|
|
|
|
|
|
|
|
|
// Setup the 3D camera
|
|
|
|
|
void setup_camera(RenderState* render_state) { |
|
|
|
|
render_state->camera.position = (Vector3){ 0.0f, 50.0f, 100.0f }; |
|
|
|
|
render_state->camera.position = (Vector3){ 0.0f, CAMERA_INITIAL_POSITION_Y, CAMERA_INITIAL_POSITION_Z }; |
|
|
|
|
render_state->camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; |
|
|
|
|
render_state->camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; |
|
|
|
|
render_state->camera.fovy = 45.0f; |
|
|
|
|
render_state->camera.fovy = CAMERA_INITIAL_FOV; |
|
|
|
|
render_state->camera.projection = CAMERA_PERSPECTIVE; |
|
|
|
|
|
|
|
|
|
render_state->distance_scale = 1e-9; |
|
|
|
|
render_state->size_scale = 0.02f; |
|
|
|
|
render_state->distance_scale = DISTANCE_SCALE_DEFAULT; |
|
|
|
|
render_state->size_scale = SIZE_SCALE_DEFAULT; |
|
|
|
|
|
|
|
|
|
render_state->texture_loaded = false; |
|
|
|
|
render_state->spacecraft_texture = (Texture2D){0, 0, 0, 0, 0}; |
|
|
|
|
@ -160,7 +184,7 @@ static void update_camera_target(RenderState* render_state, SimulationState* sim
|
|
|
|
|
|
|
|
|
|
// 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 * 0.3f, distance}; |
|
|
|
|
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]; |
|
|
|
|
@ -201,9 +225,7 @@ static void zoom_camera(RenderState* render_state, float distance_delta) {
|
|
|
|
|
Vector3 direction = Vector3Normalize(to_target); |
|
|
|
|
float camera_distance = Vector3Length(to_target); |
|
|
|
|
|
|
|
|
|
// FIXME: min_distance, distance_delta, and 'angle_speed' should be configurable
|
|
|
|
|
float min_distance = 0.1f; |
|
|
|
|
if (camera_distance - distance_delta <= min_distance) return; |
|
|
|
|
if (camera_distance - distance_delta <= CAMERA_MIN_DISTANCE) return; |
|
|
|
|
|
|
|
|
|
render_state->camera.position = Vector3Add(render_state->camera.position, Vector3Scale(direction, distance_delta)); |
|
|
|
|
|
|
|
|
|
@ -227,8 +249,6 @@ static void update_last_target(RenderState* render_state) {
|
|
|
|
|
|
|
|
|
|
// Update camera with keyboard/mouse controls
|
|
|
|
|
void update_camera(RenderState* render_state, SimulationState* sim) { |
|
|
|
|
float angle_speed = 0.02f; |
|
|
|
|
|
|
|
|
|
bool target_changed = has_target_changed(render_state); |
|
|
|
|
|
|
|
|
|
if (render_state->camera_target_enabled) { |
|
|
|
|
@ -248,17 +268,17 @@ void update_camera(RenderState* render_state, SimulationState* sim) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (IsKeyDown(KEY_LEFT)) { |
|
|
|
|
rotate_camera_orbitally(render_state, angle_speed); |
|
|
|
|
rotate_camera_orbitally(render_state, CAMERA_ORBIT_ANGLE_SPEED); |
|
|
|
|
} |
|
|
|
|
if (IsKeyDown(KEY_RIGHT)) { |
|
|
|
|
rotate_camera_orbitally(render_state, -angle_speed); |
|
|
|
|
rotate_camera_orbitally(render_state, -CAMERA_ORBIT_ANGLE_SPEED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (IsKeyDown(KEY_UP)) { |
|
|
|
|
zoom_camera(render_state, 2.0f); |
|
|
|
|
zoom_camera(render_state, CAMERA_ZOOM_DELTA); |
|
|
|
|
} |
|
|
|
|
if (IsKeyDown(KEY_DOWN)) { |
|
|
|
|
zoom_camera(render_state, -2.0f); |
|
|
|
|
zoom_camera(render_state, -CAMERA_ZOOM_DELTA); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
update_last_target(render_state); |
|
|
|
|
@ -294,9 +314,9 @@ float get_initial_camera_distance(CelestialBody* body, SimulationState* sim, Ren
|
|
|
|
|
return (float)(total_distance / child_count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// No children - use 100x body radius as fallback
|
|
|
|
|
// No children - use body radius multiplier as fallback
|
|
|
|
|
float body_radius = scale_radius(body->radius, render_state->distance_scale); |
|
|
|
|
return body_radius * 100.0f; |
|
|
|
|
return body_radius * INITIAL_DISTANCE_RADIUS_MULTIPLIER; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Transform from simulation coordinates (XY plane) to render coordinates (XZ plane)
|
|
|
|
|
|