light: implement the _softangle key for spotlights

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-03-03 21:37:21 +10:30
parent fec6d64bf1
commit 4063d8aade
5 changed files with 31 additions and 6 deletions

View File

@ -9,6 +9,7 @@
* light: lit files now automatically generated when coloured lights detected
* light: implemented 4x4 oversampling with -extra4 command line
* light: implemented the -gate option to help speed processing (default 0.001)
* light: implemented the "_softangle" key for spotlights
2013-02-25 TyrUtils v0.5

View File

@ -56,6 +56,8 @@ typedef struct entity_s {
vec3_t spotvec;
float spotangle;
float spotfalloff;
float spotangle2;
float spotfalloff2;
int style;
int light;

View File

@ -135,6 +135,13 @@ ENTITY PARAMETERS
Specifies the angle in degrees for a spotlight cone. Default 40.
"_softangle" "n"
Specifies the angle in degrees for an inner spotlight cone (must be
less than the "angle" cone. Creates a softer transition between the
full brightness of the inner cone to the edge of the outer cone.
Default 0 (disabled).
"targetname" "name"
Turns the light into a switchable light, toggled by another entity

View File

@ -126,8 +126,15 @@ SetupSpotlights(void)
entity->spotlight = true;
}
if (entity->spotlight) {
vec_t angle = entity->spotangle ? entity->spotangle : 40;
vec_t angle, angle2;
angle = (entity->spotangle > 0) ? entity->spotangle : 40;
entity->spotfalloff = -cos(angle / 2 * Q_PI / 180);
angle2 = entity->spotangle2;
if (angle2 <= 0 || angle2 > angle)
angle2 = angle;
entity->spotfalloff2 = -cos(angle2 / 2 * Q_PI / 180);
}
}
}
@ -302,11 +309,12 @@ LoadEntities(void)
entity->light = atof(com_token);
else if (!strcmp(key, "style")) {
entity->style = atof(com_token);
if ((unsigned)entity->style > 254)
Error("Bad light style %i (must be 0-254)",
entity->style);
if (entity->style < 0 || entity->style > 254)
Error("Bad light style %i (must be 0-254)", entity->style);
} else if (!strcmp(key, "angle"))
entity->spotangle = atof(com_token);
else if (!strcmp(key, "_softangle"))
entity->spotangle2 = atof(com_token);
else if (!strcmp(key, "wait"))
entity->atten = atof(com_token);
else if (!strcmp(key, "delay"))

View File

@ -477,7 +477,7 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
const vec3_t faceoffset, const vec3_t colors)
{
vec_t dist;
vec_t angle;
vec_t angle, spotscale;
vec_t add;
const vec_t *surf;
qboolean newmap, hit;
@ -540,10 +540,17 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
/* Check spotlight cone */
VectorScale(ray, 1.0 / dist, ray);
angle = DotProduct(ray, l->facenormal);
spotscale = 1;
if (light->spotlight) {
vec_t falloff = DotProduct(light->spotvec, ray);
if (falloff > light->spotfalloff)
continue;
if (falloff > light->spotfalloff2) {
/* Interpolate between the two spotlight falloffs */
spotscale = falloff - light->spotfalloff2;
spotscale /= light->spotfalloff - light->spotfalloff2;
spotscale = 1.0 - spotscale;
}
}
/* Test for line of sight */
@ -551,7 +558,7 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
continue;
angle = (1.0 - scalecos) + scalecos * angle;
add = GetLightValue(light, dist) * angle;
add = GetLightValue(light, dist) * angle * spotscale;
lightsamp[c] += add;
if (colored)
VectorMA(colorsamp[c], add / 255, colors, colorsamp[c]);