improve filtering
This commit is contained in:
@@ -1343,22 +1343,11 @@ internal static class MdlDecimator
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsBodyMaterial(mdl.Materials[mesh.MaterialIndex]);
|
return ModelDecimationFilters.IsBodyMaterial(mdl.Materials[mesh.MaterialIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsBodyMaterial(string materialPath)
|
private static bool IsBodyMaterial(string materialPath)
|
||||||
{
|
=> ModelDecimationFilters.IsBodyMaterial(materialPath);
|
||||||
if (string.IsNullOrWhiteSpace(materialPath))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var normalized = materialPath.Replace('\\', '/').ToLowerInvariant();
|
|
||||||
var nameStart = normalized.LastIndexOf('/');
|
|
||||||
var fileName = nameStart >= 0 ? normalized[(nameStart + 1)..] : normalized;
|
|
||||||
return fileName.Contains("_bibo", StringComparison.Ordinal)
|
|
||||||
|| fileName.EndsWith("_a.mtrl", StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class BodyCollisionData
|
private sealed class BodyCollisionData
|
||||||
{
|
{
|
||||||
|
|||||||
126
LightlessSync/Services/ModelDecimation/ModelDecimationFilters.cs
Normal file
126
LightlessSync/Services/ModelDecimation/ModelDecimationFilters.cs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
namespace LightlessSync.Services.ModelDecimation;
|
||||||
|
|
||||||
|
internal static class ModelDecimationFilters
|
||||||
|
{
|
||||||
|
// MODELS ONLY HERE, NOT MATERIALS
|
||||||
|
internal static readonly string[] HairPaths =
|
||||||
|
[
|
||||||
|
"/hair/",
|
||||||
|
"hir.mdl",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static readonly string[] ClothingPaths =
|
||||||
|
[
|
||||||
|
"chara/equipment/",
|
||||||
|
"/equipment/",
|
||||||
|
|
||||||
|
"met.mdl",
|
||||||
|
"top.mdl",
|
||||||
|
"glv.mdl",
|
||||||
|
"dwn.mdl",
|
||||||
|
"sho.mdl",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static readonly string[] AccessoryPaths =
|
||||||
|
[
|
||||||
|
"/accessory/",
|
||||||
|
"chara/accessory/",
|
||||||
|
|
||||||
|
"ear.mdl",
|
||||||
|
"nek.mdl",
|
||||||
|
"wrs.mdl",
|
||||||
|
"ril.mdl",
|
||||||
|
"rir.mdl",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static readonly string[] BodyPaths =
|
||||||
|
[
|
||||||
|
"/body/",
|
||||||
|
"chara/equipment/e0000/model/",
|
||||||
|
"chara/equipment/e9903/model/",
|
||||||
|
"chara/equipment/e9903/model/",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static readonly string[] FaceHeadPaths =
|
||||||
|
[
|
||||||
|
"/face/",
|
||||||
|
"/obj/face/",
|
||||||
|
"/head/",
|
||||||
|
"fac.mdl",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static readonly string[] TailOrEarPaths =
|
||||||
|
[
|
||||||
|
"/tail/",
|
||||||
|
"/obj/tail/",
|
||||||
|
"/zear/",
|
||||||
|
"/obj/zear/",
|
||||||
|
|
||||||
|
"til.mdl",
|
||||||
|
"zer.mdl",
|
||||||
|
];
|
||||||
|
|
||||||
|
// BODY MATERIALS ONLY, NOT MESHES
|
||||||
|
internal static readonly string[] BodyMaterials =
|
||||||
|
[
|
||||||
|
"_bibo",
|
||||||
|
"_a.mtrl",
|
||||||
|
"_b.mtrl",
|
||||||
|
];
|
||||||
|
|
||||||
|
internal static string NormalizePath(string path)
|
||||||
|
=> path.Replace('\\', '/').ToLowerInvariant();
|
||||||
|
|
||||||
|
internal static bool IsHairPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, HairPaths);
|
||||||
|
|
||||||
|
internal static bool IsClothingPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, ClothingPaths);
|
||||||
|
|
||||||
|
internal static bool IsAccessoryPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, AccessoryPaths);
|
||||||
|
|
||||||
|
|
||||||
|
internal static bool IsBodyPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, BodyPaths);
|
||||||
|
|
||||||
|
internal static bool IsFaceHeadPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, FaceHeadPaths);
|
||||||
|
|
||||||
|
internal static bool IsTailOrEarPath(string normalizedPath)
|
||||||
|
=> ContainsAny(normalizedPath, TailOrEarPaths);
|
||||||
|
|
||||||
|
internal static bool ContainsAny(string normalizedPath, IReadOnlyList<string> markers)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < markers.Count; i++)
|
||||||
|
{
|
||||||
|
if (normalizedPath.Contains(markers[i], StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool IsBodyMaterial(string materialPath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(materialPath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized = NormalizePath(materialPath);
|
||||||
|
var nameStart = normalized.LastIndexOf('/');
|
||||||
|
var fileName = nameStart >= 0 ? normalized[(nameStart + 1)..] : normalized;
|
||||||
|
foreach (var marker in BodyMaterials)
|
||||||
|
{
|
||||||
|
if (fileName.Contains(marker, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -348,46 +348,40 @@ public sealed class ModelDecimationService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var normalized = NormalizeGamePath(gamePath);
|
var normalized = ModelDecimationFilters.NormalizePath(gamePath);
|
||||||
if (normalized.Contains("/hair/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsHairPath(normalized))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized.Contains("/chara/equipment/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsClothingPath(normalized))
|
||||||
{
|
{
|
||||||
return _performanceConfigService.Current.ModelDecimationAllowClothing;
|
return _performanceConfigService.Current.ModelDecimationAllowClothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized.Contains("/chara/accessory/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsAccessoryPath(normalized))
|
||||||
{
|
{
|
||||||
return _performanceConfigService.Current.ModelDecimationAllowAccessories;
|
return _performanceConfigService.Current.ModelDecimationAllowAccessories;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized.Contains("/chara/human/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsBodyPath(normalized))
|
||||||
{
|
|
||||||
if (normalized.Contains("/body/", StringComparison.Ordinal))
|
|
||||||
{
|
{
|
||||||
return _performanceConfigService.Current.ModelDecimationAllowBody;
|
return _performanceConfigService.Current.ModelDecimationAllowBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized.Contains("/face/", StringComparison.Ordinal) || normalized.Contains("/head/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsFaceHeadPath(normalized))
|
||||||
{
|
{
|
||||||
return _performanceConfigService.Current.ModelDecimationAllowFaceHead;
|
return _performanceConfigService.Current.ModelDecimationAllowFaceHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalized.Contains("/tail/", StringComparison.Ordinal))
|
if (ModelDecimationFilters.IsTailOrEarPath(normalized))
|
||||||
{
|
{
|
||||||
return _performanceConfigService.Current.ModelDecimationAllowTail;
|
return _performanceConfigService.Current.ModelDecimationAllowTail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NormalizeGamePath(string path)
|
|
||||||
=> path.Replace('\\', '/').ToLowerInvariant();
|
|
||||||
|
|
||||||
private bool TryGetDecimationSettings(out ModelDecimationSettings settings)
|
private bool TryGetDecimationSettings(out ModelDecimationSettings settings)
|
||||||
{
|
{
|
||||||
settings = new ModelDecimationSettings(
|
settings = new ModelDecimationSettings(
|
||||||
|
|||||||
Reference in New Issue
Block a user