|
|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|