fyrox_impl/scene/particle_system/emitter/
cylinder.rs1use crate::{
24 core::{algebra::Vector3, numeric_range::RangeExt, reflect::prelude::*, visitor::prelude::*},
25 scene::particle_system::{
26 emitter::{
27 base::{BaseEmitter, BaseEmitterBuilder},
28 Emit, Emitter,
29 },
30 particle::Particle,
31 ParticleSystemRng,
32 },
33};
34use std::ops::{Deref, DerefMut};
35
36#[derive(Clone, Debug, Visit, PartialEq, Reflect)]
38pub struct CylinderEmitter {
39 emitter: BaseEmitter,
40 #[reflect(min_value = 0.0, step = 0.1)]
41 height: f32,
42 #[reflect(min_value = 0.0, step = 0.1)]
43 radius: f32,
44}
45
46impl Default for CylinderEmitter {
47 fn default() -> Self {
48 Self {
49 emitter: Default::default(),
50 height: 1.0,
51 radius: 0.5,
52 }
53 }
54}
55
56impl Deref for CylinderEmitter {
57 type Target = BaseEmitter;
58
59 fn deref(&self) -> &Self::Target {
60 &self.emitter
61 }
62}
63
64impl DerefMut for CylinderEmitter {
65 fn deref_mut(&mut self) -> &mut Self::Target {
66 &mut self.emitter
67 }
68}
69
70impl Emit for CylinderEmitter {
71 fn emit(&self, particle: &mut Particle, rng: &mut ParticleSystemRng) {
72 let scale: f32 = (0.0..1.0).random(rng);
74 let theta = (0.0..2.0 * std::f32::consts::PI).random(rng);
75 let z = (0.0..self.height).random(rng);
76 let radius = scale.sqrt() * self.radius;
77 let x = radius * theta.cos();
78 let y = radius * theta.sin();
79 particle.position = self.position() + Vector3::new(x, y, z);
80 }
81}
82
83impl CylinderEmitter {
84 pub fn radius(&self) -> f32 {
86 self.radius
87 }
88
89 pub fn set_radius(&mut self, radius: f32) {
91 self.radius = radius.max(0.0);
92 }
93
94 pub fn height(&self) -> f32 {
96 self.height
97 }
98
99 pub fn set_height(&mut self, height: f32) {
101 self.height = height.max(0.0);
102 }
103}
104
105pub struct CylinderEmitterBuilder {
108 base: BaseEmitterBuilder,
109 height: f32,
110 radius: f32,
111}
112
113impl CylinderEmitterBuilder {
114 pub fn new(base: BaseEmitterBuilder) -> Self {
116 Self {
117 base,
118 height: 1.0,
119 radius: 0.5,
120 }
121 }
122
123 pub fn with_height(mut self, height: f32) -> Self {
125 self.height = height;
126 self
127 }
128
129 pub fn with_radius(mut self, radius: f32) -> Self {
131 self.radius = radius;
132 self
133 }
134
135 pub fn build(self) -> Emitter {
137 Emitter::Cylinder(CylinderEmitter {
138 emitter: self.base.build(),
139 height: self.height,
140 radius: self.radius,
141 })
142 }
143}