📄 cg_particles.c
字号:
verts[3].modulate[1] = 255 * color[1];
verts[3].modulate[2] = 255 * color[2];
verts[3].modulate[3] = 255;
}
else if (p->type == P_FLAT)
{
VectorCopy (org, verts[0].xyz);
verts[0].xyz[0] -= p->height;
verts[0].xyz[1] -= p->width;
verts[0].st[0] = 0;
verts[0].st[1] = 0;
verts[0].modulate[0] = 255;
verts[0].modulate[1] = 255;
verts[0].modulate[2] = 255;
verts[0].modulate[3] = 255;
VectorCopy (org, verts[1].xyz);
verts[1].xyz[0] -= p->height;
verts[1].xyz[1] += p->width;
verts[1].st[0] = 0;
verts[1].st[1] = 1;
verts[1].modulate[0] = 255;
verts[1].modulate[1] = 255;
verts[1].modulate[2] = 255;
verts[1].modulate[3] = 255;
VectorCopy (org, verts[2].xyz);
verts[2].xyz[0] += p->height;
verts[2].xyz[1] += p->width;
verts[2].st[0] = 1;
verts[2].st[1] = 1;
verts[2].modulate[0] = 255;
verts[2].modulate[1] = 255;
verts[2].modulate[2] = 255;
verts[2].modulate[3] = 255;
VectorCopy (org, verts[3].xyz);
verts[3].xyz[0] += p->height;
verts[3].xyz[1] -= p->width;
verts[3].st[0] = 1;
verts[3].st[1] = 0;
verts[3].modulate[0] = 255;
verts[3].modulate[1] = 255;
verts[3].modulate[2] = 255;
verts[3].modulate[3] = 255;
}
// Ridah
else if (p->type == P_ANIM) {
vec3_t rr, ru;
vec3_t rotate_ang;
int i, j;
time = cg.time - p->time;
time2 = p->endtime - p->time;
ratio = time / time2;
if (ratio >= 1.0f) {
ratio = 0.9999f;
}
width = p->width + ( ratio * ( p->endwidth - p->width) );
height = p->height + ( ratio * ( p->endheight - p->height) );
// if we are "inside" this sprite, don't draw
if (Distance( cg.snap->ps.origin, org ) < width/1.5) {
return;
}
i = p->shaderAnim;
j = (int)floor(ratio * shaderAnimCounts[p->shaderAnim]);
p->pshader = shaderAnims[i][j];
if (p->roll) {
vectoangles( cg.refdef.viewaxis[0], rotate_ang );
rotate_ang[ROLL] += p->roll;
AngleVectors ( rotate_ang, NULL, rr, ru);
}
if (p->roll) {
VectorMA (org, -height, ru, point);
VectorMA (point, -width, rr, point);
} else {
VectorMA (org, -height, vup, point);
VectorMA (point, -width, vright, point);
}
VectorCopy (point, verts[0].xyz);
verts[0].st[0] = 0;
verts[0].st[1] = 0;
verts[0].modulate[0] = 255;
verts[0].modulate[1] = 255;
verts[0].modulate[2] = 255;
verts[0].modulate[3] = 255;
if (p->roll) {
VectorMA (point, 2*height, ru, point);
} else {
VectorMA (point, 2*height, vup, point);
}
VectorCopy (point, verts[1].xyz);
verts[1].st[0] = 0;
verts[1].st[1] = 1;
verts[1].modulate[0] = 255;
verts[1].modulate[1] = 255;
verts[1].modulate[2] = 255;
verts[1].modulate[3] = 255;
if (p->roll) {
VectorMA (point, 2*width, rr, point);
} else {
VectorMA (point, 2*width, vright, point);
}
VectorCopy (point, verts[2].xyz);
verts[2].st[0] = 1;
verts[2].st[1] = 1;
verts[2].modulate[0] = 255;
verts[2].modulate[1] = 255;
verts[2].modulate[2] = 255;
verts[2].modulate[3] = 255;
if (p->roll) {
VectorMA (point, -2*height, ru, point);
} else {
VectorMA (point, -2*height, vup, point);
}
VectorCopy (point, verts[3].xyz);
verts[3].st[0] = 1;
verts[3].st[1] = 0;
verts[3].modulate[0] = 255;
verts[3].modulate[1] = 255;
verts[3].modulate[2] = 255;
verts[3].modulate[3] = 255;
}
// done.
if (!p->pshader) {
// (SA) temp commented out for DM
// CG_Printf ("CG_AddParticleToScene type %d p->pshader == ZERO\n", p->type);
return;
}
if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY)
trap_R_AddPolyToScene( p->pshader, 3, TRIverts );
else
trap_R_AddPolyToScene( p->pshader, 4, verts );
}
// Ridah, made this static so it doesn't interfere with other files
static float roll = 0.0;
/*
===============
CG_AddParticles
===============
*/
void CG_AddParticles (void)
{
cparticle_t *p, *next;
float alpha;
float time, time2;
vec3_t org;
int color;
cparticle_t *active, *tail;
int type;
vec3_t rotate_ang;
if (!initparticles)
CG_ClearParticles ();
VectorCopy( cg.refdef.viewaxis[0], vforward );
VectorCopy( cg.refdef.viewaxis[1], vright );
VectorCopy( cg.refdef.viewaxis[2], vup );
vectoangles( cg.refdef.viewaxis[0], rotate_ang );
roll += ((cg.time - oldtime) * 0.1) ;
rotate_ang[ROLL] += (roll*0.9);
AngleVectors ( rotate_ang, rforward, rright, rup);
oldtime = cg.time;
active = NULL;
tail = NULL;
for (p=active_particles ; p ; p=next)
{
next = p->next;
time = (cg.time - p->time)*0.001;
alpha = p->alpha + time*p->alphavel;
if (alpha <= 0)
{ // faded out
p->next = free_particles;
free_particles = p;
p->type = 0;
p->color = 0;
p->alpha = 0;
continue;
}
if (p->type == P_SMOKE || p->type == P_ANIM || p->type == P_BLEED || p->type == P_SMOKE_IMPACT)
{
if (cg.time > p->endtime)
{
p->next = free_particles;
free_particles = p;
p->type = 0;
p->color = 0;
p->alpha = 0;
continue;
}
}
if (p->type == P_WEATHER_FLURRY)
{
if (cg.time > p->endtime)
{
p->next = free_particles;
free_particles = p;
p->type = 0;
p->color = 0;
p->alpha = 0;
continue;
}
}
if (p->type == P_FLAT_SCALEUP_FADE)
{
if (cg.time > p->endtime)
{
p->next = free_particles;
free_particles = p;
p->type = 0;
p->color = 0;
p->alpha = 0;
continue;
}
}
if ((p->type == P_BAT || p->type == P_SPRITE) && p->endtime < 0) {
// temporary sprite
CG_AddParticleToScene (p, p->org, alpha);
p->next = free_particles;
free_particles = p;
p->type = 0;
p->color = 0;
p->alpha = 0;
continue;
}
p->next = NULL;
if (!tail)
active = tail = p;
else
{
tail->next = p;
tail = p;
}
if (alpha > 1.0)
alpha = 1;
color = p->color;
time2 = time*time;
org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
type = p->type;
CG_AddParticleToScene (p, org, alpha);
}
active_particles = active;
}
/*
======================
CG_AddParticles
======================
*/
void CG_ParticleSnowFlurry (qhandle_t pshader, centity_t *cent)
{
cparticle_t *p;
qboolean turb = qtrue;
if (!pshader)
CG_Printf ("CG_ParticleSnowFlurry pshader == ZERO!\n");
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->color = 0;
p->alpha = 0.90f;
p->alphavel = 0;
p->start = cent->currentState.origin2[0];
p->end = cent->currentState.origin2[1];
p->endtime = cg.time + cent->currentState.time;
p->startfade = cg.time + cent->currentState.time2;
p->pshader = pshader;
if (rand()%100 > 90)
{
p->height = 32;
p->width = 32;
p->alpha = 0.10f;
}
else
{
p->height = 1;
p->width = 1;
}
p->vel[2] = -20;
p->type = P_WEATHER_FLURRY;
if (turb)
p->vel[2] = -10;
VectorCopy(cent->currentState.origin, p->org);
p->org[0] = p->org[0];
p->org[1] = p->org[1];
p->org[2] = p->org[2];
p->vel[0] = p->vel[1] = 0;
p->accel[0] = p->accel[1] = p->accel[2] = 0;
p->vel[0] += cent->currentState.angles[0] * 32 + (crandom() * 16);
p->vel[1] += cent->currentState.angles[1] * 32 + (crandom() * 16);
p->vel[2] += cent->currentState.angles[2];
if (turb)
{
p->accel[0] = crandom () * 16;
p->accel[1] = crandom () * 16;
}
}
void CG_ParticleSnow (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum)
{
cparticle_t *p;
if (!pshader)
CG_Printf ("CG_ParticleSnow pshader == ZERO!\n");
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->color = 0;
p->alpha = 0.40f;
p->alphavel = 0;
p->start = origin[2];
p->end = origin2[2];
p->pshader = pshader;
p->height = 1;
p->width = 1;
p->vel[2] = -50;
if (turb)
{
p->type = P_WEATHER_TURBULENT;
p->vel[2] = -50 * 1.3;
}
else
{
p->type = P_WEATHER;
}
VectorCopy(origin, p->org);
p->org[0] = p->org[0] + ( crandom() * range);
p->org[1] = p->org[1] + ( crandom() * range);
p->org[2] = p->org[2] + ( crandom() * (p->start - p->end));
p->vel[0] = p->vel[1] = 0;
p->accel[0] = p->accel[1] = p->accel[2] = 0;
if (turb)
{
p->vel[0] = crandom() * 16;
p->vel[1] = crandom() * 16;
}
// Rafael snow pvs check
p->snum = snum;
p->link = qtrue;
}
void CG_ParticleBubble (qhandle_t pshader, vec3_t origin, vec3_t origin2, int turb, float range, int snum)
{
cparticle_t *p;
float randsize;
if (!pshader)
CG_Printf ("CG_ParticleSnow pshader == ZERO!\n");
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->color = 0;
p->alpha = 0.40f;
p->alphavel = 0;
p->start = origin[2];
p->end = origin2[2];
p->pshader = pshader;
randsize = 1 + (crandom() * 0.5);
p->height = randsize;
p->width = randsize;
p->vel[2] = 50 + ( crandom() * 10 );
if (turb)
{
p->type = P_BUBBLE_TURBULENT;
p->vel[2] = 50 * 1.3;
}
else
{
p->type = P_BUBBLE;
}
VectorCopy(origin, p->org);
p->org[0] = p->org[0] + ( crandom() * range);
p->org[1] = p->org[1] + ( crandom() * range);
p->org[2] = p->org[2] + ( crandom() * (p->start - p->end));
p->vel[0] = p->vel[1] = 0;
p->accel[0] = p->accel[1] = p->accel[2] = 0;
if (turb)
{
p->vel[0] = crandom() * 4;
p->vel[1] = crandom() * 4;
}
// Rafael snow pvs check
p->snum = snum;
p->link = qtrue;
}
void CG_ParticleSmoke (qhandle_t pshader, centity_t *cent)
{
// using cent->density = enttime
// cent->frame = startfade
cparticle_t *p;
if (!pshader)
CG_Printf ("CG_ParticleSmoke == ZERO!\n");
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->endtime = cg.time + cent->currentState.time;
p->startfade = cg.time + cent->currentState.time2;
p->color = 0;
p->alpha = 1.0;
p->alphavel = 0;
p->start = cent->currentState.origin[2];
p->end = cent->currentState.origin2[2];
p->pshader = pshader;
p->rotate = qfalse;
p->height = 8;
p->width = 8;
p->endheight = 32;
p->endwidth = 32;
p->type = P_SMOKE;
VectorCopy(cent->currentState.origin, p->org);
p->vel[0] = p->vel[1] = 0;
p->accel[0] = p->accel[1] = p->accel[2] = 0;
p->vel[2] = 5;
if (cent->currentState.frame == 1)// reverse gravity
p->vel[2] *= -1;
p->roll = 8 + (crandom() * 4);
}
void CG_ParticleBulletDebris (vec3_t org, vec3_t vel, int duration)
{
cparticle_t *p;
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->endtime = cg.time + duration;
p->startfade = cg.time + duration/2;
p->color = EMISIVEFADE;
p->alpha = 1.0;
p->alphavel = 0;
p->height = 0.5;
p->width = 0.5;
p->endheight = 0.5;
p->endwidth = 0.5;
p->pshader = cgs.media.tracerShader;
p->type = P_SMOKE;
VectorCopy(org, p->org);
p->vel[0] = vel[0];
p->vel[1] = vel[1];
p->vel[2] = vel[2];
p->accel[0] = p->accel[1] = p->accel[2] = 0;
p->accel[2] = -60;
p->vel[2] += -20;
}
/*
======================
CG_ParticleExplosion
======================
*/
void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duration, int sizeStart, int sizeEnd)
{
cparticle_t *p;
int anim;
if (animStr < (char *)10)
CG_Error( "CG_ParticleExplosion: animStr is probably an index rather than a string" );
// find the animation string
for (anim=0; shaderAnimNames[anim]; anim++) {
if (!stricmp( animStr, shaderAnimNames[anim] ))
break;
}
if (!shaderAnimNames[anim]) {
CG_Error("CG_ParticleExplosion: unknown animation string: %s\n", animStr);
return;
}
if (!free_particles)
return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cg.time;
p->alpha = 1.0;
p->alphavel = 0;
if (duration < 0) {
duration *= -1;
p->roll = 0;
} else {
p->roll = crandom()*179;
}
p->shaderAnim = anim;
p->width = sizeStart;
p->height = sizeStart*shaderAnimSTRatio[anim]; // for sprites that are stretch in either direction
p->endheight = sizeEnd;
p->endwidth = sizeEnd*shaderAnimSTRatio[anim];
p->endtime = cg.time + duration;
p->type = P_ANIM;
VectorCopy( origin, p->org );
VectorCopy( vel, p->vel );
VectorClear( p->accel );
}
// Rafael Shrapnel
void CG_AddParticleShrapnel (localEntity_t *le)
{
return;
}
// done.
int CG_NewParticleArea (int num)
{
// const char *str;
char *str;
char *token;
int type;
vec3_t origin, origin2;
int i;
float range = 0;
int turb;
int numparticles;
int snum;
str = (char *) CG_ConfigString (num);
if (!str[0])
return (0);
// returns type 128 64 or 32
token = COM_Parse (&str);
type = atoi (token);
if (type == 1)
range = 128;
else if (type == 2)
range = 64;
else if (type == 3)
range = 32;
else if (type == 0)
range = 256;
else if (type == 4)
range = 8;
else if (type == 5)
range = 16;
else if (type == 6)
range = 32;
else if (type == 7)
range = 64;
for (i=0; i<3; i++)
{
token = COM_Parse (&str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -