mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-13 07:47:45 +00:00
beam system overhaul
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@333 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c9f4af34bf
commit
fd5c54cbdc
4 changed files with 702 additions and 643 deletions
|
@ -1068,7 +1068,15 @@ void CL_LinkPacketEntities (void)
|
|||
}
|
||||
if (i == cl_oldnumvisedicts)
|
||||
{
|
||||
cl.lerpents[s1->number].trailstate.lastdist = 0;
|
||||
trailstate_t *t;
|
||||
t = &cl.lerpents[s1->number].trailstate;
|
||||
t->lastdist = 0;
|
||||
if (t->lastbeam)
|
||||
{
|
||||
t->lastbeam->flags &= ~BS_LASTSEG;
|
||||
t->lastbeam->flags |= BS_NODRAW;
|
||||
}
|
||||
t->lastbeam = NULL;
|
||||
continue; // not in last message
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ int R_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum);
|
|||
void D_DrawParticleTrans (particle_t *pparticle);
|
||||
void D_DrawSparkTrans (particle_t *pparticle);
|
||||
|
||||
#define MAX_BEAMS 2048 // default max # of beam segments
|
||||
#define MAX_PARTICLES 32768 // default max # of particles at one
|
||||
// time
|
||||
|
||||
|
@ -85,6 +86,11 @@ particle_t *free_particles;
|
|||
particle_t *particles; //contains the initial list of alloced particles.
|
||||
int r_numparticles;
|
||||
|
||||
beamseg_t *free_beams;
|
||||
|
||||
beamseg_t *beams;
|
||||
int r_numbeams;
|
||||
|
||||
vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
extern cvar_t r_bouncysparks;
|
||||
|
@ -191,6 +197,7 @@ typedef struct part_type_s {
|
|||
|
||||
int loaded;
|
||||
particle_t *particles;
|
||||
beamseg_t *beams;
|
||||
skytris_t *skytris;
|
||||
} part_type_t;
|
||||
int numparticletypes;
|
||||
|
@ -287,6 +294,7 @@ void R_ParticleEffect_f(void)
|
|||
char *var, *value;
|
||||
char *buf;
|
||||
particle_t *parts;
|
||||
beamseg_t *beamsegs;
|
||||
skytris_t *st;
|
||||
|
||||
part_type_t *ptype;
|
||||
|
@ -320,11 +328,13 @@ void R_ParticleEffect_f(void)
|
|||
pnum = ptype-part_type;
|
||||
|
||||
parts = ptype->particles;
|
||||
beamsegs = ptype->beams;
|
||||
st = ptype->skytris;
|
||||
if (ptype->ramp)
|
||||
BZ_Free(ptype->ramp);
|
||||
memset(ptype, 0, sizeof(*ptype));
|
||||
ptype->particles = parts;
|
||||
ptype->beams = beamsegs;
|
||||
ptype->skytris = st;
|
||||
strcpy(ptype->name, Cmd_Argv(1));
|
||||
ptype->assoc=-1;
|
||||
|
@ -767,6 +777,67 @@ void R_DefaultTrail (model_t *model)
|
|||
model->particletrail = -1;
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
// R_BeamInfo_f - debug junk
|
||||
void R_BeamInfo_f (void)
|
||||
{
|
||||
beamseg_t *bs;
|
||||
int i, j, k, l, m;
|
||||
|
||||
i = 0;
|
||||
|
||||
for (bs = free_beams; bs; bs = bs->next)
|
||||
i++;
|
||||
|
||||
Con_Printf("%i free beams\n", i);
|
||||
|
||||
for (i = 0; i < numparticletypes; i++)
|
||||
{
|
||||
m = l = k = j = 0;
|
||||
for (bs = part_type[i].beams; bs; bs = bs->next)
|
||||
{
|
||||
if (!bs->p)
|
||||
k++;
|
||||
|
||||
if (bs->flags & BS_DEAD)
|
||||
l++;
|
||||
|
||||
if (bs->flags & BS_LASTSEG)
|
||||
m++;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j)
|
||||
Con_Printf("Type %i = %i NULL p, %i DEAD, %i LASTSEG, %i total\n", i, k, l, m, j);
|
||||
}
|
||||
}
|
||||
|
||||
void R_PartInfo_f (void)
|
||||
{
|
||||
particle_t *p;
|
||||
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
|
||||
for (p = free_particles; p; p = p->next)
|
||||
i++;
|
||||
|
||||
Con_Printf("%i free particles\n", i);
|
||||
|
||||
for (i = 0; i < numparticletypes; i++)
|
||||
{
|
||||
j = 0;
|
||||
for (p = part_type[i].particles; p; p = p->next)
|
||||
j++;
|
||||
|
||||
if (j)
|
||||
Con_Printf("Type %i = %i total\n", i, j);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
R_InitParticles
|
||||
|
@ -791,13 +862,23 @@ void R_InitParticles (void)
|
|||
r_numparticles = MAX_PARTICLES;
|
||||
}
|
||||
|
||||
r_numbeams = MAX_BEAMS;
|
||||
|
||||
particles = (particle_t *)
|
||||
Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles");
|
||||
|
||||
beams = (beamseg_t *)
|
||||
Hunk_AllocName (r_numbeams * sizeof(beamseg_t), "beams");
|
||||
|
||||
Cmd_AddCommand("r_part", R_ParticleEffect_f);
|
||||
Cmd_AddCommand("r_effect", R_AssosiateEffect_f);
|
||||
Cmd_AddCommand("r_trail", R_AssosiateTrail_f);
|
||||
|
||||
#if _DEBUG
|
||||
Cmd_AddCommand("r_partinfo", R_PartInfo_f);
|
||||
Cmd_AddCommand("r_beaminfo", R_BeamInfo_f);
|
||||
#endif
|
||||
|
||||
//particles
|
||||
Cvar_Register(&r_particlesdesc, particlecvargroupname);
|
||||
Cvar_Register(&r_bouncysparks, particlecvargroupname);
|
||||
|
@ -855,6 +936,16 @@ void R_ClearParticles (void)
|
|||
particles[i].next = &particles[i+1];
|
||||
particles[r_numparticles-1].next = NULL;
|
||||
|
||||
free_beams = &beams[0];
|
||||
|
||||
for (i=0 ;i<r_numbeams ; i++)
|
||||
{
|
||||
beams[i].p = NULL;
|
||||
beams[i].flags = BS_DEAD;
|
||||
beams[i].next = &beams[i+1];
|
||||
}
|
||||
beams[r_numbeams-1].next = NULL;
|
||||
|
||||
particletime = cl.time;
|
||||
|
||||
#ifdef RGLQUAKE
|
||||
|
@ -875,6 +966,7 @@ void R_ClearParticles (void)
|
|||
for (i = 0; i < numparticletypes; i++)
|
||||
{
|
||||
part_type[i].particles = NULL;
|
||||
part_type[i].beams = NULL;
|
||||
part_type[i].skytris = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1399,89 +1491,6 @@ int R_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum)
|
|||
return 1;
|
||||
|
||||
while(ptype)
|
||||
{
|
||||
if (ptype->isbeam)
|
||||
{
|
||||
vec3_t lastorg, lastdir;
|
||||
float a;
|
||||
|
||||
switch (ptype->spawnmode)
|
||||
{
|
||||
default:
|
||||
a = (2*M_PI);
|
||||
lastorg[0] = org[0] + sin(a)*ptype->areaspread;
|
||||
lastorg[1] = org[1] + cos(a)*ptype->areaspread;
|
||||
lastorg[2] = org[2] + ptype->offsetup;
|
||||
|
||||
VectorNormalize(lastdir);
|
||||
|
||||
for (i = 0; i < count*ptype->count; i++)
|
||||
{
|
||||
if (!free_particles)
|
||||
return 0;
|
||||
p = free_particles;
|
||||
free_particles = p->next;
|
||||
p->next = ptype->particles;
|
||||
ptype->particles = p;
|
||||
|
||||
p->die = ptype->randdie*frandom();
|
||||
p->scale = ptype->scale+ptype->randscale*frandom();
|
||||
p->alpha = ptype->alpha-p->die*(ptype->alpha/ptype->die)*ptype->alphachange;
|
||||
p->color = 0;
|
||||
|
||||
if (ptype->colorindex >= 0)
|
||||
{
|
||||
int cidx;
|
||||
cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0;
|
||||
cidx = ptype->colorindex + cidx;
|
||||
if (cidx > 255)
|
||||
p->alpha = p->alpha / 2;
|
||||
cidx = d_8to24rgbtable[cidx & 0xff];
|
||||
p->rgb[0] = (cidx & 0xff) * (1/255.0);
|
||||
p->rgb[1] = (cidx >> 8 & 0xff) * (1/255.0);
|
||||
p->rgb[2] = (cidx >> 16 & 0xff) * (1/255.0);
|
||||
}
|
||||
else
|
||||
VectorCopy(ptype->rgb, p->rgb);
|
||||
|
||||
// use org temporarily for rgbsync
|
||||
p->org[2] = frandom();
|
||||
p->org[0] = p->org[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]);
|
||||
p->org[1] = p->org[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]);
|
||||
p->org[2] = p->org[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]);
|
||||
|
||||
p->rgb[0] += p->org[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*p->die;
|
||||
p->rgb[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die;
|
||||
p->rgb[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die;
|
||||
|
||||
p->org[0] = hrandom();
|
||||
p->org[1] = hrandom();
|
||||
if (ptype->areaspreadvert)
|
||||
p->org[2] = hrandom();
|
||||
else
|
||||
p->org[2] = 0;
|
||||
|
||||
VectorNormalize(p->org);
|
||||
if (ptype->spawnmode != SM_CIRCLE)
|
||||
VectorScale(p->org, frandom(), p->org);
|
||||
|
||||
p->org[0] = org[0] + p->org[0]*ptype->areaspread;
|
||||
p->org[1] = org[1] + p->org[1]*ptype->areaspread;
|
||||
p->org[2] = org[2] + p->org[2]*ptype->areaspreadvert + ptype->offsetup;
|
||||
|
||||
p->die = particletime + ptype->die - p->die;
|
||||
|
||||
VectorCopy(lastorg, p->u.b.org2);
|
||||
VectorCopy(lastdir, p->u.b.lastdir);
|
||||
|
||||
VectorCopy(p->org, lastorg);
|
||||
VectorSubtract(p->org, p->u.b.org2, lastdir);
|
||||
VectorNormalize(lastdir);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ptype->spawnmode)
|
||||
{
|
||||
|
@ -1823,8 +1832,6 @@ int R_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum)
|
|||
p->die = particletime + ptype->die - p->die;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ptype->assoc < 0)
|
||||
break;
|
||||
|
@ -2039,6 +2046,8 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
int tcount;
|
||||
particle_t *p;
|
||||
part_type_t *ptype = &part_type[type];
|
||||
beamseg_t *b;
|
||||
beamseg_t *bfirst;
|
||||
|
||||
float veladd = -ptype->veladd;
|
||||
float randvel = ptype->randomvel;
|
||||
|
@ -2086,37 +2095,7 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
if (len/step > 1024)
|
||||
return;
|
||||
|
||||
if (!len && ptype->isbeam)
|
||||
{ //first particle of the trail
|
||||
switch(ptype->spawnmode)
|
||||
{
|
||||
case SM_SPIRAL:
|
||||
{
|
||||
float tsin, tcos;
|
||||
|
||||
tcos = cos(len/50)*ptype->areaspread;
|
||||
tsin = sin(len/50)*ptype->areaspread;
|
||||
|
||||
ts->lastorg[0] = start[0] + right[0]*tcos + up[0]*tsin;
|
||||
ts->lastorg[1] = start[1] + right[1]*tcos + up[1]*tsin;
|
||||
ts->lastorg[2] = start[2] + right[2]*tcos + up[2]*tsin;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ts->lastorg[0] = crandom();
|
||||
ts->lastorg[1] = crandom();
|
||||
ts->lastorg[2] = crandom();
|
||||
|
||||
ts->lastorg[0] = ts->lastorg[0]*ptype->areaspread + start[0];
|
||||
ts->lastorg[1] = ts->lastorg[1]*ptype->areaspread + start[1];
|
||||
ts->lastorg[2] = ts->lastorg[2]*ptype->areaspreadvert + start[2];
|
||||
break;
|
||||
}
|
||||
VectorCopy(vec, ts->lastdir);
|
||||
|
||||
len += step;
|
||||
stop += step;
|
||||
}
|
||||
b = bfirst = NULL;
|
||||
|
||||
while (len < stop)
|
||||
{
|
||||
|
@ -2124,10 +2103,34 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
|
||||
if (!free_particles)
|
||||
{
|
||||
ts->lastdist = stop;
|
||||
return;
|
||||
len = stop;
|
||||
break;
|
||||
}
|
||||
|
||||
p = free_particles;
|
||||
|
||||
if (ptype->isbeam)
|
||||
{
|
||||
if (!free_beams)
|
||||
{
|
||||
len = stop;
|
||||
break;
|
||||
}
|
||||
if (b)
|
||||
{
|
||||
b = b->next = free_beams;
|
||||
free_beams = free_beams->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = bfirst = free_beams;
|
||||
free_beams = free_beams->next;
|
||||
}
|
||||
b->flags = 0;
|
||||
b->p = p;
|
||||
VectorCopy(vec, b->dir);
|
||||
}
|
||||
|
||||
free_particles = p->next;
|
||||
p->next = ptype->particles;
|
||||
ptype->particles = p;
|
||||
|
@ -2168,41 +2171,6 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
p->rgb[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die;
|
||||
p->rgb[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die;
|
||||
|
||||
if (ptype->isbeam)
|
||||
{
|
||||
switch(ptype->spawnmode)
|
||||
{
|
||||
case SM_SPIRAL:
|
||||
{
|
||||
float tsin, tcos;
|
||||
|
||||
tcos = cos(len/50)*ptype->areaspread;
|
||||
tsin = sin(len/50)*ptype->areaspread;
|
||||
|
||||
p->org[0] = start[0] + right[0]*tcos + up[0]*tsin;
|
||||
p->org[1] = start[1] + right[1]*tcos + up[1]*tsin;
|
||||
p->org[2] = start[2] + right[2]*tcos + up[2]*tsin;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
p->org[0] = crandom();
|
||||
p->org[1] = crandom();
|
||||
p->org[2] = crandom();
|
||||
|
||||
p->org[0] = p->org[0]*ptype->areaspread + start[0];
|
||||
p->org[1] = p->org[1]*ptype->areaspread + start[1];
|
||||
p->org[2] = p->org[2]*ptype->areaspreadvert + start[2];
|
||||
break;
|
||||
}
|
||||
VectorCopy(ts->lastorg, p->u.b.org2);
|
||||
VectorCopy(ts->lastdir, p->u.b.lastdir);
|
||||
|
||||
VectorCopy(p->org, ts->lastorg);
|
||||
VectorSubtract(p->org, p->u.b.org2, ts->lastdir);
|
||||
VectorNormalize(ts->lastdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy (vec3_origin, p->u.p.vel);
|
||||
p->u.p.nextemit = particletime + ptype->emitstart - p->die;
|
||||
|
||||
|
@ -2268,7 +2236,6 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
p->org[2] = p->org[2]*ptype->areaspreadvert + start[2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VectorMA (start, step, vec, start);
|
||||
|
||||
|
@ -2276,6 +2243,47 @@ void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *ts)
|
|||
}
|
||||
|
||||
ts->lastdist = len;
|
||||
|
||||
// update beamseg list
|
||||
if (ptype->isbeam)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
if (ptype->beams)
|
||||
{
|
||||
if (ts->lastbeam)
|
||||
{
|
||||
b->next = ts->lastbeam->next;
|
||||
ts->lastbeam->next = bfirst;
|
||||
ts->lastbeam->flags &= ~BS_LASTSEG;
|
||||
}
|
||||
else
|
||||
{
|
||||
b->next = ptype->beams;
|
||||
ptype->beams = bfirst;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptype->beams = bfirst;
|
||||
b->next = NULL;
|
||||
}
|
||||
|
||||
b->flags |= BS_LASTSEG;
|
||||
ts->lastbeam = b;
|
||||
}
|
||||
|
||||
if (!free_particles || !free_beams)
|
||||
{
|
||||
if (ts->lastbeam)
|
||||
{
|
||||
b->flags &= ~BS_LASTSEG;
|
||||
b->flags |= BS_NODRAW;
|
||||
ts->lastbeam = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return; //distance the trail actually moved.
|
||||
}
|
||||
|
||||
|
@ -2551,10 +2559,27 @@ void GL_DrawSparkedParticle(particle_t *p, part_type_t *type)
|
|||
glVertex3f (p->org[0]-p->u.p.vel[0]/10, p->org[1]-p->u.p.vel[1]/10, p->org[2]-p->u.p.vel[2]/10);
|
||||
|
||||
}
|
||||
void GL_DrawParticleBeam(particle_t *p, part_type_t *type)
|
||||
void GL_DrawParticleBeam(beamseg_t *b, part_type_t *type)
|
||||
{
|
||||
vec3_t v, point;
|
||||
vec3_t fwd, cr;
|
||||
vec3_t cr;
|
||||
beamseg_t *c;
|
||||
particle_t *p;
|
||||
particle_t *q;
|
||||
|
||||
// if (!b->next)
|
||||
// return;
|
||||
|
||||
c = b->next;
|
||||
|
||||
q = c->p;
|
||||
// if (!q)
|
||||
// return;
|
||||
|
||||
p = b->p;
|
||||
// if (!p)
|
||||
// return;
|
||||
|
||||
if (lasttype != type)
|
||||
{
|
||||
lasttype = type;
|
||||
|
@ -2570,33 +2595,36 @@ void GL_DrawParticleBeam(particle_t *p, part_type_t *type)
|
|||
glShadeModel(GL_SMOOTH);
|
||||
glBegin(GL_QUADS);
|
||||
}
|
||||
glColor4f(q->rgb[0],
|
||||
q->rgb[1],
|
||||
q->rgb[2],
|
||||
q->alpha);
|
||||
// glBegin(GL_LINE_LOOP);
|
||||
VectorSubtract(r_refdef.vieworg, q->org, v);
|
||||
VectorNormalize(v);
|
||||
CrossProduct(c->dir, v, cr);
|
||||
|
||||
VectorMA(q->org, -q->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
VectorMA(q->org, q->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
|
||||
glColor4f(p->rgb[0],
|
||||
p->rgb[1],
|
||||
p->rgb[2],
|
||||
p->alpha);
|
||||
// glBegin(GL_LINE_LOOP);
|
||||
VectorSubtract(p->org, p->u.b.org2, fwd);
|
||||
VectorNormalize(fwd);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, p->org, v);
|
||||
VectorNormalize(v);
|
||||
CrossProduct(fwd, v, cr);
|
||||
CrossProduct(b->dir, v, cr); // replace with old p->dir?
|
||||
|
||||
VectorMA(p->org, -p->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
VectorMA(p->org, p->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, p->u.b.org2, v);
|
||||
VectorNormalize(v);
|
||||
CrossProduct(p->u.b.lastdir, v, cr);
|
||||
|
||||
VectorMA(p->u.b.org2, p->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
VectorMA(p->u.b.org2, -p->scale, cr, point);
|
||||
VectorMA(p->org, -p->scale, cr, point);
|
||||
glVertex3fv(point);
|
||||
// glEnd();
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
void SWD_DrawParticleSpark(particle_t *p, part_type_t *type)
|
||||
|
@ -2642,7 +2670,7 @@ void SWD_DrawParticleBlob(particle_t *p, part_type_t *type)
|
|||
D_DrawParticleTrans(p);
|
||||
}
|
||||
#endif
|
||||
void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void sparkparticles(particle_t*,part_type_t*), void beamparticles(particle_t*,part_type_t*))
|
||||
void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void sparkparticles(particle_t*,part_type_t*), void beamparticles(beamseg_t*,part_type_t*))
|
||||
{
|
||||
qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
|
||||
|
||||
|
@ -2655,6 +2683,8 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
float grav;
|
||||
vec3_t friction;
|
||||
float dist;
|
||||
particle_t *kill_list, *kill_first;
|
||||
beamseg_t *b, *bkill;
|
||||
|
||||
int traces=r_particle_tracelimit.value;
|
||||
|
||||
|
@ -2679,6 +2709,7 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
#endif
|
||||
tr = TraceLineN;
|
||||
|
||||
kill_list = kill_first = NULL;
|
||||
|
||||
for (i = 0; i < numparticletypes; i++)
|
||||
{
|
||||
|
@ -2687,15 +2718,22 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
if (!type->die)
|
||||
{
|
||||
while ((p=type->particles))
|
||||
{
|
||||
if (!type->isbeam)
|
||||
{
|
||||
if (*type->texname)
|
||||
RQ_AddDistReorder((void*)texturedparticles, p, type, p->org);
|
||||
else
|
||||
RQ_AddDistReorder((void*)sparkparticles, p, type, p->org);
|
||||
}
|
||||
|
||||
type->particles = p->next;
|
||||
p->next = free_particles;
|
||||
free_particles = p;
|
||||
// p->next = free_particles;
|
||||
// free_particles = p;
|
||||
p->next = kill_list;
|
||||
kill_list = p;
|
||||
if (!kill_first) // branch here is probably faster than list traversal later
|
||||
kill_first = p;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -2707,110 +2745,17 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
if (kill && kill->die < particletime)
|
||||
{
|
||||
type->particles = kill->next;
|
||||
kill->next = free_particles;
|
||||
free_particles = kill;
|
||||
// kill->next = free_particles;
|
||||
// free_particles = kill;
|
||||
kill->next = kill_list;
|
||||
kill_list = kill;
|
||||
if (!kill_first)
|
||||
kill_first = kill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (type->isbeam)
|
||||
{ //beams do not:
|
||||
//a: emit other particles
|
||||
//b: move
|
||||
//c: bounce
|
||||
//d: stain
|
||||
//e: obay the laws of physics in any way, shape or form.
|
||||
//f: rotate
|
||||
//g: work in SW.
|
||||
|
||||
//They do:
|
||||
//1: change colour
|
||||
//2: change alpha
|
||||
//3: change scale
|
||||
//4: follow ramps
|
||||
//5: look better than a shitload of blobby particles.
|
||||
//6: die
|
||||
|
||||
//quirks:
|
||||
//q1: beams store point A in thier origin, and point B in thier velocity
|
||||
//q2: depth 'testing' evaluates from thier central point.
|
||||
|
||||
//g
|
||||
if (!beamparticles)
|
||||
{
|
||||
for (p=type->particles ; p ; p=p->next)
|
||||
for ( ;; )
|
||||
{
|
||||
kill = p->next;
|
||||
if (kill && kill->die < particletime)
|
||||
{
|
||||
p->next = kill->next;
|
||||
kill->next = free_particles;
|
||||
free_particles = kill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//6
|
||||
for (p=type->particles ; p ; p=p->next)
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
kill = p->next;
|
||||
if (kill && kill->die < particletime)
|
||||
{
|
||||
p->next = kill->next;
|
||||
kill->next = free_particles;
|
||||
free_particles = kill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//4
|
||||
switch (type->rampmode)
|
||||
{
|
||||
case RAMP_ABSOLUTE:
|
||||
ramp = type->ramp + (int)(type->rampindexes * (type->die - (p->die - particletime)) / type->die);
|
||||
VectorCopy(ramp->rgb, p->rgb);
|
||||
p->alpha = ramp->alpha;
|
||||
p->scale = ramp->scale;
|
||||
break;
|
||||
case RAMP_DELTA: //particle ramps
|
||||
ramp = type->ramp + (int)(type->rampindexes * (type->die - (p->die - particletime)) / type->die);
|
||||
VectorMA(p->rgb, pframetime, ramp->rgb, p->rgb);
|
||||
p->alpha -= pframetime*ramp->alpha;
|
||||
p->scale += pframetime*ramp->scale;
|
||||
break;
|
||||
case RAMP_NONE: //particle changes acording to it's preset properties.
|
||||
//1
|
||||
if (particletime < (p->die-type->die+type->rgbchangetime))
|
||||
{
|
||||
p->rgb[0] += pframetime*type->rgbchange[0];
|
||||
p->rgb[1] += pframetime*type->rgbchange[1];
|
||||
p->rgb[2] += pframetime*type->rgbchange[2];
|
||||
}
|
||||
//2
|
||||
p->alpha -= pframetime*(type->alpha/type->die)*type->alphachange;
|
||||
//3
|
||||
p->scale += pframetime*type->scaledelta;
|
||||
}
|
||||
|
||||
//quirk 2
|
||||
stop[0] = (p->org[0] + p->u.b.org2[0])/2;
|
||||
stop[1] = (p->org[1] + p->u.b.org2[1])/2;
|
||||
stop[2] = (p->org[2] + p->u.b.org2[2])/2;
|
||||
//5
|
||||
RQ_AddDistReorder((void*)beamparticles, p, type, stop);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
grav = type->gravity*pframetime;
|
||||
VectorScale(type->friction, pframetime, friction);
|
||||
|
||||
|
@ -2822,8 +2767,12 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
if (kill && kill->die < particletime)
|
||||
{
|
||||
p->next = kill->next;
|
||||
kill->next = free_particles;
|
||||
free_particles = kill;
|
||||
// kill->next = free_particles;
|
||||
// free_particles = kill;
|
||||
kill->next = kill_list;
|
||||
kill_list = kill;
|
||||
if (!kill_first)
|
||||
kill_first = kill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -2921,6 +2870,8 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
}
|
||||
}
|
||||
|
||||
if (!type->isbeam)
|
||||
{
|
||||
if (*type->texname)
|
||||
RQ_AddDistReorder((void*)texturedparticles, p, type, p->org);
|
||||
else
|
||||
|
@ -2928,8 +2879,92 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
}
|
||||
}
|
||||
|
||||
// beams are dealt with here
|
||||
|
||||
// kill early entries
|
||||
for ( ;; )
|
||||
{
|
||||
bkill = type->beams;
|
||||
if (bkill && (bkill->flags & BS_DEAD || bkill->p->die < particletime) && !(bkill->flags & BS_LASTSEG))
|
||||
{
|
||||
type->beams = bkill->next;
|
||||
bkill->next = free_beams;
|
||||
free_beams = bkill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
b = type->beams;
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if (b->next)
|
||||
{
|
||||
// mark dead entries
|
||||
if (b->flags & (BS_LASTSEG|BS_DEAD|BS_NODRAW))
|
||||
{
|
||||
// kill some more dead entries
|
||||
for ( ;; )
|
||||
{
|
||||
bkill = b->next;
|
||||
if (bkill && (bkill->flags & BS_DEAD) && !(bkill->flags & BS_LASTSEG))
|
||||
{
|
||||
b->next = bkill->next;
|
||||
bkill->next = free_beams;
|
||||
free_beams = bkill;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bkill) // have to check so we don't hit NULL->next
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(b->next->flags & BS_DEAD))
|
||||
{
|
||||
VectorCopy(b->next->p->org, stop);
|
||||
VectorCopy(b->p->org, oldorg);
|
||||
VectorSubtract(stop, oldorg, b->next->dir);
|
||||
VectorNormalize(b->next->dir);
|
||||
VectorAdd(stop, oldorg, stop);
|
||||
VectorScale(stop, 0.5, stop);
|
||||
RQ_AddDistReorder((void*)beamparticles, b, type, stop);
|
||||
}
|
||||
|
||||
// if (b->p->die < particletime)
|
||||
// b->flags |= BS_DEAD;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b->p->die < particletime) // end of the list check
|
||||
b->flags |= BS_DEAD;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (b->p->die < particletime)
|
||||
b->flags |= BS_DEAD;
|
||||
|
||||
b = b->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RQ_RenderDistAndClear();
|
||||
|
||||
// lazy delete for particles is done here
|
||||
if (kill_list)
|
||||
{
|
||||
kill_first->next = free_particles;
|
||||
free_particles = kill_list;
|
||||
}
|
||||
|
||||
particletime += pframetime;
|
||||
}
|
||||
|
|
|
@ -192,10 +192,13 @@ void MediaSW_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight);
|
|||
void R_ParseParticleEffect (void);
|
||||
void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count);
|
||||
|
||||
typedef struct beamseg_s beamseg_t;
|
||||
|
||||
typedef struct {
|
||||
float lastdist;
|
||||
vec3_t lastorg; //use only if lastdist
|
||||
vec3_t lastdir; //use only if lastdist
|
||||
beamseg_t *lastbeam; // last beam point
|
||||
} trailstate_t;
|
||||
void R_RocketTrail (vec3_t start, vec3_t end, int type, trailstate_t *oldpoint);
|
||||
int R_RunParticleEffectType(vec3_t org, vec3_t dir, float count, int type);
|
||||
|
|
|
@ -62,10 +62,11 @@ typedef struct particle_s
|
|||
float rotationspeed;
|
||||
float nextemit;
|
||||
} p; //point blob
|
||||
struct {
|
||||
/* struct {
|
||||
vec3_t org2;
|
||||
vec3_t lastdir;
|
||||
} b; //beam
|
||||
} b;
|
||||
*/
|
||||
} u;
|
||||
|
||||
// drivers never touch the following fields
|
||||
|
@ -74,6 +75,18 @@ typedef struct particle_s
|
|||
float die;
|
||||
} particle_t;
|
||||
|
||||
#define BS_LASTSEG 0x1 // no draw to next, no delete
|
||||
#define BS_DEAD 0x2 // segment is dead
|
||||
#define BS_NODRAW 0x4 // only used for lerp switching
|
||||
|
||||
typedef struct beamseg_s
|
||||
{
|
||||
particle_t *p;
|
||||
struct beamseg_s *next; // next in beamseg list
|
||||
int flags; // flags for beamseg
|
||||
vec3_t dir;
|
||||
} beamseg_t;
|
||||
|
||||
#define PARTICLE_Z_CLIP 8.0
|
||||
|
||||
#define frandom() (rand()*(1.0f/RAND_MAX))
|
||||
|
|
Loading…
Reference in a new issue