1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #ifndef LOVE_GRAPHICS_PARTICLE_SYSTEM_H
22 #define LOVE_GRAPHICS_PARTICLE_SYSTEM_H
23 
24 // LOVE
25 #include "common/int.h"
26 #include "common/math.h"
27 #include "common/Vector.h"
28 #include "Drawable.h"
29 #include "Color.h"
30 #include "Quad.h"
31 #include "Texture.h"
32 
33 // STL
34 #include <vector>
35 
36 namespace love
37 {
38 namespace graphics
39 {
40 
41 /**
42  * A class for creating, moving and drawing particles.
43  * A big thanks to bobthebloke.org
44  **/
45 class ParticleSystem : public Drawable
46 {
47 public:
48 	/**
49 	 * Type of distribution new particles are drawn from: None, uniform, normal, ellipse.
50 	 */
51 	enum AreaSpreadDistribution
52 	{
53 		DISTRIBUTION_NONE,
54 		DISTRIBUTION_UNIFORM,
55 		DISTRIBUTION_NORMAL,
56 		DISTRIBUTION_ELLIPSE,
57 		DISTRIBUTION_MAX_ENUM
58 	};
59 
60 	/**
61 	 * Insertion modes of new particles in the list: top, bottom, random.
62 	 */
63 	enum InsertMode
64 	{
65 		INSERT_MODE_TOP,
66 		INSERT_MODE_BOTTOM,
67 		INSERT_MODE_RANDOM,
68 		INSERT_MODE_MAX_ENUM
69 	};
70 
71 	/**
72 	 * Maximum numbers of particles in a ParticleSystem.
73 	 * This limit comes from the fact that a quad requires four vertices and the
74 	 * OpenGL API where GLsizei is a signed int.
75 	 **/
76 	static const uint32 MAX_PARTICLES = LOVE_INT32_MAX / 4;
77 
78 	/**
79 	 * Creates a particle system with the specified buffer size and texture.
80 	 **/
81 	ParticleSystem(Texture *texture, uint32 buffer);
82 	ParticleSystem(const ParticleSystem &p);
83 
84 	/**
85 	 * Deletes any allocated memory.
86 	 **/
87 	virtual ~ParticleSystem();
88 
89 	/**
90 	 * Creates an identical copy of this ParticleSystem. The clone does not
91 	 * duplicate any existing particles from this ParticleSystem, just the
92 	 * settable parameters.
93 	 **/
94 	virtual ParticleSystem *clone() = 0;
95 
96 	/**
97 	 * Sets the texture used in the particle system.
98 	 * @param texture The new texture.
99 	 **/
100 	void setTexture(Texture *texture);
101 
102 	/**
103 	 * Returns the texture used when drawing the particle system.
104 	 **/
105 	Texture *getTexture() const;
106 
107 	/**
108 	 * Clears the current buffer and allocates the appropriate amount of space for the buffer.
109 	 * @param size The new buffer size.
110 	 **/
111 	virtual void setBufferSize(uint32 size);
112 
113 	/**
114 	 * Returns the total amount of particles this ParticleSystem can have active
115 	 * at any given point in time.
116 	 **/
117 	uint32 getBufferSize() const;
118 
119 	/**
120 	 * Sets the insert mode for new particles.
121 	 * @param mode The new insert mode.
122 	 */
123 	void setInsertMode(InsertMode mode);
124 
125 	/**
126 	 * Returns the current insert mode.
127 	 */
128 	InsertMode getInsertMode() const;
129 
130 	/**
131 	 * Sets the emission rate.
132 	 * @param rate The amount of particles per second.
133 	 **/
134 	void setEmissionRate(float rate);
135 
136 	/**
137 	 * Returns the number of particles created per second.
138 	 **/
139 	float getEmissionRate() const;
140 
141 	/**
142 	 * Sets the lifetime of the particle emitter (-1 means eternal)
143 	 * @param life The lifetime (in seconds).
144 	 **/
145 	void setEmitterLifetime(float life);
146 
147 	/**
148 	 * Returns the lifetime of the particle emitter.
149 	 **/
150 	float getEmitterLifetime() const;
151 
152 	/**
153 	 * Sets the life range of the particles.
154 	 * @param min The minimum life.
155 	 * @param max The maximum life (if 0, then becomes the same as minimum life).
156 	 **/
157 	void setParticleLifetime(float min, float max = 0);
158 
159 	/**
160 	 * Gets the lifetime of a particle.
161 	 * @param[out] min The minimum life.
162 	 * @param[out] max The maximum life.
163 	 **/
164 	void getParticleLifetime(float &min, float &max) const;
165 
166 	/**
167 	 * Sets the position of the center of the emitter.
168 	 * Used to move the emitter without changing the position of already existing particles.
169 	 * @param x The x-coordinate.
170 	 * @param y The y-coordinate.
171 	 **/
172 	void setPosition(float x, float y);
173 
174 	/**
175 	 * Returns the position of the emitter.
176 	 **/
177 	const love::Vector &getPosition() const;
178 
179 	/**
180 	 * Moves the position of the center of the emitter.
181 	 * When update is called, newly spawned particles will appear in a line
182 	 * between the old emitter position and where the emitter was moved to,
183 	 * resulting in a smoother-feeling particle system if moveTo is called
184 	 * repeatedly.
185 	 **/
186 	void moveTo(float x, float y);
187 
188 	/**
189 	 * Sets the emission area spread parameters and distribution type. The interpretation of
190 	 * the parameters depends on the distribution type:
191 	 *
192 	 * * None:    Parameters are ignored. No area spread.
193 	 * * Uniform: Parameters denote maximal (symmetric) displacement from emitter position.
194 	 * * Normal:  Parameters denote the standard deviation in x and y direction. x and y are assumed to be uncorrelated.
195 	 * @param x First parameter. Interpretation depends on distribution type.
196 	 * @param y Second parameter. Interpretation depends on distribution type.
197 	 * @param distribution Distribution type
198 	 **/
199 	void setAreaSpread(AreaSpreadDistribution distribution, float x, float y);
200 
201 	/**
202 	 * Returns area spread distribution type.
203 	 **/
204 	AreaSpreadDistribution getAreaSpreadDistribution() const;
205 
206 	/**
207 	 * Returns area spread parameters.
208 	 **/
209 	const love::Vector &getAreaSpreadParameters() const;
210 
211 	/**
212 	 * Sets the direction of the particle emitter.
213 	 * @param direction The direction (in degrees).
214 	 **/
215 	void setDirection(float direction);
216 
217 	/**
218 	 * Returns the direction of the particle emitter (in radians).
219 	 **/
220 	float getDirection() const;
221 
222 	/**
223 	 * Sets the spread of the particle emitter.
224 	 * @param spread The spread (in radians).
225 	 **/
226 	void setSpread(float spread);
227 
228 	/**
229 	 * Returns the directional spread of the emitter (in radians).
230 	 **/
231 	float getSpread() const;
232 
233 	/**
234 	 * Sets the speed of the particles.
235 	 * @param speed The speed.
236 	 **/
237 	void setSpeed(float speed);
238 
239 	/**
240 	 * Sets the speed of the particles.
241 	 * @param min The minimum speed.
242 	 * @param max The maximum speed.
243 	 **/
244 	void setSpeed(float min, float max);
245 
246 	/**
247 	 * Gets the speed of the particles.
248 	 * @param[out] min The minimum speed.
249 	 * @param[out] max The maximum speed.
250 	 **/
251 	void getSpeed(float &min, float &max) const;
252 
253 	/**
254 	 * Sets the linear acceleration (the acceleration along the x and y axes).
255 	 * @param x The acceleration along the x-axis.
256 	 * @param y The acceleration along the y-axis.
257 	 **/
258 	void setLinearAcceleration(float x, float y);
259 
260 	/**
261 	 * Sets the linear acceleration (the acceleration along the x and y axes).
262 	 * @param xmin The minimum amount of acceleration along the x-axis.
263 	 * @param ymin The minimum amount of acceleration along the y-axis.
264 	 * @param xmax The maximum amount of acceleration along the x-axis.
265 	 * @param ymax The maximum amount of acceleration along the y-axis.
266 	 **/
267 	void setLinearAcceleration(float xmin, float ymin, float xmax, float ymax);
268 
269 	/**
270 	 * Gets the linear acceleration of the particles.
271 	 * @param[out] min The minimum acceleration.
272 	 * @param[out] max The maximum acceleration.
273 	 **/
274 	void getLinearAcceleration(love::Vector &min, love::Vector &max) const;
275 
276 	/**
277 	 * Sets the radial acceleration (the acceleration towards the particle emitter).
278 	 * @param acceleration The amount of acceleration.
279 	 **/
280 	void setRadialAcceleration(float acceleration);
281 
282 	/**
283 	 * Sets the radial acceleration (the acceleration towards the particle emitter).
284 	 * @param min The minimum acceleration.
285 	 * @param max The maximum acceleration.
286 	 **/
287 	void setRadialAcceleration(float min, float max);
288 
289 	/**
290 	 * Gets the radial acceleration.
291 	 * @param[out] min The minimum amount of radial acceleration.
292 	 * @param[out] max The maximum amount of radial acceleration.
293 	 **/
294 	void getRadialAcceleration(float &min, float &max) const;
295 
296 	/**
297 	 * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction).
298 	 * @param acceleration The amount of acceleration.
299 	 **/
300 	void setTangentialAcceleration(float acceleration);
301 
302 	/**
303 	 * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction).
304 	 * @param min The minimum acceleration.
305 	 * @param max The maximum acceleration.
306 	 **/
307 	void setTangentialAcceleration(float min, float max);
308 
309 	/**
310 	 * Gets the tangential acceleration.
311 	 * @param[out] min The minimum tangential acceleration.
312 	 * @param[out] max The maximum tangential acceleration.
313 	 **/
314 	void getTangentialAcceleration(float &min, float &max) const;
315 
316 	/**
317 	 * Sets the amount of linear damping. Damping reduces the velocity of
318 	 * particles over time. A value of 0 corresponds to no damping.
319 	 **/
320 	void setLinearDamping(float min, float max);
321 
322 	/**
323 	 * Gets the current amount of linear damping.
324 	 **/
325 	void getLinearDamping(float &min, float &max) const;
326 
327 	/**
328 	 * Sets the size of the sprite (1.0 being the default size).
329 	 * @param size The size of the sprite.
330 	 **/
331 	void setSize(float size);
332 
333 	/**
334 	 * Sets the sizes of the sprite upon creation and upon death (1.0 being the default size).
335 	 * @param newSizes Array of sizes
336 	 **/
337 	void setSizes(const std::vector<float> &newSizes);
338 
339 	/**
340 	 * Returns the sizes of the particle sprites.
341 	 **/
342 	const std::vector<float> &getSizes() const;
343 
344 	/**
345 	 * Sets the amount of variation to the sprite's beginning size (0 being no variation and 1.0 a random size between start and end).
346 	 * @param variation The amount of variation.
347 	 **/
348 	void setSizeVariation(float variation);
349 
350 	/**
351 	 * Returns the amount of initial size variation between particles.
352 	 **/
353 	float getSizeVariation() const;
354 
355 	/**
356 	 * Sets the amount of rotation a sprite starts out with.
357 	 * @param rotation The amount of rotation.
358 	 **/
359 	void setRotation(float rotation);
360 
361 	/**
362 	 * Sets the amount of rotation a sprite starts out with (a random value between min and max).
363 	 * @param min The minimum amount of rotation.
364 	 * @param max The maximum amount of rotation.
365 	 **/
366 	void setRotation(float min, float max);
367 
368 	/**
369 	 * Gets the initial amount of rotation of a particle, in radians.
370 	 * @param[out] min The minimum initial rotation.
371 	 * @param[out] max The maximum initial rotation.
372 	 **/
373 	void getRotation(float &min, float &max) const;
374 
375 	/**
376 	 * Sets the spin of the sprite.
377 	 * @param spin The spin of the sprite (in degrees).
378 	 **/
379 	void setSpin(float spin);
380 
381 	/**
382 	 * Sets the spin of the sprite upon particle creation and death.
383 	 * @param start The spin of the sprite upon creation (in radians / second).
384 	 * @param end The spin of the sprite upon death (in radians / second).
385 	 **/
386 	void setSpin(float start, float end);
387 
388 	/**
389 	 * Gets the amount of spin of a particle during its lifetime.
390 	 * @param[out] start The initial spin, in radians / s.
391 	 * @param[out] end The final spin, in radians / s.
392 	 **/
393 	void getSpin(float &start, float &end) const;
394 
395 	/**
396 	 * Sets the variation of the start spin (0 being no variation and 1 being a random spin between start and end).
397 	 * @param variation The variation.
398 	 **/
399 	void setSpinVariation(float variation);
400 
401 	/**
402 	 * Returns the amount of variation of the start spin of a particle.
403 	 **/
404 	float getSpinVariation() const;
405 
406 	/**
407 	 * Sets the particles' offsets for rotation.
408 	 * @param x The x offset.
409 	 * @param y The y offset.
410 	 **/
411 	void setOffset(float x, float y);
412 
413 	/**
414 	 * Returns of the particle offset.
415 	 **/
416 	love::Vector getOffset() const;
417 
418 	/**
419 	 * Sets the color of the particles.
420 	 * @param newColors Array of colors
421 	 **/
422 	void setColor(const std::vector<Colorf> &newColors);
423 
424 	/**
425 	 * Returns the color of the particles.
426 	 **/
427 	std::vector<Colorf> getColor() const;
428 
429 	/**
430 	 * Sets a list of Quads to use for particles over their lifetime.
431 	 **/
432 	void setQuads(const std::vector<Quad *> &newQuads);
433 	void setQuads();
434 
435 	/**
436 	 * Gets the Quads used when drawing the particles.
437 	 **/
438 	std::vector<Quad *> getQuads() const;
439 
440 	/**
441 	 * sets whether particle angles & rotations are relative to their velocities.
442 	 **/
443 	void setRelativeRotation(bool enable);
444 	bool hasRelativeRotation() const;
445 
446 	/**
447 	 * Returns the amount of particles that are currently active in the system.
448 	 **/
449 	uint32 getCount() const;
450 
451 	/**
452 	 * Starts/resumes the particle emitter.
453 	 **/
454 	void start();
455 
456 	/**
457 	 * Stops the particle emitter and resets.
458 	 **/
459 	void stop();
460 
461 	/**
462 	 * Pauses the particle emitter.
463 	 **/
464 	void pause();
465 
466 	/**
467 	 * Resets the particle emitter.
468 	 **/
469 	void reset();
470 
471 	/**
472 	 * Instantly emits a number of particles.
473 	 * @param num The number of particles to emit.
474 	 **/
475 	void emit(uint32 num);
476 
477 	/**
478 	 * Returns whether the particle emitter is active.
479 	 **/
480 	bool isActive() const;
481 
482 	/**
483 	 * Returns whether the particle emitter is paused.
484 	 **/
485 	bool isPaused() const;
486 
487 	bool isStopped() const;
488 
489 	/**
490 	 * Returns whether the particle system is empty of particles or not.
491 	 **/
492 	bool isEmpty() const;
493 
494 	/**
495 	 * Returns whether the amount of particles has reached the buffer limit or not.
496 	 **/
497 	bool isFull() const;
498 
499 	/**
500 	 * Updates the particle system.
501 	 * @param dt Time since last update.
502 	 **/
503 	void update(float dt);
504 
505 	static bool getConstant(const char *in, AreaSpreadDistribution &out);
506 	static bool getConstant(AreaSpreadDistribution in, const char *&out);
507 
508 	static bool getConstant(const char *in, InsertMode &out);
509 	static bool getConstant(InsertMode in, const char *&out);
510 
511 protected:
512 
513 	// Represents a single particle.
514 	struct Particle
515 	{
516 		Particle *prev;
517 		Particle *next;
518 
519 		float lifetime;
520 		float life;
521 
522 		love::Vector position;
523 
524 		// Particles gravitate towards this point.
525 		love::Vector origin;
526 
527 		love::Vector velocity;
528 		love::Vector linearAcceleration;
529 		float radialAcceleration;
530 		float tangentialAcceleration;
531 
532 		float linearDamping;
533 
534 		float size;
535 		float sizeOffset;
536 		float sizeIntervalSize;
537 
538 		float rotation; // Amount of rotation applied to the final angle.
539 		float angle;
540 		float spinStart;
541 		float spinEnd;
542 
543 		Colorf color;
544 
545 		int quadIndex;
546 	};
547 
548 	// Pointer to the beginning of the allocated memory.
549 	Particle *pMem;
550 
551 	// Pointer to a free particle.
552 	Particle *pFree;
553 
554 	// Pointer to the start of the linked list.
555 	Particle *pHead;
556 
557 	// Pointer to the end of the linked list.
558 	Particle *pTail;
559 
560 	// The texture to be drawn.
561 	StrongRef<Texture> texture;
562 
563 	// Whether the particle emitter is active.
564 	bool active;
565 
566 	// Insert mode of new particles.
567 	InsertMode insertMode;
568 
569 	// The maximum number of particles.
570 	uint32 maxParticles;
571 
572 	// The number of active particles.
573 	uint32 activeParticles;
574 
575 	// The emission rate (particles/sec).
576 	float emissionRate;
577 
578 	// Used to determine when a particle should be emitted.
579 	float emitCounter;
580 
581 	// The relative position of the particle emitter.
582 	love::Vector position;
583 	love::Vector prevPosition;
584 
585 	// Emission area spread.
586 	AreaSpreadDistribution areaSpreadDistribution;
587 	love::Vector areaSpread;
588 
589 	// The lifetime of the particle emitter (-1 means infinite) and the life it has left.
590 	float lifetime;
591 	float life;
592 
593 	// The particle life.
594 	float particleLifeMin;
595 	float particleLifeMax;
596 
597 	// The direction (and spread) the particles will be emitted in. Measured in radians.
598 	float direction;
599 	float spread;
600 
601 	// The speed.
602 	float speedMin;
603 	float speedMax;
604 
605 	// Acceleration along the x and y axes.
606 	love::Vector linearAccelerationMin;
607 	love::Vector linearAccelerationMax;
608 
609 	// Acceleration towards the emitter's center
610 	float radialAccelerationMin;
611 	float radialAccelerationMax;
612 
613 	// Acceleration perpendicular to the particle's direction.
614 	float tangentialAccelerationMin;
615 	float tangentialAccelerationMax;
616 
617 	float linearDampingMin;
618 	float linearDampingMax;
619 
620 	// Size.
621 	std::vector<float> sizes;
622 	float sizeVariation;
623 
624 	// Rotation
625 	float rotationMin;
626 	float rotationMax;
627 
628 	// Spin.
629 	float spinStart;
630 	float spinEnd;
631 	float spinVariation;
632 
633 	// Offsets
634 	love::Vector offset;
635 
636 	// Is the ParticleSystem using a default offset?
637 	bool defaultOffset;
638 
639 	// Color.
640 	std::vector<Colorf> colors;
641 
642 	// Quads.
643 	std::vector<StrongRef<Quad>> quads;
644 
645 	bool relativeRotation;
646 
647 private:
648 
649 	void resetOffset();
650 
651 	void createBuffers(size_t size);
652 	void deleteBuffers();
653 
654 	void addParticle(float t);
655 	Particle *removeParticle(Particle *p);
656 
657 	// Called by addParticle.
658 	void initParticle(Particle *p, float t);
659 	void insertTop(Particle *p);
660 	void insertBottom(Particle *p);
661 	void insertRandom(Particle *p);
662 
663 	static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];
664 	static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM> distributions;
665 
666 	static StringMap<InsertMode, INSERT_MODE_MAX_ENUM>::Entry insertModesEntries[];
667 	static StringMap<InsertMode, INSERT_MODE_MAX_ENUM> insertModes;
668 };
669 
670 } // graphics
671 } // love
672 
673 #endif // LOVE_GRAPHICS_PARTICLE_SYSTEM_H
674