Support item padding in util::atlas
This commit is contained in:
parent
8ca5ab3f25
commit
a3eca3bef7
1 changed files with 41 additions and 8 deletions
|
|
@ -20,8 +20,16 @@ namespace psemek::util
|
||||||
std::array<std::size_t, 2> end;
|
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))
|
: default_value_(std::move(default_value))
|
||||||
|
, padding_(padding)
|
||||||
|
, padding_mode_(mode)
|
||||||
, data_(std::move(compare))
|
, data_(std::move(compare))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -36,25 +44,48 @@ namespace psemek::util
|
||||||
if (it != data_.end())
|
if (it != data_.end())
|
||||||
return {it->second, false};
|
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;
|
atlas_part part;
|
||||||
part.begin[0] = array_.width();
|
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.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_width = array_.width() + part_width;
|
||||||
std::size_t new_height = std::max(array_.height(), data.height());
|
std::size_t new_height = std::max(array_.height(), part_height);
|
||||||
|
|
||||||
array_.resize({new_width, new_height}, default_value_);
|
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;
|
data_[key] = part;
|
||||||
return {part, true};
|
return {part, true};
|
||||||
}
|
}
|
||||||
|
|
@ -74,6 +105,8 @@ namespace psemek::util
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T default_value_;
|
T default_value_;
|
||||||
|
std::size_t const padding_;
|
||||||
|
padding_mode const padding_mode_;
|
||||||
std::map<Key, atlas_part, Compare> data_;
|
std::map<Key, atlas_part, Compare> data_;
|
||||||
util::array<T, 2> array_;
|
util::array<T, 2> array_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue