Support item padding in util::atlas

This commit is contained in:
Nikita Lisitsa 2022-05-14 00:01:26 +03:00
parent 8ca5ab3f25
commit a3eca3bef7

View file

@ -20,8 +20,16 @@ namespace psemek::util
std::array<std::size_t, 2> end;
};
atlas(T default_value = T{}, Compare compare = Compare{})
enum class padding_mode
{
default_value,
clamp,
};
atlas(T default_value = T{}, std::size_t padding = 0, padding_mode mode = padding_mode::default_value, Compare compare = Compare{})
: default_value_(std::move(default_value))
, padding_(padding)
, padding_mode_(mode)
, data_(std::move(compare))
{}
@ -36,25 +44,48 @@ namespace psemek::util
if (it != data_.end())
return {it->second, false};
std::size_t part_width = data.width() + padding_ * 2;
std::size_t part_height = data.height() + padding_ * 2;
atlas_part part;
part.begin[0] = array_.width();
part.end[0] = part.begin[0] + data.width();
part.end[0] = part.begin[0] + part_width;
part.begin[1] = 0;
part.end[1] = data.height();
part.end[1] = part_height;
std::size_t new_width = array_.width() + data.width();
std::size_t new_height = std::max(array_.height(), data.height());
std::size_t new_width = array_.width() + part_width;
std::size_t new_height = std::max(array_.height(), part_height);
array_.resize({new_width, new_height}, default_value_);
for (std::size_t y = 0; y < data.height(); ++y)
for (std::size_t y = 0; y < part_height; ++y)
{
for (std::size_t x = 0; x < data.width(); ++x)
for (std::size_t x = 0; x < part_width; ++x)
{
array_(part.begin[0] + x, part.begin[1] + y) = data(x, y);
T value;
if (padding_mode_ == padding_mode::default_value)
{
if (x < padding_ || y < padding_ || x + padding_ >= part_width || y + padding_ >= part_height)
value = default_value_;
else
value = data(x - padding_, y - padding_);
}
else
{
std::size_t xx = std::min(std::max(x, padding_), part_width - padding_ - 1);
std::size_t yy = std::min(std::max(y, padding_), part_height - padding_ - 1);
value = data(xx - padding_, yy - padding_);
}
array_(part.begin[0] + x, part.begin[1] + y) = value;
}
}
part.begin[0] += padding_;
part.begin[1] += padding_;
part.end[0] -= padding_;
part.end[1] -= padding_;
data_[key] = part;
return {part, true};
}
@ -74,6 +105,8 @@ namespace psemek::util
private:
T default_value_;
std::size_t const padding_;
padding_mode const padding_mode_;
std::map<Key, atlas_part, Compare> data_;
util::array<T, 2> array_;
};