diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-05 19:32:03 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-11-05 19:32:03 +0100 |
commit | 141ecedcacda8fa094a22da067fe24423f0d6f38 (patch) | |
tree | 67a8241c1bcd4d9788e93d472859ee15b496300b | |
parent | 11f27ee84b255ee5a3f9d72832f5bfef261d2378 (diff) |
wip
-rw-r--r-- | external/CMakeLists.txt | 1 | ||||
-rw-r--r-- | serialize/anim.hpp | 6 | ||||
-rw-r--r-- | src/anim-atlas.cpp | 76 | ||||
-rw-r--r-- | src/anim-atlas.hpp | 30 | ||||
-rw-r--r-- | src/chunk.hpp | 1 | ||||
-rw-r--r-- | src/scenery.hpp | 15 |
6 files changed, 113 insertions, 16 deletions
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index f08fe35d..aeab7d0b 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -34,6 +34,7 @@ if(FLOORMAT_SUBMODULE-DEPENDENCIES) add_definitions( -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS -DIMGUI_DISABLE_OBSOLETE_KEYIO + -DJSON_HAS_THREE_WAY_COMPARISON=1 ) sets(STRING SDL_ASSERTIONS release diff --git a/serialize/anim.hpp b/serialize/anim.hpp index 74b418a8..286bc56f 100644 --- a/serialize/anim.hpp +++ b/serialize/anim.hpp @@ -9,7 +9,7 @@ namespace floormat::Serialize { struct anim_frame final { - Vector2i ground, offset, size; + Vector2ui ground, offset, size; }; enum class anim_direction : unsigned char @@ -31,10 +31,8 @@ struct anim final String object_name, anim_name; std::vector<anim_group> groups; - int nframes = 0; - int width = 0, height = 0; - int actionframe = -1, fps = default_fps; Vector2ui pixel_size; + std::size_t nframes = 0, width = 0, height = 0, fps = default_fps, actionframe = 0; }; } // namespace floormat::Serialize 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 |