g = part->color[1];
b = part->color[2];
}
- part->staincolor = r * 65536 + g * 256 + b;
+ part->staincolor[0] = r;
+ part->staincolor[1] = g;
+ part->staincolor[2] = b;
part->stainalpha = palpha * stainalpha / 256;
part->stainsize = psize * stainsize;
part->texnum = ptex;
part->airfriction = pairfriction;
part->liquidfriction = pliquidfriction;
part->die = cl.time + lifetime;
- part->delayedcollisions = 0;
+// part->delayedcollisions = 0;
part->qualityreduction = pqualityreduction;
// if it is rain or snow, trace ahead and shut off collisions until an actual collision event needs to occur to improve performance
if (part->typeindex == pt_rain)
}
}
}
+#if 0
else if (part->bounce != 0 && part->gravity == 0 && part->typeindex != pt_snow)
{
float lifetime = part->alpha / (part->alphafade ? part->alphafade : 1);
trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, true, false, NULL, false);
part->delayedcollisions = cl.time + lifetime * trace.fraction - 0.1;
}
+#endif
return part;
}
VectorCopy(part->vel, v);
VectorNormalize(v);
staintex = part->staintexnum;
- R_DecalSystem_SplatEntities(part->org, v, 1-((part->staincolor>>16)&255)*(1.0f/255.0f), 1-((part->staincolor>>8)&255)*(1.0f/255.0f), 1-((part->staincolor)&255)*(1.0f/255.0f), part->stainalpha*(1.0f/255.0f), particletexture[staintex].s1, particletexture[staintex].t1, particletexture[staintex].s2, particletexture[staintex].t2, part->stainsize);
+ R_DecalSystem_SplatEntities(part->org, v, 1-part->staincolor[0]*(1.0f/255.0f), 1-part->staincolor[1]*(1.0f/255.0f), 1-part->staincolor[2]*(1.0f/255.0f), part->stainalpha*(1.0f/255.0f), particletexture[staintex].s1, particletexture[staintex].t1, particletexture[staintex].s2, particletexture[staintex].t2, part->stainsize);
}
// blood creates a splash at spawn, not just at impact, this makes monsters bloody where they are shot
tex = &particletexture[p->texnum];
switch(p->orientation)
{
- case PARTICLE_INVALID:
+// case PARTICLE_INVALID:
case PARTICLE_BILLBOARD:
VectorScale(r_refdef.view.left, -size * p->stretch, right);
VectorScale(r_refdef.view.up, size, up);
VectorCopy(p->org, oldorg);
VectorMA(p->org, frametime, p->vel, p->org);
- if (p->bounce && cl.time >= p->delayedcollisions)
+// if (p->bounce && cl.time >= p->delayedcollisions)
+ if (p->bounce)
{
trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), true, false, &hitent, false);
// if the trace started in or hit something of SUPERCONTENTS_NODROP
if (!(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS))
{
R_Stain(p->org, 16,
- (p->staincolor >> 16) & 0xFF, (p->staincolor >> 8) & 0xFF, p->staincolor & 0xFF, (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)),
- (p->staincolor >> 16) & 0xFF, (p->staincolor >> 8) & 0xFF, p->staincolor & 0xFF, (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)));
+ p->staincolor[0], p->staincolor[1], p->staincolor[2], (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)),
+ p->staincolor[0], p->staincolor[1], p->staincolor[2], (int)(p->stainalpha * p->stainsize * (1.0f / 160.0f)));
if (cl_decals.integer)
{
// create a decal for the blood splat
- CL_SpawnDecalParticleForSurface(hitent, p->org, trace.plane.normal, 0xFFFFFF ^ p->staincolor, 0xFFFFFF ^ p->staincolor, p->staintexnum, p->stainsize, p->stainalpha); // staincolor needs to be inverted for decals!
+ a = 0xFFFFFF ^ (p->staincolor[0]*65536+p->staincolor[1]*256+p->staincolor[2]);
+ CL_SpawnDecalParticleForSurface(hitent, p->org, trace.plane.normal, a, a, p->staintexnum, p->stainsize, p->stainalpha); // staincolor needs to be inverted for decals!
}
}
}
typedef struct particle_s
{
- // for faster batch rendering, particles are rendered in groups based on where they spawned
- vec3_t sortorigin;
- // fields used by rendering: (40 bytes)
+ // for faster batch rendering, particles are rendered in groups by effect (resulting in less perfect sorting but far less state changes)
+
+ // fields used by rendering: (48 bytes)
+ vec3_t sortorigin; // sort by this group origin, not particle org
+ vec3_t org;
+ vec3_t vel; // velocity of particle, or orientation of decal, or end point of beam
+ float size;
+ float alpha; // 0-255
+ float stretch; // only for sparks
+
+ // fields not used by rendering: (44 bytes)
+ float stainsize;
+ float stainalpha;
+ float sizeincrease; // rate of size change per second
+ float alphafade; // how much alpha reduces per second
+ float time2; // used for snow fluttering and decal fade
+ 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)
+ float gravity; // how much gravity affects this particle (1.0 = normal gravity, 0.0 = none)
+ float airfriction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction)
+ float liquidfriction; // how much liquid friction affects this object (objects with a low mass/size ratio tend to get more liquid friction)
+// float delayedcollisions; // time that p->bounce becomes active
+ float delayedspawn; // time that particle appears and begins moving
+ float die; // time when this particle should be removed, regardless of alpha
+
+ // byte variables grouped to save memory (12 bytes)
+ unsigned char color[3];
+ unsigned char qualityreduction; // enables skipping of this particle according to r_refdef.view.qualityreduction
unsigned char typeindex;
- pblend_t blendmode;
- porientation_t orientation;
+ unsigned char blendmode;
+ unsigned char orientation;
unsigned char texnum;
- vec3_t org;
- vec3_t vel; // velocity of particle, or orientation of decal, or end point of beam
- float size;
- float alpha; // 0-255
- unsigned char color[3];
- unsigned char qualityreduction; // enables skipping of this particle according to r_refdef.view.qualityreduction
- float stretch; // only for sparks
- int staincolor;
+ unsigned char staincolor[3];
signed char staintexnum;
- float stainsize;
- float stainalpha;
-
- // fields not used by rendering: (40 bytes)
- float sizeincrease; // rate of size change per second
- float alphafade; // how much alpha reduces per second
- float time2; // used for snow fluttering and decal fade
- 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)
- float gravity; // how much gravity affects this particle (1.0 = normal gravity, 0.0 = none)
- float airfriction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction)
- float liquidfriction; // how much liquid friction affects this object (objects with a low mass/size ratio tend to get more liquid friction)
- float delayedcollisions; // time that p->bounce becomes active
- float delayedspawn; // time that particle appears and begins moving
- float die; // time when this particle should be removed, regardless of alpha
}
particle_t;
}
if (*vmpartspawner.particle_delayspawn)
part->delayedspawn = cl.time + *vmpartspawner.particle_delayspawn;
- if (*vmpartspawner.particle_delaycollision)
- part->delayedcollisions = cl.time + *vmpartspawner.particle_delaycollision;
+ //if (*vmpartspawner.particle_delaycollision)
+ // part->delayedcollisions = cl.time + *vmpartspawner.particle_delaycollision;
}
else // quick themed particle
{
}
if (theme->delayspawn)
part->delayedspawn = cl.time + theme->delayspawn;
- if (theme->delaycollision)
- part->delayedcollisions = cl.time + theme->delaycollision;
+ //if (theme->delaycollision)
+ // part->delayedcollisions = cl.time + theme->delaycollision;
}
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
return;
}
part->delayedspawn = cl.time + PRVM_G_FLOAT(OFS_PARM2);
- part->delayedcollisions = cl.time + PRVM_G_FLOAT(OFS_PARM3);
+ //part->delayedcollisions = cl.time + PRVM_G_FLOAT(OFS_PARM3);
PRVM_G_FLOAT(OFS_RETURN) = 0;
}