Changeset 6621 in orxonox.OLD for trunk/src/lib/particles
- Timestamp:
- Jan 19, 2006, 11:46:28 PM (19 years ago)
- Location:
- trunk/src/lib/particles
- Files:
-
- 3 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/particles/Makefile.am
r6619 r6621 4 4 noinst_LIBRARIES = libORXparticles.a 5 5 6 libORXparticles_a_SOURCES = particle_emitter.cc \ 7 particle_system.cc \ 8 quick_animation.cc 6 libORXparticles_a_SOURCES = \ 7 particle_emitter.cc \ 8 \ 9 particle_system.cc \ 10 sprite_particles.cc \ 11 quick_animation.cc 9 12 10 13 11 noinst_HEADERS= particle_emitter.h \ 12 particle_system.h \ 13 quick_animation.h 14 noinst_HEADERS = \ 15 particle_emitter.h \ 16 \ 17 particle_system.h \ 18 sprite_particles.h \ 19 quick_animation.h -
trunk/src/lib/particles/particle_system.cc
r6620 r6621 32 32 #include <algorithm> 33 33 34 35 CREATE_FACTORY(ParticleSystem, CL_PARTICLE_SYSTEM);36 SHELL_COMMAND(texture, ParticleSystem, setMaterialTexture)37 ->defaultValues(1, "maps/evil-flower.png");38 39 34 using namespace std; 40 35 … … 44 39 * @param type The Type of the ParticleSystem 45 40 */ 46 ParticleSystem::ParticleSystem (unsigned int maxCount , PARTICLE_TYPE type)41 ParticleSystem::ParticleSystem (unsigned int maxCount) 47 42 { 48 43 this->init(); 49 44 50 45 this->setMaxCount(maxCount); 51 this->setType(type, 1);52 46 } 53 47 … … 103 97 this->setLifeSpan(1); 104 98 this->glID = NULL; 105 this->setType(PARTICLE_DEFAULT_TYPE, 1);106 99 107 100 this->toList(OM_ENVIRON); … … 126 119 LoadParam(root, "conserve", this, ParticleSystem, setConserve) 127 120 .describe("sets the Conserve factor of the Particles (1.0: they keep all their energy, 0.0:they keep no energy)"); 128 129 LoadParam(root, "type", this, ParticleSystem, setType)130 .describe("sets the type of the Particles, (dot, spark, sprite or model)");131 121 132 122 LoadParam(root, "texture", this, ParticleSystem, setMaterialTexture); … … 155 145 { 156 146 this->maxCount = maxCount; 157 }158 159 160 /**161 * @param particleType the type of particles in this System162 * @param count how many particles (in PARTICLE_MULTI-mode)163 @todo this will be different164 */165 void ParticleSystem::setType(const char* particleType)166 {167 if (!strcmp(particleType, "dot"))168 this->setType(PARTICLE_DOT);169 else if(!strcmp(particleType, "spark"))170 this->setType(PARTICLE_SPARK);171 else if(!strcmp(particleType, "model"))172 this->setType(PARTICLE_MODEL);173 else // if (strcmp(particleType, "SPRITE"))174 this->setType(PARTICLE_SPRITE);175 }176 177 /**178 * @param particleType the type of particles in this System179 * @param count how many particles (in PARTICLE_MULTI-mode)180 @todo this MUST be different181 */182 void ParticleSystem::setType(PARTICLE_TYPE particleType, int count)183 {184 this->particleType = particleType;185 this->dialectCount = count;186 // if (glID != NULL)187 // delete glID;188 189 // glID = new GLuint[count];190 // for (int i = 0; i< count; i++)191 // glID[i] = 0;192 193 // glID[0] = glGenLists(count);194 if (this->material)195 delete this->material;196 this->material = NULL;197 198 switch (this->particleType)199 {200 case PARTICLE_SPRITE:201 this->material = new Material("transperencyMap");202 this->material->setDiffuseMap("maps/radialTransparency.png");203 // material->setTransparency(.5);204 break;205 }206 147 } 207 148 … … 405 346 unsigned int ParticleSystem::getFaceCount() const 406 347 { 407 switch (this->particleType) 408 { 409 case PARTICLE_SPRITE: 410 return this->count; 411 break; 412 case PARTICLE_MODEL: 413 if (this->getModel(0)) 414 return this->count * this->getModel()->getTriangleCount(); 415 break; 416 } 348 return this->count; 417 349 } 418 350 … … 425 357 This is just the fastest Way to do this, but will most likely be changed in the future. 426 358 */ 427 void ParticleSystem::draw() const 428 { 429 glPushAttrib(GL_ENABLE_BIT); 430 431 Particle* drawPart = particles; 432 433 switch (this->particleType) 434 { 435 default: 436 case PARTICLE_SPRITE: 437 glDisable(GL_LIGHTING); 438 glMatrixMode(GL_MODELVIEW); 439 glDepthMask(GL_FALSE); 440 441 material->select(); 442 glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); 443 444 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); 445 446 447 while (likely(drawPart != NULL)) 448 { 449 glColor4fv(drawPart->color); 450 //! @todo implement a faster code for the look-at Camera algorithm. 451 452 const PNode* camera = State::getCamera(); //!< @todo MUST be different 453 Vector cameraPos = camera->getAbsCoor(); 454 Vector cameraTargetPos = State::getCameraTarget()->getAbsCoor(); 455 Vector view = cameraTargetPos - cameraPos; 456 Vector up = Vector(0, 1, 0); 457 up = camera->getAbsDir().apply(up); 458 Vector h = up.cross(view); 459 Vector v = h.cross(view); 460 h.normalize(); 461 v.normalize(); 462 v *= .5 * drawPart->radius; 463 h *= .5 * drawPart->radius; 464 465 glBegin(GL_TRIANGLE_STRIP); 466 glTexCoord2i(1, 1); 467 glVertex3f(drawPart->position.x - h.x - v.x, 468 drawPart->position.y - h.y - v.y, 469 drawPart->position.z - h.z - v.z); 470 glTexCoord2i(0, 1); 471 glVertex3f(drawPart->position.x - h.x + v.x, 472 drawPart->position.y - h.y + v.y, 473 drawPart->position.z - h.z + v.z); 474 glTexCoord2i(1, 0); 475 glVertex3f(drawPart->position.x + h.x - v.x, 476 drawPart->position.y + h.y - v.y, 477 drawPart->position.z + h.z - v.z); 478 glTexCoord2i(0, 0); 479 glVertex3f(drawPart->position.x + h.x + v.x, 480 drawPart->position.y + h.y + v.y, 481 drawPart->position.z + h.z + v.z); 482 483 glEnd(); 484 485 drawPart = drawPart->next; 486 } 487 glDepthMask(GL_TRUE); 488 break; 489 490 case PARTICLE_SPARK: 491 glDisable(GL_LIGHTING); 492 glDepthMask(GL_FALSE); 493 //glEnable(GL_LINE_SMOOTH); 494 glEnable(GL_BLEND); 495 496 glBegin(GL_LINES); 497 while (likely(drawPart != NULL)) 498 { 499 glColor4fv(drawPart->color); 500 glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 501 glVertex3f(drawPart->position.x - drawPart->velocity.x * drawPart->radius, 502 drawPart->position.y - drawPart->velocity.y * drawPart->radius, 503 drawPart->position.z - drawPart->velocity.z * drawPart->radius); 504 drawPart = drawPart->next; 505 } 506 glEnd(); 507 break; 508 509 case PARTICLE_MODEL: 510 { 511 GLfloat matrix[4][4]; 512 513 if (likely(this->getModel() != NULL)) 514 while (likely(drawPart != NULL)) 515 { 516 glPushMatrix(); 517 glMatrixMode(GL_MODELVIEW); 518 /* move */ 519 glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z); 520 /* scale */ 521 glScalef(drawPart->radius, drawPart->radius, drawPart->radius); 522 /* rotate */ 523 drawPart->orientation.matrix (matrix); 524 glMultMatrixf((float*)matrix); 525 526 this->getModel()->draw(); 527 528 glPopMatrix(); 529 drawPart = drawPart->next; 530 } 531 else 532 PRINTF(2)("no model loaded onto ParticleSystem-%s\n", this->getName()); 533 } 534 break; 535 536 case PARTICLE_DOT: 537 glDisable(GL_LIGHTING); 538 glBegin(GL_POINTS); 539 while (likely(drawPart != NULL)) 540 { 541 glColor4fv(drawPart->color); 542 543 glLineWidth(drawPart->radius); 544 545 glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 546 drawPart = drawPart->next; 547 } 548 glEnd(); 549 break; 550 } 551 glPopAttrib(); 552 } 359 // void ParticleSystem::draw() const 360 // { 361 // glPushAttrib(GL_ENABLE_BIT); 362 // 363 // Particle* drawPart = particles; 364 // 365 // switch (this->particleType) 366 // { 367 // case PARTICLE_SPARK: 368 // glDisable(GL_LIGHTING); 369 // glDepthMask(GL_FALSE); 370 // //glEnable(GL_LINE_SMOOTH); 371 // glEnable(GL_BLEND); 372 // 373 // glBegin(GL_LINES); 374 // while (likely(drawPart != NULL)) 375 // { 376 // glColor4fv(drawPart->color); 377 // glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 378 // glVertex3f(drawPart->position.x - drawPart->velocity.x * drawPart->radius, 379 // drawPart->position.y - drawPart->velocity.y * drawPart->radius, 380 // drawPart->position.z - drawPart->velocity.z * drawPart->radius); 381 // drawPart = drawPart->next; 382 // } 383 // glEnd(); 384 // break; 385 // 386 // case PARTICLE_MODEL: 387 // { 388 // GLfloat matrix[4][4]; 389 // 390 // if (likely(this->getModel() != NULL)) 391 // while (likely(drawPart != NULL)) 392 // { 393 // glPushMatrix(); 394 // glMatrixMode(GL_MODELVIEW); 395 // /* move */ 396 // glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z); 397 // /* scale */ 398 // glScalef(drawPart->radius, drawPart->radius, drawPart->radius); 399 // /* rotate */ 400 // drawPart->orientation.matrix (matrix); 401 // glMultMatrixf((float*)matrix); 402 // 403 // this->getModel()->draw(); 404 // 405 // glPopMatrix(); 406 // drawPart = drawPart->next; 407 // } 408 // else 409 // PRINTF(2)("no model loaded onto ParticleSystem-%s\n", this->getName()); 410 // } 411 // break; 412 // 413 // case PARTICLE_DOT: 414 // glDisable(GL_LIGHTING); 415 // glBegin(GL_POINTS); 416 // while (likely(drawPart != NULL)) 417 // { 418 // glColor4fv(drawPart->color); 419 // 420 // glLineWidth(drawPart->radius); 421 // 422 // glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 423 // drawPart = drawPart->next; 424 // } 425 // glEnd(); 426 // break; 427 // } 428 // glPopAttrib(); 429 // } 553 430 554 431 /** … … 621 498 void ParticleSystem::debug() const 622 499 { 623 PRINT(0)(" ParticleSystem %s, type: ", this->getName());624 {625 if (this->particleType == PARTICLE_MODEL)626 PRINT(0)("model");627 else if (this->particleType == PARTICLE_SPRITE)628 PRINT(0)("sprite");629 else if (this->particleType == PARTICLE_DOT)630 PRINT(0)("dot");631 else if (this->particleType == PARTICLE_SPARK)632 PRINT(0)("spark");633 634 PRINT(0)("\n");635 }636 637 500 PRINT(0)(" ParticleCount: %d, maximumCount: %d :: filled %d%%\n", this->count, this->maxCount, 100*this->count/this->maxCount); 638 501 if (deadList) -
trunk/src/lib/particles/particle_system.h
r6612 r6621 26 26 #define PARTICLE_MULTI_MASK 0x100000 //!< A Mask if they are Multi-partilces 27 27 28 //! An enumerator for the different types of particles.29 typedef enum PARTICLE_TYPE30 {31 PARTICLE_DOT = PARTICLE_DOT_MASK,32 PARTICLE_SPARK = PARTICLE_SPARK_MASK,33 PARTICLE_SPRITE = PARTICLE_SPRITE_MASK,34 PARTICLE_MULTI_SPRITE = PARTICLE_SPRITE_MASK | PARTICLE_MULTI_MASK,35 PARTICLE_MODEL = PARTICLE_MODEL_MASK,36 PARTICLE_MULTI_MODE = PARTICLE_MODEL_MASK | PARTICLE_MULTI_MASK37 };38 39 28 #define PARTICLE_DEFAULT_MAX_COUNT 200 //!< A default count of particles in the system. 40 #define PARTICLE_DEFAULT_TYPE PARTICLE_SPRITE //!< A default type of the system.41 29 42 30 // FORWARD DECLARATION … … 69 57 70 58 public: 71 ParticleSystem(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT, 72 PARTICLE_TYPE type = PARTICLE_DEFAULT_TYPE); 59 ParticleSystem(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT); 73 60 ParticleSystem(const TiXmlElement* root); 74 61 virtual ~ParticleSystem(); … … 77 64 virtual void loadParams(const TiXmlElement* root); 78 65 79 void setType(const char* particleType);80 void setType(PARTICLE_TYPE particleType, int count = 0);81 66 void setMaterial(Material* material); 82 67 void setMaterialTexture(const char* textureFile); … … 91 76 void setColor(float lifeCycleTime, float red, float green, float blue, float alpha); 92 77 93 /** @returns the Type of the particles */94 inline PARTICLE_TYPE getType() const { return this->particleType; };95 78 /** @returns the Material that lies on this particles */ 96 79 inline const Material* getMaterial() const { return this->material; }; … … 113 96 114 97 virtual void applyField(Field* field); 115 /** \brief this is an empty function, because the Physics are implemented in tick @param dt: useless here */98 /** @brief this is an empty function, because the Physics are implemented in tick @param dt: useless here */ 116 99 virtual void tickPhys(float dt) {}; 117 100 … … 119 102 120 103 virtual void tick(float dt); 121 virtual void draw() const ;104 virtual void draw() const = 0; 122 105 123 106 void debug() const; 124 107 125 pr ivate:108 protected: 126 109 float conserve; //!< How much energy gets conserved to the next Tick. 127 110 float lifeSpan; //!< Initial lifetime of a Particle. … … 132 115 int maxCount; //!< The maximum count of Particles. 133 116 int count; //!< The current count of Particles. 134 PARTICLE_TYPE particleType; //!< A type for all the Particles135 117 Material* material; //!< A Material for all the Particles. 136 118 Particle* particles; //!< A list of particles of this System. -
trunk/src/lib/particles/sprite_particles.cc
r6620 r6621 16 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS 17 17 18 #include "particle_system.h" 19 20 #include "particle_emitter.h" 21 22 #include "field.h" 23 #include "model.h" 18 #include "sprite_particles.h" 24 19 25 20 #include "load_param.h" … … 33 28 34 29 35 CREATE_FACTORY(ParticleSystem, CL_PARTICLE_SYSTEM); 36 SHELL_COMMAND(texture, ParticleSystem, setMaterialTexture) 30 CREATE_FACTORY(SpriteParticles, CL_SPRITE_PARTICLES); 31 32 SHELL_COMMAND(texture, SpriteParticles, setMaterialTexture) 37 33 ->defaultValues(1, "maps/evil-flower.png"); 38 34 … … 42 38 * standard constructor 43 39 * @param maxCount the Count of particles in the System 44 * @param type The Type of the ParticleSystem40 * @param type The Type of the SpriteParticles 45 41 */ 46 ParticleSystem::ParticleSystem (unsigned int maxCount, PARTICLE_TYPE type) 42 SpriteParticles::SpriteParticles (unsigned int maxCount) 43 : ParticleSystem(maxCount) 47 44 { 48 45 this->init(); 49 50 this->setMaxCount(maxCount);51 this->setType(type, 1);52 46 } 53 47 … … 56 50 * @param root: the XML-element to load from 57 51 */ 58 ParticleSystem::ParticleSystem(const TiXmlElement* root)52 SpriteParticles::SpriteParticles(const TiXmlElement* root) 59 53 { 60 54 this->init(); … … 66 60 * standard deconstructor 67 61 */ 68 ParticleSystem::~ParticleSystem()62 SpriteParticles::~SpriteParticles() 69 63 { 70 71 72 73 74 75 76 64 // deleting all the living Particles 65 while (this->particles) 66 { 67 Particle* tmpDelPart = this->particles; 68 this->particles = this->particles->next; 69 delete tmpDelPart; 70 } 77 71 78 // deleting all the dead particles 79 while (this->deadList) 80 { 81 Particle* tmpDelPart = this->deadList; 82 this->deadList = this->deadList->next; 83 delete tmpDelPart; 84 } 85 86 if (this->material) 87 delete this->material; 72 // deleting all the dead particles 73 while (this->deadList) 74 { 75 Particle* tmpDelPart = this->deadList; 76 this->deadList = this->deadList->next; 77 delete tmpDelPart; 78 } 88 79 } 89 80 90 81 /** 91 \brief initializes the ParticleSystemwith default values82 * @brief initializes the SpriteParticles with default values 92 83 */ 93 void ParticleSystem::init()84 void SpriteParticles::init() 94 85 { 95 this->setClassID(CL_ PARTICLE_SYSTEM, "ParticleSystem");86 this->setClassID(CL_SPRITE_PARTICLES, "SpriteParticles"); 96 87 97 88 this->material = NULL; 98 this->setMaxCount(PARTICLE_DEFAULT_MAX_COUNT);99 this->count = 0;100 this->particles = NULL;101 this->deadList = NULL;102 this->setConserve(1);103 this->setLifeSpan(1);104 this->glID = NULL;105 this->setType(PARTICLE_DEFAULT_TYPE, 1);106 107 this->toList(OM_ENVIRON);108 89 } 109 90 … … 113 94 * @param root the XML-element to load from. 114 95 */ 115 void ParticleSystem::loadParams(const TiXmlElement* root)96 void SpriteParticles::loadParams(const TiXmlElement* root) 116 97 { 117 WorldEntity::loadParams(root); 118 PhysicsInterface::loadParams(root); 98 SpriteParticles::loadParams(root); 119 99 120 LoadParam(root, "max-count", this, ParticleSystem, setMaxCount) 121 .describe("the maximal count of Particles, that can be emitted into this system"); 122 123 LoadParam(root, "life-span", this, ParticleSystem, setLifeSpan) 124 .describe("sets the life-span of the Particles."); 125 126 LoadParam(root, "conserve", this, ParticleSystem, setConserve) 127 .describe("sets the Conserve factor of the Particles (1.0: they keep all their energy, 0.0:they keep no energy)"); 128 129 LoadParam(root, "type", this, ParticleSystem, setType) 130 .describe("sets the type of the Particles, (dot, spark, sprite or model)"); 131 132 LoadParam(root, "texture", this, ParticleSystem, setMaterialTexture); 133 LoadParamXML(root, "emitter", this, ParticleSystem, addEmitterXML); 134 135 LOAD_PARAM_START_CYCLE(root, element); 136 { 137 element->ToText(); 138 // PER-PARTICLE-ATTRIBUTES: 139 LoadParam_CYCLE(element, "radius", this, ParticleSystem, setRadius) 140 .describe("The Radius of each particle over time (TimeIndex [0-1], radius at TimeIndex, randomRadius at TimeIndex)"); 141 142 LoadParam_CYCLE(element, "mass", this, ParticleSystem, setMass) 143 .describe("The Mass of each particle over time (TimeIndex: [0-1], mass at TimeIndex, randomMass at TimeIndex)"); 144 145 LoadParam_CYCLE(element, "color", this, ParticleSystem, setColor) 146 .describe("The Color of each particle over time (TimeIndex: [0-1], red: [0-1], green: [0-1], blue: [0-1], alpha: [0-1])"); 147 } 148 LOAD_PARAM_END_CYCLE(element); 149 } 150 151 /** 152 * @param maxCount the maximum count of particles that can be emitted 153 */ 154 void ParticleSystem::setMaxCount(int maxCount) 155 { 156 this->maxCount = maxCount; 157 } 158 159 160 /** 161 * @param particleType the type of particles in this System 162 * @param count how many particles (in PARTICLE_MULTI-mode) 163 @todo this will be different 164 */ 165 void ParticleSystem::setType(const char* particleType) 166 { 167 if (!strcmp(particleType, "dot")) 168 this->setType(PARTICLE_DOT); 169 else if(!strcmp(particleType, "spark")) 170 this->setType(PARTICLE_SPARK); 171 else if(!strcmp(particleType, "model")) 172 this->setType(PARTICLE_MODEL); 173 else // if (strcmp(particleType, "SPRITE")) 174 this->setType(PARTICLE_SPRITE); 175 } 176 177 /** 178 * @param particleType the type of particles in this System 179 * @param count how many particles (in PARTICLE_MULTI-mode) 180 @todo this MUST be different 181 */ 182 void ParticleSystem::setType(PARTICLE_TYPE particleType, int count) 183 { 184 this->particleType = particleType; 185 this->dialectCount = count; 186 // if (glID != NULL) 187 // delete glID; 188 189 // glID = new GLuint[count]; 190 // for (int i = 0; i< count; i++) 191 // glID[i] = 0; 192 193 // glID[0] = glGenLists(count); 194 if (this->material) 195 delete this->material; 196 this->material = NULL; 197 198 switch (this->particleType) 199 { 200 case PARTICLE_SPRITE: 201 this->material = new Material("transperencyMap"); 202 this->material->setDiffuseMap("maps/radialTransparency.png"); 203 // material->setTransparency(.5); 204 break; 205 } 100 LoadParam(root, "texture", this, SpriteParticles, setMaterialTexture); 206 101 } 207 102 208 103 // setting properties 209 104 /** 210 * sets the material to an external material105 * @brief sets the material to an external material 211 106 * @param material: the material to set this material to. 212 213 107 * 108 * !! important if the extern material gets deleted it MUST be unregistered here or segfault !! 214 109 */ 215 void ParticleSystem::setMaterial(Material* material)110 void SpriteParticles::setMaterial(Material* material) 216 111 { 217 this->material = material;112 this->material = *material; 218 113 } 219 114 220 void ParticleSystem::setMaterialTexture(const char* textureFile)115 void SpriteParticles::setMaterialTexture(const char* textureFile) 221 116 { 222 if (this->material != NULL) 223 this->material->setDiffuseMap(textureFile); 117 this->material.setDiffuseMap(textureFile); 224 118 } 225 119 226 120 /** 227 * Sets the lifespan of newly created particles 228 */ 229 void ParticleSystem::setLifeSpan(float lifeSpan, float randomLifeSpan) 230 { 231 this->lifeSpan = lifeSpan; 232 this->randomLifeSpan = randomLifeSpan; 233 } 234 235 /** 236 * sets the conserve Factor of newly created particles 237 */ 238 void ParticleSystem::setConserve(float conserve) 239 { 240 if (conserve > 1.0) 241 this->conserve = 1.0; 242 else if (conserve < 0.0) 243 this->conserve = 0.0; 244 else 245 this->conserve = conserve; 246 } 247 248 ///////////////////////////// 249 /* Per-Particle Attributes */ 250 ///////////////////////////// 251 /** 252 * sets a key in the radius-animation on a per-particle basis 253 * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1] 254 * @param radius the radius at this position 255 * @param randRadius the randRadius at this position 256 */ 257 void ParticleSystem::setRadius(float lifeCycleTime, float radius, float randRadius) 258 { 259 this->radiusAnim.changeEntry(lifeCycleTime, radius); 260 this->randRadiusAnim.changeEntry(lifeCycleTime, randRadius); 261 } 262 263 /** 264 * sets a key in the mass-animation on a per-particle basis 265 * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1] 266 * @param mass the mass at this position 267 * @param randMass the randomMass at this position 268 */ 269 void ParticleSystem::setMass(float lifeCycleTime, float mass, float randMass) 270 { 271 this->massAnim.changeEntry(lifeCycleTime, mass); 272 this->randMassAnim.changeEntry(lifeCycleTime, randMass); 273 } 274 275 /** 276 * sets a key in the color-animation on a per-particle basis 277 * @param lifeCycleTime: the time (partilceLifeTime/particleAge) [0-1] 278 * @param red: red 279 * @param green: green 280 * @param blue: blue 281 * @param alpha: alpha 282 */ 283 void ParticleSystem::setColor(float lifeCycleTime, float red, float green, float blue, float alpha) 284 { 285 this->colorAnim[0].changeEntry(lifeCycleTime, red); 286 this->colorAnim[1].changeEntry(lifeCycleTime, green); 287 this->colorAnim[2].changeEntry(lifeCycleTime, blue); 288 this->colorAnim[3].changeEntry(lifeCycleTime, alpha); 289 } 290 291 292 void ParticleSystem::addEmitter(ParticleEmitter* emitter) 293 { 294 assert (emitter != NULL); 295 if (emitter->getSystem() != NULL) 296 emitter->getSystem()->removeEmitter(emitter); 297 this->emitters.push_back(emitter); 298 } 299 300 void ParticleSystem::addEmitterXML(const TiXmlElement* emitterRoot) 301 { 302 ParticleEmitter* emitter = new ParticleEmitter(emitterRoot); 303 this->addEmitter(emitter); 304 } 305 306 307 void ParticleSystem::removeEmitter(ParticleEmitter* emitter) 308 { 309 std::list<ParticleEmitter*>::iterator it = std::find(this->emitters.begin(), this->emitters.end(), emitter); 310 if (it != this->emitters.end()) 311 this->emitters.erase(it); 312 } 313 314 /** 315 * ticks the system. 316 * @param dt the time to tick all the Particles of the System 317 318 this is used to get all the particles some motion 319 */ 320 void ParticleSystem::tick(float dt) 321 { 322 Particle* tickPart = particles; // the particle to Tick 323 Particle* prevPart = NULL; 324 while (likely(tickPart != NULL)) 325 { 326 // applying force to the System. 327 if (likely (tickPart->mass > 0.0)) 328 tickPart->velocity += tickPart->extForce / tickPart->mass * dt; 329 // rendering new position. 330 tickPart->position += tickPart->velocity * dt; 331 tickPart->orientation += tickPart->momentum *dt; 332 333 tickPart->radius = radiusAnim.getValue(tickPart->lifeCycle) 334 + randRadiusAnim.getValue(tickPart->lifeCycle) * tickPart->radiusRand; 335 336 tickPart->mass = massAnim.getValue(tickPart->lifeCycle) 337 + randMassAnim.getValue(tickPart->lifeCycle) * tickPart->massRand; 338 339 tickPart->extForce = Vector(0,0,0); 340 341 // applying Color 342 tickPart->color[0] = this->colorAnim[0].getValue(tickPart->lifeCycle); 343 tickPart->color[1] = this->colorAnim[1].getValue(tickPart->lifeCycle); 344 tickPart->color[2] = this->colorAnim[2].getValue(tickPart->lifeCycle); 345 tickPart->color[3] = this->colorAnim[3].getValue(tickPart->lifeCycle); 346 347 // many more to come 348 349 if (this->conserve < 1.0) 350 { 351 tickPart->velocity *= this->conserve; 352 tickPart->momentum *= this->conserve; 353 } 354 // find out if we have to delete tickPart 355 if (unlikely((tickPart->lifeCycle += dt/tickPart->lifeTime) >= 1.0)) 356 { 357 // remove the particle from the list 358 if (likely(prevPart != NULL)) 359 { 360 prevPart->next = tickPart->next; 361 tickPart->next = this->deadList; 362 this->deadList = tickPart; 363 tickPart = prevPart->next; 364 } 365 else 366 { 367 prevPart = NULL; 368 this->particles = tickPart->next; 369 tickPart->next = this->deadList; 370 this->deadList = tickPart; 371 tickPart = this->particles; 372 } 373 --this->count; 374 } 375 else 376 { 377 prevPart = tickPart; 378 tickPart = tickPart->next; 379 } 380 } 381 382 std::list<ParticleEmitter*>::iterator emitter; 383 for (emitter = this->emitters.begin(); emitter != this->emitters.end(); emitter++) 384 (*emitter)->tick(dt); 385 } 386 387 /** 388 * applies some force to a Particle. 389 * @param field the Field to apply. 121 * @brief draws all the Particles of this System 122 * 123 * The Cases in this Function all do the same: 124 * Drawing all the particles with the appropriate Type. 125 * This is just the fastest Way to do this, but will most likely be changed in the future. 390 126 */ 391 void ParticleSystem::applyField(Field* field) 392 { 393 Particle* tickPart = particles; 394 while (tickPart) 395 { 396 tickPart->extForce += field->calcForce(tickPart->position); 397 tickPart = tickPart->next; 398 } 399 } 400 401 402 /** 403 * @returns the count of Faces of this ParticleSystem 404 */ 405 unsigned int ParticleSystem::getFaceCount() const 406 { 407 switch (this->particleType) 408 { 409 case PARTICLE_SPRITE: 410 return this->count; 411 break; 412 case PARTICLE_MODEL: 413 if (this->getModel(0)) 414 return this->count * this->getModel()->getTriangleCount(); 415 break; 416 } 417 } 418 419 420 /** 421 * draws all the Particles of this System 422 423 The Cases in this Function all do the same: 424 Drawing all the particles with the appropriate Type. 425 This is just the fastest Way to do this, but will most likely be changed in the future. 426 */ 427 void ParticleSystem::draw() const 127 void SpriteParticles::draw() const 428 128 { 429 129 glPushAttrib(GL_ENABLE_BIT); … … 431 131 Particle* drawPart = particles; 432 132 433 switch (this->particleType) 434 { 435 default: 436 case PARTICLE_SPRITE: 437 glDisable(GL_LIGHTING); 438 glMatrixMode(GL_MODELVIEW); 439 glDepthMask(GL_FALSE); 133 glDisable(GL_LIGHTING); 134 glMatrixMode(GL_MODELVIEW); 135 glDepthMask(GL_FALSE); 440 136 441 material->select();442 137 material.select(); 138 glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); 443 139 444 140 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); 445 141 446 142 447 448 449 450 143 while (likely(drawPart != NULL)) 144 { 145 glColor4fv(drawPart->color); 146 //! @todo implement a faster code for the look-at Camera algorithm. 451 147 452 453 454 455 456 457 458 459 460 461 462 463 148 const PNode* camera = State::getCamera(); //!< @todo MUST be different 149 Vector cameraPos = camera->getAbsCoor(); 150 Vector cameraTargetPos = State::getCameraTarget()->getAbsCoor(); 151 Vector view = cameraTargetPos - cameraPos; 152 Vector up = Vector(0, 1, 0); 153 up = camera->getAbsDir().apply(up); 154 Vector h = up.cross(view); 155 Vector v = h.cross(view); 156 h.normalize(); 157 v.normalize(); 158 v *= .5 * drawPart->radius; 159 h *= .5 * drawPart->radius; 464 160 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 161 glBegin(GL_TRIANGLE_STRIP); 162 glTexCoord2i(1, 1); 163 glVertex3f(drawPart->position.x - h.x - v.x, 164 drawPart->position.y - h.y - v.y, 165 drawPart->position.z - h.z - v.z); 166 glTexCoord2i(0, 1); 167 glVertex3f(drawPart->position.x - h.x + v.x, 168 drawPart->position.y - h.y + v.y, 169 drawPart->position.z - h.z + v.z); 170 glTexCoord2i(1, 0); 171 glVertex3f(drawPart->position.x + h.x - v.x, 172 drawPart->position.y + h.y - v.y, 173 drawPart->position.z + h.z - v.z); 174 glTexCoord2i(0, 0); 175 glVertex3f(drawPart->position.x + h.x + v.x, 176 drawPart->position.y + h.y + v.y, 177 drawPart->position.z + h.z + v.z); 482 178 483 179 glEnd(); 484 180 485 drawPart = drawPart->next; 486 } 487 glDepthMask(GL_TRUE); 488 break; 489 490 case PARTICLE_SPARK: 491 glDisable(GL_LIGHTING); 492 glDepthMask(GL_FALSE); 493 //glEnable(GL_LINE_SMOOTH); 494 glEnable(GL_BLEND); 495 496 glBegin(GL_LINES); 497 while (likely(drawPart != NULL)) 498 { 499 glColor4fv(drawPart->color); 500 glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 501 glVertex3f(drawPart->position.x - drawPart->velocity.x * drawPart->radius, 502 drawPart->position.y - drawPart->velocity.y * drawPart->radius, 503 drawPart->position.z - drawPart->velocity.z * drawPart->radius); 504 drawPart = drawPart->next; 505 } 506 glEnd(); 507 break; 508 509 case PARTICLE_MODEL: 510 { 511 GLfloat matrix[4][4]; 512 513 if (likely(this->getModel() != NULL)) 514 while (likely(drawPart != NULL)) 515 { 516 glPushMatrix(); 517 glMatrixMode(GL_MODELVIEW); 518 /* move */ 519 glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z); 520 /* scale */ 521 glScalef(drawPart->radius, drawPart->radius, drawPart->radius); 522 /* rotate */ 523 drawPart->orientation.matrix (matrix); 524 glMultMatrixf((float*)matrix); 525 526 this->getModel()->draw(); 527 528 glPopMatrix(); 529 drawPart = drawPart->next; 530 } 531 else 532 PRINTF(2)("no model loaded onto ParticleSystem-%s\n", this->getName()); 533 } 534 break; 535 536 case PARTICLE_DOT: 537 glDisable(GL_LIGHTING); 538 glBegin(GL_POINTS); 539 while (likely(drawPart != NULL)) 540 { 541 glColor4fv(drawPart->color); 542 543 glLineWidth(drawPart->radius); 544 545 glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); 546 drawPart = drawPart->next; 547 } 548 glEnd(); 549 break; 181 drawPart = drawPart->next; 550 182 } 183 glDepthMask(GL_TRUE); 551 184 glPopAttrib(); 552 185 } 553 554 /**555 * adds a new Particle to the System556 * @param position the initial position, where the particle gets emitted.557 * @param velocity the initial velocity of the particle.558 * @param orientation the initial orientation of the Paritcle.559 * @param momentum the initial momentum of the Particle (the speed of its rotation).560 * @param data some more data given by the emitter561 */562 void ParticleSystem::addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data)563 {564 if (this->count <= this->maxCount)565 {566 // if it is the first Particle567 if (unlikely(particles == NULL))568 {569 if (likely(deadList != NULL))570 {571 this->particles = this->deadList;572 deadList = deadList->next;573 }574 else575 {576 PRINTF(5)("Generating new Particle\n");577 this->particles = new Particle;578 }579 this->particles->next = NULL;580 }581 // filling the List from the beginning582 else583 {584 Particle* tmpPart;585 if (likely(deadList != NULL))586 {587 tmpPart = this->deadList;588 deadList = deadList->next;589 }590 else591 {592 PRINTF(5)("Generating new Particle\n");593 tmpPart = new Particle;594 }595 tmpPart->next = this->particles;596 this->particles = tmpPart;597 }598 particles->lifeTime = this->lifeSpan + (float)(rand()/RAND_MAX)* this->randomLifeSpan;599 particles->lifeCycle = 0.0;600 particles->position = position;601 particles->velocity = velocity;602 603 particles->orientation = orientation;604 particles->momentum = momentum;605 606 // particle->rotation = ; //! @todo rotation is once again something to be done.607 particles->massRand = 2*(float)rand()/RAND_MAX -1;608 particles->radiusRand = 2* (float)rand()/RAND_MAX -1;609 particles->mass = this->massAnim.getValue(0.0) + this->randMassAnim.getValue(0.0)*particles->massRand;610 particles->radius = this->radiusAnim.getValue(0.0) + this->randRadiusAnim.getValue(0.0)*particles->radiusRand;611 612 ++this->count;613 }614 else615 PRINTF(5)("maximum count of particles reached not adding any more\n");616 }617 618 /**619 * outputs some nice debug information620 */621 void ParticleSystem::debug() const622 {623 PRINT(0)(" ParticleSystem %s, type: ", this->getName());624 {625 if (this->particleType == PARTICLE_MODEL)626 PRINT(0)("model");627 else if (this->particleType == PARTICLE_SPRITE)628 PRINT(0)("sprite");629 else if (this->particleType == PARTICLE_DOT)630 PRINT(0)("dot");631 else if (this->particleType == PARTICLE_SPARK)632 PRINT(0)("spark");633 634 PRINT(0)("\n");635 }636 637 PRINT(0)(" ParticleCount: %d, maximumCount: %d :: filled %d%%\n", this->count, this->maxCount, 100*this->count/this->maxCount);638 if (deadList)639 {640 PRINT(0)(" - ParticleDeadList is used: ");641 int i = 1;642 Particle* tmpPart = this->deadList;643 while (tmpPart = tmpPart->next) ++i;644 PRINT(0)("count: %d\n", i);645 }646 } -
trunk/src/lib/particles/sprite_particles.h
r6619 r6621 4 4 */ 5 5 6 #ifndef _ PARTICLE_SYSTEM_H7 #define _ PARTICLE_SYSTEM_H6 #ifndef _SPRITE_PARTICLE_SYSTEM_H 7 #define _SPRITE_PARTICLE_SYSTEM_H 8 8 9 #include "world_entity.h" 10 #include "physics_interface.h" 11 12 #include "glincl.h" 13 #include "vector.h" 14 #include <list> 15 16 #include "quick_animation.h" 17 18 // Forward Declaration 19 class TiXmlElement; 20 21 #define PARTICLE_DOT_MASK 0x000001 //!< A Mask if the Particles should be displayed as DOTs 22 #define PARTICLE_SPARK_MASK 0x000010 //!< A Mask if the Particles should be displayed as SPARKs 23 #define PARTICLE_SPRITE_MASK 0x000100 //!< A Mask if the Particles should be displayed as SPRITESs 24 #define PARTICLE_MODEL_MASK 0x001000 //!< A Mask if the Particles should be displayed as MODELSs 25 #define PARTICLE_WORDL_ENTITY_MASK 0x010000 //!< A Mask if the Particles should be displayed as WORLD_ENTITIEs 26 #define PARTICLE_MULTI_MASK 0x100000 //!< A Mask if they are Multi-partilces 27 28 //! An enumerator for the different types of particles. 29 typedef enum PARTICLE_TYPE 30 { 31 PARTICLE_DOT = PARTICLE_DOT_MASK, 32 PARTICLE_SPARK = PARTICLE_SPARK_MASK, 33 PARTICLE_SPRITE = PARTICLE_SPRITE_MASK, 34 PARTICLE_MULTI_SPRITE = PARTICLE_SPRITE_MASK | PARTICLE_MULTI_MASK, 35 PARTICLE_MODEL = PARTICLE_MODEL_MASK, 36 PARTICLE_MULTI_MODE = PARTICLE_MODEL_MASK | PARTICLE_MULTI_MASK 37 }; 38 39 #define PARTICLE_DEFAULT_MAX_COUNT 200 //!< A default count of particles in the system. 40 #define PARTICLE_DEFAULT_TYPE PARTICLE_SPRITE //!< A default type of the system. 41 42 // FORWARD DECLARATION 43 class Material; 44 class ParticleEmitter; 45 class Field; 46 47 //! A struct for one Particle 48 typedef struct Particle 49 { 50 float lifeTime; //!< The time this particle has to live. 51 float lifeCycle; //!< The fraction of time passed. (in percentage of its lifeTime) 52 53 Vector position; //!< The current position of this particle. 54 Vector velocity; //!< The current velocity of this Particle. 55 Vector extForce; //!< The external Force that influences this Particle. 56 Quaternion orientation; //!< The current orientation of this Particle. 57 Quaternion momentum; //!< The current angular momentum (spin) of this Particle. 58 float mass; //!< The mass of this Particle. 59 float massRand; //!< A random mass 60 float radius; //!< The current size of this Particle. 61 float radiusRand; //!< a random Radius 62 GLfloat color [4]; //!< A Color for the particles. 63 64 Particle* next; //!< pointer to the next particle in the List. (NULL if no preceding one) 65 }; 9 #include "particle_system.h" 10 #include "material.h" 66 11 67 12 //! A class to handle ParticleSystems 68 class ParticleSystem : public WorldEntity, public PhysicsInterface { 13 class SpriteParticles : public ParticleSystem 14 { 69 15 70 public: 71 ParticleSystem(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT, 72 PARTICLE_TYPE type = PARTICLE_DEFAULT_TYPE); 73 ParticleSystem(const TiXmlElement* root); 74 virtual ~ParticleSystem(); 16 public: 17 SpriteParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT); 18 SpriteParticles(const TiXmlElement* root); 19 virtual ~SpriteParticles(); 75 20 76 void init();77 21 virtual void loadParams(const TiXmlElement* root); 78 22 79 void setType(const char* particleType);80 void setType(PARTICLE_TYPE particleType, int count = 0);81 23 void setMaterial(Material* material); 82 24 void setMaterialTexture(const char* textureFile); 83 void setModel(const char* modelName = NULL);84 void setLifeSpan(float lifeSpan, float randomLifeSpan = 0.0);85 void setConserve(float conserve);86 void setMaxCount(int maxCount);87 25 88 /* Per-Particle-Attributes */ 89 void setRadius(float lifeCycleTime, float radius, float randRadius = 0.0); 90 void setMass(float lifeCycleTime, float mass, float randMass = 0.0); 91 void setColor(float lifeCycleTime, float red, float green, float blue, float alpha); 26 /** @returns the Material that lies on this particles */ 27 inline const Material* getMaterial() const { return &this->material; }; 92 28 93 /** @returns the Type of the particles */94 inline PARTICLE_TYPE getType() const { return this->particleType; };95 /** @returns the Material that lies on this particles */96 inline const Material* getMaterial() const { return this->material; };97 /** @returns the lifespan of the particles */98 inline float getLifeSpan() const { return this->lifeSpan; };99 /** @returns the starting-radius of the particles */100 inline float getStartRadius() { return this->radiusAnim.getValue(0.0); };101 /** @returns the end-radius of the particles */102 inline float getEndRadius() { return this->radiusAnim.getValue(1.0); };103 /** @returns the conserve-factor of the particles */104 inline float getConserve() const { return this->conserve; };105 /** @returns the initial mass of the particles */106 inline float getMass() const { return this->initialMass; };107 108 virtual unsigned int getFaceCount() const;109 110 void addEmitter(ParticleEmitter* emitter);111 void addEmitterXML(const TiXmlElement* emitterRoot);112 void removeEmitter(ParticleEmitter* emitter);113 114 virtual void applyField(Field* field);115 /** \brief this is an empty function, because the Physics are implemented in tick @param dt: useless here */116 virtual void tickPhys(float dt) {};117 118 void addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data = 0);119 120 virtual void tick(float dt);121 29 virtual void draw() const; 122 30 123 31 void debug() const; 124 32 125 private: 126 float conserve; //!< How much energy gets conserved to the next Tick. 127 float lifeSpan; //!< Initial lifetime of a Particle. 128 float randomLifeSpan; //!< A random value for the Lifespan (around the initial lifetime) 129 float initialMass; //!< The initial Mass of the Particle 130 float randomInitialMass; //!< The random initial Mass of the Particle 33 private: 34 void init(); 131 35 132 int maxCount; //!< The maximum count of Particles. 133 int count; //!< The current count of Particles. 134 PARTICLE_TYPE particleType; //!< A type for all the Particles 135 Material* material; //!< A Material for all the Particles. 136 Particle* particles; //!< A list of particles of this System. 137 Particle* deadList; //!< A list of dead Particles in the System. 138 139 GLuint* glID; //!< A List of different gl-List-ID's 140 GLuint dialectCount; //!< How many different types of particles are there in the Particle System 141 142 std::list<ParticleEmitter*> emitters; //!< The Emitters that do emit into this System. 143 144 // per particle attributes 145 QuickAnimation radiusAnim; //!< Animation of the radius 146 QuickAnimation randRadiusAnim; //!< Animation of the random Value of the radius 147 QuickAnimation massAnim; //!< Animation of the mass 148 QuickAnimation randMassAnim; //!< Animation of the random Mass 149 QuickAnimation colorAnim[4]; //!< Animation of the 4 colors (r,g,b,a) 36 private: 37 Material material; //!< A Material for all the Particles. 150 38 }; 151 39 152 #endif /* _ PARTICLE_SYSTEM_H */40 #endif /* _SPRITE_PARTICLE_SYSTEM_H */
Note: See TracChangeset
for help on using the changeset viewer.