use super::{ComponentInspector, InspectorContext, impl_simple_inspector};
use crate::ecs::grass::components::{GrassInteractor, GrassRegion, GrassSpecies};
use crate::prelude::*;
fn add_grass_region(world: &mut World, entity: Entity) {
world.add_components(entity, crate::ecs::world::GRASS_REGION);
world.set_grass_region(entity, GrassRegion::default());
}
fn grass_region_ui(
world: &mut World,
entity: Entity,
ui: &mut egui::Ui,
_context: &mut InspectorContext,
) {
if let Some(region) = world.get_grass_region_mut(entity) {
ui.horizontal(|ui| {
ui.label("Enabled:");
ui.checkbox(&mut region.enabled, "");
});
ui.separator();
ui.label(egui::RichText::new("Config").strong());
ui.horizontal(|ui| {
ui.label("Blades Per Patch:");
ui.add(egui::DragValue::new(&mut region.config.blades_per_patch).range(1..=1024));
});
ui.horizontal(|ui| {
ui.label("Patch Size:");
ui.add(
egui::DragValue::new(&mut region.config.patch_size)
.speed(0.5)
.range(1.0..=64.0),
);
});
ui.horizontal(|ui| {
ui.label("Stream Radius:");
ui.add(
egui::DragValue::new(&mut region.config.stream_radius)
.speed(1.0)
.range(10.0..=1000.0),
);
});
ui.separator();
ui.label(egui::RichText::new("Wind").strong());
ui.horizontal(|ui| {
ui.label("Strength:");
ui.add(egui::Slider::new(
&mut region.config.wind_strength,
0.0..=5.0,
));
});
ui.horizontal(|ui| {
ui.label("Frequency:");
ui.add(egui::Slider::new(
&mut region.config.wind_frequency,
0.0..=5.0,
));
});
ui.horizontal(|ui| {
ui.label("Direction:");
ui.add(
egui::DragValue::new(&mut region.config.wind_direction[0])
.speed(0.1)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut region.config.wind_direction[1])
.speed(0.1)
.prefix("Z: "),
);
});
ui.separator();
ui.label(egui::RichText::new("Shadows").strong());
ui.horizontal(|ui| {
ui.label("Cast:");
ui.checkbox(&mut region.config.cast_shadows, "");
ui.label("Receive:");
ui.checkbox(&mut region.config.receive_shadows, "");
});
ui.separator();
ui.label(egui::RichText::new("Bounds").strong());
ui.horizontal(|ui| {
ui.label("Min:");
ui.add(
egui::DragValue::new(&mut region.bounds_min.x)
.speed(1.0)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut region.bounds_min.y)
.speed(1.0)
.prefix("Y: "),
);
ui.add(
egui::DragValue::new(&mut region.bounds_min.z)
.speed(1.0)
.prefix("Z: "),
);
});
ui.horizontal(|ui| {
ui.label("Max:");
ui.add(
egui::DragValue::new(&mut region.bounds_max.x)
.speed(1.0)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut region.bounds_max.y)
.speed(1.0)
.prefix("Y: "),
);
ui.add(
egui::DragValue::new(&mut region.bounds_max.z)
.speed(1.0)
.prefix("Z: "),
);
});
ui.separator();
ui.label(egui::RichText::new("Species").strong());
let mut delete_index = None;
for index in 0..region.species.len() {
ui.group(|ui| {
ui.horizontal(|ui| {
ui.label(format!("Species {}", index));
if ui.small_button("X").clicked() {
delete_index = Some(index);
}
});
ui.horizontal(|ui| {
ui.label("Name:");
ui.text_edit_singleline(&mut region.species[index].name);
});
ui.horizontal(|ui| {
ui.label("Blade Width:");
ui.add(
egui::DragValue::new(&mut region.species[index].blade_width)
.speed(0.01)
.range(0.001..=1.0),
);
});
ui.horizontal(|ui| {
ui.label("Height Min:");
ui.add(
egui::DragValue::new(&mut region.species[index].blade_height_min)
.speed(0.01)
.range(0.01..=5.0),
);
ui.label("Max:");
ui.add(
egui::DragValue::new(&mut region.species[index].blade_height_max)
.speed(0.01)
.range(0.01..=5.0),
);
});
ui.horizontal(|ui| {
ui.label("Curvature:");
ui.add(egui::Slider::new(
&mut region.species[index].blade_curvature,
0.0..=1.0,
));
});
ui.horizontal(|ui| {
ui.label("Base Color:");
ui.color_edit_button_rgba_unmultiplied(&mut region.species[index].base_color);
});
ui.horizontal(|ui| {
ui.label("Tip Color:");
ui.color_edit_button_rgba_unmultiplied(&mut region.species[index].tip_color);
});
ui.horizontal(|ui| {
ui.label("Density Scale:");
ui.add(egui::Slider::new(
&mut region.species[index].density_scale,
0.0..=3.0,
));
});
if index < region.species_weights.len() {
ui.horizontal(|ui| {
ui.label("Weight:");
ui.add(egui::Slider::new(
&mut region.species_weights[index],
0.0..=10.0,
));
});
}
});
}
if let Some(index) = delete_index
&& region.species.len() > 1
{
region.species.remove(index);
if index < region.species_weights.len() {
region.species_weights.remove(index);
}
}
if ui.button("Add Species").clicked() {
region.species.push(GrassSpecies::default());
region.species_weights.push(1.0);
}
}
}
impl_simple_inspector!(
GrassRegionInspector,
"Grass Region",
entity_has_grass_region,
remove_grass_region,
grass_region_ui,
custom_add => add_grass_region
);
fn add_grass_interactor(world: &mut World, entity: Entity) {
world.add_components(entity, crate::ecs::world::GRASS_INTERACTOR);
world.set_grass_interactor(entity, GrassInteractor::default());
}
fn grass_interactor_ui(
world: &mut World,
entity: Entity,
ui: &mut egui::Ui,
_context: &mut InspectorContext,
) {
if let Some(interactor) = world.get_grass_interactor_mut(entity) {
ui.horizontal(|ui| {
ui.label("Radius:");
ui.add(
egui::DragValue::new(&mut interactor.radius)
.speed(0.1)
.range(0.0..=10.0),
);
});
ui.horizontal(|ui| {
ui.label("Strength:");
ui.add(
egui::DragValue::new(&mut interactor.strength)
.speed(0.1)
.range(0.0..=5.0),
);
});
}
}
impl_simple_inspector!(
GrassInteractorInspector,
"Grass Interactor",
entity_has_grass_interactor,
remove_grass_interactor,
grass_interactor_ui,
custom_add => add_grass_interactor
);