vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

139 lines
4.6 KiB

#include "config_loader.h"
#include <cstdio>
#include <cmath>
#include <cstring>
static bool extract_vec3_from_table(toml_datum_t table, Vec3* pos) {
toml_datum_t x = toml_get(table, "x");
toml_datum_t y = toml_get(table, "y");
toml_datum_t z = toml_get(table, "z");
// Accept both INT64 and FP64 for coordinates (TOML may parse integers as floats)
if ((x.type != TOML_FP64 && x.type != TOML_INT64) ||
(y.type != TOML_FP64 && y.type != TOML_INT64) ||
(z.type != TOML_FP64 && z.type != TOML_INT64)) {
return false;
}
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->z = z.type == TOML_FP64 ? z.u.fp64 : (double)z.u.int64;
return true;
}
static bool extract_color_from_table(toml_datum_t table, float* color) {
toml_datum_t r = toml_get(table, "r");
toml_datum_t g = toml_get(table, "g");
toml_datum_t b = toml_get(table, "b");
// Accept both INT64 and FP64 for color components
if ((r.type != TOML_FP64 && r.type != TOML_INT64) ||
(g.type != TOML_FP64 && g.type != TOML_INT64) ||
(b.type != TOML_FP64 && b.type != TOML_INT64)) {
return false;
}
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[2] = (float)(b.type == TOML_FP64 ? b.u.fp64 : (double)b.u.int64);
return true;
}
static bool parse_toml_body(toml_datum_t body_table, CelestialBody* body) {
// Extract string fields
toml_datum_t name = toml_get(body_table, "name");
if (name.type != TOML_STRING) {
return false;
}
strncpy(body->name, name.u.s, 63);
body->name[63] = '\0';
// Extract numeric fields
toml_datum_t mass = toml_get(body_table, "mass");
toml_datum_t radius = toml_get(body_table, "radius");
toml_datum_t parent_idx = toml_get(body_table, "parent_index");
toml_datum_t eccentricity = toml_get(body_table, "eccentricity");
toml_datum_t semi_major = toml_get(body_table, "semi_major_axis");
if (mass.type != TOML_FP64 || radius.type != TOML_FP64 ||
parent_idx.type != TOML_INT64 ||
eccentricity.type != TOML_FP64 ||
semi_major.type != TOML_FP64) {
return false;
}
body->mass = mass.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->eccentricity = eccentricity.u.fp64;
body->semi_major_axis = semi_major.u.fp64;
// Extract position vector
toml_datum_t position = toml_get(body_table, "position");
if (position.type != TOML_TABLE || !extract_vec3_from_table(position, &body->position)) {
return false;
}
// Extract color
toml_datum_t color = toml_get(body_table, "color");
if (color.type != TOML_TABLE || !extract_color_from_table(color, body->color)) {
return false;
}
// Initialize velocity (will be calculated later)
body->velocity = {0.0, 0.0, 0.0};
body->soi_radius = 0.0;
return true;
}
bool load_system_config(SimulationState* sim, const char* filepath) {
toml_result_t result = toml_parse_file_ex(filepath);
if (!result.ok) {
printf("Error: Could not parse TOML config file: %s\n", filepath);
printf("TOML Error: %s\n", result.errmsg);
return false;
}
// Get bodies array
toml_datum_t bodies = toml_get(result.toptab, "bodies");
if (bodies.type != TOML_ARRAY) {
printf("Error: Expected 'bodies' array in config file: %s\n", filepath);
toml_free(result);
return false;
}
// Count bodies first
int body_count = bodies.u.arr.size;
if (body_count == 0) {
printf("Error: No bodies found in config file: %s\n", filepath);
toml_free(result);
return false;
}
if (body_count > sim->max_bodies) {
printf("Error: Too many bodies (%d) for simulation (max: %d)\n",
body_count, sim->max_bodies);
toml_free(result);
return false;
}
for (int i = 0; i < body_count; i++) {
toml_datum_t body_table = bodies.u.arr.elem[i];
if (!parse_toml_body(body_table, &sim->bodies[i])) {
printf("Error: Failed to parse body at index %d\n", i);
toml_free(result);
return false;
}
}
sim->body_count = body_count;
toml_free(result);
calculate_initial_velocities(sim);
calculate_soi_radii(sim);
initialize_local_coordinates(sim);
printf("Loaded %d bodies from %s\n", body_count, filepath);
return true;
}