Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an entry to RSI meta.json for controlling RSI atlas grouping #5249

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Robust.Client/ResourceManagement/ResourceCache.Preload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ private void PreloadRsis(ISawmill sawmill)
});

// Do not meta-atlas RSIs with custom load parameters.
var atlasList = rsiList.Where(x => x.LoadParameters == TextureLoadParameters.Default).ToArray();
var nonAtlasList = rsiList.Where(x => x.LoadParameters != TextureLoadParameters.Default).ToArray();
var atlasList = rsiList.Where(x => x.LoadParameters == TextureLoadParameters.Default && x.AtlasGroup >= 0).ToArray();
var nonAtlasList = rsiList.Where(x => x.LoadParameters != TextureLoadParameters.Default || x.AtlasGroup < 0).ToArray();

foreach (var data in nonAtlasList)
{
Expand Down Expand Up @@ -173,15 +173,19 @@ private void PreloadRsis(ISawmill sawmill)
// everything fits onto a single 8k x 8k image so as long as the computer can manage that, it should be
// fine.

// TODO allow RSIs to opt out (useful for very big & rare RSIs)
// TODO combine with (non-rsi) texture atlas?
// TODO use rectangle packing algorithms.

Array.Sort(atlasList, (b, a) => (b.AtlasSheet?.Height ?? 0).CompareTo(a.AtlasSheet?.Height ?? 0));
// TODO ensure that atlas groups are actually grouped together
// Currently atlas groups are just used for this Sort( call), which helps to try ensure that group 0 are
// all together, but doesn't really do anything for other groups.
Array.Sort(atlasList, RSIResource.LoadStepData.Comparison);

// Each RSI sub atlas has a different size.
// Even if we iterate through them once to estimate total area, I have NFI how to sanely estimate an optimal square-texture size.
// So fuck it, just default to letting it be as large as it needs to and crop it as needed?
var maxSize = Math.Min(GL.GetInteger(GetPName.MaxTextureSize), _configurationManager.GetCVar(CVars.ResRSIAtlasSize));
var maxSize = GL.GetInteger(GetPName.MaxTextureSize);
maxSize = Math.Min(maxSize, _configurationManager.GetCVar(CVars.ResRSIAtlasSize));
var sheet = new Image<Rgba32>(maxSize, maxSize);

var deltaY = 0;
Expand Down
19 changes: 19 additions & 0 deletions Robust.Client/ResourceManagement/ResourceTypes/RSIResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ internal static void LoadPreTexture(IResourceManager manager, LoadStepData data)
data.DimX = dimensionX;
data.CallbackOffsets = callbackOffsets;
data.LoadParameters = metadata.LoadParameters;
data.AtlasGroup = metadata.AtlasGroup;
}

internal static void LoadPostTexture(LoadStepData data)
Expand Down Expand Up @@ -386,6 +387,24 @@ internal sealed class LoadStepData
public Vector2i AtlasOffset;
public RSI Rsi = default!;
public TextureLoadParameters LoadParameters;

/// <summary>
/// Integer used to identify how different textures should be grouped together into atlases.
/// Negative values imply that the texture should not be put on an atlas.
/// </summary>
public int AtlasGroup;

/// <summary>
/// Comparer used for determining the order in which textures should be placed into the texture atlas.
/// </summary>
public static int Comparison(LoadStepData b, LoadStepData a)
{
var cmp = b.AtlasGroup.CompareTo(a.AtlasGroup);
if (cmp != 0)
return cmp;

return (b.AtlasSheet?.Height ?? 0).CompareTo(a.AtlasSheet?.Height ?? 0);
}
}

internal struct StateReg
Expand Down
7 changes: 4 additions & 3 deletions Robust.Shared/Resources/RsiLoading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ internal static RsiMetadata LoadRsiMetadata(Stream manifestFile)
};
}

return new RsiMetadata(size, states, textureParams);
return new RsiMetadata(size, states, textureParams, manifestJson.AtlasGroup);
}

public static void Warmup()
Expand All @@ -114,11 +114,12 @@ public static void Warmup()
JsonSerializer.Deserialize<RsiJsonMetadata>(warmupJson, SerializerOptions);
}

internal sealed class RsiMetadata(Vector2i size, StateMetadata[] states, TextureLoadParameters loadParameters)
internal sealed class RsiMetadata(Vector2i size, StateMetadata[] states, TextureLoadParameters loadParameters, int atlasGroup)
{
public readonly Vector2i Size = size;
public readonly StateMetadata[] States = states;
public readonly TextureLoadParameters LoadParameters = loadParameters;
public readonly int AtlasGroup = atlasGroup;
}

internal sealed class StateMetadata
Expand All @@ -140,7 +141,7 @@ public StateMetadata(string stateId, int dirCount, float[][] delays)

// To be directly deserialized.
[UsedImplicitly]
private sealed record RsiJsonMetadata(Vector2i Size, StateJsonMetadata[] States, RsiJsonLoad? Load);
private sealed record RsiJsonMetadata(Vector2i Size, StateJsonMetadata[] States, RsiJsonLoad? Load, int AtlasGroup = 0);

[UsedImplicitly]
private sealed record StateJsonMetadata(string Name, int? Directions, float[][]? Delays);
Expand Down
10 changes: 9 additions & 1 deletion Schemas/rsi.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
]
]
}
]
],
"atlasGroup": 0
}
],
"required": [
Expand Down Expand Up @@ -184,6 +185,13 @@
}
}
}
},
"atlasGroup": {
"$id": "#/properties/atlasGroup",
"default": "",
"description": "An integer that is used to group RSIs into the same texture atlas. Defaults to 0. Negative values prevent the RSI from being put into a larger atlas.",
"title": "atlasGroup",
"type": "integer"
Comment on lines +188 to +194
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure how the RSI schema validator works, but hopefully this is right?

}
},
"additionalProperties": true
Expand Down
Loading