ParticleSystem.h 16 KB

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