Browse Source

Migrate config system from space-separated to TOML format

- Add tomlc17 library as git submodule
- Update Makefile to build tomlc17.c with C compiler
- Replace config_loader.cpp with TOML-based implementation
- Add helper functions for parsing TOML tables (position, color)
- Convert all 5 config files from .txt to .toml format:
  * configs/solar_system.toml - full solar system with planets and moons
  * configs/example_binary_star.toml - binary star system
  * configs/test_simple.toml - various orbit types for testing
  * tests/configs/earth_circular.toml - Earth orbit test
  * tests/configs/mars_circular.toml - Mars orbit test
- Update all test files to reference .toml extensions
- Remove old .txt config files (maintain compatibility)
- Support both INT64 and FP64 TOML values (tomlc17 type flexibility)
- All automated tests pass with new TOML format

Claude
main
cinnaboot 6 months ago
parent
commit
1ac7e359a4
  1. 3
      .gitmodules
  2. 57
      Makefile
  3. 62
      configs/example_binary_star.toml
  4. 150
      configs/solar_system.toml
  5. 83
      configs/test_simple.toml
  6. 1
      ext/tomlc17
  7. 177
      src/config_loader.cpp
  8. 10
      src/config_loader.h
  9. 23
      tests/configs/earth_circular.toml
  10. 23
      tests/configs/mars_circular.toml
  11. 2
      tests/test_comet_orbit.cpp
  12. 2
      tests/test_energy.cpp
  13. 4
      tests/test_orbital_period.cpp

3
.gitmodules vendored

@ -1,3 +1,6 @@
[submodule "ext/raylib"] [submodule "ext/raylib"]
path = ext/raylib path = ext/raylib
url = https://github.com/raysan5/raylib.git url = https://github.com/raysan5/raylib.git
[submodule "ext/tomlc17"]
path = ext/tomlc17
url = https://github.com/cktan/tomlc17

57
Makefile

