Browse Source

TextureTools: use a Pair instead of Vector3i in the internals.

The z() element was input offset and not a layer. Rather confusing in an
atlas algorithm that operates with texture arrays-
pull/168/head
Vladimír Vondruš 3 years ago
parent
commit
752acbdc3e
  1. 19
      src/Magnum/TextureTools/Atlas.cpp

19
src/Magnum/TextureTools/Atlas.cpp

@ -77,14 +77,13 @@ Containers::Pair<Int, Containers::Array<Vector3i>> atlasArrayPowerOfTwo(const Ve
/* Copy the input to a sorted array, together with a mapping to the /* Copy the input to a sorted array, together with a mapping to the
original order stored in Z. Can't really reuse the output allocation original order stored in Z. Can't really reuse the output allocation
as it would be overwritten in random order. */ as it would be overwritten in random order. */
Containers::Array<Vector3i> sortedSizes{NoInit, sizes.size()}; Containers::Array<Containers::Pair<Vector2i, UnsignedInt>> sortedSizes{NoInit, sizes.size()};
for(std::size_t i = 0; i != sizes.size(); ++i) { for(std::size_t i = 0; i != sizes.size(); ++i) {
const Vector2i size = sizes[i]; const Vector2i size = sizes[i];
CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero() && size <= layerSize, CORRADE_ASSERT(size.product() && size.x() == size.y() && (size & (size - Vector2i{1})).isZero() && size <= layerSize,
"TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square not larger than" << Debug::packed << layerSize << "but got" << Debug::packed << size, {}); "TextureTools::atlasArrayPowerOfTwo(): expected size" << i << "to be a non-zero power-of-two square not larger than" << Debug::packed << layerSize << "but got" << Debug::packed << size, {});
sortedSizes[i].xy() = size; sortedSizes[i] = {size, UnsignedInt(i)};
sortedSizes[i].z() = i;
} }
/* Sort to have the biggest size first. Assuming the items are square, /* Sort to have the biggest size first. Assuming the items are square,
@ -93,15 +92,15 @@ Containers::Pair<Int, Containers::Array<Vector3i>> atlasArrayPowerOfTwo(const Ve
consistent across platforms. */ consistent across platforms. */
/** @todo stable_sort allocates, would be great if i could make it reuse /** @todo stable_sort allocates, would be great if i could make it reuse
the memory allocated for output */ the memory allocated for output */
std::stable_sort(sortedSizes.begin(), sortedSizes.end(), [](const Vector3i& a, const Vector3i& b) { std::stable_sort(sortedSizes.begin(), sortedSizes.end(), [](const Containers::Pair<Vector2i, UnsignedInt>& a, const Containers::Pair<Vector2i, UnsignedInt>& b) {
return a.x() > b.x(); return a.first().x() > b.first().x();
}); });
/* Start with the whole first layer free */ /* Start with the whole first layer free */
Int layer = 0; Int layer = 0;
UnsignedInt free = 1; UnsignedInt free = 1;
Vector2i previousSize = layerSize; Vector2i previousSize = layerSize;
for(const Vector3i& size: sortedSizes) { for(const Containers::Pair<Vector2i, UnsignedInt>& size: sortedSizes) {
/* No free slots left, go to the next layer. Then, what's free, is one /* No free slots left, go to the next layer. Then, what's free, is one
whole layer. */ whole layer. */
if(!free) { if(!free) {
@ -114,11 +113,11 @@ Containers::Pair<Int, Containers::Array<Vector3i>> atlasArrayPowerOfTwo(const Ve
size. If the size is the same, nothing changes. */ size. If the size is the same, nothing changes. */
/** @todo there's definitely some bit trick for dividing power-of-two /** @todo there's definitely some bit trick for dividing power-of-two
numbers, use it */ numbers, use it */
free *= (previousSize/size.xy()).product(); free *= (previousSize/size.first()).product();
/* Slot index as if the whole layer was consisting just of slots of /* Slot index as if the whole layer was consisting just of slots of
this size. */ this size. */
const UnsignedInt sideSlotCount = layerSize.x()/size.x(); const UnsignedInt sideSlotCount = layerSize.x()/size.first().x();
const UnsignedInt layerDepth = Math::log2(sideSlotCount); const UnsignedInt layerDepth = Math::log2(sideSlotCount);
const UnsignedInt slotIndex = sideSlotCount*sideSlotCount - free; const UnsignedInt slotIndex = sideSlotCount*sideSlotCount - free;
@ -132,8 +131,8 @@ Containers::Pair<Int, Containers::Array<Vector3i>> atlasArrayPowerOfTwo(const Ve
} }
/* Save to the output in the original order */ /* Save to the output in the original order */
output[size.z()] = {coordinates, layer}; output[size.second()] = {coordinates, layer};
previousSize = size.xy(); previousSize = size.first();
--free; --free;
} }

Loading…
Cancel
Save