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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#pragma once
#include "compat/defs.hpp"
#include "src/rotation.hpp"
#include <array>
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/String.h>
#include <Magnum/Math/Vector2.h>
#include <Magnum/Math/Color.h>
#include <Magnum/GL/Texture.h>
namespace floormat { class wall_atlas; }
namespace floormat::Wall {
struct Frame
{
Vector2ui offset = { (unsigned)-1, (unsigned)-1 };
bool operator==(const Frame&) const noexcept;
};
struct Group
{
uint32_t index = (uint32_t)-1, count = 0;
Vector2ui pixel_size;
Color4 tint_mult{1,1,1,1};
Color3 tint_add;
uint8_t from_rotation = (uint8_t)-1; // applies only to images
bool mirrored : 1 = false,
default_tint : 1 = true;
explicit operator bool() const noexcept { return !is_empty(); }
bool is_empty() const noexcept { return count == 0; }
bool operator==(const Group&) const noexcept;
};
enum class Tag : uint8_t { wall, overlay, side, top, corner_L, corner_R, COUNT };
enum class Direction_ : uint8_t { N, E, S, W, COUNT };
struct Direction
{
using memfn_ptr = Group Direction::*;
struct member_tuple { StringView str; memfn_ptr member; Tag tag; };
explicit operator bool() const noexcept { return !is_empty(); }
bool is_empty() const noexcept;
Group wall, overlay, side, top;
Group corner_L, corner_R;
static constexpr inline member_tuple members[] = {
{ "wall"_s, &Direction::wall, Tag::wall },
{ "overlay"_s, &Direction::overlay, Tag::overlay },
{ "side"_s, &Direction::side, Tag::side },
{ "top"_s, &Direction::top, Tag::top },
{ "corner-L"_s, &Direction::corner_L, Tag::corner_L, },
{ "corner-R"_s, &Direction::corner_R, Tag::corner_R, },
};
static_assert(arraySize(members) == (size_t)Tag::COUNT);
bool operator==(const Direction&) const noexcept;
};
struct Info
{
String name = "(unnamed)"_s, description = {};
unsigned depth = 0;
bool operator==(const Info&) const noexcept;
};
struct DirArrayIndex {
std::uint8_t val = (uint8_t)-1;
operator bool() const { return val == (uint8_t)-1; }
bool operator==(const DirArrayIndex&) const noexcept;
};
} // namespace floormat::Wall
namespace floormat {
class wall_atlas final
{
using Frame = Wall::Frame;
using Group = Wall::Group;
using Direction_ = Wall::Direction_;
using Direction = Wall::Direction;
using Info = Wall::Info;
using Tag = Wall::Tag;
using DirArrayIndex = Wall::DirArrayIndex;
Array<Direction> _dir_array;
Array<Frame> _frame_array;
Info _info;
GL::Texture2D _texture;
std::array<DirArrayIndex, 4> _direction_to_Direction_array_index;
Direction* get_Direction(Direction_ num) const;
public:
fm_DECLARE_DELETED_MOVE_ASSIGNMENT(wall_atlas);
wall_atlas() noexcept;
~wall_atlas() noexcept;
wall_atlas(Info info, const ImageView2D& image,
Array<Frame> frames, Array<Direction> directions,
std::array<DirArrayIndex, 4> direction_to_DirArrayIndex);
StringView name() const;
uint8_t direction_count() const;
const Group* group(size_t dir, Tag tag) const;
const Group* group(const Direction& dir, Tag tag) const;
const Group* group(const Direction* dir, Tag tag) const;
const Direction* direction(size_t dir) const;
ArrayView<const Frame> frames(const Group& a) const;
ArrayView<const Frame> raw_frame_array() const;
static size_t enum_to_index(enum rotation x);
};
} // namespace floormat
|