/* * 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); } }
/** * @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); } }
/** * @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; }