This commit is contained in:
2025-12-16 06:31:29 +09:00
parent bdfcf254a8
commit 4444a88746
32 changed files with 1204 additions and 464 deletions

View File

@@ -88,26 +88,39 @@ public sealed class TextureMetadataHelper
private static readonly (TextureMapKind Kind, string Token)[] MapTokens =
{
(TextureMapKind.Normal, "_n"),
(TextureMapKind.Normal, "_n."),
(TextureMapKind.Normal, "_n_"),
(TextureMapKind.Normal, "_normal"),
(TextureMapKind.Normal, "normal_"),
(TextureMapKind.Normal, "_norm"),
(TextureMapKind.Normal, "norm_"),
(TextureMapKind.Mask, "_m"),
(TextureMapKind.Mask, "_m."),
(TextureMapKind.Mask, "_m_"),
(TextureMapKind.Mask, "_mask"),
(TextureMapKind.Mask, "mask_"),
(TextureMapKind.Mask, "_msk"),
(TextureMapKind.Specular, "_s"),
(TextureMapKind.Specular, "_s."),
(TextureMapKind.Specular, "_s_"),
(TextureMapKind.Specular, "_spec"),
(TextureMapKind.Specular, "_specular"),
(TextureMapKind.Specular, "specular_"),
(TextureMapKind.Index, "_id"),
(TextureMapKind.Index, "_id."),
(TextureMapKind.Index, "_id_"),
(TextureMapKind.Index, "_idx"),
(TextureMapKind.Index, "_index"),
(TextureMapKind.Index, "index_"),
(TextureMapKind.Index, "_multi"),
(TextureMapKind.Diffuse, "_d"),
(TextureMapKind.Diffuse, "_d."),
(TextureMapKind.Diffuse, "_d_"),
(TextureMapKind.Diffuse, "_diff"),
(TextureMapKind.Diffuse, "_b"),
(TextureMapKind.Diffuse, "_base")
(TextureMapKind.Diffuse, "_b."),
(TextureMapKind.Diffuse, "_b_"),
(TextureMapKind.Diffuse, "_base"),
(TextureMapKind.Diffuse, "base_")
};
private const string TextureSegment = "/texture/";
@@ -376,73 +389,83 @@ public sealed class TextureMetadataHelper
private static TextureMapKind GuessMapFromFileName(string path)
{
var normalized = Normalize(path);
var fileName = Path.GetFileNameWithoutExtension(normalized);
if (string.IsNullOrEmpty(fileName))
var fileNameWithExtension = Path.GetFileName(normalized);
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(normalized);
if (string.IsNullOrEmpty(fileNameWithExtension) && string.IsNullOrEmpty(fileNameWithoutExtension))
return TextureMapKind.Unknown;
foreach (var (kind, token) in MapTokens)
{
if (fileName.Contains(token, StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrEmpty(fileNameWithExtension) &&
fileNameWithExtension.Contains(token, StringComparison.OrdinalIgnoreCase))
return kind;
if (!string.IsNullOrEmpty(fileNameWithoutExtension) &&
fileNameWithoutExtension.Contains(token, StringComparison.OrdinalIgnoreCase))
return kind;
}
return TextureMapKind.Unknown;
}
private static readonly (string Token, TextureCompressionTarget Target)[] FormatTargetTokens =
{
("BC1", TextureCompressionTarget.BC1),
("DXT1", TextureCompressionTarget.BC1),
("BC3", TextureCompressionTarget.BC3),
("DXT3", TextureCompressionTarget.BC3),
("DXT5", TextureCompressionTarget.BC3),
("BC4", TextureCompressionTarget.BC4),
("ATI1", TextureCompressionTarget.BC4),
("BC5", TextureCompressionTarget.BC5),
("ATI2", TextureCompressionTarget.BC5),
("3DC", TextureCompressionTarget.BC5),
("BC7", TextureCompressionTarget.BC7),
("BPTC", TextureCompressionTarget.BC7)
}; // idk man
public static bool TryMapFormatToTarget(string? format, out TextureCompressionTarget target)
{
var normalized = (format ?? string.Empty).ToUpperInvariant();
if (normalized.Contains("BC1", StringComparison.Ordinal))
foreach (var (token, mappedTarget) in FormatTargetTokens)
{
target = TextureCompressionTarget.BC1;
return true;
}
if (normalized.Contains("BC3", StringComparison.Ordinal))
{
target = TextureCompressionTarget.BC3;
return true;
}
if (normalized.Contains("BC4", StringComparison.Ordinal))
{
target = TextureCompressionTarget.BC4;
return true;
}
if (normalized.Contains("BC5", StringComparison.Ordinal))
{
target = TextureCompressionTarget.BC5;
return true;
}
if (normalized.Contains("BC7", StringComparison.Ordinal))
{
target = TextureCompressionTarget.BC7;
return true;
if (normalized.Contains(token, StringComparison.Ordinal))
{
target = mappedTarget;
return true;
}
}
target = TextureCompressionTarget.BC7;
return false;
}
public static (TextureCompressionTarget Target, string Reason)? GetSuggestedTarget(string? format, TextureMapKind mapKind)
public static (TextureCompressionTarget Target, string Reason)? GetSuggestedTarget(
string? format,
TextureMapKind mapKind,
string? texturePath = null)
{
TextureCompressionTarget? current = null;
if (TryMapFormatToTarget(format, out var mapped))
current = mapped;
var prefersBc4 = IsFacePaintOrMarkTexture(texturePath);
var suggestion = mapKind switch
{
TextureMapKind.Normal => TextureCompressionTarget.BC7,
TextureMapKind.Mask => TextureCompressionTarget.BC4,
TextureMapKind.Index => TextureCompressionTarget.BC3,
TextureMapKind.Specular => TextureCompressionTarget.BC4,
TextureMapKind.Mask => TextureCompressionTarget.BC7,
TextureMapKind.Index => TextureCompressionTarget.BC5,
TextureMapKind.Specular => TextureCompressionTarget.BC3,
TextureMapKind.Diffuse => TextureCompressionTarget.BC7,
_ => TextureCompressionTarget.BC7
};
if (mapKind == TextureMapKind.Diffuse && !HasAlphaHint(format))
if (prefersBc4)
{
suggestion = TextureCompressionTarget.BC4;
}
else if (mapKind == TextureMapKind.Diffuse && current is null && !HasAlphaHint(format))
suggestion = TextureCompressionTarget.BC1;
if (current == suggestion)
@@ -498,14 +521,41 @@ public sealed class TextureMetadataHelper
|| normalized.Contains("skin", StringComparison.OrdinalIgnoreCase)
|| normalized.Contains("bibo", StringComparison.OrdinalIgnoreCase))
return "Skin";
if (normalized.Contains("decal_face", StringComparison.OrdinalIgnoreCase))
if (IsFacePaintPath(normalized))
return "Face Paint";
if (IsLegacyMarkPath(normalized))
return "Legacy Mark";
if (normalized.Contains("decal_equip", StringComparison.OrdinalIgnoreCase))
return "Equipment Decal";
return "Customization";
}
private static bool IsFacePaintOrMarkTexture(string? texturePath)
{
var normalized = Normalize(texturePath);
return IsFacePaintPath(normalized) || IsLegacyMarkPath(normalized);
}
private static bool IsFacePaintPath(string? normalizedPath)
{
if (string.IsNullOrEmpty(normalizedPath))
return false;
return normalizedPath.Contains("decal_face", StringComparison.Ordinal)
|| normalizedPath.Contains("facepaint", StringComparison.Ordinal)
|| normalizedPath.Contains("_decal_", StringComparison.Ordinal);
}
private static bool IsLegacyMarkPath(string? normalizedPath)
{
if (string.IsNullOrEmpty(normalizedPath))
return false;
return normalizedPath.Contains("transparent", StringComparison.Ordinal)
|| normalizedPath.Contains("transparent.tex", StringComparison.Ordinal);
}
private static bool HasAlphaHint(string? format)
{
if (string.IsNullOrEmpty(format))