@ -1,6 +1,6 @@
# Compiler and flags # Compiler and flags
CXX = g++ CXX = g++
CXXFLAGS = -Wall -Wextra -g -ggdb3 -std=c++14 -I./src -isystem./ext/raylib/src CXXFLAGS = -Wall -Wextra -g -ggdb3 -std=c++14 -I./src -isystem./ext/raylib/src -I./ext/tomlc17/src
LDFLAGS = -L./ext/raylib/src -lraylib -lm -lpthread -ldl -lrt -lX11 LDFLAGS = -L./ext/raylib/src -lraylib -lm -lpthread -ldl -lrt -lX11
# Directories # Directories
@ -12,14 +12,20 @@ TEST_DIR = tests
TEST_TARGET = orbit_test TEST_TARGET = orbit_test
# Source files # Source files
SOURCES = $(SRC_DIR)/main.cpp \ CPP_SOURCES = $(SRC_DIR)/main.cpp \
$(SRC_DIR)/physics.cpp \ $(SRC_DIR)/physics.cpp \
$(SRC_DIR)/bodies.cpp \ $(SRC_DIR)/bodies.cpp \
$(SRC_DIR)/config_loader.cpp \ $(SRC_DIR)/config_loader.cpp \
$(SRC_DIR)/renderer.cpp $(SRC_DIR)/renderer.cpp
C_SOURCES = $(SRC_DIR)/../ext/tomlc17/src/tomlc17.c
SOURCES = $(CPP_SOURCES) $(C_SOURCES)
# Object files # Object files
OBJECTS = $(SOURCES:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o) CPP_OBJECTS = $(CPP_SOURCES:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
C_OBJECTS = $(C_SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
OBJECTS = $(CPP_OBJECTS) $(C_OBJECTS)
# Default target # Default target
all: raylib $(BUILD_DIR) $(TARGET) all: raylib $(BUILD_DIR) $(TARGET)
@ -39,10 +45,14 @@ $(BUILD_DIR):
$(TARGET): $(OBJECTS) raylib $(TARGET): $(OBJECTS) raylib
$(CXX) $(OBJECTS) -o $(TARGET) $(LDFLAGS) $(CXX) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
# Compile source files # Compile C++ source files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@ $(CXX) $(CXXFLAGS) -c $< -o $@
# Compile C source files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) -Wall -Wextra -g -ggdb3 -std=c99 -I./src -I./ext/tomlc17/src -c $< -o $@
# Clean build files # Clean build files
clean: clean:
rm -rf $(BUILD_DIR) $(TARGET) rm -rf $(BUILD_DIR) $(TARGET)
@ -60,20 +70,31 @@ run: $(TARGET)
# Run manual integration test with simulation # Run manual integration test with simulation
test-manual: $(TARGET) test-manual: $(TARGET)
./$(TARGET) configs/test_simple.txt --headless --readable --days 365 ./$(TARGET) configs/test_simple.toml --headless --readable --days 365
# Build automated test suite # Build automated test suite
test-build: test-build:
$(CXX) $(CXXFLAGS) -I/usr/include/catch2 \ $(CXX) $(CXXFLAGS) -I/usr/include/catch2 \
$(TEST_DIR)/test_main.cpp \ -c $(TEST_DIR)/test_main.cpp -o build/test_main.o
$(TEST_DIR)/test_integration.cpp \ $(CXX) $(CXXFLAGS) -I/usr/include/catch2 \
$(TEST_DIR)/test_energy.cpp \ -c $(TEST_DIR)/test_integration.cpp -o build/test_integration.o
$(TEST_DIR)/test_orbital_period.cpp \ $(CXX) $(CXXFLAGS) -I/usr/include/catch2 \
$(TEST_DIR)/test_comet_orbit.cpp \ -c $(TEST_DIR)/test_energy.cpp -o build/test_energy.o
$(SRC_DIR)/test_utilities.cpp \ $(CXX) $(CXXFLAGS) -I/usr/include/catch2 \
$(SRC_DIR)/physics.cpp \ -c $(TEST_DIR)/test_orbital_period.cpp -o build/test_orbital_period.o
$(SRC_DIR)/bodies.cpp \ $(CXX) $(CXXFLAGS) -I/usr/include/catch2 \
$(SRC_DIR)/config_loader.cpp \ -c $(TEST_DIR)/test_comet_orbit.cpp -o build/test_comet_orbit.o
$(CXX) $(CXXFLAGS) \
-c $(SRC_DIR)/test_utilities.cpp -o build/test_utilities.o
$(CXX) $(CXXFLAGS) \
-c $(SRC_DIR)/physics.cpp -o build/test_physics.o
$(CXX) $(CXXFLAGS) \
-c $(SRC_DIR)/bodies.cpp -o build/test_bodies.o
$(CXX) $(CXXFLAGS) \
-c $(SRC_DIR)/config_loader.cpp -o build/test_config_loader.o
$(CC) -Wall -Wextra -g -ggdb3 -std=c99 -I./src -I./ext/tomlc17/src \
-c $(SRC_DIR)/../ext/tomlc17/src/tomlc17.c -o build/test_tomlc17.o
$(CXX) build/test_main.o build/test_integration.o build/test_energy.o build/test_orbital_period.o build/test_comet_orbit.o build/test_utilities.o build/test_physics.o build/test_bodies.o build/test_config_loader.o build/test_tomlc17.o \
-o $(TEST_TARGET) -lCatch2Main -lCatch2 -lm -o $(TEST_TARGET) -lCatch2Main -lCatch2 -lm
# Run automated test suite # Run automated test suite

62
configs/example_binary_star.toml

@ -0,0 +1,62 @@
# Binary Star System with Planets
# A simple example of two stars orbiting each other with planets around them
[bodies.stara]
name = "StarA"
mass = 1.5e30
radius = 8.0e8
position = { x = 3.0e11, y = 0, z = 0 }
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.2 }
eccentricity = 0
semi_major_axis = 0
[bodies.starb]
name = "StarB"
mass = 1.2e30
radius = 7.0e8
position = { x = -3.7e11, y = 0, z = 0 }
parent_index = -1
color = { r = 0.3, g = 0.5, b = 1.0 }
eccentricity = 0
semi_major_axis = 0
[bodies.planeta1]
name = "PlanetA1"
mass = 6.0e24
radius = 7.0e6
position = { x = 3.5e11, y = 0, z = 0 }
parent_index = 0
color = { r = 0.8, g = 0.3, b = 0.2 }
eccentricity = 0
semi_major_axis = 3.5e11
[bodies.planetb1]
name = "PlanetB1"
mass = 4.0e24
radius = 6.0e6
position = { x = -4.2e11, y = 0, z = 0 }
parent_index = 1
color = { r = 0.2, g = 0.8, b = 0.6 }
eccentricity = 0
semi_major_axis = 4.2e11
[bodies.moona1]
name = "MoonA1"
mass = 1.0e23
radius = 2.0e6
position = { x = 3.52e11, y = 0, z = 0 }
parent_index = 2
color = { r = 0.7, g = 0.7, b = 0.7 }
eccentricity = 0
semi_major_axis = 3.52e11
[bodies.planeta2]
name = "PlanetA2"
mass = 8.0e24
radius = 8.0e6
position = { x = 4.0e11, y = 0, z = 0 }
parent_index = 0
color = { r = 0.5, g = 0.6, b = 0.3 }
eccentricity = 0
semi_major_axis = 4.0e11

150
configs/solar_system.toml

@ -0,0 +1,150 @@
# Solar System Configuration
[[bodies]]
name = "Sun"
mass = 1.989e30 # kg
radius = 6.96e8 # m
position = { x = 0.0, y = 0.0, z = 0.0 }
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.0 }
eccentricity = 0.0
semi_major_axis = 0.0
name = "Venus"
mass = 4.867e24
radius = 6.0518e6
position = { x = 1.082e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.9, g = 0.7, b = 0.3 }
eccentricity = 0.0
semi_major_axis = 1.082e11
[[bodies]]
name = "Venus"
mass = 4.867e24
radius = 6.0518e6
position = { x = 1.082e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.9, g = 0.7, b = 0.3 }
eccentricity = 0.0
semi_major_axis = 1.082e11
[[bodies]]
name = "Earth"
mass = 5.972e24
radius = 6.371e6
position = { x = 1.496e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.0, g = 0.5, b = 1.0 }
eccentricity = 0.0
semi_major_axis = 1.496e11
[[bodies]]
name = "Mars"
mass = 6.39e23
radius = 3.3895e6
position = { x = 2.279e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.8, g = 0.3, b = 0.1 }
eccentricity = 0.0
semi_major_axis = 2.279e11
[[bodies]]
name = "Jupiter"
mass = 1.898e27
radius = 6.9911e7
position = { x = 7.785e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.9, g = 0.7, b = 0.5 }
eccentricity = 0.0
semi_major_axis = 7.785e11
[[bodies]]
name = "Saturn"
mass = 5.683e26
radius = 5.8232e7
position = { x = 1.434e12, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.9, g = 0.8, b = 0.6 }
eccentricity = 0.0
semi_major_axis = 1.434e12
[[bodies]]
name = "Uranus"
mass = 8.681e25
radius = 2.5362e7
position = { x = 2.871e12, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.5, g = 0.8, b = 0.9 }
eccentricity = 0.0
semi_major_axis = 2.871e12
[[bodies]]
name = "Neptune"
mass = 1.024e26
radius = 2.4622e7
position = { x = 4.495e12, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.2, g = 0.4, b = 0.9 }
eccentricity = 0.0
semi_major_axis = 4.495e12
[[bodies]]
name = "Moon"
mass = 7.342e22
radius = 1.737e6
position = { x = 1.500e11, y = 0.0, z = 0.0 }
parent_index = 3
color = { r = 0.7, g = 0.7, b = 0.7 }
eccentricity = 0.0
semi_major_axis = 1.500e11
[[bodies]]
name = "Io"
mass = 8.93e22
radius = 1.822e6
position = { x = 8.207e11, y = 0.0, z = 0.0 }
parent_index = 5
color = { r = 0.9, g = 0.9, b = 0.3 }
eccentricity = 0.0
semi_major_axis = 8.207e11
[[bodies]]
name = "Europa"
mass = 4.80e22
radius = 1.561e6
position = { x = 8.456e11, y = 0.0, z = 0.0 }
parent_index = 5
color = { r = 0.8, g = 0.8, b = 0.7 }
eccentricity = 0.0
semi_major_axis = 8.456e11
[[bodies]]
name = "Ganymede"
mass = 1.48e23
radius = 2.634e6
position = { x = 8.853e11, y = 0.0, z = 0.0 }
parent_index = 5
color = { r = 0.6, g = 0.6, b = 0.5 }
eccentricity = 0.0
semi_major_axis = 8.853e11
[[bodies]]
name = "Callisto"
mass = 1.08e23
radius = 2.410e6
position = { x = 9.670e11, y = 0.0, z = 0.0 }
parent_index = 5
color = { r = 0.5, g = 0.5, b = 0.4 }
eccentricity = 0.0
semi_major_axis = 9.670e11
[[bodies]]
name = "Titan"
mass = 1.345e23
radius = 2.575e6
position = { x = 1.556e12, y = 0.0, z = 0.0 }
parent_index = 6
color = { r = 0.9, g = 0.6, b = 0.3 }
eccentricity = 0.0
semi_major_axis = 1.556e12

