feat(planets): spawn_planet_system with deterministic ChaCha8Rng seeding
This commit is contained in:
parent
78a222e685
commit
ec69698530
@ -96,6 +96,7 @@ impl Plugin for BlackHolePlugin {
|
|||||||
app.init_resource::<crate::camera::OrbitCamera>()
|
app.init_resource::<crate::camera::OrbitCamera>()
|
||||||
.init_resource::<crate::camera::WantsPointer>()
|
.init_resource::<crate::camera::WantsPointer>()
|
||||||
.init_resource::<crate::params::BlackHoleParams>()
|
.init_resource::<crate::params::BlackHoleParams>()
|
||||||
|
.init_resource::<crate::scene::planets::PlanetSystemDirty>()
|
||||||
.add_plugins(Material2dPlugin::<BlackHoleMaterial>::default())
|
.add_plugins(Material2dPlugin::<BlackHoleMaterial>::default())
|
||||||
.add_plugins(Material2dPlugin::<crate::render::material::CompositeMaterial>::default())
|
.add_plugins(Material2dPlugin::<crate::render::material::CompositeMaterial>::default())
|
||||||
.add_plugins(Material2dPlugin::<crate::render::material::BrightPassMaterial>::default())
|
.add_plugins(Material2dPlugin::<crate::render::material::BrightPassMaterial>::default())
|
||||||
@ -110,7 +111,7 @@ impl Plugin for BlackHolePlugin {
|
|||||||
// Runs in PreStartup, before setup_primary_egui_context_system.
|
// Runs in PreStartup, before setup_primary_egui_context_system.
|
||||||
.add_systems(bevy::prelude::PreStartup, disable_egui_auto_context)
|
.add_systems(bevy::prelude::PreStartup, disable_egui_auto_context)
|
||||||
.add_systems(Startup, spawn_fullscreen_quad)
|
.add_systems(Startup, spawn_fullscreen_quad)
|
||||||
.add_systems(Startup, crate::scene::planets::spawn_default_planet)
|
.add_systems(Startup, crate::scene::planets::spawn_planet_system)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(
|
||||||
@ -120,6 +121,12 @@ impl Plugin for BlackHolePlugin {
|
|||||||
nudge_camera,
|
nudge_camera,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.add_systems(Update, crate::scene::planets::spawn_planet_system)
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
crate::scene::planets::orbit_system
|
||||||
|
.before(crate::scene::planets::upload_planets),
|
||||||
|
)
|
||||||
.add_systems(Update, crate::scene::planets::upload_planets)
|
.add_systems(Update, crate::scene::planets::upload_planets)
|
||||||
.add_systems(Update, rebuild_bloom)
|
.add_systems(Update, rebuild_bloom)
|
||||||
// bevy_egui 0.41 requires UI systems to run inside the egui context
|
// bevy_egui 0.41 requires UI systems to run inside the egui context
|
||||||
|
|||||||
@ -2,6 +2,8 @@ use std::f32::consts::{PI, TAU};
|
|||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::render::storage::ShaderBuffer;
|
use bevy::render::storage::ShaderBuffer;
|
||||||
|
use rand::{Rng, SeedableRng};
|
||||||
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
|
||||||
use crate::render::material::{SphereData, MAX_PLANETS};
|
use crate::render::material::{SphereData, MAX_PLANETS};
|
||||||
|
|
||||||
@ -27,6 +29,10 @@ pub struct OrbitParams {
|
|||||||
pub phase: f32,
|
pub phase: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UI 改了种子/count/k 时置位, spawn_planet_system 检测到就重生整个行星系统.
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct PlanetSystemDirty(pub bool);
|
||||||
|
|
||||||
/// 由轨道根数 + 当前 (模拟)时间 + 自旋, 计算行星世界空间位置.
|
/// 由轨道根数 + 当前 (模拟)时间 + 自旋, 计算行星世界空间位置.
|
||||||
/// 纯函数: 无 Bevy 依赖, 可独立测试.
|
/// 纯函数: 无 Bevy 依赖, 可独立测试.
|
||||||
///
|
///
|
||||||
@ -134,14 +140,74 @@ pub fn upload_planets(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns a default test planet behind/above the hole so lensing is visible.
|
/// (重)生成行星系统. 检测 PlanetSystemDirty: 若置位, 先 despawn 所有现有
|
||||||
pub fn spawn_default_planet(mut commands: Commands) {
|
/// (Planet, OrbitParams), 再用 ChaCha8Rng + params.planet_seed 重新随机生成.
|
||||||
commands.spawn(Planet {
|
/// 确定性种子 → 同种子给同布局, 方便调试/截图/测试.
|
||||||
center: Vec3::new(0.0, 2.0, -25.0),
|
///
|
||||||
radius: 2.0,
|
/// 同时注册在 Startup 和 Update: Startup 首帧靠 "existing 为空" 门控首次生成;
|
||||||
color: Vec3::new(0.3, 0.5, 1.0),
|
/// Update 路径靠 dirty flag 门控重生. 不会每帧重建.
|
||||||
|
pub fn spawn_planet_system(
|
||||||
|
mut commands: Commands,
|
||||||
|
params: Res<crate::params::BlackHoleParams>,
|
||||||
|
mut dirty: ResMut<PlanetSystemDirty>,
|
||||||
|
existing: Query<Entity, With<Planet>>,
|
||||||
|
) {
|
||||||
|
// 只在 dirty, 或现有行星为零 (首帧/Startup) 时重生.
|
||||||
|
if !dirty.0 && !existing.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// despawn 现有行星
|
||||||
|
for entity in &existing {
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
}
|
||||||
|
dirty.0 = false;
|
||||||
|
|
||||||
|
if !params.planets_enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rng = ChaCha8Rng::seed_from_u64(params.planet_seed as u64);
|
||||||
|
let max = crate::render::material::MAX_PLANETS as u32;
|
||||||
|
for _ in 0..params.planet_count_target.min(max) {
|
||||||
|
let inclination = rng.gen_range(0.0..PI);
|
||||||
|
let longitude = rng.gen_range(0.0..TAU);
|
||||||
|
let phase = rng.gen_range(0.0..TAU);
|
||||||
|
let radius_factor = rng.gen_range(2.0..4.0);
|
||||||
|
// 颜色: 暖色行星 (橙/红/黄系), 避开蓝色 (易与背景星混淆)
|
||||||
|
let hue = rng.gen_range(0.02..0.13);
|
||||||
|
let color = hsv_to_rgb(hue, rng.gen_range(0.5..0.9), rng.gen_range(0.7..1.0));
|
||||||
|
commands.spawn((
|
||||||
|
OrbitParams {
|
||||||
|
radius_factor,
|
||||||
|
inclination,
|
||||||
|
longitude_of_node: longitude,
|
||||||
|
phase,
|
||||||
|
},
|
||||||
|
Planet {
|
||||||
|
center: Vec3::ZERO, // 首帧由 orbit_system 填
|
||||||
|
radius: rng.gen_range(0.8..1.6),
|
||||||
|
color,
|
||||||
emissive: false,
|
emissive: false,
|
||||||
});
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// HSV → RGB (h,s,v ∈ [0,1]). 行星颜色用.
|
||||||
|
fn hsv_to_rgb(h: f32, s: f32, v: f32) -> Vec3 {
|
||||||
|
let i = (h * 6.0).floor() as i32 % 6;
|
||||||
|
let f = h * 6.0 - (h * 6.0).floor();
|
||||||
|
let p = v * (1.0 - s);
|
||||||
|
let q = v * (1.0 - f * s);
|
||||||
|
let t = v * (1.0 - (1.0 - f) * s);
|
||||||
|
match i {
|
||||||
|
0 => Vec3::new(v, t, p),
|
||||||
|
1 => Vec3::new(q, v, p),
|
||||||
|
2 => Vec3::new(p, v, t),
|
||||||
|
3 => Vec3::new(p, q, v),
|
||||||
|
4 => Vec3::new(t, p, v),
|
||||||
|
_ => Vec3::new(v, p, q),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user