From 63cac32f8871ffdbea95feca5078b85dfb048044 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 11 Dec 2022 15:36:08 -0700 Subject: [PATCH] light: quick experiment with a _light_group feature for lights that only affect linked bmodels --- include/light/entities.hh | 1 + include/light/light.hh | 1 + light/entities.cc | 3 +- light/light.cc | 3 +- light/ltface.cc | 6 +++ testmaps/q2_light_group.map | 91 +++++++++++++++++++++++++++++++++++++ tests/test_ltface.cc | 26 +++++++++++ 7 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 testmaps/q2_light_group.map diff --git a/include/light/entities.hh b/include/light/entities.hh index 6b9cfac2..4406760a 100644 --- a/include/light/entities.hh +++ b/include/light/entities.hh @@ -99,6 +99,7 @@ public: settings::setting_string suntexture; settings::setting_bool nostaticlight; settings::setting_int32 surflight_group; + settings::setting_string light_group; light_t(); diff --git a/include/light/light.hh b/include/light/light.hh index 8238355e..cfa75867 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -219,6 +219,7 @@ public: settings::setting_color minlight_color; settings::setting_bool lightignore; settings::setting_scalar lightcolorscale; + settings::setting_string light_group; float getResolvedPhongAngle() const; bool isWorld() const; diff --git a/light/entities.cc b/light/entities.cc index 1b5ce08c..06523425 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -105,7 +105,8 @@ light_t::light_t() : project_texture{this, "project_texture", ""}, suntexture{this, "suntexture", ""}, nostaticlight{this, "nostaticlight", false}, - surflight_group{this, "surflight_group", 0} + surflight_group{this, "surflight_group", 0}, + light_group{this, "light_group", ""} {} std::string light_t::classname() const diff --git a/light/light.cc b/light/light.cc index 3a0bd5ba..b2a6e3dc 100644 --- a/light/light.cc +++ b/light/light.cc @@ -137,7 +137,8 @@ modelinfo_t::modelinfo_t(const mbsp_t *b, const dmodelh2_t *m, float lmscale) : alpha{this, "alpha", 1.0}, minlight_color{this, {"minlight_color", "mincolor"}, 255.0, 255.0, 255.0}, lightignore{this, "lightignore", false}, - lightcolorscale{this, "lightcolorscale", 1} + lightcolorscale{this, "lightcolorscale", 1}, + light_group{this, "light_group", ""} {} namespace settings diff --git a/light/ltface.cc b/light/ltface.cc index 1277b16a..91430f4a 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1229,6 +1229,12 @@ static void LightFace_Entity( return; } + if (!entity->light_group.value().empty()) { + if (entity->light_group.value() != lightsurf->modelinfo->light_group.value()) { + return; + } + } + /* * Check it for real */ diff --git a/testmaps/q2_light_group.map b/testmaps/q2_light_group.map new file mode 100644 index 00000000..a813ee3f --- /dev/null +++ b/testmaps/q2_light_group.map @@ -0,0 +1,91 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +"_bounce" "0" +"_minlight" "0.5" +"_minlightMottle" "0" +// brush 0 +{ +( 480 1088 928 ) ( 480 1089 928 ) ( 480 1088 929 ) e1u1/twall2_1 0 32 0 1 1 +( 704 1088 928 ) ( 704 1088 929 ) ( 705 1088 928 ) e1u1/twall2_1 0 32 0 1 1 +( 704 1088 928 ) ( 705 1088 928 ) ( 704 1089 928 ) e1u1/twall2_1 0 0 0 1 1 +( 944 1472 944 ) ( 944 1473 944 ) ( 945 1472 944 ) e1u1/twall2_1 0 0 0 1 1 +( 944 1488 944 ) ( 945 1488 944 ) ( 944 1488 945 ) e1u1/twall2_1 0 32 0 1 1 +( 1056 1472 944 ) ( 1056 1472 945 ) ( 1056 1473 944 ) e1u1/twall2_1 0 32 0 1 1 +} +// brush 1 +{ +( 480 1088 1248 ) ( 480 1089 1248 ) ( 480 1088 1249 ) e1u1/twall2_1 0 96 0 1 1 +( 704 1072 1248 ) ( 704 1072 1249 ) ( 705 1072 1248 ) e1u1/twall2_1 0 96 0 1 1 +( 704 1088 1248 ) ( 705 1088 1248 ) ( 704 1089 1248 ) e1u1/twall2_1 0 0 0 1 1 +( 944 1472 1264 ) ( 944 1473 1264 ) ( 945 1472 1264 ) e1u1/twall2_1 0 0 0 1 1 +( 944 1488 1264 ) ( 945 1488 1264 ) ( 944 1488 1265 ) e1u1/twall2_1 0 96 0 1 1 +( 1056 1472 1264 ) ( 1056 1472 1265 ) ( 1056 1473 1264 ) e1u1/twall2_1 0 96 0 1 1 +} +// brush 2 +{ +( 480 1072 928 ) ( 480 1073 928 ) ( 480 1072 929 ) e1u1/twall2_1 16 32 0 1 1 +( 704 1072 928 ) ( 704 1072 929 ) ( 705 1072 928 ) e1u1/twall2_1 0 32 0 1 1 +( 704 1072 928 ) ( 705 1072 928 ) ( 704 1073 928 ) e1u1/twall2_1 0 -16 0 1 1 +( 944 1456 1248 ) ( 944 1457 1248 ) ( 945 1456 1248 ) e1u1/twall2_1 0 -16 0 1 1 +( 944 1088 944 ) ( 945 1088 944 ) ( 944 1088 945 ) e1u1/twall2_1 0 32 0 1 1 +( 1056 1456 944 ) ( 1056 1456 945 ) ( 1056 1457 944 ) e1u1/twall2_1 16 32 0 1 1 +} +// brush 3 +{ +( 480 1392 928 ) ( 480 1393 928 ) ( 480 1392 929 ) e1u1/twall2_1 -48 32 0 1 1 +( 832 1488 928 ) ( 832 1488 929 ) ( 833 1488 928 ) e1u1/twall2_1 -128 32 0 1 1 +( 832 1392 928 ) ( 833 1392 928 ) ( 832 1393 928 ) e1u1/twall2_1 -128 48 0 1 1 +( 1072 1776 1248 ) ( 1072 1777 1248 ) ( 1073 1776 1248 ) e1u1/twall2_1 -128 48 0 1 1 +( 1072 1504 944 ) ( 1073 1504 944 ) ( 1072 1504 945 ) e1u1/twall2_1 -128 32 0 1 1 +( 1056 1392 928 ) ( 1056 1392 929 ) ( 1056 1393 928 ) e1u1/twall2_1 -48 32 0 1 1 +} +// brush 4 +{ +( 1056 1088 1056 ) ( 1056 1089 1056 ) ( 1056 1088 1057 ) e1u1/twall2_1 0 32 0 1 1 +( 736 1088 1056 ) ( 736 1088 1057 ) ( 737 1088 1056 ) e1u1/twall2_1 -32 32 0 1 1 +( 736 1088 928 ) ( 737 1088 928 ) ( 736 1089 928 ) e1u1/twall2_1 -32 0 0 1 1 +( 976 1472 1248 ) ( 976 1473 1248 ) ( 977 1472 1248 ) e1u1/twall2_1 -32 0 0 1 1 +( 976 1488 1072 ) ( 977 1488 1072 ) ( 976 1488 1073 ) e1u1/twall2_1 -32 32 0 1 1 +( 1072 1472 1072 ) ( 1072 1472 1073 ) ( 1072 1473 1072 ) e1u1/twall2_1 0 32 0 1 1 +} +// brush 5 +{ +( 464 1088 1056 ) ( 464 1089 1056 ) ( 464 1088 1057 ) e1u1/twall2_1 0 32 0 1 1 +( 144 1072 1056 ) ( 144 1072 1057 ) ( 145 1072 1056 ) e1u1/twall2_1 48 32 0 1 1 +( 144 1088 928 ) ( 145 1088 928 ) ( 144 1089 928 ) e1u1/twall2_1 48 0 0 1 1 +( 384 1472 1248 ) ( 384 1473 1248 ) ( 385 1472 1248 ) e1u1/twall2_1 48 0 0 1 1 +( 384 1488 1072 ) ( 385 1488 1072 ) ( 384 1488 1073 ) e1u1/twall2_1 48 32 0 1 1 +( 480 1472 1072 ) ( 480 1472 1073 ) ( 480 1473 1072 ) e1u1/twall2_1 0 32 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "976 1408 968" +"angle" "180" +} +// entity 2 +{ +"classname" "light" +"origin" "680 1224 1000" +"light" "300" +"_light_group" "pillar" +} +// entity 3 +{ +"classname" "func_wall" +"_light_group" "pillar" +// brush 0 +{ +( 656 1248 944 ) ( 656 1249 944 ) ( 656 1248 945 ) e1u1/twall2_1 0 0 0 1 1 +( 656 1248 944 ) ( 656 1248 945 ) ( 657 1248 944 ) e1u1/twall2_1 0 0 0 1 1 +( 656 1248 944 ) ( 657 1248 944 ) ( 656 1249 944 ) e1u1/twall2_1 0 0 0 1 1 +( 704 1280 1040 ) ( 704 1281 1040 ) ( 705 1280 1040 ) e1u1/twall2_1 0 0 0 1 1 +( 704 1280 960 ) ( 705 1280 960 ) ( 704 1280 961 ) e1u1/twall2_1 0 0 0 1 1 +( 704 1280 960 ) ( 704 1280 961 ) ( 704 1281 960 ) e1u1/twall2_1 0 0 0 1 1 +} +} diff --git a/tests/test_ltface.cc b/tests/test_ltface.cc index f8223ce1..2fe6e00b 100644 --- a/tests/test_ltface.cc +++ b/tests/test_ltface.cc @@ -293,3 +293,29 @@ TEST_CASE("negative lights work") { } } } + +TEST_CASE("_light_group") { + auto [bsp, bspx] = LoadTestmap("q2_light_group.map", {}); + + { + INFO("world doesn't receive light from the light ent with '_light_group' 'pillar'"); + + auto *face_under_light = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {680, 1224, 944}); + REQUIRE(face_under_light); + + CheckFaceLuxels(bsp, *face_under_light, [](qvec3b sample) { + CHECK(sample == qvec3b(64)); + }); + } + + { + INFO("pillar with matching _light_group is receiving light"); + + auto *face_on_pillar = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[1], {680, 1248, 1000}); + REQUIRE(face_on_pillar); + + CheckFaceLuxels(bsp, *face_on_pillar, [](qvec3b sample) { + CHECK(sample[0] > 100); + }); + } +}