Porytiles
Loading...
Searching...
No Matches
tile_converters.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4
11
12namespace porytiles2 {
13
14namespace details {
15
32template <SupportsTransparency PixelType, typename TransparencyPredicate>
34 const PixelTile<PixelType> &pixel_tile,
35 const ColorIndexMap<PixelType> &color_index_map,
36 TransparencyPredicate is_transparent_pred)
37{
38 // Map from color index to ShapeMask
39 std::map<ColorIndex, ShapeMask> index_to_mask;
40
41 // Iterate through all pixels
42 for (std::size_t row = 0; row < tile::side_length_pix; ++row) {
43 for (std::size_t col = 0; col < tile::side_length_pix; ++col) {
44 const auto pixel = pixel_tile.at(row, col);
45
46 // Skip transparent pixels
47 if (is_transparent_pred(pixel)) {
48 continue;
49 }
50
51 // Look up the color index
52 auto index_opt = color_index_map.index_at_color(pixel);
53 if (!index_opt) {
54 panic("Pixel not found in ColorIndexMap");
55 }
56
57 const ColorIndex &index = *index_opt;
58
59 // Create mask if it doesn't exist
60 if (index_to_mask.find(index) == index_to_mask.end()) {
61 index_to_mask[index] = ShapeMask{};
62 }
63
64 // Set the bit for this position
65 index_to_mask[index].set(row, col);
66 }
67 }
68
69 // Build the result ShapeTile
71 for (const auto &[index, mask] : index_to_mask) {
72 result.set(mask, index);
73 }
74
75 return result;
76}
77
78} // namespace details
79
104template <SupportsTransparency PixelType>
105[[nodiscard]] ShapeTile<ColorIndex>
106from_pixel_tile(const PixelTile<PixelType> &pixel_tile, const ColorIndexMap<PixelType> &color_index_map)
107 requires requires(const PixelType &p) { p.is_transparent(); }
108{
110 pixel_tile, color_index_map, [](const PixelType &p) { return p.is_transparent(); });
111}
112
139template <SupportsTransparency PixelType>
141 const PixelTile<PixelType> &pixel_tile, const ColorIndexMap<PixelType> &color_index_map, const PixelType &extrinsic)
142 requires requires(const PixelType &p) { p.is_transparent(p); }
143{
145 pixel_tile, color_index_map, [&extrinsic](const PixelType &p) { return p.is_transparent(extrinsic); });
146}
147
171template <SupportsTransparency PixelType>
172[[nodiscard]] PixelTile<PixelType>
173from_shape_tile(const ShapeTile<ColorIndex> &shape_tile, const ColorIndexMap<PixelType> &color_index_map)
174{
175 // Start with a default (transparent) PixelTile
177
178 // Track which pixels have been set to detect overlaps
179 std::array<bool, tile::size_pix> pixel_set{};
180
181 // Iterate through each (ShapeMask, ColorIndex) pair
182 for (const auto &[mask, index] : shape_tile.colors()) {
183 // Look up the actual color from the ColorIndexMap
184 auto color_opt = color_index_map.color_at_index(index);
185 if (!color_opt) {
186 panic("ColorIndex not found in ColorIndexMap");
187 }
188
189 const PixelType &color = *color_opt;
190
191 // Set all pixels marked by this ShapeMask
192 for (std::size_t row = 0; row < tile::side_length_pix; ++row) {
193 for (std::size_t col = 0; col < tile::side_length_pix; ++col) {
194 if (mask.get(row, col)) {
195 std::size_t pixel_index = row * tile::side_length_pix + col;
196
197 // Check for overlap
198 if (pixel_set[pixel_index]) {
199 panic("Overlapping masks detected in ShapeTile - programmer error");
200 }
201
202 result.set(row, col, color);
203 pixel_set[pixel_index] = true;
204 }
205 }
206 }
207 }
208
209 return result;
210}
211
234template <SupportsTransparency PixelType>
235[[nodiscard]] ShapeTile<PixelType>
237{
239
240 // Iterate through each (ShapeMask, ColorIndex) pair
241 for (const auto &[mask, index] : shape_tile.colors()) {
242 // Look up the actual color from the ColorIndexMap
243 auto color_opt = color_index_map.color_at_index(index);
244 if (!color_opt) {
245 panic("ColorIndex not found in ColorIndexMap");
246 }
247
248 const PixelType &color = *color_opt;
249
250 // Set the mask with the pixel color in the result
251 result.set(mask, color);
252 }
253
254 return result;
255}
256
257} // namespace porytiles2
A bidirectional mapping between pixel color values and sequential integer indices.
std::optional< PixelType > color_at_index(ColorIndex index) const
Retrieves the color associated with a given index.
std::optional< ColorIndex > index_at_color(const PixelType &color) const
Retrieves the index associated with a given color.
Represents a color index value for palette operations.
An 8x8 tile backed by literal-array-based per-pixel storage of an arbitrary pixel type.
void set(std::size_t i, const PixelType &p)
PixelType at(std::size_t i) const
Represents which pixels in an 8x8 tile are non-transparent.
void set(int row, int col)
Sets the bit at the specified row and column to 1.
An 8x8 tile backed by mask-based storage that maps shape regions to pixel values.
const std::map< ShapeMask, PixelType > & colors() const
Returns the internal map of shape masks to pixel values.
bool is_transparent() const
Checks if this entire ShapeTile is transparent.
void set(const ShapeMask &mask, const PixelType &color)
Sets or updates the pixel value for a specific shape mask.
ShapeTile< ColorIndex > from_pixel_tile_impl(const PixelTile< PixelType > &pixel_tile, const ColorIndexMap< PixelType > &color_index_map, TransparencyPredicate is_transparent_pred)
Helper function implementing the core PixelTile to ShapeTile conversion logic.
constexpr std::size_t side_length_pix
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
Definition panic.hpp:53
PixelTile< PixelType > from_shape_tile(const ShapeTile< ColorIndex > &shape_tile, const ColorIndexMap< PixelType > &color_index_map)
Converts a ShapeTile<ColorIndex> to a PixelTile using a ColorIndexMap.
ShapeTile< ColorIndex > from_pixel_tile(const PixelTile< PixelType > &pixel_tile, const ColorIndexMap< PixelType > &color_index_map)
Converts a PixelTile to a ShapeTile<ColorIndex> using a ColorIndexMap (intrinsic transparency).
ShapeTile< PixelType > shape_tile_to_pixel_colors(const ShapeTile< ColorIndex > &shape_tile, const ColorIndexMap< PixelType > &color_index_map)
Converts a ShapeTile<ColorIndex> to a ShapeTile<PixelType> using a ColorIndexMap.