Skip to content

Commit

Permalink
Reinstate texture slot reuse (LostArtefacts#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahm86 authored May 11, 2024
1 parent de16e49 commit 26e5027
Show file tree
Hide file tree
Showing 20 changed files with 93 additions and 35 deletions.
17 changes: 14 additions & 3 deletions TRDataControl/Transport/TRDataImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ protected void ImportTextures(List<B> blobs)

// Packing passed, so remap mesh textures to their new object references
Dictionary<string, Dictionary<int, int>> globalRemap = new();
Queue<int> freeSlots = new(Level.GetFreeTextureSlots());
foreach (TRTextileRegion region in importRegions)
{
globalRemap[region.ID] = new();
Expand All @@ -352,13 +353,23 @@ protected void ImportTextures(List<B> blobs)
if (globalRemap[region.ID].ContainsKey(segment.Index))
continue;

if (Level.ObjectTextures.Count >= Data.TextureObjectLimit)
int newIndex;
if (freeSlots.Count > 0)
{
newIndex = freeSlots.Dequeue();
Level.ObjectTextures[newIndex] = segment.Texture as TRObjectTexture;
}
else if (Level.ObjectTextures.Count < Data.TextureObjectLimit)
{
newIndex = Level.ObjectTextures.Count;
Level.ObjectTextures.Add(segment.Texture as TRObjectTexture);
}
else
{
throw new PackingException($"Limit of {Data.TextureObjectLimit} textures reached.");
}

globalRemap[region.ID][segment.Index] = Level.ObjectTextures.Count;
Level.ObjectTextures.Add(segment.Texture as TRObjectTexture);
globalRemap[region.ID][segment.Index] = newIndex;
}
}

Expand Down
20 changes: 3 additions & 17 deletions TRDataControl/Transport/TRTextureRemapper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Drawing;
using TRImageControl;
using TRImageControl.Packing;
using TRLevelControl.Model;

Expand Down Expand Up @@ -89,7 +90,7 @@ static string Hash(TRObjectTexture t)
{
int j = _level.ObjectTextures.IndexOf(copies[i]);
remap[j] = rootIndex;
_level.ObjectTextures[j].Atlas = ushort.MaxValue;
_level.ObjectTextures[j].Invalidate();
}
}

Expand All @@ -108,23 +109,8 @@ public void ResetUnusedTextures()
.Distinct();
foreach (int unused in allIndices.Except(usedIndices))
{
_level.ObjectTextures[unused].Atlas = ushort.MaxValue;
_level.ObjectTextures[unused].Invalidate();
}

// Remap all indices after deleting the nulls
Dictionary<int, int> remap = new();
List<TRObjectTexture> oldTextures = new(_level.ObjectTextures);
_level.ObjectTextures.RemoveAll(o => o.Atlas == ushort.MaxValue);
for (int i = 0; i < oldTextures.Count; i++)
{
if (oldTextures[i].Atlas != ushort.MaxValue)
{
remap[i] = _level.ObjectTextures.IndexOf(oldTextures[i]);
}
}

// Update all faces
RemapTextures(remap);
}

private void RemapTextures(Dictionary<int, int> remap)
Expand Down
14 changes: 14 additions & 0 deletions TRDataControl/Utilities/TRModelExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Security.Cryptography;
using System.Text;
using TRImageControl;
using TRLevelControl.Build;
using TRLevelControl.Model;

Expand Down Expand Up @@ -29,6 +30,19 @@ public static void ResetUnusedTextures(this TRLevelBase level)
}
}

public static List<int> GetFreeTextureSlots(this TRLevelBase level)
{
List<int> slots = new();
for (int i = 0; i < level.ObjectTextures.Count; i++)
{
if (!level.ObjectTextures[i].IsValid())
{
slots.Add(i);
}
}
return slots;
}

