summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/anim-atlas.cpp76
-rw-r--r--src/anim-atlas.hpp30
-rw-r--r--src/chunk.hpp1
-rw-r--r--src/scenery.hpp15
4 files changed, 110 insertions, 12 deletions
diff --git a/src/anim-atlas.cpp b/src/anim-atlas.cpp
new file mode 100644
index 00000000..2e4361df
--- /dev/null
+++ b/src/anim-atlas.cpp
@@ -0,0 +1,76 @@
+#include "anim-atlas.hpp"
+#include <Corrade/Containers/StringStlView.h>
+
+namespace floormat {
+
+static constexpr std::array<char[3], (std::size_t)rotation::COUNT> name_array = {
+ "n", "ne", "e", "se", "s", "sw", "w", "nw",
+};
+
+std::uint8_t anim_atlas::rotation_to_index(const anim_info& info, rotation r) noexcept
+{
+ StringView str = name_array[std::size_t(r)];
+ for (std::size_t sz = info.groups.size(), i = 0; i < sz; i++)
+ {
+ const anim_group& g = info.groups[i];
+ if (g.name == str)
+ return std::uint8_t(i);
+ }
+ return 0xff;
+}
+
+decltype(anim_atlas::_group_indices) anim_atlas::make_group_indices(const anim_info& a) noexcept
+{
+ std::array<std::uint8_t, (std::size_t)rotation::COUNT> array;
+ for (std::size_t i = 0; i < array.size(); i++)
+ array[i] = rotation_to_index(a, rotation(i));
+ return array;
+}
+
+anim_atlas::anim_atlas() noexcept = default;
+anim_atlas::anim_atlas(StringView name, GL::Texture2D&& tex, Vector2ui pixel_size, anim_info info) noexcept :
+ _tex{std::move(tex)}, _name{name}, _pixel_size{pixel_size},
+ _info{std::move(info)}, _group_indices{make_group_indices(_info)}
+{
+}
+
+anim_atlas::~anim_atlas() noexcept = default;
+anim_atlas::anim_atlas(anim_atlas&&) noexcept = default;
+anim_atlas& anim_atlas::operator=(anim_atlas&&) noexcept = default;
+
+StringView anim_atlas::name() const noexcept { return _name; }
+GL::Texture2D& anim_atlas::texture() noexcept { return _tex; }
+const Serialize::anim& anim_atlas::info() const noexcept { return _info; }
+
+auto anim_atlas::group(rotation r) const noexcept -> const anim_group&
+{
+ const auto group_idx = _group_indices[std::size_t(r)];
+ fm_assert(group_idx != 0xff);
+ return _info.groups[group_idx];
+}
+
+auto anim_atlas::frame(rotation r, std::size_t frame) const noexcept -> const anim_frame&
+{
+ const anim_group& g = group(r);
+ fm_assert(frame < g.frames.size());
+ return g.frames[frame];
+}
+
+auto anim_atlas::frame_texcoords(rotation r, std::size_t idx) const noexcept -> texcoords
+{
+ return frame_texcoords(frame(r, idx));
+}
+
+auto anim_atlas::frame_texcoords(const anim_frame& frame) const noexcept -> texcoords
+{
+ const Vector2 p0(frame.offset), p1(frame.offset + frame.size);
+ const auto x0 = p0.x()+.5f, x1 = p1.x()-1, y0 = p0.y()+.5f, y1 = p1.y()-1;
+ return {{
+ { (x0+x1) / _pixel_size[0], (y0+y1) / _pixel_size[1] }, // bottom right
+ { (x0+x1) / _pixel_size[0], y0 / _pixel_size[1] }, // top right
+ { x0 / _pixel_size[0], (y0+y1) / _pixel_size[1] }, // bottom left
+ { x0 / _pixel_size[0], y0 / _pixel_size[1] }, // top left
+ }};
+}
+
+} // namespace floormat
diff --git a/src/anim-atlas.hpp b/src/anim-atlas.hpp
index 186715ab..4c7140d9 100644
--- a/src/anim-atlas.hpp
+++ b/src/anim-atlas.hpp
@@ -1,30 +1,50 @@
#pragma once
#include "compat/defs.hpp"
+#include "scenery.hpp"
#include "serialize/anim.hpp"
+#include <array>
#include <Corrade/Containers/String.h>
+#include <Magnum/Math/Vector2.h>
#include <Magnum/GL/Texture.h>
-
namespace floormat {
struct anim_atlas final
{
- anim_atlas();
- anim_atlas(StringView name, GL::Texture2D&& tex, Serialize::anim metadata) noexcept;
+ using anim_info = Serialize::anim;
+ using anim_group = Serialize::anim_group;
+ using anim_frame = Serialize::anim_frame;
+ using texcoords = std::array<Vector2, 4>;
+
+ anim_atlas() noexcept;
+ anim_atlas(StringView name, GL::Texture2D&& tex, Vector2ui pixel_size, anim_info info) noexcept;
~anim_atlas() noexcept;
anim_atlas(anim_atlas&&) noexcept;
anim_atlas& operator=(anim_atlas&&) noexcept;
StringView name() const noexcept;
- GL::Texture2D texture() noexcept;
+ GL::Texture2D& texture() noexcept;
+ const anim_info& info() const noexcept;
+
+ const anim_group& group(rotation r) const noexcept;
+ const anim_frame& frame(rotation r, std::size_t frame) const noexcept;
+ texcoords frame_texcoords(rotation r, std::size_t frame) const noexcept;
+ texcoords frame_texcoords(const anim_frame& frame) const noexcept;
fm_DECLARE_DELETED_COPY_ASSIGNMENT(anim_atlas);
private:
GL::Texture2D _tex;
String _name;
- Serialize::anim _anim;
+ Vector2ui _pixel_size;
+ anim_info _info;
+ std::array<std::uint8_t, (std::size_t)rotation::COUNT> _group_indices = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+
+ static decltype(_group_indices) make_group_indices(const Serialize::anim& anim) noexcept;
+ static std::uint8_t rotation_to_index(const anim_info& a, rotation r) noexcept;
};
} // namespace floormat
diff --git a/src/chunk.hpp b/src/chunk.hpp
index 5472130d..7967484c 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -42,7 +42,6 @@ private:
std::array<std::shared_ptr<tile_atlas>, TILE_COUNT> _ground_atlases, _wall_north_atlases, _wall_west_atlases;
std::array<std::shared_ptr<anim_atlas>, TILE_COUNT> _scenery;
std::array<variant_t, TILE_COUNT> _ground_variants = {}, _wall_north_variants = {}, _wall_west_variants = {};
- std::array<
std::bitset<TILE_COUNT*2> _passability = {};
mutable bool _maybe_empty = true;
};
diff --git a/src/scenery.hpp b/src/scenery.hpp
index 4e362070..731b999b 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -4,16 +4,19 @@
namespace floormat {
-struct anim_atlas;
+enum class rotation : std::uint16_t {
+ N, NE, E, SE, S, SW, W, NW,
+ COUNT,
+};
struct scenery final
{
- enum class rotation : std::uint16_t {
- N, NE, E, SE, S, SW, W, NW,
- };
+ using frame_t = std::uint16_t;
- rotation r : 3 = rotation::N;
- std::uint16_t frame : 13 = 0;
+ frame_t frame : 13 = 0;
+ rotation r : 3 = rotation::N;
};
+static_assert(sizeof(scenery) == sizeof(std::uint16_t));
+
} // namespace floormat