use bevy::prelude::*; #[derive(Resource, Clone)] pub struct PlanetData { pub lod_focus: Vec3, // add radius, noise params, max lod, etc } #[derive(Component)] pub struct Planet; #[derive(Component)] pub struct PlanetMeshFace { pub normal: Vec3, pub name: &'static str, } const PLANET_FACES: [(Vec3, &str); 6] = [ (Vec3::Y, "Top"), (-Vec3::Y, "Bot"), (-Vec3::X, "Left"), (Vec3::X, "Right"), (-Vec3::Z, "Back"), (Vec3::Z, "Front"), ]; pub fn spawn_planet( mut commands: Commands, ) { commands .spawn(( Planet, Transform::default(), GlobalTransform::default(), )) .with_children(|parent| { for (normal, name) in PLANET_FACES { parent.spawn(( PlanetMeshFace { normal, name }, Transform::default(), GlobalTransform::default(), )); } }); } pub fn regenerate_faces_on_planet_data_change( planet_data: Res, mut faces: Query<&PlanetMeshFace>, ) { if !planet_data.is_changed() { return; } for face in &mut faces { regenerate_mesh(face, &planet_data); } } fn regenerate_mesh(face: &PlanetMeshFace, planet_data: &PlanetData) { // Equivalent of: // child._regenerate_mesh(planet_data) // Typical steps: // - Build quadtree // - Project cube → sphere // - LOD based on planet_data.lod_focus // - Write Mesh } #[derive(Component)] pub struct Player; pub fn update_lod_focus_from_player( player: Query<&GlobalTransform, With>, mut planet_data: ResMut, ) { if let Ok(player_transform) = player.get_single() { planet_data.lod_focus = player_transform.translation(); } } pub struct PlanetPlugin; impl Plugin for PlanetPlugin { fn build(&self, app: &mut App) { app .insert_resource(PlanetData { lod_focus: Vec3::ZERO, }) .add_startup_system(spawn_planet) .add_system(update_lod_focus_from_player) .add_system(regenerate_faces_on_planet_data_change); } }