ParticleSystem.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /**
  2. * Copyright (c) 2006-2017 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(Graphics *gfx, 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. virtual ParticleSystem *clone() = 0;
  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. virtual 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 x First parameter. Interpretation depends on distribution type.
  177. * @param y Second parameter. Interpretation depends on distribution type.
  178. * @param distribution Distribution type
  179. **/
  180. void setAreaSpread(AreaSpreadDistribution distribution, float x, float y);
  181. /**
  182. * Returns area spread distribution type.
  183. **/
  184. AreaSpreadDistribution getAreaSpreadDistribution() const;
  185. /**
  186. * Returns area spread parameters.
  187. **/
  188. const love::Vector2 &getAreaSpreadParameters() const;
  189. /**
  190. * Returns the angle of the area distribution (in radians).
  191. **/
  192. float getAreaSpreadAngle() const;
  193. /**
  194. * Sets the angle of the area distribution
  195. * @param angle The angle (in radians).
  196. **/
  197. void setAreaSpreadAngle(float angle);
  198. /**
  199. * Returns true if particles spawn relative to the center of the
  200. * shape area or false if they will use the setDirection parameter
  201. **/
  202. bool getAreaSpreadIsRelativeDirection() const;
  203. /**
  204. * Sets if particles starting direction is away from the center of the
  205. * area spread or the setDirection parameter
  206. * @param isRelativeDirection boolean use relative direction from center
  207. **/
  208. void setAreaSpreadIsRelativeDirection(bool isRelativeDirection);
  209. /**
  210. * Sets the direction of the particle emitter.
  211. * @param direction The direction (in degrees).
  212. **/
  213. void setDirection(float direction);
  214. /**
  215. * Returns the direction of the particle emitter (in radians).
  216. **/
  217. float getDirection() const;
  218. /**
  219. * Sets the spread of the particle emitter.
  220. * @param spread The spread (in radians).
  221. **/
  222. void setSpread(float spread);
  223. /**
  224. * Returns the directional spread of the emitter (in radians).
  225. **/
  226. float getSpread() const;
  227. /**
  228. * Sets the speed of the particles.
  229. * @param speed The speed.
  230. **/
  231. void setSpeed(float speed);
  232. /**
  233. * Sets the speed of the particles.
  234. * @param min The minimum speed.
  235. * @param max The maximum speed.
  236. **/
  237. void setSpeed(float min, float max);
  238. /**
  239. * Gets the speed of the particles.
  240. * @param[out] min The minimum speed.
  241. * @param[out] max The maximum speed.
  242. **/
  243. void getSpeed(float &min, float &max) const;
  244. /**
  245. * Sets the linear acceleration (the acceleration along the x and y axes).
  246. * @param x The acceleration along the x-axis.
  247. * @param y The acceleration along the y-axis.
  248. **/
  249. void setLinearAcceleration(float x, float y);
  250. /**
  251. * Sets the linear acceleration (the acceleration along the x and y axes).
  252. * @param xmin The minimum amount of acceleration along the x-axis.
  253. * @param ymin The minimum amount of acceleration along the y-axis.
  254. * @param xmax The maximum amount of acceleration along the x-axis.
  255. * @param ymax The maximum amount of acceleration along the y-axis.
  256. **/
  257. void setLinearAcceleration(float xmin, float ymin, float xmax, float ymax);
  258. /**
  259. * Gets the linear acceleration of the particles.
  260. * @param[out] min The minimum acceleration.
  261. * @param[out] max The maximum acceleration.
  262. **/
  263. void getLinearAcceleration(love::Vector2 &min, love::Vector2 &max) const;
  264. /**
  265. * Sets the radial acceleration (the acceleration towards the particle emitter).
  266. * @param acceleration The amount of acceleration.
  267. **/
  268. void setRadialAcceleration(float acceleration);
  269. /**
  270. * Sets the radial acceleration (the acceleration towards the particle emitter).
  271. * @param min The minimum acceleration.
  272. * @param max The maximum acceleration.
  273. **/
  274. void setRadialAcceleration(float min, float max);
  275. /**
  276. * Gets the radial acceleration.
  277. * @param[out] min The minimum amount of radial acceleration.
  278. * @param[out] max The maximum amount of radial acceleration.
  279. **/
  280. void getRadialAcceleration(float &min, float &max) const;
  281. /**
  282. * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction).
  283. * @param acceleration The amount of acceleration.
  284. **/
  285. void setTangentialAcceleration(float acceleration);
  286. /**
  287. * Sets the tangential acceleration (the acceleration perpendicular to the particle's direction).
  288. * @param min The minimum acceleration.
  289. * @param max The maximum acceleration.
  290. **/
  291. void setTangentialAcceleration(float min, float max);
  292. /**
  293. * Gets the tangential acceleration.
  294. * @param[out] min The minimum tangential acceleration.
  295. * @param[out] max The maximum tangential acceleration.
  296. **/
  297. void getTangentialAcceleration(float &min, float &max) const;
  298. /**
  299. * Sets the amount of linear damping. Damping reduces the velocity of
  300. * particles over time. A value of 0 corresponds to no damping.
  301. **/
  302. void setLinearDamping(float min, float max);
  303. /**
  304. * Gets the current amount of linear damping.
  305. **/
  306. void getLinearDamping(float &min, float &max) const;
  307. /**
  308. * Sets the size of the sprite (1.0 being the default size).
  309. * @param size The size of the sprite.
  310. **/
  311. void setSize(float size);
  312. /**
  313. * Sets the sizes of the sprite upon creation and upon death (1.0 being the default size).
  314. * @param newSizes Array of sizes
  315. **/
  316. void setSizes(const std::vector<float> &newSizes);
  317. /**
  318. * Returns the sizes of the particle sprites.
  319. **/
  320. const std::vector<float> &getSizes() const;
  321. /**
  322. * 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).
  323. * @param variation The amount of variation.
  324. **/
  325. void setSizeVariation(float variation);
  326. /**
  327. * Returns the amount of initial size variation between particles.
  328. **/
  329. float getSizeVariation() const;
  330. /**
  331. * Sets the amount of rotation a sprite starts out with.
  332. * @param rotation The amount of rotation.
  333. **/
  334. void setRotation(float rotation);
  335. /**
  336. * Sets the amount of rotation a sprite starts out with (a random value between min and max).
  337. * @param min The minimum amount of rotation.
  338. * @param max The maximum amount of rotation.
  339. **/
  340. void setRotation(float min, float max);
  341. /**
  342. * Gets the initial amount of rotation of a particle, in radians.
  343. * @param[out] min The minimum initial rotation.
  344. * @param[out] max The maximum initial rotation.
  345. **/
  346. void getRotation(float &min, float &max) const;
  347. /**
  348. * Sets the spin of the sprite.
  349. * @param spin The spin of the sprite (in degrees).
  350. **/
  351. void setSpin(float spin);
  352. /**
  353. * Sets the spin of the sprite upon particle creation and death.
  354. * @param start The spin of the sprite upon creation (in radians / second).
  355. * @param end The spin of the sprite upon death (in radians / second).
  356. **/
  357. void setSpin(float start, float end);
  358. /**
  359. * Gets the amount of spin of a particle during its lifetime.
  360. * @param[out] start The initial spin, in radians / s.
  361. * @param[out] end The final spin, in radians / s.
  362. **/
  363. void getSpin(float &start, float &end) const;
  364. /**
  365. * Sets the variation of the start spin (0 being no variation and 1 being a random spin between start and end).
  366. * @param variation The variation.
  367. **/
  368. void setSpinVariation(float variation);
  369. /**
  370. * Returns the amount of variation of the start spin of a particle.
  371. **/
  372. float getSpinVariation() const;
  373. /**
  374. * Sets the particles' offsets for rotation.
  375. * @param x The x offset.
  376. * @param y The y offset.
  377. **/
  378. void setOffset(float x, float y);
  379. /**
  380. * Returns of the particle offset.
  381. **/
  382. love::Vector2 getOffset() const;
  383. /**
  384. * Sets the color of the particles.
  385. * @param newColors Array of colors
  386. **/
  387. void setColor(const std::vector<Colorf> &newColors);
  388. /**
  389. * Returns the color of the particles.
  390. **/
  391. std::vector<Colorf> getColor() const;
  392. /**
  393. * Sets a list of Quads to use for particles over their lifetime.
  394. **/
  395. void setQuads(const std::vector<Quad *> &newQuads);
  396. void setQuads();
  397. /**
  398. * Gets the Quads used when drawing the particles.
  399. **/
  400. std::vector<Quad *> getQuads() const;
  401. /**
  402. * sets whether particle angles & rotations are relative to their velocities.
  403. **/
  404. void setRelativeRotation(bool enable);
  405. bool hasRelativeRotation() const;
  406. /**
  407. * Returns the amount of particles that are currently active in the system.
  408. **/
  409. uint32 getCount() const;
  410. /**
  411. * Starts/resumes the particle emitter.
  412. **/
  413. void start();
  414. /**
  415. * Stops the particle emitter and resets.
  416. **/
  417. void stop();
  418. /**
  419. * Pauses the particle emitter.
  420. **/
  421. void pause();
  422. /**
  423. * Resets the particle emitter.
  424. **/
  425. void reset();
  426. /**
  427. * Instantly emits a number of particles.
  428. * @param num The number of particles to emit.
  429. **/
  430. void emit(uint32 num);
  431. /**
  432. * Returns whether the particle emitter is active.
  433. **/
  434. bool isActive() const;
  435. /**
  436. * Returns whether the particle emitter is paused.
  437. **/
  438. bool isPaused() const;
  439. bool isStopped() const;
  440. /**
  441. * Returns whether the particle system is empty of particles or not.
  442. **/
  443. bool isEmpty() const;
  444. /**
  445. * Returns whether the amount of particles has reached the buffer limit or not.
  446. **/
  447. bool isFull() const;
  448. /**
  449. * Updates the particle system.
  450. * @param dt Time since last update.
  451. **/
  452. void update(float dt);
  453. // Implements Drawable.
  454. void draw(Graphics *gfx, const Matrix4 &m) override;
  455. static bool getConstant(const char *in, AreaSpreadDistribution &out);
  456. static bool getConstant(AreaSpreadDistribution in, const char *&out);
  457. static bool getConstant(const char *in, InsertMode &out);
  458. static bool getConstant(InsertMode in, const char *&out);
  459. protected:
  460. // Represents a single particle.
  461. struct Particle
  462. {
  463. Particle *prev;
  464. Particle *next;
  465. float lifetime;
  466. float life;
  467. love::Vector2 position;
  468. // Particles gravitate towards this point.
  469. love::Vector2 origin;
  470. love::Vector2 velocity;
  471. love::Vector2 linearAcceleration;
  472. float radialAcceleration;
  473. float tangentialAcceleration;
  474. float linearDamping;
  475. float size;
  476. float sizeOffset;
  477. float sizeIntervalSize;
  478. float rotation; // Amount of rotation applied to the final angle.
  479. float angle;
  480. float spinStart;
  481. float spinEnd;
  482. Colorf color;
  483. int quadIndex;
  484. };
  485. virtual void drawInternal() const = 0;
  486. // Pointer to the beginning of the allocated memory.
  487. Particle *pMem;
  488. // Pointer to a free particle.
  489. Particle *pFree;
  490. // Pointer to the start of the linked list.
  491. Particle *pHead;
  492. // Pointer to the end of the linked list.
  493. Particle *pTail;
  494. // The texture to be drawn.
  495. StrongRef<Texture> texture;
  496. // Whether the particle emitter is active.
  497. bool active;
  498. // Insert mode of new particles.
  499. InsertMode insertMode;
  500. // The maximum number of particles.
  501. uint32 maxParticles;
  502. // The number of active particles.
  503. uint32 activeParticles;
  504. // The emission rate (particles/sec).
  505. float emissionRate;
  506. // Used to determine when a particle should be emitted.
  507. float emitCounter;
  508. // The relative position of the particle emitter.
  509. love::Vector2 position;
  510. love::Vector2 prevPosition;
  511. // Emission area spread.
  512. AreaSpreadDistribution areaSpreadDistribution;
  513. love::Vector2 areaSpread;
  514. float areaSpreadAngle;
  515. bool areaSpreadIsRelativeDirection;
  516. // The lifetime of the particle emitter (-1 means infinite) and the life it has left.
  517. float lifetime;
  518. float life;
  519. // The particle life.
  520. float particleLifeMin;
  521. float particleLifeMax;
  522. // The direction (and spread) the particles will be emitted in. Measured in radians.
  523. float direction;
  524. float spread;
  525. // The speed.
  526. float speedMin;
  527. float speedMax;
  528. // Acceleration along the x and y axes.
  529. love::Vector2 linearAccelerationMin;
  530. love::Vector2 linearAccelerationMax;
  531. // Acceleration towards the emitter's center
  532. float radialAccelerationMin;
  533. float radialAccelerationMax;
  534. // Acceleration perpendicular to the particle's direction.
  535. float tangentialAccelerationMin;
  536. float tangentialAccelerationMax;
  537. float linearDampingMin;
  538. float linearDampingMax;
  539. // Size.
  540. std::vector<float> sizes;
  541. float sizeVariation;
  542. // Rotation
  543. float rotationMin;
  544. float rotationMax;
  545. // Spin.
  546. float spinStart;
  547. float spinEnd;
  548. float spinVariation;
  549. // Offsets
  550. love::Vector2 offset;
  551. // Is the ParticleSystem using a default offset?
  552. bool defaultOffset;
  553. // Color.
  554. std::vector<Colorf> colors;
  555. // Quads.
  556. std::vector<StrongRef<Quad>> quads;
  557. bool relativeRotation;
  558. Buffer *buffer;
  559. // Vertex index buffer.
  560. QuadIndices quadIndices;
  561. private:
  562. void resetOffset();
  563. void createBuffers(size_t size);
  564. void deleteBuffers();
  565. void addParticle(float t);
  566. Particle *removeParticle(Particle *p);
  567. // Called by addParticle.
  568. void initParticle(Particle *p, float t);
  569. void insertTop(Particle *p);
  570. void insertBottom(Particle *p);
  571. void insertRandom(Particle *p);
  572. static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];
  573. static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM> distributions;
  574. static StringMap<InsertMode, INSERT_MODE_MAX_ENUM>::Entry insertModesEntries[];
  575. static StringMap<InsertMode, INSERT_MODE_MAX_ENUM> insertModes;
  576. };
  577. } // graphics
  578. } // love
  579. #endif // LOVE_GRAPHICS_PARTICLE_SYSTEM_H