typedef struct particle_s
{
+ ptype_t type;
vec3_t org;
- float color;
vec3_t vel;
- float die;
- ptype_t type;
- float scale;
rtexture_t *tex;
byte dynlight; // if set the particle will be dynamically lit (if r_dynamicparticles is on), used for smoke and blood
byte rendermode; // a TPOLYTYPE_ value
- byte pad1;
+ byte color;
byte pad2;
+ float die;
+ float scale;
float alpha; // 0-255
float time2; // used for various things (snow fluttering, for example)
- float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical of bouncing particles)
+ float bounce; // how much bounce-back from a surface the particle hits (0 = no physics, 1 = stop and slide, 2 = keep bouncing forever, 1.5 is typical)
vec3_t oldorg;
vec3_t vel2; // used for snow fluttering (base velocity, wind for instance)
// vec3_t direction; // used by decals
rtexture_t *rainparticletexture;
rtexture_t *bubbleparticletexture;
rtexture_t *bulletholetexture[8];
+rtexture_t *rocketglowparticletexture;
particle_t *particles;
int r_numparticles;
bulletholetexture[i] = R_LoadTexture (va("bulletholetexture%d", i), 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
}
+
+ for (y = 0;y < 32;y++)
+ {
+ dy = y - 16;
+ for (x = 0;x < 32;x++)
+ {
+ dx = x - 16;
+ d = (2048.0f / (dx*dx+dy*dy+1)) - 8.0f;
+ data[y][x][0] = bound(0, d * 1.0f, 255);
+ data[y][x][1] = bound(0, d * 0.8f, 255);
+ data[y][x][2] = bound(0, d * 0.5f, 255);
+ data[y][x][3] = bound(0, d * 1.0f, 255);
+ }
+ }
+ rocketglowparticletexture = R_LoadTexture ("glowparticletexture", 32, 32, &data[0][0][0], TEXF_MIPMAP | TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
}
-void r_part_start()
+void r_part_start(void)
{
particles = (particle_t *) qmalloc(r_numparticles * sizeof(particle_t));
freeparticles = (void *) qmalloc(r_numparticles * sizeof(particle_t *));
R_InitParticleTexture ();
}
-void r_part_shutdown()
+void r_part_shutdown(void)
{
numparticles = 0;
qfree(particles);
qfree(freeparticles);
}
-void r_part_newmap()
+void r_part_newmap(void)
{
numparticles = 0;
}
forward[1] = cp*sy;
forward[2] = -sp;
- particle(pt_oneframe, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 9999, 0, ent->origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0);
+ particle(pt_oneframe, 0x6f, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 9999, 0, ent->render.origin[0] + m_bytenormals[i][0]*dist + forward[0]*beamlength, ent->render.origin[1] + m_bytenormals[i][1]*dist + forward[1]*beamlength, ent->render.origin[2] + m_bytenormals[i][2]*dist + forward[2]*beamlength, 0, 0, 0);
}
}
void R_ReadPointFile_f (void)
{
- FILE *f;
+ QFile *f;
vec3_t org;
int r;
int c;
sprintf (name,"maps/%s.pts", sv.name);
- COM_FOpenFile (name, &f, false);
+ COM_FOpenFile (name, &f, false, true);
if (!f)
{
Con_Printf ("couldn't open %s\n", name);
c = 0;
for (;;)
{
- r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]);
+ char *str = Qgetline (f);
+ r = sscanf (str,"%f %f %f\n", &org[0], &org[1], &org[2]);
if (r != 3)
break;
c++;
particle(pt_static, (-c)&15, particletexture, TPOLYTYPE_ALPHA, false, 2, 255, 99999, 0, org[0], org[1], org[2], 0, 0, 0);
}
- fclose (f);
+ Qclose (f);
Con_Printf ("%i points read\n", c);
}
VectorSubtract(end, start, dir);
VectorNormalize(dir);
- /*
- if (type == 0) // rocket glow
- particle(pt_glow, 254, particletexture, TPOLYTYPE_ADD, false, 10, 160, 9999, 0, start[0] - 12 * dir[0], start[1] - 12 * dir[1], start[2] - 12 * dir[2], 0, 0, 0);
- */
+ if (type == 0 && host_frametime != 0) // rocket glow
+ particle(pt_oneframe, 254, rocketglowparticletexture, TPOLYTYPE_ADD, false, 24, 255, 9999, 0, end[0] - 12 * dir[0], end[1] - 12 * dir[1], end[2] - 12 * dir[2], 0, 0, 0);
- t = ent->trail_time;
+ t = ent->render.trail_time;
if (t >= cl.time)
return; // no particles to spawn this frame (sparse trail)
if (len <= 0.01f)
{
// advance the trail time
- ent->trail_time = cl.time;
+ ent->render.trail_time = cl.time;
return;
}
speed = len / (cl.time - cl.oldtime);
if (contents == CONTENTS_SKY || contents == CONTENTS_LAVA)
{
// advance the trail time
- ent->trail_time = cl.time;
+ ent->render.trail_time = cl.time;
return;
}
bubbles = (contents == CONTENTS_WATER || contents == CONTENTS_SLIME);
polytype = TPOLYTYPE_ALPHA;
- if (ent->effects & EF_ADDITIVE)
+ if (ent->render.effects & EF_ADDITIVE)
polytype = TPOLYTYPE_ADD;
while (t < cl.time)
dec *= speed;
VectorMA (start, dec, vec, start);
}
- ent->trail_time = t;
+ ent->render.trail_time = t;
}
void R_RocketTrail2 (vec3_t start, vec3_t end, int color, entity_t *ent)
R_DrawParticles
===============
*/
-extern cvar_t sv_gravity;
-
void R_MoveParticles (void)
{
particle_t *p;
float scale, scale2, minparticledist;
byte *color24;
vec3_t uprightangles, up2, right2, tempcolor, corner;
+ mleaf_t *leaf;
// LordHavoc: early out condition
if ((!numparticles) || (!r_drawparticles.value))
uprightangles[2] = 0;
AngleVectors (uprightangles, NULL, right2, up2);
- minparticledist = DotProduct(r_refdef.vieworg, vpn) + 16.0f;
+ minparticledist = DotProduct(r_origin, vpn) + 16.0f;
for (i = 0, p = particles;i < numparticles;i++, p++)
{
if (DotProduct(p->org, vpn) < minparticledist)
continue;
+ // LordHavoc: check if it's in a visible leaf
+ leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
+ if (leaf->visframe != r_framecount)
+ continue;
+
/*
if (p->type == pt_decal)
{
- VectorSubtract(p->org, r_refdef.vieworg, v);
+ VectorSubtract(p->org, r_origin, v);
if (DotProduct(p->direction, v) < 0)
continue;
}