light: setup spotlight paramters once at load time

We were calculating these values for every light and for every surface,
which seems a little excessive... Also made the variable names a bit more
sensible - we had stored a direction vector, not the actual mangle values.

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-03-01 11:49:46 +10:30
parent 580b2912fb
commit f07007f8ad
3 changed files with 37 additions and 32 deletions

View File

@ -51,16 +51,18 @@ typedef enum {
typedef struct entity_s {
char classname[MAX_ENT_VALUE];
vec3_t origin;
float angle;
light_formula_t formula;
qboolean spotlight;
vec3_t spotvec;
float spotangle;
float spotfalloff;
int style;
int light;
float atten;
vec3_t mangle;
qboolean use_mangle;
light_formula_t formula;
vec3_t lightcolor;
int light;
int style;
char target[MAX_ENT_VALUE];
char targetname[MAX_ENT_VALUE];
struct epair_s *epairs;

View File

@ -110,6 +110,28 @@ MatchTargets(void)
}
}
static void
SetupSpotlights(void)
{
int i;
entity_t *entity;
for (i = 0, entity = entities; i < num_entities; i++, entity++) {
if (strncmp(entity->classname, "light", 5))
continue;
if (entity->targetent) {
VectorSubtract(entity->targetent->origin, entity->origin,
entity->spotvec);
VectorNormalize(entity->spotvec);
entity->spotlight = true;
}
if (entity->spotlight) {
vec_t angle = entity->spotangle ? entity->spotangle : 40;
entity->spotfalloff = -cos(angle / 2 * Q_PI / 180);
}
}
}
/* helper function */
static void
scan_vec3(vec3_t dest, const char *buf, const char *name)
@ -249,15 +271,15 @@ LoadEntities(void)
Error("Bad light style %i (must be 0-254)",
entity->style);
} else if (!strcmp(key, "angle"))
entity->angle = atof(com_token);
entity->spotangle = atof(com_token);
else if (!strcmp(key, "wait"))
entity->atten = atof(com_token);
else if (!strcmp(key, "delay"))
entity->formula = atoi(com_token);
else if (!strcmp(key, "mangle")) {
scan_vec3(vec, com_token, "mangle");
vec_from_mangle(entity->mangle, vec);
entity->use_mangle = true;
vec_from_mangle(entity->spotvec, vec);
entity->spotlight = true;
} else if (!strcmp(key, "_color") || !strcmp(key, "color"))
scan_vec3(entity->lightcolor, com_token, "color");
else if (!strcmp(key, "_sunlight"))
@ -311,6 +333,7 @@ LoadEntities(void)
logprint("%d entities read, %d are lights.\n", num_entities, num_lights);
MatchTargets();
SetupSpotlights();
}
const char *

View File

@ -517,8 +517,6 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
int mapnum;
int c;
vec3_t rel;
vec3_t spotvec;
vec_t falloff;
vec_t *lightsamp;
vec3_t *colorsamp;
vec_t newlightmap[SINGLEMAP];
@ -538,23 +536,6 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
return;
}
if (light->targetent) {
VectorSubtract(light->targetent->origin, light->origin, spotvec);
VectorNormalize(spotvec);
if (!light->angle)
falloff = -cos(20 * Q_PI / 180);
else
falloff = -cos(light->angle / 2 * Q_PI / 180);
} else if (light->use_mangle) {
VectorCopy(light->mangle, spotvec);
if (!light->angle)
falloff = -cos(20 * Q_PI / 180);
else
falloff = -cos(light->angle / 2 * Q_PI / 180);
} else {
falloff = 0; /* shut up compiler warnings */
}
/*
* Find the lightmap with matching style
*/
@ -590,11 +571,10 @@ SingleLightFace(const entity_t *light, lightinfo_t * l,
VectorSubtract(light->origin, surf, incoming);
VectorNormalize(incoming);
angle = DotProduct(incoming, l->facenormal);
if (light->targetent || light->use_mangle) {
if (light->spotlight &&
DotProduct(light->spotvec, incoming) > light->spotfalloff)
/* spotlight cutoff */
if (DotProduct(spotvec, incoming) > falloff)
continue;
}
continue;
angle = (1.0 - scalecos) + scalecos * angle;
add = scaledLight(CastRay(light->origin, surf), light);