diff options
Diffstat (limited to 'src/engine/renderparticles.cpp')
| -rw-r--r-- | src/engine/renderparticles.cpp | 675 |
1 files changed, 196 insertions, 479 deletions
diff --git a/src/engine/renderparticles.cpp b/src/engine/renderparticles.cpp index 392e943..dbdf855 100644 --- a/src/engine/renderparticles.cpp +++ b/src/engine/renderparticles.cpp @@ -11,8 +11,7 @@ VARP(emitmillis, 1, 17, 1000); static int lastemitframe = 0, emitoffset = 0; static bool canemit = false, regenemitters = false, canstep = false; -static bool canemitparticles() -{ +static bool canemitparticles() { return canemit || emitoffset; } @@ -21,29 +20,23 @@ VAR(cullparticles, 0, 1, 1); VAR(replayparticles, 0, 1, 1); VARN(seedparticles, seedmillis, 0, 3000, 10000); -struct particleemitter -{ +struct particleemitter { extentity *ent; vec bbmin, bbmax; vec center; float radius; ivec cullmin, cullmax; int maxfade, lastemit, lastcull; - particleemitter(extentity *ent) - : ent(ent), bbmin(ent->o), bbmax(ent->o), maxfade(-1), lastemit(0), lastcull(0) - {} - - void finalize() - { + : ent(ent), bbmin(ent->o), bbmax(ent->o), maxfade(-1), lastemit(0), lastcull(0) { + } + void finalize() { center = vec(bbmin).add(bbmax).mul(0.5f); radius = bbmin.dist(bbmax)/2; cullmin = ivec(int(floor(bbmin.x)), int(floor(bbmin.y)), int(floor(bbmin.z))); cullmax = ivec(int(ceil(bbmax.x)), int(ceil(bbmax.y)), int(ceil(bbmax.z))); } - - void extendbb(const vec &o, float size = 0) - { + void extendbb(const vec &o, float size = 0) { bbmin.x = min(bbmin.x, o.x - size); bbmin.y = min(bbmin.y, o.y - size); bbmin.z = min(bbmin.z, o.z - size); @@ -51,9 +44,7 @@ struct particleemitter bbmax.y = max(bbmax.y, o.y + size); bbmax.z = max(bbmax.z, o.z + size); } - - void extendbb(float z, float size = 0) - { + void extendbb(float z, float size = 0) { bbmin.z = min(bbmin.z, z - size); bbmax.z = max(bbmax.z, z + size); } @@ -62,18 +53,15 @@ struct particleemitter static vector<particleemitter> emitters; static particleemitter *seedemitter = NULL; -void clearparticleemitters() -{ +void clearparticleemitters() { emitters.setsize(0); regenemitters = true; } -void addparticleemitters() -{ +void addparticleemitters() { emitters.setsize(0); const vector<extentity *> &ents = entities::getents(); - loopv(ents) - { + loopv(ents) { extentity &e = *ents[i]; if(e.type != ET_PARTICLES) continue; emitters.add(particleemitter(&e)); @@ -81,8 +69,7 @@ void addparticleemitters() regenemitters = false; } -enum -{ +enum { PT_PART = 0, PT_TAPE, PT_TRAIL, @@ -90,10 +77,7 @@ enum PT_TEXTICON, PT_METER, PT_METERVS, - PT_FIREBALL, - PT_LIGHTNING, PT_FLARE, - PT_MOD = 1<<8, PT_RND4 = 1<<9, PT_LERP = 1<<10, // use very sparingly - order of blending issues @@ -111,30 +95,26 @@ enum PT_FLIP = PT_HFLIP | PT_VFLIP | PT_ROT }; -const char *partnames[] = { "part", "tape", "trail", "text", "texticon", "meter", "metervs", "fireball", "lightning", "flare" }; +const char *partnames[] = { "part", "tape", "trail", "text", "texticon", "meter", "metervs", "flare" }; -struct particle -{ +struct particle { vec o, d; int gravity, fade, millis; bvec color; uchar flags; float size; - union - { + union { const char *text; float val; physent *owner; - struct - { + struct { uchar color2[3]; uchar progress; }; }; }; -struct partvert -{ +struct partvert { vec pos; bvec4 color; vec2 tc; @@ -143,27 +123,21 @@ struct partvert #define COLLIDERADIUS 8.0f #define COLLIDEERROR 1.0f -struct partrenderer -{ +struct partrenderer { Texture *tex; const char *texname; int texclamp; uint type; int collide; string info; - partrenderer(const char *texname, int texclamp, int type, int collide = 0) - : tex(NULL), texname(texname), texclamp(texclamp), type(type), collide(collide) - { + : tex(NULL), texname(texname), texclamp(texclamp), type(type), collide(collide) { } partrenderer(int type, int collide = 0) - : tex(NULL), texname(NULL), texclamp(0), type(type), collide(collide) - { + : tex(NULL), texname(NULL), texclamp(0), type(type), collide(collide) { } - virtual ~partrenderer() - { + virtual ~partrenderer() { } - virtual void init(int n) { } virtual void reset() = 0; virtual void resettracked(physent *owner) { } @@ -172,44 +146,34 @@ struct partrenderer virtual void render() = 0; virtual bool haswork() = 0; virtual void cleanup() {} - - virtual void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) - { + virtual void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) { } - //blend = 0 => remove it - void calc(particle *p, int &blend, int &ts, vec &o, vec &d, bool step = true) - { + void calc(particle *p, int &blend, int &ts, vec &o, vec &d, bool step = true) { o = p->o; d = p->d; if(type&PT_TRACK && p->owner) game::particletrack(p->owner, o, d); - if(p->fade <= 5) - { + if(p->fade <= 5) { ts = 1; blend = 255; } - else - { + else { ts = lastmillis-p->millis; blend = max(255 - (ts<<8)/p->fade, 0); - if(p->gravity) - { + if(p->gravity) { if(ts > p->fade) ts = p->fade; float t = ts; o.add(vec(d).mul(t/5000.0f)); o.z -= t*t/(2.0f * 5000.0f * p->gravity); } - if(collide && o.z < p->val && step) - { - if(collide >= 0) - { + if(collide && o.z < p->val && step) { + if(collide >= 0) { vec surface; float floorz = rayfloor(vec(o.x, o.y, p->val), surface, RAY_CLIPMAT, COLLIDERADIUS); float collidez = floorz<0 ? o.z-COLLIDERADIUS : p->val - floorz; if(o.z >= collidez+COLLIDEERROR) p->val = collidez+COLLIDEERROR; - else - { + else { adddecal(collide, vec(o.x, o.y, collidez), vec(p->o).sub(o).normalize(), 2*p->size, p->color, type&PT_RND4 ? (p->flags>>5)&3 : 0); blend = 0; } @@ -220,41 +184,29 @@ struct partrenderer } }; -struct listparticle : particle -{ +struct listparticle : particle { listparticle *next; }; VARP(outlinemeters, 0, 0, 1); -struct listrenderer : partrenderer -{ +struct listrenderer : partrenderer { static listparticle *parempty; listparticle *list; - listrenderer(const char *texname, int texclamp, int type, int collide = 0) - : partrenderer(texname, texclamp, type, collide), list(NULL) - { + : partrenderer(texname, texclamp, type, collide), list(NULL) { } listrenderer(int type, int collide = 0) - : partrenderer(type, collide), list(NULL) - { + : partrenderer(type, collide), list(NULL) { } - - virtual ~listrenderer() - { + virtual ~listrenderer() { } - - virtual void killpart(listparticle *p) - { + virtual void killpart(listparticle *p) { } - - void reset() - { + void reset() { if(!list) return; listparticle *p = list; - for(;;) - { + for(;;) { killpart(p); if(p->next) p = p->next; else break; @@ -263,14 +215,10 @@ struct listrenderer : partrenderer parempty = list; list = NULL; } - - void resettracked(physent *owner) - { + void resettracked(physent *owner) { if(!(type&PT_TRACK)) return; - for(listparticle **prev = &list, *cur = list; cur; cur = *prev) - { - if(!owner || cur->owner==owner) - { + for(listparticle **prev = &list, *cur = list; cur; cur = *prev) { + if(!owner || cur->owner==owner) { *prev = cur->next; cur->next = parempty; parempty = cur; @@ -278,11 +226,8 @@ struct listrenderer : partrenderer else prev = &cur->next; } } - - particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) - { - if(!parempty) - { + particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) { + if(!parempty) { listparticle *ps = new listparticle[256]; loopi(255) ps[i].next = &ps[i+1]; ps[255].next = parempty; @@ -303,44 +248,31 @@ struct listrenderer : partrenderer p->flags = 0; return p; } - - int count() - { + int count() { int num = 0; listparticle *lp; for(lp = list; lp; lp = lp->next) num++; return num; } - - bool haswork() - { + bool haswork() { return (list != NULL); } - virtual void startrender() = 0; virtual void endrender() = 0; virtual void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) = 0; - - void render() - { + void render() { startrender(); - if(texname) - { + if(texname) { if(!tex) tex = textureload(texname, texclamp); glBindTexture(GL_TEXTURE_2D, tex->id); } - - for(listparticle **prev = &list, *p = list; p; p = *prev) - { + for(listparticle **prev = &list, *p = list; p; p = *prev) { vec o, d; int blend, ts; calc(p, blend, ts, o, d, canstep); - if(blend > 0) - { + if(blend > 0) { renderpart(p, o, d, blend, ts); - - if(p->fade > 5 || !canstep) - { + if(p->fade > 5 || !canstep) { prev = &p->next; continue; } @@ -351,44 +283,33 @@ struct listrenderer : partrenderer killpart(p); parempty = p; } - endrender(); } }; listparticle *listrenderer::parempty = NULL; -struct meterrenderer : listrenderer -{ +struct meterrenderer : listrenderer { meterrenderer(int type) - : listrenderer(type|PT_NOTEX|PT_LERP) - {} - - void startrender() - { + : listrenderer(type|PT_NOTEX|PT_LERP) { + } + void startrender() { glDisable(GL_BLEND); gle::defvertex(); } - - void endrender() - { + void endrender() { glEnable(GL_BLEND); } - - void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) - { + void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) { int basetype = type&0xFF; float scale = FONTH*p->size/80.0f, right = 8, left = p->progress/100.0f*right; matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o); m.scale(scale); m.translate(-right/2.0f, 0, 0); - - if(outlinemeters) - { + if(outlinemeters) { gle::colorf(0, 0.8f, 0); gle::begin(GL_TRIANGLE_STRIP); - loopk(10) - { + loopk(10) { const vec2 &sc = sincos360[k*(180/(10-1))]; float c = (0.5f + 0.1f)*sc.y, s = 0.5f - (0.5f + 0.1f)*sc.x; gle::attrib(m.transform(vec2(-c, s))); @@ -396,36 +317,29 @@ struct meterrenderer : listrenderer } gle::end(); } - if(basetype==PT_METERVS) gle::colorub(p->color2[0], p->color2[1], p->color2[2]); else gle::colorf(0, 0, 0); gle::begin(GL_TRIANGLE_STRIP); - loopk(10) - { + loopk(10) { const vec2 &sc = sincos360[k*(180/(10-1))]; float c = 0.5f*sc.y, s = 0.5f - 0.5f*sc.x; gle::attrib(m.transform(vec2(left + c, s))); gle::attrib(m.transform(vec2(right + c, s))); } gle::end(); - - if(outlinemeters) - { + if(outlinemeters) { gle::colorf(0, 0.8f, 0); gle::begin(GL_TRIANGLE_FAN); - loopk(10) - { + loopk(10) { const vec2 &sc = sincos360[k*(180/(10-1))]; float c = (0.5f + 0.1f)*sc.y, s = 0.5f - (0.5f + 0.1f)*sc.x; gle::attrib(m.transform(vec2(left + c, s))); } gle::end(); } - gle::color(p->color); gle::begin(GL_TRIANGLE_STRIP); - loopk(10) - { + loopk(10) { const vec2 &sc = sincos360[k*(180/(10-1))]; float c = 0.5f*sc.y, s = 0.5f - 0.5f*sc.x; gle::attrib(m.transform(vec2(-c, s))); @@ -436,33 +350,22 @@ struct meterrenderer : listrenderer }; static meterrenderer meters(PT_METER), metervs(PT_METERVS); -struct textrenderer : listrenderer -{ +struct textrenderer : listrenderer { textrenderer(int type) - : listrenderer(type) - {} - - void startrender() - { + : listrenderer(type) { } - - void endrender() - { + void startrender() { } - - void killpart(listparticle *p) - { + void endrender() { + } + void killpart(listparticle *p) { if(p->text && p->flags&1) delete[] p->text; } - - void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) - { + void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) { float scale = p->size/80.0f, xoff = -(text_width(p->text) + ((p->flags>>1)&7)*FONTH)/2, yoff = 0; - matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o); m.scale(scale); m.translate(xoff, yoff, 50); - textmatrix = &m; draw_text(p->text, 0, 0, p->color.r, p->color.g, p->color.b, blend); textmatrix = NULL; @@ -470,35 +373,25 @@ struct textrenderer : listrenderer }; static textrenderer texts(PT_TEXT|PT_LERP); -struct texticonrenderer : listrenderer -{ +struct texticonrenderer : listrenderer { texticonrenderer(const char *texname, int type) - : listrenderer(texname, 3, type) - {} - - void startrender() - { + : listrenderer(texname, 3, type) { + } + void startrender() { gle::defvertex(); gle::deftexcoord0(); gle::defcolor(4, GL_UNSIGNED_BYTE); gle::begin(GL_QUADS); } - - void endrender() - { + void endrender() { gle::end(); } - - void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) - { + void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) { float scale = p->size/80.0f, xoff = p->val, yoff = 0; - matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o); m.scale(scale); m.translate(xoff, yoff, 50); - float tx = 0.25f*(p->flags&3), ty = 0.25f*((p->flags>>2)&3); - gle::attrib(m.transform(vec2(0, 0))); gle::attrib(tx, ty); gle::attrib(p->color, blend); @@ -516,19 +409,16 @@ struct texticonrenderer : listrenderer static texticonrenderer texticons("packages/hud/items.png", PT_TEXTICON|PT_LERP); template<int T> -static inline void modifyblend(const vec &o, int &blend) -{ +static inline void modifyblend(const vec &o, int &blend) { blend = min(blend<<2, 255); } template<> -inline void modifyblend<PT_TAPE>(const vec &o, int &blend) -{ +inline void modifyblend<PT_TAPE>(const vec &o, int &blend) { } template<int T> -static inline void genpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs) -{ +static inline void genpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs) { vec udir = vec(camup).sub(camright).mul(size); vec vdir = vec(camup).add(camright).mul(size); vs[0].pos = vec(o.x + udir.x, o.y + udir.y, o.z + udir.z); @@ -538,8 +428,7 @@ static inline void genpos(const vec &o, const vec &d, float size, int grav, int } template<> -inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) -{ +inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) { vec dir1 = d, dir2 = d, c; dir1.sub(o); dir2.sub(camera1->o); @@ -551,8 +440,7 @@ inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int } template<> -inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) -{ +inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) { vec e = d; if(grav) e.z -= float(ts)/grav; e.div(-75.0f).add(o); @@ -560,8 +448,7 @@ inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int } template<int T> -static inline void genrotpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) -{ +static inline void genrotpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) { genpos<T>(o, d, size, grav, ts, vs); } @@ -571,8 +458,7 @@ static inline void genrotpos(const vec &o, const vec &d, float size, int grav, i vec( 1, -1, 0).rotate_around_z(n*2*M_PI/32.0f), \ vec(-1, -1, 0).rotate_around_z(n*2*M_PI/32.0f) \ } -static const vec rotcoeffs[32][4] = -{ +static const vec rotcoeffs[32][4] = { ROTCOEFFS(0), ROTCOEFFS(1), ROTCOEFFS(2), ROTCOEFFS(3), ROTCOEFFS(4), ROTCOEFFS(5), ROTCOEFFS(6), ROTCOEFFS(7), ROTCOEFFS(8), ROTCOEFFS(9), ROTCOEFFS(10), ROTCOEFFS(11), ROTCOEFFS(12), ROTCOEFFS(13), ROTCOEFFS(14), ROTCOEFFS(15), ROTCOEFFS(16), ROTCOEFFS(17), ROTCOEFFS(18), ROTCOEFFS(19), ROTCOEFFS(20), ROTCOEFFS(21), ROTCOEFFS(22), ROTCOEFFS(7), @@ -580,8 +466,7 @@ static const vec rotcoeffs[32][4] = }; template<> -inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) -{ +inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) { const vec *coeffs = rotcoeffs[rot]; (vs[0].pos = o).add(vec(camright).mul(coeffs[0].x*size)).add(vec(camup).mul(coeffs[0].y*size)); (vs[1].pos = o).add(vec(camright).mul(coeffs[1].x*size)).add(vec(camup).mul(coeffs[1].y*size)); @@ -590,30 +475,25 @@ inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav, } template<int T> -static inline void seedpos(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) -{ - if(grav) - { +static inline void seedpos(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) { + if(grav) { vec end(o); float t = fade; end.add(vec(d).mul(t/5000.0f)); end.z -= t*t/(2.0f * 5000.0f * grav); pe.extendbb(end, size); - float tpeak = d.z*grav; if(tpeak > 0 && tpeak < fade) pe.extendbb(o.z + 1.5f*d.z*tpeak/5000.0f, size); } } template<> -inline void seedpos<PT_TAPE>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) -{ +inline void seedpos<PT_TAPE>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) { pe.extendbb(d, size); } template<> -inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) -{ +inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) { vec e = d; if(grav) e.z -= float(fade)/grav; e.div(-75.0f).add(o); @@ -621,30 +501,23 @@ inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, i } template<int T> -struct varenderer : partrenderer -{ +struct varenderer : partrenderer { partvert *verts; particle *parts; int maxparts, numparts, lastupdate, rndmask; GLuint vbo; - varenderer(const char *texname, int type, int collide = 0) : partrenderer(texname, 3, type, collide), - verts(NULL), parts(NULL), maxparts(0), numparts(0), lastupdate(-1), rndmask(0), vbo(0) - { + verts(NULL), parts(NULL), maxparts(0), numparts(0), lastupdate(-1), rndmask(0), vbo(0) { if(type & PT_HFLIP) rndmask |= 0x01; if(type & PT_VFLIP) rndmask |= 0x02; if(type & PT_ROT) rndmask |= 0x1F<<2; if(type & PT_RND4) rndmask |= 0x03<<5; } - - void cleanup() - { + void cleanup() { if(vbo) { glDeleteBuffers_(1, &vbo); vbo = 0; } } - - void init(int n) - { + void init(int n) { DELETEA(parts); DELETEA(verts); parts = new particle[n]; @@ -653,36 +526,25 @@ struct varenderer : partrenderer numparts = 0; lastupdate = -1; } - - void reset() - { + void reset() { numparts = 0; lastupdate = -1; } - - void resettracked(physent *owner) - { + void resettracked(physent *owner) { if(!(type&PT_TRACK)) return; - loopi(numparts) - { + loopi(numparts) { particle *p = parts+i; if(!owner || (p->owner == owner)) p->fade = -1; } lastupdate = -1; } - - int count() - { + int count() { return numparts; } - - bool haswork() - { + bool haswork() { return (numparts > 0); } - - particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) - { + particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) { particle *p = parts + (numparts < maxparts ? numparts++ : rnd(maxparts)); //next free slot, or kill a random kitten p->o = o; p->d = d; @@ -696,42 +558,30 @@ struct varenderer : partrenderer lastupdate = -1; return p; } - - void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) - { + void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) { pe.maxfade = max(pe.maxfade, fade); size *= SQRT2; pe.extendbb(o, size); - seedpos<T>(pe, o, d, fade, size, gravity); if(!gravity) return; - vec end(o); float t = fade; end.add(vec(d).mul(t/5000.0f)); end.z -= t*t/(2.0f * 5000.0f * gravity); pe.extendbb(end, size); - float tpeak = d.z*gravity; if(tpeak > 0 && tpeak < fade) pe.extendbb(o.z + 1.5f*d.z*tpeak/5000.0f, size); } - - void genverts(particle *p, partvert *vs, bool regen) - { + void genverts(particle *p, partvert *vs, bool regen) { vec o, d; int blend, ts; - calc(p, blend, ts, o, d); if(blend <= 1 || p->fade <= 5) p->fade = -1; //mark to remove on next pass (i.e. after render) - modifyblend<T>(o, blend); - - if(regen) - { + if(regen) { p->flags &= ~0x80; - - #define SETTEXCOORDS(u1c, u2c, v1c, v2c, body) \ - { \ + #define SETTEXCOORDS(u1c, u2c, v1c, v2c, body) { \ + \ float u1 = u1c, u2 = u2c, v1 = v1c, v2 = v2c; \ body; \ vs[0].tc = vec2(u1, v1); \ @@ -739,22 +589,18 @@ struct varenderer : partrenderer vs[2].tc = vec2(u2, v2); \ vs[3].tc = vec2(u1, v2); \ } - if(type&PT_RND4) - { + if(type&PT_RND4) { float tx = 0.5f*((p->flags>>5)&1), ty = 0.5f*((p->flags>>6)&1); - SETTEXCOORDS(tx, tx + 0.5f, ty, ty + 0.5f, - { + SETTEXCOORDS(tx, tx + 0.5f, ty, ty + 0.5f, { if(p->flags&0x01) swap(u1, u2); if(p->flags&0x02) swap(v1, v2); }); } - else if(type&PT_ICON) - { + else if(type&PT_ICON) { float tx = 0.25f*(p->flags&3), ty = 0.25f*((p->flags>>2)&3); SETTEXCOORDS(tx, tx + 0.25f, ty, ty + 0.25f, {}); } else SETTEXCOORDS(0, 1, 0, 1, {}); - #define SETCOLOR(r, g, b, a) \ do { \ bvec4 col(r, g, b, a); \ @@ -766,21 +612,15 @@ struct varenderer : partrenderer } else if(type&PT_MOD) SETMODCOLOR; else loopi(4) vs[i].color.a = blend; - if(type&PT_ROT) genrotpos<T>(o, d, p->size, ts, p->gravity, vs, (p->flags>>2)&0x1F); else genpos<T>(o, d, p->size, ts, p->gravity, vs); } - - void genverts() - { - loopi(numparts) - { + void genverts() { + loopi(numparts) { particle *p = &parts[i]; partvert *vs = &verts[i*4]; - if(p->fade < 0) - { - do - { + if(p->fade < 0) { + do { --numparts; if(numparts <= i) return; } @@ -791,26 +631,19 @@ struct varenderer : partrenderer else genverts(p, vs, (p->flags&0x80)!=0); } } - - void update() - { + void update() { if(lastmillis == lastupdate && vbo) return; lastupdate = lastmillis; - genverts(); - if(!vbo) glGenBuffers_(1, &vbo); gle::bindvbo(vbo); glBufferData_(GL_ARRAY_BUFFER, maxparts*4*sizeof(partvert), NULL, GL_STREAM_DRAW); glBufferSubData_(GL_ARRAY_BUFFER, 0, numparts*4*sizeof(partvert), verts); gle::clearvbo(); } - - void render() - { + void render() { if(!tex) tex = textureload(texname, texclamp); glBindTexture(GL_TEXTURE_2D, tex->id); - gle::bindvbo(vbo); const partvert *ptr = 0; gle::vertexpointer(sizeof(partvert), ptr->pos.v); @@ -820,9 +653,7 @@ struct varenderer : partrenderer gle::enabletexcoord0(); gle::enablecolor(); gle::enablequads(); - gle::drawquads(0, numparts); - gle::disablequads(); gle::disablevertex(); gle::disabletexcoord0(); @@ -830,35 +661,24 @@ struct varenderer : partrenderer gle::clearvbo(); } }; + typedef varenderer<PT_PART> quadrenderer; typedef varenderer<PT_TAPE> taperenderer; typedef varenderer<PT_TRAIL> trailrenderer; -#include "explosion.h" -#include "lightning.h" - -struct softquadrenderer : quadrenderer -{ +struct softquadrenderer : quadrenderer { softquadrenderer(const char *texname, int type, int collide = 0) - : quadrenderer(texname, type|PT_SOFT, collide) - { + : quadrenderer(texname, type|PT_SOFT, collide) { } }; -static partrenderer *parts[] = -{ +static partrenderer *parts[] = { new quadrenderer("<grey>packages/particles/blood.png", PT_PART|PT_FLIP|PT_MOD|PT_RND4, DECAL_BLOOD), // blood spats (note: rgb is inverted) new trailrenderer("packages/particles/base.png", PT_TRAIL|PT_LERP), // water, entity new quadrenderer("<grey>packages/particles/smoke.png", PT_PART|PT_FLIP|PT_LERP), // smoke new quadrenderer("<grey>packages/particles/steam.png", PT_PART|PT_FLIP), // steam new quadrenderer("<grey>packages/particles/flames.png", PT_PART|PT_HFLIP|PT_RND4|PT_GLARE), // flame on - no flipping please, they have orientation - new quadrenderer("packages/particles/ball1.png", PT_PART|PT_FEW|PT_GLARE), // fireball1 - new quadrenderer("packages/particles/ball2.png", PT_PART|PT_FEW|PT_GLARE), // fireball2 - new quadrenderer("packages/particles/ball3.png", PT_PART|PT_FEW|PT_GLARE), // fireball3 new taperenderer("packages/particles/flare.png", PT_TAPE|PT_GLARE), // streak - &lightnings, // lightning - &fireballs, // explosion fireball - &bluefireballs, // bluish explosion fireball new quadrenderer("packages/particles/spark.png", PT_PART|PT_FLIP|PT_GLARE), // sparks new quadrenderer("packages/particles/base.png", PT_PART|PT_FLIP|PT_GLARE), // edit mode entities new quadrenderer("<grey>packages/particles/snow.png", PT_PART|PT_FLIP|PT_RND4, -1), // colliding snow @@ -876,73 +696,54 @@ static partrenderer *parts[] = VARFP(maxparticles, 10, 4000, 40000, initparticles()); VARFP(fewparticles, 10, 100, 40000, initparticles()); -void initparticles() -{ +void initparticles() { if(!particleshader) particleshader = lookupshaderbyname("particle"); if(!particlenotextureshader) particlenotextureshader = lookupshaderbyname("particlenotexture"); loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->init(parts[i]->type&PT_FEW ? min(fewparticles, maxparticles) : maxparticles); } -void clearparticles() -{ +void clearparticles() { loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->reset(); clearparticleemitters(); } -void cleanupparticles() -{ +void cleanupparticles() { loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->cleanup(); } -void removetrackedparticles(physent *owner) -{ +void removetrackedparticles(physent *owner) { loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->resettracked(owner); } -void renderparticles(bool mainpass) -{ +void renderparticles(bool mainpass) { canstep = mainpass; - - loopi(sizeof(parts)/sizeof(parts[0])) - { + loopi(sizeof(parts)/sizeof(parts[0])) { parts[i]->update(); } - bool rendered = false; uint lastflags = PT_LERP|PT_SHADER, flagmask = PT_LERP|PT_MOD|PT_SHADER|PT_NOTEX; - - loopi(sizeof(parts)/sizeof(parts[0])) - { + loopi(sizeof(parts)/sizeof(parts[0])) { partrenderer *p = parts[i]; if(!(p->type&PT_GLARE)) continue; if(!p->haswork()) continue; - - if(!rendered) - { + if(!rendered) { rendered = true; glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GLOBALPARAMF(colorscale, 1, 1, 1, 1); } - uint flags = p->type & flagmask, changedbits = (flags ^ lastflags); - if(changedbits) - { - if(changedbits&(PT_LERP|PT_MOD)) - { + if(changedbits) { + if(changedbits&(PT_LERP|PT_MOD)) { if(flags&PT_LERP) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); else if(flags&PT_MOD) glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); else glBlendFunc(GL_SRC_ALPHA, GL_ONE); } - if(!(flags&PT_SHADER)) - { - if(changedbits&(PT_SOFT|PT_SHADER|PT_NOTEX|PT_LERP)) - { - if(flags&PT_SOFT) - { + if(!(flags&PT_SHADER)) { + if(changedbits&(PT_SOFT|PT_SHADER|PT_NOTEX|PT_LERP)) { + if(flags&PT_SOFT) { SETSHADER(particlesoft); } else if(flags&PT_NOTEX) particlenotextureshader->set(); @@ -953,9 +754,7 @@ void renderparticles(bool mainpass) } p->render(); } - - if(rendered) - { + if(rendered) { if(lastflags&(PT_LERP|PT_MOD)) glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDisable(GL_BLEND); glDepthMask(GL_TRUE); @@ -964,11 +763,9 @@ void renderparticles(bool mainpass) static int addedparticles = 0; -static inline particle *newparticle(const vec &o, const vec &d, int fade, int type, int color, float size, int gravity = 0) -{ +static inline particle *newparticle(const vec &o, const vec &d, int fade, int type, int color, float size, int gravity = 0) { static particle dummy; - if(seedemitter) - { + if(seedemitter) { parts[type]->seedemitter(*seedemitter, o, d, fade, size, gravity); return &dummy; } @@ -979,17 +776,14 @@ static inline particle *newparticle(const vec &o, const vec &d, int fade, int ty VARP(maxparticledistance, 256, 1024, 4096); -static void splash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity) -{ +static void splash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity) { if(camera1->o.dist(p) > maxparticledistance && !seedemitter) return; float collidez = parts[type]->collide ? p.z - raycube(p, vec(0, 0, -1), COLLIDERADIUS, RAY_CLIPMAT) + (parts[type]->collide >= 0 ? COLLIDEERROR : 0) : -1; int fmin = 1; int fmax = fade*3; - loopi(num) - { + loopi(num) { int x, y, z; - do - { + do { x = rnd(radius*2)-radius; y = rnd(radius*2)-radius; z = rnd(radius*2)-radius; @@ -1001,41 +795,35 @@ static void splash(int type, int color, int radius, int num, int fade, const vec } } -static void regularsplash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity, int delay = 0) -{ +static void regularsplash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity, int delay = 0) { if(!canemitparticles() || (delay > 0 && rnd(delay) != 0)) return; splash(type, color, radius, num, fade, p, size, gravity); } -bool canaddparticles() -{ +bool canaddparticles() { return !renderedgame && !shadowmapping && !minimized; } -void regular_particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity, int delay) -{ +void regular_particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity, int delay) { if(!canaddparticles()) return; regularsplash(type, color, radius, num, fade, p, size, gravity, delay); } -void particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity) -{ +void particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity) { if(!canaddparticles()) return; splash(type, color, radius, num, fade, p, size, gravity); } VARP(maxtrail, 1, 500, 10000); -void particle_trail(int type, int fade, const vec &s, const vec &e, int color, float size, int gravity) -{ +void particle_trail(int type, int fade, const vec &s, const vec &e, int color, float size, int gravity) { if(!canaddparticles()) return; vec v; float d = e.dist(s, v); int steps = clamp(int(d*2), 1, maxtrail); v.div(steps); vec p = s; - loopi(steps) - { + loopi(steps) { p.add(v); vec tmp = vec(float(rnd(11)-5), float(rnd(11)-5), float(rnd(11)-5)); newparticle(p, tmp, rnd(fade)+fade, type, color, size, gravity); @@ -1045,8 +833,7 @@ void particle_trail(int type, int fade, const vec &s, const vec &e, int color, f VARP(particletext, 0, 1, 1); VARP(maxparticletextdistance, 0, 128, 10000); -void particle_text(const vec &s, const char *t, int type, int fade, int color, float size, int gravity, int icons) -{ +void particle_text(const vec &s, const char *t, int type, int fade, int color, float size, int gravity, int icons) { if(!canaddparticles()) return; if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return; particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity); @@ -1054,8 +841,7 @@ void particle_text(const vec &s, const char *t, int type, int fade, int color, f p->flags = icons<<1; } -void particle_textcopy(const vec &s, const char *t, int type, int fade, int color, float size, int gravity) -{ +void particle_textcopy(const vec &s, const char *t, int type, int fade, int color, float size, int gravity) { if(!canaddparticles()) return; if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return; particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity); @@ -1063,8 +849,7 @@ void particle_textcopy(const vec &s, const char *t, int type, int fade, int colo p->flags = 1; } -void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int fade, int color, float size, int gravity) -{ +void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int fade, int color, float size, int gravity) { if(!canaddparticles()) return; if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return; particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity); @@ -1072,15 +857,13 @@ void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int p->val = offset; } -void particle_icon(const vec &s, int ix, int iy, int type, int fade, int color, float size, int gravity) -{ +void particle_icon(const vec &s, int ix, int iy, int type, int fade, int color, float size, int gravity) { if(!canaddparticles()) return; particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity); p->flags |= ix | (iy<<2); } -void particle_meter(const vec &s, float val, int type, int fade, int color, int color2, float size) -{ +void particle_meter(const vec &s, float val, int type, int fade, int color, int color2, float size) { if(!canaddparticles()) return; particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size); p->color2[0] = color2>>16; @@ -1089,31 +872,20 @@ void particle_meter(const vec &s, float val, int type, int fade, int color, int p->progress = clamp(int(val*100), 0, 100); } -void particle_flare(const vec &p, const vec &dest, int fade, int type, int color, float size, physent *owner) -{ +void particle_flare(const vec &p, const vec &dest, int fade, int type, int color, float size, physent *owner) { if(!canaddparticles()) return; newparticle(p, dest, fade, type, color, size)->owner = owner; } -void particle_fireball(const vec &dest, float maxsize, int type, int fade, int color, float size) -{ - if(!canaddparticles()) return; - float growth = maxsize - size; - if(fade < 0) fade = int(growth*20); - newparticle(dest, vec(0, 0, 1), fade, type, color, size)->val = growth; -} - //dir = 0..6 where 0=up -static inline vec offsetvec(vec o, int dir, int dist) -{ +static inline vec offsetvec(vec o, int dir, int dist) { vec v = vec(o); v[(2+dir)%3] += (dir>2)?(-dist):dist; return v; } //converts a 16bit color to 24bit -static inline int colorfromattr(int attr) -{ +static inline int colour_from_attribute(int attr) { return (((attr&0xF)<<4) | ((attr&0xF0)<<8) | ((attr&0xF00)<<12)) + 0x0F0F0F; } @@ -1128,19 +900,15 @@ static inline int colorfromattr(int attr) * 24..26 flat plane * +32 to inverse direction */ -void regularshape(int type, int radius, int color, int dir, int num, int fade, const vec &p, float size, int gravity, int vel = 200) -{ +void regularshape(int type, int radius, int color, int dir, int num, int fade, const vec &p, float size, int gravity, int vel = 200) { if(!canemitparticles()) return; - int basetype = parts[type]->type&0xFF; - bool flare = (basetype == PT_TAPE) || (basetype == PT_LIGHTNING), + bool flare = (basetype == PT_TAPE), inv = (dir&0x20)!=0, taper = (dir&0x40)!=0 && !seedemitter; dir &= 0x1F; - loopi(num) - { + loopi(num) { vec to, from; - if(dir < 12) - { + if(dir < 12) { const vec2 &sc = sincos360[rnd(360)]; to[dir%3] = sc.y*radius; to[(dir+1)%3] = sc.x*radius; @@ -1148,20 +916,17 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c to.add(p); if(dir < 3) //circle from = p; - else if(dir < 6) //cylinder - { + else if(dir < 6) { //cylinder { from = to; to[(dir+2)%3] += radius; from[(dir+2)%3] -= radius; } - else //cone - { + else { //cone { from = p; to[(dir+2)%3] += (dir < 9)?radius:(-radius); } } - else if(dir < 15) //plane - { + else if(dir < 15) { //plane { to[dir%3] = float(rnd(radius<<4)-(radius<<3))/8.0; to[(dir+1)%3] = float(rnd(radius<<4)-(radius<<3))/8.0; to[(dir+2)%3] = radius; @@ -1169,15 +934,12 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c from = to; from[(dir+2)%3] -= 2*radius; } - else if(dir < 21) //line - { - if(dir < 18) - { + else if(dir < 21) { //line { + if(dir < 18) { to[dir%3] = float(rnd(radius<<4)-(radius<<3))/8.0; to[(dir+1)%3] = 0.0; } - else - { + else { to[dir%3] = 0.0; to[(dir+1)%3] = float(rnd(radius<<4)-(radius<<3))/8.0; } @@ -1186,14 +948,12 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c from = to; to[(dir+2)%3] += radius; } - else if(dir < 24) //sphere - { + else if(dir < 24) { //sphere { to = vec(2*M_PI*float(rnd(1000))/1000.0, M_PI*float(rnd(1000)-500)/1000.0).mul(radius); to.add(p); from = p; } - else if(dir < 27) // flat plane - { + else if(dir < 27) { // flat plane { to[dir%3] = float(rndscale(2*radius)-radius); to[(dir+1)%3] = float(rndscale(2*radius)-radius); to[(dir+2)%3] = 0.0; @@ -1201,23 +961,17 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c from = to; } else from = to = p; - if(inv) swap(from, to); - - if(taper) - { + if(taper) { float dist = clamp(from.dist2(camera1->o)/maxparticledistance, 0.0f, 1.0f); - if(dist > 0.2f) - { + if(dist > 0.2f) { dist = 1 - (dist - 0.2f)/0.8f; if(rnd(0x10000) > dist*dist*0xFFFF) continue; } } - if(flare) newparticle(from, to, rnd(fade*3)+1, type, color, size, gravity); - else - { + else { vec d = vec(to).sub(from).rescale(vel); //velocity particle *n = newparticle(from, d, rnd(fade*3)+1, type, color, size, gravity); if(parts[type]->collide) @@ -1226,14 +980,11 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c } } -static void regularflame(int type, const vec &p, float radius, float height, int color, int density = 3, float scale = 2.0f, float speed = 200.0f, float fade = 600.0f, int gravity = -15) -{ +static void regularflame(int type, const vec &p, float radius, float height, int color, int density = 3, float scale = 2.0f, float speed = 200.0f, float fade = 600.0f, int gravity = -15) { if(!canemitparticles()) return; - float size = scale * min(radius, height); vec v(0, 0, min(1.0f, height)*speed); - loopi(density) - { + loopi(density) { vec s = p; s.x += rndscale(radius*2.0f)-radius; s.y += rndscale(radius*2.0f)-radius; @@ -1241,65 +992,48 @@ static void regularflame(int type, const vec &p, float radius, float height, int } } -void regular_particle_flame(int type, const vec &p, float radius, float height, int color, int density, float scale, float speed, float fade, int gravity) -{ +void regular_particle_flame(int type, const vec &p, float radius, float height, int color, int density, float scale, float speed, float fade, int gravity) { if(!canaddparticles()) return; regularflame(type, p, radius, height, color, density, scale, speed, fade, gravity); } -static void makeparticles(entity &e) -{ - switch(e.attr1) - { - case 0: //fire and smoke - <radius> <height> <rgb> - 0 values default to compat for old maps - { - //regularsplash(PART_FIREBALL1, 0xFFC8C8, 150, 1, 40, e.o, 4.8f); - //regularsplash(PART_SMOKE, 0x897661, 50, 1, 200, vec(e.o.x, e.o.y, e.o.z+3.0f), 2.4f, -20, 3); +static void makeparticles(entity &e) { + switch(e.attr1) { + case 0: { //fire and smoke - <radius> <height> <rgb> - 0 values default to compat for old maps { float radius = e.attr2 ? float(e.attr2)/100.0f : 1.5f, height = e.attr3 ? float(e.attr3)/100.0f : radius/3; - regularflame(PART_FLAME, e.o, radius, height, e.attr4 ? colorfromattr(e.attr4) : 0x903020, 3, 2.0f); + regularflame(PART_FLAME, e.o, radius, height, e.attr4 ? colour_from_attribute(e.attr4) : 0x903020, 3, 2.0f); regularflame(PART_SMOKE, vec(e.o.x, e.o.y, e.o.z + 4.0f*min(radius, height)), radius, height, 0x303020, 1, 4.0f, 100.0f, 2000.0f, -20); break; } case 1: //steam vent - <dir> regularsplash(PART_STEAM, 0x897661, 50, 1, 200, offsetvec(e.o, e.attr2, rnd(10)), 2.4f, -20); break; - case 2: //water fountain - <dir> - { + case 2: { //water fountain - <dir> { int color; - if(e.attr3 > 0) color = colorfromattr(e.attr3); - else - { - int mat = clamp(-e.attr3, 0, 3); - color = 0xff7700; - } + if(e.attr3 > 0) color = colour_from_attribute(e.attr3); + else color = 0xff7700; regularsplash(PART_WATER, color, 150, 4, 200, offsetvec(e.o, e.attr2, rnd(10)), 0.6f, 2); break; } - case 3: //fire ball - <size> <rgb> - newparticle(e.o, vec(0, 0, 1), 1, PART_EXPLOSION, colorfromattr(e.attr3), 4.0f)->val = 1+e.attr2; - break; - case 4: //tape - <dir> <length> <rgb> - case 7: //lightning case 9: //steam + case 4: //tape - <dir> <length> <rgb> case 10: //water - case 13: //snow - { - static const int typemap[] = { PART_STREAK, -1, -1, PART_LIGHTNING, -1, PART_STEAM, PART_WATER, -1, -1, PART_SNOW }; - static const float sizemap[] = { 0.28f, 0.0f, 0.0f, 1.0f, 0.0f, 2.4f, 0.60f, 0.0f, 0.0f, 0.5f }; + case 13: { //snow { + static const int typemap[] = { PART_STREAK, -1, -1, -1, -1, PART_STEAM, PART_WATER, -1, -1, PART_SNOW }; + static const float sizemap[] = { 0.28f, 0.0f, 0.0f, 0.0f, 0.0f, 2.4f, 0.60f, 0.0f, 0.0f, 0.5f }; static const int gravmap[] = { 0, 0, 0, 0, 0, -20, 2, 0, 0, 20 }; int type = typemap[e.attr1-4]; float size = sizemap[e.attr1-4]; int gravity = gravmap[e.attr1-4]; - if(e.attr2 >= 256) regularshape(type, max(1+e.attr3, 1), colorfromattr(e.attr4), e.attr2-256, 5, e.attr5 > 0 ? min(int(e.attr5), 10000) : 200, e.o, size, gravity); - else newparticle(e.o, offsetvec(e.o, e.attr2, max(1+e.attr3, 0)), 1, type, colorfromattr(e.attr4), size, gravity); + if(e.attr2 >= 256) regularshape(type, max(1+e.attr3, 1), colour_from_attribute(e.attr4), e.attr2-256, 5, e.attr5 > 0 ? min(int(e.attr5), 10000) : 200, e.o, size, gravity); + else newparticle(e.o, offsetvec(e.o, e.attr2, max(1+e.attr3, 0)), 1, type, colour_from_attribute(e.attr4), size, gravity); break; } case 5: //meter, metervs - <percent> <rgb> <rgb2> - case 6: - { - particle *p = newparticle(e.o, vec(0, 0, 1), 1, e.attr1==5 ? PART_METER : PART_METER_VS, colorfromattr(e.attr3), 2.0f); - int color2 = colorfromattr(e.attr4); + case 6: { + particle *p = newparticle(e.o, vec(0, 0, 1), 1, e.attr1==5 ? PART_METER : PART_METER_VS, colour_from_attribute(e.attr3), 2.0f); + int color2 = colour_from_attribute(e.attr4); p->color2[0] = color2>>16; p->color2[1] = (color2>>8)&0xFF; p->color2[2] = color2&0xFF; @@ -1307,10 +1041,10 @@ static void makeparticles(entity &e) break; } case 11: // flame <radius> <height> <rgb> - radius=100, height=100 is the classic size - regularflame(PART_FLAME, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colorfromattr(e.attr4), 3, 2.0f); + regularflame(PART_FLAME, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colour_from_attribute(e.attr4), 3, 2.0f); break; case 12: // smoke plume <radius> <height> <rgb> - regularflame(PART_SMOKE, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colorfromattr(e.attr4), 1, 4.0f, 100.0f, 2000.0f, -20); + regularflame(PART_SMOKE, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colour_from_attribute(e.attr4), 1, 4.0f, 100.0f, 2000.0f, -20); break; case 32: //lens flares - plain/sparkle/sun/sparklesun <red> <green> <blue> case 33: @@ -1318,8 +1052,7 @@ static void makeparticles(entity &e) case 35: break; default: - if(!editmode) - { + if(!editmode) { defformatstring(ds, "particles %d?", e.attr1); particle_textcopy(e.o, ds, PART_TEXT, 1, 0x6496FF, 2.0f); } @@ -1327,10 +1060,8 @@ static void makeparticles(entity &e) } } -bool printparticles(extentity &e, char *buf, int len) -{ - switch(e.attr1) - { +bool printparticles(extentity &e, char *buf, int len) { + switch(e.attr1) { case 0: case 4: case 7: case 8: case 9: case 10: case 11: case 12: case 13: nformatstring(buf, len, "%s %d %d %d 0x%.3hX %d", entities::entname(e.type), e.attr1, e.attr2, e.attr3, e.attr4, e.attr5); return true; @@ -1344,13 +1075,11 @@ bool printparticles(extentity &e, char *buf, int len) return false; } -void seedparticles() -{ +void seedparticles() { renderprogress(0, "seeding particles"); addparticleemitters(); canemit = true; - loopv(emitters) - { + loopv(emitters) { particleemitter &pe = emitters[i]; extentity &e = *pe.ent; seedemitter = &pe; @@ -1362,34 +1091,25 @@ void seedparticles() } } -void updateparticles() -{ +void updateparticles() { if(regenemitters) addparticleemitters(); - if(minimized) { canemit = false; return; } - - if(lastmillis - lastemitframe >= emitmillis) - { + if(lastmillis - lastemitframe >= emitmillis) { canemit = true; lastemitframe = lastmillis - (lastmillis%emitmillis); } else canemit = false; - - if(!editmode || showparticles) - { + if(!editmode || showparticles) { int emitted = 0, replayed = 0; addedparticles = 0; - loopv(emitters) - { + loopv(emitters) { particleemitter &pe = emitters[i]; extentity &e = *pe.ent; if(e.o.dist(camera1->o) > maxparticledistance) { pe.lastemit = lastmillis; continue; } makeparticles(e); emitted++; - if(replayparticles && pe.maxfade > 5 && pe.lastcull > pe.lastemit) - { - for(emitoffset = max(pe.lastemit + emitmillis - lastmillis, -pe.maxfade); emitoffset < 0; emitoffset += emitmillis) - { + if(replayparticles && pe.maxfade > 5 && pe.lastcull > pe.lastemit) { + for(emitoffset = max(pe.lastemit + emitmillis - lastmillis, -pe.maxfade); emitoffset < 0; emitoffset += emitmillis) { makeparticles(e); replayed++; } @@ -1398,17 +1118,14 @@ void updateparticles() pe.lastemit = lastmillis; } } - if(editmode) // show sparkly thingies for map entities in edit mode - { + if(editmode) { // show sparkly thingies for map entities in edit mode { const vector<extentity *> &ents = entities::getents(); // note: order matters in this case as particles of the same type are drawn in the reverse order that they are added - loopv(entgroup) - { + loopv(entgroup) { entity &e = *ents[entgroup[i]]; particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0xFF4B19, 2.0f); } - loopv(ents) - { + loopv(ents) { entity &e = *ents[i]; if(e.type==ET_EMPTY) continue; particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0x1EC850, 2.0f); |
