|
|
|
@ -8,14 +8,14 @@ bool extract_vec3_from_table(toml_datum_t table, Vec3* pos) { |
|
|
|
toml_datum_t x = toml_get(table, "x"); |
|
|
|
toml_datum_t x = toml_get(table, "x"); |
|
|
|
toml_datum_t y = toml_get(table, "y"); |
|
|
|
toml_datum_t y = toml_get(table, "y"); |
|
|
|
toml_datum_t z = toml_get(table, "z"); |
|
|
|
toml_datum_t z = toml_get(table, "z"); |
|
|
|
|
|
|
|
|
|
|
|
// Accept both INT64 and FP64 for coordinates (TOML may parse integers as floats)
|
|
|
|
// Accept both INT64 and FP64 for coordinates (TOML may parse integers as floats)
|
|
|
|
if ((x.type != TOML_FP64 && x.type != TOML_INT64) || |
|
|
|
if ((x.type != TOML_FP64 && x.type != TOML_INT64) || |
|
|
|
(y.type != TOML_FP64 && y.type != TOML_INT64) || |
|
|
|
(y.type != TOML_FP64 && y.type != TOML_INT64) || |
|
|
|
(z.type != TOML_FP64 && z.type != TOML_INT64)) { |
|
|
|
(z.type != TOML_FP64 && z.type != TOML_INT64)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pos->x = x.type == TOML_FP64 ? x.u.fp64 : (double)x.u.int64; |
|
|
|
pos->x = x.type == TOML_FP64 ? x.u.fp64 : (double)x.u.int64; |
|
|
|
pos->y = y.type == TOML_FP64 ? y.u.fp64 : (double)y.u.int64; |
|
|
|
pos->y = y.type == TOML_FP64 ? y.u.fp64 : (double)y.u.int64; |
|
|
|
pos->z = z.type == TOML_FP64 ? z.u.fp64 : (double)z.u.int64; |
|
|
|
pos->z = z.type == TOML_FP64 ? z.u.fp64 : (double)z.u.int64; |
|
|
|
@ -27,14 +27,14 @@ bool extract_color_from_table(toml_datum_t table, float* color) { |
|
|
|
toml_datum_t r = toml_get(table, "r"); |
|
|
|
toml_datum_t r = toml_get(table, "r"); |
|
|
|
toml_datum_t g = toml_get(table, "g"); |
|
|
|
toml_datum_t g = toml_get(table, "g"); |
|
|
|
toml_datum_t b = toml_get(table, "b"); |
|
|
|
toml_datum_t b = toml_get(table, "b"); |
|
|
|
|
|
|
|
|
|
|
|
// Accept both INT64 and FP64 for color components
|
|
|
|
// Accept both INT64 and FP64 for color components
|
|
|
|
if ((r.type != TOML_FP64 && r.type != TOML_INT64) || |
|
|
|
if ((r.type != TOML_FP64 && r.type != TOML_INT64) || |
|
|
|
(g.type != TOML_FP64 && g.type != TOML_INT64) || |
|
|
|
(g.type != TOML_FP64 && g.type != TOML_INT64) || |
|
|
|
(b.type != TOML_FP64 && b.type != TOML_INT64)) { |
|
|
|
(b.type != TOML_FP64 && b.type != TOML_INT64)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
color[0] = (float)(r.type == TOML_FP64 ? r.u.fp64 : (double)r.u.int64); |
|
|
|
color[0] = (float)(r.type == TOML_FP64 ? r.u.fp64 : (double)r.u.int64); |
|
|
|
color[1] = (float)(g.type == TOML_FP64 ? g.u.fp64 : (double)g.u.int64); |
|
|
|
color[1] = (float)(g.type == TOML_FP64 ? g.u.fp64 : (double)g.u.int64); |
|
|
|
color[2] = (float)(b.type == TOML_FP64 ? b.u.fp64 : (double)b.u.int64); |
|
|
|
color[2] = (float)(b.type == TOML_FP64 ? b.u.fp64 : (double)b.u.int64); |
|
|
|
@ -50,14 +50,14 @@ bool parse_toml_body(toml_datum_t body_table, CelestialBody* body) { |
|
|
|
} |
|
|
|
} |
|
|
|
strncpy(body->name, name.u.s, 63); |
|
|
|
strncpy(body->name, name.u.s, 63); |
|
|
|
body->name[63] = '\0'; |
|
|
|
body->name[63] = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
// Extract numeric fields
|
|
|
|
// Extract numeric fields
|
|
|
|
toml_datum_t mass = toml_get(body_table, "mass"); |
|
|
|
toml_datum_t mass = toml_get(body_table, "mass"); |
|
|
|
toml_datum_t radius = toml_get(body_table, "radius"); |
|
|
|
toml_datum_t radius = toml_get(body_table, "radius"); |
|
|
|
toml_datum_t parent_idx = toml_get(body_table, "parent_index"); |
|
|
|
toml_datum_t parent_idx = toml_get(body_table, "parent_index"); |
|
|
|
toml_datum_t eccentricity = toml_get(body_table, "eccentricity"); |
|
|
|
toml_datum_t eccentricity = toml_get(body_table, "eccentricity"); |
|
|
|
toml_datum_t semi_major = toml_get(body_table, "semi_major_axis"); |
|
|
|
toml_datum_t semi_major = toml_get(body_table, "semi_major_axis"); |
|
|
|
|
|
|
|
|
|
|
|
// Accept both INT64 and FP64 for parent_index (TOML may parse integers as floats)
|
|
|
|
// Accept both INT64 and FP64 for parent_index (TOML may parse integers as floats)
|
|
|
|
if (mass.type != TOML_FP64 || radius.type != TOML_FP64 || |
|
|
|
if (mass.type != TOML_FP64 || radius.type != TOML_FP64 || |
|
|
|
(parent_idx.type != TOML_INT64 && parent_idx.type != TOML_FP64) || |
|
|
|
(parent_idx.type != TOML_INT64 && parent_idx.type != TOML_FP64) || |
|
|
|
@ -65,29 +65,29 @@ bool parse_toml_body(toml_datum_t body_table, CelestialBody* body) { |
|
|
|
semi_major.type != TOML_FP64) { |
|
|
|
semi_major.type != TOML_FP64) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
body->mass = mass.u.fp64; |
|
|
|
body->mass = mass.u.fp64; |
|
|
|
body->radius = radius.u.fp64; |
|
|
|
body->radius = radius.u.fp64; |
|
|
|
body->parent_index = (int)(parent_idx.type == TOML_INT64 ? parent_idx.u.int64 : (int)parent_idx.u.fp64); |
|
|
|
body->parent_index = (int)(parent_idx.type == TOML_INT64 ? parent_idx.u.int64 : (int)parent_idx.u.fp64); |
|
|
|
body->eccentricity = eccentricity.u.fp64; |
|
|
|
body->eccentricity = eccentricity.u.fp64; |
|
|
|
body->semi_major_axis = semi_major.u.fp64; |
|
|
|
body->semi_major_axis = semi_major.u.fp64; |
|
|
|
|
|
|
|
|
|
|
|
// Extract position vector
|
|
|
|
// Extract position vector
|
|
|
|
toml_datum_t position = toml_get(body_table, "position"); |
|
|
|
toml_datum_t position = toml_get(body_table, "position"); |
|
|
|
if (position.type != TOML_TABLE || !extract_vec3_from_table(position, &body->position)) { |
|
|
|
if (position.type != TOML_TABLE || !extract_vec3_from_table(position, &body->position)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Extract color
|
|
|
|
// Extract color
|
|
|
|
toml_datum_t color = toml_get(body_table, "color"); |
|
|
|
toml_datum_t color = toml_get(body_table, "color"); |
|
|
|
if (color.type != TOML_TABLE || !extract_color_from_table(color, body->color)) { |
|
|
|
if (color.type != TOML_TABLE || !extract_color_from_table(color, body->color)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Initialize velocity (will be calculated later)
|
|
|
|
// Initialize velocity (will be calculated later)
|
|
|
|
body->velocity = {0.0, 0.0, 0.0}; |
|
|
|
body->velocity = {0.0, 0.0, 0.0}; |
|
|
|
body->soi_radius = 0.0; |
|
|
|
body->soi_radius = 0.0; |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -107,7 +107,7 @@ bool load_system_config(SimulationState* sim, const char* filepath) { |
|
|
|
printf("TOML Error: %s\n", result.errmsg); |
|
|
|
printf("TOML Error: %s\n", result.errmsg); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get bodies array
|
|
|
|
// Get bodies array
|
|
|
|
toml_datum_t bodies = toml_get(result.toptab, "bodies"); |
|
|
|
toml_datum_t bodies = toml_get(result.toptab, "bodies"); |
|
|
|
if (bodies.type != TOML_ARRAY) { |
|
|
|
if (bodies.type != TOML_ARRAY) { |
|
|
|
@ -115,7 +115,7 @@ bool load_system_config(SimulationState* sim, const char* filepath) { |
|
|
|
toml_free(result); |
|
|
|
toml_free(result); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Count bodies first
|
|
|
|
// Count bodies first
|
|
|
|
int body_count = bodies.u.arr.size; |
|
|
|
int body_count = bodies.u.arr.size; |
|
|
|
if (body_count == 0) { |
|
|
|
if (body_count == 0) { |
|
|
|
@ -123,17 +123,17 @@ bool load_system_config(SimulationState* sim, const char* filepath) { |
|
|
|
toml_free(result); |
|
|
|
toml_free(result); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (body_count > sim->max_bodies) { |
|
|
|
if (body_count > sim->max_bodies) { |
|
|
|
printf("Error: Too many bodies (%d) for simulation (max: %d)\n",
|
|
|
|
printf("Error: Too many bodies (%d) for simulation (max: %d)\n", |
|
|
|
body_count, sim->max_bodies); |
|
|
|
body_count, sim->max_bodies); |
|
|
|
toml_free(result); |
|
|
|
toml_free(result); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Parse each body and store orbit params
|
|
|
|
// Parse each body and store orbit params
|
|
|
|
OrbitParams orbit_params[100]; |
|
|
|
OrbitParams orbit_params[100]; |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < body_count; i++) { |
|
|
|
for (int i = 0; i < body_count; i++) { |
|
|
|
toml_datum_t body_table = bodies.u.arr.elem[i]; |
|
|
|
toml_datum_t body_table = bodies.u.arr.elem[i]; |
|
|
|
if (!parse_toml_body(body_table, &sim->bodies[i])) { |
|
|
|
if (!parse_toml_body(body_table, &sim->bodies[i])) { |
|
|
|
@ -141,21 +141,21 @@ bool load_system_config(SimulationState* sim, const char* filepath) { |
|
|
|
toml_free(result); |
|
|
|
toml_free(result); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Store orbit parameters for velocity calculation
|
|
|
|
// Store orbit parameters for velocity calculation
|
|
|
|
orbit_params[i].eccentricity = sim->bodies[i].eccentricity; |
|
|
|
orbit_params[i].eccentricity = sim->bodies[i].eccentricity; |
|
|
|
orbit_params[i].semi_major_axis = sim->bodies[i].semi_major_axis; |
|
|
|
orbit_params[i].semi_major_axis = sim->bodies[i].semi_major_axis; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sim->body_count = body_count; |
|
|
|
sim->body_count = body_count; |
|
|
|
toml_free(result); |
|
|
|
toml_free(result); |
|
|
|
|
|
|
|
|
|
|
|
// Calculate initial velocities
|
|
|
|
// Calculate initial velocities
|
|
|
|
calculate_velocities(sim, orbit_params); |
|
|
|
calculate_velocities(sim, orbit_params); |
|
|
|
|
|
|
|
|
|
|
|
// Calculate SOI radii
|
|
|
|
// Calculate SOI radii
|
|
|
|
calculate_soi_radii(sim); |
|
|
|
calculate_soi_radii(sim); |
|
|
|
|
|
|
|
|
|
|
|
printf("Loaded %d bodies from %s\n", body_count, filepath); |
|
|
|
printf("Loaded %d bodies from %s\n", body_count, filepath); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -326,4 +326,4 @@ void calculate_soi_radii(SimulationState* sim) { |
|
|
|
update_soi(body, parent, body->semi_major_axis); |
|
|
|
update_soi(body, parent, body->semi_major_axis); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|