diff --git a/include/light/light.hh b/include/light/light.hh index 2c398a3e..25c441d5 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -133,6 +133,7 @@ struct lightsurf_t the pvs at each of the sample points */ std::vector pvs; + std::vector leaves; // output width * extra int width; diff --git a/include/light/surflight.hh b/include/light/surflight.hh index 3440e26b..665ee910 100644 --- a/include/light/surflight.hh +++ b/include/light/surflight.hh @@ -47,7 +47,6 @@ struct surfacelight_t std::optional minlight_scale; std::vector points; - std::vector leaves; // Surface light settings... struct per_style_t diff --git a/light/bounce.cc b/light/bounce.cc index e881ab6e..b232752b 100644 --- a/light/bounce.cc +++ b/light/bounce.cc @@ -109,12 +109,8 @@ static void MakeBounceLight(const mbsp_t *bsp, const settings::worldspawn_keys & // Init bbox... if (light_options.visapprox.value() == visapprox_t::RAYS) { l->bounds = EstimateVisibleBoundsAtPoint(facemidpoint); - } - for (auto &pt : l->points) { - if (light_options.visapprox.value() == visapprox_t::VIS) { - l->leaves.push_back(Light_PointInLeaf(bsp, pt)); - } else if (light_options.visapprox.value() == visapprox_t::RAYS) { + for (auto &pt : l->points) { l->bounds += EstimateVisibleBoundsAtPoint(pt); } } diff --git a/light/ltface.cc b/light/ltface.cc index 4f1a9b02..b9393351 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -506,29 +506,37 @@ static const std::vector *Mod_LeafPvs(const mbsp_t *bsp, const mleaf_t static void CalcPvs(const mbsp_t *bsp, lightsurf_t *lightsurf) { - const int pvssize = DecompressedVisSize(bsp); - const mleaf_t *lastleaf = nullptr; - - // set defaults - lightsurf->pvs.clear(); - if (!bsp->dvis.bits.size()) { return; } + + const int pvssize = DecompressedVisSize(bsp); // set lightsurf->pvs uint8_t *pointpvs = (uint8_t *)alloca(pvssize); lightsurf->pvs.resize(pvssize); - for (auto &sample : lightsurf->samples) { - const mleaf_t *leaf = Light_PointInLeaf(bsp, sample.point); + if (lightsurf->modelinfo->isWorld()) { + size_t face_index = lightsurf->face - bsp->dfaces.data(); - /* most/all of the surface points are probably in the same leaf */ - if (leaf == lastleaf) - continue; + for (auto &leaf : bsp->dleafs) { + for (size_t surf = 0; surf < leaf.nummarksurfaces; surf++) { + if (bsp->dleaffaces[leaf.firstmarksurface + surf] == face_index) { + lightsurf->leaves.push_back(&leaf); + } + } + } + } else { + for (auto &sample : lightsurf->samples) { + const mleaf_t *leaf = Light_PointInLeaf(bsp, sample.point); - lastleaf = leaf; + if (std::find(lightsurf->leaves.begin(), lightsurf->leaves.end(), leaf) == lightsurf->leaves.end()) { + lightsurf->leaves.push_back(leaf); + } + } + } + for (auto &leaf : lightsurf->leaves) { /* copy the pvs for this leaf into pointpvs */ Mod_LeafPvs(bsp, leaf, pointpvs); @@ -547,6 +555,8 @@ static void CalcPvs(const mbsp_t *bsp, lightsurf_t *lightsurf) lightsurf->pvs[j] |= pointpvs[j]; } } + + lightsurf->leaves.shrink_to_fit(); } static std::unique_ptr Lightsurf_Init(const modelinfo_t *modelinfo, const settings::worldspawn_keys &cfg, @@ -1978,6 +1988,20 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf, return qv::gate(color, (float)bouncelight_gate); } +static bool +SurfaceLight_VisCull(const mbsp_t *bsp, const std::vector *pvs, const lightsurf_t *lightsurf_b) +{ + if (pvs && light_options.visapprox.value() == visapprox_t::VIS) { + for (auto &leaf : lightsurf_b->leaves) { + if (VisCullEntity(bsp, *pvs, leaf)) { + return true; + } + } + } + + return false; +} + static void // mxd LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t *lightmaps, std::optional bounce_depth, const float &standard_scale, const float &sky_scale, const float &hotspot_clamp) @@ -1999,17 +2023,14 @@ LightFace_SurfaceLight(const mbsp_t *bsp, lightsurf_t *lightsurf, lightmapdict_t continue; else if (SurfaceLight_SphereCull(&vpl, lightsurf, vpl_setting, surflight_gate, hotspot_clamp)) continue; + else if (SurfaceLight_VisCull(bsp, &lightsurf->pvs, surf_ptr)) + continue; raystream_occlusion_t &rs = occlusion_stream; rs.clearPushedRays(); for (int c = 0; c < vpl.points.size(); c++) { - if (light_options.visapprox.value() == visapprox_t::VIS && - VisCullEntity(bsp, lightsurf->pvs, vpl.leaves[c])) { - continue; - } - for (int i = 0; i < lightsurf->samples.size(); i++) { const auto &sample = lightsurf->samples[i]; @@ -2099,11 +2120,11 @@ LightPoint_SurfaceLight(const mbsp_t *bsp, const std::vector *pvs, rays for (const auto &surf : EmissiveLightSurfaces()) { const surfacelight_t &vpl = *surf->vpl; - for (int c = 0; c < vpl.points.size(); c++) { - if (light_options.visapprox.value() == visapprox_t::VIS && pvs && VisCullEntity(bsp, *pvs, vpl.leaves[c])) { - continue; - } + if (SurfaceLight_VisCull(bsp, pvs, surf)) { + continue; + } + for (int c = 0; c < vpl.points.size(); c++) { // 1 ray for (auto &vpl_settings : vpl.styles) { if (vpl_settings.bounce_level.has_value() != bounce) diff --git a/light/surflight.cc b/light/surflight.cc index 8878754e..cfc2a14f 100644 --- a/light/surflight.cc +++ b/light/surflight.cc @@ -23,7 +23,6 @@ See file, 'COPYING', for details. #include #include // for FixLightOnFace -#include // for Light_PointInLeaf #include #include @@ -172,12 +171,8 @@ static void MakeSurfaceLight(const mbsp_t *bsp, const settings::worldspawn_keys // Init bbox... if (light_options.visapprox.value() == visapprox_t::RAYS) { l->bounds = EstimateVisibleBoundsAtPoint(l->pos); - } - for (auto &pt : l->points) { - if (light_options.visapprox.value() == visapprox_t::VIS) { - l->leaves.push_back(Light_PointInLeaf(bsp, pt)); - } else if (light_options.visapprox.value() == visapprox_t::RAYS) { + for (auto &pt : l->points) { l->bounds += EstimateVisibleBoundsAtPoint(pt); } }