update
This commit is contained in:
parent
e83da3156b
commit
bd37295da9
333
src/main.rs
333
src/main.rs
@ -6,10 +6,6 @@ use bevy::{
|
|||||||
};
|
};
|
||||||
use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin};
|
use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin};
|
||||||
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
|
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
|
||||||
use big_space::{
|
|
||||||
plugin::BigSpaceDefaultPlugins,
|
|
||||||
prelude::{BigSpaceCommands, FloatingOrigin},
|
|
||||||
};
|
|
||||||
use iyes_perf_ui::{PerfUiPlugin, prelude::*};
|
use iyes_perf_ui::{PerfUiPlugin, prelude::*};
|
||||||
use solar_sim::InitialState;
|
use solar_sim::InitialState;
|
||||||
|
|
||||||
@ -118,14 +114,7 @@ impl Plugin for SolarRenderingPlugin {
|
|||||||
PostUpdate,
|
PostUpdate,
|
||||||
(update_label_positions.after(manage_label_overlaps),),
|
(update_label_positions.after(manage_label_overlaps),),
|
||||||
)
|
)
|
||||||
.add_systems(
|
.add_systems(Update, (handle_label_clicks, handle_speed_controls));
|
||||||
Update,
|
|
||||||
(
|
|
||||||
handle_label_clicks,
|
|
||||||
handle_speed_controls,
|
|
||||||
enhance_sun_emissive_with_retry,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,18 +122,39 @@ fn sync_position_to_transform(
|
|||||||
mut query: Query<(Entity, &Position, &mut Transform)>,
|
mut query: Query<(Entity, &Position, &mut Transform)>,
|
||||||
origin: Res<Origin>,
|
origin: Res<Origin>,
|
||||||
) {
|
) {
|
||||||
// let offset = origin.target.map_or(DVec3::ZERO, |target| {
|
let offset = origin.target.map_or(DVec3::ZERO, |target| {
|
||||||
// query
|
query
|
||||||
// .get(target)
|
.get(target)
|
||||||
// .map_or(DVec3::ZERO, |(_, position, _)| position.0.0)
|
.map_or(DVec3::ZERO, |(_, position, _)| position.0.0)
|
||||||
// });
|
});
|
||||||
let offset = DVec3::ZERO;
|
|
||||||
for (_, position, mut transform) in query.iter_mut() {
|
for (_, position, mut transform) in query.iter_mut() {
|
||||||
transform.translation = ((position.0.0 - offset) * AU_TO_GAME_UNITS).as_vec3();
|
transform.translation = ((position.0.0 - offset) * AU_TO_GAME_UNITS).as_vec3();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_rendering(mut commands: Commands) {
|
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());
|
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<StandardMaterial>>,
|
|
||||||
mut sun_query: Query<
|
|
||||||
(Entity, &Children, Option<&mut EmissiveEnhancementAttempts>),
|
|
||||||
(
|
|
||||||
With<Star>,
|
|
||||||
With<NeedsEmissiveEnhancement>,
|
|
||||||
Without<EmissiveEnhanced>,
|
|
||||||
),
|
|
||||||
>,
|
|
||||||
children_query: Query<&Children>,
|
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
||||||
) {
|
|
||||||
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::<NeedsEmissiveEnhancement>();
|
|
||||||
commands
|
|
||||||
.entity(sun_entity)
|
|
||||||
.remove::<EmissiveEnhancementAttempts>();
|
|
||||||
} else if attempts >= 300 {
|
|
||||||
// Give up after max attempts
|
|
||||||
info!(
|
|
||||||
"Giving up on sun emissive enhancement after {} attempts",
|
|
||||||
attempts
|
|
||||||
);
|
|
||||||
commands
|
|
||||||
.entity(sun_entity)
|
|
||||||
.remove::<NeedsEmissiveEnhancement>();
|
|
||||||
commands
|
|
||||||
.entity(sun_entity)
|
|
||||||
.remove::<EmissiveEnhancementAttempts>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enhance_emissive_for_children(
|
|
||||||
children: &Children,
|
|
||||||
children_query: &Query<&Children>,
|
|
||||||
mesh_query: &Query<&MeshMaterial3d<StandardMaterial>>,
|
|
||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
|
||||||
) -> 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;
|
const AU_TO_KM: f64 = 149597870.691;
|
||||||
|
|
||||||
fn setup_solar_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup_solar_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
commands.spawn_big_space_default(|commands| {
|
// Load initial state from RON file
|
||||||
commands.spawn((
|
let initial_state_content = match std::fs::read_to_string("assets/initial_state.ron") {
|
||||||
PanOrbitCamera {
|
Ok(content) => content,
|
||||||
zoom_lower_limit: 1e-6,
|
Err(err) => {
|
||||||
..default()
|
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 {
|
Trackable {},
|
||||||
hdr: true,
|
Transform::default(),
|
||||||
clear_color: ClearColorConfig::Custom(Color::BLACK),
|
Visibility::default(),
|
||||||
..default()
|
));
|
||||||
},
|
let scene_handle = asset_server.load(format!("models/{}#Scene0", body_data.model.path));
|
||||||
Projection::Perspective(PerspectiveProjection {
|
entity_commands.with_child((
|
||||||
near: 1e-8, // Very close near plane for extreme zooming
|
SceneRoot(scene_handle.clone()),
|
||||||
far: 1e-2,
|
Transform::from_scale(
|
||||||
..default()
|
Vec3::new(
|
||||||
}),
|
body_data.model.scale.0,
|
||||||
Tonemapping::TonyMcMapface,
|
body_data.model.scale.1,
|
||||||
Transform::from_translation(Vec3::new(0., 0., 10.0)),
|
body_data.model.scale.2,
|
||||||
Bloom::NATURAL,
|
) / AU_TO_KM as f32
|
||||||
FloatingOrigin,
|
* 10000.,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
// Load initial state from RON file
|
// Add special components for Sun and Earth
|
||||||
let initial_state_content = match std::fs::read_to_string("assets/initial_state.ron") {
|
match body_data.name.as_str() {
|
||||||
Ok(content) => content,
|
"Sun" => {
|
||||||
Err(err) => {
|
entity_commands.insert(Star);
|
||||||
error!("Failed to read initial_state.ron: {}", err);
|
entity_commands.insert(NeedsEmissiveEnhancement);
|
||||||
return;
|
entity_commands.insert(PointLight {
|
||||||
|
color: Color::WHITE,
|
||||||
|
shadows_enabled: true,
|
||||||
|
..default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
"Earth" => {
|
||||||
|
entity_commands.insert(Earth);
|
||||||
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)),
|
|
||||||
},
|
|
||||||
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
|
// High precision constants
|
||||||
@ -673,20 +561,15 @@ fn n_body(mut query: Query<(&Mass, &mut Position, &mut Velocity)>) {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||||
DefaultPlugins
|
primary_window: Some(Window {
|
||||||
.set(WindowPlugin {
|
title: "Solar Sim".to_string(),
|
||||||
primary_window: Some(Window {
|
mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
|
||||||
title: "Solar Sim".to_string(),
|
resolution: WindowResolution::default().with_scale_factor_override(2.0),
|
||||||
mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary),
|
..default()
|
||||||
resolution: WindowResolution::default().with_scale_factor_override(2.0),
|
}),
|
||||||
..default()
|
..default()
|
||||||
}),
|
}))
|
||||||
..default()
|
|
||||||
})
|
|
||||||
.disable::<TransformPlugin>(),
|
|
||||||
)
|
|
||||||
.add_plugins(BigSpaceDefaultPlugins)
|
|
||||||
.add_plugins(EguiPlugin::default())
|
.add_plugins(EguiPlugin::default())
|
||||||
.add_plugins(PanOrbitCameraPlugin)
|
.add_plugins(PanOrbitCameraPlugin)
|
||||||
.register_type::<Name>()
|
.register_type::<Name>()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user