fix fallback particles not rendering properly with high fps

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6032 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
TimeServ 2021-08-21 21:33:09 +00:00
parent ee1a93d01b
commit d63a4cea1f
2 changed files with 62 additions and 80 deletions

View file

@ -4173,6 +4173,35 @@ static trailstate_t *P_NewTrailstate(trailstate_t **key)
return ts; return ts;
} }
static trailstate_t* P_FetchTrailstate(trailstate_t** tsk)
{
trailstate_t* ts;
// trailstate allocation/deallocation
if (tsk)
{
if (*tsk == NULL)
{
ts = P_NewTrailstate(tsk);
*tsk = ts;
}
else
{
ts = *tsk;
if (ts->key != tsk) // trailstate was overwritten
{
ts = P_NewTrailstate(tsk); // so get a new one
*tsk = ts;
}
}
}
else
ts = NULL;
return ts;
}
#define NUMVERTEXNORMALS 162 #define NUMVERTEXNORMALS 162
static float r_avertexnormals[NUMVERTEXNORMALS][3] = { static float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "anorms.h" #include "anorms.h"
@ -4665,28 +4694,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
if (ptype->flags & PT_NOSTATE) if (ptype->flags & PT_NOSTATE)
tsk = NULL; tsk = NULL;
// trailstate allocation/deallocation ts = P_FetchTrailstate(tsk);
if (tsk)
{
// if *tsk = NULL get a new one
if (*tsk == NULL)
{
ts = P_NewTrailstate(tsk);
*tsk = ts;
}
else
{
ts = *tsk;
if (ts->key != tsk) // trailstate was overwritten
{
ts = P_NewTrailstate(tsk); // so get a new one
*tsk = ts;
}
}
}
else
ts = NULL;
// get msvc to shut up // get msvc to shut up
j = k = l = 0; j = k = l = 0;
@ -4830,7 +4838,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
if (ptype->flags & PT_INVFRAMETIME) if (ptype->flags & PT_INVFRAMETIME)
pcount /= host_frametime; pcount /= host_frametime;
if (ts) if (ts)
pcount += ts->state2.emittime; pcount += ts->effect.emittime;
pcount *= r_part_density.value; pcount *= r_part_density.value;
@ -4889,10 +4897,10 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
// time limit (for completeness) // time limit (for completeness)
if (ptype->spawntime && ts) if (ptype->spawntime && ts)
{ {
if (ts->state1.statetime > particletime) if (ts->effect.statetime > particletime)
return 0; // timelimit still in effect return 0; // timelimit still in effect
ts->state1.statetime = particletime + ptype->spawntime; // record old time ts->effect.statetime = particletime + ptype->spawntime; // record old time
} }
// random chance for point effects // random chance for point effects
@ -5233,7 +5241,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
// save off emit times in trailstate // save off emit times in trailstate
if (ts) if (ts)
ts->state2.emittime = pcount - i; ts->effect.emittime = pcount - i;
// maintain run list // maintain run list
if (!(ptype->state & PS_INRUNLIST) && (ptype->particles || ptype->clippeddecals)) if (!(ptype->state & PS_INRUNLIST) && (ptype->particles || ptype->clippeddecals))
@ -5256,22 +5264,7 @@ skip:
if (ts) if (ts)
{ {
tsk = &(ts->assoc); tsk = &(ts->assoc);
// if *tsk = NULL get a new one ts = P_FetchTrailstate(tsk);
if (*tsk == NULL)
{
ts = P_NewTrailstate(tsk);
*tsk = ts;
}
else
{
ts = *tsk;
if (ts->key != tsk) // trailstate was overwritten
{
ts = P_NewTrailstate(tsk); // so get a new one
*tsk = ts;
}
}
} }
ptype = &part_type[ptype->assoc]; ptype = &part_type[ptype->assoc];
@ -5557,7 +5550,7 @@ static void PScript_RunParticleEffectPalette (const char *nameprefix, vec3_t org
} }
} }
static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptype, float timeinterval, trailstate_t **tsk, int dlkey, vec3_t dlaxis[3]) static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptype, float timeinterval, trailstate_t** tsk, int dlkey, vec3_t dlaxis[3])
{ {
vec3_t vec, vstep, right, up, start; vec3_t vec, vstep, right, up, start;
float len; float len;
@ -5581,28 +5574,7 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
if (ptype->flags & PT_NOSTATE) if (ptype->flags & PT_NOSTATE)
tsk = NULL; tsk = NULL;
// trailstate allocation/deallocation ts = P_FetchTrailstate(tsk);
if (tsk)
{
// if *tsk = NULL get a new one
if (*tsk == NULL)
{
ts = P_NewTrailstate(tsk);
*tsk = ts;
}
else
{
ts = *tsk;
if (ts->key != tsk) // trailstate was overwritten
{
ts = P_NewTrailstate(tsk); // so get a new one
*tsk = ts;
}
}
}
else
ts = NULL;
PScript_EffectSpawned(ptype, start, dlaxis, dlkey, 1); PScript_EffectSpawned(ptype, start, dlaxis, dlkey, 1);
@ -5628,10 +5600,10 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
// time limit for trails // time limit for trails
if (ptype->spawntime && ts) if (ptype->spawntime && ts)
{ {
if (ts->state1.statetime > particletime) if (ts->effect.statetime > particletime)
return; // timelimit still in effect return; // timelimit still in effect
ts->state1.statetime = particletime + ptype->spawntime; // record old time ts->effect.statetime = particletime + ptype->spawntime; // record old time
ts = NULL; // clear trailstate so we don't save length/lastseg ts = NULL; // clear trailstate so we don't save length/lastseg
} }
@ -5674,8 +5646,8 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
// store last stop here for lack of a better solution besides vectors // store last stop here for lack of a better solution besides vectors
if (ts) if (ts)
{ {
ts->state2.laststop = stop = ts->state2.laststop + len; //when to stop ts->trail.laststop = stop = ts->trail.laststop + len; //when to stop
len = ts->state1.lastdist; len = ts->trail.lastdist;
} }
else else
{ {
@ -6016,7 +5988,7 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
if (ts) if (ts)
{ {
ts->state1.lastdist = len; ts->trail.lastdist = len;
// update beamseg list // update beamseg list
if (ptype->looks.type == PT_BEAM||ptype->looks.type == PT_VBEAM) if (ptype->looks.type == PT_BEAM||ptype->looks.type == PT_VBEAM)
@ -6083,10 +6055,17 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, float t
{ {
part_type_t *ptype = &part_type[type]; part_type_t *ptype = &part_type[type];
// TODO: fallback particle system won't have a decent trailstate which will mess up
// high fps trails
if (type >= FALLBACKBIAS && fallback) if (type >= FALLBACKBIAS && fallback)
return fallback->ParticleTrail(startpos, end, type-FALLBACKBIAS, timeinterval, dlkey, axis, NULL); {
// this will cause problems if dealing with fallbacks that actually
// allocate their own trail state, but for now this should suffice
//
// also reusing fallback space for emit/trail info will cause some
// issues with entities in action during particle reconfiguration
// but that shouldn't be happening too often
trailstate_t* ts = P_FetchTrailstate(tsk);
return fallback->ParticleTrail(startpos, end, type - FALLBACKBIAS, timeinterval, dlkey, axis, &(ts->fallback));
}
if (type < 0 || type >= numparticletypes) if (type < 0 || type >= numparticletypes)
return 1; //bad value return 1; //bad value

View file

@ -173,13 +173,16 @@ typedef struct trailstate_s {
struct trailstate_s *assoc; // assoc linked trail struct trailstate_s *assoc; // assoc linked trail
struct beamseg_s *lastbeam; // last beam pointer (flagged with BS_LASTSEG) struct beamseg_s *lastbeam; // last beam pointer (flagged with BS_LASTSEG)
union { union {
float lastdist; // last distance used with particle effect struct {
float statetime; // time to emit effect again (used by spawntime field) float lastdist; // last distance used with particle effect
} state1; float laststop; // last stopping point for particle effect
union { } trail;
float laststop; // last stopping point for particle effect struct {
float emittime; // used by r_effect emitters float statetime; // time to emit effect again (used by spawntime field)
} state2; float emittime; // used by r_effect emitters
} effect;
struct trailstate_s* fallback;
};
} trailstate_t; } trailstate_t;
#define PARTICLE_Z_CLIP 8.0 #define PARTICLE_Z_CLIP 8.0