$darkmode
Suckless OGL 1.0.0
A lean, high-performance C11 PBR Renderer
nbody.c File Reference
#include "nbody.h"
#include "dvec3.h"
#include "utils.h"
#include <cglm/affine.h>
#include <cglm/mat4.h>
#include <cglm/vec3.h>
#include <math.h>
Include dependency graph for nbody.c:

Data Structures

struct  OrbiterDef
 

Functions

static void add_body (NBodySim *sim, const double pos[3], const double vel[3], double mass, float radius, const vec3 albedo, float metallic, float roughness)
 
static double pair_softening_sq (double radius_i, double radius_j)
 
static double softened_orbital_vel (double grav, double central_mass, double orbit_r, double star_r, double body_r)
 
void nbody_init_preset (NBodySim *sim)
 Initializes the simulation with a preset solar system configuration. More...
 
float nbody_total_energy (const NBodySim *sim)
 Computes the total energy (kinetic + gravitational potential). More...
 
static void compute_accelerations (const NBodySim *sim, double accel[][3])
 
static void integrate_step (NBodySim *sim, float delta_time)
 
void nbody_step (NBodySim *sim, float delta_time)
 Advances the simulation by the given wall-clock delta time. More...
 
void nbody_write_instances (const NBodySim *sim, SphereInstance *out)
 Writes current body positions and materials into a SphereInstance array suitable for the instanced rendering pipeline. More...
 
int nbody_get_count (const NBodySim *sim)
 Returns the number of active bodies. More...
 
float nbody_kinetic_energy (const NBodySim *sim)
 Computes kinetic energy only: Σ ½ m v². More...
 
float nbody_energy_drift (const NBodySim *sim)
 Returns the relative energy drift |E(t) - E₀| / |E₀|. More...
 
float nbody_energy_drift_signed (const NBodySim *sim)
 
void nbody_update_time_scale (NBodySim *sim, float delta_time)
 Smoothly transitions time_scale toward target_time_scale. More...
 

Variables

static const float EPSILON = 1e-6F
 
static const double MIN_DIST = 1e-9
 
static const double CENTRAL_STAR_MASS = 100.0
 
static const float CENTRAL_STAR_RADIUS = 1.5F
 
static const vec3 CENTRAL_STAR_ALBEDO = {1.0F, 0.76F, 0.34F}
 
static const float CENTRAL_STAR_METALLIC = 1.0F
 
static const float CENTRAL_STAR_ROUGHNESS = 0.2F
 
static const double HALF = 0.5
 
static const struct OrbiterDef ORBITERS []
 
static const int ORBITER_COUNT = (int)(sizeof(ORBITERS) / sizeof(ORBITERS[0]))
 

Function Documentation

◆ add_body()

static void add_body ( NBodySim *  sim,
const double  pos[3],
const double  vel[3],
double  mass,
float  radius,
const vec3  albedo,
float  metallic,
float  roughness 
)
static
Here is the call graph for this function:

◆ compute_accelerations()

static void compute_accelerations ( const NBodySim *  sim,
double  accel[][3] 
)
static
Here is the call graph for this function:

◆ integrate_step()

static void integrate_step ( NBodySim *  sim,
float  delta_time 
)
static
Here is the call graph for this function:

◆ nbody_energy_drift()

float nbody_energy_drift ( const NBodySim *  sim)

Returns the relative energy drift |E(t) - E₀| / |E₀|.

Returns 0 when initial_energy is zero (no reference).

Here is the call graph for this function:

◆ nbody_energy_drift_signed()

float nbody_energy_drift_signed ( const NBodySim *  sim)

Signed energy drift: negative = energy lost (damping), positive = energy gained (divergence).

Here is the call graph for this function:

◆ nbody_get_count()

int nbody_get_count ( const NBodySim *  sim)

Returns the number of active bodies.

◆ nbody_init_preset()

void nbody_init_preset ( NBodySim *  sim)

Initializes the simulation with a preset solar system configuration.

Parameters
simPointer to the simulation state.
Here is the call graph for this function:

◆ nbody_kinetic_energy()

float nbody_kinetic_energy ( const NBodySim *  sim)

Computes kinetic energy only: Σ ½ m v².

Here is the call graph for this function:

◆ nbody_step()

void nbody_step ( NBodySim *  sim,
float  delta_time 
)

Advances the simulation by the given wall-clock delta time.

Uses a fixed-timestep accumulator with Velocity Verlet integration.

Parameters
simPointer to the simulation state.
delta_timeWall-clock time elapsed since last call (seconds).
Here is the call graph for this function:

◆ nbody_total_energy()

float nbody_total_energy ( const NBodySim *  sim)

Computes the total energy (kinetic + gravitational potential).

Useful for stability diagnostics. With a symplectic integrator, this quantity oscillates with bounded amplitude around E₀.

