feat: full egui control panel + pointer routing
This commit is contained in:
parent
90e8c9b3a4
commit
7e0ac65d55
@ -24,6 +24,10 @@ impl Default for OrbitCamera {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set by the UI system each frame; the orbit controller ignores input when true.
|
||||||
|
#[derive(Resource, Default)]
|
||||||
|
pub struct WantsPointer(pub bool);
|
||||||
|
|
||||||
impl OrbitCamera {
|
impl OrbitCamera {
|
||||||
/// Compute the camera eye position and an orthonormal basis (forward/right/up)
|
/// Compute the camera eye position and an orthonormal basis (forward/right/up)
|
||||||
/// in Bevy's right-handed Y-up coordinate system. The black hole sits at origin.
|
/// in Bevy's right-handed Y-up coordinate system. The black hole sits at origin.
|
||||||
@ -50,11 +54,18 @@ impl OrbitCamera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn orbit_controller(
|
pub fn orbit_controller(
|
||||||
|
wants: Res<WantsPointer>,
|
||||||
mut camera: ResMut<OrbitCamera>,
|
mut camera: ResMut<OrbitCamera>,
|
||||||
mouse: Res<ButtonInput<MouseButton>>,
|
mouse: Res<ButtonInput<MouseButton>>,
|
||||||
mut motion: MessageReader<MouseMotion>,
|
mut motion: MessageReader<MouseMotion>,
|
||||||
mut wheel: MessageReader<MouseWheel>,
|
mut wheel: MessageReader<MouseWheel>,
|
||||||
) {
|
) {
|
||||||
|
if wants.0 {
|
||||||
|
// egui is using the pointer: drain events so they don't pile up, and ignore.
|
||||||
|
motion.clear();
|
||||||
|
wheel.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if mouse.pressed(MouseButton::Left) {
|
if mouse.pressed(MouseButton::Left) {
|
||||||
for ev in motion.read() {
|
for ev in motion.read() {
|
||||||
camera.yaw -= ev.delta.x * 0.005;
|
camera.yaw -= ev.delta.x * 0.005;
|
||||||
|
|||||||
@ -8,6 +8,7 @@ pub struct BlackHolePlugin;
|
|||||||
impl Plugin for BlackHolePlugin {
|
impl Plugin for BlackHolePlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<crate::camera::OrbitCamera>()
|
app.init_resource::<crate::camera::OrbitCamera>()
|
||||||
|
.init_resource::<crate::camera::WantsPointer>()
|
||||||
.init_resource::<crate::params::BlackHoleParams>()
|
.init_resource::<crate::params::BlackHoleParams>()
|
||||||
.add_plugins(Material2dPlugin::<BlackHoleMaterial>::default())
|
.add_plugins(Material2dPlugin::<BlackHoleMaterial>::default())
|
||||||
.add_plugins(bevy_egui::EguiPlugin::default())
|
.add_plugins(bevy_egui::EguiPlugin::default())
|
||||||
|
|||||||
49
src/ui.rs
49
src/ui.rs
@ -4,14 +4,51 @@ use bevy_egui::egui;
|
|||||||
pub fn ui_system(
|
pub fn ui_system(
|
||||||
mut contexts: bevy_egui::EguiContexts,
|
mut contexts: bevy_egui::EguiContexts,
|
||||||
mut params: ResMut<crate::params::BlackHoleParams>,
|
mut params: ResMut<crate::params::BlackHoleParams>,
|
||||||
|
mut camera: ResMut<crate::camera::OrbitCamera>,
|
||||||
|
mut wants: ResMut<crate::camera::WantsPointer>,
|
||||||
) {
|
) {
|
||||||
if let Ok(ctx) = contexts.ctx_mut() {
|
if let Ok(ctx) = contexts.ctx_mut() {
|
||||||
egui::Window::new("Controls").show(ctx, |ui| {
|
egui::Window::new("Controls")
|
||||||
ui.add(
|
.collapsible(true)
|
||||||
egui::Slider::new(&mut params.disk_brightness, 0.0..=3.0)
|
.default_pos([16.0, 16.0])
|
||||||
.text("Disk brightness"),
|
.show(ctx, |ui| {
|
||||||
);
|
egui::CollapsingHeader::new("Camera")
|
||||||
ui.add(egui::Slider::new(&mut params.steps, 50..=600).text("Steps"));
|
.default_open(true)
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.add(egui::Slider::new(&mut camera.distance, 3.0..=200.0).text("Distance"));
|
||||||
|
ui.add(egui::Slider::new(&mut camera.yaw, -3.14..=3.14).text("Yaw"));
|
||||||
|
ui.add(egui::Slider::new(&mut camera.pitch, 0.05..=3.09).text("Pitch"));
|
||||||
|
ui.add(egui::Slider::new(&mut camera.fov, 0.3..=2.0).text("FOV"));
|
||||||
});
|
});
|
||||||
|
egui::CollapsingHeader::new("Accretion Disk")
|
||||||
|
.default_open(true)
|
||||||
|
.show(ui, |ui| {
|
||||||
|
ui.add(egui::Slider::new(&mut params.disk_inner, 1.5..=6.0).text("Inner radius"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.disk_outer, 6.0..=40.0).text("Outer radius"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.disk_tilt, 0.0..=3.14).text("Tilt"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.disk_brightness, 0.0..=3.0).text("Brightness"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.disk_rotation_speed, 0.0..=3.0).text("Rotation speed"));
|
||||||
|
});
|
||||||
|
egui::CollapsingHeader::new("Doppler").show(ui, |ui| {
|
||||||
|
ui.checkbox(&mut params.doppler_enabled, "Enabled");
|
||||||
|
ui.add_enabled(params.doppler_enabled, egui::Slider::new(&mut params.doppler_strength, 0.0..=3.0).text("Strength"));
|
||||||
|
});
|
||||||
|
egui::CollapsingHeader::new("Renderer").show(ui, |ui| {
|
||||||
|
ui.add(egui::Slider::new(&mut params.steps, 50..=600).text("Steps"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.render_scale, 0.5..=1.0).text("Render scale"));
|
||||||
|
});
|
||||||
|
egui::CollapsingHeader::new("Background").show(ui, |ui| {
|
||||||
|
ui.add(egui::Slider::new(&mut params.star_intensity, 0.0..=3.0).text("Star intensity"));
|
||||||
|
ui.add(egui::Slider::new(&mut params.skybox_intensity, 0.0..=3.0).text("Skybox intensity"));
|
||||||
|
});
|
||||||
|
egui::CollapsingHeader::new("Grid").show(ui, |ui| {
|
||||||
|
ui.checkbox(&mut params.grid_enabled, "Enabled");
|
||||||
|
ui.add_enabled(params.grid_enabled, egui::Slider::new(&mut params.grid_density, 0.1..=4.0).text("Density"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// egui captures pointer when the cursor is over a window or being interacted with.
|
||||||
|
wants.0 = ctx.egui_wants_pointer_input();
|
||||||
|
} else {
|
||||||
|
wants.0 = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user