Merge branch 'master' of ssh://tuon/~/scm/tyrutils

Conflicts:
	light/ltface.c

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-03-11 18:25:34 +10:30
commit f208efcfa0
7 changed files with 476 additions and 604 deletions

View File

@ -1,6 +1,8 @@
Unreleased
* light: implemented self shadowing and full shadows for brush models
* light: removed the "-nominlimit" option (now the default behaviour)
* light: remove support for negative color components (never worked properly)
2013-03-07 TyrUtils v0.6

View File

@ -20,7 +20,9 @@
#ifndef __LIGHT_ENTITIES_H__
#define __LIGHT_ENTITIES_H__
#include <common/mathlib.h>
#include <common/bspfile.h>
#include <light/light.h>
#define DEFAULTLIGHTLEVEL 300
@ -59,12 +61,11 @@ typedef struct entity_s {
float spotangle2;
float spotfalloff2;
int style;
int light;
float atten;
lightsample_t light;
light_formula_t formula;
vec3_t lightcolor;
vec_t fadedist;
float atten;
int style;
char target[MAX_ENT_VALUE];
char targetname[MAX_ENT_VALUE];

View File

@ -25,7 +25,6 @@
#include <common/bspfile.h>
#include <common/log.h>
#include <common/threads.h>
#include <light/entities.h>
#include <light/litfile.h>
#define ON_EPSILON 0.1
@ -38,30 +37,31 @@ qboolean TestLine(const vec3_t start, const vec3_t stop);
qboolean TestLineModel(const dmodel_t *model,
const vec3_t start, const vec3_t stop);
typedef struct {
vec_t light;
vec3_t color;
} lightsample_t;
typedef struct {
const dmodel_t *model;
qboolean shadowself;
int minlight;
vec3_t mincolor;
lightsample_t minlight;
vec3_t offset;
} modelinfo_t;
/* tracelist is a null terminated array of BSP models to use for LOS tests */
extern const dmodel_t *const *tracelist;
void LightFace(int surfnum, const modelinfo_t *modelinfo);
void LightLeaf(dleaf_t * leaf);
void LightFace(dface_t *face, const modelinfo_t *modelinfo);
void MakeTnodes(void);
extern float scaledist;
extern float rangescale;
extern float fadegate;
extern int worldminlight;
extern const vec3_t vec3_white;
extern vec3_t minlight_color;
extern int sunlight;
extern vec3_t sunlight_color;
extern lightsample_t minlight;
extern lightsample_t sunlight;
extern vec3_t sunvec;
/*
@ -73,15 +73,9 @@ void GetFileSpace(byte **lightdata, byte **colordata, int size);
extern byte *filebase;
extern byte *lit_filebase;
void TransformSample(vec3_t in, vec3_t out);
void RotateSample(vec3_t in, vec3_t out);
extern int oversample;
extern qboolean compress_ents;
extern qboolean facecounter;
extern qboolean colored;
extern qboolean bsp30;
extern qboolean litfile;
extern qboolean nominlimit;
#endif /* __LIGHT_LIGHT_H__ */

View File

@ -23,9 +23,6 @@ OPTIONS
-light n Set a global minimum light level. Overrides default
light level set in worldspawn.
-nominlimit Allow negative lights to reduce surface lighting below
the global minumum light level.
-dist n Scales the fade distance of all lights by a factor of n.
If n > 1 lights fade more quickly with distance and if
n < 1, lights fade more slowly with distance and light
@ -61,7 +58,7 @@ ENTITY PARAMETERS
Set a global minimum light level of "n" across the whole map. This is
an easy way to eliminate completely dark areas of the level, however
you may lose some contrast as a result, so use with care.
you may lose some contrast as a result, so use with care. Default 0.
"_sunlight" "n"
@ -81,9 +78,8 @@ ENTITY PARAMETERS
"_sunlight_color" "r g b"
Specify red(r), green(g) and blue(b) components for the colour of the
sunlight. RGB component values are between -255 and 255. Negative
values will cause colour subtraction from light cast by other entities.
Default is white light ("255 255 255").
sunlight. RGB component values are between 0 and 255. Default is white
light ("255 255 255").
MODEL PARAMETERS
@ -147,8 +143,8 @@ ENTITY PARAMETERS
"_color" "r g b"
Specify red(r), green(g) and blue(b) components for the colour of the
light. RGB component values are between -255 and 255. Negative values
will cause colour subtraction from light cast by other entities.
light. RGB component values are between 0 and 255. Default is white
light ("255 255 255").
"target" "name"

View File

@ -166,8 +166,8 @@ vec_from_mangle(vec3_t v, const vec3_t m)
static void
CheckEntityFields(entity_t *entity)
{
if (!entity->light)
entity->light = DEFAULTLIGHTLEVEL;
if (!entity->light.light)
entity->light.light = DEFAULTLIGHTLEVEL;
if (entity->atten <= 0.0)
entity->atten = 1.0;
@ -184,19 +184,19 @@ CheckEntityFields(entity_t *entity)
entity->formula = LF_LINEAR;
}
if (!VectorCompare(entity->lightcolor, vec3_origin)) {
if (!VectorCompare(entity->light.color, vec3_origin)) {
if (!colored) {
colored = true;
logprint("Colored light entities detected: "
".lit output enabled.\n");
}
} else {
VectorCopy(vec3_white, entity->lightcolor);
VectorCopy(vec3_white, entity->light.color);
}
if (entity->formula == LF_LINEAR) {
/* Linear formula always has a falloff point */
entity->fadedist = fabs(entity->light / entity->atten / scaledist);
entity->fadedist = fabs(entity->light.light / entity->atten / scaledist);
} else if (fadegate < EQUAL_EPSILON) {
/* If fadegate is tiny, other lights have effectively infinite reach */
entity->fadedist = VECT_MAX;
@ -208,17 +208,17 @@ CheckEntityFields(entity_t *entity)
entity->fadedist = VECT_MAX;
break;
case LF_INVERSE:
entity->fadedist = entity->light * entity->atten * scaledist;
entity->fadedist = entity->light.light * entity->atten * scaledist;
entity->fadedist *= LF_SCALE / fadegate;
entity->fadedist = fabs(entity->fadedist);
break;
case LF_INVERSE2:
entity->fadedist = entity->light * entity->atten * scaledist;
entity->fadedist = entity->light.light * entity->atten * scaledist;
entity->fadedist *= LF_SCALE / sqrt(fadegate);
entity->fadedist = fabs(entity->fadedist);
break;
case LF_INVERSE2A:
entity->fadedist = entity->light * entity->atten * scaledist;
entity->fadedist = entity->light.light * entity->atten * scaledist;
entity->fadedist -= LF_SCALE;
entity->fadedist *= LF_SCALE / sqrt(fadegate);
entity->fadedist = fabs(entity->fadedist);
@ -306,7 +306,7 @@ LoadEntities(void)
else if (!strcmp(key, "origin"))
scan_vec3(entity->origin, com_token, "origin");
else if (!strncmp(key, "light", 5) || !strcmp(key, "_light"))
entity->light = atof(com_token);
entity->light.light = atof(com_token);
else if (!strcmp(key, "style")) {
entity->style = atof(com_token);
if (entity->style < 0 || entity->style > 254)
@ -324,18 +324,18 @@ LoadEntities(void)
vec_from_mangle(entity->spotvec, vec);
entity->spotlight = true;
} else if (!strcmp(key, "_color") || !strcmp(key, "color"))
scan_vec3(entity->lightcolor, com_token, "color");
scan_vec3(entity->light.color, com_token, "color");
else if (!strcmp(key, "_sunlight"))
sunlight = atof(com_token);
sunlight.light = atof(com_token);
else if (!strcmp(key, "_sun_mangle")) {
scan_vec3(vec, com_token, "_sun_mangle");
vec_from_mangle(sunvec, vec);
VectorNormalize(sunvec);
VectorScale(sunvec, -16384, sunvec);
} else if (!strcmp(key, "_sunlight_color"))
scan_vec3(sunlight_color, com_token, "_sunlight_color");
scan_vec3(sunlight.color, com_token, "_sunlight_color");
else if (!strcmp(key, "_minlight_color"))
scan_vec3(minlight_color, com_token, "_minlight_color");
scan_vec3(minlight.color, com_token, "_minlight_color");
}
/*
@ -354,19 +354,19 @@ LoadEntities(void)
}
}
if (!strcmp(entity->classname, "worldspawn")) {
if (entity->light > 0 && !worldminlight) {
worldminlight = entity->light;
if (entity->light.light > 0 && !minlight.light) {
minlight.light = entity->light.light;
logprint("using minlight value %i from worldspawn.\n",
worldminlight);
} else if (worldminlight) {
(int)minlight.light);
} else if (minlight.light) {
logprint("Using minlight value %i from command line.\n",
worldminlight);
(int)minlight.light);
}
}
}
if (!VectorCompare(sunlight_color, vec3_white) ||
!VectorCompare(minlight_color, vec3_white)) {
if (!VectorCompare(sunlight.color, vec3_white) ||
!VectorCompare(minlight.color, vec3_white)) {
if (!colored) {
colored = true;
logprint("Colored light entities detected: "

View File

@ -20,15 +20,15 @@
#include <stdint.h>
#include <light/light.h>
#include <light/entities.h>
float scaledist = 1.0;
float rangescale = 0.5;
float fadegate = EQUAL_EPSILON;
int worldminlight = 0;
int sunlight = 0;
const vec3_t vec3_white = { 255, 255, 255 };
vec3_t minlight_color = { 255, 255, 255 }; /* defaults to white light */
vec3_t sunlight_color = { 255, 255, 255 }; /* defaults to white light */
lightsample_t minlight = { 0, { 255, 255, 255 } };
lightsample_t sunlight = { 0, { 255, 255, 255 } };
vec3_t sunvec = { 0, 0, 16384 }; /* defaults to straight down */
byte *filebase; // start of lightmap data
@ -45,7 +45,6 @@ const dmodel_t *const *tracelist;
int oversample = 1;
qboolean compress_ents;
qboolean colored;
qboolean nominlimit;
void
GetFileSpace(byte **lightdata, byte **colordata, int size)
@ -95,7 +94,7 @@ LightThread(void *junk)
if (i == nummodels)
Error("%s: no model has face %d", __func__, facenum);
LightFace(facenum, &modelinfo[i]);
LightFace(dfaces + facenum, &modelinfo[i]);
}
return NULL;
@ -109,6 +108,7 @@ FindModelInfo(void)
char modelname[20];
const char *attribute;
const dmodel_t **shadowmodels;
modelinfo_t *info;
shadowmodels = malloc(sizeof(dmodel_t *) * (nummodels + 1));
memset(shadowmodels, 0, sizeof(dmodel_t *) * (nummodels + 1));
@ -120,8 +120,8 @@ FindModelInfo(void)
memset(modelinfo, 0, sizeof(*modelinfo) * nummodels);
modelinfo[0].model = &dmodels[0];
for (i = 1; i < nummodels; i++) {
modelinfo[i].model = &dmodels[i];
for (i = 1, info = modelinfo + 1; i < nummodels; i++, info++) {
info->model = &dmodels[i];
/* Find the entity for the model */
snprintf(modelname, sizeof(modelname), "*%d", i);
@ -137,27 +137,27 @@ FindModelInfo(void)
} else {
shadow = atoi(ValueForKey(entity, "_shadowself"));
if (shadow)
modelinfo[i].shadowself = true;
info->shadowself = true;
}
/* Set up the offset for rotate_* entities */
attribute = ValueForKey(entity, "classname");
if (!strncmp(attribute, "rotate_", 7))
GetVectorForKey(entity, "origin", modelinfo[i].offset);
GetVectorForKey(entity, "origin", info->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)) {
info->minlight.light = atoi(attribute);
GetVectorForKey(entity, "_mincolor", info->minlight.color);
if (!VectorCompare(info->minlight.color, vec3_origin)) {
if (!colored) {
colored = true;
logprint("Colored light entities detected: "
".lit output enabled.\n");
}
} else {
VectorCopy(vec3_white, modelinfo[i].mincolor);
VectorCopy(vec3_white, info->minlight.color);
}
}
@ -245,15 +245,13 @@ main(int argc, const char **argv)
fadegate = atof(argv[i + 1]);
i++;
} else if (!strcmp(argv[i], "-light")) {
worldminlight = atof(argv[i + 1]);
minlight.light = atof(argv[i + 1]);
i++;
} else if (!strcmp(argv[i], "-compress")) {
compress_ents = true;
logprint("light entity compression enabled\n");
} else if (!strcmp(argv[i], "-lit")) {
colored = true;
} else if (!strcmp(argv[i], "-nominlimit")) {
nominlimit = true;
} else if (argv[i][0] == '-')
Error("Unknown option \"%s\"", argv[i]);
else
@ -263,7 +261,7 @@ main(int argc, const char **argv)
if (i != argc - 1) {
printf("usage: light [-threads num] [-light num] [-extra|-extra4]\n"
" [-dist n] [-range n] [-gate n] [-lit] "
" [-compress] [-nominlimit] bspfile\n");
" [-compress] bspfile\n");
exit(1);
}

File diff suppressed because it is too large Load Diff