From a2399ab48c9f3cdc5924b8fbb8e23d06c98e5c5b Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 8 Jan 2023 13:46:49 -0700 Subject: [PATCH] tests: add dirt / object_channel_mask interaction test was already working correctly --- common/bsputils.cc | 5 ++ testmaps/q2_light_group_dirt.map | 123 +++++++++++++++++++++++++++++++ tests/test_ltface.cc | 38 ++++++++++ 3 files changed, 166 insertions(+) create mode 100644 testmaps/q2_light_group_dirt.map diff --git a/common/bsputils.cc b/common/bsputils.cc index 9b31fcc0..c18cfbe0 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -925,6 +925,11 @@ qvec3f faceextents_t::LMCoordToWorld(qvec2f lm) const */ qvec3b LM_Sample(const mbsp_t *bsp, const std::vector *lit, const faceextents_t &faceextents, int byte_offset_of_face, qvec2i coord) { + Q_assert(coord[0] >= 0); + Q_assert(coord[1] >= 0); + Q_assert(coord[0] < faceextents.width()); + Q_assert(coord[1] < faceextents.height()); + int pixel = coord[0] + (coord[1] * faceextents.width()); assert(byte_offset_of_face >= 0); diff --git a/testmaps/q2_light_group_dirt.map b/testmaps/q2_light_group_dirt.map new file mode 100644 index 00000000..0f60d203 --- /dev/null +++ b/testmaps/q2_light_group_dirt.map @@ -0,0 +1,123 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +"_bounce" "0" +"_minlight" "0.5" +"_minlightMottle" "0" +"_dirt" "1" +"_minlight_dirt" "1" +// 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 +( 1440 1472 944 ) ( 1440 1472 945 ) ( 1440 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 +( 1440 1472 1264 ) ( 1440 1472 1265 ) ( 1440 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 +( 1456 1456 944 ) ( 1456 1456 945 ) ( 1456 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 +( 1440 1392 928 ) ( 1440 1392 929 ) ( 1440 1393 928 ) e1u1/twall2_1 -48 32 0 1 1 +} +// brush 4 +{ +( 1440 1088 1056 ) ( 1440 1089 1056 ) ( 1440 1088 1057 ) e1u1/twall2_1 0 32 0 1 1 +( 1120 1088 1056 ) ( 1120 1088 1057 ) ( 1121 1088 1056 ) e1u1/twall2_1 96 32 0 1 1 +( 1120 1088 928 ) ( 1121 1088 928 ) ( 1120 1089 928 ) e1u1/twall2_1 96 0 0 1 1 +( 1360 1472 1248 ) ( 1360 1473 1248 ) ( 1361 1472 1248 ) e1u1/twall2_1 96 0 0 1 1 +( 1360 1488 1072 ) ( 1361 1488 1072 ) ( 1360 1488 1073 ) e1u1/twall2_1 96 32 0 1 1 +( 1456 1472 1072 ) ( 1456 1472 1073 ) ( 1456 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 +} +// brush 6 +{ +( 1196 1232 944 ) ( 1196 1233 944 ) ( 1196 1232 945 ) e1u1/twall2_1 -16 0 0 1 1 +( 1196 1232 944 ) ( 1196 1232 945 ) ( 1197 1232 944 ) e1u1/twall2_1 -60 0 0 1 1 +( 1196 1232 944 ) ( 1197 1232 944 ) ( 1196 1233 944 ) e1u1/twall2_1 -60 16 0 1 1 +( 1212 1312 1072 ) ( 1212 1313 1072 ) ( 1213 1312 1072 ) e1u1/twall2_1 -60 16 0 1 1 +( 1212 1328 960 ) ( 1213 1328 960 ) ( 1212 1328 961 ) e1u1/twall2_1 -60 0 0 1 1 +( 1212 1312 960 ) ( 1212 1312 961 ) ( 1212 1313 960 ) e1u1/twall2_1 -16 0 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "1232 1160 968" +"angle" "90" +} +// entity 2 +{ +"classname" "func_wall" +"_object_channel_mask" "16" +"_minlight" "0.5" +// brush 0 +{ +( 1216 1232 944 ) ( 1216 1233 944 ) ( 1216 1232 945 ) e1u1/twall2_1 -16 0 0 1 1 +( 1216 1232 944 ) ( 1216 1232 945 ) ( 1217 1232 944 ) e1u1/twall2_1 48 0 0 1 1 +( 1216 1232 944 ) ( 1217 1232 944 ) ( 1216 1233 944 ) e1u1/twall2_1 48 16 0 1 1 +( 1232 1328 1072 ) ( 1232 1329 1072 ) ( 1233 1328 1072 ) e1u1/twall2_1 48 16 0 1 1 +( 1232 1328 960 ) ( 1233 1328 960 ) ( 1232 1328 961 ) e1u1/twall2_1 48 0 0 1 1 +( 1232 1328 960 ) ( 1232 1328 961 ) ( 1232 1329 960 ) e1u1/twall2_1 -16 0 0 1 1 +} +// brush 1 +{ +( 1232 1232 944 ) ( 1232 1233 944 ) ( 1232 1232 945 ) e1u1/twall2_1 -16 0 0 1 1 +( 1232 1312 944 ) ( 1232 1312 945 ) ( 1233 1312 944 ) e1u1/twall2_1 32 0 0 1 1 +( 1232 1232 944 ) ( 1233 1232 944 ) ( 1232 1233 944 ) e1u1/twall2_1 32 16 0 1 1 +( 1248 1328 1072 ) ( 1248 1329 1072 ) ( 1249 1328 1072 ) e1u1/twall2_1 32 16 0 1 1 +( 1248 1328 960 ) ( 1249 1328 960 ) ( 1248 1328 961 ) e1u1/twall2_1 32 0 0 1 1 +( 1296 1328 960 ) ( 1296 1328 961 ) ( 1296 1329 960 ) e1u1/twall2_1 -16 0 0 1 1 +} +// brush 2 +{ +( 1232 1296 944 ) ( 1232 1297 944 ) ( 1232 1296 945 ) e1u1/twall2_1 -16 0 0 1 1 +( 1232 1296 944 ) ( 1232 1296 945 ) ( 1233 1296 944 ) e1u1/twall2_1 -48 0 0 1 1 +( 1232 1296 944 ) ( 1233 1296 944 ) ( 1232 1297 944 ) e1u1/twall2_1 -48 16 0 1 1 +( 1248 1312 960 ) ( 1248 1313 960 ) ( 1249 1312 960 ) e1u1/twall2_1 -48 16 0 1 1 +( 1248 1312 960 ) ( 1249 1312 960 ) ( 1248 1312 961 ) e1u1/twall2_1 -48 0 0 1 1 +( 1296 1312 960 ) ( 1296 1312 961 ) ( 1296 1313 960 ) e1u1/twall2_1 -16 0 0 1 1 +} +// brush 3 +{ +( 1232 1296 1056 ) ( 1232 1297 1056 ) ( 1232 1296 1057 ) e1u1/twall2_1 -16 0 0 1 1 +( 1232 1232 1056 ) ( 1232 1232 1057 ) ( 1233 1232 1056 ) e1u1/twall2_1 -48 0 0 1 1 +( 1232 1296 1056 ) ( 1233 1296 1056 ) ( 1232 1297 1056 ) e1u1/twall2_1 -48 16 0 1 1 +( 1248 1312 1072 ) ( 1248 1313 1072 ) ( 1249 1312 1072 ) e1u1/twall2_1 -48 16 0 1 1 +( 1248 1312 1072 ) ( 1249 1312 1072 ) ( 1248 1312 1073 ) e1u1/twall2_1 -48 0 0 1 1 +( 1296 1312 1072 ) ( 1296 1312 1073 ) ( 1296 1313 1072 ) e1u1/twall2_1 -16 0 0 1 1 +} +} diff --git a/tests/test_ltface.cc b/tests/test_ltface.cc index 84f9ae15..cc72c1a0 100644 --- a/tests/test_ltface.cc +++ b/tests/test_ltface.cc @@ -206,6 +206,8 @@ TEST_CASE("-novanilla + -world_units_per_luxel") template static void CheckFaceLuxels(const mbsp_t &bsp, const mface_t &face, L&& lambda, const std::vector* lit = nullptr) { + // FIXME: assumes no DECOUPLED_LM lump + const faceextents_t extents(face, bsp, LMSCALE_DEFAULT); for (int x = 0; x < extents.width(); ++x) { @@ -224,6 +226,24 @@ static void CheckFaceLuxelsNonBlack(const mbsp_t &bsp, const mface_t &face) }); } +static void CheckFaceLuxelAtPoint(const mbsp_t *bsp, const dmodelh2_t *model, const qvec3b &expected_color, + const qvec3d &point, const qvec3d &normal = {0, 0, 0}) +{ + auto *face = BSP_FindFaceAtPoint(bsp, model, point, normal); + REQUIRE(face); + + // FIXME: assumes no DECOUPLED_LM lump + + const faceextents_t extents(*face, *bsp, LMSCALE_DEFAULT); + + const auto coord = extents.worldToLMCoord(point); + + const qvec3b sample = LM_Sample(bsp, nullptr, extents, face->lightofs, qvec2i(coord)); + INFO("sample ", coord[0], ", ", coord[1]); + + CHECK(sample == expected_color); +} + TEST_CASE("emissive lights") { auto [bsp, bspx] = QbspVisLight_Q2("q2_light_flush.map", {}); REQUIRE(bspx.empty()); @@ -442,6 +462,24 @@ TEST_CASE("light channel mask (_object_channel_mask, _light_channel_mask, _shado } } +TEST_CASE("light channel mask / dirt interaction") { + auto [bsp, bspx] = QbspVisLight_Q2("q2_light_group_dirt.map", {}); + + REQUIRE(2 == bsp.dmodels.size()); + + INFO("worldspawn has dirt in the corner"); + CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[0], {26,26,26}, {1432, 1480, 944}); + + INFO("worldspawn not receiving dirt from func_wall on different channel"); + CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[0], {62, 62, 62}, {1212, 1272, 1014}); + + INFO("func_wall on different channel not receiving dirt from worldspawn"); + CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[1], {64, 64, 64}, {1216, 1266, 1014}); + + INFO("func_wall on different channel is receiving dirt from itself"); + CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[1], {19, 19, 19}, {1236, 1308, 960}); +} + // FIXME: figure out why this is failing on CI only TEST_CASE("surface lights minlight" * doctest::may_fail()) { auto [bsp, bspx, lit] = QbspVisLight_Q1("q1_surflight_minlight.map", {});