diff --git a/src/main.rs b/src/main.rs index 2f57c4f..0b2baf5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,10 +6,6 @@ use bevy::{ }; use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin}; -use big_space::{ - plugin::BigSpaceDefaultPlugins, - prelude::{BigSpaceCommands, FloatingOrigin}, -}; use iyes_perf_ui::{PerfUiPlugin, prelude::*}; use solar_sim::InitialState; @@ -118,14 +114,7 @@ impl Plugin for SolarRenderingPlugin { PostUpdate, (update_label_positions.after(manage_label_overlaps),), ) - .add_systems( - Update, - ( - handle_label_clicks, - handle_speed_controls, - enhance_sun_emissive_with_retry, - ), - ); + .add_systems(Update, (handle_label_clicks, handle_speed_controls)); } } @@ -133,18 +122,39 @@ fn sync_position_to_transform( mut query: Query<(Entity, &Position, &mut Transform)>, origin: Res, ) { - // let offset = origin.target.map_or(DVec3::ZERO, |target| { - // query - // .get(target) - // .map_or(DVec3::ZERO, |(_, position, _)| position.0.0) - // }); - let offset = DVec3::ZERO; + let offset = origin.target.map_or(DVec3::ZERO, |target| { + query + .get(target) + .map_or(DVec3::ZERO, |(_, position, _)| position.0.0) + }); for (_, position, mut transform) in query.iter_mut() { transform.translation = ((position.0.0 - offset) * AU_TO_GAME_UNITS).as_vec3(); } } fn setup_rendering(mut commands: Commands) { + // Spawn camera with pan/orbit/zoom controls + // Place it at a good distance to view the solar system + commands.spawn(( + PanOrbitCamera { + zoom_lower_limit: 1e-6, + ..default() + }, + Camera { + hdr: true, + clear_color: ClearColorConfig::Custom(Color::BLACK), + ..default() + }, + Projection::Perspective(PerspectiveProjection { + near: 1e-8, // Very close near plane for extreme zooming + far: 1e-2, + ..default() + }), + Tonemapping::TonyMcMapface, + Transform::from_translation(Vec3::new(0., 0., 10.0)), + Bloom::NATURAL, + )); + commands.spawn(PerfUiAllEntries::default()); } @@ -374,208 +384,86 @@ fn handle_speed_controls( } } -fn enhance_sun_emissive_with_retry( - mut commands: Commands, - mesh_query: Query<&MeshMaterial3d>, - mut sun_query: Query< - (Entity, &Children, Option<&mut EmissiveEnhancementAttempts>), - ( - With, - With, - Without, - ), - >, - children_query: Query<&Children>, - mut materials: ResMut>, -) { - for (sun_entity, children, attempts_opt) in sun_query.iter_mut() { - // Initialize attempts tracking if not present - let mut attempts = if let Some(mut att) = attempts_opt { - att.attempts += 1; - att.attempts - } else { - // First attempt, add the component - commands - .entity(sun_entity) - .insert(EmissiveEnhancementAttempts { - attempts: 1, - max_attempts: 300, // Try for ~5 seconds at 60fps - }); - 1 - }; - - // Only try every 10 frames to avoid spam - if attempts % 10 != 0 { - continue; - } - - info!("Attempting sun emissive enhancement (attempt {})", attempts); - - // Try to enhance the sun's emissive material - let enhanced = - enhance_emissive_for_children(children, &children_query, &mesh_query, &mut materials); - - if enhanced { - info!("Successfully enhanced sun emissive material!"); - // Mark this sun as enhanced to avoid repeated processing - commands.entity(sun_entity).insert(EmissiveEnhanced); - commands - .entity(sun_entity) - .remove::(); - commands - .entity(sun_entity) - .remove::(); - } else if attempts >= 300 { - // Give up after max attempts - info!( - "Giving up on sun emissive enhancement after {} attempts", - attempts - ); - commands - .entity(sun_entity) - .remove::(); - commands - .entity(sun_entity) - .remove::(); - } - } -} - -fn enhance_emissive_for_children( - children: &Children, - children_query: &Query<&Children>, - mesh_query: &Query<&MeshMaterial3d>, - materials: &mut ResMut>, -) -> bool { - let mut enhanced_any = false; - - for child in children.iter() { - // Try to enhance material for this child if it has a mesh - if let Ok(material_handle) = mesh_query.get(child) { - if let Some(material) = materials.get_mut(&material_handle.0) { - // Enhance emissive properties while preserving existing textures - // Set emissive to bright white to enhance the existing emissive texture - info!("Enhanced material for child entity!"); - material.emissive = LinearRgba::rgb(200.0, 200.0, 200.0); - // Keep all existing textures (base_color_texture, emissive_texture, etc.) - enhanced_any = true; - } - } - - // Recursively check this child's children - if let Ok(grandchildren) = children_query.get(child) { - if enhance_emissive_for_children(grandchildren, children_query, mesh_query, materials) { - enhanced_any = true; - } - } - } - - enhanced_any -} - const AU_TO_KM: f64 = 149597870.691; fn setup_solar_system(mut commands: Commands, asset_server: Res) { - commands.spawn_big_space_default(|commands| { - commands.spawn(( - PanOrbitCamera { - zoom_lower_limit: 1e-6, - ..default() + // Load initial state from RON file + let initial_state_content = match std::fs::read_to_string("assets/initial_state.ron") { + Ok(content) => content, + Err(err) => { + error!("Failed to read initial_state.ron: {}", err); + return; + } + }; + + let initial_state: InitialState = match ron::from_str(&initial_state_content) { + Ok(state) => state, + Err(err) => { + error!("Failed to parse initial_state.ron: {}", err); + return; + } + }; + + for body_data in initial_state.bodies { + // Convert radius from km to AU + let radius_au = body_data.radius / AU_TO_KM; // km to AU conversion + + // Convert mass from kg to solar masses + let mass_solar = body_data.mass / SOLAR_MASS_KG; + + // Create base bundle + let mut entity_commands = commands.spawn(( + ObjectBundle { + name: Name(ObjectName(body_data.name.clone())), + position: Position(PositionAu(DVec3::new( + body_data.position.0, + body_data.position.1, + body_data.position.2, + ))), + velocity: Velocity(VelocityAuPerDay(DVec3::new( + body_data.velocity.0, + body_data.velocity.1, + body_data.velocity.2, + ))), + mass: Mass(MassSolarMass(mass_solar)), + radius: Radius(DistanceAu(radius_au)), }, - Camera { - hdr: true, - clear_color: ClearColorConfig::Custom(Color::BLACK), - ..default() - }, - Projection::Perspective(PerspectiveProjection { - near: 1e-8, // Very close near plane for extreme zooming - far: 1e-2, - ..default() - }), - Tonemapping::TonyMcMapface, - Transform::from_translation(Vec3::new(0., 0., 10.0)), - Bloom::NATURAL, - FloatingOrigin, + Trackable {}, + Transform::default(), + Visibility::default(), + )); + let scene_handle = asset_server.load(format!("models/{}#Scene0", body_data.model.path)); + entity_commands.with_child(( + SceneRoot(scene_handle.clone()), + Transform::from_scale( + Vec3::new( + body_data.model.scale.0, + body_data.model.scale.1, + body_data.model.scale.2, + ) / AU_TO_KM as f32 + * 10000., + ), )); - // Load initial state from RON file - let initial_state_content = match std::fs::read_to_string("assets/initial_state.ron") { - Ok(content) => content, - Err(err) => { - error!("Failed to read initial_state.ron: {}", err); - return; + // Add special components for Sun and Earth + match body_data.name.as_str() { + "Sun" => { + entity_commands.insert(Star); + entity_commands.insert(NeedsEmissiveEnhancement); + entity_commands.insert(PointLight { + color: Color::WHITE, + shadows_enabled: true, + ..default() + }); } - }; - - let initial_state: InitialState = match ron::from_str(&initial_state_content) { - Ok(state) => state, - Err(err) => { - error!("Failed to parse initial_state.ron: {}", err); - return; + "Earth" => { + entity_commands.insert(Earth); } - }; - - for body_data in initial_state.bodies { - // Convert radius from km to AU - let radius_au = body_data.radius / AU_TO_KM; // km to AU conversion - - // Convert mass from kg to solar masses - let mass_solar = body_data.mass / SOLAR_MASS_KG; - - // Create base bundle - let mut entity_commands = commands.spawn(( - ObjectBundle { - name: Name(ObjectName(body_data.name.clone())), - position: Position(PositionAu(DVec3::new( - body_data.position.0, - body_data.position.1, - body_data.position.2, - ))), - velocity: Velocity(VelocityAuPerDay(DVec3::new( - body_data.velocity.0, - body_data.velocity.1, - body_data.velocity.2, - ))), - mass: Mass(MassSolarMass(mass_solar)), - radius: Radius(DistanceAu(radius_au)), - }, - Trackable {}, - Transform::default(), - Visibility::default(), - )); - let scene_handle = asset_server.load(format!("models/{}#Scene0", body_data.model.path)); - entity_commands.with_child(( - SceneRoot(scene_handle.clone()), - Transform::from_scale( - Vec3::new( - body_data.model.scale.0, - body_data.model.scale.1, - body_data.model.scale.2, - ) / AU_TO_KM as f32 - * 10000., - ), - )); - - // Add special components for Sun and Earth - match body_data.name.as_str() { - "Sun" => { - entity_commands.insert(Star); - entity_commands.insert(NeedsEmissiveEnhancement); - entity_commands.insert(PointLight { - color: Color::WHITE, - shadows_enabled: true, - ..default() - }); - } - "Earth" => { - entity_commands.insert(Earth); - } - _ => {} - } - - info!("Spawned celestial body: {}", body_data.name); + _ => {} } - }); + + info!("Spawned celestial body: {}", body_data.name); + } } // High precision constants @@ -673,20 +561,15 @@ fn n_body(mut query: Query<(&Mass, &mut Position, &mut Velocity)>) { fn main() { App::new() - .add_plugins( - DefaultPlugins - .set(WindowPlugin { - primary_window: Some(Window { - title: "Solar Sim".to_string(), - mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), - resolution: WindowResolution::default().with_scale_factor_override(2.0), - ..default() - }), - ..default() - }) - .disable::(), - ) - .add_plugins(BigSpaceDefaultPlugins) + .add_plugins(DefaultPlugins.set(WindowPlugin { + primary_window: Some(Window { + title: "Solar Sim".to_string(), + mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), + resolution: WindowResolution::default().with_scale_factor_override(2.0), + ..default() + }), + ..default() + })) .add_plugins(EguiPlugin::default()) .add_plugins(PanOrbitCameraPlugin) .register_type::()