use super::{ComponentInspector, InspectorContext, impl_simple_inspector};
use crate::ecs::particles::components::{EmitterShape, EmitterType, ParticleEmitter};
use crate::prelude::*;
fn add_particle_emitter(world: &mut World, entity: Entity) {
world.add_components(entity, crate::ecs::world::PARTICLE_EMITTER);
world.set_particle_emitter(entity, ParticleEmitter::default());
}
fn particle_emitter_ui(
world: &mut World,
entity: Entity,
ui: &mut egui::Ui,
_context: &mut InspectorContext,
) {
if let Some(emitter) = world.get_particle_emitter_mut(entity) {
ui.horizontal(|ui| {
ui.label("Enabled:");
ui.checkbox(&mut emitter.enabled, "");
});
ui.horizontal(|ui| {
ui.label("One Shot:");
ui.checkbox(&mut emitter.one_shot, "");
});
ui.separator();
ui.label(egui::RichText::new("Emitter Type").strong());
let type_label = match emitter.emitter_type {
EmitterType::Firework => "Firework",
EmitterType::Fire => "Fire",
EmitterType::Smoke => "Smoke",
EmitterType::Sparks => "Sparks",
EmitterType::Trail => "Trail",
};
egui::ComboBox::from_id_salt("emitter_type")
.selected_text(type_label)
.show_ui(ui, |ui| {
ui.selectable_value(&mut emitter.emitter_type, EmitterType::Fire, "Fire");
ui.selectable_value(&mut emitter.emitter_type, EmitterType::Smoke, "Smoke");
ui.selectable_value(&mut emitter.emitter_type, EmitterType::Sparks, "Sparks");
ui.selectable_value(&mut emitter.emitter_type, EmitterType::Trail, "Trail");
ui.selectable_value(&mut emitter.emitter_type, EmitterType::Firework, "Firework");
});
ui.separator();
ui.label(egui::RichText::new("Shape").strong());
let shape_label = match emitter.shape {
EmitterShape::Point => "Point",
EmitterShape::Sphere { .. } => "Sphere",
EmitterShape::Cone { .. } => "Cone",
EmitterShape::Box { .. } => "Box",
};
let mut shape_index = match emitter.shape {
EmitterShape::Point => 0,
EmitterShape::Sphere { .. } => 1,
EmitterShape::Cone { .. } => 2,
EmitterShape::Box { .. } => 3,
};
let old_shape_index = shape_index;
egui::ComboBox::from_id_salt("emitter_shape")
.selected_text(shape_label)
.show_ui(ui, |ui| {
ui.selectable_value(&mut shape_index, 0, "Point");
ui.selectable_value(&mut shape_index, 1, "Sphere");
ui.selectable_value(&mut shape_index, 2, "Cone");
ui.selectable_value(&mut shape_index, 3, "Box");
});
if shape_index != old_shape_index {
emitter.shape = match shape_index {
1 => EmitterShape::Sphere { radius: 1.0 },
2 => EmitterShape::Cone {
angle: 0.5,
height: 1.0,
},
3 => EmitterShape::Box {
half_extents: nalgebra_glm::vec3(0.5, 0.5, 0.5),
},
_ => EmitterShape::Point,
};
}
match &mut emitter.shape {
EmitterShape::Sphere { radius } => {
ui.horizontal(|ui| {
ui.label("Radius:");
ui.add(egui::DragValue::new(radius).speed(0.1).range(0.01..=100.0));
});
}
EmitterShape::Cone { angle, height } => {
ui.horizontal(|ui| {
ui.label("Angle:");
ui.add(egui::Slider::new(angle, 0.01..=std::f32::consts::PI));
});
ui.horizontal(|ui| {
ui.label("Height:");
ui.add(egui::DragValue::new(height).speed(0.1).range(0.01..=100.0));
});
}
EmitterShape::Box { half_extents } => {
ui.horizontal(|ui| {
ui.label("Half Extents:");
ui.add(
egui::DragValue::new(&mut half_extents.x)
.speed(0.1)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut half_extents.y)
.speed(0.1)
.prefix("Y: "),
);
ui.add(
egui::DragValue::new(&mut half_extents.z)
.speed(0.1)
.prefix("Z: "),
);
});
}
EmitterShape::Point => {}
}
ui.separator();
ui.label(egui::RichText::new("Spawning").strong());
ui.horizontal(|ui| {
ui.label("Spawn Rate:");
ui.add(
egui::DragValue::new(&mut emitter.spawn_rate)
.speed(1.0)
.range(0.0..=10000.0),
);
});
ui.horizontal(|ui| {
ui.label("Burst Count:");
ui.add(egui::DragValue::new(&mut emitter.burst_count).speed(1.0));
});
ui.separator();
ui.label(egui::RichText::new("Lifetime").strong());
ui.horizontal(|ui| {
ui.label("Min:");
ui.add(
egui::DragValue::new(&mut emitter.particle_lifetime_min)
.speed(0.1)
.range(0.01..=60.0),
);
ui.label("Max:");
ui.add(
egui::DragValue::new(&mut emitter.particle_lifetime_max)
.speed(0.1)
.range(0.01..=60.0),
);
});
ui.separator();
ui.label(egui::RichText::new("Velocity").strong());
ui.horizontal(|ui| {
ui.label("Min Speed:");
ui.add(
egui::DragValue::new(&mut emitter.initial_velocity_min)
.speed(0.1)
.range(0.0..=100.0),
);
ui.label("Max Speed:");
ui.add(
egui::DragValue::new(&mut emitter.initial_velocity_max)
.speed(0.1)
.range(0.0..=100.0),
);
});
ui.horizontal(|ui| {
ui.label("Spread:");
ui.add(egui::Slider::new(
&mut emitter.velocity_spread,
0.0..=std::f32::consts::PI,
));
});
ui.horizontal(|ui| {
ui.label("Direction:");
ui.add(
egui::DragValue::new(&mut emitter.direction.x)
.speed(0.1)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut emitter.direction.y)
.speed(0.1)
.prefix("Y: "),
);
ui.add(
egui::DragValue::new(&mut emitter.direction.z)
.speed(0.1)
.prefix("Z: "),
);
});
ui.separator();
ui.label(egui::RichText::new("Physics").strong());
ui.horizontal(|ui| {
ui.label("Gravity:");
ui.add(
egui::DragValue::new(&mut emitter.gravity.x)
.speed(0.1)
.prefix("X: "),
);
ui.add(
egui::DragValue::new(&mut emitter.gravity.y)
.speed(0.1)
.prefix("Y: "),
);
ui.add(
egui::DragValue::new(&mut emitter.gravity.z)
.speed(0.1)
.prefix("Z: "),
);
});
ui.horizontal(|ui| {
ui.label("Drag:");
ui.add(egui::Slider::new(&mut emitter.drag, 0.0..=2.0));
});
ui.separator();
ui.label(egui::RichText::new("Size").strong());
ui.horizontal(|ui| {
ui.label("Start:");
ui.add(
egui::DragValue::new(&mut emitter.size_start)
.speed(0.01)
.range(0.0..=10.0),
);
ui.label("End:");
ui.add(
egui::DragValue::new(&mut emitter.size_end)
.speed(0.01)
.range(0.0..=10.0),
);
});
ui.separator();
ui.label(egui::RichText::new("Rendering").strong());
ui.horizontal(|ui| {
ui.label("Emissive Strength:");
ui.add(egui::Slider::new(
&mut emitter.emissive_strength,
0.0..=30.0,
));
});
ui.horizontal(|ui| {
ui.label("Texture Index:");
ui.add(egui::DragValue::new(&mut emitter.texture_index));
});
ui.separator();
ui.label(egui::RichText::new("Turbulence").strong());
ui.horizontal(|ui| {
ui.label("Strength:");
ui.add(egui::Slider::new(
&mut emitter.turbulence_strength,
0.0..=5.0,
));
});
ui.horizontal(|ui| {
ui.label("Frequency:");
ui.add(egui::Slider::new(
&mut emitter.turbulence_frequency,
0.01..=10.0,
));
});
}
}
impl_simple_inspector!(
ParticleEmitterInspector,
"Particle Emitter",
entity_has_particle_emitter,
remove_particle_emitter,
particle_emitter_ui,
custom_add => add_particle_emitter
);