summaryrefslogtreecommitdiffhomepage
path: root/src/anim-atlas.cpp
blob: 2e4361dfeedf24efbfaaa9f28d8a2443b83d5b0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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