From ca2b06efb87676a85acefa339c4a7fa59a1f27ac Mon Sep 17 00:00:00 2001 From: Leon Liu Date: Wed, 13 Aug 2025 20:50:09 +0900 Subject: [PATCH] update --- src/main.rs | 142 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 32 deletions(-) diff --git a/src/main.rs b/src/main.rs index 04127f2..0ee0737 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,84 +1,162 @@ use bevy::{math::DVec3, prelude::*}; +// Unit wrapper types - all distances in AU +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct DistanceAu(pub f64); + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct PositionAu(pub DVec3); + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct VelocityAuPerDay(pub DVec3); + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct MassKg(pub f64); + +#[derive(Clone, Debug, PartialEq)] +pub struct ObjectName(pub String); + +// Component wrappers #[derive(Component)] -struct PositionAu(DVec3); +struct Position(PositionAu); #[derive(Component)] -struct VelocityAuPerDay(DVec3); +struct Velocity(VelocityAuPerDay); #[derive(Component)] -struct MassKg(f64); +struct Mass(MassKg); #[derive(Component)] -struct RadiusKm(f64); +struct Radius(DistanceAu); #[derive(Component)] -struct Name(String); +struct Name(ObjectName); #[derive(Bundle)] struct ObjectBundle { name: Name, - position: PositionAu, - mass: MassKg, - radius: RadiusKm, - velocity: VelocityAuPerDay, + position: Position, + mass: Mass, + radius: Radius, + velocity: Velocity, } pub struct SolarRenderingPlugin; impl Plugin for SolarRenderingPlugin { fn build(&self, app: &mut App) { - // Rendering systems will be added here + app.add_systems(Startup, setup_rendering) + .add_systems( + FixedPostUpdate, + (sync_radius_to_mesh, sync_position_to_transform), + ); } } +fn sync_radius_to_mesh( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + query: Query<(Entity, &Radius, Option<&Mesh3d>), Changed>, +) { + for (entity, radius, existing_mesh) in query.iter() { + // Radius is already in AU, use directly for rendering + let render_radius = radius.0.0; + + // Create or update sphere mesh + let sphere_mesh = meshes.add(Sphere::new(render_radius as f32)); + let material = materials.add(StandardMaterial { + base_color: Color::WHITE, + ..default() + }); + + if existing_mesh.is_none() { + // Add mesh and material components if they don't exist + commands + .entity(entity) + .insert((Mesh3d(sphere_mesh), MeshMaterial3d(material))); + } else { + // Update existing mesh + commands.entity(entity).insert(Mesh3d(sphere_mesh)); + } + } +} + +fn sync_position_to_transform(mut query: Query<(&Position, &mut Transform), Changed>) { + for (position, mut transform) in query.iter_mut() { + // Convert AU to rendering units (1 AU = 1 unit for simplicity) + transform.translation = position.0.0.as_vec3(); + } +} + +fn setup_rendering(mut commands: Commands) { + // Spawn camera positioned to view the solar system + // Place it above and to the side for a good perspective view + commands.spawn(( + Camera3d::default(), + Transform::from_xyz(2.0, 1.5, 2.0).looking_at(Vec3::ZERO, Vec3::Y), + )); + + // Spawn directional light from the sun's position + // This simulates sunlight illuminating the planets + commands.spawn(( + DirectionalLight { + color: Color::WHITE, + illuminance: 10000.0, // Bright like the sun + shadows_enabled: true, + ..default() + }, + Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::new(1.0, 0.0, 0.0), Vec3::Y), + )); +} + fn setup_solar_system(mut commands: Commands) { // Sun - From NASA JPL Horizons data (J2000.0 epoch) - // Physical properties: Mass = 1988410 x 10^24 kg, Radius = 695700 km + // Physical properties: Mass = 1988410 x 10^24 kg, Radius = 695700 km = 0.00465 AU commands.spawn(ObjectBundle { - name: Name("Sun".to_string()), - position: PositionAu(DVec3::new(0.0, 0.0, 0.0)), // At barycenter - velocity: VelocityAuPerDay(DVec3::new(0.0, 0.0, 0.0)), // Stationary relative to barycenter - mass: MassKg(1.988410e30), // Solar mass in kg - radius: RadiusKm(695700.0), // Solar radius in km + name: Name(ObjectName("Sun".to_string())), + position: Position(PositionAu(DVec3::new(0.0, 0.0, 0.0))), // At barycenter + velocity: Velocity(VelocityAuPerDay(DVec3::new(0.0, 0.0, 0.0))), // Stationary relative to barycenter + mass: Mass(MassKg(1.988410e30)), // Solar mass in kg + radius: Radius(DistanceAu(0.00465)), // Solar radius in AU (695700 km / 149597870.691) }); // Earth - From NASA JPL Horizons data (A.D. 2000-Jan-01 12:00:00.0000 TDB) // Position and velocity vectors in ecliptic J2000.0 frame relative to Sun - // Mass = 5.97219 x 10^24 kg, Mean radius = 6371.01 km + // Mass = 5.97219 x 10^24 kg, Mean radius = 6371.01 km = 0.0000426 AU commands.spawn(ObjectBundle { - name: Name("Earth".to_string()), - position: PositionAu(DVec3::new( + name: Name(ObjectName("Earth".to_string())), + position: Position(PositionAu(DVec3::new( -1.771350992727098e-1, // X = -0.177135 AU 9.672416867665306e-1, // Y = 0.967242 AU -4.085281582511366e-6, // Z = -4.085e-6 AU - )), - velocity: VelocityAuPerDay(DVec3::new( + ))), + velocity: Velocity(VelocityAuPerDay(DVec3::new( -1.720762506872895e-2, // VX = -0.0172076 AU/day -3.158782144324866e-3, // VY = -0.00315878 AU/day 1.049888594613343e-7, // VZ = 1.04989e-7 AU/day - )), - mass: MassKg(5.97219e24), // Earth mass in kg - radius: RadiusKm(6371.01), // Mean radius in km + ))), + mass: Mass(MassKg(5.97219e24)), // Earth mass in kg + radius: Radius(DistanceAu(0.0000426)), // Mean radius in AU (6371.01 km / 149597870.691) }); // Moon - From NASA JPL Horizons data (A.D. 2000-Jan-01 12:00:00.0000 TDB) // Position and velocity vectors in ecliptic J2000.0 frame relative to Sun - // Mass = 7.349 x 10^22 kg, Mean radius = 1737.53 km + // Mass = 7.349 x 10^22 kg, Mean radius = 1737.53 km = 0.0000116 AU commands.spawn(ObjectBundle { - name: Name("Moon".to_string()), - position: PositionAu(DVec3::new( + name: Name(ObjectName("Moon".to_string())), + position: Position(PositionAu(DVec3::new( -1.790843809223965e-1, // X = -0.179084 AU 9.654035607264573e-1, // Y = 0.965404 AU 2.383726922995396e-4, // Z = 0.000238373 AU - )), - velocity: VelocityAuPerDay(DVec3::new( + ))), + velocity: Velocity(VelocityAuPerDay(DVec3::new( -1.683595459141215e-2, // VX = -0.0168360 AU/day -3.580960720855671e-3, // VY = -0.00358096 AU/day -6.540550604528720e-6, // VZ = -6.54055e-6 AU/day - )), - mass: MassKg(7.349e22), // Moon mass in kg - radius: RadiusKm(1737.53), // Mean radius in km + ))), + mass: Mass(MassKg(7.349e22)), // Moon mass in kg + radius: Radius(DistanceAu(0.0000116)), // Mean radius in AU (1737.53 km / 149597870.691) }); }