From fff8cbffbc76e4de3e7f86b2da8f01b527cd0e55 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Thu, 14 Apr 2016 19:54:52 -0600 Subject: [PATCH] light: use vis data --- include/light/entities.h | 2 + include/light/light.h | 14 ++++- light/entities.c | 11 ++++ light/ltface.c | 130 ++++++++++++++++++++++++++++++++++++++- light/trace.c | 11 ++-- 5 files changed, 158 insertions(+), 10 deletions(-) diff --git a/include/light/entities.h b/include/light/entities.h index 5811d5c6..db97b0a2 100644 --- a/include/light/entities.h +++ b/include/light/entities.h @@ -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; diff --git a/include/light/light.h b/include/light/light.h index e2c9421e..9424c1e2 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -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__ */ diff --git a/light/entities.c b/light/entities.c index aad109b3..a3c07bb6 100644 --- a/light/entities.c +++ b/light/entities.c @@ -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 * diff --git a/light/ltface.c b/light/ltface.c index 974eb054..8aefaea0 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -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; jpvs[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) diff --git a/light/trace.c b/light/trace.c index a4d8fb48..284bb223 100644 --- a/light/trace.c +++ b/light/trace.c @@ -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; } /*