light: implement minlighting for bmodels

Collect the appropriate keys from the models at load time and pass them
into the minlighting function (if > world minlight).

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-03-07 18:22:25 +10:30
parent e734671b03
commit b4387359a4
5 changed files with 56 additions and 17 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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 */