From c70d2cfb9ae83fa14282627904411ceac79b01c2 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Tue, 18 Jul 2023 11:50:15 -0400 Subject: [PATCH] Fix bug with loading non-square textures. We had a case where loading textures of sizes like 32x16 could lead to one of the dimensions width becoming 0 in the mip-loading loop. Fix this by making sure the resolution is at least 1. --- .../DBPF/Scenegraph/ScenegraphTextureAsset.cs | 5 +++-- .../Codecs/ScenegraphTextureCodecTest.cs | 20 ++++++++++++++++++ TestAssets/Scenegraph/textures.package | Bin 55256 -> 56164 bytes 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Scenegraph/ScenegraphTextureAsset.cs b/Assets/Scripts/OpenTS2/Content/DBPF/Scenegraph/ScenegraphTextureAsset.cs index edf5ae6..1e6897c 100644 --- a/Assets/Scripts/OpenTS2/Content/DBPF/Scenegraph/ScenegraphTextureAsset.cs +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Scenegraph/ScenegraphTextureAsset.cs @@ -73,8 +73,9 @@ namespace OpenTS2.Content.DBPF.Scenegraph texture.SetPixelData(pixelData, currentMipLevel); currentMipLevel++; - width /= 2; - height /= 2; + // Make sure the width and height are always at least 1-pixel. + width = Math.Max(width / 2, 1); + height = Math.Max(height / 2, 1); } texture.Apply(); return texture; diff --git a/Assets/Tests/OpenTS2/Files/Formats/DBPF/Scenegraph/Codecs/ScenegraphTextureCodecTest.cs b/Assets/Tests/OpenTS2/Files/Formats/DBPF/Scenegraph/Codecs/ScenegraphTextureCodecTest.cs index 8d071b7..e6075d9 100644 --- a/Assets/Tests/OpenTS2/Files/Formats/DBPF/Scenegraph/Codecs/ScenegraphTextureCodecTest.cs +++ b/Assets/Tests/OpenTS2/Files/Formats/DBPF/Scenegraph/Codecs/ScenegraphTextureCodecTest.cs @@ -84,4 +84,24 @@ public class ScenegraphTextureCodecTest // Check that the last mip is a LIFO reference. Assert.That(imageBlock.SubImages[0].MipMap[8], Is.InstanceOf()); } + + [Test] + public void TestLoadsTextureThatSqueezesToOnePixel() + { + // This test is for an edge case of resolutions like 32x16 with 6 mip levels. If we naively go down the path + // of dividing the shorter side by 2 for each mip level we end up with: + // + // mip level: 6 -> 5 -> 4 -> 3 -> 2 -> 1 + // pixels: 16 -> 8 -> 4 -> 2 -> 1 -> 0 + // + // but we can't have a 1x0 resolution texture, so gotta make sure we clamp that lower value to at least 1 + // pixel :) + var textureAsset = + ContentProvider.Get().GetAsset(new ResourceKey("small_non_square_txtr", 0x1C0532FA, + TypeIDs.SCENEGRAPH_TXTR)); + + // Check that the smallest mip is a 1x1 image. + var texture = textureAsset.GetSelectedImageAsUnityTexture(ContentProvider.Get()); + Assert.That(texture.GetPixels32(5).Length, Is.EqualTo(1)); + } } \ No newline at end of file diff --git a/TestAssets/Scenegraph/textures.package b/TestAssets/Scenegraph/textures.package index c771ec8cb3d92e7fe9af3203fce2e6508a6c9e6a..95370608a8940ded5ccaf5f0be23e64458f55507 100644 GIT binary patch delta 886 zcmZ8gPiWIn82_}ZV>y`YkI=&oqf->6tZ2cL3?&!E!@Bt>?P2KR;QxrA;Jy; zXDvNQ4m~tD3ZXbi50-daPg2lgBYMz-Cl69AVWmQ!?yDG2bU9dAB!5F#;8cf4s^y}l%|JXMt>H}CRot7r}|U2X_++p3w> zDg`<~H@ybORo^lKZD2aXf_O8~aEPE+4q)#GK2*r^__gTKUZ=1tvfD^F{ zF*9$_2A+HekkKmt?c)R1fEsWG4gnS)H~3U?CEN+rtcZSm0uiIDZS{v1y5+sX;3$>> z@>;7v1=s|-TE4)Yb;zAPMPy9r7yQEpfkx3Zbe6?9qVH+Me$tx&#w~3@<>%y>SB-I4 z5fqFQPgpD{ymEA*dGaM0;7tJIs46I(&Oe70q}8xmsqi5dPwM#s#(L<=%k>+tRr_ur ab@9%0|Eho5T>XPTl^Qp9Y=8{;8U6#;$xjpj delta 26 icmaE|jrqoU<_RjC%nS?+6RtBbcx=>7zCM}dwg&)!ObKZK