PolyParticleEmitter.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * PolyParticleEmitter.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 7/18/08.
  6. * Copyright 2008 __MyCompanyName__. All rights reserved.
  7. *
  8. */
  9. #include "PolyParticleEmitter.h"
  10. using namespace Polycode;
  11. ParticleEmitter::ParticleEmitter(string imageFile, Mesh *particleMesh, SceneMesh *emitter, Scene *particleParentScene, int particleType, int emitterType, float lifespan, unsigned int numParticles, Vector3 direction, Vector3 gravity, Vector3 deviation)
  12. : SceneEntity() {
  13. emitterMesh = emitter;
  14. dirVector = direction;
  15. gravVector = gravity;
  16. this->emitterType = emitterType;
  17. this->particleParentScene = particleParentScene;
  18. this->emitSpeed = emitSpeed;
  19. this->deviation = deviation;
  20. pMesh = particleMesh;
  21. rotationFollowsPath = false;
  22. rotationSpeed = 0.0f;
  23. startingColor.setColor(1.0f,1.0f,1.0f,1.0f);
  24. endingColor.setColor(1.0f,1.0f,1.0f,1.0f);
  25. perlinEnabled = false;
  26. startingScaleMod = 1.0f;
  27. endingScaleMod = 1.0f;
  28. emitterRadius = 0.0f;
  29. perlinModSize = 0.002;
  30. brightnessDeviation = 0.0f;
  31. particleSpeedMod = 1.0f;
  32. emitRotationVector.set(0.0f, 0.0f, 0.0f);
  33. emitRotationDeviance.set(360.0f, 360.0f, 360.0f);
  34. isEmitterEnabled = true;
  35. allAtOnce = false;
  36. // particleTexture = CoreServices::getInstance()->getMaterialManager()->createTextureFromFile(imageFile);
  37. particleMaterial = (Material*)CoreServices::getInstance()->getResourceManager()->getResource(Resource::RESOURCE_MATERIAL, imageFile);
  38. Particle *particle;
  39. this->numParticles = numParticles;
  40. this->lifespan = lifespan;
  41. for(int i=0; i < numParticles; i++) {
  42. particle = new Particle(particleType, particleMaterial,particleMesh);
  43. particle->velVector = dirVector;
  44. particle->dirVector = dirVector;
  45. particle->deviation = deviation;
  46. particle->lifespan = lifespan;
  47. particles.push_back(particle);
  48. particleParentScene->addEntity(particle->particleBody);
  49. resetParticle(particle);
  50. particle->life = lifespan * ((float)rand()/RAND_MAX);
  51. }
  52. timer = new Timer(true, 1);
  53. motionPerlin = new Perlin(3,5,1.0,rand());
  54. Update();
  55. }
  56. void ParticleEmitter::setEmitterRadius(float rad) {
  57. emitterRadius = rad;
  58. }
  59. void ParticleEmitter::setEndingColor(Color c) {
  60. endingColor = c;
  61. }
  62. void ParticleEmitter::setStartingColor(Color c) {
  63. startingColor = c;
  64. }
  65. void ParticleEmitter::setRotationSpeed(float speed) {
  66. rotationSpeed = speed;
  67. }
  68. void ParticleEmitter::setStartingScaleModifier(float mod) {
  69. startingScaleMod = mod;
  70. }
  71. void ParticleEmitter::setEndingScaleModifier(float mod) {
  72. endingScaleMod = mod;
  73. }
  74. void ParticleEmitter::setBlendingMode(int mode) {
  75. for(int i=0;i < particles.size(); i++) {
  76. particles[i]->particleBody->setBlendingMode(mode);
  77. }
  78. }
  79. void ParticleEmitter::setAlphaTest(bool val) {
  80. for(int i=0;i < particles.size(); i++) {
  81. particles[i]->particleBody->alphaTest = val;
  82. }
  83. }
  84. void ParticleEmitter::setDepthWrite(bool val) {
  85. for(int i=0;i < particles.size(); i++) {
  86. particles[i]->particleBody->setDepthWrite(true);
  87. }
  88. }
  89. void ParticleEmitter::setBillboardMode(bool mode) {
  90. for(int i=0;i < particles.size(); i++) {
  91. particles[i]->particleBody->billboardMode = mode;
  92. }
  93. }
  94. void ParticleEmitter::setEmitRotationVector(Vector3 rotVector) {
  95. emitRotationVector = rotVector;
  96. }
  97. void ParticleEmitter::setEmitRotationDeviance(Vector3 rotVector) {
  98. emitRotationDeviance = rotVector;
  99. }
  100. void ParticleEmitter::enablePerlin(bool val) {
  101. perlinEnabled = val;
  102. }
  103. ParticleEmitter::~ParticleEmitter() {
  104. }
  105. void ParticleEmitter::setParticleCount(int count) {
  106. if(count > particles.size()) {
  107. int oldSize = count-particles.size();
  108. Particle *particle;
  109. for(int i=0; i < oldSize; i++) {
  110. particle = new Particle(particleType, particleMaterial, pMesh);
  111. particle->velVector = dirVector;
  112. particle->dirVector = dirVector;
  113. particle->deviation = deviation;
  114. particle->lifespan = lifespan;
  115. particle->life = lifespan * ((float)rand()/RAND_MAX);
  116. particles.push_back(particle);
  117. particleParentScene->addEntity(particle->particleBody);
  118. }
  119. }
  120. numParticles = count;
  121. for(int i=0; i < particles.size(); i++) {
  122. if(i < numParticles)
  123. particles[i]->particleBody->visible =true;
  124. else
  125. particles[i]->particleBody->visible = false;
  126. }
  127. }
  128. void ParticleEmitter::setPerlinModSize(float size) {
  129. perlinModSize = size;
  130. }
  131. void ParticleEmitter::enableEmitter(bool val) {
  132. isEmitterEnabled = val;
  133. if(val) {
  134. for(int i=0;i < numParticles; i++) {
  135. particles[i]->life = particles[i]->lifespan * ((float)rand()/RAND_MAX);
  136. }
  137. }
  138. }
  139. void ParticleEmitter::Trigger() {
  140. if(!isEmitterEnabled)
  141. return;
  142. for(int i=0;i < numParticles; i++) {
  143. resetParticle(particles[i]);
  144. }
  145. }
  146. bool ParticleEmitter::emitterEnabled() {
  147. return isEmitterEnabled;
  148. }
  149. void ParticleEmitter::resetParticle(Particle *particle) {
  150. particle->particleBody->visible = true;
  151. particle->lifespan = lifespan;
  152. Matrix4 concatMatrix = getConcatenatedMatrix();
  153. Vector3 startVector;
  154. if(emitterMesh) {
  155. Polygon *randPoly = emitterMesh->getMesh()->getPolygon(rand() % emitterMesh->getMesh()->getPolygonCount());
  156. startVector = *randPoly->getVertex(rand() % 3);
  157. startVector = emitterMesh->getConcatenatedMatrix() * startVector;
  158. } else {
  159. startVector = Vector3(-(emitterRadius/2.0f)+emitterRadius*((float)rand()/RAND_MAX),-(emitterRadius/2.0f)+emitterRadius*((float)rand()/RAND_MAX),-(emitterRadius/2.0f)+emitterRadius*((float)rand()/RAND_MAX));
  160. }
  161. particle->Reset();
  162. particle->velVector = particle->dirVector;
  163. float dev = ((deviation.x/2.0f)*-1.0f) + ((deviation.x)*((float)rand()/RAND_MAX));
  164. particle->velVector.x += dev;
  165. dev = (deviation.y/2.0f*-1.0f) + ((deviation.y)*((float)rand()/RAND_MAX));
  166. particle->velVector.y += dev;
  167. dev = (deviation.z/2.0f*-1.0f) + ((deviation.z)*((float)rand()/RAND_MAX));
  168. particle->velVector.z += dev;
  169. particle->brightnessDeviation = 1.0f - ( (-brightnessDeviation) + ((brightnessDeviation*2) * ((float)rand()/RAND_MAX)));
  170. particle->velVector = concatMatrix.rotateVector(particle->velVector);
  171. particle->particleBody->setTransformByMatrix(concatMatrix);
  172. particle->particleBody->Translate(startVector);
  173. particle->particleBody->rebuildTransformMatrix();
  174. // particle->particleBody->setPitch(emitRotationVector.y+(emitRotationDeviance.y*((float)rand()/RAND_MAX)));
  175. // particle->particleBody->setRoll(emitRotationVector.x+(emitRotationDeviance.x*((float)rand()/RAND_MAX)));
  176. // particle->particleBody->setYaw(emitRotationVector.z+(emitRotationDeviance.z*((float)rand()/RAND_MAX)));
  177. particle->particleBody->setScale(scaleCurve.getHeightAt(0),
  178. scaleCurve.getHeightAt(0),
  179. scaleCurve.getHeightAt(0));
  180. particle->particleBody->color.setColor(colorCurveR.getHeightAt(0),
  181. colorCurveG.getHeightAt(0),
  182. colorCurveB.getHeightAt(0),
  183. colorCurveA.getHeightAt(0));
  184. }
  185. void ParticleEmitter::setAllAtOnce(bool val) {
  186. allAtOnce = val;
  187. for(int i=0;i < particles.size(); i++) {
  188. if(allAtOnce)
  189. particles[i]->life = 0;
  190. else
  191. particles[i]->life = particles[i]->lifespan * ((float)rand()/RAND_MAX);
  192. }
  193. }
  194. void ParticleEmitter::Update() {
  195. Vector3 translationVector;
  196. float elapsed = timer->getElapsedf();
  197. Particle *particle;
  198. float normLife;
  199. for(int i=0;i < numParticles; i++) {
  200. particle = particles[i];
  201. normLife = particle->life / particle->lifespan;
  202. Vector3 gVec = gravVector;
  203. particle->life += elapsed;
  204. particle->velVector -= gVec*elapsed*particleSpeedMod;
  205. translationVector = particle->velVector;
  206. translationVector = translationVector*elapsed*particleSpeedMod;
  207. if(perlinEnabled) {
  208. translationVector.x += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosX))*elapsed*particleSpeedMod);
  209. translationVector.y += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosY))*elapsed*particleSpeedMod);
  210. translationVector.z += ((perlinModSize * motionPerlin->Get((particle->life/particle->lifespan), particle->perlinPosZ))*elapsed*particleSpeedMod);
  211. }
  212. particle->particleBody->Translate(translationVector);
  213. if(rotationFollowsPath) {
  214. particle->particleBody->lookAt(*particle->particleBody->getPosition() + translationVector, Vector3(1,0,0));
  215. } else {
  216. particle->particleBody->Roll(rotationSpeed*elapsed);
  217. particle->particleBody->Pitch(rotationSpeed*elapsed);
  218. particle->particleBody->Yaw(rotationSpeed*elapsed);
  219. }
  220. particle->particleBody->color.setColor(colorCurveR.getHeightAt(normLife)*particle->brightnessDeviation,
  221. colorCurveG.getHeightAt(normLife)*particle->brightnessDeviation,
  222. colorCurveB.getHeightAt(normLife)*particle->brightnessDeviation,
  223. colorCurveA.getHeightAt(normLife)*particle->brightnessDeviation);
  224. particle->particleBody->setScale(scaleCurve.getHeightAt(normLife),
  225. scaleCurve.getHeightAt(normLife),
  226. scaleCurve.getHeightAt(normLife));
  227. if(particle->life > particle->lifespan && isEmitterEnabled) {
  228. if(emitterType == CONTINUOUS_EMITTER) {
  229. resetParticle(particle);
  230. } else {
  231. particle->particleBody->visible = false;
  232. }
  233. }
  234. }
  235. }