/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PARTICLE #include "particle_system.h" #include "particle_emitter.h" #include "particle_engine.h" #include "compiler.h" using namespace std; /** \brief standard constructor \param count the Count of particles in the System \param type The Type of the ParticleSystem \todo this constructor is not jet implemented - do it */ ParticleSystem::ParticleSystem (unsigned int maxCount, PARTICLE_TYPE type) { this->setClassName ("ParticleSystem"); this->maxCount = maxCount; this->count = 0; this->particleType = type; this->particles = NULL; this->setConserve(.8); this->setLifeSpan(.1); ParticleEngine::getInstance()->addSystem(this); } /** \brief standard deconstructor */ ParticleSystem::~ParticleSystem() { // delete what has to be deleted here ParticleEngine::getInstance()->removeSystem(this); } // setting properties void ParticleSystem::setMaterial(Material* material) { this->material = material; } void ParticleSystem::setLifeSpan(float lifeSpan, float randomLifeSpan) { this->lifeSpan = lifeSpan; this->randomLifeSpan = randomLifeSpan; } void ParticleSystem::setRadius(float startRadius, float endRadius, float randomRadius) { this->startRadius = startRadius; this->endRadius = endRadius; this->randomRadius = randomRadius; } void ParticleSystem::setConserve(float conserve) { if (conserve > 1.0) this->conserve = 1.0; else if (conserve < 0.0) this->conserve = 0.0; else this->conserve = conserve; } void ParticleSystem::tick(float dt) { Particle* tickPart = particles; // the particle to Tick Particle* prevPart = NULL; // while (likely(tickPart != NULL)) { tickPart->position = tickPart->position + tickPart->velocity; // many more to come if (this->conserve < 1.0) tickPart->velocity = tickPart->velocity * this->conserve; // find out if we have to delete tickPart if ((tickPart->timeToLive -= dt) <= 0) { // remove the particle from the list if (likely(prevPart != NULL)) { prevPart->next = tickPart->next; delete tickPart; tickPart = prevPart->next; } else { prevPart = NULL; this->particles = tickPart->next; delete tickPart; tickPart = this->particles; } --this->count; } else { prevPart = tickPart; tickPart = tickPart->next; } } } void ParticleSystem::draw(void) { Particle* drawPart = particles; if (likely(drawPart != NULL)) { glBegin(GL_POINTS); while (likely(drawPart != NULL)) { // draw in DOT mode glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z); drawPart = drawPart->next; } glEnd(); } } void ParticleSystem::addParticle(Vector position, Vector velocity, unsigned int data) { if (this->count <= this->maxCount) { // if it is the first Particle if (unlikely(particles == NULL)) { this->particles = new Particle; this->particles->next = NULL; } // filling the List from the beginning else { Particle* tmpPart = new Particle; tmpPart->next = this->particles; this->particles = tmpPart; } particles->timeToLive = this->lifeSpan + (float)(random()/RAND_MAX)* this->randomLifeSpan; particles->position = position; particles->velocity = velocity; // particle->rotation = ; //! \todo rotation is once again something to be done. particles->mass = this->initialMass + (random()/RAND_MAX)* this->randomInitialMass; particles->radius = this->startRadius + (random()/RAND_MAX)*this->randomRadius; ++this->count; } else PRINTF(4)("maximum count of particles reached not adding any more\n"); }