fyrox_impl/scene/particle_system/emitter/
sphere.rs1use crate::{
25 core::{algebra::Vector3, numeric_range::RangeExt, reflect::prelude::*, visitor::prelude::*},
26 scene::particle_system::{
27 emitter::{
28 base::{BaseEmitter, BaseEmitterBuilder},
29 Emit, Emitter,
30 },
31 particle::Particle,
32 ParticleSystemRng,
33 },
34};
35use std::ops::{Deref, DerefMut};
36
37#[derive(Debug, Clone, Reflect, PartialEq, Visit)]
39pub struct SphereEmitter {
40 emitter: BaseEmitter,
41 #[reflect(min_value = 0.0, step = 0.1)]
42 radius: f32,
43}
44
45impl Deref for SphereEmitter {
46 type Target = BaseEmitter;
47
48 fn deref(&self) -> &Self::Target {
49 &self.emitter
50 }
51}
52
53impl DerefMut for SphereEmitter {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut self.emitter
56 }
57}
58
59impl Default for SphereEmitter {
60 fn default() -> Self {
61 Self {
62 emitter: BaseEmitter::default(),
63 radius: 0.5,
64 }
65 }
66}
67
68impl SphereEmitter {
69 pub fn new(emitter: BaseEmitter, radius: f32) -> Self {
71 Self { emitter, radius }
72 }
73
74 pub fn radius(&self) -> f32 {
76 self.radius
77 }
78
79 pub fn set_radius(&mut self, radius: f32) {
81 self.radius = radius.max(0.0);
82 }
83}
84
85impl Emit for SphereEmitter {
86 fn emit(&self, particle: &mut Particle, rng: &mut ParticleSystemRng) {
87 self.emitter.emit(particle, rng);
88 let phi = (0.0..std::f32::consts::PI).random(rng);
89 let theta = (0.0..2.0 * std::f32::consts::PI).random(rng);
90 let radius = (0.0..self.radius).random(rng);
91 let cos_theta = theta.cos();
92 let sin_theta = theta.sin();
93 let cos_phi = phi.cos();
94 let sin_phi = phi.sin();
95 particle.position = self.position()
96 + Vector3::new(
97 radius * sin_theta * cos_phi,
98 radius * sin_theta * sin_phi,
99 radius * cos_theta,
100 );
101 }
102}
103
104pub struct SphereEmitterBuilder {
107 base: BaseEmitterBuilder,
108 radius: f32,
109}
110
111impl SphereEmitterBuilder {
112 pub fn new(base: BaseEmitterBuilder) -> Self {
114 Self { base, radius: 0.5 }
115 }
116
117 pub fn with_radius(mut self, radius: f32) -> Self {
119 self.radius = radius;
120 self
121 }
122
123 pub fn build(self) -> Emitter {
125 Emitter::Sphere(SphereEmitter {
126 emitter: self.base.build(),
127 radius: self.radius,
128 })
129 }
130}