PolyParticleEmitter.cpp 11 KB

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