summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-12-09 10:35:53 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-12-09 10:35:53 +0100
commit3464b29a50c1718a298b7e48c5e9c0dd509f1bb1 (patch)
treec630535a27d3f047a43c22fa249fc33e07129cdc /src
parentb8b9e24acff21404943252f70ba137c7a8d0be72 (diff)
w
Diffstat (limited to 'src')
-rw-r--r--src/chunk-walls.cpp73
-rw-r--r--src/chunk.hpp5
-rw-r--r--src/wall-atlas.cpp28
-rw-r--r--src/wall-defs.hpp2
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 };