Ejemplo n.º 1
0
void CL_DrawParticles( void )
{
	particle_t	*p, *kill;
	float		frametime;
	static int	framecount = -1;

	if( !cl_draw_particles->integer )
		return;

	// HACKHACK: don't evaluate particles when executes many times at same frame
	// e.g. mirror rendering
	if( framecount != tr.realframecount )
	{
		frametime = cl.time - cl.oldtime;
		framecount = tr.realframecount;
	}
	else frametime = 0.0f;

	if( tracerred->modified || tracergreen->modified || tracerblue->modified )
	{
		gTracerColors[4][0] = (byte)(tracerred->value * 255);
		gTracerColors[4][1] = (byte)(tracergreen->value * 255);
		gTracerColors[4][2] = (byte)(tracerblue->value * 255);
		tracerred->modified = tracergreen->modified = tracerblue->modified = false;
	}

	while( 1 ) 
	{
		// free time-expired particles
		kill = cl_active_particles;
		if( kill && kill->die < cl.time )
		{
			cl_active_particles = kill->next;
			CL_FreeParticle( kill );
			continue;
		}
		break;
	}

	for( p = cl_active_particles; p; p = p->next )
	{
		while( 1 )
		{
			kill = p->next;
			if( kill && kill->die < cl.time )
			{
				p->next = kill->next;
				CL_FreeParticle( kill );
				continue;
			}
			break;
		}

		CL_UpdateParticle( p, frametime );
	}
}
Ejemplo n.º 2
0
/*
===============
CL_AddParticles
===============
*/
void CL_AddParticles (void)
{
	cparticle_t		*p, *next;
	float			alpha;
	float			time, time2;
	vec3_t			org;
	int				color;
	cparticle_t		*active, *tail;
	int             contents;
	float			grav;

	active = NULL;
	tail = NULL;

	if (!cl_drawParticles->integer)
		return;

	// allow gravity tweaks by the server
	grav = Cvar_VariableValue("sv_gravity");
	if (!grav)
		grav = 1;
	else
		grav /= 800;

	for (p = active_particles; p; p = next)
	{
		next = p->next;

		// set alpha
		// PMM - added INSTANT_PARTICLE handling
		if (p->alphavel != INSTANT_PARTICLE)
		{
			time = (cl.time - p->time) * 0.001;
			alpha = p->alpha + time * p->alphavel;

			if (alpha <= 0)
			{
				// faded out
				CL_FreeParticle (p);
				continue;
			}
			else if (alpha <= 0.3f && p->color == 240) // this is HACK central...
			{
				// do blood decals
				if (rand() & 4)
				{
					trace_t tr;

					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;

					tr = CL_Trace(p->org, org, 0, MASK_SOLID);
					if (tr.fraction != 1.0f)
					{
						if (!VectorCompare(tr.plane.normal, vec3_origin) && !(CM_PointContents(p->org, 0) & MASK_WATER)) // no blood splatters underwater...
						{
							vec4_t color;
							Vector4Set(color, 1.0, 0.0, 0.0, 1.0f);
							RE_AddDecal(tr.endpos, tr.plane.normal, color, 16 + ((rand() % 21 * 0.05f) - 0.5f), DECAL_BLOOD + (rand() & 4), 0, frand() * 360);
						}
					}
				}
			}
		}
		else
		{
			alpha = p->alpha;
		}

		if (alpha > 1.0)
			alpha = 1;

		// set color
		color = p->color;

		// backup old position
		VectorCopy (p->org, p->oldOrg);

		// calculate new position
		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;

		// gravity modulation
		//if (!p->ignoreGrav)
		//	org[2] += time2 * -PARTICLE_GRAVITY;

		// collision test
		if (cl_particleCollision->integer)
		{
			if (p->bounceFactor)
			{
				trace_t trace;
				vec3_t vel;
				int hitTime;
				float time;

				trace = CL_Trace(p->oldOrg, org, 0, CONTENTS_SOLID);
				if (trace.fraction > 0 && trace.fraction < 1)
				{
					// reflect the velocity on the trace plane
					hitTime = cl.time - cls.rframetime + cls.rframetime * trace.fraction;

					time = ((float)hitTime - p->time) * 0.001;

					Vector3Set (vel, p->vel[0], p->vel[1], p->vel[2] + p->accel[2] * time * grav);
					VectorReflect (vel, trace.plane.normal, p->vel);
					VectorScale (p->vel, p->bounceFactor, p->vel);

					// check for stop, making sure that even on low FPS systems it doesn't bobble
					if (trace.allsolid || (trace.plane.normal[2] > 0 && (p->vel[2] < 40 || p->vel[2] < -cls.rframetime * p->vel[2])))
					{
						VectorClear(p->vel);
						VectorClear(p->accel);

						p->bounceFactor = 0.0f;
					}

					VectorCopy (trace.endpos, org);

					// reset particle
					p->time = cl.time;

					VectorCopy (org, p->org);
				}
			}
		}

		// kill all particles in solid
		contents = CM_PointContents (org, 0);
		if (contents & MASK_SOLID)
		{
			CL_FreeParticle (p);
			continue;
		}

		// have this always below CL_FreeParticle(p); !
		p->next = NULL;
		if (!tail)
		{
			active = tail = p;
		}
		else
		{
			tail->next = p;
			tail = p;
		}

		// add to scene
		V_AddParticle (org, color, alpha);

		// PMM
		if (p->alphavel == INSTANT_PARTICLE)
		{
			p->alphavel = 0.0;
			p->alpha = 0.0;
		}
	}

	active_particles = active;
}