Back to index

supertuxkart  0.5+dfsg1
particle_system.cpp
Go to the documentation of this file.
00001 /*
00002      $Id: particle_system.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00003      PLIB - A Suite of Portable Game Libraries
00004      Copyright (C) 1998,2002  Steve Baker
00005 
00006      This library is free software; you can redistribute it and/or
00007      modify it under the terms of the GNU Library General Public
00008      License as published by the Free Software Foundation; either
00009      version 2 of the License, or (at your option) any later version.
00010 
00011      This library is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014      Library General Public License for more details.
00015 
00016      You should have received a copy of the GNU Library General Public
00017      License along with this library; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 
00020      For further information visit http://plib.sourceforge.net
00021 */
00022 
00023 #include "particle_system.hpp"
00024 
00025 ParticleSystem::ParticleSystem ( int num, float _create_rate, int _ttf,
00026                                  float sz, float bsphere_size)
00027         : ssgVtxTable ( GL_QUADS,
00028             new ssgVertexArray   ( num * 4 /*, new sgVec3 [ num * 4 ]*/ ),
00029             new ssgNormalArray   ( num * 4 /*, new sgVec3 [ num * 4 ]*/ ),
00030             new ssgTexCoordArray ( num * 4 /*, new sgVec2 [ num * 4 ]*/ ),
00031             new ssgColourArray   ( num * 4 /*, new sgVec4 [ num * 4 ]*/ )
00032             )
00033 {
00034     m_turn_to_face = _ttf ;
00035     m_create_error = 0 ;
00036     m_create_rate = _create_rate ;
00037 
00038     m_size = sz ;
00039 
00040     bsphere . setRadius ( bsphere_size ) ;
00041     bsphere . setCenter ( 0, 0, 0 ) ;
00042 
00043     m_num_particles = num ;
00044     m_num_verts     = num * 4 ;
00045 
00046     m_particles = new Particle [ num ] ;
00047 
00048     int i ;
00049 
00050     for ( i = 0 ; i < m_num_verts ; i++ )
00051     {
00052         sgSetVec3  ( getNormal ( i ), 0, -1, 0 ) ;
00053         sgSetVec4  ( getColour ( i ), 1, 1, 1, 1 ) ;
00054         sgZeroVec3 ( getVertex ( i ) ) ;
00055     }
00056 
00057     for ( i = 0 ; i < m_num_particles ; i++ )
00058     {
00059         sgSetVec2 ( getTexCoord ( i*4+0 ), 0, 0 ) ;
00060         sgSetVec2 ( getTexCoord ( i*4+1 ), 1, 0 ) ;
00061         sgSetVec2 ( getTexCoord ( i*4+2 ), 1, 1 ) ;
00062         sgSetVec2 ( getTexCoord ( i*4+3 ), 0, 1 ) ;
00063     }
00064 
00065     m_num_active = 0 ;
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 void
00070 ParticleSystem::init(int initial_num)
00071 {
00072     for ( int i = 0 ; i < initial_num ; i++ )
00073         particle_create(i, & m_particles [ i ] ) ;
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 void
00078 ParticleSystem::recalcBSphere()
00079 {
00080     bsphere . setRadius ( 1000.0f ) ;
00081     bsphere . setCenter ( 0, 0, 0 ) ;
00082 }
00083 
00084 //-----------------------------------------------------------------------------
00085 void ParticleSystem::draw_geometry ()
00086 {
00087     sgVec3 nxny, xxny, xxyy, nxyy ;
00088 
00089     float SZ = m_size / 2.0f ;
00090 
00091     if ( m_turn_to_face )
00092     {
00093         sgMat4 mat ;
00094 
00095         glGetFloatv ( GL_MODELVIEW_MATRIX, (float *) mat ) ;
00096 
00097         sgVec3 xx, yy ;
00098 
00099         sgSetVec3 ( xx, mat[0][0] * SZ, mat[1][0] * SZ, mat[2][0] * SZ ) ;
00100         sgSetVec3 ( yy, mat[0][1] * SZ, mat[1][1] * SZ, mat[2][1] * SZ ) ;
00101 
00102         sgSetVec3 ( nxny, -xx[0]-yy[0], -xx[1]-yy[1], -xx[2]-yy[2] ) ;
00103         sgSetVec3 ( nxyy, -xx[0]+yy[0], -xx[1]+yy[1], -xx[2]+yy[2] ) ;
00104         sgSetVec3 ( xxny,  xx[0]-yy[0],  xx[1]-yy[1],  xx[2]-yy[2] ) ;
00105         sgSetVec3 ( xxyy,  xx[0]+yy[0],  xx[1]+yy[1],  xx[2]+yy[2] ) ;
00106     }
00107     else
00108     {
00109         sgSetVec3 ( xxny ,  SZ, 0, -SZ ) ;
00110         sgSetVec3 ( nxny , -SZ, 0, -SZ ) ;
00111         sgSetVec3 ( nxyy , -SZ, 0,  SZ ) ;
00112         sgSetVec3 ( xxyy,   SZ, 0,  SZ ) ;
00113     }
00114 
00115     int j = 0 ;
00116 
00117     for ( int i = 0 ; i < m_num_particles ; i++ )
00118     {
00119         /* Make them disappear if not needed */
00120 
00121         if ( m_particles[i].m_time_to_live <= 0.0f )
00122             continue ;
00123 
00124         sgCopyVec4 ( getColour ( j + 0 ), m_particles[i].m_col ) ;
00125         sgCopyVec4 ( getColour ( j + 1 ), m_particles[i].m_col ) ;
00126         sgCopyVec4 ( getColour ( j + 2 ), m_particles[i].m_col ) ;
00127         sgCopyVec4 ( getColour ( j + 3 ), m_particles[i].m_col ) ;
00128 
00129         sgAddScaledVec3 ( getVertex ( j + 0 ), m_particles[i].m_pos,
00130                           nxny, m_particles[i].m_size ) ;
00131         sgAddScaledVec3 ( getVertex ( j + 1 ), m_particles[i].m_pos,
00132                           xxny, m_particles[i].m_size ) ;
00133         sgAddScaledVec3 ( getVertex ( j + 2 ), m_particles[i].m_pos,
00134                           xxyy, m_particles[i].m_size ) ;
00135         sgAddScaledVec3 ( getVertex ( j + 3 ), m_particles[i].m_pos,
00136                           nxyy, m_particles[i].m_size ) ;
00137 
00138         j += 4 ;
00139     }
00140 
00141     rawSetNumVertices ( j ) ; /* Avoid drawing more than 'j' vertices. */
00142 
00143     if ( j > 0 )
00144     {
00145         glDisable   ( GL_CULL_FACE ) ;
00146         glDepthMask ( 0 ) ;
00147 
00148         ssgVtxTable::draw_geometry () ;
00149 
00150         glDepthMask ( 1 ) ;
00151         glEnable ( GL_CULL_FACE ) ;
00152     }
00153 }
00154 
00155 //-----------------------------------------------------------------------------
00156 ParticleSystem::~ParticleSystem ()
00157 {
00158     // TODO we should call particle_delete here, but that's not possible, because
00159     // the functions are virtual (illegal in destructor)
00160 
00161     delete[] m_particles ;
00162 }
00163 
00164 //-----------------------------------------------------------------------------
00165 void ParticleSystem::update ( float t )
00166 {
00167     int i ;
00168 
00169     m_create_error += m_create_rate * t ;
00170 
00171     m_num_active = 0 ;
00172 
00173     /* Call the update routine for all the particles */
00174     for ( i = 0 ; i < m_num_particles ; i++ )
00175         if ( m_particles [ i ] . m_time_to_live > 0.0f )
00176         {
00177             m_particles [ i ] . update ( t ) ;
00178             particle_update( t, i, & m_particles [ i ] ) ;
00179         }
00180 
00181     /* Check for death of particles */
00182     for ( i = 0 ; i < m_num_particles ; i++ )
00183         if ( m_particles [ i ] . m_time_to_live <= 0.0 )
00184         {
00185             particle_delete ( i, & m_particles [ i ] ) ;
00186 
00187             m_particles [ i ] . m_pos [ 2 ] = -1000000.0f ;
00188 
00189             if ( m_create_error >= 1.0f )
00190             {
00191                 particle_create( i, & m_particles [ i ] ) ;
00192                 m_create_error -= 1.0f ;
00193             }
00194         }
00195         else
00196         {
00197             m_num_active++ ;
00198         }
00199 }
00200 
00201 /* EOF */
00202