Surface particle emittence should be nicer now.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@266 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2004-09-30 22:43:23 +00:00
parent b08fe6561b
commit 95ca49effb

View file

@ -116,11 +116,8 @@ typedef struct skytris_s {
float area; float area;
float nexttime; float nexttime;
msurface_t *face; msurface_t *face;
int ptype;
} skytris_t; } skytris_t;
static skytris_t *skytris;
@ -196,6 +193,7 @@ typedef struct part_type_s {
int loaded; int loaded;
particle_t *particles; particle_t *particles;
skytris_t *skytris;
} part_type_t; } part_type_t;
int numparticletypes; int numparticletypes;
part_type_t *part_type; part_type_t *part_type;
@ -291,6 +289,7 @@ void R_ParticleEffect_f(void)
char *var, *value; char *var, *value;
char *buf; char *buf;
particle_t *parts; particle_t *parts;
skytris_t *st;
part_type_t *ptype; part_type_t *ptype;
int pnum, assoc; int pnum, assoc;
@ -323,10 +322,12 @@ void R_ParticleEffect_f(void)
pnum = ptype-part_type; pnum = ptype-part_type;
parts = ptype->particles; parts = ptype->particles;
st = ptype->skytris;
if (ptype->ramp) if (ptype->ramp)
BZ_Free(ptype->ramp); BZ_Free(ptype->ramp);
memset(ptype, 0, sizeof(*ptype)); memset(ptype, 0, sizeof(*ptype));
ptype->particles = parts; ptype->particles = parts;
ptype->skytris = st;
strcpy(ptype->name, Cmd_Argv(1)); strcpy(ptype->name, Cmd_Argv(1));
ptype->assoc=-1; ptype->assoc=-1;
ptype->cliptype = -1; ptype->cliptype = -1;
@ -859,8 +860,6 @@ void R_ClearParticles (void)
particletime = cl.time; particletime = cl.time;
skytris = NULL;
#ifdef RGLQUAKE #ifdef RGLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
@ -877,7 +876,10 @@ void R_ClearParticles (void)
#endif #endif
for (i = 0; i < numparticletypes; i++) for (i = 0; i < numparticletypes; i++)
{
part_type[i].particles = NULL; part_type[i].particles = NULL;
part_type[i].skytris = NULL;
}
} }
void R_Part_NewServer(void) void R_Part_NewServer(void)
@ -1012,6 +1014,7 @@ void R_AddRainParticles(void)
float x; float x;
float y; float y;
static float skipped; static float skipped;
int ptype;
vec3_t org, vdist; vec3_t org, vdist;
@ -1023,46 +1026,92 @@ void R_AddRainParticles(void)
return; return;
} }
if (!skytris) //don't bother (let's use test for the first one for timings) // if (skytris->nexttime < particletime - 0.5)
return; // skipped = true; //we've gone for half a sec without any new rain. This would cause some strange effects, so reset times.
if (skytris->nexttime < particletime - 0.5)
skipped = true; //we've gone for half a sec without any new rain. This would cause some strange effects, so reset times.
if (skipped) if (skipped)
{ {
for (st = skytris; st; st = st->next) for (ptype = 0; ptype<numparticletypes; ptype++)
{ {
st->nexttime = particletime; for (st = part_type[ptype].skytris; st; st = st->next)
{
st->nexttime = particletime;
}
} }
} }
skipped = false; skipped = false;
/*
{
int i;
for (st = skytris; st; st = st->next) glDisable(GL_TEXTURE_2D);
{ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// if (st->face->visframe != r_framecount) glDisable(GL_DEPTH_TEST);
// continue; glBegin(GL_TRIANGLES);
while (st->nexttime < particletime)
st = skytris;
for (i = 0; i < r_part_rain_quantity.value; i++)
st = st->next;
glVertex3f(st->org[0], st->org[1], st->org[2]);
glVertex3f(st->org[0]+st->x[0], st->org[1]+st->x[1], st->org[2]+st->x[2]);
glVertex3f(st->org[0]+st->y[0], st->org[1]+st->y[1], st->org[2]+st->y[2]);
glEnd();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_POINTS);
for (i = 0; i < 1000; i++)
{ {
if (!free_particles) x = frandom()*frandom();
return; y = frandom() * (1-x);
st->nexttime += 10000/(st->area*r_part_rain_quantity.value);
x = frandom();
y = frandom();
VectorMA(st->org, x, st->x, org); VectorMA(st->org, x, st->x, org);
VectorMA(org, y, st->y, org); VectorMA(org, y, st->y, org);
glVertex3f(org[0], org[1], org[2]);
}
glEnd();
glEnable(GL_DEPTH_TEST);
}
*/
for (ptype = 0; ptype<numparticletypes; ptype++)
{
if (!part_type[ptype].loaded) //woo, batch skipping.
continue;
VectorSubtract(org, r_refdef.vieworg, vdist); for (st = part_type[ptype].skytris; st; st = st->next)
{
// if (st->face->visframe != r_framecount)
// continue;
while (st->nexttime < particletime)
{
if (!free_particles)
return;
if (Length(vdist) > (1024+512)*frandom()) st->nexttime += 10000/(st->area*r_part_rain_quantity.value);
continue;
x = frandom()*frandom();
if (!(cl.worldmodel->hulls->funcs.HullPointContents(cl.worldmodel->hulls, org) & FTECONTENTS_SOLID)) y = frandom() * (1-x);
R_RunParticleEffectType(org, st->face->plane->normal, 1, st->ptype); VectorMA(st->org, x, st->x, org);
VectorMA(org, y, st->y, org);
VectorSubtract(org, r_refdef.vieworg, vdist);
if (Length(vdist) > (1024+512)*frandom())
continue;
if (!(cl.worldmodel->hulls->funcs.HullPointContents(cl.worldmodel->hulls, org) & FTECONTENTS_SOLID))
{
if (st->face->flags & SURF_PLANEBACK)
{
vdist[0] = -st->face->plane->normal[0];
vdist[1] = -st->face->plane->normal[1];
vdist[2] = -st->face->plane->normal[2];
R_RunParticleEffectType(org, vdist, 1, ptype);
}
else
R_RunParticleEffectType(org, st->face->plane->normal, 1, ptype);
}
}
} }
} }
} }
@ -1080,17 +1129,17 @@ void R_Part_SkyTri(float *v1, float *v2, float *v3, msurface_t *surf)
skytris_t *st; skytris_t *st;
st = Hunk_Alloc(sizeof(skytris_t)); st = Hunk_Alloc(sizeof(skytris_t));
st->next = skytris; st->next = part_type[surf->texinfo->texture->parttype].skytris;
VectorCopy(v1, st->org); VectorCopy(v1, st->org);
VectorSubtract(v2, st->org, st->x); VectorSubtract(v2, st->org, st->x);
VectorSubtract(v3, st->org, st->y); VectorSubtract(v3, st->org, st->y);
VectorCopy(st->x, xd); VectorCopy(st->x, xd);
VectorCopy(st->y, yd); VectorCopy(st->y, yd);
/*
xd[2] = 0; //prevent area from being valid on vertical surfaces xd[2] = 0; //prevent area from being valid on vertical surfaces
yd[2] = 0; yd[2] = 0;
*/
xm = Length(xd); xm = Length(xd);
ym = Length(yd); ym = Length(yd);
@ -1099,12 +1148,11 @@ void R_Part_SkyTri(float *v1, float *v2, float *v3, msurface_t *surf)
st->area = sin(theta)*xm*ym; st->area = sin(theta)*xm*ym;
st->nexttime = particletime; st->nexttime = particletime;
st->face = surf; st->face = surf;
st->ptype = surf->texinfo->texture->parttype;
if (st->area<=0) if (st->area<=0)
return;//bummer. return;//bummer.
skytris = st; part_type[surf->texinfo->texture->parttype].skytris = st;
} }
@ -1350,9 +1398,6 @@ int R_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum)
if (!ptype->loaded) if (!ptype->loaded)
return 1; return 1;
if (!ptype->scale)
return 1;
while(ptype) while(ptype)
{ {
switch (ptype->spawnmode) switch (ptype->spawnmode)
@ -2144,6 +2189,7 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
normal[0] = -delta[0]; normal[0] = -delta[0];
normal[1] = -delta[1]; normal[1] = -delta[1];
normal[2] = -delta[2]; normal[2] = -delta[2];
VectorCopy (start, impact);
return true; return true;
} }