ParticleSystem.h 17 KB

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