54 if(static_cast<int32_t>(width*height*pixelSize) > freePixels) {
59 AtlasBlock* newBlock = &blocks[blocks.size() - 1];
61 for(
uint32_t v = 0; (v+1)*height <= this->height; ++v) {
62 newBlock->
top = v * height;
63 newBlock->
bottom = (v+1) * height;
65 for(
uint32_t u = 0; (u+1)*width <= this->width; ++u) {
67 newBlock->
left = u * width;
68 newBlock->
right = (u+1) * width;
72 freePixels -= width*height*pixelSize;
73 assert(freePixels >= 0);
76 if(newBlock->
left > 0) {
85 int blockWidth = newBlock->
getWidth();
88 for(
int i = 0, div = 2; i < 4; ++i) {
89 squeezed.
left -= blockWidth / div;
90 squeezed.
right -= blockWidth / div;
93 squeezed.
left += blockWidth / div;
94 squeezed.
right += blockWidth / div;
100 while(!(intersection =
intersects(&squeezed)) && squeezed.
left > 0) {
111 if(newBlock->
top > 0) {
123 for(
int i = 0, div = 2; i < 4; ++i) {
124 squeezed.
top -= blockHeight / div;
125 squeezed.
bottom -= blockHeight / div;
128 squeezed.
top += blockHeight / div;
129 squeezed.
bottom += blockHeight / div;
135 while(!(intersection =
intersects(&squeezed)) && squeezed.
top > 0) {
140 newBlock->
top = squeezed.
top + 1;
157 for(Blocks::iterator block = blocks.begin(); block != blocks.end(); ++block) {
158 boundaryBox.
merge(*block);
161 assert(boundaryBox.
left == 0);
162 assert(boundaryBox.
top == 0);
171 while(powof2 < bwidth) powof2 <<= 1;
172 width = std::min(powof2, width);
175 if(bheight < height) {
178 while(powof2 < bheight) powof2 <<= 1;
179 height = std::min(powof2, height);
189 for(
size_t b = 0; b < blocks.size() - 1; ++b) {
198 for(Pages::iterator
page = pages.begin();
page != pages.end(); ++
page) {
204 return extendCache(width, height)->getBlock(width, height);
208 if(minPageWidth > pageWidth ||
209 minPageHeight > pageHeight) {
210 throw Exception(
"Texture is too big for this atlas.");
213 assert(minPageWidth <= pageWidth);
214 assert(minPageHeight <= pageHeight);
216 pages.push_back(
AtlasPage(pageWidth, pageHeight, pixelSize, pages.size()));
217 return &pages[pages.size()-1];
221 for(Pages::iterator
page = pages.begin();
page != pages.end(); ++
page) {
AtlasBlock * getBlock(uint32_t width, uint32_t height)
void merge(AtlasBlock const &rect)
AtlasPage * extendCache(uint32_t minPageWidth, uint32_t minPageHeight)
AtlasBlock * getBlock(uint32_t width, uint32_t height)
uint32_t getHeight() const
AtlasBlock intersects(AtlasBlock const &rect) const
AtlasBlock const * intersects(AtlasBlock const *block) const
uint32_t getWidth() const