Files
WickedEngine/WickedEngine/wiRectPacker.h
T
2022-06-21 20:26:20 +02:00

67 lines
1.6 KiB
C++

#pragma once
#include "CommonInclude.h"
#include "wiVector.h"
#include "Utility/stb_rect_pack.h"
namespace wi::rectpacker
{
using Rect = stbrp_rect;
// Convenience state wrapper around stb_rect_pack
// This can be used to automatically grow backing memory for the packer,
// and also supports iteratively finding a minimal containing size when packing
struct State
{
stbrp_context context = {};
wi::vector<stbrp_node> nodes;
wi::vector<Rect> rects;
int width = 0;
int height = 0;
// Clears the rectangles to empty, but doesn't reset the containing width/height result
void clear()
{
rects.clear();
}
// Add a new rect and also grow the minimum containing size
void add_rect(const Rect& rect)
{
rects.push_back(rect);
width = std::max(width, rect.w);
height = std::max(height, rect.h);
}
// Performs packing of the rect array
// The rectangle offsets will be filled after this
// The width, height for minimal containing area will be filled after this if the packing is successful
// max_width : if the packing is unsuccessful above this, it will result in a failure
// returns true for success, false for failure
bool pack(int max_width)
{
while (width <= max_width || height <= max_width)
{
if (nodes.size() < width)
{
nodes.resize(width);
}
stbrp_init_target(&context, width, height, nodes.data(), int(nodes.size()));
if (stbrp_pack_rects(&context, rects.data(), int(rects.size())))
return true;
if (height < width)
{
height *= 2;
}
else
{
width *= 2;
}
}
width = 0;
height = 0;
return false;
}
};
}