diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chunk-walls.cpp | 73 | ||||
-rw-r--r-- | src/chunk.hpp | 5 | ||||
-rw-r--r-- | src/wall-atlas.cpp | 28 | ||||
-rw-r--r-- | 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 <Corrade/Containers/ArrayViewStl.h> #include <Corrade/Containers/PairStl.h> #include <algorithm> +#include <ranges> 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<Group_ G, bool IsWest> constexpr std::array<Vector3, 4> make_wall_vertex_data(float depth); +template<Group_ G, bool IsWest> constexpr std::array<Vector3, 4> make_vertex_data(float depth); // ----------------------- // corner left -template<> quad constexpr make_wall_vertex_data<Group_::corner_L, false>(float) +template<> quad constexpr make_vertex_data<Group_::corner_L, false>(float) { constexpr float x_offset = (float)(unsigned)X; return {{ @@ -48,7 +52,7 @@ template<> quad constexpr make_wall_vertex_data<Group_::corner_L, false>(float) } // corner right -template<> quad constexpr make_wall_vertex_data<Group_::corner_R, true>(float) +template<> quad constexpr make_vertex_data<Group_::corner_R, true>(float) { constexpr float y_offset = TILE_SIZE.y() - (float)(unsigned)Y; return {{ @@ -60,7 +64,7 @@ template<> quad constexpr make_wall_vertex_data<Group_::corner_R, true>(float) } // wall north -template<> quad constexpr make_wall_vertex_data<Group_::wall, false>(float) +template<> quad constexpr make_vertex_data<Group_::wall, false>(float) { return {{ { X, -Y, Z }, @@ -71,7 +75,7 @@ template<> quad constexpr make_wall_vertex_data<Group_::wall, false>(float) } // wall west -template<> quad constexpr make_wall_vertex_data<Group_::wall, true>(float) +template<> quad constexpr make_vertex_data<Group_::wall, true>(float) { return {{ {-X, -Y, Z }, @@ -82,7 +86,7 @@ template<> quad constexpr make_wall_vertex_data<Group_::wall, true>(float) } // side north -template<> quad constexpr make_wall_vertex_data<Group_::side, false>(float depth) +template<> quad constexpr make_vertex_data<Group_::side, false>(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<Group_::side, false>(float depth } // side west -template<> quad constexpr make_wall_vertex_data<Group_::side, true>(float depth) +template<> quad constexpr make_vertex_data<Group_::side, true>(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<Group_::side, true>(float depth) } // top north -template<> quad constexpr make_wall_vertex_data<Group_::top, false>(float depth) +template<> quad constexpr make_vertex_data<Group_::top, false>(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<Group_::top, false>(float depth) } // top west -template<> quad constexpr make_wall_vertex_data<Group_::top, true>(float depth) +template<> quad constexpr make_vertex_data<Group_::top, true>(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<Group_::top, true>(float depth) }}; } +#define FM_WALL_MAKE_CASE(name) \ + case name: return make_vertex_data<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) + +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<Quads::indexes> 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<const uint_fast16_t> ids; + const ArrayView<const uint16_t> ids; const size_t size; }; struct topo_sort_data; @@ -134,8 +134,7 @@ private: std::array<std::shared_ptr<wall_atlas>, 2*TILE_COUNT> atlases; std::array<variant_t, 2*TILE_COUNT> variants; - std::array<uint_fast16_t, max_wall_mesh_size> mesh_indexes; - uint32_t mesh_quad_count = 0; + std::array<uint16_t, max_wall_mesh_size> mesh_indexes; }; Pointer<ground_stuff> _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 <utility> #include <Corrade/Containers/ArrayViewStl.h> @@ -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 }; |