watafak
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user