X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=r_explosion.c;h=430e399c08533ef30bc8f9fdbd27fff52e771139;hp=267e0928c10b1b66b01bbd827d3763bda010285d;hb=49bc2c682053460fa93f8caee386a6c5fd77e564;hpb=eab50b35822052aad2a31fece513583600e5941f diff --git a/r_explosion.c b/r_explosion.c index 267e0928..430e399c 100644 --- a/r_explosion.c +++ b/r_explosion.c @@ -25,38 +25,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define EXPLOSIONGRID 8 #define EXPLOSIONVERTS ((EXPLOSIONGRID+1)*(EXPLOSIONGRID+1)) #define EXPLOSIONTRIS (EXPLOSIONGRID*EXPLOSIONGRID*2) -#define EXPLOSIONSTARTVELOCITY (256.0f) -#define EXPLOSIONFADESTART (1.5f) -#define EXPLOSIONFADERATE (3.0f) -float explosiontexcoord2f[EXPLOSIONVERTS][2]; -int explosiontris[EXPLOSIONTRIS][3]; -int explosionnoiseindex[EXPLOSIONVERTS]; -vec3_t explosionpoint[EXPLOSIONVERTS]; -vec3_t explosionspherevertvel[EXPLOSIONVERTS]; +static float explosiontexcoord2f[EXPLOSIONVERTS][2]; +static int explosiontris[EXPLOSIONTRIS][3]; +static int explosionnoiseindex[EXPLOSIONVERTS]; +static vec3_t explosionpoint[EXPLOSIONVERTS]; typedef struct explosion_s { float starttime; + float endtime; float time; float alpha; + float fade; vec3_t origin; vec3_t vert[EXPLOSIONVERTS]; vec3_t vertvel[EXPLOSIONVERTS]; + qboolean clipping; } explosion_t; -explosion_t explosion[MAX_EXPLOSIONS]; +static explosion_t explosion[MAX_EXPLOSIONS]; -rtexture_t *explosiontexture; -rtexture_t *explosiontexturefog; +static rtexture_t *explosiontexture; +static rtexture_t *explosiontexturefog; -rtexturepool_t *explosiontexturepool; +static rtexturepool_t *explosiontexturepool; cvar_t r_explosionclip = {CVAR_SAVE, "r_explosionclip", "1"}; -cvar_t r_drawexplosions = {0, "r_drawexplosions", "1"}; +static cvar_t r_drawexplosions = {0, "r_drawexplosions", "1"}; -void r_explosion_start(void) +static void r_explosion_start(void) { int x, y; qbyte noise1[128][128], noise2[128][128], noise3[128][128], data[128][128][4]; @@ -88,17 +87,17 @@ void r_explosion_start(void) // note that explosions survive the restart } -void r_explosion_shutdown(void) +static void r_explosion_shutdown(void) { R_FreeTexturePool(&explosiontexturepool); } -void r_explosion_newmap(void) +static void r_explosion_newmap(void) { memset(explosion, 0, sizeof(explosion)); } -int R_ExplosionVert(int column, int row) +static int R_ExplosionVert(int column, int row) { int i; float yaw, pitch; @@ -111,9 +110,6 @@ int R_ExplosionVert(int column, int row) explosionpoint[i][0] = cos(yaw) * cos(pitch); explosionpoint[i][1] = sin(yaw) * cos(pitch); explosionpoint[i][2] = 1 * -sin(pitch); - explosionspherevertvel[i][0] = explosionpoint[i][0] * EXPLOSIONSTARTVELOCITY; - explosionspherevertvel[i][1] = explosionpoint[i][1] * EXPLOSIONSTARTVELOCITY; - explosionspherevertvel[i][2] = explosionpoint[i][2] * EXPLOSIONSTARTVELOCITY; explosiontexcoord2f[i][0] = (float) column / (float) EXPLOSIONGRID; explosiontexcoord2f[i][1] = (float) row / (float) EXPLOSIONGRID; explosionnoiseindex[i] = (row % EXPLOSIONGRID) * EXPLOSIONGRID + (column % EXPLOSIONGRID); @@ -148,31 +144,43 @@ void R_Explosion_Init(void) void R_NewExplosion(vec3_t org) { int i, j; - float dist; + float dist, n; + explosion_t *e; + trace_t trace; qbyte noise[EXPLOSIONGRID*EXPLOSIONGRID]; fractalnoisequick(noise, EXPLOSIONGRID, 4); // adjust noise grid size according to explosion - for (i = 0;i < MAX_EXPLOSIONS;i++) + for (i = 0, e = explosion;i < MAX_EXPLOSIONS;i++, e++) { - if (explosion[i].alpha <= 0.01f) + if (cl.time >= e->endtime) { - explosion[i].starttime = cl.time; - explosion[i].time = explosion[i].starttime - 0.1; - explosion[i].alpha = EXPLOSIONFADESTART; - VectorCopy(org, explosion[i].origin); + e->starttime = cl.time; + e->endtime = cl.time + cl_explosions_lifetime.value; + e->time = e->starttime; + e->alpha = cl_explosions_alpha_start.value; + e->fade = (cl_explosions_alpha_start.value - cl_explosions_alpha_end.value) / cl_explosions_lifetime.value; + e->clipping = r_explosionclip.integer != 0; + VectorCopy(org, e->origin); for (j = 0;j < EXPLOSIONVERTS;j++) { - // calculate start - VectorCopy(explosion[i].origin, explosion[i].vert[j]); - // calculate velocity - dist = noise[explosionnoiseindex[j]] * (1.0f / 255.0f) + 0.5; - VectorScale(explosionspherevertvel[j], dist, explosion[i].vertvel[j]); + // calculate start origin and velocity + n = noise[explosionnoiseindex[j]] * (1.0f / 255.0f) + 0.5; + dist = n * cl_explosions_size_start.value; + VectorMA(e->origin, dist, explosionpoint[j], e->vert[j]); + dist = n * (cl_explosions_size_end.value - cl_explosions_size_start.value) / cl_explosions_lifetime.value; + VectorScale(explosionpoint[j], dist, e->vertvel[j]); + // clip start origin + if (e->clipping) + { + trace = CL_TraceBox(e->origin, vec3_origin, vec3_origin, e->vert[j], true, NULL, SUPERCONTENTS_SOLID, false); + VectorCopy(trace.endpos, e->vert[i]); + } } break; } } } -void R_DrawExplosionCallback(const void *calldata1, int calldata2) +static void R_DrawExplosionCallback(const void *calldata1, int calldata2) { int numtriangles, numverts; float alpha; @@ -188,8 +196,6 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) numtriangles = EXPLOSIONTRIS; numverts = EXPLOSIONVERTS; alpha = e->alpha; - GL_ColorPointer(NULL); - GL_Color(alpha, alpha, alpha, 1); memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(explosiontexture); @@ -197,39 +203,37 @@ void R_DrawExplosionCallback(const void *calldata1, int calldata2) m.pointer_vertex = e->vert[0]; R_Mesh_State(&m); - R_Mesh_Draw(numverts, numtriangles, explosiontris[0]); + GL_Color(alpha, alpha, alpha, 1); + + GL_LockArrays(0, numverts); + R_Mesh_Draw(0, numverts, numtriangles, explosiontris[0]); + GL_LockArrays(0, 0); } -void R_MoveExplosion(explosion_t *e) +static void R_MoveExplosion(explosion_t *e) { int i; - float dot, frictionscale, end[3], impact[3], normal[3], frametime; + float dot, end[3], frametime; + trace_t trace; frametime = cl.time - e->time; e->time = cl.time; - e->alpha = EXPLOSIONFADESTART - (cl.time - e->starttime) * EXPLOSIONFADERATE; - if (e->alpha <= 0.01f) - { - e->alpha = -1; - return; - } - frictionscale = 1 - frametime; - frictionscale = bound(0, frictionscale, 1); + e->alpha = e->alpha - (e->fade * frametime); for (i = 0;i < EXPLOSIONVERTS;i++) { if (e->vertvel[i][0] || e->vertvel[i][1] || e->vertvel[i][2]) { - VectorScale(e->vertvel[i], frictionscale, e->vertvel[i]); VectorMA(e->vert[i], frametime, e->vertvel[i], end); - if (r_explosionclip.integer) + if (e->clipping) { - if (CL_TraceLine(e->vert[i], end, impact, normal, true, NULL, SUPERCONTENTS_SOLID) < 1) + trace = CL_TraceBox(e->vert[i], vec3_origin, vec3_origin, end, true, NULL, SUPERCONTENTS_SOLID, false); + if (trace.fraction < 1) { // clip velocity against the wall - dot = DotProduct(e->vertvel[i], normal) * -1.125f; - VectorMA(e->vertvel[i], dot, normal, e->vertvel[i]); + dot = -DotProduct(e->vertvel[i], trace.plane.normal); + VectorMA(e->vertvel[i], dot, trace.plane.normal, e->vertvel[i]); } - VectorCopy(impact, e->vert[i]); + VectorCopy(trace.endpos, e->vert[i]); } else VectorCopy(end, e->vert[i]); @@ -241,12 +245,8 @@ void R_MoveExplosion(explosion_t *e) void R_MoveExplosions(void) { int i; - float frametime; - - frametime = cl.time - cl.oldtime; - for (i = 0;i < MAX_EXPLOSIONS;i++) - if (explosion[i].alpha > 0.01f) + if (cl.time < explosion[i].endtime) R_MoveExplosion(&explosion[i]); } @@ -257,7 +257,7 @@ void R_DrawExplosions(void) if (!r_drawexplosions.integer) return; for (i = 0;i < MAX_EXPLOSIONS;i++) - if (explosion[i].alpha > 0.01f) + if (r_refdef.time < explosion[i].endtime) R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosionCallback, &explosion[i], 0); }