|
|
|
|
@ -3,9 +3,6 @@
|
|
|
|
|
#include <cmath> |
|
|
|
|
#include <cstdio> |
|
|
|
|
|
|
|
|
|
// Scale target for local frame rendering
|
|
|
|
|
static const double SOI_SCALE_TARGET = 100.0; |
|
|
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
|
static Vector3 sim_to_render(Vec3 pos, double scale); |
|
|
|
|
|
|
|
|
|
@ -99,17 +96,6 @@ void setup_camera(RenderState* render_state) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static TrackingMode detect_camera_mode(RenderState* render_state) { |
|
|
|
|
if (render_state->camera_target_enabled) { |
|
|
|
|
if (render_state->selected_craft_index >= 0) { |
|
|
|
|
return TRACKING_CRAFT; |
|
|
|
|
} else if (render_state->selected_body_index >= 0) { |
|
|
|
|
return TRACKING_BODY; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return TRACKING_FREE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool has_target_changed(RenderState* render_state) { |
|
|
|
|
int current_target = -1; |
|
|
|
|
if (render_state->selected_body_index >= 0) { |
|
|
|
|
@ -121,12 +107,12 @@ static bool has_target_changed(RenderState* render_state) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void update_camera_target(RenderState* render_state, SimulationState* sim) { |
|
|
|
|
if (render_state->camera_mode == TRACKING_BODY && render_state->selected_body_index >= 0) { |
|
|
|
|
if (render_state->selected_body_index >= 0) { |
|
|
|
|
CelestialBody* body = &sim->bodies[render_state->selected_body_index]; |
|
|
|
|
Vector3 body_pos = sim_to_render(body->global_position, render_state->distance_scale); |
|
|
|
|
render_state->camera.target = body_pos; |
|
|
|
|
render_state->camera.position = Vector3Add(body_pos, render_state->camera_offset); |
|
|
|
|
} else if (render_state->camera_mode == TRACKING_CRAFT && render_state->selected_craft_index >= 0) { |
|
|
|
|
} 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; |
|
|
|
|
@ -187,73 +173,21 @@ static void update_last_target(RenderState* render_state) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static RenderFrameMode detect_render_frame_mode(RenderState* render_state, SimulationState* sim) { |
|
|
|
|
if (!render_state->camera_target_enabled) { |
|
|
|
|
return RENDER_FRAME_GLOBAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (render_state->camera_mode == TRACKING_BODY) { |
|
|
|
|
CelestialBody* body = NULL; |
|
|
|
|
if (render_state->selected_body_index >= 0) { |
|
|
|
|
body = &sim->bodies[render_state->selected_body_index]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (body && body->parent_index >= 0) { |
|
|
|
|
return RENDER_FRAME_LOCAL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (render_state->camera_mode == TRACKING_CRAFT) { |
|
|
|
|
Spacecraft* craft = NULL; |
|
|
|
|
if (render_state->selected_craft_index >= 0) { |
|
|
|
|
craft = &sim->spacecraft[render_state->selected_craft_index]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (craft && craft->parent_index >= 0) { |
|
|
|
|
return RENDER_FRAME_LOCAL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return RENDER_FRAME_GLOBAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void update_camera_frame_mode(RenderState* render_state, SimulationState* sim) { |
|
|
|
|
RenderFrameMode new_frame_mode = detect_render_frame_mode(render_state, sim); |
|
|
|
|
|
|
|
|
|
if (new_frame_mode != render_state->frame_mode) { |
|
|
|
|
render_state->frame_mode = new_frame_mode; |
|
|
|
|
|
|
|
|
|
if (new_frame_mode == RENDER_FRAME_LOCAL) { |
|
|
|
|
if (render_state->camera_mode == TRACKING_BODY && render_state->selected_body_index >= 0) { |
|
|
|
|
CelestialBody* body = &sim->bodies[render_state->selected_body_index]; |
|
|
|
|
render_state->local_frame_parent_index = body->parent_index; |
|
|
|
|
} else if (render_state->camera_mode == TRACKING_CRAFT && render_state->selected_craft_index >= 0) { |
|
|
|
|
Spacecraft* craft = &sim->spacecraft[render_state->selected_craft_index]; |
|
|
|
|
render_state->local_frame_parent_index = craft->parent_index; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
render_state->local_frame_parent_index = -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Update camera with keyboard/mouse controls
|
|
|
|
|
void update_camera(RenderState* render_state, SimulationState* sim) { |
|
|
|
|
float angle_speed = 0.02f; |
|
|
|
|
|
|
|
|
|
render_state->camera_mode = detect_camera_mode(render_state); |
|
|
|
|
|
|
|
|
|
bool target_changed = has_target_changed(render_state); |
|
|
|
|
|
|
|
|
|
if (render_state->camera_target_enabled) { |
|
|
|
|
if (target_changed) { |
|
|
|
|
update_camera_target(render_state, sim); |
|
|
|
|
} else if (render_state->camera_mode == TRACKING_BODY && render_state->selected_body_index >= 0) { |
|
|
|
|
} else if (render_state->selected_body_index >= 0) { |
|
|
|
|
CelestialBody* body = &sim->bodies[render_state->selected_body_index]; |
|
|
|
|
Vector3 body_pos = sim_to_render(body->global_position, render_state->distance_scale); |
|
|
|
|
render_state->camera.target = body_pos; |
|
|
|
|
render_state->camera.position = Vector3Add(body_pos, render_state->camera_offset); |
|
|
|
|
} else if (render_state->camera_mode == TRACKING_CRAFT && render_state->selected_craft_index >= 0) { |
|
|
|
|
} 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; |
|
|
|
|
@ -276,7 +210,6 @@ void update_camera(RenderState* render_state, SimulationState* sim) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
update_last_target(render_state); |
|
|
|
|
update_camera_frame_mode(render_state, sim); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Transform from simulation coordinates (XY plane) to render coordinates (XZ plane)
|
|
|
|
|
@ -289,25 +222,6 @@ Vector3 sim_to_render(Vec3 pos, double scale) {
|
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static double get_local_frame_scale(CelestialBody* parent) { |
|
|
|
|
if (!parent) return 1e-9; |
|
|
|
|
|
|
|
|
|
double soi_radius = parent->soi_radius; |
|
|
|
|
if (soi_radius > 0) { |
|
|
|
|
return SOI_SCALE_TARGET / soi_radius; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 1e-9; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static Vector3 sim_to_render_local(Vec3 local_pos, double scale) { |
|
|
|
|
return (Vector3){ |
|
|
|
|
(float)(local_pos.x * scale), |
|
|
|
|
(float)(local_pos.z * scale), |
|
|
|
|
(float)(-local_pos.y * scale) |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Scale a radius for rendering (with minimum visible size)
|
|
|
|
|
float scale_radius(double radius, double scale) { |
|
|
|
|
float scaled = (float)(scale * log10(radius)); |
|
|
|
|
|