diff --git a/changelog.txt b/changelog.txt index 3bec68a5..701bb7fc 100644 --- a/changelog.txt +++ b/changelog.txt @@ -14,6 +14,7 @@ * 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 +* light: implemented minlighting for brush models 2013-02-25 TyrUtils v0.5 diff --git a/include/light/light.h b/include/light/light.h index 7c0d2d47..a6315c2f 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -38,7 +38,13 @@ void LoadNodes(char *file); qboolean TestLine(const vec3_t start, const vec3_t stop); qboolean TestSky(const vec3_t start, const vec3_t dirn); -void LightFace(int surfnum, const vec3_t faceoffset); +typedef struct { + int minlight; + vec3_t mincolor; + vec3_t offset; +} modelinfo_t; + +void LightFace(int surfnum, const modelinfo_t *modelinfo); void LightLeaf(dleaf_t * leaf); void MakeTnodes(void); diff --git a/light.txt b/light.txt index ea1beaaf..e9291e6f 100644 --- a/light.txt +++ b/light.txt @@ -82,6 +82,19 @@ ENTITY PARAMETERS sunlight. RGB component values are between -255 and 255. Negative values will cause colour subtraction from light cast by other entities. + MODEL PARAMETERS + + The following parameters can be used on any entity with a brush model. + + "_minlight" "n" + + Set the minimum light level for any surface of the brush model. + + "_mincolor" "r g b" + + Specify red(r), green(g) and blue(b) components for the colour of the + minlight. RGB component values are between 0 and 255. + LIGHT PARAMETERS Light parameters can be used in any entity with a classname starting diff --git a/light/light.c b/light/light.c index 6457bf48..312bd0e3 100644 --- a/light/light.c +++ b/light/light.c @@ -39,7 +39,7 @@ byte *lit_filebase; // start of litfile data static byte *lit_file_p; // start of free space after litfile data static byte *lit_file_end; // end of space for litfile data -static vec3_t *modeloffset; +static modelinfo_t *modelinfo; int oversample = 1; qboolean compress_ents; @@ -94,21 +94,21 @@ LightThread(void *junk) if (i == nummodels) Error("%s: no model has face %d", __func__, facenum); - LightFace(facenum, modeloffset[i]); + LightFace(facenum, &modelinfo[i]); } return NULL; } static void -FindModelOffsets(void) +FindModelInfo(void) { int i; entity_t *entity; char modelname[20]; - const char *classname; + const char *attribute; - memset(modeloffset, 0, sizeof(*modeloffset) * nummodels); + memset(modelinfo, 0, sizeof(*modelinfo) * nummodels); for (i = 1; i < nummodels; i++) { snprintf(modelname, sizeof(modelname), "*%d", i); entity = FindEntityWithKeyPair("model", modelname); @@ -116,9 +116,25 @@ FindModelOffsets(void) Error("%s: Couldn't find entity for model %s.\n", __func__, modelname); - classname = ValueForKey(entity, "classname"); - if (!strncmp(classname, "rotate_", 7)) - GetVectorForKey(entity, "origin", modeloffset[i]); + /* Set up the offset for rotate_* entities */ + attribute = ValueForKey(entity, "classname"); + if (!strncmp(attribute, "rotate_", 7)) + GetVectorForKey(entity, "origin", modelinfo[i].offset); + + /* Grab the bmodel minlight values, if any */ + attribute = ValueForKey(entity, "_minlight"); + if (attribute[0]) + modelinfo[i].minlight = atoi(attribute); + GetVectorForKey(entity, "_mincolor", modelinfo[i].mincolor); + if (!VectorCompare(modelinfo[i].mincolor, vec3_origin)) { + if (!colored) { + colored = true; + logprint("Colored light entities detected: " + ".lit output enabled.\n"); + } + } else { + VectorCopy(vec3_white, modelinfo[i].mincolor); + } } } @@ -239,10 +255,10 @@ main(int argc, const char **argv) LoadEntities(); MakeTnodes(); - modeloffset = malloc(nummodels * sizeof(*modeloffset)); - FindModelOffsets(); + modelinfo = malloc(nummodels * sizeof(*modelinfo)); + FindModelInfo(); LightWorld(); - free(modeloffset); + free(modelinfo); WriteEntitiesToString(); WriteBSPFile(source, bsp_version); diff --git a/light/ltface.c b/light/ltface.c index 2c767619..2f1e56ff 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -825,7 +825,7 @@ NegativeColors(int light, vec3_t dest, const vec3_t src) * ============ */ void -LightFace(int surfnum, const vec3_t faceoffset) +LightFace(int surfnum, const modelinfo_t *modelinfo) { const entity_t *entity; dface_t *face; @@ -864,7 +864,7 @@ LightFace(int surfnum, const vec3_t faceoffset) VectorCopy(dplanes[face->planenum].normal, l.facenormal); l.facedist = dplanes[face->planenum].dist; VectorScale(l.facenormal, l.facedist, point); - VectorAdd(point, faceoffset, point); + VectorAdd(point, modelinfo->offset, point); l.facedist = DotProduct(point, l.facenormal); if (face->side) { @@ -873,7 +873,7 @@ LightFace(int surfnum, const vec3_t faceoffset) } CalcFaceVectors(&l); - CalcFaceExtents(&l, faceoffset); + CalcFaceExtents(&l, modelinfo->offset); CalcPoints(&l); lightmapwidth = l.texsize[0] + 1; @@ -935,8 +935,11 @@ LightFace(int surfnum, const vec3_t faceoffset) SkyLightFace(&l, sunlight_color); } - /* Minimum lighting */ - FixMinlight(&l, worldminlight, minlight_color); + /* Minimum lighting - Use the greater of global or model minlight. */ + if (modelinfo->minlight > worldminlight) + FixMinlight(&l, modelinfo->minlight, modelinfo->mincolor); + else + FixMinlight(&l, worldminlight, minlight_color); if (nominlimit) { /* cast only negative lights */