diff --git a/src/renderer.cpp b/src/renderer.cpp index 12f10d3..305311e 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -369,18 +369,10 @@ static OrbitalBasis calculate_orbital_basis(Vec3 r_vec, Vec3 velocity, Vec3 e_ve OrbitalBasis basis; basis.periapsis_dir = vec3_normalize(e_vec); - Vec3 h_vec = { - r_vec.y * velocity.z - r_vec.z * velocity.y, - r_vec.z * velocity.x - r_vec.x * velocity.z, - r_vec.x * velocity.y - r_vec.y * velocity.x - }; + Vec3 h_vec = vec3_cross(r_vec, velocity); basis.normal = vec3_normalize(h_vec); - basis.q_vec = { - basis.normal.y * basis.periapsis_dir.z - basis.normal.z * basis.periapsis_dir.y, - basis.normal.z * basis.periapsis_dir.x - basis.normal.x * basis.periapsis_dir.z, - basis.normal.x * basis.periapsis_dir.y - basis.normal.y * basis.periapsis_dir.x - }; + basis.q_vec = vec3_cross(basis.normal, basis.periapsis_dir); return basis; } @@ -466,64 +458,57 @@ static void render_parabolic_orbit(double p, OrbitalBasis basis, } } -// Render orbit path for a body -void render_orbit(CelestialBody* body, CelestialBody* parent, RenderState* render_state) { - if (body->parent_index == -1 || parent == NULL) { - return; - } +Color get_body_orbit_color(CelestialBody* body) { + return (Color){ + (unsigned char)(body->color[0] * 128), + (unsigned char)(body->color[1] * 128), + (unsigned char)(body->color[2] * 128), + 128 + }; +} - Vec3 r_vec = vec3_sub(body->position, parent->position); +void render_orbit(Vec3 position, Vec3 velocity, Vec3 parent_position, + double parent_mass, Color orbit_color, RenderState* render_state) { + Vec3 r_vec = vec3_sub(position, parent_position); double r = vec3_magnitude(r_vec); - Vec3 v_vec = body->local_velocity; - double v = vec3_magnitude(v_vec); + double v = vec3_magnitude(velocity); if (r < 1.0) return; - double mu = G * parent->mass; + double mu = G * parent_mass; double specific_energy = (v * v) / 2.0 - mu / r; double v_squared = v * v; - double r_dot_v = r_vec.x * v_vec.x + r_vec.y * v_vec.y + r_vec.z * v_vec.z; + double r_dot_v = vec3_dot(r_vec, velocity); Vec3 e_vec = { - (v_squared - mu / r) * r_vec.x - r_dot_v * v_vec.x, - (v_squared - mu / r) * r_vec.y - r_dot_v * v_vec.y, - (v_squared - mu / r) * r_vec.z - r_dot_v * v_vec.z + (v_squared - mu / r) * r_vec.x - r_dot_v * velocity.x, + (v_squared - mu / r) * r_vec.y - r_dot_v * velocity.y, + (v_squared - mu / r) * r_vec.z - r_dot_v * velocity.z }; double e = vec3_magnitude(e_vec) / mu; - Color orbit_color = { - (unsigned char)(body->color[0] * 128), - (unsigned char)(body->color[1] * 128), - (unsigned char)(body->color[2] * 128), - 128 - }; - - OrbitalBasis basis = calculate_orbital_basis(r_vec, v_vec, e_vec); + OrbitalBasis basis = calculate_orbital_basis(r_vec, velocity, e_vec); if (e < 0.98) { double a = -mu / (2.0 * specific_energy); if (a <= 0.0) return; - render_elliptical_orbit(a, e, basis, parent->position, render_state, orbit_color); + render_elliptical_orbit(a, e, basis, parent_position, render_state, orbit_color); } else if (e > 1.02) { double a = mu / (2.0 * (-specific_energy)); double p = a * (1.0 - e * e); if (p <= 0.0) return; - render_hyperbolic_orbit(p, e, basis, parent->position, render_state, orbit_color); + render_hyperbolic_orbit(p, e, basis, parent_position, render_state, orbit_color); } else { - Vec3 h_vec = { - r_vec.y * v_vec.z - r_vec.z * v_vec.y, - r_vec.z * v_vec.x - r_vec.x * v_vec.z, - r_vec.x * v_vec.y - r_vec.y * v_vec.x - }; - double h_squared = h_vec.x * h_vec.x + h_vec.y * h_vec.y + h_vec.z * h_vec.z; + Vec3 h_vec = vec3_cross(r_vec, velocity); + double h_squared = vec3_dot(h_vec, h_vec); double p = h_squared / mu; if (p <= 0.0) return; - render_parabolic_orbit(p, basis, parent->position, render_state, orbit_color); + render_parabolic_orbit(p, basis, parent_position, render_state, orbit_color); } } @@ -558,7 +543,18 @@ void render_simulation(SimulationState* sim, RenderState* render_state) { CelestialBody* body = &sim->bodies[i]; if (body->parent_index >= 0 && body->parent_index < sim->body_count) { CelestialBody* parent = &sim->bodies[body->parent_index]; - render_orbit(body, parent, render_state); + render_orbit(body->position, body->local_velocity, parent->position, + parent->mass, get_body_orbit_color(body), render_state); + } + } + + // Render spacecraft orbits + for (int i = 0; i < sim->craft_count; i++) { + Spacecraft* craft = &sim->spacecraft[i]; + if (craft->parent_index >= 0 && craft->parent_index < sim->body_count) { + CelestialBody* parent = &sim->bodies[craft->parent_index]; + render_orbit(craft->position, craft->local_velocity, parent->position, + parent->mass, (Color){0, 255, 255, 128}, render_state); } } diff --git a/src/renderer.h b/src/renderer.h index a4322e4..4b757b5 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -45,6 +45,8 @@ void update_camera(RenderState* render_state, SimulationState* sim); void render_body(CelestialBody* body, RenderState* render_state); void render_spacecraft_screen_space(Spacecraft* craft, RenderState* render_state); void render_maneuver_marker_screen_space(Spacecraft* craft, Maneuver* maneuver, RenderState* render_state); +void render_orbit(Vec3 position, Vec3 velocity, Vec3 parent_position, double parent_mass, Color orbit_color, RenderState* render_state); +Color get_body_orbit_color(CelestialBody* body); // NOTE: needs to be called between begin_frame() and end_frame() void render_simulation(SimulationState* sim, RenderState* render_state); void begin_frame();