ParticleSystem.h 18 KB

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