From 3464b29a50c1718a298b7e48c5e9c0dd509f1bb1 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 9 Dec 2023 10:35:53 +0100 Subject: w --- src/chunk-walls.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++--------- src/chunk.hpp | 5 ++-- src/wall-atlas.cpp | 28 +++++++++++++++++--- src/wall-defs.hpp | 2 +- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp index f11242ac..1fe7685f 100644 --- a/src/chunk-walls.cpp +++ b/src/chunk-walls.cpp @@ -6,9 +6,12 @@ #include #include #include +#include namespace floormat { +namespace ranges = std::ranges; + void chunk::ensure_alloc_walls() { if (!_walls) [[unlikely]] @@ -30,13 +33,14 @@ constexpr float X = half_tile.x(), Y = half_tile.y(), Z = TILE_SIZE.z(); using namespace floormat::Quads; using Wall::Group_; +using Wall::Direction_; -template constexpr std::array make_wall_vertex_data(float depth); +template constexpr std::array make_vertex_data(float depth); // ----------------------- // corner left -template<> quad constexpr make_wall_vertex_data(float) +template<> quad constexpr make_vertex_data(float) { constexpr float x_offset = (float)(unsigned)X; return {{ @@ -48,7 +52,7 @@ template<> quad constexpr make_wall_vertex_data(float) } // corner right -template<> quad constexpr make_wall_vertex_data(float) +template<> quad constexpr make_vertex_data(float) { constexpr float y_offset = TILE_SIZE.y() - (float)(unsigned)Y; return {{ @@ -60,7 +64,7 @@ template<> quad constexpr make_wall_vertex_data(float) } // wall north -template<> quad constexpr make_wall_vertex_data(float) +template<> quad constexpr make_vertex_data(float) { return {{ { X, -Y, Z }, @@ -71,7 +75,7 @@ template<> quad constexpr make_wall_vertex_data(float) } // wall west -template<> quad constexpr make_wall_vertex_data(float) +template<> quad constexpr make_vertex_data(float) { return {{ {-X, -Y, Z }, @@ -82,7 +86,7 @@ template<> quad constexpr make_wall_vertex_data(float) } // side north -template<> quad constexpr make_wall_vertex_data(float depth) +template<> quad constexpr make_vertex_data(float depth) { auto left = Vector2{X, -Y }, right = Vector2{left.x(), left.y() - depth }; @@ -95,7 +99,7 @@ template<> quad constexpr make_wall_vertex_data(float depth } // side west -template<> quad constexpr make_wall_vertex_data(float depth) +template<> quad constexpr make_vertex_data(float depth) { auto right = Vector2{ -X, Y }; auto left = Vector2{ right.x() - depth, right.y() }; @@ -108,7 +112,7 @@ template<> quad constexpr make_wall_vertex_data(float depth) } // top north -template<> quad constexpr make_wall_vertex_data(float depth) +template<> quad constexpr make_vertex_data(float depth) { auto top_right = Vector2{X, Y - depth }, bottom_right = Vector2{top_right.x(), Y }, @@ -123,7 +127,7 @@ template<> quad constexpr make_wall_vertex_data(float depth) } // top west -template<> quad constexpr make_wall_vertex_data(float depth) +template<> quad constexpr make_vertex_data(float depth) { auto top_right = Vector2{-X, -Y }, top_left = Vector2{top_right.x() - depth, top_right.y() }, @@ -138,6 +142,44 @@ template<> quad constexpr make_wall_vertex_data(float depth) }}; } +#define FM_WALL_MAKE_CASE(name) \ + case name: return make_vertex_data(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) + +quad get_vertex_data(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(); + } + } +} + // ----------------------- Array make_indexes_() @@ -169,25 +211,32 @@ GL::Mesh chunk::make_wall_mesh(size_t count) for (auto k = 0uz; k < count; k++) { - const uint_fast16_t i = _walls->mesh_indexes[k]; + const auto i = _walls->mesh_indexes[k]; const auto& atlas = _walls->atlases[i]; fm_assert(atlas != nullptr); const auto variant = _walls->variants[i]; const local_coords pos{i / 2u}; const auto center = Vector3(pos) * TILE_SIZE; const auto& dir = atlas->calc_direction(i & 1 ? Wall::Direction_::W : Wall::Direction_::N); + for (auto [_, member, group] : Wall::Direction::groups) + { + const auto& G = dir.*member; + if (!G.is_defined) + continue; + + } // ... //const auto quad = i & 1 ? wall_quad_W(center, TILE_SIZE) : wall_quad_N(center, TILE_SIZE); const float depth = tile_shader::depth_value(pos, tile_shader::wall_depth_offset); //const auto texcoords = atlas->texcoords_for_id(variant); - auto& v = vertexes[k]; + auto& v = vertexes[N++]; for (auto j = 0uz; j < 4; j++) v[j] = { quad[j], texcoords[j], depth, }; } auto vertex_view = vertexes.prefix(N); - auto index_view = make_indexes(i); + auto index_view = make_indexes(N); //auto indexes = make_index_array<2>(count); //const auto vertex_view = ArrayView{&vertexes[0], count}; diff --git a/src/chunk.hpp b/src/chunk.hpp index 067b8811..b22ab5e9 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -79,7 +79,7 @@ struct chunk final }; struct wall_mesh_tuple final { GL::Mesh& mesh; - const ArrayView ids; + const ArrayView ids; const size_t size; }; struct topo_sort_data; @@ -134,8 +134,7 @@ private: std::array, 2*TILE_COUNT> atlases; std::array variants; - std::array mesh_indexes; - uint32_t mesh_quad_count = 0; + std::array mesh_indexes; }; Pointer _ground; diff --git a/src/wall-atlas.cpp b/src/wall-atlas.cpp index aff48c58..3767949a 100644 --- a/src/wall-atlas.cpp +++ b/src/wall-atlas.cpp @@ -1,6 +1,5 @@ #include "wall-atlas.hpp" -#include "compat/assert.hpp" -//#include "compat/exception.hpp" +#include "compat/exception.hpp" #include "src/tile-defs.hpp" #include #include @@ -45,6 +44,27 @@ wall_atlas::wall_atlas(wall_atlas_def def, String path, const ImageView2D& img) _info{std::move(def.header)}, _path{std::move(path)}, _direction_map{def.direction_map} { + { + bool found = false; + for (auto [_, dir] : wall_atlas::directions) + { + const auto* D = direction((size_t)dir); + if (!D) + continue; + for (auto [_, gmemb, gr] : Direction::groups) + { + const auto& G = group(dir, gr); + if (!G->is_defined) + continue; + found = true; + if (G->count == 0) [[unlikely]] + fm_throw("wall_atlas '{}' defined group {}/{} has no frames!"_cf, _path, (int)dir, (int)gr); + } + } + if (!found) [[unlikely]] + fm_throw("wall_atlas '{}' is empty!"_cf, _path); + } + _texture.setLabel(_path) .setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Nearest) @@ -80,7 +100,7 @@ auto wall_atlas::group(size_t dir, Group_ gr) const -> const Group* { return gro auto wall_atlas::group(size_t dir, size_t group) const -> const Group* { - fm_assert((Group_)group < Group_::COUNT); + fm_assert(group < (size_t)Group_::COUNT); const auto* const set_ = direction(dir); if (!set_) return {}; @@ -158,7 +178,7 @@ Group& Direction::group(Group_ i) { return group((size_t)i); } Group& Direction::group(size_t i) { - fm_assert(i < (size_t)Group_::COUNT); + fm_assert(i < Group_COUNT); auto ptr = groups[i].member; return this->*ptr; } diff --git a/src/wall-defs.hpp b/src/wall-defs.hpp index 26f3df4f..0f33ae4c 100644 --- a/src/wall-defs.hpp +++ b/src/wall-defs.hpp @@ -3,7 +3,7 @@ namespace floormat::Wall { -enum class Group_ : uint8_t { corner_L, corner_R, wall, side, top, COUNT }; +enum class Group_ : uint8_t { wall, side, top, corner_L, corner_R, COUNT }; enum class Direction_ : uint8_t { N, W, COUNT }; -- cgit v1.2.3