summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-09 16:08:34 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-09 16:08:34 +0100
commit03bce5306284e7a3fa5d0a6f158d4e91c5b61cf8 (patch)
tree13de11f57c1f10ce027c5f7b1ca2dd5a4bc598ed
parente72eb0b1d3149288d2a5291722c3ba68bb567a84 (diff)
w
-rw-r--r--compat/map.hpp8
-rw-r--r--src/chunk-walls.cpp84
-rw-r--r--test/map.cpp6
3 files changed, 68 insertions, 30 deletions
diff --git a/compat/map.hpp b/compat/map.hpp
index 9bcceadb..3c1610d4 100644
--- a/compat/map.hpp
+++ b/compat/map.hpp
@@ -9,7 +9,7 @@ namespace floormat::detail::map {
template<typename T, typename F, size_t N, size_t... Indexes>
CORRADE_ALWAYS_INLINE
-constexpr auto map0(const std::array<T, N>& array, const F& fun, std::index_sequence<Indexes...>)
+constexpr auto map0(const F& fun, const std::array<T, N>& array, std::index_sequence<Indexes...>)
{
return std::array { fun(array[Indexes])... };
}
@@ -17,7 +17,7 @@ constexpr auto map0(const std::array<T, N>& array, const F& fun, std::index_sequ
template<typename T, typename F>
[[deprecated("zero-length array!")]]
CORRADE_ALWAYS_INLINE
-constexpr auto map0(const std::array<T, 0>&, const F&, std::index_sequence<>)
+constexpr auto map0(const F&, const std::array<T, 0>&, std::index_sequence<>)
{
return std::array<std::decay_t<std::invoke_result_t<std::decay_t<F>, const std::remove_cvref_t<T>&>>, 0>{};
}
@@ -27,14 +27,14 @@ constexpr auto map0(const std::array<T, 0>&, const F&, std::index_sequence<>)
namespace floormat {
template<typename T, std::invocable<const T&> F, size_t N>
-constexpr auto map(const std::array<T, N>& array, const F& fun)
+constexpr auto map(const F& fun, const std::array<T, N>& array)
{
using return_type = std::decay_t<decltype( fun(array[0]) )>;
static_assert(!std::is_same_v<return_type, void>);
static_assert(std::is_same_v<T, std::decay_t<T>>);
static_assert(sizeof(return_type) > 0);
using ::floormat::detail::map::map0;
- return map0(array, fun, std::make_index_sequence<N>{});
+ return map0(fun, array, std::make_index_sequence<N>{});
}
} // namespace floormat
diff --git a/src/chunk-walls.cpp b/src/chunk-walls.cpp
index 9e808b41..eca7a29f 100644
--- a/src/chunk-walls.cpp
+++ b/src/chunk-walls.cpp
@@ -156,6 +156,7 @@ constexpr auto depth_offset_for_group(Group_ G)
{
default:
return tile_shader::wall_depth_offset;
+ case Wall::Group_::corner:
case Wall::Group_::side:
return tile_shader::wall_side_offset;
// // todo
@@ -191,7 +192,7 @@ GL::Mesh chunk::make_wall_mesh()
{
CORRADE_ASSUME(G < Group_::COUNT);
- bool corner_ok = false;
+ bool corner_ok = false, pillar_ok = false;
if (!(dir.*member).is_defined)
continue;
@@ -203,13 +204,20 @@ GL::Mesh chunk::make_wall_mesh()
default:
break;
case Wall::Group_::side:
- if (auto t2 = at_offset_(pos, {1, 0}); t2 && t2->wall_west_atlas())
- continue;
- else if (auto t2 = at_offset_(pos, {1, -1}); t2 && t2->wall_west_atlas())
- continue;
- else if (auto t2 = at_offset_(pos, {-1, 0}); t2 && !t2->wall_north_atlas())
- if (auto t2 = at_offset_(pos, {0, -1}); t2 && t2->wall_west_atlas())
- corner_ok = true;
+ if (_walls->atlases[k+1]) // west on same tile
+ if (auto t2 = at_offset_(pos, {-1, 0}); !t2 || !t2->wall_north_atlas())
+ if (auto t2 = at_offset_(pos, {0, -1}); !t2 || !t2->wall_west_atlas())
+ pillar_ok = true;
+ if (!pillar_ok) [[likely]]
+ {
+ if (auto t2 = at_offset_(pos, {1, 0}); t2 && t2->wall_west_atlas())
+ continue;
+ else if (auto t2 = at_offset_(pos, {1, -1}); t2 && t2->wall_west_atlas())
+ continue;
+ else if (auto t2 = at_offset_(pos, {-1, 0}); !t2 || !t2->wall_north_atlas())
+ if (auto t2 = at_offset_(pos, {0, -1}); t2 && t2->wall_west_atlas())
+ corner_ok = true;
+ }
break;
}
}
@@ -224,36 +232,65 @@ GL::Mesh chunk::make_wall_mesh()
continue;
else if (auto t2 = at_offset_(pos, {-1, 1}); t2 && t2->wall_north_atlas())
continue;
- else if (auto t2 = at_offset_(pos, {0, -1}); t2 && !t2->wall_west_atlas())
+ else if (auto t2 = at_offset_(pos, {0, -1}); !t2 || !t2->wall_west_atlas())
if (auto t2 = at_offset_(pos, {-1, 0}); t2 && t2->wall_north_atlas())
corner_ok = true;
break;
}
}
- const auto depth_offset = depth_offset_for_group(G);
auto quad = get_quad(D, G, Depth);
for (auto& v : quad)
v += center;
- if (corner_ok)
+ if (pillar_ok)
+ {
+ if (dir.top.is_defined)
+ {
+ const auto frames = atlas->frames(dir.top);
+ auto variant = (variant_ != (uint8_t)-1 ? variant_ : vpos);
+ variant += !is_west ? frames.size() - 1 : 1;
+ variant = variant % frames.size();
+ constexpr Vector2 half_tile = TILE_SIZE2*.5f;
+ constexpr float X = half_tile.x(), Y = half_tile.y(), Z = TILE_SIZE.z();
+ Quads::quad quad = {{
+ { -X - Depth, -Y - Depth, Z },
+ { -X, -Y - Depth, Z },
+ { -X - Depth, -Y, Z },
+ { -X, -Y, Z }
+ }};
+ const auto& frame = frames[variant];
+ fm_assert(frame.size.x() == Depth);
+ fm_assert(frame.size.y() >= Depth);
+ auto start = frame.offset + Vector2ui{0, frame.size.y()} - Vector2ui{0, Depth};
+ const auto texcoords = Quads::texcoords_at(start, Vector2ui{Depth, Depth}, atlas->image_size());
+ const auto i = N++;
+ fm_assert(i < vertexes.size());
+ _walls->mesh_indexes[i] = (uint16_t)k;
+ const auto depth_offset = depth_offset_for_group(Group_::top);
+ const auto depth = tile_shader::depth_value(pos, depth_offset);
+ auto& v = vertexes[i];
+ for (auto& v : quad)
+ v += center;
+ for (uint8_t j = 0; j < 4; j++)
+ v[j] = { quad[j], texcoords[j], depth };
+ }
+ }
+ else if (corner_ok)
{
if (dir.corner.is_defined)
{
const auto frames = atlas->frames(dir.corner);
auto variant = (variant_ != (uint8_t)-1 ? variant_ : vpos);
- variant += frames.size();
- if (!is_west)
- variant -= 1;
- else
- variant += 1;
- variant %= frames.size();
+ variant += !is_west ? frames.size() - 1 : 1;
+ variant = variant % frames.size();
const auto& frame = frames[variant];
const auto texcoords = Quads::texcoords_at(frame.offset, frame.size, atlas->image_size());
const auto i = N++;
+ fm_assert(i < vertexes.size());
_walls->mesh_indexes[i] = (uint16_t)k;
+ const auto depth_offset = depth_offset_for_group(Group_::corner);
const auto depth = tile_shader::depth_value(pos, depth_offset);
- fm_debug_assert(i < vertexes.size());
auto& v = vertexes[i];
auto quad = get_quad(D, Group_::corner, Depth);
for (auto& v : quad)
@@ -265,16 +302,17 @@ GL::Mesh chunk::make_wall_mesh()
{
const auto frames = atlas->frames(dir.wall);
auto variant = (variant_ != (uint8_t)-1 ? variant_ : vpos);
- variant += frames.size() - 1;
+ variant += !is_west ? frames.size() - 1 : 1;
variant %= frames.size();
const auto& frame = frames[variant];
fm_assert(frame.size.x() > Depth);
- auto start = frame.offset + Vector2ui(frame.size.x(), 0) - Vector2ui{Depth, 0};
+ auto start = frame.offset + Vector2ui{frame.size.x(), 0} - Vector2ui{Depth, 0};
const auto texcoords = Quads::texcoords_at(start, {Depth, frame.size.y()}, atlas->image_size());
const auto i = N++;
+ fm_assert(i < vertexes.size());
_walls->mesh_indexes[i] = (uint16_t)k;
+ const auto depth_offset = depth_offset_for_group(Group_::corner);
const auto depth = tile_shader::depth_value(pos, depth_offset);
- fm_debug_assert(i < vertexes.size());
auto& v = vertexes[i];
auto quad = get_corner(D, G, Depth);
for (auto& v : quad)
@@ -288,14 +326,14 @@ GL::Mesh chunk::make_wall_mesh()
const auto frames = atlas->frames(group);
const auto i = N++;
- fm_debug_assert(i < max_wall_quad_count);
+ fm_assert(i < vertexes.size());
_walls->mesh_indexes[i] = (uint16_t)k;
const auto variant = (variant_ != (uint8_t)-1 ? variant_ : vpos) % frames.size();
const auto& frame = frames[variant];
const auto texcoords = Quads::texcoords_at(frame.offset, frame.size, atlas->image_size());
+ const auto depth_offset = depth_offset_for_group(G);
const auto depth = tile_shader::depth_value(pos, depth_offset);
- fm_debug_assert(i < vertexes.size());
auto& v = vertexes[i];
for (uint8_t j = 0; j < 4; j++)
v[j] = { quad[j], texcoords[j], depth };
diff --git a/test/map.cpp b/test/map.cpp
index 62860b22..69c9942c 100644
--- a/test/map.cpp
+++ b/test/map.cpp
@@ -12,9 +12,9 @@ namespace {
constexpr bool test1()
{
constexpr auto array = std::array{0, 1, 2, 3, 4};
- auto array2 = map(array, [](int x) constexpr {
+ auto array2 = map([](int x) constexpr {
return (unsigned)(x - 1);
- });
+ }, array);
constexpr auto array3 = std::array{(unsigned)-1, 0u, 1u, 2u, 3u};
fm_assert(array2.size() == array.size());
fm_assert(array3.size() == array.size());
@@ -25,7 +25,7 @@ constexpr bool test1()
constexpr bool test2()
{
- fm_assert(map(std::array<int, 0>{}, [](int x) constexpr { return x;}).size() == 0);
+ fm_assert(map([](int x) constexpr { return x; }, std::array<int, 0>{}).size() == 0);
return true;
}