From 752acbdc3eae942b86cec30a673440da89b37910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 25 Sep 2023 16:51:07 +0200 Subject: [PATCH] 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- --- src/Magnum/TextureTools/Atlas.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Magnum/TextureTools/Atlas.cpp b/src/Magnum/TextureTools/Atlas.cpp index 19bfdab9c..83d10a006 100644 --- a/src/Magnum/TextureTools/Atlas.cpp +++ b/src/Magnum/TextureTools/Atlas.cpp @@ -77,14 +77,13 @@ Containers::Pair> atlasArrayPowerOfTwo(const Ve /* 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 as it would be overwritten in random order. */ - Containers::Array sortedSizes{NoInit, sizes.size()}; + Containers::Array> sortedSizes{NoInit, sizes.size()}; for(std::size_t i = 0; i != sizes.size(); ++i) { const Vector2i size = sizes[i]; 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, {}); - sortedSizes[i].xy() = size; - sortedSizes[i].z() = i; + sortedSizes[i] = {size, UnsignedInt(i)}; } /* Sort to have the biggest size first. Assuming the items are square, @@ -93,15 +92,15 @@ Containers::Pair> atlasArrayPowerOfTwo(const Ve consistent across platforms. */ /** @todo stable_sort allocates, would be great if i could make it reuse the memory allocated for output */ - std::stable_sort(sortedSizes.begin(), sortedSizes.end(), [](const Vector3i& a, const Vector3i& b) { - return a.x() > b.x(); + std::stable_sort(sortedSizes.begin(), sortedSizes.end(), [](const Containers::Pair& a, const Containers::Pair& b) { + return a.first().x() > b.first().x(); }); /* Start with the whole first layer free */ Int layer = 0; UnsignedInt free = 1; Vector2i previousSize = layerSize; - for(const Vector3i& size: sortedSizes) { + for(const Containers::Pair& size: sortedSizes) { /* No free slots left, go to the next layer. Then, what's free, is one whole layer. */ if(!free) { @@ -114,11 +113,11 @@ Containers::Pair> atlasArrayPowerOfTwo(const Ve size. If the size is the same, nothing changes. */ /** @todo there's definitely some bit trick for dividing power-of-two 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 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 slotIndex = sideSlotCount*sideSlotCount - free; @@ -132,8 +131,8 @@ Containers::Pair> atlasArrayPowerOfTwo(const Ve } /* Save to the output in the original order */ - output[size.z()] = {coordinates, layer}; - previousSize = size.xy(); + output[size.second()] = {coordinates, layer}; + previousSize = size.first(); --free; }