83
configs/test_simple.toml

@ -0,0 +1,83 @@
# Simple Test Configuration
# Planets in circular and eccentric orbits
#
# Orbital periods (for verification):
# Earth: ~365 days
# Mars: ~687 days
# Comet: ~1444 days
#
# At t=0:
# Earth starts at (1.0 AU, 0, 0) = (1.496e11 m, 0, 0)
# Mars starts at (1.5 AU, 0, 0) = (2.244e11 m, 0, 0)
# Comet starts at perihelion (0.75 AU, 0, 0) = (1.122e11 m, 0, 0)
# All orbit counter-clockwise when viewed from +Z
[[bodies]]
name = "Sun"
mass = 1.989e30
radius = 6.96e8
position = { x = 0.0, y = 0.0, z = 0.0 }
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.0 }
eccentricity = 0.0
semi_major_axis = 0.0
[[bodies]]
name = "Earth"
mass = 5.972e24
radius = 6.371e6
position = { x = 1.496e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.0, g = 0.5, b = 1.0 }
eccentricity = 0.0
semi_major_axis = 1.496e11
[[bodies]]
name = "Mars"
mass = 6.39e23
radius = 3.3895e6
position = { x = 2.244e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.8, g = 0.3, b = 0.1 }
eccentricity = 0.0
semi_major_axis = 2.244e11
[[bodies]]
name = "Comet"
mass = 1e14
radius = 5e3
position = { x = 1.122e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.5, g = 0.8, b = 1.0 }
eccentricity = 0.7
semi_major_axis = 3.74e11
[[bodies]]
name = "Parabolic"
mass = 1e13
radius = 3e3
position = { x = 7.48e10, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 1.0, g = 1.0, b = 0.5 }
eccentricity = 1.0
semi_major_axis = 7.48e10
[[bodies]]
name = "Inclined"
mass = 1e12
radius = 2e3
position = { x = 1.795e11, y = 0.0, z = 3.114e10 }
parent_index = 0
color = { r = 0.8, g = 0.8, b = 0.0 }
eccentricity = 0.0
semi_major_axis = 1.795e11
[[bodies]]
name = "Hyperbolic"
mass = 1e13
radius = 3e3
position = { x = 7.48e10, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.3, g = 1.0, b = 0.3 }
eccentricity = 1.5
semi_major_axis = -1.496e11

