/* * This program is under the GNU GPL. * Use at your own risk. * * written by David Bucciarelli (humanware@plus.it) * Humanware s.r.l. */ #include #include "particles.h" #define vinit(a,i,j,k) {\ (a)[0]=i;\ (a)[1]=j;\ (a)[2]=k;\ } #define vadds(a,dt,b) {\ (a)[0]+=(dt)*(b)[0];\ (a)[1]+=(dt)*(b)[1];\ (a)[2]+=(dt)*(b)[2];\ } #define vequ(a,b) {\ (a)[0]=(b)[0];\ (a)[1]=(b)[1];\ (a)[2]=(b)[2];\ } #define vinter(a,dt,b,c) {\ (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ } #define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) #define vclamp(v) {\ (v)[0]=clamp((v)[0]);\ (v)[1]=clamp((v)[1]);\ (v)[2]=clamp((v)[2]);\ } float rainParticle::min[3]; float rainParticle::max[3]; float rainParticle::partLength=0.2f; static float vrnd(void) { return(((float)rand())/RAND_MAX); } particle::particle() { age=0.0f; vinit(acc,0.0f,0.0f,0.0f); vinit(vel,0.0f,0.0f,0.0f); vinit(pos,0.0f,0.0f,0.0f); } void particle::elapsedTime(float dt) { age+=dt; vadds(vel,dt,acc); vadds(pos,dt,vel); } ///////////////////////////////////////// // Particle System ///////////////////////////////////////// particleSystem::particleSystem() { t=0.0f; part=NULL; particleNum=0; } particleSystem::~particleSystem() { if(part) free(part); } void particleSystem::addParticle(particle *p) { if(!part) { part=(particle **)calloc(1,sizeof(particle *)); part[0]=p; particleNum=1; } else { particleNum++; part=(particle **)realloc(part,sizeof(particle *)*particleNum); part[particleNum-1]=p; } } void particleSystem::reset(void) { if(part) free(part); t=0.0f; part=NULL; particleNum=0; } void particleSystem::draw(void) { if(!part) return; part[0]->beginDraw(); for(unsigned int i=0;idraw(); part[0]->endDraw(); } void particleSystem::addTime(float dt) { if(!part) return; for(unsigned int i=0;ielapsedTime(dt); part[i]->checkAge(); } } ///////////////////////////////////////// // Rain ///////////////////////////////////////// void rainParticle::init(void) { age=0.0f; acc[0]=0.0f; acc[1]=-0.98f; acc[2]=0.0f; vel[0]=0.0f; vel[1]=0.0f; vel[2]=0.0f; oldpos[0]=pos[0]=min[0]+(max[0]-min[0])*vrnd(); oldpos[1]=pos[1]=max[1]+0.2f*max[1]*vrnd(); oldpos[2]=pos[2]=min[2]+(max[2]-min[2])*vrnd(); vadds(oldpos,-partLength,vel); } rainParticle::rainParticle() { init(); } void rainParticle::setRainingArea(float minx, float miny, float minz, float maxx, float maxy, float maxz) { vinit(min,minx,miny,minz); vinit(max,maxx,maxy,maxz); } void rainParticle::setLength(float l) { partLength=l; } void rainParticle::draw(void) { glColor4f(0.7f,0.95f,1.0f,0.0f); glVertex3fv(oldpos); glColor4f(0.3f,0.7f,1.0f,1.0f); glVertex3fv(pos); } void rainParticle::checkAge(void) { if(pos[1]max[0]) pos[0]=min[0]+(pos[0]-max[0]); if(pos[2]>max[2]) pos[2]=min[2]+(pos[2]-max[2]); vequ(oldpos,pos); vadds(oldpos,-partLength,vel); } void rainParticle::randomHeight(void) { pos[1]=(max[1]-min[1])*vrnd()+min[1]; oldpos[1]=pos[1]-partLength*vel[1]; }