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