light: use vis data

This commit is contained in:
Eric Wasylishen 2016-04-14 19:54:52 -06:00
parent 32b48a443b
commit fff8cbffbc
5 changed files with 158 additions and 10 deletions

View File

@ -97,6 +97,8 @@ typedef struct entity_s {
qboolean generated; // if true, don't write to the bsp
const bsp2_dleaf_t *leaf; // for vis testing
struct entity_s *next;
} entity_t;

View File

@ -62,8 +62,6 @@ typedef struct traceinfo_s {
bool TraceFaces (traceinfo_t *ti, int node, const vec3_t start, const vec3_t end);
int Light_PointContents( const vec3_t point );
typedef struct {
const dplane_t *dplane;
int side;
@ -180,6 +178,12 @@ typedef struct {
*/
vec_t *occlusion; // malloc'ed array of numpoints
/*
pvs for the entire light surface. generated by ORing together
the pvs at each of the sample points
*/
byte *pvs;
/* for sphere culling */
vec3_t origin;
vec_t radius;
@ -290,4 +294,10 @@ PrintFaceInfo(const bsp2_dface_t *face, const bsp2_t *bsp);
}
#endif
/* vis testing */
const bsp2_dleaf_t *Light_PointInLeaf( const bsp2_t *bsp, const vec3_t point );
int PointInLeafnum (const bsp2_t *bsp, const vec3_t point);
void PvsForOrigin (const bsp2_t *bsp, const vec3_t org, byte *pvs);
int Light_PointContents( const bsp2_t *bsp, const vec3_t point );
#endif /* __LIGHT_LIGHT_H__ */

View File

@ -827,6 +827,16 @@ FindLights()
logprint("FindLights: %d total lights\n", totallights);
}
static void
SetupLightLeafnums(const bsp2_t *bsp)
{
entity_t *entity;
for (entity = entities; entity; entity = entity->next) {
entity->leaf = Light_PointInLeaf(bsp, entity->origin);
}
}
/*
* ==================
* LoadEntities
@ -1153,6 +1163,7 @@ SetupLights(const bsp2_t *bsp)
SetupSuns();
SetupSkyDome();
FindLights();
SetupLightLeafnums(bsp);
}
const char *

View File

@ -662,6 +662,96 @@ CalcPoints(const modelinfo_t *modelinfo, const vec3_t offset, lightsurf_t *surf,
}
}
/*
===================
DecompressVis
===================
*/
static void
DecompressVis (const bsp2_t *bsp, const byte *in, byte *decompressed)
{
//static byte decompressed[(bsp->numleafs+7)/8];
int c;
byte *out;
int row;
row = (bsp->numleafs+7)>>3;
out = decompressed;
if (!in)
{ // no vis info, so make all visible
while (row)
{
*out++ = 0xff;
row--;
}
return;
}
do
{
if (*in)
{
if (!(out - decompressed < row)) return;
*out++ = *in++;
continue;
}
c = in[1];
in += 2;
while (c)
{
if (!(out - decompressed < row)) return;
*out++ = 0;
c--;
}
} while (out - decompressed < row);
}
static void
CalcPvs(const bsp2_t *bsp, lightsurf_t *lightsurf)
{
const int pvssize = (bsp->numleafs+7)/8;
byte *pointpvs;
const vec_t *surfpoint;
int i, j;
const bsp2_dleaf_t *lastleaf = NULL;
if (!bsp->visdatasize) return;
pointpvs = calloc(pvssize, 1);
lightsurf->pvs = calloc(pvssize, 1);
surfpoint = lightsurf->points[0];
for (i = 0; i < lightsurf->numpoints; i++, surfpoint += 3) {
const bsp2_dleaf_t *leaf = Light_PointInLeaf (bsp, surfpoint);
if (leaf == NULL)
continue;
/* most/all of the surface points are probably in the same leaf */
if (leaf == lastleaf)
continue;
lastleaf = leaf;
/* copy the pvs for this leaf into pointpvs */
if (leaf == bsp->dleafs)
memset (pointpvs, 255, pvssize );
else
DecompressVis (bsp, bsp->dvisdata + leaf->visofs, pointpvs);
/* merge the pvs for this sample point into lightsurf->pvs */
for (j=0; j<pvssize; j++)
{
lightsurf->pvs[j] |= pointpvs[j];
}
}
free(pointpvs);
}
__attribute__((noinline))
static void
Lightsurf_Init(const modelinfo_t *modelinfo, const bsp2_dface_t *face,
@ -724,6 +814,9 @@ Lightsurf_Init(const modelinfo_t *modelinfo, const bsp2_dface_t *face,
/* Allocate occlusion array */
lightsurf->occlusion = calloc(lightsurf->numpoints, sizeof(float));
/* Setup vis data */
CalcPvs(bsp, lightsurf);
}
static void
@ -1092,13 +1185,36 @@ ProjectPointOntoPlane(const vec3_t point, const plane_t *plane, vec3_t out)
VectorMA(point, -dist, plane->normal, out);
}
static qboolean
VisCullEntity(const bsp2_t *bsp, const lightsurf_t *lightsurf, const entity_t *entity)
{
int i;
if (lightsurf->pvs == NULL) return false;
if (entity->leaf == NULL) return false;
if (entity->leaf->contents == CONTENTS_SOLID
|| entity->leaf->contents == CONTENTS_SKY)
return false;
i = entity->leaf - bsp->dleafs;
if (lightsurf->pvs[i>>3] & (1<<(i&7))) return false;
return true;
}
extern int totalhit;
extern int totalmissed;
/*
* ================
* LightFace_Entity
* ================
*/
static void
LightFace_Entity(const entity_t *entity, const lightsample_t *light,
LightFace_Entity(const bsp2_t *bsp,
const entity_t *entity, const lightsample_t *light,
const lightsurf_t *lightsurf, lightmap_t *lightmaps)
{
const modelinfo_t *modelinfo = lightsurf->modelinfo;
@ -1112,6 +1228,11 @@ LightFace_Entity(const entity_t *entity, const lightsample_t *light,
lightmap_t *lightmap;
qboolean curved = lightsurf->curved;
/* vis cull */
if (VisCullEntity(bsp, lightsurf, entity)) {
return;
}
planedist = DotProduct(entity->origin, plane->normal) - plane->dist;
/* don't bother with lights behind the surface */
@ -1738,6 +1859,9 @@ void LightFaceShutdown(struct ltface_ctx *ctx)
if (ctx->lightsurf.occluded)
free(ctx->lightsurf.occluded);
if (ctx->lightsurf.pvs)
free(ctx->lightsurf.pvs);
free(ctx);
}
@ -1834,7 +1958,7 @@ LightFace(bsp2_dface_t *face, facesup_t *facesup, const modelinfo_t *modelinfo,
if (entity->formula == LF_LOCALMIN)
continue;
if (entity->light.light > 0)
LightFace_Entity(entity, &entity->light, lightsurf, lightmaps);
LightFace_Entity(bsp, entity, &entity->light, lightsurf, lightmaps);
}
for ( sun = suns; sun; sun = sun->next )
if (sun->sunlight.light > 0)
@ -1852,7 +1976,7 @@ LightFace(bsp2_dface_t *face, facesup_t *facesup, const modelinfo_t *modelinfo,
if (entity->formula == LF_LOCALMIN)
continue;
if (entity->light.light < 0)
LightFace_Entity(entity, &entity->light, lightsurf, lightmaps);
LightFace_Entity(bsp, entity, &entity->light, lightsurf, lightmaps);
}
for ( sun = suns; sun; sun = sun->next )
if (sun->sunlight.light < 0)

View File

@ -57,14 +57,15 @@ Light_PointInLeaf
from hmap2
==============
*/
bsp2_dleaf_t *Light_PointInLeaf( const vec3_t point )
const bsp2_dleaf_t *
Light_PointInLeaf( const bsp2_t *bsp, const vec3_t point )
{
int num = 0;
while( num >= 0 )
num = bsp_static->dnodes[num].children[PlaneDiff(point, &bsp_static->dplanes[bsp_static->dnodes[num].planenum]) < 0];
num = bsp->dnodes[num].children[PlaneDiff(point, &bsp->dplanes[bsp->dnodes[num].planenum]) < 0];
return bsp_static->dleafs + (-1 - num);
return bsp->dleafs + (-1 - num);
}
/*
@ -74,9 +75,9 @@ Light_PointContents
from hmap2
==============
*/
int Light_PointContents( const vec3_t point )
int Light_PointContents( const bsp2_t *bsp, const vec3_t point )
{
return Light_PointInLeaf(point)->contents;
return Light_PointInLeaf(bsp, point)->contents;
}
/*