fyrox_impl/scene/particle_system/emitter/
cuboid.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! Box emitter emits particles uniformly in its volume. Can be used to create simple fog
//! layer.

use crate::core::numeric_range::RangeExt;
use crate::scene::particle_system::ParticleSystemRng;
use crate::{
    core::{algebra::Vector3, reflect::prelude::*, visitor::prelude::*},
    scene::particle_system::{
        emitter::{
            base::{BaseEmitter, BaseEmitterBuilder},
            Emit, Emitter,
        },
        particle::Particle,
    },
};
use std::ops::{Deref, DerefMut};

/// See module docs.
#[derive(Debug, Clone, Visit, PartialEq, Reflect)]
pub struct CuboidEmitter {
    emitter: BaseEmitter,
    #[reflect(min_value = 0.0, step = 0.1)]
    half_width: f32,
    #[reflect(min_value = 0.0, step = 0.1)]
    half_height: f32,
    #[reflect(min_value = 0.0, step = 0.1)]
    half_depth: f32,
}

impl Deref for CuboidEmitter {
    type Target = BaseEmitter;

    fn deref(&self) -> &Self::Target {
        &self.emitter
    }
}

impl DerefMut for CuboidEmitter {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.emitter
    }
}

impl CuboidEmitter {
    /// Creates new box emitter of given width, height and depth.
    pub fn new(emitter: BaseEmitter, width: f32, height: f32, depth: f32) -> Self {
        Self {
            emitter,
            half_width: width * 0.5,
            half_height: height * 0.5,
            half_depth: depth * 0.5,
        }
    }

    /// Returns half width of the box emitter.
    pub fn half_width(&self) -> f32 {
        self.half_width
    }

    /// Sets half width of the box emitter.
    pub fn set_half_width(&mut self, half_width: f32) {
        self.half_width = half_width.max(0.0);
    }

    /// Returns half height of the box emitter.
    pub fn half_height(&self) -> f32 {
        self.half_height
    }

    /// Sets half height of the box emitter.
    pub fn set_half_height(&mut self, half_height: f32) {
        self.half_height = half_height.max(0.0);
    }

    /// Returns half depth of the box emitter.
    pub fn half_depth(&self) -> f32 {
        self.half_depth
    }

    /// Sets half depth of the box emitter.
    pub fn set_half_depth(&mut self, half_depth: f32) {
        self.half_depth = half_depth.max(0.0);
    }
}

impl Default for CuboidEmitter {
    fn default() -> Self {
        Self {
            emitter: Default::default(),
            half_width: 0.5,
            half_height: 0.5,
            half_depth: 0.5,
        }
    }
}

impl Emit for CuboidEmitter {
    fn emit(&self, particle: &mut Particle, rng: &mut ParticleSystemRng) {
        self.emitter.emit(particle, rng);
        let position = self.position();
        particle.position = Vector3::new(
            position.x + (-self.half_width..self.half_width).random(rng),
            position.y + (-self.half_height..self.half_height).random(rng),
            position.z + (-self.half_depth..self.half_depth).random(rng),
        )
    }
}

/// Box emitter builder allows you to construct box emitter in declarative manner.
/// This is typical implementation of Builder pattern.
pub struct CuboidEmitterBuilder {
    base: BaseEmitterBuilder,
    width: f32,
    height: f32,
    depth: f32,
}

impl CuboidEmitterBuilder {
    /// Creates new box emitter builder with
    pub fn new(base: BaseEmitterBuilder) -> Self {
        Self {
            base,
            width: 1.0,
            height: 1.0,
            depth: 1.0,
        }
    }

    /// Sets desired width of the emitter.
    pub fn with_width(mut self, width: f32) -> Self {
        self.width = width;
        self
    }

    /// Sets desired height of the emitter.
    pub fn with_height(mut self, height: f32) -> Self {
        self.height = height;
        self
    }

    /// Sets desired depth of the emitter.
    pub fn with_depth(mut self, depth: f32) -> Self {
        self.depth = depth;
        self
    }

    /// Creates new box emitter with given parameters.
    pub fn build(self) -> Emitter {
        Emitter::Cuboid(CuboidEmitter {
            emitter: self.base.build(),
            half_width: self.width * 0.5,
            half_height: self.height * 0.5,
            half_depth: self.depth * 0.5,
        })
    }
}