FastLED 3.9.15
Loading...
Searching...
No Matches
tile2x2.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/stdint.h"
4
5#include "fl/math/geometry.h"
6#include "fl/stl/pair.h"
7#include "fl/stl/span.h"
8#include "fl/math/xymap.h"
9#include "fl/stl/vector.h"
10#include "fl/stl/noexcept.h"
11
12namespace fl {
13
14class XYMap; // IWYU pragma: keep
16
18
19 public:
20 static void Rasterize(const span<const Tile2x2_u8> &tiles,
21 XYRasterU8Sparse *output);
22
24 Tile2x2_u8(const vec2<u16> &origin) : mOrigin(origin) {}
25 Tile2x2_u8(const Tile2x2_u8 &) FL_NOEXCEPT = default;
28
29 void scale(u8 scale);
30
31 void setOrigin(u16 x, u16 y) { mOrigin = vec2<u16>(x, y); }
32
33 u8 &operator()(int x, int y) { return at(x, y); }
34 u8 &at(int x, int y) { return mTile[y][x]; }
35 const u8 &at(int x, int y) const { return mTile[y][x]; }
36
37 u8 &lower_left() { return at(0, 0); }
38 u8 &upper_left() { return at(0, 1); }
39 u8 &lower_right() { return at(1, 0); }
40 u8 &upper_right() { return at(1, 1); }
41
42 const u8 &lower_left() const { return at(0, 0); }
43 const u8 &upper_left() const { return at(0, 1); }
44 const u8 &lower_right() const { return at(1, 0); }
45 const u8 &upper_right() const { return at(1, 1); }
46
47 u8 maxValue() const;
48
49 static Tile2x2_u8 MaxTile(const Tile2x2_u8 &a, const Tile2x2_u8 &b);
50
51 vec2<u16> origin() const { return mOrigin; }
52
54 rect<u16> bounds() const;
55
56 // Draws the subpixel tile to the led array.
57 void draw(const CRGB &color, const XYMap &xymap, fl::span<CRGB> out) const;
58
59 // Inlined, yet customizable drawing access. This will only send you pixels
60 // that are within the bounds of the XYMap.
61 // Why use a template? Speed.
62 // You have an array of Tile2x2_u8 in a draw list and you need to dispatch
63 // them fast. Templates will inline completely for max speed.
64 template <typename XYVisitor>
65 void draw(const XYMap &xymap, XYVisitor &visitor) const {
66 for (u16 x = 0; x < 2; ++x) {
67 for (u16 y = 0; y < 2; ++y) {
68 u8 value = at(x, y);
69 if (value > 0) {
70 int xx = mOrigin.x + x;
71 int yy = mOrigin.y + y;
72 if (xymap.has(xx, yy)) {
73 // we know index cannot be -1 because we checked has(xx, yy) above.
74 u16 ux = static_cast<u16>(xx);
75 u16 uy = static_cast<u16>(yy);
76 int index = xymap.mapToIndex(ux, uy);
77 if (index >= 0) {
78 u32 uindex = static_cast<u32>(index);
79 vec2<u16> pt(ux, uy);
80 visitor.draw(pt, uindex, value);
81 } else {
82 // Unexpected because has(xx, yy) is true above therefore
83 // index cannot be < 0. TODO: low level log this.
84 }
85 }
86 }
87 }
88 }
89 }
90
91 private:
92 u8 mTile[2][2] = {};
93 // Subpixels can be rendered outside the viewport so this must be signed.
95};
96
98 // This is a class that is like a Tile2x2_u8 but wraps around the edges.
99 // This is useful for cylinder mapping where the x-coordinate wraps around
100 // the width of the cylinder and the y-coordinate wraps around the height.
101 // This converts a tile2x2 to a wrapped x,y version.
102 public:
103 using Entry = fl::pair<vec2<u16>, u8>; // absolute position, alpha
104 using Data = Entry[2][2];
105
107 Tile2x2_u8_wrap(const Tile2x2_u8 &from, u16 width);
108 Tile2x2_u8_wrap(const Tile2x2_u8 &from, u16 width, u16 height);
109
110 Tile2x2_u8_wrap(const Data& data);
111
112 // Returns the absolute position and the alpha.
113 Entry &at(u16 x, u16 y);
114 const Entry &at(u16 x, u16 y) const;
115
116 // Interpolates between two wrapped tiles and returns up to 2 interpolated tiles
117 static vector_fixed<Tile2x2_u8_wrap, 2> Interpolate(const Tile2x2_u8_wrap& a, const Tile2x2_u8_wrap& b, float t);
118
119 private:
121};
122
123} // namespace fl
XYMap xymap
Entry & at(u16 x, u16 y)
fl::pair< vec2< u16 >, u8 > Entry
Definition tile2x2.h:103
static vector_fixed< Tile2x2_u8_wrap, 2 > Interpolate(const Tile2x2_u8_wrap &a, const Tile2x2_u8_wrap &b, float t)
Entry[2][2] Data
Definition tile2x2.h:104
Tile2x2_u8_wrap() FL_NOEXCEPT
const u8 & at(int x, int y) const
Definition tile2x2.h:35
static Tile2x2_u8 MaxTile(const Tile2x2_u8 &a, const Tile2x2_u8 &b)
const u8 & upper_left() const
Definition tile2x2.h:43
void draw(const CRGB &color, const XYMap &xymap, fl::span< CRGB > out) const
const u8 & lower_right() const
Definition tile2x2.h:44
u8 & at(int x, int y)
Definition tile2x2.h:34
u8 mTile[2][2]
Definition tile2x2.h:92
Tile2x2_u8(Tile2x2_u8 &&) FL_NOEXCEPT=default
void scale(u8 scale)
static void Rasterize(const span< const Tile2x2_u8 > &tiles, XYRasterU8Sparse *output)
u8 maxValue() const
u8 & lower_right()
Definition tile2x2.h:39
void setOrigin(u16 x, u16 y)
Definition tile2x2.h:31
const u8 & upper_right() const
Definition tile2x2.h:45
Tile2x2_u8(const Tile2x2_u8 &) FL_NOEXCEPT=default
Tile2x2_u8 & operator=(const Tile2x2_u8 &) FL_NOEXCEPT=default
u8 & upper_right()
Definition tile2x2.h:40
u8 & operator()(int x, int y)
Definition tile2x2.h:33
const u8 & lower_left() const
Definition tile2x2.h:42
u8 & lower_left()
Definition tile2x2.h:37
u8 & upper_left()
Definition tile2x2.h:38
vec2< u16 > origin() const
Definition tile2x2.h:51
void draw(const XYMap &xymap, XYVisitor &visitor) const
Definition tile2x2.h:65
Tile2x2_u8() FL_NOEXCEPT=default
rect< u16 > bounds() const
bounds => [begin_x, end_x) (where end_x is exclusive)
vec2< u16 > mOrigin
Definition tile2x2.h:94
unsigned char u8
Definition stdint.h:131
constexpr int type_rank< T >::value
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
FixedVector< T, INLINED_SIZE > vector_fixed
Definition vector.h:1130
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38