From f07007f8ad08d0edf3c14d9c27ab9132ec347e7f Mon Sep 17 00:00:00 2001 From: Kevin Shanahan Date: Fri, 1 Mar 2013 11:49:46 +1030 Subject: [PATCH] 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 --- include/light/entities.h | 14 ++++++++------ light/entities.c | 29 ++++++++++++++++++++++++++--- light/ltface.c | 26 +++----------------------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/include/light/entities.h b/include/light/entities.h index 7009d609..69ad2626 100644 --- a/include/light/entities.h +++ b/include/light/entities.h @@ -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; diff --git a/light/entities.c b/light/entities.c index 0c9ad511..66e21897 100644 --- a/light/entities.c +++ b/light/entities.c @@ -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 * diff --git a/light/ltface.c b/light/ltface.c index 4f55fdee..1ac58276 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -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);