PolyParticleEmitter.cpp 9.9 KB

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