solarsystems 0.0.1

N-body solar system engine — gravitational dynamics, orbital mechanics, perturbations, event detection, and full celestial orchestration
Documentation
use crate::BodyId;

mod asteroids;
mod comets;
mod dwarf_planets;
mod planets;
mod rings;
mod satellites;
mod stars;

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SurfaceFeature {
    pub name: &'static str,
    pub kind: &'static str,
    pub material: &'static str,
    pub lon_deg: f32,
    pub lat_deg: f32,
    pub lon_size_deg: f32,
    pub lat_size_deg: f32,
    pub rotation_deg: f32,
    pub intensity: f32,
    pub noise: f32,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RingBand {
    pub name: &'static str,
    pub inner_radius: f32,
    pub outer_radius: f32,
    pub color: [f32; 3],
    pub opacity: f32,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RenderQuality {
    pub mesh_segments: u16,
    pub texture_width: u16,
    pub texture_height: u16,
    pub ring_segments: u16,
    pub ring_slice_density: u16,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BodyRenderProfile {
    pub family: &'static str,
    pub base_material: &'static str,
    pub secondary_material: &'static str,
    pub accent_material: &'static str,
    pub polar_material: &'static str,
    pub ocean_material: &'static str,
    pub height_scale: f32,
    pub roughness_bias: f32,
    pub normal_scale: f32,
}

pub fn body_surface_features(id: BodyId) -> &'static [SurfaceFeature] {
    match id {
        BodyId::Mercury => planets::MERCURY_SURFACE_FEATURES,
        BodyId::Venus => planets::VENUS_SURFACE_FEATURES,
        BodyId::Earth => planets::EARTH_SURFACE_FEATURES,
        BodyId::Mars => planets::MARS_SURFACE_FEATURES,
        BodyId::Sun => stars::SUN_SURFACE_FEATURES,
        BodyId::Jupiter => planets::JUPITER_SURFACE_FEATURES,
        BodyId::Saturn => planets::SATURN_SURFACE_FEATURES,
        BodyId::Uranus => planets::URANUS_SURFACE_FEATURES,
        BodyId::Neptune => planets::NEPTUNE_SURFACE_FEATURES,
        BodyId::Moon => satellites::MOON_SURFACE_FEATURES,
        BodyId::Io => satellites::IO_SURFACE_FEATURES,
        BodyId::Europa => satellites::EUROPA_SURFACE_FEATURES,
        BodyId::Ganymede => satellites::GANYMEDE_SURFACE_FEATURES,
        BodyId::Callisto => satellites::CALLISTO_SURFACE_FEATURES,
        BodyId::Titan => satellites::TITAN_SURFACE_FEATURES,
        BodyId::Enceladus => satellites::ENCELADUS_SURFACE_FEATURES,
        BodyId::Triton => satellites::TRITON_SURFACE_FEATURES,
        BodyId::Titania => satellites::TITANIA_SURFACE_FEATURES,
        BodyId::Oberon => satellites::OBERON_SURFACE_FEATURES,
        BodyId::Phobos => satellites::PHOBOS_SURFACE_FEATURES,
        BodyId::Deimos => satellites::DEIMOS_SURFACE_FEATURES,
        BodyId::Pluto => dwarf_planets::PLUTO_SURFACE_FEATURES,
        BodyId::Eris => dwarf_planets::ERIS_SURFACE_FEATURES,
        BodyId::Haumea => dwarf_planets::HAUMEA_SURFACE_FEATURES,
        BodyId::Makemake => dwarf_planets::MAKEMAKE_SURFACE_FEATURES,
        BodyId::Sedna => dwarf_planets::SEDNA_SURFACE_FEATURES,
        BodyId::Ceres => asteroids::CERES_SURFACE_FEATURES,
        BodyId::Vesta => asteroids::VESTA_SURFACE_FEATURES,
        BodyId::Pallas => asteroids::PALLAS_SURFACE_FEATURES,
        BodyId::Hygiea => asteroids::HYGIEA_SURFACE_FEATURES,
        BodyId::Juno => asteroids::JUNO_SURFACE_FEATURES,
        BodyId::Halley => comets::HALLEY_SURFACE_FEATURES,
        BodyId::Encke => comets::ENCKE_SURFACE_FEATURES,
        BodyId::HaleBopp => comets::HALE_BOPP_SURFACE_FEATURES,
        BodyId::ChuryumovGerasimenko => comets::CHURYUMOV_GERASIMENKO_SURFACE_FEATURES,
        BodyId::Tempel1 => comets::TEMPEL1_SURFACE_FEATURES,
        _ => &[],
    }
}

pub fn body_ring_bands(id: BodyId) -> &'static [RingBand] {
    match id {
        BodyId::Saturn => rings::SATURN_RING_BANDS,
        BodyId::Jupiter => rings::JUPITER_RING_BANDS,
        BodyId::Uranus => rings::URANUS_RING_BANDS,
        BodyId::Neptune => rings::NEPTUNE_RING_BANDS,
        _ => &[],
    }
}

pub fn body_render_quality(id: BodyId) -> RenderQuality {
    match id {
        BodyId::Sun => RenderQuality {
            mesh_segments: 320,
            texture_width: 2048,
            texture_height: 1024,
            ring_segments: 0,
            ring_slice_density: 0,
        },
        BodyId::Jupiter | BodyId::Saturn | BodyId::Earth => RenderQuality {
            mesh_segments: 256,
            texture_width: 2048,
            texture_height: 1024,
            ring_segments: 720,
            ring_slice_density: 96,
        },
        BodyId::Mercury | BodyId::Venus | BodyId::Mars | BodyId::Uranus | BodyId::Neptune => {
            RenderQuality {
                mesh_segments: 224,
                texture_width: 1024,
                texture_height: 512,
                ring_segments: 640,
                ring_slice_density: 72,
            }
        }
        BodyId::Moon
        | BodyId::Io
        | BodyId::Europa
        | BodyId::Ganymede
        | BodyId::Callisto
        | BodyId::Titan
        | BodyId::Enceladus
        | BodyId::Titania
        | BodyId::Oberon
        | BodyId::Triton => RenderQuality {
            mesh_segments: 192,
            texture_width: 1024,
            texture_height: 512,
            ring_segments: 512,
            ring_slice_density: 48,
        },
        BodyId::Phobos
        | BodyId::Deimos
        | BodyId::Pluto
        | BodyId::Eris
        | BodyId::Haumea
        | BodyId::Makemake
        | BodyId::Sedna
        | BodyId::Ceres
        | BodyId::Vesta
        | BodyId::Pallas
        | BodyId::Hygiea
        | BodyId::Juno
        | BodyId::Halley
        | BodyId::Encke
        | BodyId::HaleBopp
        | BodyId::ChuryumovGerasimenko
        | BodyId::Tempel1 => RenderQuality {
            mesh_segments: 128,
            texture_width: 512,
            texture_height: 256,
            ring_segments: 360,
            ring_slice_density: 36,
        },
        BodyId::BeltAsteroid(_) | BodyId::KuiperObject(_) => RenderQuality {
            mesh_segments: 96,
            texture_width: 512,
            texture_height: 256,
            ring_segments: 240,
            ring_slice_density: 24,
        },
    }
}

pub fn body_render_profile(id: BodyId) -> BodyRenderProfile {
    match id {
        BodyId::Sun => BodyRenderProfile {
            family: "star",
            base_material: "photosphere",
            secondary_material: "prominence",
            accent_material: "sunspot",
            polar_material: "prominence",
            ocean_material: "",
            height_scale: 0.10,
            roughness_bias: -0.35,
            normal_scale: 0.45,
        },
        BodyId::Earth => BodyRenderProfile {
            family: "oceanic_terrestrial",
            base_material: "grassland",
            secondary_material: "forest",
            accent_material: "rock",
            polar_material: "ice",
            ocean_material: "ocean",
            height_scale: 0.38,
            roughness_bias: 0.00,
            normal_scale: 1.35,
        },
        BodyId::Mercury
        | BodyId::Moon
        | BodyId::Phobos
        | BodyId::Deimos
        | BodyId::Ceres
        | BodyId::Vesta
        | BodyId::Pallas
        | BodyId::Hygiea
        | BodyId::Juno => BodyRenderProfile {
            family: "airless_rocky",
            base_material: "regolith",
            secondary_material: "smooth_plains",
            accent_material: "crater_floor",
            polar_material: "polar_ice",
            ocean_material: "",
            height_scale: 0.28,
            roughness_bias: 0.10,
            normal_scale: 1.25,
        },
        BodyId::Venus | BodyId::Mars => BodyRenderProfile {
            family: "terrestrial",
            base_material: "regolith",
            secondary_material: "bright_dust",
            accent_material: "volcanic",
            polar_material: "water_ice",
            ocean_material: "",
            height_scale: 0.32,
            roughness_bias: 0.04,
            normal_scale: 1.20,
        },
        BodyId::Jupiter | BodyId::Saturn => BodyRenderProfile {
            family: "banded_gas_giant",
            base_material: "ammoniacloud",
            secondary_material: "nh4shcloud",
            accent_material: "stormregion",
            polar_material: "hazelayer",
            ocean_material: "",
            height_scale: 0.12,
            roughness_bias: -0.18,
            normal_scale: 0.70,
        },
        BodyId::Uranus | BodyId::Neptune => BodyRenderProfile {
            family: "ice_giant",
            base_material: "methanecloud",
            secondary_material: "h2scloud",
            accent_material: "stormregion",
            polar_material: "hazelayer",
            ocean_material: "",
            height_scale: 0.10,
            roughness_bias: -0.14,
            normal_scale: 0.62,
        },
        BodyId::Io
        | BodyId::Europa
        | BodyId::Ganymede
        | BodyId::Callisto
        | BodyId::Titan
        | BodyId::Enceladus
        | BodyId::Titania
        | BodyId::Oberon
        | BodyId::Triton => BodyRenderProfile {
            family: "icy_body",
            base_material: "dark_terrain",
            secondary_material: "icy_bright",
            accent_material: "crater_floor",
            polar_material: "pristine_ice",
            ocean_material: "",
            height_scale: 0.26,
            roughness_bias: 0.02,
            normal_scale: 1.15,
        },
        BodyId::Pluto | BodyId::Eris | BodyId::Haumea | BodyId::Makemake | BodyId::Sedna => {
            BodyRenderProfile {
                family: "minor_body",
                base_material: "dark_terrain",
                secondary_material: "icy_bright",
                accent_material: "crater_floor",
                polar_material: "icy_bright",
                ocean_material: "",
                height_scale: 0.22,
                roughness_bias: 0.05,
                normal_scale: 1.10,
            }
        }
        BodyId::Halley
        | BodyId::Encke
        | BodyId::HaleBopp
        | BodyId::ChuryumovGerasimenko
        | BodyId::Tempel1 => BodyRenderProfile {
            family: "comet_nucleus",
            base_material: "dark_terrain",
            secondary_material: "icy_bright",
            accent_material: "icy_bright",
            polar_material: "icy_bright",
            ocean_material: "",
            height_scale: 0.20,
            roughness_bias: 0.08,
            normal_scale: 1.05,
        },
        BodyId::BeltAsteroid(_) | BodyId::KuiperObject(_) => BodyRenderProfile {
            family: "minor_body",
            base_material: "dark_terrain",
            secondary_material: "icy_bright_patch",
            accent_material: "crater_floor",
            polar_material: "icy_bright_patch",
            ocean_material: "",
            height_scale: 0.18,
            roughness_bias: 0.08,
            normal_scale: 1.00,
        },
    }
}