From 96c7658b80b85612239fec53ab5464f863e31822 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 7 Feb 2023 00:56:27 -0700 Subject: [PATCH] light: nudge lightgrid points if stuck in solid --- include/light/entities.hh | 1 + light/entities.cc | 19 +++++++++++-------- light/light.cc | 9 +++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/include/light/entities.hh b/include/light/entities.hh index 4142cdde..e98ff5f2 100644 --- a/include/light/entities.hh +++ b/include/light/entities.hh @@ -149,3 +149,4 @@ aabb3d EstimateVisibleBoundsAtPoint(const qvec3d &point); bool EntDict_CheckNoEmptyValues(const mbsp_t *bsp, const entdict_t &entdict); entdict_t &WorldEnt(); +std::tuple FixLightOnFace(const mbsp_t *bsp, const qvec3d &point, bool warn = true, float max_dist = 2.f); diff --git a/light/entities.cc b/light/entities.cc index 5326614e..a8e50f02 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -1018,11 +1018,11 @@ void LoadEntities(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) logging::print("{} entities read, {} are lights.\n", entdicts.size(), all_lights.size()); } -static qvec3d FixLightOnFace(const mbsp_t *bsp, const qvec3d &point) +std::tuple FixLightOnFace(const mbsp_t *bsp, const qvec3d &point, bool warn, float max_dist) { // FIXME: Check all shadow casters if (!Light_PointInWorld(bsp, point)) { - return point; + return {point, true}; } for (int i = 0; i < 6; i++) { @@ -1030,24 +1030,27 @@ static qvec3d FixLightOnFace(const mbsp_t *bsp, const qvec3d &point) int axis = i / 2; bool add = i % 2; - testpoint[axis] += (add ? 2 : -2); // sample points are 1 unit off faces. so nudge by 2 units, so the lights are - // above the sample points + // sample points are 1 unit off faces. so nudge by 2 units, so the lights are + // above the sample points + testpoint[axis] += (add ? max_dist : -max_dist); // FIXME: Check all shadow casters if (!Light_PointInWorld(bsp, testpoint)) { - return testpoint; + return {testpoint, true}; } } - logging::print("WARNING: couldn't nudge light out of solid at {}\n", point); - return point; + if (warn) + logging::print("WARNING: couldn't nudge light out of solid at {}\n", point); + return {point, false}; } void FixLightsOnFaces(const mbsp_t *bsp) { for (auto &entity : all_lights) { if (entity->light.value() != 0 && !entity->nonudge.value()) { - entity->origin.setValue(FixLightOnFace(bsp, entity->origin.value()), settings::source::MAP); + auto [fixed_pos, success] = FixLightOnFace(bsp, entity->origin.value()); + entity->origin.setValue(fixed_pos, settings::source::MAP); } } } diff --git a/light/light.cc b/light/light.cc index ade81cd0..959a9def 100644 --- a/light/light.cc +++ b/light/light.cc @@ -1079,6 +1079,15 @@ static void LightGrid(bspdata_t *bspdata) qvec3d world_point = grid_mins + (qvec3d{x,y,z} * light_options.lightgrid_dist.value()); bool occluded = Light_PointInWorld(&bsp, world_point); + if (occluded) { + // search for a nearby point + auto [fixed_pos, success] = FixLightOnFace(&bsp, world_point, false, 2.0f); + if (success) { + occluded = false; + world_point = fixed_pos; + } + } + lightgrid_samples_t samples; if (!occluded)