00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00040 #include "omicron/internal.h"
00041 #include "omicron/render.h"
00042 #include "omicron/texture.h"
00043 #include "omicron/particle.h"
00044
00045 #include "omicron/array.h"
00046
00047 #define PCOUNT_GROWTH 100
00048
00049
00050
00051
00052
00053
00054
00055 particle_type_c::particle_type_c()
00056 {
00057 particlecount = PCOUNT_GROWTH;
00058 particles = new particle_t[particlecount];
00059
00060 verts = new vertex_t[4*particlecount];
00061 vertexcount = 4*particlecount;
00062
00063 begincolor.set(1,1,1,1);
00064 endcolor.set(1,1,1,1);
00065
00066 beginsize.set(1,1);
00067 endsize.set(1,1);
00068
00069 anglespeed.clear();
00070 startangle.clear();
00071
00072 force.set(0,0,-1);
00073
00074 mass = 1;
00075
00076
00077 sparkle = 0;
00078 }
00079
00080 particle_type_c::~particle_type_c()
00081 {
00082 SafeArrayDelete(particles);
00083 SafeArrayDelete(verts);
00084 }
00085
00086 void
00087 particle_type_c::update
00088 ()
00089 {
00090 ulong i;
00091
00092 for (i=0; i<particlecount; i++)
00093 {
00094 if (!particles[i].alife)
00095 continue;
00096
00097 float age = gv.time - particles[i].birthtime;
00098 float agefrac = age / lifetime;
00099
00100 if (agefrac>1)
00101 particles[i].alife = false;
00102
00103 agefrac += frand(-sparkle, sparkle);
00104
00105 if (agefrac<0) agefrac = 0;
00106 if (agefrac>1) agefrac = 1;
00107
00108 particles[i].speed = particles[i].speed + force * gv.dtime * mass;
00109 particles[i].pos = particles[i].pos + particles[i].speed * gv.dtime;
00110
00111 particles[i].size = vec2_c::linear(beginsize, endsize, agefrac);
00112
00113 particles[i].angle += particles[i].anglespeed*gv.time;
00114 }
00115 }
00116
00117 void
00118 particle_type_c::draw
00119 ()
00120 {
00121 ulong i;
00122 ulong activecount = 0;
00123
00124 if (vertexcount<particlecount*4)
00125 {
00126 SafeArrayDelete(verts);
00127
00128 verts = new vertex_t[4*particlecount];
00129 vertexcount = 4*particlecount;
00130 }
00131
00132 vec3_c vright, vup, vdirinv;
00133
00134 vdirinv = gv.renderer->get_viewdir() * (-1);
00135
00136 ulong bc, ec;
00137
00138 bc = color_from_vec(begincolor);
00139 ec = color_from_vec(endcolor);
00140
00141 for (i=0; i<particlecount; i++)
00142 {
00143 if (!particles[i].alife)
00144 continue;
00145
00146 vec3_c pos;
00147 vec3_c vecs[4];
00148
00149 float age, agefrac;
00150
00151 age = gv.time - particles[i].birthtime;
00152 agefrac = (age / lifetime)+frand(-sparkle, sparkle);
00153
00154 if (agefrac<0) agefrac = 0;
00155 if (agefrac>1) agefrac = 1;
00156
00157 pos = particles[i].pos;
00158
00159 vright = gv.renderer->get_viewright().rotate_vec(particles[i].angle, vdirinv);
00160 vup = gv.renderer->get_viewup2().rotate_vec(particles[i].angle, vdirinv);
00161
00162 vecs[0] = pos - (vright * (particles[i].size[0]/2)) - (vup * (particles[i].size[1]/2));
00163 vecs[1] = pos + (vright * (particles[i].size[0]/2)) - (vup * (particles[i].size[1]/2));
00164 vecs[2] = pos + (vright * (particles[i].size[0]/2)) + (vup * (particles[i].size[1]/2));
00165 vecs[3] = pos - (vright * (particles[i].size[0]/2)) + (vup * (particles[i].size[1]/2));
00166
00167 vertex_set(&verts[activecount*4+0], vecs[0][0], vecs[0][1] , vecs[0][2], 0, 0);
00168 vertex_set(&verts[activecount*4+1], vecs[1][0], vecs[1][1] , vecs[1][2], 1, 0);
00169 vertex_set(&verts[activecount*4+2], vecs[2][0], vecs[2][1] , vecs[2][2], 1, 1);
00170 vertex_set(&verts[activecount*4+3], vecs[3][0], vecs[3][1] , vecs[3][2], 0, 1);
00171
00172 verts[activecount*4+0].diffuse =
00173 verts[activecount*4+1].diffuse =
00174 verts[activecount*4+2].diffuse =
00175 verts[activecount*4+3].diffuse = color_interpolate(bc, ec, agefrac);
00176
00177 vdirinv.copy(verts[activecount*4+0].normal);
00178 vdirinv.copy(verts[activecount*4+1].normal);
00179 vdirinv.copy(verts[activecount*4+2].normal);
00180 vdirinv.copy(verts[activecount*4+3].normal);
00181
00182 activecount++;
00183 }
00184
00185 if (activecount)
00186 {
00187 gv.texman->set(texture);
00188 gv.renderer->set_blending(blendtype);
00189 gv.renderer->use_vertices(verts, activecount*4);
00190
00191 glMatrixMode(GL_TEXTURE);
00192 glLoadIdentity();
00193
00194 gv.renderer->push_vertices(PT_QUADS, activecount*4);
00195
00196 }
00197 }
00198
00199 void
00200 particle_type_c::new_particle
00201 (
00202 const vec3_t pos,
00203 const vec3_t speed
00204 )
00205 {
00206 ulong i;
00207
00208 for (i=0; i<particlecount; i++)
00209 {
00210 if (particles[i].alife == false)
00211 break;
00212 }
00213
00214 if (i==particlecount)
00215 {
00216 particle_t *newparticles = new particle_t[PCOUNT_GROWTH+particlecount];
00217
00218 memcpy(newparticles, particles, sizeof(particle_t)*particlecount);
00219
00220 SafeArrayDelete(particles);
00221 particles = newparticles;
00222 particlecount += PCOUNT_GROWTH;
00223 }
00224
00225 particles[i].alife = true;
00226
00227 particles[i].pos = pos;
00228 particles[i].speed = speed;
00229
00230 particles[i].color = begincolor;
00231
00232 particles[i].size = beginsize;
00233
00234 particles[i].birthtime = gv.time;
00235
00236 particles[i].anglespeed = frand(anglespeed[0], anglespeed[1]);
00237 particles[i].angle = frand(startangle[0], startangle[1]);
00238 }