1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #pragma once |
4 | |
5 | #include "BsCorePrerequisites.h" |
6 | #include "Particles/BsParticleModule.h" |
7 | #include "Math/BsDegree.h" |
8 | #include "Math/BsVector2.h" |
9 | #include "Math/BsVector3.h" |
10 | #include "Math/BsMatrix4.h" |
11 | #include "BsParticleDistribution.h" |
12 | |
13 | namespace bs |
14 | { |
15 | class Random; |
16 | class ParticleSet; |
17 | |
18 | /** @addtogroup Particles |
19 | * @{ |
20 | */ |
21 | |
22 | /** Types of emission modes. */ |
23 | enum class BS_SCRIPT_EXPORT(m:Particles) ParticleEmissionModeType |
24 | { |
25 | /** Position will be picked randomly on a shape. */ |
26 | Random, |
27 | |
28 | /** Positions will loop around the shape in a predictable fashion. */ |
29 | Loop, |
30 | |
31 | /** Similar to Loop, except the order will be reversed when one loop iteration finishes. */ |
32 | PingPong, |
33 | |
34 | /** |
35 | * All particles spawned on the shape at some instant (usually a frame) will be spread around the shape equally. |
36 | */ |
37 | Spread |
38 | }; |
39 | |
40 | /** Controls how are particle positions on a shape chosen. */ |
41 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true) ParticleEmissionMode |
42 | { |
43 | /** Type that determines general behaviour. */ |
44 | ParticleEmissionModeType type = ParticleEmissionModeType::Random; |
45 | |
46 | /** |
47 | * Speed along which particle generation should move around the shape, relevant for Loop and PingPing emission |
48 | * modes. |
49 | */ |
50 | float speed = 1.0f; |
51 | |
52 | /** |
53 | * Determines the minimum interval allowed between the generated particles. 0 specifies the particles can be |
54 | * generated anywhere on the shape. |
55 | */ |
56 | float interval = 0.0f; |
57 | }; |
58 | |
59 | /** |
60 | * Base class from all emitter shapes. Emitter shapes determine the position and direction of newly created particles. |
61 | */ |
62 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterShape : public IReflectable |
63 | { |
64 | public: |
65 | virtual ~ParticleEmitterShape() = default; |
66 | |
67 | /** |
68 | * @name Internal |
69 | * @{ |
70 | */ |
71 | |
72 | /** |
73 | * Spawns a new set of particles using the current shape's distribution. |
74 | * |
75 | * @param[in] random Random number generator. |
76 | * @param[in] particles Particle set in which to insert new particles. |
77 | * @param[in] count Number of particles to spawn. |
78 | * @param[in] state Optional state that can contain various per-frame information required for spawning |
79 | * the particles. |
80 | * @return Index at which the first of the particles was inserted, with other particles following |
81 | * sequentially. |
82 | */ |
83 | virtual UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
84 | const ParticleSystemState& state) const = 0; |
85 | |
86 | /** @} */ |
87 | protected: |
88 | friend class ParticleEmitter; |
89 | |
90 | ParticleEmitterShape() = default; |
91 | |
92 | /** |
93 | * Calculates the bounds of the emitter shape. |
94 | * |
95 | * @param[in] shape AABB for the emitter shape itself. |
96 | * @param[in] velocity AABB for the generated normals. |
97 | */ |
98 | virtual void calcBounds(AABox& shape, AABox& velocity) const = 0; |
99 | |
100 | /** |
101 | * Checks has the emitter been initialized properly. If the emitter is not valid then the spawn() method is |
102 | * not allowed to be called. |
103 | */ |
104 | bool isValid() const { return mIsValid; } |
105 | |
106 | bool mIsValid = true; |
107 | }; |
108 | |
109 | /** Determines the emission type for the cone particle emitter shape. */ |
110 | enum class BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterConeType |
111 | { |
112 | /** Emit particles only from the cone base. */ |
113 | Base, |
114 | /** Emit particles from the entire cone volume. */ |
115 | Volume |
116 | }; |
117 | |
118 | /** Information describing a ParticleEmitterConeShape. */ |
119 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleConeShapeOptions) PARTICLE_CONE_SHAPE_DESC |
120 | { |
121 | /** Determines where on the cone are the particles emitter from. */ |
122 | ParticleEmitterConeType type = ParticleEmitterConeType::Base; |
123 | |
124 | /** Radius of the cone base. */ |
125 | float radius = 0.0f; |
126 | |
127 | /** Angle of the cone. */ |
128 | Degree angle = Degree(45.0f); |
129 | |
130 | /** Length of the cone. Irrelevant if emission type is Base. */ |
131 | float length = 1.0f; |
132 | |
133 | /** |
134 | * Proportion of the volume that can emit particles. Thickness of 0 results in particles being emitted only from the |
135 | * edge of the cone, while thickness of 1 results in particles being emitted from the entire volume. In-between |
136 | * values will use a part of the volume. |
137 | */ |
138 | float thickness = 1.0f; |
139 | |
140 | /** Angular portion of the cone from which to emit particles from, in degrees. */ |
141 | Degree arc = Degree(360.0f); |
142 | |
143 | /** Determines how will particle positions on the shape be generated. */ |
144 | ParticleEmissionMode mode; |
145 | }; |
146 | |
147 | /** |
148 | * Particle emitter shape that emits particles from a cone. Particles can be created on cone base or volume, while |
149 | * controling the radial arc of the emitted portion of the volume, as well as thickness of the cone emission volume. |
150 | * All particles will have random normals within the distribution of the cone. |
151 | */ |
152 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterConeShape : public ParticleEmitterShape |
153 | { |
154 | public: |
155 | ParticleEmitterConeShape(const PARTICLE_CONE_SHAPE_DESC& desc); |
156 | ParticleEmitterConeShape() = default; |
157 | virtual ~ParticleEmitterConeShape() = default; |
158 | |
159 | /** Options describing the shape. */ |
160 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
161 | void setOptions(const PARTICLE_CONE_SHAPE_DESC& options) { mInfo = options; } |
162 | |
163 | /** @copydoc setOptions */ |
164 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
165 | const PARTICLE_CONE_SHAPE_DESC& getOptions() const { return mInfo; } |
166 | |
167 | /** Creates a new particle emitter cone shape. */ |
168 | BS_SCRIPT_EXPORT(ec:T) |
169 | static SPtr<ParticleEmitterConeShape> create(const PARTICLE_CONE_SHAPE_DESC& desc); |
170 | |
171 | /** Creates a new particle emitter cone shape. */ |
172 | BS_SCRIPT_EXPORT(ec:T) |
173 | static SPtr<ParticleEmitterConeShape> create(); |
174 | |
175 | /** |
176 | * @name Internal |
177 | * @{ |
178 | */ |
179 | |
180 | /** @copydoc ParticleEmitterShape::_spawn */ |
181 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
182 | const ParticleSystemState& state) const override; |
183 | |
184 | /** Spawns a single particle randomly, generating its position and normal. */ |
185 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
186 | |
187 | /** Spawns a single particle on the specified point on the cone, generating its position and normal. */ |
188 | void _spawn(float t, Vector3& position, Vector3& normal) const; |
189 | |
190 | /** @} */ |
191 | protected: |
192 | /** @copydoc ParticleEmitterShape::calcBounds */ |
193 | void calcBounds(AABox& shape, AABox& velocity) const override; |
194 | |
195 | /** Generates a position and normal of a particle based on the input 2D position on the cone circle base. */ |
196 | void getPointInCone(const Vector2& pos2D, float distance, Vector3& position, Vector3& normal) const; |
197 | |
198 | PARTICLE_CONE_SHAPE_DESC mInfo; |
199 | |
200 | /************************************************************************/ |
201 | /* RTTI */ |
202 | /************************************************************************/ |
203 | public: |
204 | friend class ParticleEmitterConeShapeRTTI; |
205 | static RTTITypeBase* getRTTIStatic(); |
206 | RTTITypeBase* getRTTI() const override; |
207 | }; |
208 | |
209 | /** Information describing a ParticleEmitterSphereShape. */ |
210 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleSphereShapeOptions) PARTICLE_SPHERE_SHAPE_DESC |
211 | { |
212 | /** Radius of the sphere. */ |
213 | float radius = 1.0f; |
214 | |
215 | /** |
216 | * Proportion of the volume that can emit particles. Thickness of 0 results in particles being emitted only from the |
217 | * edge of the volume, while thickness of 1 results in particles being emitted from the entire volume. In-between |
218 | * values will use a part of the volume. |
219 | */ |
220 | float thickness = 0.0f; |
221 | }; |
222 | |
223 | /** |
224 | * Particle emitter shape that emits particles from a sphere. Particles can be emitted from sphere surface, the entire |
225 | * volume or a proportion of the volume depending on the thickness parameter. All particles will have normals pointing |
226 | * outwards in a spherical direction. |
227 | */ |
228 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterSphereShape : public ParticleEmitterShape |
229 | { |
230 | public: |
231 | ParticleEmitterSphereShape() = default; |
232 | ParticleEmitterSphereShape(const PARTICLE_SPHERE_SHAPE_DESC& desc); |
233 | |
234 | /** Options describing the shape. */ |
235 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
236 | void setOptions(const PARTICLE_SPHERE_SHAPE_DESC& options) { mInfo = options; } |
237 | |
238 | /** @copydoc setOptions */ |
239 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
240 | const PARTICLE_SPHERE_SHAPE_DESC& getOptions() const { return mInfo; } |
241 | |
242 | /** Creates a new particle emitter sphere shape. */ |
243 | BS_SCRIPT_EXPORT(ec:T) |
244 | static SPtr<ParticleEmitterSphereShape> create(const PARTICLE_SPHERE_SHAPE_DESC& desc); |
245 | |
246 | /** Creates a new particle emitter sphere shape. */ |
247 | BS_SCRIPT_EXPORT(ec:T) |
248 | static SPtr<ParticleEmitterSphereShape> create(); |
249 | |
250 | /** |
251 | * @name Internal |
252 | * @{ |
253 | */ |
254 | |
255 | /** @copydoc ParticleEmitterShape::_spawn */ |
256 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
257 | const ParticleSystemState& state) const override; |
258 | |
259 | /** Spawns a single particle, generating its position and normal. */ |
260 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
261 | |
262 | /** @} */ |
263 | protected: |
264 | /** @copydoc ParticleEmitterShape::calcBounds */ |
265 | void calcBounds(AABox& shape, AABox& velocity) const override; |
266 | |
267 | PARTICLE_SPHERE_SHAPE_DESC mInfo; |
268 | |
269 | /************************************************************************/ |
270 | /* RTTI */ |
271 | /************************************************************************/ |
272 | public: |
273 | friend class ParticleEmitterSphereShapeRTTI; |
274 | static RTTITypeBase* getRTTIStatic(); |
275 | RTTITypeBase* getRTTI() const override; |
276 | }; |
277 | |
278 | /** Information describing a ParticleEmitterHemisphereShape. */ |
279 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleHemisphereShapeOptions) PARTICLE_HEMISPHERE_SHAPE_DESC |
280 | { |
281 | /** Radius of the hemisphere. */ |
282 | float radius = 1.0f; |
283 | |
284 | /** |
285 | * Proportion of the volume that can emit particles. Thickness of 0 results in particles being emitted only from the |
286 | * edge of the volume, while thickness of 1 results in particles being emitted from the entire volume. In-between |
287 | * values will use a part of the volume. |
288 | */ |
289 | float thickness = 0.0f; |
290 | }; |
291 | |
292 | /** |
293 | * Particle emitter shape that emits particles from a hemisphere. Particles can be emitted from the hemisphere surface, |
294 | * the entire volume or a proportion of the volume depending on the thickness parameter. All particles will have |
295 | * normals pointing outwards in a spherical direction. |
296 | */ |
297 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterHemisphereShape : public ParticleEmitterShape |
298 | { |
299 | public: |
300 | ParticleEmitterHemisphereShape() = default; |
301 | ParticleEmitterHemisphereShape(const PARTICLE_HEMISPHERE_SHAPE_DESC& desc); |
302 | |
303 | /** Options describing the shape. */ |
304 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
305 | void setOptions(const PARTICLE_HEMISPHERE_SHAPE_DESC& options) { mInfo = options; } |
306 | |
307 | /** @copydoc setOptions */ |
308 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
309 | const PARTICLE_HEMISPHERE_SHAPE_DESC& getOptions() const { return mInfo; } |
310 | |
311 | /** Creates a new particle emitter sphere shape. */ |
312 | BS_SCRIPT_EXPORT(ec:T) |
313 | static SPtr<ParticleEmitterHemisphereShape> create(const PARTICLE_HEMISPHERE_SHAPE_DESC& desc); |
314 | |
315 | /** Creates a new particle emitter sphere shape. */ |
316 | BS_SCRIPT_EXPORT(ec:T) |
317 | static SPtr<ParticleEmitterHemisphereShape> create(); |
318 | |
319 | /** |
320 | * @name Internal |
321 | * @{ |
322 | */ |
323 | |
324 | /** @copydoc ParticleEmitterShape::_spawn */ |
325 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
326 | const ParticleSystemState& state) const override; |
327 | |
328 | /** Spawns a single particle, generating its position and normal. */ |
329 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
330 | |
331 | /** @} */ |
332 | protected: |
333 | /** @copydoc ParticleEmitterShape::calcBounds */ |
334 | void calcBounds(AABox& shape, AABox& velocity) const override; |
335 | |
336 | PARTICLE_HEMISPHERE_SHAPE_DESC mInfo; |
337 | |
338 | /************************************************************************/ |
339 | /* RTTI */ |
340 | /************************************************************************/ |
341 | public: |
342 | friend class ParticleEmitterHemisphereShapeRTTI; |
343 | static RTTITypeBase* getRTTIStatic(); |
344 | RTTITypeBase* getRTTI() const override; |
345 | }; |
346 | |
347 | /** Determines the emission type for the cone particle emitter shape. */ |
348 | enum class BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterBoxType |
349 | { |
350 | /** Particles will be emitted from the entire volume. */ |
351 | Volume, |
352 | /** Particles will be emitted only from box surface. */ |
353 | Surface, |
354 | /** Particles will be emitted only from box edge. */ |
355 | Edge |
356 | }; |
357 | |
358 | /** Information describing a ParticleEmitterBoxShape. */ |
359 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleBoxShapeOptions) PARTICLE_BOX_SHAPE_DESC |
360 | { |
361 | /** Determines from which portion of the box should particles be emitted from. */ |
362 | ParticleEmitterBoxType type = ParticleEmitterBoxType::Volume; |
363 | |
364 | /** Extends of the box. */ |
365 | Vector3 extents = Vector3::ONE; |
366 | }; |
367 | |
368 | /** |
369 | * Particle emitter shape that emits particles from an axis aligned box. Particles can be emitted from box volume, |
370 | * surface or edges. All particles have their normals set to positive Z direction. |
371 | */ |
372 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterBoxShape : public ParticleEmitterShape |
373 | { |
374 | public: |
375 | ParticleEmitterBoxShape() = default; |
376 | ParticleEmitterBoxShape(const PARTICLE_BOX_SHAPE_DESC& desc); |
377 | |
378 | /** Options describing the shape. */ |
379 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
380 | void setOptions(const PARTICLE_BOX_SHAPE_DESC& options) { mInfo = options; } |
381 | |
382 | /** @copydoc setOptions */ |
383 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
384 | const PARTICLE_BOX_SHAPE_DESC& getOptions() const { return mInfo; } |
385 | |
386 | /** Creates a new particle emitter box shape. */ |
387 | BS_SCRIPT_EXPORT(ec:T) |
388 | static SPtr<ParticleEmitterBoxShape> create(const PARTICLE_BOX_SHAPE_DESC& desc); |
389 | |
390 | /** Creates a new particle emitter box shape. */ |
391 | BS_SCRIPT_EXPORT(ec:T) |
392 | static SPtr<ParticleEmitterBoxShape> create(); |
393 | |
394 | /** |
395 | * @name Internal |
396 | * @{ |
397 | */ |
398 | |
399 | /** @copydoc ParticleEmitterShape::_spawn */ |
400 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
401 | const ParticleSystemState& state) const override; |
402 | |
403 | /** Spawns a single particle, generating its position and normal. */ |
404 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
405 | |
406 | /** @} */ |
407 | protected: |
408 | /** @copydoc ParticleEmitterShape::calcBounds */ |
409 | void calcBounds(AABox& shape, AABox& velocity) const override; |
410 | |
411 | PARTICLE_BOX_SHAPE_DESC mInfo; |
412 | |
413 | float mSurfaceArea[3]; |
414 | float mEdgeLengths[3]; |
415 | |
416 | /************************************************************************/ |
417 | /* RTTI */ |
418 | /************************************************************************/ |
419 | public: |
420 | friend class ParticleEmitterBoxShapeRTTI; |
421 | static RTTITypeBase* getRTTIStatic(); |
422 | RTTITypeBase* getRTTI() const override; |
423 | }; |
424 | |
425 | /** Information describing a ParticleEmitterLineShape. */ |
426 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleLineShapeOptions) PARTICLE_LINE_SHAPE_DESC |
427 | { |
428 | /** Length of the line. */ |
429 | float length = 1.0f; |
430 | |
431 | /** Determines how will particle positions on the shape be generated. */ |
432 | ParticleEmissionMode mode; |
433 | }; |
434 | |
435 | /** Particle emitter shape that emits particles from a line segment. */ |
436 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterLineShape : public ParticleEmitterShape |
437 | { |
438 | public: |
439 | ParticleEmitterLineShape() = default; |
440 | ParticleEmitterLineShape(const PARTICLE_LINE_SHAPE_DESC& desc); |
441 | |
442 | /** Options describing the shape. */ |
443 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
444 | void setOptions(const PARTICLE_LINE_SHAPE_DESC& options) { mInfo = options; } |
445 | |
446 | /** @copydoc setOptions */ |
447 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
448 | const PARTICLE_LINE_SHAPE_DESC& getOptions() const { return mInfo; } |
449 | |
450 | /** Creates a new particle emitter edge shape. */ |
451 | BS_SCRIPT_EXPORT(ec:T) |
452 | static SPtr<ParticleEmitterLineShape> create(const PARTICLE_LINE_SHAPE_DESC& desc); |
453 | |
454 | /** Creates a new particle emitter edge shape. */ |
455 | BS_SCRIPT_EXPORT(ec:T) |
456 | static SPtr<ParticleEmitterLineShape> create(); |
457 | |
458 | /** |
459 | * @name Internal |
460 | * @{ |
461 | */ |
462 | |
463 | /** @copydoc ParticleEmitterShape::_spawn */ |
464 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
465 | const ParticleSystemState& state) const override; |
466 | |
467 | /** Spawns a single particle randomly, generating its position and normal. */ |
468 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
469 | |
470 | /** Spawns a single particle on the specified point on the line, generating its position and normal. */ |
471 | void _spawn(float t, Vector3& position, Vector3& normal) const; |
472 | |
473 | /** @} */ |
474 | protected: |
475 | /** @copydoc ParticleEmitterShape::calcBounds */ |
476 | void calcBounds(AABox& shape, AABox& velocity) const override; |
477 | |
478 | PARTICLE_LINE_SHAPE_DESC mInfo; |
479 | |
480 | /************************************************************************/ |
481 | /* RTTI */ |
482 | /************************************************************************/ |
483 | public: |
484 | friend class ParticleEmitterLineShapeRTTI; |
485 | static RTTITypeBase* getRTTIStatic(); |
486 | RTTITypeBase* getRTTI() const override; |
487 | }; |
488 | |
489 | /** Information describing a ParticleEmitterCircleShape. */ |
490 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleCircleShapeOptions) PARTICLE_CIRCLE_SHAPE_DESC |
491 | { |
492 | /** Radius of the circle. */ |
493 | float radius = 1.0f; |
494 | |
495 | /** |
496 | * Proportion of the surface that can emit particles. Thickness of 0 results in particles being emitted only from |
497 | * the edge of the circle, while thickness of 1 results in particles being emitted from the entire surface. |
498 | * In-between values will use a part of the surface. |
499 | */ |
500 | float thickness = 0.0f; |
501 | |
502 | /** Angular portion of the cone from which to emit particles from, in degrees. */ |
503 | Degree arc = Degree(360.0f); |
504 | |
505 | /** Determines how will particle positions on the shape be generated. */ |
506 | ParticleEmissionMode mode; |
507 | }; |
508 | |
509 | /** |
510 | * Particle emitter shape that emits particles from a circle. Using the thickness parameter you can control whether to |
511 | * emit only from circle edge, the entire surface or just a part of the surface. Using the arc parameter you can emit |
512 | * from a specific angular portion of the circle. |
513 | */ |
514 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterCircleShape : public ParticleEmitterShape |
515 | { |
516 | public: |
517 | ParticleEmitterCircleShape() = default; |
518 | ParticleEmitterCircleShape(const PARTICLE_CIRCLE_SHAPE_DESC& desc); |
519 | virtual ~ParticleEmitterCircleShape() = default; |
520 | |
521 | /** Options describing the shape. */ |
522 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
523 | void setOptions(const PARTICLE_CIRCLE_SHAPE_DESC& options) { mInfo = options; } |
524 | |
525 | /** @copydoc setOptions */ |
526 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
527 | const PARTICLE_CIRCLE_SHAPE_DESC& getOptions() const { return mInfo; } |
528 | |
529 | /** Creates a new particle emitter circle shape. */ |
530 | BS_SCRIPT_EXPORT(ec:T) |
531 | static SPtr<ParticleEmitterCircleShape> create(const PARTICLE_CIRCLE_SHAPE_DESC& desc); |
532 | |
533 | /** Creates a new particle emitter circle shape. */ |
534 | BS_SCRIPT_EXPORT(ec:T) |
535 | static SPtr<ParticleEmitterCircleShape> create(); |
536 | |
537 | /** |
538 | * @name Internal |
539 | * @{ |
540 | */ |
541 | |
542 | /** @copydoc ParticleEmitterShape::_spawn */ |
543 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
544 | const ParticleSystemState& state) const override; |
545 | |
546 | /** Spawns a single particle randomly, generating its position and normal. */ |
547 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
548 | |
549 | /** Spawns a single particle on the specified point on the circle, generating its position and normal. */ |
550 | void _spawn(float t, Vector3& position, Vector3& normal) const; |
551 | |
552 | /** @} */ |
553 | protected: |
554 | /** @copydoc ParticleEmitterShape::calcBounds */ |
555 | void calcBounds(AABox& shape, AABox& velocity) const override; |
556 | |
557 | PARTICLE_CIRCLE_SHAPE_DESC mInfo; |
558 | |
559 | /************************************************************************/ |
560 | /* RTTI */ |
561 | /************************************************************************/ |
562 | public: |
563 | friend class ParticleEmitterCircleShapeRTTI; |
564 | static RTTITypeBase* getRTTIStatic(); |
565 | RTTITypeBase* getRTTI() const override; |
566 | }; |
567 | |
568 | /** Information describing a ParticleEmitterRectShape. */ |
569 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleRectShapeOptions) PARTICLE_RECT_SHAPE_DESC |
570 | { |
571 | /** Extents of the rectangle. */ |
572 | Vector2 extents = Vector2::ONE; |
573 | }; |
574 | |
575 | /** Particle emitter shape that emits particles from the surface of a rectangle. */ |
576 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterRectShape : public ParticleEmitterShape |
577 | { |
578 | public: |
579 | ParticleEmitterRectShape() = default; |
580 | ParticleEmitterRectShape(const PARTICLE_RECT_SHAPE_DESC& desc); |
581 | |
582 | /** Options describing the shape. */ |
583 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
584 | void setOptions(const PARTICLE_RECT_SHAPE_DESC& options) { mInfo = options; } |
585 | |
586 | /** @copydoc setOptions */ |
587 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
588 | const PARTICLE_RECT_SHAPE_DESC& getOptions() const { return mInfo; } |
589 | |
590 | /** Creates a new particle emitter rectangle shape. */ |
591 | BS_SCRIPT_EXPORT(ec:T) |
592 | static SPtr<ParticleEmitterRectShape> create(const PARTICLE_RECT_SHAPE_DESC& desc); |
593 | |
594 | /** Creates a new particle emitter rectangle shape. */ |
595 | BS_SCRIPT_EXPORT(ec:T) |
596 | static SPtr<ParticleEmitterRectShape> create(); |
597 | |
598 | /** |
599 | * @name Internal |
600 | * @{ |
601 | */ |
602 | |
603 | /** @copydoc ParticleEmitterShape::_spawn */ |
604 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
605 | const ParticleSystemState& state) const override; |
606 | |
607 | /** Spawns a single particle, generating its position and normal. */ |
608 | void _spawn(const Random& random, Vector3& position, Vector3& normal) const; |
609 | |
610 | /** @} */ |
611 | protected: |
612 | /** @copydoc ParticleEmitterShape::calcBounds */ |
613 | void calcBounds(AABox& shape, AABox& velocity) const override; |
614 | |
615 | PARTICLE_RECT_SHAPE_DESC mInfo; |
616 | |
617 | /************************************************************************/ |
618 | /* RTTI */ |
619 | /************************************************************************/ |
620 | public: |
621 | friend class ParticleEmitterRectShapeRTTI; |
622 | static RTTITypeBase* getRTTIStatic(); |
623 | RTTITypeBase* getRTTI() const override; |
624 | }; |
625 | |
626 | /** Determines the emission type for the mesh particle emitter shape. */ |
627 | enum class BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterMeshType |
628 | { |
629 | /** Particles will be emitted from mesh vertices. */ |
630 | Vertex, |
631 | /** Particles will be emitted from mesh edges. */ |
632 | Edge, |
633 | /** Particles will be emitted from mesh triangles. */ |
634 | Triangle |
635 | }; |
636 | |
637 | /** Information describing a ParticleEmitterStaticMeshShape. */ |
638 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleStaticMeshShapeOptions) PARTICLE_STATIC_MESH_SHAPE_DESC |
639 | { |
640 | /** Determines from which portion of the mesh are the particles emitted from. */ |
641 | ParticleEmitterMeshType type = ParticleEmitterMeshType::Triangle; |
642 | |
643 | /** |
644 | * When enabled the particles will be emitted sequentially from mesh vertices in the order they are defined. |
645 | * Only relevant for the Vertex emit mode. |
646 | */ |
647 | bool sequential = false; |
648 | |
649 | /** |
650 | * Mesh to spawn particles on. Must at least contain per-vertex position data encoded as 3D float vectors. Can |
651 | * optionally contain per-vertex normals encoded as 3D float vectors or as 4-byte unsigned-normalized format. |
652 | */ |
653 | HMesh mesh; |
654 | }; |
655 | |
656 | /** |
657 | * Calculates and stores per-triangle weights that can be used for easily picking a random triangle on a mesh, ensuring |
658 | * larger triangles are picked more likely. |
659 | */ |
660 | class MeshWeightedTriangles |
661 | { |
662 | /** Contains the cumulative, normalized weight of the triangle and its vertex indices. */ |
663 | struct TriangleWeight |
664 | { |
665 | float cumulativeWeight; |
666 | UINT32 indices[3]; |
667 | }; |
668 | |
669 | public: |
670 | MeshWeightedTriangles() = default; |
671 | MeshWeightedTriangles(const MeshData& meshData); |
672 | |
673 | /** Updates the weights from the provided mesh data. */ |
674 | void calculate(const MeshData& meshData); |
675 | |
676 | /** Find a random triangle on the mesh and outputs its vertex indices. */ |
677 | void getTriangle(const Random& random, std::array<UINT32, 3>& indices) const; |
678 | |
679 | private: |
680 | Vector<TriangleWeight> mWeights; |
681 | }; |
682 | |
683 | /** Contains common functionality for particle mesh emitters. */ |
684 | class MeshEmissionHelper |
685 | { |
686 | public: |
687 | /** |
688 | * Initializes the emission helper if the provided mesh contains necessary data for particle emission. Otherwise |
689 | * reports any issues in the log. |
690 | * |
691 | * @param[in] mesh Mesh to validate. |
692 | * @param[in] perVertex Set to true if particle emission is happening on mesh vertices. |
693 | * @param[in] skinning Set to true if the mesh will be animated using skinning. |
694 | * @return True if initialized, or false if issues were detected. |
695 | */ |
696 | bool initialize(const HMesh& mesh, bool perVertex, bool skinning); |
697 | |
698 | /** |
699 | * Returns the next sequential vertex on the mesh and increments the internal counter so the next vertex is |
700 | * returned on the following call. Loops around if end is reached. Returns vertex position, normal and index. |
701 | */ |
702 | void getSequentialVertex(Vector3& position, Vector3& normal, UINT32& idx) const; |
703 | |
704 | /** Randomly picks a vertex on the mesh and returns its position, normal and index. */ |
705 | void getRandomVertex(const Random& random, Vector3& position, Vector3& normal, UINT32& idx) const; |
706 | |
707 | /** Randomly picks an edge on the mesh and returns the position, normal and indices of its vertices. */ |
708 | void getRandomEdge(const Random& random, std::array<Vector3, 2>& position, std::array<Vector3, 2>& normal, |
709 | std::array<UINT32, 2>& idx) const; |
710 | |
711 | /** Randomly picks an triangle on the mesh and returns the position, normal and indices of its vertices. */ |
712 | void getRandomTriangle(const Random& random, std::array<Vector3, 3>& position, std::array<Vector3, 3>& normal, |
713 | std::array<UINT32, 3>& idx) const; |
714 | |
715 | /** Evaluates a blend matrix for a vertex at the specified index. */ |
716 | Matrix4 getBlendMatrix(const Matrix4* bones, UINT32 vertexIdx) const; |
717 | |
718 | private: |
719 | MeshWeightedTriangles mWeightedTriangles; |
720 | |
721 | UINT8* mVertices = nullptr; |
722 | UINT8* mNormals = nullptr; |
723 | UINT32 mNumVertices = 0; |
724 | UINT32 mVertexStride = 0; |
725 | bool m32BitNormals = true; |
726 | |
727 | UINT8* mBoneIndices = nullptr; |
728 | UINT8* mBoneWeights = nullptr; |
729 | |
730 | SPtr<MeshData> mMeshData; |
731 | |
732 | // Transient |
733 | mutable UINT32 mNextSequentialIdx = 0; |
734 | }; |
735 | |
736 | /** |
737 | * Particle emitter shape that emits particles from a surface of a static (non-animated) mesh. Particles can be |
738 | * emitted from mesh vertices, edges or triangles. If information about normals exists, particles will also inherit |
739 | * the normals. |
740 | */ |
741 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterStaticMeshShape : public ParticleEmitterShape |
742 | { |
743 | public: |
744 | ParticleEmitterStaticMeshShape(const PARTICLE_STATIC_MESH_SHAPE_DESC& desc); |
745 | ParticleEmitterStaticMeshShape(); |
746 | virtual ~ParticleEmitterStaticMeshShape() = default; |
747 | |
748 | /** Options describing the shape. */ |
749 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
750 | void setOptions(const PARTICLE_STATIC_MESH_SHAPE_DESC& options); |
751 | |
752 | /** @copydoc setOptions */ |
753 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
754 | const PARTICLE_STATIC_MESH_SHAPE_DESC& getOptions() const { return mInfo; } |
755 | |
756 | /** Creates a new particle emitter static mesh shape. */ |
757 | BS_SCRIPT_EXPORT(ec:T) |
758 | static SPtr<ParticleEmitterStaticMeshShape> create(const PARTICLE_STATIC_MESH_SHAPE_DESC& desc); |
759 | |
760 | /** Creates a new particle emitter static mesh shape. */ |
761 | BS_SCRIPT_EXPORT(ec:T) |
762 | static SPtr<ParticleEmitterStaticMeshShape> create(); |
763 | |
764 | /** |
765 | * @name Internal |
766 | * @{ |
767 | */ |
768 | |
769 | /** @copydoc ParticleEmitterShape::_spawn */ |
770 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
771 | const ParticleSystemState& state) const override; |
772 | |
773 | /** @} */ |
774 | protected: |
775 | /** @copydoc ParticleEmitterShape::calcBounds */ |
776 | void calcBounds(AABox& shape, AABox& velocity) const override; |
777 | |
778 | PARTICLE_STATIC_MESH_SHAPE_DESC mInfo; |
779 | MeshEmissionHelper mMeshEmissionHelper; |
780 | |
781 | /************************************************************************/ |
782 | /* RTTI */ |
783 | /************************************************************************/ |
784 | public: |
785 | friend class ParticleEmitterStaticMeshShapeRTTI; |
786 | static RTTITypeBase* getRTTIStatic(); |
787 | RTTITypeBase* getRTTI() const override; |
788 | }; |
789 | |
790 | /** Information describing a ParticleEmitterSkinnedMeshShape. */ |
791 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true,n:ParticleSkinnedMeshShapeOptions) PARTICLE_SKINNED_MESH_SHAPE_DESC |
792 | { |
793 | /** Determines from which portion of the mesh are the particles emitted from. */ |
794 | ParticleEmitterMeshType type = ParticleEmitterMeshType::Triangle; |
795 | |
796 | /** |
797 | * When enabled the particles will be emitted sequentially from mesh vertices in the order they are defined. |
798 | * Only relevant for the Vertex emit mode. |
799 | */ |
800 | bool sequential = false; |
801 | |
802 | /** |
803 | * Renderable object containing a mesh to spawn particles on, as well as the attached Animation object resposible |
804 | * for performing skinned animation. Mesh must at least contain per-vertex position data encoded as 3D float |
805 | * vectors, blend indices encoded in 4-byte format, and blend weights encoded a 4D float vectors. Can optionally |
806 | * contain per-vertex normals encoded as 3D float vectors or as 4-byte unsigned-normalized format. |
807 | */ |
808 | ComponentOrActor<Renderable> renderable; |
809 | }; |
810 | |
811 | /** |
812 | * Particle emitter shape that emits particles from a surface of a skinned (animated) mesh. Particles can be |
813 | * emitted from mesh vertices, edges or triangles. If information about normals exists, particles will also inherit |
814 | * the normals. |
815 | */ |
816 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitterSkinnedMeshShape : public ParticleEmitterShape |
817 | { |
818 | public: |
819 | ParticleEmitterSkinnedMeshShape(const PARTICLE_SKINNED_MESH_SHAPE_DESC& desc); |
820 | ParticleEmitterSkinnedMeshShape(); |
821 | virtual ~ParticleEmitterSkinnedMeshShape() = default; |
822 | |
823 | /** Options describing the shape. */ |
824 | BS_SCRIPT_EXPORT(pr:setter,n:Options,inline) |
825 | void setOptions(const PARTICLE_SKINNED_MESH_SHAPE_DESC& options); |
826 | |
827 | /** @copydoc setOptions */ |
828 | BS_SCRIPT_EXPORT(pr:getter,n:Options) |
829 | const PARTICLE_SKINNED_MESH_SHAPE_DESC& getOptions() const { return mInfo; } |
830 | |
831 | /** Creates a new particle emitter skinned mesh shape. */ |
832 | BS_SCRIPT_EXPORT(ec:T) |
833 | static SPtr<ParticleEmitterSkinnedMeshShape> create(const PARTICLE_SKINNED_MESH_SHAPE_DESC& desc); |
834 | |
835 | /** Creates a new particle emitter skinned mesh shape. */ |
836 | BS_SCRIPT_EXPORT(ec:T) |
837 | static SPtr<ParticleEmitterSkinnedMeshShape> create(); |
838 | |
839 | /** |
840 | * @name Internal |
841 | * @{ |
842 | */ |
843 | |
844 | /** @copydoc ParticleEmitterShape::_spawn */ |
845 | UINT32 _spawn(const Random& random, ParticleSet& particles, UINT32 count, |
846 | const ParticleSystemState& state) const override; |
847 | |
848 | /** @} */ |
849 | protected: |
850 | /** @copydoc ParticleEmitterShape::calcBounds */ |
851 | void calcBounds(AABox& shape, AABox& velocity) const override; |
852 | |
853 | PARTICLE_SKINNED_MESH_SHAPE_DESC mInfo; |
854 | MeshEmissionHelper mMeshEmissionHelper; |
855 | |
856 | /************************************************************************/ |
857 | /* RTTI */ |
858 | /************************************************************************/ |
859 | public: |
860 | friend class ParticleEmitterSkinnedMeshShapeRTTI; |
861 | static RTTITypeBase* getRTTIStatic(); |
862 | RTTITypeBase* getRTTI() const override; |
863 | }; |
864 | |
865 | /** Specifies a burst of particles that occurs at a certain time point. */ |
866 | struct BS_SCRIPT_EXPORT(m:Particles,pl:true) ParticleBurst |
867 | { |
868 | ParticleBurst() = default; |
869 | ParticleBurst(float time, FloatDistribution count, UINT32 cycles = 1, float interval = 1.0f) |
870 | :time(time), count(std::move(count)), cycles(cycles), interval(interval) |
871 | { } |
872 | |
873 | /** Time at which to trigger the burst, in seconds. */ |
874 | float time = 0.0f; |
875 | |
876 | /** Number of particles to emit when the burst triggers. */ |
877 | FloatDistribution count = 0; |
878 | |
879 | /** |
880 | * Determines how many times to trigger the burst. If 0 the burst will trigger infinitely. Use @p interval to |
881 | * to control the time between each cycle. |
882 | */ |
883 | UINT32 cycles = 1; |
884 | |
885 | /** Controls how much time needs to pass before triggering another burst cycle, in seconds. */ |
886 | float interval = 1.0f; |
887 | }; |
888 | |
889 | /** Handles spawning of new particles using the specified parameters and shape. */ |
890 | class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Particles) ParticleEmitter : public ParticleModule |
891 | { |
892 | public: |
893 | /** Shape over which to emit the particles. */ |
894 | BS_SCRIPT_EXPORT(pr:setter,n:Shape) |
895 | void setShape(SPtr<ParticleEmitterShape> shape) { mShape = std::move(shape); } |
896 | |
897 | /** @copydoc setShape */ |
898 | BS_SCRIPT_EXPORT(pr:getter,n:Shape) |
899 | const SPtr<ParticleEmitterShape>& getShape() const { return mShape; } |
900 | |
901 | /** Determines the number of particles that are emitted every second. */ |
902 | BS_SCRIPT_EXPORT(pr:setter,n:EmissionRate) |
903 | void setEmissionRate(FloatDistribution value) { mEmissionRate = std::move(value); } |
904 | |
905 | /** @copydoc setEmissionRate */ |
906 | BS_SCRIPT_EXPORT(pr:getter,n:EmissionRate) |
907 | const FloatDistribution& getEmissionRate() const { return mEmissionRate; } |
908 | |
909 | /** Determines discrete intervals to emit particles. */ |
910 | BS_SCRIPT_EXPORT(pr:setter,n:EmissionBursts) |
911 | void setEmissionBursts(Vector<ParticleBurst> bursts); |
912 | |
913 | /** @copydoc setEmissionBursts */ |
914 | BS_SCRIPT_EXPORT(pr:getter,n:EmissionBursts) |
915 | const Vector<ParticleBurst>& getEmissionBursts() const { return mBursts; } |
916 | |
917 | /** Determines the lifetime of particles when they are initially spawned, in seconds. */ |
918 | BS_SCRIPT_EXPORT(pr:setter,n:InitialLifetime) |
919 | void setInitialLifetime(FloatDistribution value) { mInitialLifetime = std::move(value); } |
920 | |
921 | /** @copydoc setInitialLifetime */ |
922 | BS_SCRIPT_EXPORT(pr:getter,n:InitialLifetime) |
923 | const FloatDistribution& getInitialLifetime() const { return mInitialLifetime; } |
924 | |
925 | /** |
926 | * Sets the initial speed of the particles, in meters/second. The speed is applied along the particle's velocity |
927 | * direction, which is determined by the emission shape and potentially other properties. |
928 | */ |
929 | BS_SCRIPT_EXPORT(pr:setter,n:InitialSpeed) |
930 | void setInitialSpeed(FloatDistribution value) { mInitialSpeed = std::move(value); } |
931 | |
932 | /** @copydoc setInitialSpeed */ |
933 | BS_SCRIPT_EXPORT(pr:getter,n:InitialSpeed) |
934 | const FloatDistribution& getInitialSpeed() const { return mInitialSpeed; } |
935 | |
936 | /** |
937 | * Determines the size of the particles when initially spawned. The size is applied uniformly in all dimensions. |
938 | * Only used if 3D size is disabled. |
939 | */ |
940 | BS_SCRIPT_EXPORT(pr:setter,n:InitialSize) |
941 | void setInitialSize(FloatDistribution value) { mInitialSize = std::move(value); } |
942 | |
943 | /** @copydoc setInitialSize */ |
944 | BS_SCRIPT_EXPORT(pr:getter,n:InitialSize) |
945 | const FloatDistribution& getInitialSize() const { return mInitialSize; } |
946 | |
947 | /** |
948 | * Determines the size of the particles when initially spawned. Size can be specified for each dimension separately. |
949 | * Only used if 3D size is enabled. |
950 | */ |
951 | BS_SCRIPT_EXPORT(pr:setter,n:InitialSize3D) |
952 | void setInitialSize3D(Vector3Distribution value) { mInitialSize3D = std::move(value); } |
953 | |
954 | /** @copydoc setInitialSize3D */ |
955 | BS_SCRIPT_EXPORT(pr:getter,n:InitialSize3D) |
956 | const Vector3Distribution& getInitialSize3D() const { return mInitialSize3D; } |
957 | |
958 | /** |
959 | * Determines should the initial particle size be applied uniformly (if disabled), or evaluated separately for each |
960 | * dimension (if enabled). |
961 | */ |
962 | BS_SCRIPT_EXPORT(pr:setter,n:Use3DSize) |
963 | void setUse3DSize(bool value) { mUse3DSize = value; } |
964 | |
965 | /** @copydoc setUse3DSize */ |
966 | BS_SCRIPT_EXPORT(pr:getter,n:Use3DSize) |
967 | bool getUse3DSize() const { return mUse3DSize; } |
968 | |
969 | /** |
970 | * Determines the rotation of the particles when initially spawned, in degrees. The rotation is applied around the |
971 | * particle's local Z axis. Only used if 3D rotation is disabled. |
972 | */ |
973 | BS_SCRIPT_EXPORT(pr:setter,n:InitialRotation) |
974 | void setInitialRotation(FloatDistribution value) { mInitialRotation = std::move(value); } |
975 | |
976 | /** @copydoc setInitialRotation */ |
977 | BS_SCRIPT_EXPORT(pr:getter,n:InitialRotation) |
978 | const FloatDistribution& getInitialRotation() const { return mInitialRotation; } |
979 | |
980 | /** |
981 | * Determines the rotation of the particles when initially spawned, in Euler angles. Only used if 3D rotation is |
982 | * enabled. |
983 | */ |
984 | BS_SCRIPT_EXPORT(pr:setter,n:InitialRotation3D) |
985 | void setInitialRotation3D(Vector3Distribution value) { mInitialRotation3D = std::move(value); } |
986 | |
987 | /** @copydoc setInitialRotation3D */ |
988 | BS_SCRIPT_EXPORT(pr:getter,n:InitialRotation3D) |
989 | const Vector3Distribution& getInitialRotation3D() const { return mInitialRotation3D; } |
990 | |
991 | /** |
992 | * Determines should the initial particle rotation be a single angle applied around a Z axis (if disabled), or a |
993 | * set of Euler angles that allow you to rotate around every axis (if enabled). |
994 | */ |
995 | BS_SCRIPT_EXPORT(pr:setter,n:Use3DRotation) |
996 | void setUse3DRotation(bool value) { mUse3DRotation = value; } |
997 | |
998 | /** @copydoc setUse3DRotation */ |
999 | BS_SCRIPT_EXPORT(pr:getter,n:Use3DRotation) |
1000 | bool getUse3DRotation() const { return mUse3DRotation; } |
1001 | |
1002 | /** Determines the initial color (in RGB channels) and transparency (in A channel) of particles. */ |
1003 | BS_SCRIPT_EXPORT(pr:setter,n:InitialColor) |
1004 | void setInitialColor(const ColorDistribution& value) { mInitialColor = value; } |
1005 | |
1006 | /** @copydoc setInitialColor */ |
1007 | BS_SCRIPT_EXPORT(pr:getter,n:InitialColor) |
1008 | const ColorDistribution& getInitialColor() const { return mInitialColor; } |
1009 | |
1010 | /** |
1011 | * Determines a range of values determining a random offset to apply to particle position after it has been emitted. |
1012 | * Offset will be randomly selected in all three axes in range [-value, value]. |
1013 | */ |
1014 | BS_SCRIPT_EXPORT(pr:setter,n:RandomOffset) |
1015 | void setRandomOffset(float value) { mRandomOffset = value; } |
1016 | |
1017 | /** @copydoc setRandomOffset */ |
1018 | BS_SCRIPT_EXPORT(pr:getter,n:RandomOffset) |
1019 | float getRandomOffset() const { return mRandomOffset; } |
1020 | |
1021 | /** |
1022 | * Determines should particle U texture coordinate be randomly flipped, mirroring the image. The value represents |
1023 | * a percent of particles that should be flipped, in range [0, 1]. |
1024 | */ |
1025 | BS_SCRIPT_EXPORT(pr:setter,n:FlipU) |
1026 | void setFlipU(float value) { mFlipU = Math::clamp01(value); } |
1027 | |
1028 | /** @copydoc setFlipU */ |
1029 | BS_SCRIPT_EXPORT(pr:getter,n:FlipU) |
1030 | float getFlipU() const { return mFlipU; } |
1031 | |
1032 | /** |
1033 | * Determines should particle V texture coordinate be randomly flipped, mirroring the image. The value represents |
1034 | * a percent of particles that should be flipped, in range [0, 1]. |
1035 | */ |
1036 | BS_SCRIPT_EXPORT(pr:setter,n:FlipV) |
1037 | void setFlipV(float value) { mFlipV = Math::clamp01(value); } |
1038 | |
1039 | /** @copydoc setFlipV */ |
1040 | BS_SCRIPT_EXPORT(pr:getter,n:FlipV) |
1041 | float getFlipV() const { return mFlipV; } |
1042 | |
1043 | /** Creates a new emitter. */ |
1044 | BS_SCRIPT_EXPORT(ec:T) |
1045 | static SPtr<ParticleEmitter> create(); |
1046 | private: |
1047 | friend class ParticleSystem; |
1048 | |
1049 | /** |
1050 | * Spawns new particles in the specified time increment (if any). |
1051 | * |
1052 | * @param[in] random Random number generator. |
1053 | * @param[in] state Various per-frame information provided by the parent particle system. |
1054 | * @param[in] set Set to which to append new particles to. |
1055 | */ |
1056 | void spawn(Random& random, const ParticleSystemState& state, ParticleSet& set) const; |
1057 | |
1058 | /** |
1059 | * Spawns the specified number of particles. |
1060 | * |
1061 | * @param[in] count Number of particles to spawn. |
1062 | * @param[in] random Random number generator. |
1063 | * @param[in] state Various per-frame information provided by the parent particle system. |
1064 | * @param[in] set Set to which to append new particles to. |
1065 | * @param[in] spacing When false all particles will use the current emitter time. When true the particles |
1066 | * will be assigned a time between current time and time step end time, so they are |
1067 | * unifomly distributed in this time range. |
1068 | * @return Actual number of spawned particles. |
1069 | */ |
1070 | UINT32 spawn(UINT32 count, Random& random, const ParticleSystemState& state, ParticleSet& set, bool spacing) const; |
1071 | |
1072 | // User-visible properties |
1073 | SPtr<ParticleEmitterShape> mShape; |
1074 | |
1075 | FloatDistribution mEmissionRate = 50.0f; |
1076 | Vector<ParticleBurst> mBursts; |
1077 | |
1078 | FloatDistribution mInitialLifetime = 10.0f; |
1079 | FloatDistribution mInitialSpeed = 1.0f; |
1080 | |
1081 | FloatDistribution mInitialSize = 0.1f; |
1082 | Vector3Distribution mInitialSize3D = Vector3::ONE; |
1083 | bool mUse3DSize = false; |
1084 | |
1085 | FloatDistribution mInitialRotation = 0.0f; |
1086 | Vector3Distribution mInitialRotation3D = Vector3::ZERO; |
1087 | bool mUse3DRotation = false; |
1088 | |
1089 | ColorDistribution mInitialColor = Color::White; |
1090 | |
1091 | float mFlipU = 0.0f; |
1092 | float mFlipV = 0.0f; |
1093 | |
1094 | float mRandomOffset = 0.0f; |
1095 | |
1096 | // Internal state |
1097 | mutable float mEmitAccumulator = 0.0f; |
1098 | mutable Vector<float> mBurstAccumulator; |
1099 | |
1100 | /************************************************************************/ |
1101 | /* RTTI */ |
1102 | /************************************************************************/ |
1103 | public: |
1104 | friend class ParticleEmitterRTTI; |
1105 | static RTTITypeBase* getRTTIStatic(); |
1106 | RTTITypeBase* getRTTI() const override; |
1107 | }; |
1108 | |
1109 | /** @} */ |
1110 | |
1111 | } |
1112 | |