From 45a00f30d21c9f3d3833c6110c034b4fd7106d83 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 27 Jul 2013 10:24:22 +0000 Subject: [PATCH] Separate box and trail particles. Makes Xonotic's Nex beam possible again. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11985 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 12 ++++++------ cl_particles.c | 45 ++++++++++++++++++++++++++++++++------------- client.h | 3 ++- clvm_cmds.c | 25 +++++++++++++++++++++---- prvm_offsets.h | 2 ++ 5 files changed, 63 insertions(+), 24 deletions(-) diff --git a/cl_main.c b/cl_main.c index 76f27168..d50d4dd6 100644 --- a/cl_main.c +++ b/cl_main.c @@ -1218,9 +1218,9 @@ static void CL_UpdateNetworkEntityTrail(entity_t *e) CL_EntityParticles(e); } if (e->render.effects & EF_FLAME) - CL_ParticleTrail(EFFECT_EF_FLAME, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL); + CL_ParticleTrail(EFFECT_EF_FLAME, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL, 1); if (e->render.effects & EF_STARDUST) - CL_ParticleTrail(EFFECT_EF_STARDUST, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL); + CL_ParticleTrail(EFFECT_EF_STARDUST, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true, NULL, NULL, 1); } if (e->render.internaleffects & (INTEF_FLAG1QW | INTEF_FLAG2QW)) { @@ -1267,7 +1267,7 @@ static void CL_UpdateNetworkEntityTrail(entity_t *e) len = 1.0f / len; VectorScale(vel, len, vel); // pass time as count so that trails that are time based (such as an emitter) will emit properly as long as they don't use trailspacing - CL_ParticleTrail(trailtype, bound(0, cl.time - cl.oldtime, 0.1), e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true, NULL, NULL); + CL_ParticleTrail(trailtype, bound(0, cl.time - cl.oldtime, 0.1), e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true, NULL, NULL, 1); } // now that the entity has survived one trail update it is allowed to // leave a real trail on later frames @@ -1472,9 +1472,9 @@ static void CL_LinkNetworkEntity(entity_t *e) dlightcolor[2] += 1.50f; } if (e->render.effects & EF_FLAME) - CL_ParticleTrail(EFFECT_EF_FLAME, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL); + CL_ParticleTrail(EFFECT_EF_FLAME, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL, 1); if (e->render.effects & EF_STARDUST) - CL_ParticleTrail(EFFECT_EF_STARDUST, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL); + CL_ParticleTrail(EFFECT_EF_STARDUST, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0, true, false, NULL, NULL, 1); } // muzzleflash fades over time, and is offset a bit if (e->persistent.muzzleflash > 0 && r_refdef.scene.numlights < MAX_DLIGHTS) @@ -1556,7 +1556,7 @@ static void CL_LinkNetworkEntity(entity_t *e) if (e->state_current.traileffectnum) trailtype = (effectnameindex_t)e->state_current.traileffectnum; if (trailtype) - CL_ParticleTrail(trailtype, 1, origin, origin, vec3_origin, vec3_origin, NULL, e->state_current.glowcolor, true, false, NULL, NULL); + CL_ParticleTrail(trailtype, 1, origin, origin, vec3_origin, vec3_origin, NULL, e->state_current.glowcolor, true, false, NULL, NULL, 1); // don't show entities with no modelindex (note: this still shows // entities which have a modelindex that resolved to a NULL model) diff --git a/cl_particles.c b/cl_particles.c index 941c638e..e2e9ca08 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -1442,7 +1442,7 @@ static void CL_ParticleEffect_Fallback(int effectnameindex, float count, const v // spawnparticles = true // it is called CL_ParticleTrail because most code does not want to supply // these parameters, only trail handling does -void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4]) +static void CL_NewParticlesFromEffectinfo(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade, qboolean istrail) { qboolean found = false; char vabuf[1024]; @@ -1497,11 +1497,15 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins if ((info->flags & PARTICLEEFFECT_NOTUNDERWATER) && underwater) continue; + // if trailspacing is set, only ever use this effect as trail + if (info->trailspacing > 0 && !istrail) + continue; + // spawn a dlight if requested if (info->lightradiusstart > 0 && spawndlight) { matrix4x4_t tempmatrix; - if (info->trailspacing > 0) + if (istrail) Matrix4x4_CreateTranslate(&tempmatrix, originmaxs[0], originmaxs[1], originmaxs[2]); else Matrix4x4_CreateTranslate(&tempmatrix, center[0], center[1], center[2]); @@ -1573,20 +1577,25 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins default: break; } VectorCopy(originmins, trailpos); - if (info->trailspacing > 0) + if (istrail) { - info->particleaccumulator += traillen / info->trailspacing * cl_particles_quality.value; - trailstep = info->trailspacing / cl_particles_quality.value; + float cnt = info->countabsolute; + cnt += (pcount * info->countmultiplier) * cl_particles_quality.value; + if (info->trailspacing > 0) + cnt += (traillen / info->trailspacing) * cl_particles_quality.value; + cnt *= fade; + info->particleaccumulator += cnt; + trailstep = traillen / cnt; immediatebloodstain = false; AnglesFromVectors(angles, traildir, NULL, false); - AngleVectors(angles, forward, right, up); - VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos); - VectorMAMAM(info->relativevelocityoffset[0], forward, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity); } else { - info->particleaccumulator += info->countabsolute + pcount * info->countmultiplier * cl_particles_quality.value; + float cnt = info->countabsolute; + cnt += (pcount * info->countmultiplier) * cl_particles_quality.value; + cnt *= fade; + info->particleaccumulator += cnt; trailstep = 0; immediatebloodstain = ((cl_decals_newsystem_immediatebloodstain.integer >= 1) && (info->particletype == pt_blood)) @@ -1595,10 +1604,10 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins VectorMAM(0.5f, velocitymins, 0.5f, velocitymaxs, velocity); AnglesFromVectors(angles, velocity, NULL, false); - AngleVectors(angles, forward, right, up); - VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], traildir, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos); - VectorMAMAM(info->relativevelocityoffset[0], traildir, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity); } + AngleVectors(angles, forward, right, up); + VectorMAMAMAM(1.0f, trailpos, info->relativeoriginoffset[0], forward, info->relativeoriginoffset[1], right, info->relativeoriginoffset[2], up, trailpos); + VectorMAMAM(info->relativevelocityoffset[0], forward, info->relativevelocityoffset[1], right, info->relativevelocityoffset[2], up, velocity); info->particleaccumulator = bound(0, info->particleaccumulator, 16384); for (;info->particleaccumulator >= 1;info->particleaccumulator--) { @@ -1636,9 +1645,19 @@ void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins CL_ParticleEffect_Fallback(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles); } +void CL_ParticleTrail(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade) +{ + CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, true); +} + +void CL_ParticleBox(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade) +{ + CL_NewParticlesFromEffectinfo(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, spawndlight, spawnparticles, tintmins, tintmaxs, fade, false); +} + void CL_ParticleEffect(int effectnameindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor) { - CL_ParticleTrail(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL); + CL_ParticleBox(effectnameindex, pcount, originmins, originmaxs, velocitymins, velocitymaxs, ent, palettecolor, true, true, NULL, NULL, 1); } /* diff --git a/client.h b/client.h index 83b171cf..f830c2e7 100644 --- a/client.h +++ b/client.h @@ -1720,7 +1720,8 @@ effectnameindex_t; int CL_ParticleEffectIndexForName(const char *name); const char *CL_ParticleEffectNameForIndex(int i); void CL_ParticleEffect(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor); -void CL_ParticleTrail(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4]); +void CL_ParticleTrail(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade); +void CL_ParticleBox(int effectindex, float pcount, const vec3_t originmins, const vec3_t originmaxs, const vec3_t velocitymins, const vec3_t velocitymaxs, entity_t *ent, int palettecolor, qboolean spawndlight, qboolean spawnparticles, float tintmins[4], float tintmaxs[4], float fade); void CL_ParseParticleEffect (void); void CL_ParticleCube (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, vec_t gravity, vec_t randomvel); void CL_ParticleRain (const vec3_t mins, const vec3_t maxs, const vec3_t dir, int count, int colorbase, int type); diff --git a/clvm_cmds.c b/clvm_cmds.c index 6ca2749c..c0cad226 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -1364,10 +1364,13 @@ static void VM_CL_boxparticles (prvm_prog_t *prog) vec3_t origin_from, origin_to, dir_from, dir_to; float count; int flags; - float tintmins[4], tintmaxs[4]; + qboolean istrail; + float tintmins[4], tintmaxs[4], fade; VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles); effectnum = (int)PRVM_G_FLOAT(OFS_PARM0); + if (effectnum < 0) + return; // own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin_from); VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin_to ); @@ -1378,8 +1381,12 @@ static void VM_CL_boxparticles (prvm_prog_t *prog) flags = PRVM_G_FLOAT(OFS_PARM7); else flags = 0; + Vector4Set(tintmins, 1, 1, 1, 1); Vector4Set(tintmaxs, 1, 1, 1, 1); + fade = 1; + istrail = false; + if(flags & 1) // read alpha { tintmins[3] = PRVM_clientglobalfloat(particles_alphamin); @@ -1390,9 +1397,19 @@ static void VM_CL_boxparticles (prvm_prog_t *prog) VectorCopy(PRVM_clientglobalvector(particles_colormin), tintmins); VectorCopy(PRVM_clientglobalvector(particles_colormax), tintmaxs); } - if (effectnum < 0) - return; - CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs); + if(flags & 4) // read fade + { + fade = PRVM_clientglobalfloat(particles_fade); + } + if(flags & 128) // draw as trail + { + istrail = true; + } + + if (istrail) + CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade); + else + CL_ParticleBox(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade); } //#531 void(float pause) setpause diff --git a/prvm_offsets.h b/prvm_offsets.h index 440b3e45..c02bc07a 100644 --- a/prvm_offsets.h +++ b/prvm_offsets.h @@ -150,6 +150,7 @@ PRVM_DECLARE_clientglobalfloat(particle_type) PRVM_DECLARE_clientglobalfloat(particle_velocityjitter) PRVM_DECLARE_clientglobalfloat(particles_alphamax) PRVM_DECLARE_clientglobalfloat(particles_alphamin) +PRVM_DECLARE_clientglobalfloat(particles_fade) PRVM_DECLARE_clientglobalfloat(player_localentnum) PRVM_DECLARE_clientglobalfloat(player_localnum) PRVM_DECLARE_clientglobalfloat(require_spawnfunc_prefix) @@ -527,6 +528,7 @@ PRVM_DECLARE_global(particle_type) PRVM_DECLARE_global(particle_velocityjitter) PRVM_DECLARE_global(particles_alphamax) PRVM_DECLARE_global(particles_alphamin) +PRVM_DECLARE_global(particles_fade) PRVM_DECLARE_global(particles_colormax) PRVM_DECLARE_global(particles_colormin) PRVM_DECLARE_global(player_localentnum) -- 2.39.2