public static string ComputeSkeletonHash(this IEnumerable<TRMesh> meshes)
{
using MemoryStream ms = new();
Expand Down
27 changes: 26 additions & 1 deletion TRDataControlTests/Remapping/RemappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,34 @@
namespace TRDataControlTests.IO;

[TestClass]
[TestCategory("OriginalIO")]
public class RemappingTests : TestBase
{
[TestMethod]
[TestCategory("DataTransport")]
[Description("Test that texture slots are freed correctly when requested.")]
public void TestFreeSlots()
{
TR1Level level = GetTR1TestLevel();

HashSet<int> slots = new();
Random random = new();
while (slots.Count < 10)
{
slots.Add(random.Next(0, level.ObjectTextures.Count));
}

foreach (int slot in slots)
{
level.ObjectTextures[slot].Invalidate();
Assert.IsFalse(level.ObjectTextures[slot].IsValid());
}

List<int> freeSlots = level.GetFreeTextureSlots();
CollectionAssert.AreEquivalent(slots.ToList(), freeSlots);
}

[TestMethod]
[TestCategory("OriginalIO")]
[Description("Test that object textures are correct after removing data.")]
public void TestTextureRemoval()
{
Expand Down Expand Up @@ -46,6 +70,7 @@ string GetFaceID(TRFace face)
}

[TestMethod]
[TestCategory("OriginalIO")]
[Description("As above, but with an added dependency on a different model.")]
public void TestDependencies()
{
Expand Down
13 changes: 13 additions & 0 deletions TRImageControl/Extensions/ColourExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,17 @@ public static int FindClosest(this IEnumerable<Color> palette, Color colour, int
.Where(item => item.Index >= startIndex)
.MinBy(item => item.Delta).Index;
}

public static bool IsValid(this TRTexture texture)
{
return texture.Atlas != 0 || texture.Bounds != _nullBounds;
}

public static void Invalidate(this TRTexture texture)
{
texture.Atlas = 0;
texture.Bounds = _nullBounds;
}

private static readonly Rectangle _nullBounds = new(0, 0, 1, 1);
}
4 changes: 2 additions & 2 deletions TRImageControl/Packing/TRTextileSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ public void Commit(int tileIndex)

public void Invalidate()
{
Atlas = ushort.MaxValue;
Texture.Invalidate();
}

public bool IsValid()
{
return Atlas != ushort.MaxValue;
return Texture.IsValid();
}

public override string ToString()
Expand Down
3 changes: 3 additions & 0 deletions TRImageControl/Packing/Types/TR1TexturePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ protected override List<TRTextileSegment> LoadObjectSegments()
List<TRTextileSegment> segments = new();
for (int i = 0; i < _level.ObjectTextures.Count; i++)
{
if (!_level.ObjectTextures[i].IsValid())
continue;

segments.Add(new()
{
Index = i,
Expand Down
3 changes: 3 additions & 0 deletions TRImageControl/Packing/Types/TR2TexturePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ protected override List<TRTextileSegment> LoadObjectSegments()
List<TRTextileSegment> segments = new();
for (int i = 0; i < _level.ObjectTextures.Count; i++)
{
if (!_level.ObjectTextures[i].IsValid())
continue;

segments.Add(new()
{
Index = i,
Expand Down
3 changes: 3 additions & 0 deletions TRImageControl/Packing/Types/TR3TexturePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ protected override List<TRTextileSegment> LoadObjectSegments()
List<TRTextileSegment> segments = new();
for (int i = 0; i < _level.ObjectTextures.Count; i++)
{
if (!_level.ObjectTextures[i].IsValid())
continue;

segments.Add(new()
{
Index = i,
Expand Down
2 changes: 1 addition & 1 deletion TRImageControl/Packing/Types/TR4TexturePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected override List<TRTextileSegment> LoadObjectSegments()
for (int i = 0; i < _level.ObjectTextures.Count; i++)
{
TRObjectTexture texture = _level.ObjectTextures[i];
if (group != null && !group.Contains(texture))
if (group != null && !group.Contains(texture) || !texture.IsValid())
continue;

segments.Add(new()
Expand Down
2 changes: 1 addition & 1 deletion TRImageControl/Packing/Types/TR5TexturePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected override List<TRTextileSegment> LoadObjectSegments()
for (int i = 0; i < _level.ObjectTextures.Count; i++)
{
TRObjectTexture texture = _level.ObjectTextures[i];
if (group != null && !group.Contains(texture))
if (group != null && !group.Contains(texture) || !texture.IsValid())
continue;

segments.Add(new()
Expand Down
1 change: 0 additions & 1 deletion TRRandomizerCore/Processors/TR2/TR2TextureDeduplicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ protected override void ProcessImpl()

TR2TextureRemapper remapper = new(level.Data);
remapper.ResetUnusedTextures();
remapper.Remap();

_outer.SaveLevel(level);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"RoomNumber": 0,
"RectangleIndices": [ 57 ],
"BackgroundIndex": 1464
"BackgroundIndex": 1520
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
{
"RoomNumber": 73,
"RectangleIndices": [ 9 ],
"BackgroundIndex": 1297
"BackgroundIndex": 1314
}
]
},
Expand All @@ -114,7 +114,7 @@
{
"RoomNumber": 121,
"RectangleIndices": [ 7 ],
"BackgroundIndex": 1330
"BackgroundIndex": 1344
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"RoomNumber": 40,
"RectangleIndices": [ 29, 58 ],
"BackgroundIndex": 1611
"BackgroundIndex": 1667
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"RoomNumber": 40,
"RectangleIndices": [ 29, 58 ],
"BackgroundIndex": 1627
"BackgroundIndex": 1683
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"RoomNumber": 5,
"RectangleIndices": [ 72 ],
"BackgroundIndex": 1360
"BackgroundIndex": 1378
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
"RoomNumber": 131,
"RectangleIndices": [ 15 ],
"BackgroundIndex": 1462
"BackgroundIndex": 1480
}
]
},
Expand All @@ -14,7 +14,7 @@
{
"RoomNumber": 124,
"RectangleIndices": [ 4 ],
"BackgroundIndex": 1332
"BackgroundIndex": 1350
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
{
"RoomNumber": 65,
"RectangleIndices": [ 134 ],
"BackgroundIndex": 1130
"BackgroundIndex": 1186
}
]
}
Expand Down

0 comments on commit 26e5027

Please sign in to comment.