mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
bring in lordhavoc's vis data optimisations (doesn't work properly yet) and
parsing of his extra fields.
This commit is contained in:
parent
ba4ca3515d
commit
26f3839276
9 changed files with 436 additions and 16 deletions
|
@ -31,6 +31,7 @@
|
|||
#define __entities_h
|
||||
|
||||
#define DEFAULTLIGHTLEVEL 300
|
||||
#define DEFAULTFALLOFF 1.0f
|
||||
|
||||
typedef struct epair_s {
|
||||
struct epair_s *next;
|
||||
|
@ -41,7 +42,7 @@ typedef struct epair_s {
|
|||
typedef struct entity_s {
|
||||
const char *classname;
|
||||
vec3_t origin;
|
||||
float angle;
|
||||
vec_t angle;
|
||||
int light;
|
||||
// LordHavoc: added falloff (smaller fractions = bigger light area),
|
||||
// color, and lightradius (also subbrightness to implement lightradius)
|
||||
|
@ -68,6 +69,7 @@ extern int num_entities;
|
|||
const char *ValueForKey (entity_t *ent, const char *key);
|
||||
void SetKeyValue (entity_t *ent, const char *key, const char *value);
|
||||
float FloatForKey (entity_t *ent, const char *key);
|
||||
entity_t *FindEntityWithKeyPair(char *key, char *value);
|
||||
void GetVectorForKey (entity_t *ent, const char *key, vec3_t vec);
|
||||
|
||||
void LoadEntities (void);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#define ON_EPSILON 0.1
|
||||
#define MAXLIGHTS 1024
|
||||
#define LIGHTDISTBIAS 65536.0
|
||||
|
||||
extern float scaledist;
|
||||
extern float scalecos;
|
||||
|
@ -60,7 +61,19 @@ int GetFileSpace (int size);
|
|||
void TransformSample (vec3_t in, vec3_t out);
|
||||
void RotateSample (vec3_t in, vec3_t out);
|
||||
|
||||
void VisEntity (int ent_index);
|
||||
void VisStats (void);
|
||||
|
||||
extern struct bsp_s *bsp;
|
||||
extern struct dstring_s *lightdata;
|
||||
|
||||
typedef struct lightchain_s {
|
||||
struct lightchain_s *next;
|
||||
struct entity_s *light;
|
||||
} lightchain_t;
|
||||
|
||||
extern lightchain_t **surfacelightchain;
|
||||
extern struct entity_s **novislights;
|
||||
extern int num_novislights;
|
||||
|
||||
#endif// __light_h
|
||||
|
|
|
@ -34,9 +34,12 @@
|
|||
typedef struct {
|
||||
int verbosity; // 0=silent
|
||||
int threads;
|
||||
int novis;
|
||||
qboolean extra;
|
||||
float distance;
|
||||
float range;
|
||||
vec_t distance;
|
||||
vec_t range;
|
||||
vec_t globallightscale;
|
||||
const char *lightsfilename;
|
||||
} options_t;
|
||||
|
||||
extern options_t options;
|
||||
|
|
|
@ -17,7 +17,7 @@ endif
|
|||
bin_PROGRAMS= $(qflight)
|
||||
EXTRA_PROGRAMS= qflight
|
||||
|
||||
qflight_SOURCES= entities.c ltface.c options.c qflight.c threads.c trace.c
|
||||
qflight_SOURCES= entities.c ltface.c options.c qflight.c threads.c trace.c vis.c
|
||||
|
||||
qflight_LDFLAGS= $(PTHREAD_LDFLAGS)
|
||||
qflight_LDADD= $(QFLIGHT_LIBS)
|
||||
|
|
|
@ -104,6 +104,14 @@ MatchTargets (void)
|
|||
if (entities[j].targetname
|
||||
&& !strcmp (entities[j].targetname, entities[i].target)) {
|
||||
entities[i].targetent = &entities[j];
|
||||
// set up spotlight values for lighting code to use
|
||||
VectorSubtract (entities[i].targetent->origin,
|
||||
entities[i].origin, entities[i].spotdir);
|
||||
VectorNormalize (entities[i].spotdir);
|
||||
if (!entities[i].angle)
|
||||
entities[i].spotcone = -cos(20 * M_PI / 180);
|
||||
else
|
||||
entities[i].spotcone = -cos(entities[i].angle * M_PI / 360);
|
||||
break;
|
||||
}
|
||||
if (j == num_entities) {
|
||||
|
@ -121,17 +129,49 @@ MatchTargets (void)
|
|||
sprintf (s, "%i", entities[i].style);
|
||||
SetKeyValue (&entities[i], "style", s);
|
||||
}
|
||||
|
||||
if (entities[i].spotcone <= 0) {
|
||||
VectorZero (entities[i].spotdir);
|
||||
entities[i].spotcone = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WriteLights (void)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
entity_t *e;
|
||||
|
||||
if (!options.lightsfilename)
|
||||
return;
|
||||
printf ("building .lights file\n");
|
||||
f = fopen (options.lightsfilename, "wb");
|
||||
for (i = 0; i < num_entities; i++) {
|
||||
e = entities + i;
|
||||
if (e->light)
|
||||
fprintf(f, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d\n",
|
||||
e->origin[0], e->origin[1], e->origin[2],
|
||||
e->falloff,
|
||||
e->color[0], e->color[1], e->color[2],
|
||||
e->subbrightness,
|
||||
e->spotdir[0], e->spotdir[1], e->spotdir[2],
|
||||
e->spotcone, e->lightoffset, e->style);
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
void
|
||||
LoadEntities (void)
|
||||
{
|
||||
const char *data;
|
||||
const char *key;
|
||||
double vec[3];
|
||||
double vec[4];
|
||||
double temp, color2[3];
|
||||
entity_t *entity;
|
||||
epair_t *epair;
|
||||
int i;
|
||||
|
||||
data = bsp->entdata;
|
||||
|
||||
|
@ -156,6 +196,13 @@ LoadEntities (void)
|
|||
entity = &entities[num_entities];
|
||||
num_entities++;
|
||||
|
||||
memset (entity, 0, sizeof (*entity));
|
||||
entity->color[0] = entity->color[1] = entity->color[2] = 1.0f;
|
||||
color2[0] = color2[1] = color2[2] = 1.0f;
|
||||
entity->falloff = DEFAULTFALLOFF * DEFAULTFALLOFF;
|
||||
entity->lightradius = 0;
|
||||
entity->lightoffset = LIGHTDISTBIAS;
|
||||
|
||||
// go through all the keys in this entity
|
||||
while (1) {
|
||||
int c;
|
||||
|
@ -196,7 +243,37 @@ LoadEntities (void)
|
|||
fprintf (stderr, "LoadEntities: not 3 values for origin");
|
||||
VectorCopy (vec, entity->origin);
|
||||
} else if (!strncmp (key, "light", 5) || !strcmp (key, "_light")) {
|
||||
entity->light = atof(com_token);
|
||||
i = sscanf (com_token, "%lf %lf %lf %lf",
|
||||
&vec[0], &vec[1], &vec[2], &vec[3]);
|
||||
switch (i) {
|
||||
case 4: // HalfLife light
|
||||
entity->light = vec[3];
|
||||
entity->color[0] = vec[0] * (1.0f / 255.0f);
|
||||
entity->color[1] = vec[1] * (1.0f / 255.0f);
|
||||
entity->color[2] = vec[2] * (1.0f / 255.0f);
|
||||
break;
|
||||
case 3:
|
||||
entity->light = 1;
|
||||
entity->color[0] = vec[0];
|
||||
entity->color[1] = vec[1];
|
||||
entity->color[2] = vec[2];
|
||||
break;
|
||||
case 1:
|
||||
entity->light = vec[0];
|
||||
entity->color[0] = 1.0f;
|
||||
entity->color[1] = 1.0f;
|
||||
entity->color[2] = 1.0f;
|
||||
break;
|
||||
default:
|
||||
Sys_Error ("LoadEntities: _light (or light) key must "
|
||||
"be 1 (Quake), 4 (HalfLife), or 3 (HLight) "
|
||||
"values, \"%s\" is not valid\n", com_token);
|
||||
}
|
||||
} else if (!strcmp (key, "wait")) {
|
||||
entity->falloff = atof (com_token);
|
||||
entity->falloff *= entity->falloff; // presquared
|
||||
} else if (!strcmp (key, "_lightradius")) {
|
||||
entity->lightradius = atof (com_token);
|
||||
} else if (!strcmp (key, "style")) {
|
||||
entity->style = atof (com_token);
|
||||
if ((unsigned) entity->style > 254)
|
||||
|
@ -204,13 +281,45 @@ LoadEntities (void)
|
|||
entity->style);
|
||||
} else if (!strcmp (key, "angle")) {
|
||||
entity->angle = atof(com_token);
|
||||
} else if (!strcmp (key, "color") || !strcmp (key, "_color")) {
|
||||
if (sscanf (com_token, "%lf %lf %lf",
|
||||
&vec[0], &vec[1], &vec[2]) != 3)
|
||||
Sys_Error ("LoadEntities: not 3 values for color");
|
||||
// scale the color to have at least one component at 1.0
|
||||
temp = vec[0];
|
||||
if (vec[1] > temp)
|
||||
temp = vec[1];
|
||||
if (vec[2] > temp)
|
||||
temp = vec[2];
|
||||
if (temp != 0.0)
|
||||
temp = 1.0 / temp;
|
||||
VectorScale (vec, temp, color2);
|
||||
}
|
||||
}
|
||||
|
||||
// all fields have been parsed
|
||||
if (entity->classname && !strncmp (entity->classname, "light", 5)
|
||||
&& !entity->light)
|
||||
entity->light = DEFAULTLIGHTLEVEL;
|
||||
if (entity->classname && !strncmp (entity->classname, "light", 5))
|
||||
if (!entity->light)
|
||||
entity->light = DEFAULTLIGHTLEVEL;
|
||||
|
||||
if (entity->light) {
|
||||
// convert to subtraction to the brightness for the whole light,
|
||||
// so it will fade nicely, rather than being clipped off
|
||||
VectorScale (color2,
|
||||
entity->light * 16384.0 * options.globallightscale,
|
||||
color2);
|
||||
entity->color[0] *= color2[0];
|
||||
entity->color[1] *= color2[1];
|
||||
entity->color[2] *= color2[2];
|
||||
|
||||
if (entity->lightradius)
|
||||
entity->subbrightness = 1.0 / (entity->lightradius
|
||||
* entity->lightradius
|
||||
* entity->falloff
|
||||
+ LIGHTDISTBIAS);
|
||||
if (entity->subbrightness < (1.0 / 1048576.0))
|
||||
entity->subbrightness = (1.0 / 1048576.0);
|
||||
}
|
||||
|
||||
if (entity->classname && !strcmp (entity->classname, "light")) {
|
||||
if (entity->targetname && entity->targetname[0]
|
||||
|
@ -229,6 +338,10 @@ LoadEntities (void)
|
|||
printf ("%d entities read\n", num_entities);
|
||||
|
||||
MatchTargets ();
|
||||
|
||||
WriteLights();
|
||||
|
||||
novislights = (entity_t **)calloc (num_entities, sizeof (entity_t *));
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -268,6 +381,26 @@ FloatForKey (entity_t *ent, const char *key)
|
|||
return atof (k);
|
||||
}
|
||||
|
||||
entity_t *
|
||||
FindEntityWithKeyPair (char *key, char *value)
|
||||
{
|
||||
entity_t *ent;
|
||||
epair_t *ep;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_entities; i++) {
|
||||
ent = &entities[i];
|
||||
for (ep = ent->epairs; ep; ep = ep->next) {
|
||||
if (!strcmp (ep->key, key)) {
|
||||
if (!strcmp (ep->value, value))
|
||||
return ent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
GetVectorForKey (entity_t *ent, const char *key, vec3_t vec)
|
||||
{
|
||||
|
@ -281,7 +414,6 @@ void
|
|||
WriteEntitiesToString (void)
|
||||
{
|
||||
dstring_t *buf;
|
||||
char line[128];
|
||||
epair_t *ep;
|
||||
int i;
|
||||
|
||||
|
@ -298,8 +430,7 @@ WriteEntitiesToString (void)
|
|||
dstring_appendstr (buf, "{\n");
|
||||
|
||||
for (ep = entities[i].epairs; ep; ep = ep->next) {
|
||||
sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
|
||||
dstring_appendstr (buf, line);
|
||||
dasprintf (buf, "\"%s\" \"%s\"\n", ep->key, ep->value);
|
||||
}
|
||||
dstring_appendstr (buf, "}\n");
|
||||
}
|
||||
|
|
|
@ -461,6 +461,7 @@ LightFace (int surfnum)
|
|||
lightinfo_t l;
|
||||
vec_t total;
|
||||
vec_t *light;
|
||||
lightchain_t *lightchain;
|
||||
|
||||
f = bsp->faces + surfnum;
|
||||
|
||||
|
@ -500,9 +501,12 @@ LightFace (int surfnum)
|
|||
|
||||
// cast all lights
|
||||
l.numlightstyles = 0;
|
||||
for (i = 0; i < num_entities; i++) {
|
||||
if (entities[i].light)
|
||||
SingleLightFace (&entities[i], &l);
|
||||
for (lightchain = surfacelightchain[surfnum]; lightchain;
|
||||
lightchain = lightchain->next) {
|
||||
SingleLightFace (lightchain->light, &l);
|
||||
}
|
||||
for (i = 0; i < num_novislights; i++) {
|
||||
SingleLightFace (novislights[i], &l);
|
||||
}
|
||||
|
||||
FixMinlight (&l);
|
||||
|
|
|
@ -54,6 +54,7 @@ static struct option const long_options[] = {
|
|||
{"version", no_argument, 0, 'V'},
|
||||
{"threads", required_argument, 0, 't'},
|
||||
{"extra", no_argument, 0, 'e'},
|
||||
{"novis", no_argument, 0, 'N'},
|
||||
{"distance", required_argument, 0, 'd'},
|
||||
{"range", required_argument, 0, 'r'},
|
||||
{"file", required_argument, 0, 'f'},
|
||||
|
@ -65,6 +66,7 @@ static const char *short_options =
|
|||
"v" // verbose
|
||||
"h" // help
|
||||
"V" // version
|
||||
"N" // novis
|
||||
"t:" // threads
|
||||
"e" // extra sampling
|
||||
"d:" // scale distance
|
||||
|
@ -83,6 +85,7 @@ usage (int status)
|
|||
" -v, --verbose Display more output than usual\n"
|
||||
" -h, --help Display this help and exit\n"
|
||||
" -V, --version Output version information and exit\n"
|
||||
" -N, --novis Don't use vis data\n"
|
||||
" -t, --threads [num] Number of threads to use\n"
|
||||
" -e, --extra Apply extra sampling\n"
|
||||
" -d, --distance [scale] Scale distance\n"
|
||||
|
@ -96,11 +99,13 @@ DecodeArgs (int argc, char **argv)
|
|||
{
|
||||
int c;
|
||||
|
||||
memset (&options, 0, sizeof (options));
|
||||
options.verbosity = 0;
|
||||
options.threads = 1;
|
||||
options.extra = false;
|
||||
options.distance = 1.0;
|
||||
options.range = 0.5;
|
||||
options.globallightscale = 1.0;
|
||||
bspfile = NULL;
|
||||
|
||||
while ((c = getopt_long (argc, argv, short_options, long_options, 0))
|
||||
|
@ -115,6 +120,9 @@ DecodeArgs (int argc, char **argv)
|
|||
case 'h': // help
|
||||
usage (0);
|
||||
break;
|
||||
case 'N': // novis
|
||||
options.novis = 1;
|
||||
break;
|
||||
case 'V': // version
|
||||
printf ("%s version %s\n", PACKAGE, VERSION);
|
||||
exit (0);
|
||||
|
|
|
@ -71,6 +71,7 @@ dstring_t *lightdata;
|
|||
|
||||
dmodel_t *bspmodel;
|
||||
int bspfileface; // next surface to dispatch
|
||||
int bspfileent; // next entity to dispatch
|
||||
|
||||
vec3_t bsp_origin;
|
||||
|
||||
|
@ -93,10 +94,25 @@ GetFileSpace (int size)
|
|||
return ofs;
|
||||
}
|
||||
|
||||
static void *
|
||||
VisThread (void *junk)
|
||||
{
|
||||
int i;
|
||||
|
||||
while (1) {
|
||||
LOCK;
|
||||
i = bspfileent++;
|
||||
UNLOCK;
|
||||
if (i >= num_entities)
|
||||
return 0;
|
||||
VisEntity (i);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
LightThread (void *junk)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
while (1) {
|
||||
LOCK;
|
||||
|
@ -113,7 +129,11 @@ static void
|
|||
LightWorld (void)
|
||||
{
|
||||
lightdata = dstring_new ();
|
||||
surfacelightchain = (lightchain_t **) calloc (bsp->numfaces,
|
||||
sizeof (lightchain_t *));
|
||||
|
||||
VisThread (0); // not worth threading :/
|
||||
VisStats ();
|
||||
RunThreadsOn (LightThread);
|
||||
|
||||
BSP_AddLighting (bsp, lightdata->str, lightdata->size);
|
||||
|
|
239
tools/qflight/source/vis.c
Normal file
239
tools/qflight/source/vis.c
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
vis.c
|
||||
|
||||
PVS support to speed lighting calcs
|
||||
|
||||
Copyright (C) 2003 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2003/9/8
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
static __attribute__ ((unused)) const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/bspfile.h"
|
||||
#include "QF/mathlib.h"
|
||||
|
||||
#include "entities.h"
|
||||
#include "light.h"
|
||||
#include "options.h"
|
||||
#include "threads.h"
|
||||
|
||||
static struct {
|
||||
int empty;
|
||||
int solid;
|
||||
int water;
|
||||
int slime;
|
||||
int lava;
|
||||
int sky;
|
||||
int misc;
|
||||
|
||||
int lights;
|
||||
int cast;
|
||||
} counts;
|
||||
|
||||
static lightchain_t *free_lightchains;
|
||||
lightchain_t **surfacelightchain;
|
||||
entity_t **alllights;
|
||||
int num_alllights;
|
||||
entity_t **novislights;
|
||||
int num_novislights;
|
||||
|
||||
static dleaf_t *
|
||||
Light_PointInLeaf (vec3_t point)
|
||||
{
|
||||
int num = 0, side;
|
||||
dnode_t *node;
|
||||
dplane_t *plane;
|
||||
|
||||
while (num >= 0) {
|
||||
node = bsp->nodes + num;
|
||||
plane = bsp->planes + node->planenum;
|
||||
side = DotProduct (point, plane->normal) < plane->dist;
|
||||
num = node->children[side];
|
||||
}
|
||||
return bsp->leafs + (-1 - num);
|
||||
}
|
||||
|
||||
static void
|
||||
DecompressVis (byte *in, byte *out, int size)
|
||||
{
|
||||
byte *end = out + size;
|
||||
int n;
|
||||
|
||||
while (out < end) {
|
||||
n = *in++;
|
||||
if (n) {
|
||||
*out++ = n;
|
||||
} else {
|
||||
n = *in++;
|
||||
while (n-- && out < end)
|
||||
*out++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static lightchain_t *
|
||||
get_lightchain (void)
|
||||
{
|
||||
lightchain_t *lc;
|
||||
int i;
|
||||
|
||||
if (!free_lightchains) {
|
||||
lc = free_lightchains = malloc (1024 * sizeof (lightchain_t));
|
||||
for (i = 0; i < 1023; i++, lc++)
|
||||
lc->next = lc + 1;
|
||||
lc->next = 0;
|
||||
}
|
||||
lc = free_lightchains;
|
||||
free_lightchains = lc->next;
|
||||
return lc;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mark_face (int surfnum, byte *surfacehit, entity_t *entity)
|
||||
{
|
||||
lightchain_t *lc;
|
||||
|
||||
if (surfacehit[surfnum >> 3] & (1 << (surfnum & 7)))
|
||||
return;
|
||||
surfacehit[surfnum >> 3] |= (1 << (surfnum & 7));
|
||||
counts.cast++;
|
||||
lc = get_lightchain ();
|
||||
lc->next = surfacelightchain[surfnum];
|
||||
lc->light = entity;
|
||||
surfacelightchain[surfnum] = lc;
|
||||
}
|
||||
|
||||
void
|
||||
VisEntity (int ent_index)
|
||||
{
|
||||
entity_t *entity = entities + ent_index;
|
||||
dleaf_t *leaf;
|
||||
int ignorevis = false;
|
||||
int i, j;
|
||||
unsigned short *mark;
|
||||
byte *vis, *surfacehit;
|
||||
int vis_size;
|
||||
|
||||
if (!entity->light)
|
||||
return;
|
||||
|
||||
counts.lights++;
|
||||
|
||||
leaf = Light_PointInLeaf (entity->origin);
|
||||
|
||||
switch (leaf->contents) {
|
||||
case CONTENTS_EMPTY:
|
||||
counts.empty++;
|
||||
break;
|
||||
case CONTENTS_SOLID:
|
||||
counts.solid++;
|
||||
ignorevis = true;
|
||||
break;
|
||||
case CONTENTS_WATER:
|
||||
counts.water++;
|
||||
break;
|
||||
case CONTENTS_SLIME:
|
||||
counts.slime++;
|
||||
break;
|
||||
case CONTENTS_LAVA:
|
||||
counts.lava++;
|
||||
break;
|
||||
case CONTENTS_SKY:
|
||||
counts.sky++;
|
||||
ignorevis = true;
|
||||
break;
|
||||
default:
|
||||
counts.misc++;
|
||||
break;
|
||||
}
|
||||
if (leaf->visofs == -1 || ignorevis || options.novis) {
|
||||
counts.cast += bsp->numfaces;
|
||||
novislights[num_novislights++] = entity;
|
||||
} else {
|
||||
vis_size = (bsp->numleafs + 7) / 8;
|
||||
vis = alloca (vis_size + (bsp->numfaces + 7) / 8);
|
||||
surfacehit = vis + vis_size;
|
||||
memset (surfacehit, 0, (bsp->numfaces + 7) / 8);
|
||||
|
||||
DecompressVis (bsp->visdata + leaf->visofs, vis,
|
||||
(bsp->numleafs + 7) >> 3);
|
||||
for (i = 1, leaf = bsp->leafs + 1; i < bsp->numleafs; i++, leaf++) {
|
||||
if (!leaf->nummarksurfaces)
|
||||
continue;
|
||||
if (vis[i >> 3] & (1 << (i & 7))) {
|
||||
for (j = 0, mark = bsp->marksurfaces + leaf->firstmarksurface;
|
||||
j < leaf->nummarksurfaces; j++, mark++) {
|
||||
mark_face (*mark, surfacehit, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 1; i < bsp->nummodels; i++) {
|
||||
for (j = 0; j < bsp->models[i].numfaces; j++) {
|
||||
//FIXME vis
|
||||
mark_face (bsp->models[i].firstface + j, surfacehit, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VisStats (void)
|
||||
{
|
||||
int i, count;
|
||||
|
||||
printf ("%4i lights\n", counts.lights);
|
||||
printf ("%4i air\n", counts.empty);
|
||||
printf ("%4i solid\n", counts.solid);
|
||||
printf ("%4i water\n", counts.water);
|
||||
printf ("%4i slime\n", counts.slime);
|
||||
printf ("%4i lava\n", counts.lava);
|
||||
printf ("%4i sky\n", counts.sky);
|
||||
printf ("%4i unknown\n", counts.misc);
|
||||
|
||||
for (i = count = 0; i < bsp->numfaces; i++)
|
||||
if (surfacelightchain[i])
|
||||
count++;
|
||||
printf ("%i faces, %i (%i%%) may receive light\n", bsp->numfaces,
|
||||
count, count * 100 / bsp->numfaces);
|
||||
if (counts.solid || counts.sky)
|
||||
printf ("warning: %i lights of %i lights (%i%%) were found in sky\n"
|
||||
"or solid and will not be accelerated using vis, move them\n"
|
||||
"out of the solid or sky to accelerate compiling\n",
|
||||
counts.solid + counts.sky, counts.lights,
|
||||
(counts.solid + counts.sky) * 100 / counts.lights);
|
||||
printf ("%i lights will be cast onto %i surfaces, %i casts will\n"
|
||||
"be performed\n", counts.lights, bsp->numfaces, counts.cast);
|
||||
}
|
Loading…
Reference in a new issue