diff --git a/common/bsputils.cc b/common/bsputils.cc index 4df7c3d1..28f6db7a 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -1085,10 +1085,23 @@ qvec3f faceextents_t::LMCoordToWorld(qvec2f lm) const } /** - * Samples the lightmap at an integer coordinate - * FIXME: this doesn't deal with styles at all + * Returns an offset, in samples, from the start of the face's lightmaps to the location of the given style data. + * Returns -1 if the face doesn't have lightmaps for that style. */ -qvec3b LM_Sample(const mbsp_t *bsp, const lit_variant_t *lit, const faceextents_t &faceextents, +static int StyleOffset(int style, const mface_t *face, const faceextents_t &faceextents) +{ + for (int i = 0; i < face->styles.size(); ++i) { + if (face->styles[i] == style) { + return i * faceextents.width() * faceextents.height(); + } + } + return -1; +} + +/** + * Samples the lightmap at an integer coordinate in style 0 + */ +qvec3b LM_Sample(const mbsp_t *bsp, const mface_t *face, const lit_variant_t *lit, const faceextents_t &faceextents, int byte_offset_of_face, qvec2i coord) { if (byte_offset_of_face == -1) { @@ -1100,7 +1113,12 @@ qvec3b LM_Sample(const mbsp_t *bsp, const lit_variant_t *lit, const faceextents_ Q_assert(coord[0] < faceextents.width()); Q_assert(coord[1] < faceextents.height()); - int pixel = coord[0] + (coord[1] * faceextents.width()); + int style_offset = StyleOffset(0, face, faceextents); + if (style_offset == -1) { + return {0, 0, 0}; + } + + int pixel = style_offset + coord[0] + (coord[1] * faceextents.width()); assert(byte_offset_of_face >= 0); @@ -1124,7 +1142,7 @@ qvec3b LM_Sample(const mbsp_t *bsp, const lit_variant_t *lit, const faceextents_ } } -qvec3f LM_Sample_HDR(const mbsp_t *bsp, +qvec3f LM_Sample_HDR(const mbsp_t *bsp, const mface_t *face, const faceextents_t &faceextents, int byte_offset_of_face, qvec2i coord, const lit_variant_t *lit, const bspxentries_t *bspx) @@ -1138,7 +1156,12 @@ qvec3f LM_Sample_HDR(const mbsp_t *bsp, Q_assert(coord[0] < faceextents.width()); Q_assert(coord[1] < faceextents.height()); - int pixel = coord[0] + (coord[1] * faceextents.width()); + int style_offset = StyleOffset(0, face, faceextents); + if (style_offset == -1) { + return {0, 0, 0}; + } + + int pixel = style_offset + coord[0] + (coord[1] * faceextents.width()); assert(byte_offset_of_face >= 0); diff --git a/include/common/bsputils.hh b/include/common/bsputils.hh index c2bdc33d..aeb9eafb 100644 --- a/include/common/bsputils.hh +++ b/include/common/bsputils.hh @@ -175,10 +175,11 @@ public: qvec3f LMCoordToWorld(qvec2f lm) const; }; -qvec3b LM_Sample(const mbsp_t *bsp, const lit_variant_t *lit, const faceextents_t &faceextents, +qvec3b LM_Sample(const mbsp_t *bsp, const mface_t *face, const lit_variant_t *lit, const faceextents_t &faceextents, int byte_offset_of_face, qvec2i coord); qvec3f LM_Sample_HDR(const mbsp_t *bsp, + const mface_t *face, const faceextents_t &faceextents, int byte_offset_of_face, qvec2i coord, const lit_variant_t *lit = nullptr, const bspxentries_t *bspx = nullptr); diff --git a/testmaps/q1_hdrtest.map b/testmaps/q1_hdrtest.map index 76e0ec4a..f919693c 100644 --- a/testmaps/q1_hdrtest.map +++ b/testmaps/q1_hdrtest.map @@ -63,7 +63,8 @@ // entity 1 { "classname" "info_player_start" -"origin" "-292 0 156" +"origin" "-292 0 72" +"angle" "90" } // entity 2 { @@ -73,3 +74,12 @@ "delay" "2" "_color" "0.75 0.65 0.44" } +// entity 3 +{ +"classname" "light" +"origin" "88 -176 260" +"light" "15" +"delay" "2" +"_color" "0 1 0.7" +"style" "5" +} diff --git a/tests/test_ltface.cc b/tests/test_ltface.cc index 85b746b8..ff11c219 100644 --- a/tests/test_ltface.cc +++ b/tests/test_ltface.cc @@ -252,7 +252,7 @@ TEST_CASE("emissive cube artifacts") auto lm_coord = extents.worldToLMCoord(pos); - auto sample = LM_Sample(&bsp, nullptr, extents, lm_info.offset, lm_coord); + auto sample = LM_Sample(&bsp, floor, nullptr, extents, lm_info.offset, lm_coord); CHECK(sample[0] >= previous_sample[0]); // logging::print("world: {} lm_coord: {} sample: {} lm size: {}x{}\n", pos, lm_coord, sample, lm_info.lmwidth, @@ -306,7 +306,7 @@ static void CheckFaceLuxels( for (int x = 0; x < extents.width(); ++x) { for (int y = 0; y < extents.height(); ++y) { - const qvec3b sample = LM_Sample(&bsp, lit, extents, face.lightofs, {x, y}); + const qvec3b sample = LM_Sample(&bsp, &face, lit, extents, face.lightofs, {x, y}); INFO("sample ", x, ", ", y); lambda(sample); } @@ -341,7 +341,7 @@ static void CheckFaceLuxelAtPoint(const mbsp_t *bsp, const dmodelh2_t *model, co const auto coord = extents.worldToLMCoord(point); const auto int_coord = qvec2i(round(coord[0]), round(coord[1])); - const qvec3b sample = LM_Sample(bsp, lit, extents, offset, int_coord); + const qvec3b sample = LM_Sample(bsp, face, lit, extents, offset, int_coord); INFO("world point: ", point); INFO("lm coord: ", coord[0], ", ", coord[1]); INFO("lm int_coord: ", int_coord[0], ", ", int_coord[1]); @@ -378,7 +378,7 @@ static void CheckFaceLuxelAtPoint_HDR(const mbsp_t *bsp, const dmodelh2_t *model const auto coord = extents.worldToLMCoord(point); const auto int_coord = qvec2i(round(coord[0]), round(coord[1])); - const qvec3f sample = LM_Sample_HDR(bsp, extents, offset, int_coord, lit, bspx); + const qvec3f sample = LM_Sample_HDR(bsp, face, extents, offset, int_coord, lit, bspx); INFO("world point: ", point); INFO("lm coord: ", coord[0], ", ", coord[1]); INFO("lm int_coord: ", int_coord[0], ", ", int_coord[1]);