Unravel Engine C++ Reference
Loading...
Searching...
No Matches
packrect.h
Go to the documentation of this file.
1/*
2 * Copyright 2011-2026 Branimir Karadzic. All rights reserved.
3 * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
4 */
5
6 #ifndef RECTPACK_H_HEADER_GUARD
7 #define RECTPACK_H_HEADER_GUARD
8
9 struct Pack2D
10 {
11 uint16_t m_x;
12 uint16_t m_y;
13 uint16_t m_width;
14 uint16_t m_height;
15 };
16
17 struct PackCube
18 {
20 uint8_t m_side;
21 };
22
23 template <uint16_t numBlocks>
24 class RectPackCubeT;
25
26 template <uint16_t numBlocks>
28 {
29 public:
30 RectPack2DT(uint16_t _width, uint16_t _height)
31 {
32 reset(_width, _height);
33 }
34
35 void reset(uint16_t _width, uint16_t _height)
36 {
37 m_bw = _width/64;
38 m_bh = _height/numBlocks;
39 bx::memSet(m_mem, 0xff, sizeof(m_mem) );
40 }
41
42 bool find(uint16_t _width, uint16_t _height, Pack2D& _pack)
43 {
44 uint16_t width = bx::min<uint16_t>(64, (_width + m_bw - 1) / m_bw);
45 uint16_t height = bx::min<uint16_t>(numBlocks, (_height + m_bh - 1) / m_bh);
46 uint16_t numx = 64-width;
47 uint16_t numy = numBlocks-height;
48
49 const uint64_t scan = width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1;
50
51 for (uint16_t starty = 0; starty <= numy; ++starty)
52 {
53 uint64_t mem = m_mem[starty];
54 uint16_t ntz = bx::countTrailingZeros(mem);
55 uint64_t mask = scan<<ntz;
56
57 for (uint16_t xx = ntz; xx <= numx; ++xx, mask <<= 1)
58 {
59 uint16_t yy = starty;
60 if ( (mem&mask) == mask)
61 {
62 uint16_t endy = starty + height;
63 while (yy < endy && (m_mem[yy]&mask) == mask)
64 {
65 ++yy;
66 }
67
68 if (yy == endy)
69 {
70 uint64_t cmask = ~mask;
71 for (yy = starty; yy < endy; ++yy)
72 {
73 m_mem[yy] &= cmask;
74 }
75
76 _pack.m_x = xx * m_bw;
77 _pack.m_y = starty * m_bh;
78 _pack.m_width = width * m_bw;
79 _pack.m_height = height * m_bh;
80 return true;
81 }
82 }
83 }
84 }
85
86 return false;
87 }
88
89 void clear(const Pack2D& _pack)
90 {
91 uint16_t startx = bx::min<uint16_t>(63, _pack.m_x / m_bw);
92 uint16_t starty = bx::min<uint16_t>(numBlocks-1, _pack.m_y / m_bh);
93 uint16_t endx = bx::min<uint16_t>(64, (_pack.m_width + m_bw - 1) / m_bw + startx);
94 uint16_t endy = bx::min<uint16_t>(numBlocks, (_pack.m_height + m_bh - 1) / m_bh + starty);
95 uint16_t width = endx - startx;
96
97 const uint64_t mask = (width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1 )<<startx;
98
99 for (uint16_t yy = starty; yy < endy; ++yy)
100 {
101 m_mem[yy] |= mask;
102 }
103 }
104
105 private:
106 friend class RectPackCubeT<numBlocks>;
107
109 {
110 }
111
112 uint64_t m_mem[numBlocks];
113 uint16_t m_bw;
114 uint16_t m_bh;
115 };
116
117 template <uint16_t numBlocks>
119 {
120 public:
121 RectPackCubeT(uint16_t _side)
122 {
123 reset(_side);
124 }
125
126 void reset(uint16_t _side)
127 {
128 for (uint8_t ii = 0; ii < 6; ++ii)
129 {
130 m_mru[ii] = ii;
131 m_ra[ii].reset(_side, _side);
132 }
133 }
134
135 bool find(uint16_t _width, uint16_t _height, PackCube& _pack)
136 {
137 bool found = false;
138 for (uint32_t ii = 0; ii < 6; ++ii)
139 {
140 uint8_t side = m_mru[ii];
141 found = m_ra[side].find(_width, _height, _pack.m_rect);
142
143 if (found)
144 {
145 _pack.m_side = side;
146 m_mru[ii] = m_mru[0];
147 m_mru[0] = side;
148 return true;
149 }
150 }
151
152 return false;
153 }
154
155 void clear(const PackCube& _pack)
156 {
157 uint8_t side = _pack.m_side;
158
159 uint32_t ii = 0;
160 for (; ii < 6 && m_mru[ii] != side; ++ii) {};
161
162 m_mru[ii] = m_mru[0];
163 m_mru[0] = side;
164
165 m_ra[side].clear(_pack.m_rect);
166 }
167
168 private:
170
172 uint8_t m_mru[6];
173 };
174
175 #endif // RECTPACK_H_HEADER_GUARD
176
uint32_t width
uint32_t height
bool find(uint16_t _width, uint16_t _height, Pack2D &_pack)
Definition packrect.h:42
RectPack2DT(uint16_t _width, uint16_t _height)
Definition packrect.h:30
void reset(uint16_t _width, uint16_t _height)
Definition packrect.h:35
void clear(const Pack2D &_pack)
Definition packrect.h:89
RectPackCubeT(uint16_t _side)
Definition packrect.h:121
void clear(const PackCube &_pack)
Definition packrect.h:155
bool find(uint16_t _width, uint16_t _height, PackCube &_pack)
Definition packrect.h:135
void reset(uint16_t _side)
Definition packrect.h:126
uint16_t m_width
Definition packrect.h:13
uint16_t m_height
Definition packrect.h:14
uint16_t m_y
Definition packrect.h:12
uint16_t m_x
Definition packrect.h:11
Pack2D m_rect
Definition packrect.h:19
uint8_t m_side
Definition packrect.h:20