1
ext/tomlc17

@ -0,0 +1 @@
Subproject commit b256fbf714c9edc8645010e3e44c1b6980da67b9

177
src/config_loader.cpp

@ -1,23 +1,94 @@
#include "config_loader.h" #include "config_loader.h"
#include <cstdio> #include <cstdio>
#include <cstring>
#include <cmath> #include <cmath>
#include <cstring>
// Helper function: extract Vec3 from TOML table
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");
// Parse a single body definition line // Accept both INT64 and FP64 for coordinates (TOML may parse integers as floats)
bool parse_body_line(const char* line, char* name, double* mass, double* radius, if ((x.type != TOML_FP64 && x.type != TOML_INT64) ||
Vec3* pos, int* parent_index, float* r, float* g, float* b, (y.type != TOML_FP64 && y.type != TOML_INT64) ||
double* eccentricity, double* semi_major_axis) { (z.type != TOML_FP64 && z.type != TOML_INT64)) {
// Skip empty lines and comments
if (line[0] == '\0' || line[0] == '#' || line[0] == '\n') {
return false; return false;
} }
// Format: name mass radius x y z parent_index r g b eccentricity semi_major_axis pos->x = x.type == TOML_FP64 ? x.u.fp64 : (double)x.u.int64;
int result = sscanf(line, "%63s %lf %lf %lf %lf %lf %d %f %f %f %lf %lf", pos->y = y.type == TOML_FP64 ? y.u.fp64 : (double)y.u.int64;
name, mass, radius, &pos->x, &pos->y, &pos->z, pos->z = z.type == TOML_FP64 ? z.u.fp64 : (double)z.u.int64;
parent_index, r, g, b, eccentricity, semi_major_axis); return true;
}
// Helper function: extract color RGB from TOML table
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");
return result == 12; // 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;
}
// Parse individual body from TOML table
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");
// Accept both INT64 and FP64 for parent_index (TOML may parse integers as floats)
if (mass.type != TOML_FP64 || radius.type != TOML_FP64 ||
(parent_idx.type != TOML_INT64 && parent_idx.type != TOML_FP64) ||
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;
} }
struct OrbitParams { struct OrbitParams {
@ -28,50 +99,64 @@ struct OrbitParams {
// Forward declaration // Forward declaration
void calculate_velocities(SimulationState* sim, OrbitParams* orbit_params); void calculate_velocities(SimulationState* sim, OrbitParams* orbit_params);
// Load system configuration from file // Load system configuration from TOML file
bool load_system_config(SimulationState* sim, const char* filepath) { bool load_system_config(SimulationState* sim, const char* filepath) {
FILE* file = fopen(filepath, "r"); toml_result_t result = toml_parse_file_ex(filepath);
if (!file) { if (!result.ok) {
printf("Error: Could not open config file: %s\n", filepath); printf("Error: Could not parse TOML config file: %s\n", filepath);
printf("TOML Error: %s\n", result.errmsg);
return false; return false;
} }
char line[256]; // Get bodies array
char name[64]; toml_datum_t bodies = toml_get(result.toptab, "bodies");
double mass, radius; if (bodies.type != TOML_ARRAY) {
Vec3 pos; printf("Error: Expected 'bodies' array in config file: %s\n", filepath);
int parent_index; toml_free(result);
float r, g, b; return false;
double eccentricity, semi_major_axis;
OrbitParams orbit_params[100];
while (fgets(line, sizeof(line), file)) {
if (parse_body_line(line, name, &mass, &radius, &pos, &parent_index, &r, &g, &b,
&eccentricity, &semi_major_axis)) {
Vec3 vel = {0.0, 0.0, 0.0};
add_body(sim, name, mass, radius, pos, vel, parent_index, r, g, b,
eccentricity, semi_major_axis);
orbit_params[sim->body_count - 1].eccentricity = eccentricity;
orbit_params[sim->body_count - 1].semi_major_axis = semi_major_axis;
}
} }
fclose(file); // Count bodies first
int body_count = bodies.u.arr.size;
if (sim->body_count == 0) { if (body_count == 0) {
printf("Error: No bodies loaded from config file\n"); printf("Error: No bodies found in config file: %s\n", filepath);
toml_free(result);
return false; 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;
}
// Parse each body and store orbit params
OrbitParams orbit_params[100];
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;
}
// Store orbit parameters for velocity calculation
orbit_params[i].eccentricity = sim->bodies[i].eccentricity;
orbit_params[i].semi_major_axis = sim->bodies[i].semi_major_axis;
}
sim->body_count = body_count;
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", sim->body_count, filepath); printf("Loaded %d bodies from %s\n", body_count, filepath);
return true; return true;
} }

10
src/config_loader.h

@ -2,13 +2,15 @@
#define CONFIG_LOADER_H #define CONFIG_LOADER_H
#include "bodies.h" #include "bodies.h"
#include "../ext/tomlc17/src/tomlc17.h"
// Load a system configuration from a file // Load a system configuration from a file (TOML format)
bool load_system_config(SimulationState* sim, const char* filepath); bool load_system_config(SimulationState* sim, const char* filepath);
// Parse a single body definition line // Helper functions for TOML parsing
bool parse_body_line(const char* line, char* name, double* mass, double* radius, bool extract_vec3_from_table(toml_datum_t table, Vec3* pos);
Vec3* pos, int* parent_index, float* r, float* g, float* b); bool extract_color_from_table(toml_datum_t table, float* color);
bool parse_toml_body(toml_datum_t body_table, CelestialBody* body);
// Calculate initial circular orbit velocities for all bodies // Calculate initial circular orbit velocities for all bodies
void calculate_initial_velocities(SimulationState* sim); void calculate_initial_velocities(SimulationState* sim);

23
tests/configs/earth_circular.toml

@ -0,0 +1,23 @@
# Test Configuration: Sun + Earth (circular orbit)
# Earth at 1 AU with circular orbit
# Expected orbital period: ~365 days
[[bodies]]
name = "Sun"
mass = 1.989e30
radius = 6.96e8
position = { x = 0.0, y = 0.0, z = 0.0 }
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.0 }
eccentricity = 0.0
semi_major_axis = 0.0
[[bodies]]
name = "Earth"
mass = 5.972e24
radius = 6.371e6
position = { x = 1.496e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.0, g = 0.5, b = 1.0 }
eccentricity = 0.0
semi_major_axis = 1.496e11

23
tests/configs/mars_circular.toml

@ -0,0 +1,23 @@
# Test Configuration: Sun + Mars (circular orbit)
# Mars at 1.5 AU with circular orbit
# Expected orbital period: ~687 days
[[bodies]]
name = "Sun"
mass = 1.989e30
radius = 6.96e8
position = { x = 0.0, y = 0.0, z = 0.0 }
parent_index = -1
color = { r = 1.0, g = 1.0, b = 0.0 }
eccentricity = 0.0
semi_major_axis = 0.0
[[bodies]]
name = "Mars"
mass = 6.39e23
radius = 3.3895e6
position = { x = 2.244e11, y = 0.0, z = 0.0 }
parent_index = 0
color = { r = 0.8, g = 0.3, b = 0.1 }
eccentricity = 0.0
semi_major_axis = 2.244e11

2
tests/test_comet_orbit.cpp

@ -79,7 +79,7 @@ TEST_CASE("Comet orbital elements and SOI transitions during Mars encounter", "[
SimulationState* sim = create_simulation(10, TIME_STEP); SimulationState* sim = create_simulation(10, TIME_STEP);
REQUIRE(load_system_config(sim, "configs/test_simple.txt")); REQUIRE(load_system_config(sim, "configs/test_simple.toml"));
const int COMET_INDEX = 3; const int COMET_INDEX = 3;
const int MARS_INDEX = 2; const int MARS_INDEX = 2;

2
tests/test_energy.cpp

@ -12,7 +12,7 @@ TEST_CASE("Energy conservation - Earth circular orbit", "[energy][rk4]") {
SimulationState* sim = create_simulation(10, TIME_STEP); SimulationState* sim = create_simulation(10, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/configs/earth_circular.txt")); REQUIRE(load_system_config(sim, "tests/configs/earth_circular.toml"));
double initial_energy = calculate_system_total_energy(sim); double initial_energy = calculate_system_total_energy(sim);

4
tests/test_orbital_period.cpp

@ -13,7 +13,7 @@ TEST_CASE("Orbital period - Earth (RK4)", "[period][rk4]") {
SimulationState* sim = create_simulation(10, TIME_STEP); SimulationState* sim = create_simulation(10, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/configs/earth_circular.txt")); REQUIRE(load_system_config(sim, "tests/configs/earth_circular.toml"));
OrbitTracker* tracker = create_orbit_tracker(1); OrbitTracker* tracker = create_orbit_tracker(1);
@ -46,7 +46,7 @@ TEST_CASE("Orbital period - Mars (RK4)", "[period][rk4]") {
SimulationState* sim = create_simulation(10, TIME_STEP); SimulationState* sim = create_simulation(10, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/configs/mars_circular.txt")); REQUIRE(load_system_config(sim, "tests/configs/mars_circular.toml"));
OrbitTracker* tracker = create_orbit_tracker(1); OrbitTracker* tracker = create_orbit_tracker(1);

Loading…
Cancel
Save