Here is the call graph for this function:

◆ nbody_update_time_scale()

void nbody_update_time_scale ( NBodySim *  sim,
float  delta_time 
)

Smoothly transitions time_scale toward target_time_scale.

Called once per frame. Ramps at NBODY_TIME_SCALE_RATE units/s, producing a decelerate → pause → accelerate-in-reverse effect.

Parameters
simPointer to the simulation state.
delta_timeWall-clock frame delta (seconds).

◆ nbody_write_instances()

void nbody_write_instances ( const NBodySim *  sim,
SphereInstance *  out 
)

Writes current body positions and materials into a SphereInstance array suitable for the instanced rendering pipeline.

Parameters
simPointer to the simulation state.
outOutput array (must have capacity >= sim->body_count).

◆ pair_softening_sq()

static double pair_softening_sq ( double  radius_i,
double  radius_j 
)
static

◆ softened_orbital_vel()

static double softened_orbital_vel ( double  grav,
double  central_mass,
double  orbit_r,
double  star_r,
double  body_r 
)
static
Here is the call graph for this function:

Variable Documentation

◆ CENTRAL_STAR_ALBEDO

const vec3 CENTRAL_STAR_ALBEDO = {1.0F, 0.76F, 0.34F}
static

◆ CENTRAL_STAR_MASS

const double CENTRAL_STAR_MASS = 100.0
static

◆ CENTRAL_STAR_METALLIC

const float CENTRAL_STAR_METALLIC = 1.0F
static

◆ CENTRAL_STAR_RADIUS

const float CENTRAL_STAR_RADIUS = 1.5F
static

◆ CENTRAL_STAR_ROUGHNESS

const float CENTRAL_STAR_ROUGHNESS = 0.2F
static

◆ EPSILON

const float EPSILON = 1e-6F
static

Small epsilon to avoid division by zero.

◆ HALF

const double HALF = 0.5
static

◆ MIN_DIST

const double MIN_DIST = 1e-9
static

Minimum distance threshold to avoid division by near-zero.

◆ ORBITER_COUNT

const int ORBITER_COUNT = (int)(sizeof(ORBITERS) / sizeof(ORBITERS[0]))
static

◆ ORBITERS

const struct OrbiterDef ORBITERS[]
static
Initial value:
= {
{{ 3, 0, 0}, { 0, 1, 0}, 3, 0.30F, 0.3F, {1.0F,0.84F,0.0F}, 1.0F, 0.10F, 1.00F},
{{ 0, 5, 0.5F}, {-1, 0, 0}, 5, 0.50F, 1.5F, {0.77F,0.78F,0.78F},1.0F, 0.05F, 1.00F},
{{ 0,-1, 7}, { 1, 0, 0}, 7, 0.60F, 2.0F, {0.85F,0.85F,0.90F},1.0F, 0.15F, 1.00F},
{{-10, 0, 1.5F}, { 0,-1, 0}, 10, 0.80F, 4.0F, {0.72F,0.45F,0.20F},1.0F, 0.30F, 1.00F},
{{ 8, 2, 2}, { 0, 1,-0.3F}, 8, 0.40F, 0.5F, {0.15F,0.85F,0.95F},0.1F, 0.05F, 0.85F},
{{-3,11,-2}, { 0.5F, 0, 0.6F},11, 0.35F, 0.5F, {0.90F,0.20F,0.75F},0.1F, 0.05F, 0.85F},
{{ 4, 0.5F, 0}, { 0, 0, 1}, 4, 0.35F, 0.6F, {0.15F,0.85F,0.30F},0.8F, 0.15F, 1.00F},
{{ 0,-10, 2}, { 1, 0, 0}, 10, 0.55F, 1.8F, {0.90F,0.55F,0.65F},0.3F, 0.25F, 0.95F},
{{ 0, 0,-3.5F}, { 0, 1, 0}, 3.5F,0.30F, 0.4F, {0.10F,0.25F,0.95F},0.9F, 0.10F, 1.00F},
{{ 9,-2, 0}, { 0, 1, 0}, 9, 0.65F, 3.0F, {1.0F,0.60F,0.10F}, 0.7F, 0.30F, 1.00F},
{{11, 2,-3}, {-0.4F, 0, 0.7F},11, 0.30F, 0.4F, {0.55F,0.15F,0.95F},0.2F, 0.08F, 0.92F},
{{-6, 0,-1}, { 0, 1, 0}, 6, 0.45F, 1.2F, {0.20F,0.80F,0.75F},0.6F, 0.12F, 1.00F},
{{-12,-2, 1}, { 0.3F, 0.7F, 0},12, 0.50F, 2.5F, {0.90F,0.12F,0.15F},0.85F,0.35F, 0.95F},
}