Back to index

kdeartwork  4.3.2
firesaverparticle.cpp
Go to the documentation of this file.
00001 //     This file is part of KFireSaver3D.
00002 
00003 //     KFireSaver3D is free software; you can redistribute it and/or modify
00004 //     it under the terms of the GNU General Public License as published by
00005 //     the Free Software Foundation; either version 2 of the License, or
00006 //     (at your option) any later version.
00007 
00008 //     KFireSaver3D is distributed in the hope that it will be useful,
00009 //     but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //     GNU General Public License for more details.
00012 
00013 //     You should have received a copy of the GNU General Public License
00014 //     along with KFireSaver3D; if not, write to the Free Software
00015 //     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00016 
00017 
00018 //     Author: Enrico Ros, based on the great work of David Sansome (kfiresaver)
00019 //     Email:  asy@libero.it
00020 
00021 #include <math.h>
00022 #include <stdlib.h>
00023 
00024 #include "firesaverparticle.h"
00025 #include "firesaver.h"
00026 
00027 //current color scheme :           red  orng grn  blue w  m  c
00028 static const GLfloat c_red_min[7] =   { 0.4, 0.9,   0,   0, 1, 0, 0 };
00029 static const GLfloat c_red_max[7] =   {   1,   1,   0,   0, 1, 1, 0 };
00030 static const GLfloat c_green_min[7] = {   0, 0.4, 0.4,   0, 1, 0, 0 };
00031 static const GLfloat c_green_max[7] = {   0, 0.5,   1, 0.5, 1, 0, 1 };
00032 static const GLfloat c_blue_min[7] =  {   0, 0.1,   0, 0.5, 1, 0, 0 };
00033 static const GLfloat c_blue_max[7] =  {   0, 0.2,   0,   1, 1, 1, 1 };
00034 
00035 
00036 //default initialization (good for Leader / Fire)
00037 Particle :: Particle( ParticleType pT )
00038     : particleType( pT ), explosionsDepth( 0 ), texture( 0 ),
00039     xpos( 0.0 ), ypos( 0.0 ), zpos( -9.9 ),
00040     xspeed( 0.0 ), yspeed( 0.0 ), zspeed( 0.0 ), zacc( -9.807 ),
00041     life( 0.0 ), startLife( 0.0 ),
00042     pixelSize( 5.0 ), useLife( true ), flicker( 0 )
00043 {
00044        colour[0] = 0;
00045        colour[1] = 0;
00046        colour[2] = 0;
00047        colour[3] = 1;
00048 }
00049 
00050 
00051 void Particle :: initializeValues (
00052        int cs,
00053        Particle* debrisParent,
00054        GLfloat powermin, GLfloat powermax,
00055        bool flickers,
00056        GLfloat *displace )
00057 //note:       this function is called when a particle needs a set of default parameters.
00058 //     these depends on the ParticleType.
00059 {
00060        switch (particleType)
00061        {
00062 //     -- FireParticle (params: [cs])
00063 //            born in a rectangle centered in { 0, 0, -9.9 }
00064 //            speed 3-6 [m/s] blue/cyan colored
00065 //            this is only done at the beginning or when a particle dies
00066            case FireParticle:
00067               xpos = DRAND * FIELDWIDTH - FIELDW_2;
00068               ypos = DRAND - 2.0;
00069 
00070               xspeed = DRAND * 4.0 - 2.0;
00071               yspeed = DRAND * 2.0;
00072               zspeed = DRAND * 3.0 + 3.0;
00073 
00074               useLife = false;
00075               pixelSize = 2.0 + DRAND * 2.0;
00076               break;
00077 
00078 //     -- FireWorkLeaderParticle (params: none)
00079 //            they start in a rectangle at the same height but
00080 //            with different power and the same 'orange' colour
00081            case FireWorkLeaderParticle:
00082               xpos = DRAND * 14.0 - 7.0;
00083               ypos = DRAND * 2.0 - 1.0;
00084 
00085               xspeed = DRAND * 8.0 - 4.0 - (xpos / 2.0)*DRAND;
00086               yspeed = DRAND * 8.0 - 4.0;
00087               zspeed = DRAND * 6.5 + 18.0;
00088 
00089               colour[0] = 0.6;
00090               colour[1] = DRAND * 0.4;
00091               colour[2] = 0.0;
00092 
00093               useLife = false;
00094               break;
00095 
00096 //     -- LogoParticle (params: none)
00097 //            they start in the middle of the screen.
00098 //            little g-force, constant life, weavy-y
00099            case LogoParticle:
00100               yspeed = 3*(DRAND - DRAND);
00101               zacc = -9.807f / 5.0f;
00102 
00103               startLife = 0.7f;
00104               life = 1.7f;
00105               break;
00106 
00107 //     -- StarParticle (params: none)
00108 //            spherically distributed. xpos and ypos are the
00109 //            transformed screen positions of the star.
00110            case StarParticle:
00111               colour[0] = DRAND * 0.2 + 0.5;
00112               colour[1] = DRAND * 0.2 + 0.5;
00113               colour[2] = DRAND * 0.2 + 0.5;
00114 
00115               {bool accepted = false;
00116               while (!accepted) {
00117                      float module = 30,
00118                            theta = DRAND * M_PI * 2.0,
00119                            u = DRAND * 2.0 - 1.0,
00120                            root = sqrt( 1 - u*u );
00121                      xpos = module * root * cos(theta);
00122                      ypos = fabs(module * root * sin(theta)) - 10.0;
00123                      zpos = fabs(module * u);
00124 
00125                      float sfactor = 256.0 / (256.0 + PERSP_MAG_FACTOR*ypos);
00126                      xpos *= sfactor;
00127                      ypos = sfactor * zpos - FIELDW_2;
00128 
00129                      pixelSize = sfactor * (2.0 + 3.0*DRAND);
00130 
00131                      accepted = xpos > -FIELDW_2 && xpos < FIELDW_2 &&
00132                                ypos > -FIELDW_2 && ypos < FIELDW_2;
00133               }}
00134               break;
00135 
00136 //     -- FireWorkDebrisParticle (params: cs, parent, [powerm], [powerM], [flickers], [displace])
00137 //            parameters are randomized for a 'spherical' explosion.
00138 //            power{min,max}, flickers and displace applies only for that
00139 //            kind of ParticleType.
00140            case FireWorkDebrisParticle:
00141 
00142               //same origin of the dead leader
00143               xpos = debrisParent->xpos;
00144               ypos = debrisParent->ypos;
00145               zpos = debrisParent->zpos;
00146 
00147               //true spherical randomization
00148               float module = powermin + DRAND * (powermax - powermin),
00149                     theta = DRAND * M_PI * 2.0,
00150                     u = DRAND * 2.0 - 1.0,
00151                     root = sqrt( 1 - u*u );
00152               xspeed = debrisParent->xspeed + module * root * cos(theta) * (1.0 + DRAND/3.0);
00153               yspeed = debrisParent->yspeed + module * root * sin(theta) * (1.0 + DRAND/3.0);
00154               zspeed = module * u * (1.0 + DRAND/3.0);  //was 0.9 + DRAND/3
00155 
00156               //if set add a displace to speed
00157               if ( displace ) {
00158                      xspeed += displace[0];
00159                      yspeed += displace[1];
00160                      zspeed += displace[2];
00161               }
00162 
00163               //randomize the color choosing on current palette
00164               colour[0] = c_red_min[cs] + (c_red_max[cs]-c_red_min[cs]) * DRAND;
00165               colour[1] = c_green_min[cs] + (c_green_max[cs]-c_green_min[cs]) * DRAND;
00166               colour[2] = c_blue_min[cs] + (c_blue_max[cs]-c_blue_min[cs]) * DRAND;
00167 
00168               pixelSize = DRAND * 2.0 + 2.0;
00169               zacc = -9.807 / (6.0 - pixelSize);
00170 
00171               life = startLife = pixelSize / 2.0;
00172 
00173               //if flickers is set the current visible delay is randomized
00174               if ( flickers )
00175                      flicker = (int) ((DRAND * 2.0 - 1.0) * (float)FLICKER_FRAMES_DELAY);
00176               break;
00177        }
00178 }
00179 
00180 
00181 void Particle :: updateParameters( float dT )
00182 //note:       this procedure uses a reduced set of parameters
00183 //     x and y axis acceleration is no more used
00184 //     the only external iterations are:
00185 //     - the g force
00186 //     - a sort of air friction that limits speed in x,y and
00187 //       acceleration on z
00188 {
00189        xpos += xspeed * dT;
00190        ypos += yspeed * dT;
00191        zpos += (zspeed + zacc*dT/2) * dT;
00192 
00193        zspeed += zacc * dT;
00194 
00195        xspeed *= 0.998;
00196        yspeed *= 0.998;
00197        zspeed *= 0.999;
00198 
00199        if (useLife)
00200            life -= dT;
00201 }
00202 
00203 
00204 // BEGIN TurningParticle class 
00205 
00206 TurningParticle :: TurningParticle( ParticleType pT )
00207        : Particle( pT ) {}
00208 
00209 void TurningParticle :: initializeValues (
00210        int cs,
00211        Particle* leader,
00212        GLfloat powermin,
00213        GLfloat powermax,
00214        bool /*flickers*/,
00215        GLfloat * /*displace*/ )
00216 {
00217        //same origin of the parent
00218        xpos = leader->xpos;
00219        ypos = leader->ypos;
00220        zpos = leader->zpos;
00221 
00222        //velocity : true spherical randomization
00223        float   module = powermin + (powermax - powermin) * DRAND * 0.6,
00224               theta = DRAND * M_PI * 2.0,
00225               u = DRAND * 2.0 - 1.0,
00226               root = sqrt( 1 - u*u );
00227        xspeed = -module * root * cos(theta);
00228        yspeed = -module * root * sin(theta);
00229        zspeed = module * u;
00230 
00231        //spin axis : in quadrature with velocity
00232        module = (1 + DRAND) / 40;
00233        u = DRAND * 2.0 - 1.0;
00234        root = sqrt( 1 - u*u );
00235        // axis to spin around
00236        wx = module * root * cos(theta + M_PI_2);
00237        wy = module * root * sin(theta + M_PI_2);
00238        wz = module * u;
00239 
00240        //randomize the color choosing on current palette
00241        colour[0] = c_red_min[cs] + (c_red_max[cs]-c_red_min[cs]) * DRAND;
00242        colour[1] = c_green_min[cs] + (c_green_max[cs]-c_green_min[cs]) * DRAND;
00243        colour[2] = c_blue_min[cs] + (c_blue_max[cs]-c_blue_min[cs]) * DRAND;
00244 
00245         pixelSize = DRAND * 2.0 + 2.0;
00246        zacc = -9.807 / 5.0;
00247        life = startLife = pixelSize / 2.0;
00248 }
00249 
00250 
00251 void TurningParticle :: updateParameters ( float dT )
00252 {
00253        //update position
00254        xpos += xspeed * dT;
00255        ypos += yspeed * dT;
00256        zpos += zspeed * dT;
00257 
00258        //tan vector = velocity vector (vect producted by) spin axis
00259        float vx = yspeed * wz - zspeed * wy,
00260              vy = zspeed * wx - xspeed * wz,
00261              vz = xspeed * wy - yspeed * wx;
00262 
00263        //update velocity adding a tangential component (aka infinitesimally
00264        //rotating the vector)
00265        xspeed += vx;
00266        yspeed += vy;
00267        zspeed += vz + zacc * dT;
00268 
00269        if (useLife)
00270               life -= dT;
00271 }
00272 
00273 //END TurningParticle