Пример #1
0
/*
 * R_AddSustainedLights
 */
static void R_AddSustainedLights(void) {
	r_sustained_light_t *s;
	int i;

	// sustains must be recalculated every frame
	for (i = 0, s = r_view.sustained_lights; i < MAX_LIGHTS; i++, s++) {

		if (s->sustain <= r_view.time) { // clear it
			s->sustain = 0.0;
			continue;
		}

		r_light_t l = s->light;

		const float intensity = (s->sustain - r_view.time) / (s->sustain
				- s->time);
		VectorScale(s->light.color, intensity, l.color);

		R_AddLight(&l);
	}
}
Пример #2
0
/**
 * @brief Updates state of sustained lights; should be called once per frame right before world rendering
 * @sa R_RenderFrame
 * @sa R_AddSustainedLight
 */
void R_UpdateSustainedLights (void)
{
	sustain_t *s;
	int i;

	/* sustains must be recalculated every frame */
	for (i = 0, s = r_sustainArray; i < MAX_GL_LIGHTS; i++, s++) {
		float intensity;
		vec3_t color;

		if (s->sustain <= refdef.time) {  /* clear it */
			s->sustain = 0;
			continue;
		}

		intensity = (s->sustain - refdef.time) / (s->sustain - s->time);
		VectorScale(s->light.color, intensity, color);

		R_AddLight(s->light.origin, s->light.radius, color);
	}
}
Пример #3
0
/**
 * @brief Prepares the particle rendering, calculate new position, velocity and all the
 * other particle values that are needed to display it
 * @sa CL_ParticleRun
 * @param[in,out] p The particle to handle
 */
static void CL_ParticleRun2 (ptl_t *p)
{
	/* advance time */
	p->dt = cls.frametime;
	p->t = (cl.time - p->startTime) * 0.001f;
	p->lastThink += p->dt;
	p->lastFrame += p->dt;

	if (p->rounds && !p->roundsCnt)
		p->roundsCnt = p->rounds;

	/* test for end of life */
	if (p->life && p->t >= p->life && !p->parent) {
		CL_ParticleFree(p);
		return;
	/* don't play the weather particles if a user don't want them there can
	 * be a lot of weather particles - which might slow the computer down */
	} else if (p->weather && !cl_particleweather->integer) {
		CL_ParticleFree(p);
		return;
	}

	/* kinematics */
	if (p->style != STYLE_LINE) {
		VectorMA(p->s, 0.5 * p->dt * p->dt, p->a, p->s);
		VectorMA(p->s, p->dt, p->v, p->s);
		VectorMA(p->v, p->dt, p->a, p->v);
		VectorMA(p->angles, p->dt, p->omega, p->angles);
	}

	/* basic 'physics' for particles */
	if (p->physics) {
		vec3_t mins, maxs;
		const float size = std::max(p->size[0], p->size[1]);

		if (p->hitSolid && p->bounce) {
			VectorCopy(p->oldV, p->v);
			VectorNegate(p->a, p->a);
			p->hitSolid = false;
		}

		/* if the particle hit a solid already and is sticking to the surface, no further
		 * traces are needed */
		if (p->hitSolid && p->stick)
			return;

		VectorSet(mins, -size, -size, -size);
		VectorSet(maxs, size, size, size);
		const trace_t tr = PTL_Trace(p, mins, maxs);

		/* hit something solid */
		if (tr.fraction < 1.0 || tr.startsolid) {

			p->hitSolid = true;

			/* now execute the physics handler */
			if (p->ctrl->physics)
				CL_ParticleFunction(p, p->ctrl->physics);
			/* let them stay on the ground until they fade out or die */
			if (!p->stayalive) {
				CL_ParticleFree(p);
				return;
			} else if (p->bounce) {
				/* bounce */
				vec3_t temp;
				VectorCopy(p->v, p->oldV);
				VectorScale(tr.plane.normal, -DotProduct(tr.plane.normal, p->v), temp);
				VectorAdd(temp, p->v, temp);
				VectorAdd(temp, temp, p->v);
				VectorNegate(p->a, p->a);
			} else {
				VectorClear(p->v);
			}
			VectorCopy(tr.endpos, p->s);
		}
	}

	/* run */
	CL_ParticleFunction(p, p->ctrl->run);

	/* think */
	while (p->tps && p->lastThink * p->tps >= 1) {
		CL_ParticleFunction(p, p->ctrl->think);
		p->lastThink -= 1.0 / p->tps;
	}

	/* animate */
	while (p->fps && p->lastFrame * p->fps >= 1) {
		/* advance frame */
		p->frame++;
		if (p->frame > p->endFrame)
			p->frame = 0;
		p->lastFrame -= 1.0 / p->fps;

		/* load next frame */
		assert(p->pic);
		p->pic = CL_ParticleGetArt(p->pic->name, p->frame, ART_PIC);
	}

	/* fading */
	if (p->thinkFade || p->frameFade) {
		const bool onlyAlpha = (p->blend == BLEND_BLEND);
		if (!onlyAlpha)
			Vector4Set(p->color, 1.0f, 1.0f, 1.0f, 1.0f);
		else
			p->color[3] = 1.0;

		if (p->thinkFade)
			CL_Fading(p->color, p->thinkFade, p->lastThink * p->tps, onlyAlpha);
		if (p->frameFade)
			CL_Fading(p->color, p->frameFade, p->lastFrame * p->fps, onlyAlpha);
	}

	/* this is useful for particles like weather effects that are on top of
	 * some other brushes in higher level but should be visible in lower ones */
	if (p->autohide) {
		const int z = (int)p->s[2] / UNIT_HEIGHT;
		if (z > cl_worldlevel->integer) {
			p->invis = true;
			return;
		} else if (z < 0) {
			CL_ParticleFree(p);
			return;
		}
	}

	/* add light to the scene */
	if (VectorNotEmpty(p->lightColor)) {
		const float intensity = 0.5 + p->lightIntensity;
		if (p->lightSustain)
			R_AddSustainedLight(p->s, intensity * PTL_INTENSITY_TO_RADIUS, p->lightColor, p->lightSustain);
		else
			R_AddLight(p->s, intensity * PTL_INTENSITY_TO_RADIUS, p->lightColor);
	}

	/* set the new origin */
	VectorCopy(p->s, p->origin);

	p->invis = false;
}