diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-12-10 14:31:34 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-12-10 14:31:34 +0100 |
commit | 0a1df3ff5a6d8cc8d652477d98af666616ecc737 (patch) | |
tree | d75d067efb2d26a0e42f8132e271fbd9f809a922 /src | |
parent | 1f90adeb8c09911a1a826453e213dccac906405b (diff) |
w
Diffstat (limited to 'src')
-rw-r--r-- | src/chunk-walls.cpp | 257 | ||||
-rw-r--r-- | src/wall-atlas.hpp | 2 |
2 files changed, 110 insertions, 149 deletions
diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp index 743bfb9d..2ad7a8a7 100644 --- a/src/chunk-walls.cpp +++ b/src/chunk-walls.cpp @@ -5,6 +5,7 @@ #include "shaders/shader.hpp" #include <Corrade/Containers/ArrayViewStl.h> #include <Corrade/Containers/PairStl.h> +#include <utility> #include <algorithm> #include <ranges> @@ -39,155 +40,111 @@ using Wall::Direction_; #pragma clang diagnostic ignored "-Wundefined-internal" #endif -template<Group_ G, bool IsWest> constexpr quad get_quad(float depth); constexpr quad get_quad(Direction_ D, Group_ G, float depth); // ----------------------- -// corner left -template<> quad constexpr get_quad<Group_::corner_L, false>(float) -{ - constexpr float x_offset = (float)(unsigned)X; - return {{ - { -X + x_offset, -Y, Z }, - { -X + x_offset, -Y, 0 }, - { -X, -Y, Z }, - { -X, -Y, 0 }, - }}; -} - -// corner right -template<> quad constexpr get_quad<Group_::corner_R, true>(float) -{ - constexpr float y_offset = TILE_SIZE.y() - (float)(unsigned)Y; - return {{ - {-X, -Y, Z }, - {-X, -Y, 0 }, - {-X, -Y + y_offset, Z }, - {-X, -Y + y_offset, 0 }, - }}; -} - -// wall north -template<> quad constexpr get_quad<Group_::wall, false>(float) -{ - return {{ - { X, -Y, Z }, - { X, -Y, 0 }, - {-X, -Y, Z }, - {-X, -Y, 0 }, - }}; -} - -// wall west -template<> quad constexpr get_quad<Group_::wall, true>(float) -{ - return {{ - {-X, -Y, Z }, - {-X, -Y, 0 }, - {-X, Y, Z }, - {-X, Y, 0 }, - }}; -} - -// side north -template<> quad constexpr get_quad<Group_::side, false>(float depth) -{ - auto left = Vector2{X, -Y }, - right = Vector2{left.x(), left.y() - depth }; - return {{ - { right.x(), right.y(), Z }, - { right.x(), right.y(), 0 }, - { left.x(), left.y(), Z }, - { left.x(), left.y(), 0 }, - }}; -} - -// side west -template<> quad constexpr get_quad<Group_::side, true>(float depth) +constexpr quad get_quad(Direction_ D, Group_ G, float depth) { - auto right = Vector2{ -X, Y }; - auto left = Vector2{ right.x() - depth, right.y() }; - return {{ - { right.x(), right.y(), Z }, - { right.x(), right.y(), 0 }, - { left.x(), left.y(), Z }, - { left.x(), left.y(), 0 }, - }}; -} + CORRADE_ASSUME(D < Direction_::COUNT); + CORRADE_ASSUME(G < Group_::COUNT); -// top north -template<> quad constexpr get_quad<Group_::top, false>(float depth) -{ - auto top_right = Vector2{X, Y - depth }, - bottom_right = Vector2{top_right.x(), Y }, - top_left = Vector2{-X, top_right.y() }, - bottom_left = Vector2{top_left.x(), bottom_right.y() }; - return {{ - { top_right.x(), top_right.y(), Z }, // br tr - { top_left.x(), top_left.y(), Z }, // tr tl - { bottom_right.x(), bottom_right.y(), Z }, // bl br - { bottom_left.x(), bottom_left.y(), Z }, // tl bl - }}; -} + const bool is_west = D == Wall::Direction_::W; -// top west -template<> quad constexpr get_quad<Group_::top, true>(float depth) -{ - auto top_right = Vector2{-X, -Y }, - top_left = Vector2{top_right.x() - depth, top_right.y() }, - bottom_right = Vector2{top_right.x(), Y }, - bottom_left = Vector2{top_left.x(), bottom_right.y() }; - - return {{ - { bottom_right.x(), bottom_right.y(), Z }, - { top_right.x(), top_right.y(), Z }, - { bottom_left.x(), bottom_left.y(), Z }, - { top_left.x(), top_left.y(), Z }, - }}; + switch (G) + { + using enum Group_; + case COUNT: + std::unreachable(); + case wall: + if (!is_west) + return {{ + { X, -Y, Z }, + { X, -Y, 0 }, + {-X, -Y, Z }, + {-X, -Y, 0 }, + }}; + else + return {{ + {-X, -Y, Z }, + {-X, -Y, 0 }, + {-X, Y, Z }, + {-X, Y, 0 }, + }}; + case corner_L: { + constexpr float x_offset = (float)(unsigned)X; + return {{ + { -X + x_offset, -Y, Z }, + { -X + x_offset, -Y, 0 }, + { -X, -Y, Z }, + { -X, -Y, 0 }, + }}; + } + case corner_R: { + constexpr float y_offset = TILE_SIZE.y() - (float)(unsigned)Y; + return {{ + {-X, -Y, Z }, + {-X, -Y, 0 }, + {-X, -Y + y_offset, Z }, + {-X, -Y + y_offset, 0 }, + }}; + } + case side: + if (!is_west) + { + auto left = Vector2{X, -Y }, + right = Vector2{left.x(), left.y() - depth }; + return {{ + { right.x(), right.y(), Z }, + { right.x(), right.y(), 0 }, + { left.x(), left.y(), Z }, + { left.x(), left.y(), 0 }, + }}; + } + else + { + auto right = Vector2{ -X, Y }; + auto left = Vector2{ right.x() - depth, right.y() }; + return {{ + { right.x(), right.y(), Z }, + { right.x(), right.y(), 0 }, + { left.x(), left.y(), Z }, + { left.x(), left.y(), 0 }, + }}; + } + case top: + if (!is_west) + { + auto top_right = Vector2{X, Y - depth }, + bottom_right = Vector2{top_right.x(), Y }, + top_left = Vector2{-X, top_right.y() }, + bottom_left = Vector2{top_left.x(), bottom_right.y() }; + return {{ + { top_right.x(), top_right.y(), Z }, // br tr + { top_left.x(), top_left.y(), Z }, // tr tl + { bottom_right.x(), bottom_right.y(), Z }, // bl br + { bottom_left.x(), bottom_left.y(), Z }, // tl bl + }}; + } + else + { + auto top_right = Vector2{-X, -Y }, + top_left = Vector2{top_right.x() - depth, top_right.y() }, + bottom_right = Vector2{top_right.x(), Y }, + bottom_left = Vector2{top_left.x(), bottom_right.y() }; + return {{ + { bottom_right.x(), bottom_right.y(), Z }, + { top_right.x(), top_right.y(), Z }, + { bottom_left.x(), bottom_left.y(), Z }, + { top_left.x(), top_left.y(), Z }, + }}; + } + } } // ----------------------- -#define FM_WALL_MAKE_CASE(name) \ - case name: return get_quad<name, IsWest>(depth) - -#define FM_WALL_MAKE_CASES() \ - do { \ - switch (G) \ - { \ - FM_WALL_MAKE_CASE(Group_::wall); \ - FM_WALL_MAKE_CASE(Group_::side); \ - FM_WALL_MAKE_CASE(Group_::top); \ - FM_WALL_MAKE_CASE(Group_::corner_L); \ - FM_WALL_MAKE_CASE(Group_::corner_R); \ - case Group_::COUNT: \ - fm_abort("invalid wall group '%d'", (int)G); \ - } \ - } while (false) -constexpr quad get_quad(Direction_ D, Group_ G, float depth) -{ - CORRADE_ASSUME(G < Group_::COUNT); - CORRADE_ASSUME(D < Direction_::COUNT); - - switch (D) - { - case Direction_::COUNT: - fm_abort("invalid wall direction '%d'", (int)D); - case Direction_::N: { - constexpr auto IsWest = false; - FM_WALL_MAKE_CASES(); - break; - } - case Direction_::W: { - constexpr auto IsWest = true; - FM_WALL_MAKE_CASES(); - } - } -} -#undef FM_WALL_MAKE_CASES -#undef FM_WALL_MAKE_CASE Array<Quads::indexes> make_indexes_() { @@ -222,24 +179,28 @@ constexpr auto depth_offset_for_group(Group_ G) GL::Mesh chunk::make_wall_mesh() { fm_debug_assert(_walls); - //std::array<std::array<vertex, 4>, TILE_COUNT*2> vertexes; - //vertex vertexes[TILE_COUNT*2][4]; uint32_t N = 0; static auto vertexes = Array<std::array<vertex, 4>>{NoInit, max_wall_quad_count }; for (uint32_t k = 0; k < 2*TILE_COUNT; k++) { + const auto D = k & 1 ? Wall::Direction_::W : Wall::Direction_::N; const auto& atlas = _walls->atlases[k]; fm_assert(atlas != nullptr); const auto variant = _walls->variants[k]; const auto pos = local_coords{k / 2u}; const auto center = Vector3(pos) * TILE_SIZE; - const auto D = k & 1 ? Wall::Direction_::W : Wall::Direction_::N; const auto& dir = atlas->calc_direction(D); + for (auto [_, member, G] : Wall::Direction::groups) { CORRADE_ASSUME(G < Group_::COUNT); + + if (G == Group_::corner_L && D != Direction_::N || + G == Group_::corner_R && D != Direction_::W) [[unlikely]] + continue; + const auto& group = dir.*member; if (!group.is_defined) continue; @@ -248,10 +209,11 @@ GL::Mesh chunk::make_wall_mesh() for (auto& v : quad) v += center; - fm_debug_assert(N + quad.size() <= max_wall_quad_count); const auto i = N++; + fm_debug_assert(i < max_wall_quad_count); _walls->mesh_indexes[i] = (uint16_t)k; - const auto& frame = atlas->frames(group)[variant]; + const auto frames = atlas->frames(group); + const auto& frame = frames[variant]; const auto texcoords = Quads::texcoords_at(frame.offset, frame.size, atlas->image_size()); const auto depth = tile_shader::depth_value(pos, depth_offset); auto& v = vertexes[i]; @@ -260,12 +222,11 @@ GL::Mesh chunk::make_wall_mesh() } } - const auto* __restrict const atlases = _walls->atlases.data(); - ranges::sort(ranges::zip_view(vertexes, _walls->mesh_indexes), [=](const auto& a, const auto& b) { - const auto& [a_v, a_i] = a; - const auto& [b_v, b_i] = b; - return atlases[a_i].get() < atlases[b_i].get(); - }); + const auto comp = [&atlases = _walls->atlases](const auto& a, const auto& b) { + return atlases[a.second] < atlases[b.second]; + }; + + ranges::sort(ranges::zip_view(vertexes, _walls->mesh_indexes), comp); auto vertex_view = std::as_const(vertexes).prefix(N); auto index_view = make_indexes(N); diff --git a/src/wall-atlas.hpp b/src/wall-atlas.hpp index 515f60e1..6ace0f7c 100644 --- a/src/wall-atlas.hpp +++ b/src/wall-atlas.hpp @@ -44,7 +44,6 @@ struct Direction Group wall{}, overlay{}, side{}, top{}; Group corner_L{}, corner_R{}; - pass_mode passability = pass_mode::blocked; const Group& group(Group_ i) const; const Group& group(size_t i) const; @@ -67,6 +66,7 @@ struct Info { String name; unsigned depth = 0; + pass_mode passability = pass_mode::blocked; bool operator==(const Info&) const noexcept; }; |