@ -35,6 +35,14 @@ int find_dominant_body(SimulationState* sim, int body_index) {
CelestialBody * body = & sim - > bodies [ body_index ] ;
int dominant = body - > parent_index ;
// Check if we're outside current parent's SOI
bool outside_current_soi = false ;
if ( dominant > = 0 & & dominant < sim - > body_count ) {
CelestialBody * current_parent = & sim - > bodies [ dominant ] ;
double dist_to_current = vec3_distance ( body - > position , current_parent - > position ) ;
outside_current_soi = dist_to_current > current_parent - > soi_radius ;
}
// Check all other bodies to see if we're within their SOI
for ( int i = 0 ; i < sim - > body_count ; i + + ) {
if ( i = = body_index ) continue ;
@ -42,18 +50,27 @@ int find_dominant_body(SimulationState* sim, int body_index) {
CelestialBody * potential_parent = & sim - > bodies [ i ] ;
double distance = vec3_distance ( body - > position , potential_parent - > position ) ;
// If we're within this body's SOI and it's not our current parent
if ( distance < potential_parent - > soi_radius & & i ! = dominant ) {
// Check if this body is more dominant (closer or more massive)
// If we're outside current parent's SOI, consider all bodies
// Otherwise, only consider bodies within their SOI
bool can_switch = outside_current_soi | | distance < potential_parent - > soi_radius ;
if ( can_switch & & i ! = dominant ) {
if ( dominant = = - 1 ) {
dominant = i ;
} else {
CelestialBody * current_parent = & sim - > bodies [ dominant ] ;
double dist_to_current = vec3_distance ( body - > position , current_parent - > position ) ;
// Switch if this potential parent is significantly closer
if ( distance < dist_to_current * 0.5 ) {
dominant = i ;
if ( outside_current_soi ) {
// Outside current SOI: switch to closest body
if ( distance < dist_to_current ) {
dominant = i ;
}
} else {
// Inside current SOI: apply hysteresis to prevent oscillations
if ( distance < dist_to_current * 0.5 ) {
dominant = i ;
}
}
}
}