1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 */
22
23 #include "ssgAux.h"
24
ssgaParticleSystem(int num,int initial_num,float _create_rate,int _ttf,float sz,float bsphere_size,ssgaParticleCreateFunc _particle_create,ssgaParticleUpdateFunc _particle_update,ssgaParticleDeleteFunc _particle_delete)25 ssgaParticleSystem::ssgaParticleSystem ( int num, int initial_num,
26 float _create_rate, int _ttf,
27 float sz, float bsphere_size,
28 ssgaParticleCreateFunc _particle_create,
29 ssgaParticleUpdateFunc _particle_update,
30 ssgaParticleDeleteFunc _particle_delete ) :
31 ssgVtxTable ( GL_QUADS,
32 new ssgVertexArray ( num * 4, new sgVec3 [ num * 4 ] ),
33 new ssgNormalArray ( num * 4, new sgVec3 [ num * 4 ] ),
34 new ssgTexCoordArray ( num * 4, new sgVec2 [ num * 4 ] ),
35 new ssgColourArray ( num * 4, new sgVec4 [ num * 4 ] ) )
36 {
37 turn_to_face = _ttf ;
38 create_error = 0 ;
39 create_rate = _create_rate ;
40 particle_create = _particle_create ;
41 particle_update = _particle_update ;
42 particle_delete = _particle_delete ;
43
44 size = sz ;
45
46 num_particles = num ;
47 num_verts = num * 4 ;
48
49 getBSphere () -> setRadius ( bsphere_size ) ;
50 getBSphere () -> setCenter ( 0, 0, 0 ) ;
51
52 particle = new ssgaParticle [ num ] ;
53
54 int i ;
55
56 for ( i = 0 ; i < num_verts ; i++ )
57 {
58 sgSetVec3 ( getNormal ( i ), 0, -1, 0 ) ;
59 sgSetVec4 ( getColour ( i ), 1, 1, 1, 1 ) ;
60 sgZeroVec3 ( getVertex ( i ) ) ;
61 }
62
63 for ( i = 0 ; i < num_particles ; i++ )
64 {
65 sgSetVec2 ( getTexCoord ( i*4+0 ), 0, 0 ) ;
66 sgSetVec2 ( getTexCoord ( i*4+1 ), 1, 0 ) ;
67 sgSetVec2 ( getTexCoord ( i*4+2 ), 1, 1 ) ;
68 sgSetVec2 ( getTexCoord ( i*4+3 ), 0, 1 ) ;
69 }
70
71 num_active = 0 ;
72
73 if ( particle_create )
74 for ( i = 0 ; i < initial_num ; i++ )
75 (*particle_create) ( this, i, & particle [ i ] ) ;
76 }
77
78
draw_geometry()79 void ssgaParticleSystem::draw_geometry ()
80 {
81 sgVec3 nxny, xxny, xxyy, nxyy ;
82
83 float sz = size / 2.0f ;
84
85 if ( turn_to_face )
86 {
87 sgMat4 mat ;
88
89 glGetFloatv ( GL_MODELVIEW_MATRIX, (float *) mat ) ;
90
91 sgVec3 xx, yy ;
92
93 sgSetVec3 ( xx, mat[0][0] * sz, mat[1][0] * sz, mat[2][0] * sz ) ;
94 sgSetVec3 ( yy, mat[0][1] * sz, mat[1][1] * sz, mat[2][1] * sz ) ;
95
96 sgSetVec3 ( nxny, -xx[0]-yy[0], -xx[1]-yy[1], -xx[2]-yy[2] ) ;
97 sgSetVec3 ( nxyy, -xx[0]+yy[0], -xx[1]+yy[1], -xx[2]+yy[2] ) ;
98 sgSetVec3 ( xxny, xx[0]-yy[0], xx[1]-yy[1], xx[2]-yy[2] ) ;
99 sgSetVec3 ( xxyy, xx[0]+yy[0], xx[1]+yy[1], xx[2]+yy[2] ) ;
100 }
101 else
102 {
103 sgSetVec3 ( xxny , sz, 0, -sz ) ;
104 sgSetVec3 ( nxny , -sz, 0, -sz ) ;
105 sgSetVec3 ( nxyy , -sz, 0, sz ) ;
106 sgSetVec3 ( xxyy, sz, 0, sz ) ;
107 }
108
109 int j = 0 ;
110
111 for ( int i = 0 ; i < num_particles ; i++ )
112 {
113 /* Make them disappear if not needed */
114
115 if ( particle[i].time_to_live <= 0.0f )
116 continue ;
117
118 sgCopyVec4 ( getColour ( j + 0 ), particle[i].col ) ;
119 sgCopyVec4 ( getColour ( j + 1 ), particle[i].col ) ;
120 sgCopyVec4 ( getColour ( j + 2 ), particle[i].col ) ;
121 sgCopyVec4 ( getColour ( j + 3 ), particle[i].col ) ;
122
123 sgAddScaledVec3 ( getVertex ( j + 0 ), particle[i].pos,
124 nxny, particle[i].size ) ;
125 sgAddScaledVec3 ( getVertex ( j + 1 ), particle[i].pos,
126 xxny, particle[i].size ) ;
127 sgAddScaledVec3 ( getVertex ( j + 2 ), particle[i].pos,
128 xxyy, particle[i].size ) ;
129 sgAddScaledVec3 ( getVertex ( j + 3 ), particle[i].pos,
130 nxyy, particle[i].size ) ;
131
132 j += 4 ;
133 }
134
135 rawSetNumVertices ( j ) ; /* Avoid drawing more than 'j' vertices. */
136
137 if ( j > 0 )
138 {
139 glDisable ( GL_CULL_FACE ) ;
140 glDepthMask ( 0 ) ;
141
142 ssgVtxTable::draw_geometry () ;
143
144 glDepthMask ( 1 ) ;
145 glEnable ( GL_CULL_FACE ) ;
146 }
147 }
148
149
~ssgaParticleSystem()150 ssgaParticleSystem::~ssgaParticleSystem ()
151 {
152 if ( particle_delete )
153 for ( int i = 0 ; i < num_particles ; i++ )
154 if ( particle [ i ] . time_to_live >= 0.0 )
155 (*particle_delete) ( this, i, & particle [ i ] ) ;
156
157 delete [] particle ;
158 }
159
160
update(float t)161 void ssgaParticleSystem::update ( float t )
162 {
163 int i ;
164
165 create_error += create_rate * t ;
166
167 num_active = 0 ;
168
169 /* Call the update routine for all the particles */
170
171 if ( particle_update )
172 {
173 for ( i = 0 ; i < num_particles ; i++ )
174 if ( particle [ i ] . time_to_live > 0.0f )
175 {
176 particle [ i ] . update ( t ) ;
177 (*particle_update) ( t, this, i, & particle [ i ] ) ;
178 }
179 }
180 else
181 for ( i = 0 ; i < num_particles ; i++ )
182 if ( particle [ i ] . time_to_live > 0.0f )
183 particle [ i ] . update ( t ) ;
184
185 /* Check for death of particles */
186
187 for ( i = 0 ; i < num_particles ; i++ )
188 if ( particle [ i ] . time_to_live <= 0.0 )
189 {
190 if ( particle_delete )
191 (*particle_delete) ( this, i, & particle [ i ] ) ;
192
193 particle [ i ] . pos [ 2 ] = -1000000.0f ;
194
195 if ( create_error >= 1.0f && particle_create )
196 {
197 (*particle_create) ( this, i, & particle [ i ] ) ;
198 create_error -= 1.0f ;
199 }
200 }
201 else
202 num_active++ ;
203 }
204
205
206